summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--.gitmodules6
-rw-r--r--makefile46
-rw-r--r--src/bootloader/bl_pnorAccess.C71
-rw-r--r--src/bootloader/bootloader.C6
-rw-r--r--src/bootloader/makefile5
-rw-r--r--src/build/beam/core/assert.C6
-rw-r--r--src/build/beam/core/pagemgr.C5
-rw-r--r--src/build/beam/core/stacksegment.C5
-rw-r--r--src/build/beam/hwp/mvpdRingFuncs.C5
-rw-r--r--src/build/beam/i2c/i2c.C6
-rw-r--r--src/build/beam/prdf/prdfBitKey.C5
-rw-r--r--src/build/beam/prdf/prdfPegasusConfigurator.C5
-rw-r--r--src/build/beam/targeting/targetservice.C5
-rw-r--r--src/build/buildpnor/PnorUtils.pm134
-rw-r--r--src/build/buildpnor/bpm-utils/LICENSE_PROLOG24
-rw-r--r--src/build/buildpnor/bpm-utils/imageCrc.c479
-rwxr-xr-xsrc/build/buildpnor/bpm-utils/insertBpmFwCrc.py191
-rwxr-xr-xsrc/build/buildpnor/buildBpmFlashImages.pl878
-rwxr-xr-xsrc/build/buildpnor/buildpnor.pl11
-rw-r--r--src/build/buildpnor/defaultPnorLayout.xml36
-rwxr-xr-xsrc/build/buildpnor/genPnorImages.pl68
-rwxr-xr-xsrc/build/buildpnor/memd_creation.pl2
-rwxr-xr-xsrc/build/buildpnor/pkgOcmbFw.pl7
-rw-r--r--src/build/buildpnor/pnorLayoutAxone.xml91
-rw-r--r--src/build/buildpnor/pnorLayoutFSP.xml30
-rwxr-xr-xsrc/build/citest/autocitest64
-rwxr-xr-xsrc/build/citest/build-script185
-rwxr-xr-xsrc/build/citest/create-sandbox4
-rwxr-xr-xsrc/build/citest/cxxtest-start.sh2
-rw-r--r--src/build/citest/etc/bbuild2
-rw-r--r--src/build/citest/etc/cppcheck (renamed from src/import/chips/ocmb/gemini/procedures/hwp/memory/00gem_common.mk)5
-rw-r--r--src/build/citest/etc/eecache_prebuilt1
-rw-r--r--src/build/citest/etc/simbuild2
-rwxr-xr-xsrc/build/citest/etc/workarounds.postsimsetup7
-rwxr-xr-xsrc/build/citest/setup-env1
-rw-r--r--src/build/configs/simics_axone.config40
-rw-r--r--src/build/debug/Hostboot/BlTrace.pm1
-rwxr-xr-xsrc/build/debug/Hostboot/Dump.pm14
-rwxr-xr-xsrc/build/debug/Hostboot/Gcov.pm464
-rw-r--r--src/build/debug/Hostboot/GcovModuleUnload.pm69
-rw-r--r--src/build/debug/Hostboot/PrintVMM.pm4
-rwxr-xr-xsrc/build/debug/Hostboot/_DebugFrameworkVMM.pm4
-rwxr-xr-xsrc/build/debug/eSEL.pl44
-rwxr-xr-xsrc/build/debug/ffdcExpander727
-rw-r--r--src/build/debug/simics-debug-framework.py23
-rw-r--r--src/build/linker/genlist.C71
-rw-r--r--src/build/linker/linker.C30
-rw-r--r--src/build/mkrules/cc.rules.mk71
-rw-r--r--src/build/mkrules/cflags.env.mk4
-rwxr-xr-xsrc/build/mkrules/dist.targets.mk6
-rw-r--r--src/build/mkrules/gcov.env.mk50
-rwxr-xr-xsrc/build/mkrules/hbfw/img/makefile58
-rw-r--r--src/build/mkrules/images.rules.mk39
-rwxr-xr-xsrc/build/simics/standalone.simics92
-rwxr-xr-xsrc/build/simics/startup.simics32
-rwxr-xr-xsrc/build/tools/addCopyright6
-rwxr-xr-xsrc/build/tools/build-cppcheck95
-rwxr-xr-xsrc/build/tools/cflags.sh68
-rwxr-xr-xsrc/build/tools/eecache_editor.pl802
-rwxr-xr-xsrc/build/tools/hb22
-rwxr-xr-xsrc/build/tools/listdeps.pl1
-rwxr-xr-xsrc/build/tools/pre-commit49
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/lib/shared/dimmConsts.H1
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/lib/utils/cumulus_find.H126
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/lib/utils/mem_size.C4
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/mss_dynamic_vid_utils.C4
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_cen_plug_rules.H396
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_bulk_pwr_throttles.C4
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.C4
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.C2
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config.C6
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config.H3
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config_thermal.C4
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_mrs6_DDR4.C17
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_rowRepairFuncs.C4
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.C4
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.C4
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_volt_dimm_count.C4
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_volt_vddr_offset.C4
-rw-r--r--src/import/chips/centaur/procedures/xml/error_info/p9c_memory_mss_eff_config_errors.xml104
-rw-r--r--src/import/chips/common/utils/chipids.H19
-rw-r--r--src/import/chips/ocmb/common/include/pmic_regs.H154
-rw-r--r--src/import/chips/ocmb/common/include/pmic_regs_fld.H193
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_attr_engine_traits.H2486
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_efd_processing.C274
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_efd_processing.H144
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/lib/i2c/i2c_pmic.H159
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_common_utils.C390
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_common_utils.H337
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_consts.H313
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.C615
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.H788
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/pmic_enable.C95
-rw-r--r--src/import/chips/ocmb/common/procedures/hwp/pmic/pmic_enable.H (renamed from src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config_thermal.H)52
-rw-r--r--src/import/chips/ocmb/common/procedures/xml/attribute_info/pmic_eff_attributes.xml729
-rw-r--r--src/import/chips/ocmb/common/procedures/xml/error_info/pmic_errors.xml209
-rw-r--r--src/import/chips/ocmb/common/spd_access/pmic_i2c_addr_get.H (renamed from src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config_thermal.C)67
-rw-r--r--src/import/chips/ocmb/explorer/common/include/exp_data_structs.H280
-rw-r--r--src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses.H1074
-rw-r--r--src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fixes.H3297
-rw-r--r--src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fld.H13429
-rw-r--r--src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fld_fixes.H57
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.C58
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.H55
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.mk31
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.C59
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.H39
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.mk6
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_check_for_ready.C33
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C66
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.mk2
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit_mc.C17
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_log_data.C109
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_log_data.H77
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_update.C379
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_update.H126
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getecid.C31
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getidec.C130
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getidec.H60
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.mk32
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_eff_config_thermal.C190
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_eff_config_thermal.H55
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_memdiag.C71
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_memdiag.H (renamed from src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.H)38
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_memdiag.mk (renamed from src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config_thermal.mk)10
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.C90
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.H53
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.mk31
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.C47
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.mk4
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C91
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train.C48
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.C141
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.H53
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.mk (renamed from src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_config_thermal.mk)7
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scominit.C5
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.C40
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.H31
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.mk7
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_explorer.C166
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_explorer.H (renamed from src/import/chips/p9/procedures/hwp/memory/lib/utils/num.H)36
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_traits_explorer.H260
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/exp_rank.H126
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/ecc_traits_explorer.C47
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/ecc_traits_explorer.H274
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/exp_mbs_error_vector_trap.H205
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/exp_modal_symbol_count.H245
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_attr_engine_traits.H266
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_efd_processing.C276
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_efd_processing.H130
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_attribute_accessors_manual.H129
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_draminit_utils.C393
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_draminit_utils.H537
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C25
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.H8
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_mss_thermal_init_utils.C176
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_mss_thermal_init_utils.H95
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir.C (renamed from src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/port.H)4
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir.H26
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir_traits.H99
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_unmask.C177
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_unmask.H24
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/hwp_wrappers_exp.C169
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H412
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_fields.C48
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_fields.H102
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_pmic.H24
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_scom.H8
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_fw_log.C139
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_fw_log.H104
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.C (renamed from src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.C)476
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.H (renamed from src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.H)164
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/exp_port.C81
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/exp_port.H115
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/exp_port_traits.H (renamed from src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_config_thermal.C)2
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/address.H24
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_address.H25
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist.C199
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist.H65
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist_traits.H626
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_memdiags.C167
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_memdiags.H57
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_settings.H23
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist.C24
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist.H24
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist_traits.H24
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/memdiags.C24
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/memdiags.H24
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/settings.H24
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/crc32.H105
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.C91
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.H74
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_display.C239
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_display.H344
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.C81
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.H271
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.C155
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.H82
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/pmic/exp_pmic_consts.H24
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_decoder.C282
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_decoder.H58
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle.C128
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle.H58
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle_traits.H144
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_consts.H163
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_defaults.H9
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/explorer_pos.C17
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/mss_exp_conversions.H189
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.C201
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.H106
-rw-r--r--src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_attributes.xml280
-rw-r--r--src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_omi_train.xml53
-rw-r--r--src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_power_thermal.xml164
-rw-r--r--src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_collect_explorer_errors.xml49
-rw-r--r--src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_fw_update_errors.xml154
-rw-r--r--src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_getidec.xml (renamed from src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_pmic_errors.xml)28
-rw-r--r--src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_inband_errors.xml16
-rw-r--r--src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_init_errors.xml14
-rw-r--r--src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_train_errors.xml55
-rw-r--r--src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml593
-rw-r--r--src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.C36
-rw-r--r--src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.H31
-rw-r--r--src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.mk7
-rw-r--r--src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.C41
-rw-r--r--src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.H21
-rw-r--r--src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.mk5
-rw-r--r--src/import/chips/ocmb/gemini/procedures/hwp/memory/lib/gem_draminit_utils.C123
-rw-r--r--src/import/chips/ocmb/gemini/procedures/hwp/memory/lib/gem_draminit_utils.H48
-rw-r--r--src/import/chips/ocmb/gemini/procedures/xml/error_info/gem_draminit_errors.xml31
-rw-r--r--src/import/chips/ocmb/procedures/hwp/initfiles/explorer_scom.C336
-rw-r--r--src/import/chips/p9/common/include/p9_frequency_buckets.H26
-rw-r--r--src/import/chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h22
-rw-r--r--src/import/chips/p9/common/scominfo/p9_cu.H5
-rw-r--r--src/import/chips/p9/common/scominfo/p9_scom_addr.H7
-rw-r--r--src/import/chips/p9/common/scominfo/p9_scominfo.C93
-rw-r--r--src/import/chips/p9/initfiles/p9a.int.scan.initfile47
-rw-r--r--src/import/chips/p9/initfiles/p9a.int.scom.initfile178
-rwxr-xr-x[-rw-r--r--]src/import/chips/p9/procedures/hwp/accessors/ddimm_get_efd.C156
-rw-r--r--src/import/chips/p9/procedures/hwp/customize/p9_xip_customize.C13
-rw-r--r--src/import/chips/p9/procedures/hwp/ffdc/exp_collect_explorer_log.C253
-rw-r--r--src/import/chips/p9/procedures/hwp/ffdc/exp_collect_explorer_log.H109
-rw-r--r--src/import/chips/p9/procedures/hwp/ffdc/ffdc_includes.H6
-rw-r--r--src/import/chips/p9/procedures/hwp/ffdc/p9_collect_lpc_regs.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp1_scom.C16
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp2_scom.C22
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp3_scom.C22
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_npu_scom.C84
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_npu_scom.H45
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_scom.C36
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_no_hp_scom.C23
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9_npu_scom.C307
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9_xbus_g0_scom.C35
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9_xbus_g1_scom.C40
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.C72
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.H47
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.mk36
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.C228
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.H45
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.mk27
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scan.C786
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scan.H8
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scom.C179
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_mi_scom.C20
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_init_scom.C10
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_io_scom.C1923
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_io_scom.H4
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_omic_io_scom.C299
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9a_omic_io_scom.H45
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9n_mca_scom.C19
-rw-r--r--src/import/chips/p9/procedures/hwp/io/p9_io_regs.H15
-rw-r--r--src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.C55
-rw-r--r--src/import/chips/p9/procedures/hwp/io/p9a_io_omi_dccal.C43
-rw-r--r--src/import/chips/p9/procedures/hwp/io/p9a_io_omi_scominit.C16
-rw-r--r--src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_base.H10
-rw-r--r--src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_occ_sram.H5
-rw-r--r--src/import/chips/p9/procedures/hwp/lib/p9_hcode_image_defines.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/lib/p9_pm_hcd_flags.h5
-rw-r--r--src/import/chips/p9/procedures/hwp/lib/p9_pstates_cmeqm.h47
-rw-r--r--src/import/chips/p9/procedures/hwp/lib/p9_pstates_common.h15
-rw-r--r--src/import/chips/p9/procedures/hwp/lib/p9_pstates_occ.h4
-rw-r--r--src/import/chips/p9/procedures/hwp/lib/p9_pstates_pgpe.h4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lab/sdk/example/C/mss_lab_sfwrite.C6
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C376
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_nimbus.C243
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_nimbus.H58
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_traits_nimbus.H274
-rwxr-xr-xsrc/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load.C19
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load.H16
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.C25
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.H8
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/control_word_ddr4.H52
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H42
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.C10
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.H8
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs00.C19
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs01.C19
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs02.C14
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs03.C14
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs04.C14
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs05.C14
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs06.C14
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C106
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H249
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C148
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.H23
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pba.C15
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pba.H7
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.C20
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.H16
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C18
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.H18
-rw-r--r--[-rwxr-xr-x]src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C221
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/kind.H263
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.C22
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.H23
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/nimbus_kind.H85
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.C21
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H12
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load.C44
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load.H23
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.H4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc.H789
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits.H331
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits_nimbus.C46
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits_nimbus.H319
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/fw_mark_store.H619
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/galois.H190
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/hw_mark_store.H507
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_aue_trap.H130
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_mpe_trap.H162
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_nce_trap.H195
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_rce_trap.H130
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_ue_trap.H130
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/maint_current_trap.H187
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/mark_shadow_reg.H149
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/modal_symbol_count.H573
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/nimbus_mbs_error_vector_trap.H (renamed from src/import/chips/p9/procedures/hwp/memory/lib/ecc/mbs_error_vector_trap.H)90
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/read_error_count_regs.H648
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/memory_size.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_mss_voltage.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/p9n_data_init_traits.H (renamed from src/import/generic/memory/lib/data_engine/p9n/p9n_data_init_traits.H)85
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C39
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H26
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/pre_data_init.H (renamed from src/import/generic/memory/lib/data_engine/pre_data_init.H)134
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.C167
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H735
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/fir/memdiags_fir.C175
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.C126
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.H52
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_freq_traits.H3
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.C12
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.H56
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/perf_reg.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C254
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H593
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C242
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.H132
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/address.H494
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C644
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H3342
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist_traits.H644
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C601
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.H397
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/settings.H760
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C175
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mss.mk3
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H191
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mss_vpd_decoder.H4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.H4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C17
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H25
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.C28
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.H39
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C30
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/accessor_wrapper.H257
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C183
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H277
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C821
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H320
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle_traits.H122
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H256
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/shared/nimbus_defaults.H3
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C5
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/find_magic.H (renamed from src/import/generic/memory/lib/utils/find_magic.H)26
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/hwp_wrappers_nim.C169
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_nimbus_conversions.H4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_pair.H4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/nimbus_find.H112
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.C254
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.H45
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dll_workarounds.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C73
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H44
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/draminit_workarounds.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/draminit_workarounds.H4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.C94
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.H (renamed from src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits.C)69
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.C19
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C35
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H14
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/nvdimm_workarounds.C285
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/nvdimm_workarounds.H46
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/quad_encode_workarounds.C256
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/quad_encode_workarounds.H373
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/mss.H10
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_background_scrub.C50
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C8
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_ddr_phy_reset.C5
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C18
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_mc.C12
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C3
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C6
-rwxr-xr-xsrc/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C3
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C20
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_freq_system.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.C11
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_scominit.C6
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C106
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_thermal_init.C5
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C86
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9a_omi_init.C23
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_fab_iovalid.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C33
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.C464
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_npu_scominit.C25
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_setup_bars.C180
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_setup_bars_defs.H42
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_throttle_sync.C35
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_tod_setup.C156
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.C68
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9a_get_mmio.C10
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.mk3
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9a_put_mmio.C10
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.C346
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.H78
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.mk30
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_nv_ref_clk_enable.C34
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_proc_gettracearray.H17
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_ram_core.C14
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_sbe_hreset.C10
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.C62
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.H16
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_spr_name_map.H6
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_start_cbs.C66
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_tracearray_defs.H23
-rw-r--r--src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.C309
-rw-r--r--src/import/chips/p9/procedures/hwp/pm/p9_pm_corequad_init.C10
-rw-r--r--src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket.C40
-rw-r--r--src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket.H4
-rw-r--r--src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket_attr.C8
-rw-r--r--src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket_attr.H18
-rw-r--r--src/import/chips/p9/procedures/hwp/pm/p9_pm_pstate_gpe_init.C6
-rw-r--r--src/import/chips/p9/procedures/hwp/pm/p9_pm_reset.C6
-rw-r--r--src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.C746
-rw-r--r--src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.H89
-rwxr-xr-xsrc/import/chips/p9/procedures/utils/stopreg/p9_cpu_reg_restore_instruction.H5
-rwxr-xr-xsrc/import/chips/p9/procedures/utils/stopreg/p9_stop_api.C715
-rwxr-xr-xsrc/import/chips/p9/procedures/utils/stopreg/p9_stop_api.H139
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/chip_ec_attributes.xml329
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/freq_attributes.xml13
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml12
-rwxr-xr-xsrc/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml16
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/nest_attributes.xml67
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/p9_io_obus_attributes.xml16
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/p9_setup_bars_attributes.xml180
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/p9a_io_attributes.xml21
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/p9a_omi_train.xml55
-rwxr-xr-xsrc/import/chips/p9/procedures/xml/attribute_info/pervasive_attributes.xml5
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/pm_plat_attributes.xml5
-rwxr-xr-x[-rw-r--r--]src/import/chips/p9/procedures/xml/error_info/ddimm_get_efd.xml25
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_get_mem_vpd_keyword.xml17
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_draminit_training.xml14
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml136
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config_thermal.xml189
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_freq.xml86
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml100
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_memdiags.xml185
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_spd_decode.xml221
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_mss_eff_grouping_errors.xml16
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_sbe_check_master_stop15_errors.xml16
-rw-r--r--src/import/chips/p9/xip/p9_xip_image.h3
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/eff_config/p9a_data_init_traits.H (renamed from src/import/generic/memory/lib/data_engine/p9a/p9a_data_init_traits.H)242
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/fir/p9a_fir.H (renamed from src/import/generic/memory/lib/utils/mcbist/address.H)4
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/fir/p9a_fir_traits.H (renamed from src/import/chips/p9/procedures/hwp/memory/lib/dimm/nimbus_kind.C)4
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/fir/p9a_unmask.C (renamed from src/import/chips/p9a/procedures/hwp/memory/p9a_mss_scrub.C)4
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_freq_traits.H7
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_mss_freq.C174
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.C44
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H60
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/mc/host_mc_traits.H (renamed from src/import/chips/p9a/procedures/hwp/memory/p9a_mss_scrub.H)4
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/mc/omi.H574
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.C (renamed from src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_config_thermal.H)4
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.H (renamed from src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/ecc_traits.H)4
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/shared/axone_consts.H4
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.C212
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.H124
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_bulk_pwr_throttles.mk2
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.C49
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.mk2
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.C41
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.H6
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.C56
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.H8
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.mk4
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.C117
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.mk2
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_volt.C5
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_volt.mk4
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_ocmb_thermal_init.C24
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_ocmb_thermal_init.H24
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.C98
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.H53
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.mk29
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.C57
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.mk2
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train_check.C73
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train_check.mk2
-rw-r--r--src/import/chips/p9a/procedures/xml/error_info/p9a_freq_errors.xml4
-rw-r--r--src/import/chips/p9a/procedures/xml/error_info/p9a_omi_train_errors.xml18
-rw-r--r--src/import/generic/memory/lib/ccs/ccs.H (renamed from src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H)842
-rw-r--r--src/import/generic/memory/lib/ccs/ccs_traits.H (renamed from src/import/chips/p9/procedures/hwp/memory/lib/utils/dump_regs.H)30
-rw-r--r--src/import/generic/memory/lib/data_engine/attr_engine_traits.H2805
-rw-r--r--src/import/generic/memory/lib/data_engine/data_engine.H249
-rw-r--r--src/import/generic/memory/lib/data_engine/data_engine_traits_def.H143
-rw-r--r--src/import/generic/memory/lib/data_engine/data_engine_utils.H485
-rw-r--r--src/import/generic/memory/lib/ecc/ecc.H758
-rw-r--r--src/import/generic/memory/lib/ecc/ecc_traits.H30
-rw-r--r--src/import/generic/memory/lib/ecc/fw_mark_store.H596
-rw-r--r--src/import/generic/memory/lib/ecc/galois.H166
-rw-r--r--src/import/generic/memory/lib/ecc/hw_mark_store.H482
-rw-r--r--src/import/generic/memory/lib/ecc/mainline_aue_trap.H107
-rw-r--r--src/import/generic/memory/lib/ecc/mainline_mpe_trap.H139
-rw-r--r--src/import/generic/memory/lib/ecc/mainline_nce_trap.H172
-rw-r--r--src/import/generic/memory/lib/ecc/mainline_rce_trap.H107
-rw-r--r--src/import/generic/memory/lib/ecc/mainline_ue_trap.H107
-rw-r--r--src/import/generic/memory/lib/ecc/maint_current_trap.H170
-rw-r--r--src/import/generic/memory/lib/ecc/mark_shadow_reg.H126
-rw-r--r--src/import/generic/memory/lib/ecc/mbs_error_vector_trap.H179
-rw-r--r--src/import/generic/memory/lib/ecc/modal_symbol_count.H549
-rw-r--r--src/import/generic/memory/lib/ecc/read_error_count_regs.H625
-rw-r--r--src/import/generic/memory/lib/mss_generic_attribute_getters.H470
-rw-r--r--src/import/generic/memory/lib/prd/hwp_wrappers.H246
-rw-r--r--src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H18
-rw-r--r--src/import/generic/memory/lib/spd/common/dimm_module_decoder.H200
-rw-r--r--src/import/generic/memory/lib/spd/common/spd_decoder_base.H62
-rw-r--r--src/import/generic/memory/lib/spd/ddimm/ddr4/ddimm_decoder_ddr4.H288
-rw-r--r--src/import/generic/memory/lib/spd/ddimm/ddr4/efd_ddr4_custom_microchip_decoder.H398
-rw-r--r--src/import/generic/memory/lib/spd/ddimm/ddr4/efd_fields_ddr4.H356
-rw-r--r--src/import/generic/memory/lib/spd/ddimm/ddr4/efd_traits_ddr4.H508
-rw-r--r--src/import/generic/memory/lib/spd/ddimm/efd_decoder.H289
-rw-r--r--src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.C24
-rw-r--r--src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.H10
-rw-r--r--src/import/generic/memory/lib/spd/spd_checker.H5
-rw-r--r--src/import/generic/memory/lib/spd/spd_facade.H289
-rw-r--r--src/import/generic/memory/lib/spd/spd_factory_pattern.H13
-rw-r--r--src/import/generic/memory/lib/spd/spd_fields_ddr4.H183
-rw-r--r--src/import/generic/memory/lib/spd/spd_traits_ddr4.H295
-rw-r--r--src/import/generic/memory/lib/spd/spd_utils.C8
-rw-r--r--src/import/generic/memory/lib/utils/buffer_ops.H28
-rw-r--r--src/import/generic/memory/lib/utils/conversions.H2
-rw-r--r--src/import/generic/memory/lib/utils/count_dimm.H22
-rw-r--r--src/import/generic/memory/lib/utils/dimm/kind.H249
-rw-r--r--src/import/generic/memory/lib/utils/dimm/mss_timing.H912
-rw-r--r--src/import/generic/memory/lib/utils/dump_regs.H31
-rw-r--r--src/import/generic/memory/lib/utils/endian_utils.H36
-rw-r--r--src/import/generic/memory/lib/utils/find.H186
-rw-r--r--src/import/generic/memory/lib/utils/fir/gen_mss_unmask.H39
-rw-r--r--src/import/generic/memory/lib/utils/freq/cas_latency.H16
-rw-r--r--src/import/generic/memory/lib/utils/freq/gen_mss_freq.H59
-rw-r--r--src/import/generic/memory/lib/utils/freq/mss_freq_scoreboard.H52
-rw-r--r--src/import/generic/memory/lib/utils/index.H19
-rw-r--r--src/import/generic/memory/lib/utils/mc/gen_mss_port.H960
-rw-r--r--src/import/generic/memory/lib/utils/mcbist/gen_address.H24
-rw-r--r--src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist.H3829
-rw-r--r--src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H441
-rw-r--r--src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_ecc_trap_address.H176
-rw-r--r--src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_fwms_address.H175
-rw-r--r--src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.C (renamed from src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.C)16
-rw-r--r--src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H (renamed from src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.H)21
-rw-r--r--src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H815
-rw-r--r--src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H41
-rw-r--r--src/import/generic/memory/lib/utils/mcbist/gen_mss_memdiags.H1287
-rw-r--r--src/import/generic/memory/lib/utils/mcbist/gen_patterns.C24
-rw-r--r--src/import/generic/memory/lib/utils/mcbist/gen_patterns.H24
-rw-r--r--src/import/generic/memory/lib/utils/mcbist/gen_settings.H24
-rw-r--r--src/import/generic/memory/lib/utils/mcbist/settings.H24
-rw-r--r--src/import/generic/memory/lib/utils/mss_bad_bits.H28
-rw-r--r--src/import/generic/memory/lib/utils/mss_field.H49
-rw-r--r--src/import/generic/memory/lib/utils/mss_generic_check.H25
-rw-r--r--src/import/generic/memory/lib/utils/mss_math.H29
-rw-r--r--src/import/generic/memory/lib/utils/mss_rank.H326
-rw-r--r--src/import/generic/memory/lib/utils/num.H31
-rw-r--r--src/import/generic/memory/lib/utils/power_thermal/gen_decoder.H584
-rw-r--r--src/import/generic/memory/lib/utils/power_thermal/gen_throttle.H1308
-rw-r--r--src/import/generic/memory/lib/utils/power_thermal/gen_throttle_traits.H33
-rw-r--r--src/import/generic/memory/lib/utils/shared/mss_generic_consts.H626
-rw-r--r--src/import/generic/memory/lib/utils/voltage/gen_mss_volt.H4
-rw-r--r--src/import/generic/memory/mss_git_data_helper.H34
-rw-r--r--src/import/generic/procedures/xml/attribute_info/generic_memory_attributes.xml39
-rw-r--r--src/import/generic/procedures/xml/attribute_info/generic_memory_eff_attributes.xml111
-rw-r--r--src/import/generic/procedures/xml/attribute_info/generic_memory_mrw_attributes.xml157
-rw-r--r--src/import/generic/procedures/xml/attribute_info/generic_memory_si_attributes.xml57
-rw-r--r--src/import/generic/procedures/xml/error_info/generic_error.xml917
-rw-r--r--src/import/hwpf/fapi2/include/error_info.H8
-rw-r--r--src/import/hwpf/fapi2/include/error_info_defs.H23
-rw-r--r--src/import/hwpf/fapi2/include/fapi2_hw_access.H3
-rw-r--r--src/import/hwpf/fapi2/include/target_types.H96
-rw-r--r--src/import/hwpf/fapi2/include/variable_buffer.H4
-rw-r--r--src/import/hwpf/fapi2/src/error_info.C15
-rwxr-xr-xsrc/import/hwpf/fapi2/tools/parseErrorInfo.pl13
-rw-r--r--src/import/hwpf/fapi2/xml/attribute_info/chip_attributes.xml5
-rw-r--r--src/import/hwpf/fapi2/xml/attribute_info/common_attributes.xml17
-rw-r--r--src/import/hwpf/fapi2/xml/attribute_info/i2cslave_attributes.xml54
-rw-r--r--src/import/hwpf/fapi2/xml/attribute_info/scratch_attributes.xml101
-rw-r--r--src/import/hwpf/fapi2/xml/attribute_info/system_attributes.xml5
m---------src/import/libmctp0
-rwxr-xr-xsrc/import/tools/genMemVpd.pl1637
-rw-r--r--src/include/arch/memorymap.H25
-rw-r--r--src/include/arch/ppc.H30
-rw-r--r--src/include/bootloader/bootloader_trace.H4
-rw-r--r--src/include/bootloader/hbblreasoncodes.H11
-rw-r--r--src/include/iterator48
-rw-r--r--src/include/kernel/ptmgr.H3
-rw-r--r--src/include/kernel/terminate.H13
-rwxr-xr-xsrc/include/runtime/README.md107
-rw-r--r--src/include/runtime/generic_hbrt_fsp_message.H70
-rw-r--r--src/include/runtime/hbrt_utilities.H90
-rw-r--r--src/include/runtime/interface.h131
-rw-r--r--src/include/securerom/ROM.H8
-rw-r--r--src/include/usr/console/consoleif.H4
-rw-r--r--src/include/usr/console/uartif.H3
-rwxr-xr-xsrc/include/usr/cxxtest/TestSuite.H6
-rw-r--r--src/include/usr/devicefw/driverif.H4
-rw-r--r--src/include/usr/devicefw/userif.H42
-rw-r--r--src/include/usr/diag/attn/attn.H3
-rw-r--r--src/include/usr/diag/prdf/prdfMain_ipl.H9
-rw-r--r--src/include/usr/dump/dumpif.H15
-rw-r--r--src/include/usr/errl/errlentry.H18
-rw-r--r--src/include/usr/errl/errlmanager.H71
-rw-r--r--src/include/usr/errl/errludattribute.H87
-rw-r--r--src/include/usr/errl/errludprintk.H6
-rw-r--r--src/include/usr/errldisplay/errldisplay.H3
-rw-r--r--src/include/usr/expscom/expscom_reasoncodes.H8
-rw-r--r--src/include/usr/expupd/expupd.H45
-rw-r--r--src/include/usr/expupd/expupd_reasoncodes.H54
-rw-r--r--src/include/usr/expupd/ocmbFwImage_const.H111
-rw-r--r--src/include/usr/fapi2/attribute_service.H83
-rw-r--r--src/include/usr/fapi2/dimmBadDqBitmapFuncs.H14
-rw-r--r--src/include/usr/fapi2/fapiPlatTrace.H3
-rw-r--r--src/include/usr/fapi2/hwpf_fapi2_reasoncodes.H12
-rw-r--r--src/include/usr/fapi2/rowRepairsFuncs.H14
-rw-r--r--src/include/usr/fapi2/target.H10
-rw-r--r--src/include/usr/fapiwrap/fapiWrapif.H79
-rw-r--r--src/include/usr/gcov.h229
-rw-r--r--src/include/usr/gpio/gpioddreasoncodes.H10
-rw-r--r--src/include/usr/gpio/gpioif.H121
-rw-r--r--src/include/usr/hbotcompid.H32
-rw-r--r--src/include/usr/hwas/common/hwasCallout.H10
-rw-r--r--src/include/usr/hwas/common/hwas_reasoncodes.H9
-rw-r--r--src/include/usr/hwas/common/pgLogic.H45
-rw-r--r--src/include/usr/hwas/common/vpdConstants.H123
-rw-r--r--src/include/usr/hwas/hwasPlat.H1
-rw-r--r--src/include/usr/i2c/eeprom_const.H38
-rw-r--r--src/include/usr/i2c/eepromddreasoncodes.H11
-rw-r--r--src/include/usr/i2c/tpmddif.H3
-rw-r--r--src/include/usr/initservice/mboxRegs.H8
-rw-r--r--src/include/usr/ipmi/ipmi_reasoncodes.H4
-rw-r--r--src/include/usr/ipmi/ipmiif.H8
-rw-r--r--src/include/usr/isteps/istep07list.H3
-rw-r--r--src/include/usr/isteps/istep08list.H5
-rw-r--r--src/include/usr/isteps/istep09list.H3
-rw-r--r--src/include/usr/isteps/istep10list.H1
-rw-r--r--src/include/usr/isteps/istep11list.H3
-rw-r--r--src/include/usr/isteps/istep12list.H2
-rw-r--r--src/include/usr/isteps/istep13list.H2
-rw-r--r--src/include/usr/isteps/istep14list.H1
-rw-r--r--src/include/usr/isteps/istep15list.H4
-rw-r--r--src/include/usr/isteps/istep21list.H1
-rw-r--r--src/include/usr/isteps/istep_reasoncodes.H2
-rw-r--r--src/include/usr/isteps/nvdimm/bpmreasoncodes.H90
-rw-r--r--src/include/usr/isteps/nvdimm/nvdimm.H400
-rw-r--r--src/include/usr/isteps/nvdimm/nvdimmif.H16
-rw-r--r--src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H158
-rw-r--r--src/include/usr/isteps/pm/occAccess.H3
-rw-r--r--src/include/usr/isteps/pm/occCheckstop.H6
-rw-r--r--src/include/usr/isteps/pm/pm_common_ext.H5
-rw-r--r--src/include/usr/isteps/spless_255list.H3
-rw-r--r--src/include/usr/mbox/mbox_queues.H2
-rw-r--r--src/include/usr/mmio/mmio_reasoncodes.H8
-rw-r--r--src/include/usr/pnor/pnor_const.H7
-rw-r--r--src/include/usr/pnor/pnor_reasoncodes.H7
-rw-r--r--src/include/usr/pnor/pnorif.H2
-rw-r--r--src/include/usr/runtime/customize_attrs_for_payload.H6
-rw-r--r--src/include/usr/runtime/runtime.H4
-rw-r--r--src/include/usr/runtime/runtime_reasoncodes.H13
-rw-r--r--src/include/usr/sbeio/runtime/sbe_msg_passing.H3
-rw-r--r--src/include/usr/sbeio/runtime/sbeio_nvdimm_operation.H58
-rw-r--r--src/include/usr/sbeio/sbe_psudd.H2
-rw-r--r--src/include/usr/scom/centaurScomCache.H7
-rw-r--r--src/include/usr/secureboot/drtm.H3
-rw-r--r--src/include/usr/secureboot/nodecommif.H3
-rw-r--r--src/include/usr/secureboot/phys_presence_if.H68
-rw-r--r--src/include/usr/secureboot/secure_reasoncodes.H19
-rw-r--r--src/include/usr/secureboot/service.H3
-rw-r--r--src/include/usr/secureboot/trustedbootif.H1
-rw-r--r--src/include/usr/targeting/common/attributeTank.H429
-rw-r--r--src/include/usr/targeting/common/hbrt_target.H45
-rw-r--r--src/include/usr/targeting/common/target.H174
-rw-r--r--src/include/usr/targeting/common/targetUtil.H154
-rw-r--r--src/include/usr/targeting/common/trace.H3
-rw-r--r--src/include/usr/targeting/common/util.H9
-rw-r--r--src/include/usr/targeting/runtime/rt_targeting.H (renamed from src/include/usr/runtime/rt_targeting.H)17
-rw-r--r--src/include/usr/util/impl/threadpool.H14
-rw-r--r--src/include/usr/util/runtime/rt_fwnotify.H45
-rw-r--r--src/include/usr/util/threadpool.H20
-rw-r--r--src/include/usr/util/util_reasoncodes.H2
-rw-r--r--src/include/usr/util/utillidmgr.H4
-rw-r--r--src/include/usr/vmmconst.h5
-rw-r--r--src/include/usr/vpd/spdenums.H21
-rw-r--r--src/include/usr/vpd/vpd_if.H17
-rw-r--r--src/include/usr/vpd/vpdreasoncodes.H13
-rw-r--r--src/kernel/heapmgr.C3
-rw-r--r--src/kernel/machchk.C11
-rw-r--r--src/kernel/makefile5
-rw-r--r--src/kernel/misc.C22
-rw-r--r--src/kernel/terminate.C15
-rw-r--r--src/kernel/vmmmgr.C3
-rw-r--r--src/lib/makefile5
-rw-r--r--src/lib/sprintf.C197
-rw-r--r--src/lib/stdio.C30
-rw-r--r--src/lib/stdlib.C1
-rw-r--r--src/lib/utilmisc.C8
-rw-r--r--src/libc++/makefile6
-rw-r--r--src/makefile43
-rw-r--r--src/module.ld3
-rw-r--r--src/runtime/makefile8
-rw-r--r--src/runtime/rt_main.C7
-rw-r--r--src/securerom/ecverify.C38
-rw-r--r--src/securerom/makefile4
-rwxr-xr-xsrc/usr/cxxtest/TestSuite.C46
-rw-r--r--src/usr/cxxtest/cxxtestexec.C70
-rw-r--r--src/usr/diag/attn/common/attnprd.C3
-rw-r--r--src/usr/diag/attn/ipl/attn.C3
-rw-r--r--src/usr/diag/attn/ipl/attnsvc.C3
-rw-r--r--src/usr/diag/attn/ipl/attnsvc.H3
-rw-r--r--src/usr/diag/attn/runtime/attn_rt.C2
-rw-r--r--src/usr/diag/attn/runtime/test/attntestRtAttns.H10
-rw-r--r--src/usr/diag/mdia/makefile7
-rw-r--r--src/usr/diag/mdia/mdia.C13
-rw-r--r--src/usr/diag/mdia/mdiafwd.H6
-rw-r--r--src/usr/diag/mdia/mdiasm.C79
-rw-r--r--src/usr/diag/mdia/mdiasm.H4
-rw-r--r--src/usr/diag/mdia/test/mdiatestmba.H113
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/config/iipSystem.h4
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/iipCaptureData.h2
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/iipErrorRegisterMask.h6
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/iipMopRegisterAccess.h184
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/iipMopRegisterAccessScanComm.h158
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/iipMopRegisterAccessScanComm.inl67
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/iipscr.C4
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/iipscr.h4
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/prdfCaptureData.C2
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/prdfErrorRegister.C4
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.C16
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.H16
-rw-r--r--src/usr/diag/prdf/common/framework/register/prdfRegisterCache.H4
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/prdfScomRegister.C10
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/prdfScomRegister.H11
-rw-r--r--src/usr/diag/prdf/common/framework/resolution/prdfCalloutMap.H2
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/resolution/prdfThresholdResolutions.H13
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/iipServiceDataCollector.h7
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/prdfServiceDataCollector.C84
-rwxr-xr-xsrc/usr/diag/prdf/common/iipconst.h5
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_mc.rule106
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_mc_actions.rule4
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_mc_regs.rule47
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_mcc.rule161
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_mcc_actions.rule156
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_mcc_regs.rule80
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_mi.rule14
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_mi_regs.rule56
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_npu.rule203
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_obus.rule64
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_omic.rule193
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_omic_actions.rule129
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_omic_regs.rule62
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_phb.rule10
-rw-r--r--src/usr/diag/prdf/common/plat/axone/axone_proc.rule195
-rw-r--r--src/usr/diag/prdf/common/plat/axone/prdfMccPlugins.C142
-rw-r--r--src/usr/diag/prdf/common/plat/axone/prdfOmicPlugins.C173
-rw-r--r--src/usr/diag/prdf/common/plat/axone/prdf_plat_axone.mk6
-rw-r--r--src/usr/diag/prdf/common/plat/cumulus/cumulus_mc_regs.rule19
-rw-r--r--src/usr/diag/prdf/common/plat/cumulus/cumulus_obus.rule64
-rw-r--r--src/usr/diag/prdf/common/plat/cumulus/cumulus_phb.rule10
-rw-r--r--src/usr/diag/prdf/common/plat/cumulus/cumulus_proc.rule4
-rw-r--r--src/usr/diag/prdf/common/plat/cumulus/cumulus_proc_actions.rule8
-rw-r--r--src/usr/diag/prdf/common/plat/explorer/explorer_ocmb.rule564
-rw-r--r--src/usr/diag/prdf/common/plat/explorer/explorer_ocmb_actions.rule299
-rw-r--r--src/usr/diag/prdf/common/plat/explorer/explorer_ocmb_regs.rule256
-rw-r--r--src/usr/diag/prdf/common/plat/explorer/prdfExplorerPlugins_common.C574
-rw-r--r--src/usr/diag/prdf/common/plat/explorer/prdf_plat_explorer.mk39
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemAddress.C100
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemAddress.H11
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C95
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemCeTable.C2
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemDbUtils.H63
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.C27
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.H28
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C452
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H30
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemExtraSig.H20
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemMark.C279
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemMark.H22
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemRowRepair.C87
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/mem/prdfMemSymbol.C94
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/mem/prdfMemSymbol.H8
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/mem/prdfMemThresholds.C11
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/mem/prdfMemUtils.C622
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/mem/prdfMemUtils.H4
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/mem/prdfMemoryMru.C94
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfOcmbDataBundle.H247
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdf_plat_mem.mk3
-rw-r--r--src/usr/diag/prdf/common/plat/nimbus/nimbus_mca.rule16
-rw-r--r--src/usr/diag/prdf/common/plat/nimbus/nimbus_mca_actions.rule22
-rw-r--r--src/usr/diag/prdf/common/plat/nimbus/nimbus_mcbist.rule4
-rw-r--r--src/usr/diag/prdf/common/plat/nimbus/nimbus_mcbist_actions.rule13
-rw-r--r--src/usr/diag/prdf/common/plat/nimbus/nimbus_mcs.rule4
-rw-r--r--src/usr/diag/prdf/common/plat/nimbus/nimbus_mcs_actions.rule13
-rw-r--r--src/usr/diag/prdf/common/plat/nimbus/nimbus_obus.rule64
-rw-r--r--src/usr/diag/prdf/common/plat/nimbus/nimbus_proc.rule4
-rw-r--r--src/usr/diag/prdf/common/plat/nimbus/nimbus_proc_actions.rule12
-rw-r--r--src/usr/diag/prdf/common/plat/p9/p9_common_actions.rule9
-rw-r--r--src/usr/diag/prdf/common/plat/p9/p9_common_obus_actions.rule146
-rw-r--r--src/usr/diag/prdf/common/plat/p9/p9_common_obus_regs.rule9
-rw-r--r--src/usr/diag/prdf/common/plat/p9/p9_common_proc_actions.rule3
-rw-r--r--src/usr/diag/prdf/common/plat/p9/prdfCommonPlugins.C82
-rw-r--r--src/usr/diag/prdf/common/plat/p9/prdfLaneRepair.C122
-rw-r--r--src/usr/diag/prdf/common/plat/p9/prdfLaneRepair.H8
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/p9/prdfP9Configurator.C27
-rw-r--r--src/usr/diag/prdf/common/plat/p9/prdfP9Obus.C193
-rw-r--r--src/usr/diag/prdf/common/plat/p9/prdfP9OcmbChipDomain.C78
-rw-r--r--src/usr/diag/prdf/common/plat/p9/prdfP9OcmbChipDomain.H12
-rw-r--r--src/usr/diag/prdf/common/plat/p9/prdf_plat_p9.mk3
-rw-r--r--src/usr/diag/prdf/common/plat/prdfPlatServices_common.C92
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/prdfPlatServices_common.H6
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/prdfRasServices_common.C21
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/prdfTargetServices.C200
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/prdfTargetServices.H34
-rw-r--r--src/usr/diag/prdf/common/plugins/prdfLogParse_common.C19
-rw-r--r--src/usr/diag/prdf/common/plugins/prdfMemLogParse.C25
-rw-r--r--src/usr/diag/prdf/common/plugins/prdfMemoryMruData.H14
-rw-r--r--src/usr/diag/prdf/common/plugins/prdfParserEnums.H6
-rw-r--r--src/usr/diag/prdf/common/plugins/prdfParserUtils.C46
-rwxr-xr-xsrc/usr/diag/prdf/common/prdfMain_common.C7
-rwxr-xr-xsrc/usr/diag/prdf/common/util/iipbits.h24
-rwxr-xr-xsrc/usr/diag/prdf/framework/prdfFileRegisterAccess.C8
-rwxr-xr-xsrc/usr/diag/prdf/framework/prdfFileRegisterAccess.H4
-rwxr-xr-xsrc/usr/diag/prdf/makefile5
-rw-r--r--src/usr/diag/prdf/occ_firdata/prdfWriteHomerFirData.C62
-rw-r--r--src/usr/diag/prdf/plat/explorer/prdfExplorerPlugins.C89
-rw-r--r--src/usr/diag/prdf/plat/explorer/prdf_plat_explorer_hb_only.mk42
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemDsd.H4
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemDsd_ipl.C93
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemDsd_rt.C81
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C506
-rwxr-xr-xsrc/usr/diag/prdf/plat/mem/prdfMemIplCeStats.C10
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C76
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C62
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H16
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C16
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_rt.C500
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTdRankList.H22
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C71
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTps_rt.C399
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemVcm.C118
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemVcm.H5
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C9
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C72
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfP9Mca.C835
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfP9Mcbist.C6
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfP9McbistDataBundle.H21
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfRestoreDramRepairs.C147
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices.C275
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices.H24
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices_ipl.C209
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices_ipl.H4
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices_rt.C154
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices_rt.H18
-rw-r--r--src/usr/diag/prdf/prdfMain_ipl.C9
-rw-r--r--src/usr/diag/prdf/prdf_hb_only.mk29
-rw-r--r--src/usr/diag/prdf/runtime/makefile5
-rw-r--r--src/usr/diag/prdf/test/prdfTest_BadDqBitmap.H227
-rwxr-xr-xsrc/usr/diag/prdf/test/prdf_hb_common_test.mk4
-rwxr-xr-xsrc/usr/diag/prdf/test/prdfsimHomRegisterAccess.C8
-rwxr-xr-xsrc/usr/diag/prdf/test/prdfsimHomRegisterAccess.H4
-rwxr-xr-xsrc/usr/diag/prdf/test/prdfsimScrDB.C4
-rw-r--r--src/usr/dump/dumpCollect.C233
-rw-r--r--src/usr/errl/errl.mk3
-rw-r--r--src/usr/errl/errlentry.C307
-rw-r--r--src/usr/errl/errlentry_consts.H12
-rw-r--r--src/usr/errl/errli2c.C3
-rw-r--r--src/usr/errl/errlmanager.C167
-rw-r--r--src/usr/errl/errlmanager_common.C3
-rw-r--r--src/usr/errl/errludattribute.C84
-rw-r--r--src/usr/errl/errludlogregister.C1
-rwxr-xr-xsrc/usr/errl/parser/genErrlParsers.pl4
-rw-r--r--src/usr/errl/parser/makefile2
-rw-r--r--src/usr/errl/plugins/errludattributeP.H41
-rw-r--r--src/usr/errl/plugins/errludbacktrace.H7
-rw-r--r--src/usr/errl/plugins/errludcallout.H1
-rw-r--r--src/usr/errl/plugins/errludlogregister.H14
-rwxr-xr-xsrc/usr/errl/plugins/errludparser.H4
-rw-r--r--src/usr/errl/plugins/errludparserfactoryerrl.H4
-rw-r--r--src/usr/errl/plugins/errludwofdata.H5
-rwxr-xr-xsrc/usr/errl/plugins/errluserdetails.H91
-rw-r--r--src/usr/errl/runtime/rt_errlmanager.C10
-rw-r--r--src/usr/errl/runtime/test/test_runtimeDeconfig.H14
-rw-r--r--src/usr/errl/test/errltest.H53
-rw-r--r--src/usr/errldisplay/errldisplay.C9
-rw-r--r--src/usr/errldisplay/makefile3
-rw-r--r--src/usr/expaccess/errlud_expscom.C216
-rw-r--r--src/usr/expaccess/errlud_expscom.H160
-rw-r--r--src/usr/expaccess/expaccess.mk10
-rw-r--r--src/usr/expaccess/expscom_utils.C15
-rw-r--r--src/usr/expaccess/mmioscomdd.C2
-rw-r--r--src/usr/expaccess/plugins/EXPSCOM_COMP_ID_Parse.C (renamed from src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/memory_size.C)10
-rw-r--r--src/usr/expaccess/plugins/errludP_expscom.H168
-rw-r--r--src/usr/expaccess/plugins/expscomUdParserFactory.H58
-rw-r--r--src/usr/expaccess/runtime/makefile5
-rw-r--r--src/usr/expaccess/runtime/test/makefile3
-rw-r--r--src/usr/expaccess/test/expErrlTest.C158
-rw-r--r--src/usr/expaccess/test/expErrlTest.H129
-rw-r--r--src/usr/expaccess/test/expscomtest.H1077
-rw-r--r--src/usr/expaccess/test/exptest_utils.C136
-rw-r--r--src/usr/expaccess/test/exptest_utils.H64
-rw-r--r--src/usr/expaccess/test/makefile5
-rw-r--r--src/usr/expaccess/test/ocmbcommtest.H289
-rw-r--r--src/usr/expaccess/test/rcExpLog.C55
-rw-r--r--src/usr/expaccess/test/rcExpLog.H49
-rw-r--r--src/usr/expaccess/test/test.mk23
-rw-r--r--src/usr/fapi2/attribute_service.C441
-rw-r--r--src/usr/fapi2/dimmBadDqBitmapFuncs.C25
-rwxr-xr-xsrc/usr/fapi2/fapi2.mk12
-rwxr-xr-xsrc/usr/fapi2/platCreateHwpErrParser.pl11
-rw-r--r--src/usr/fapi2/plat_mmio_access.C310
-rw-r--r--src/usr/fapi2/plat_spd_access.C122
-rw-r--r--src/usr/fapi2/plat_utils.C22
-rw-r--r--src/usr/fapi2/rowRepairsFuncs.C12
-rw-r--r--src/usr/fapi2/test/fapi2DdimmGetEfdTest.C3
-rw-r--r--src/usr/fapi2/test/fapi2GetChildrenTest.H135
-rw-r--r--src/usr/fapi2/test/fapi2GetVpdTest.H6
-rw-r--r--src/usr/fapi2/test/fapi2MmioAccessTest.H70
-rw-r--r--src/usr/fapi2/test/fapi2MvpdTestCxx.H6
-rw-r--r--src/usr/fapi2/test/fapi2SpdTestCxx.H194
-rw-r--r--src/usr/fapi2/test/fapi2Test.mk2
-rw-r--r--src/usr/fapi2/test/fapi2TestUtils.H3
-rw-r--r--src/usr/fapi2/test/p9_mmiotests.C31
-rw-r--r--src/usr/fapiwrap/fapiWrap.C106
-rw-r--r--src/usr/fapiwrap/makefile53
-rw-r--r--src/usr/fsi/fsipres.C3
-rw-r--r--src/usr/fsi/runtime/rt_fsi.C4
-rw-r--r--src/usr/gpio/HBconfig2
-rw-r--r--src/usr/gpio/gpio_pca9551.C343
-rw-r--r--src/usr/gpio/gpiodd.C54
-rw-r--r--src/usr/gpio/makefile4
-rw-r--r--src/usr/hdat/hdatiohub.C45
-rwxr-xr-xsrc/usr/hdat/hdatiohub.H3
-rwxr-xr-xsrc/usr/hdat/hdatiplparms.C32
-rwxr-xr-xsrc/usr/hdat/hdatiplparms.H4
-rwxr-xr-xsrc/usr/hdat/hdatmsarea.C12
-rwxr-xr-xsrc/usr/hdat/hdatmsarea.H21
-rwxr-xr-xsrc/usr/hdat/hdatmsvpd.C1875
-rwxr-xr-xsrc/usr/hdat/hdatmsvpd.H49
-rw-r--r--src/usr/hdat/hdatpcrd.C6
-rw-r--r--src/usr/hdat/hdatutil.C76
-rwxr-xr-xsrc/usr/hdat/hdatutil.H11
-rwxr-xr-xsrc/usr/hdat/hdatvpd.C84
-rw-r--r--src/usr/htmgt/htmgt.C1
-rw-r--r--src/usr/htmgt/htmgt_occ.H25
-rw-r--r--src/usr/htmgt/occError.C140
-rw-r--r--src/usr/htmgt/occError.H47
-rw-r--r--src/usr/htmgt/runtime/rt_occ.C4
-rw-r--r--src/usr/hwas/common/deconfigGard.C24
-rw-r--r--src/usr/hwas/common/hwas.C148
-rw-r--r--src/usr/hwas/common/pgLogic.C25
-rw-r--r--src/usr/hwas/hwasPlat.C548
-rw-r--r--src/usr/hwas/hwasPlatDeconfigGard.C3
-rw-r--r--src/usr/hwas/test/hwas1test.H267
-rw-r--r--src/usr/hwas/test/hwasGardTest.H2
-rw-r--r--src/usr/hwplibs/nest/nestmemutils.mk13
-rw-r--r--src/usr/i2c/eepromCache.C812
-rw-r--r--src/usr/i2c/eepromCache.H157
-rw-r--r--src/usr/i2c/eepromCache_common.C325
-rw-r--r--src/usr/i2c/eeprom_utils.C14
-rwxr-xr-xsrc/usr/i2c/eepromdd.C73
-rw-r--r--src/usr/i2c/eepromdd_hardware.C16
-rw-r--r--src/usr/i2c/fapi_i2c_dd.C74
-rwxr-xr-xsrc/usr/i2c/i2c.C138
-rwxr-xr-xsrc/usr/i2c/i2c.H4
-rw-r--r--src/usr/i2c/i2c.mk4
-rw-r--r--src/usr/i2c/i2cTargetPres.C127
-rw-r--r--src/usr/i2c/makefile1
-rw-r--r--src/usr/i2c/runtime/makefile6
-rw-r--r--src/usr/i2c/runtime/rt_eepromCache.C285
-rwxr-xr-xsrc/usr/i2c/runtime/rt_i2c.C8
-rw-r--r--src/usr/i2c/test/eecachetest.H121
-rw-r--r--src/usr/i2c/test/makefile3
-rwxr-xr-xsrc/usr/i2c/test/tpmddtest.H36
-rwxr-xr-xsrc/usr/i2c/tpmdd.C3
-rw-r--r--src/usr/initservice/baseinitsvc/initservice.C9
-rw-r--r--src/usr/initservice/bootconfig/bootconfig.C3
-rw-r--r--src/usr/initservice/bootconfig/bootconfig_ast2400.C3
-rw-r--r--src/usr/initservice/bootconfig/bootconfigif.C4
-rw-r--r--src/usr/initservice/extinitsvc/extinitsvctasks.H24
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.C5
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.H3
-rw-r--r--src/usr/intr/intrrp.C15
-rw-r--r--src/usr/ipmibase/ipmibt.C3
-rw-r--r--src/usr/ipmibase/ipmiconfig.C4
-rw-r--r--src/usr/ipmibase/ipmidd.C3
-rw-r--r--src/usr/ipmibase/ipmimsg.C3
-rw-r--r--src/usr/ipmibase/ipmirp.C1
-rw-r--r--src/usr/ipmiext/ipmidcmi.C131
-rw-r--r--src/usr/ipmiext/ipmifruinv.C101
-rw-r--r--src/usr/ipmiext/ipmisensor.C93
-rw-r--r--src/usr/ipmiext/runtime/rt_ipmirp.C3
-rw-r--r--src/usr/isteps/expupd/expupd.C393
-rw-r--r--src/usr/isteps/expupd/expupd.mk38
-rw-r--r--src/usr/isteps/expupd/expupd_trace.H40
-rw-r--r--src/usr/isteps/expupd/makefile35
-rw-r--r--src/usr/isteps/expupd/ocmbFwImage.C391
-rw-r--r--src/usr/isteps/expupd/ocmbFwImage.H68
-rw-r--r--src/usr/isteps/expupd/test/expupdatetest.H175
-rw-r--r--src/usr/isteps/expupd/test/makefile (renamed from src/import/chips/ocmb/gemini/procedures/hwp/memory/lib/mss_gemini.mk)11
-rw-r--r--src/usr/isteps/expupd/test/test.mk35
-rw-r--r--src/usr/isteps/istep06/call_host_update_master_tpm.C28
-rw-r--r--src/usr/isteps/istep06/call_host_voltage_config.C6
-rw-r--r--src/usr/isteps/istep06/host_discover_targets.C65
-rw-r--r--src/usr/isteps/istep06/host_gard.C1
-rw-r--r--src/usr/isteps/istep06/host_init_fsi.C1
-rw-r--r--src/usr/isteps/istep07/call_mss_attr_update.C33
-rw-r--r--src/usr/isteps/istep07/call_mss_eff_config.C69
-rw-r--r--src/usr/isteps/istep07/call_mss_freq.C121
-rw-r--r--src/usr/isteps/istep07/host_mss_attr_cleanup.C9
-rw-r--r--src/usr/isteps/istep07/makefile13
-rw-r--r--src/usr/isteps/istep08/call_host_set_voltages.C46
-rw-r--r--src/usr/isteps/istep08/call_proc_attr_update.C3
-rw-r--r--src/usr/isteps/istep08/call_proc_xbus_scominit.C3
-rw-r--r--src/usr/isteps/istep08/makefile23
-rw-r--r--src/usr/isteps/istep10/call_host_rng_bist.C5
-rw-r--r--src/usr/isteps/istep10/call_host_slave_sbe_update.C22
-rw-r--r--src/usr/isteps/istep10/call_host_update_redundant_tpm.C25
-rw-r--r--src/usr/isteps/istep10/call_proc_abus_scominit.C3
-rw-r--r--src/usr/isteps/istep10/call_proc_build_smp.C2
-rw-r--r--src/usr/isteps/istep10/call_proc_cen_ref_clk_enable.C60
-rw-r--r--src/usr/isteps/istep10/call_proc_chiplet_scominit.C6
-rw-r--r--src/usr/isteps/istep10/call_proc_enable_osclite.C3
-rw-r--r--src/usr/isteps/istep10/call_proc_npu_scominit.C4
-rw-r--r--src/usr/isteps/istep10/call_proc_pcie_scominit.C3
-rw-r--r--src/usr/isteps/istep10/call_proc_scomoverride_chiplets.C3
-rw-r--r--src/usr/isteps/istep10/host_proc_pcie_scominit.C1
-rw-r--r--src/usr/isteps/istep10/makefile3
-rw-r--r--src/usr/isteps/istep11/call_host_prd_hwreconfig.C3
-rw-r--r--src/usr/isteps/istep12/call_cen_dmi_scominit.C48
-rw-r--r--src/usr/isteps/istep12/call_cen_set_inband_addr.C369
-rw-r--r--src/usr/isteps/istep12/call_dmi_io_dccal.C266
-rw-r--r--src/usr/isteps/istep12/call_dmi_io_run_training.C105
-rw-r--r--src/usr/isteps/istep12/call_dmi_post_trainadv.C112
-rw-r--r--src/usr/isteps/istep12/call_dmi_pre_trainadv.C102
-rw-r--r--src/usr/isteps/istep12/call_mss_getecid.C182
-rw-r--r--src/usr/isteps/istep12/call_proc_dmi_scominit.C53
-rw-r--r--src/usr/isteps/istep12/makefile20
-rw-r--r--src/usr/isteps/istep13/call_mss_ddr_phy_reset.C6
-rw-r--r--src/usr/isteps/istep13/call_mss_draminit.C285
-rw-r--r--src/usr/isteps/istep13/call_mss_draminit_mc.C82
-rw-r--r--src/usr/isteps/istep13/call_mss_draminit_trainadv.C16
-rw-r--r--src/usr/isteps/istep13/call_mss_draminit_training.C4
-rw-r--r--src/usr/isteps/istep13/call_mss_scominit.C380
-rw-r--r--src/usr/isteps/istep13/istep13consts.H4
-rw-r--r--src/usr/isteps/istep13/makefile120
-rw-r--r--src/usr/isteps/istep14/call_host_mpipl_service.C7
-rw-r--r--src/usr/isteps/istep14/call_mss_memdiag.C42
-rw-r--r--src/usr/isteps/istep14/call_mss_power_cleanup.C3
-rw-r--r--src/usr/isteps/istep14/call_mss_thermal_init.C300
-rw-r--r--src/usr/isteps/istep14/call_proc_exit_cache_contained.C5
-rw-r--r--src/usr/isteps/istep14/call_proc_setup_bars.C1
-rw-r--r--src/usr/isteps/istep14/makefile25
-rw-r--r--src/usr/isteps/istep15/host_build_stop_image.C89
-rw-r--r--src/usr/isteps/istep15/host_establish_ex_chiplet.C5
-rw-r--r--src/usr/isteps/istep15/host_start_stop_engine.C11
-rw-r--r--src/usr/isteps/istep15/proc_set_pba_homer_bar.C78
-rw-r--r--src/usr/isteps/istep16/call_host_activate_master.C5
-rw-r--r--src/usr/isteps/istep16/call_host_activate_slave_cores.C2
-rw-r--r--src/usr/isteps/istep16/call_host_secure_rng.C3
-rw-r--r--src/usr/isteps/istep16/call_mss_scrub.C7
-rw-r--r--src/usr/isteps/istep18/establish_system_smp.C5
-rw-r--r--src/usr/isteps/istep18/smp_unfencing_inter_enclosure_abus_links.C3
-rw-r--r--src/usr/isteps/istep20/call_host_load_payload.C9
-rw-r--r--src/usr/isteps/istep21/call_host_runtime_setup.C69
-rw-r--r--src/usr/isteps/istep21/call_host_start_payload.C96
-rw-r--r--src/usr/isteps/istep21/call_nvdimm_update.C3
-rw-r--r--src/usr/isteps/istep21/call_update_ucd_flash.C1
-rw-r--r--src/usr/isteps/istep21/freqAttrData.C3
-rw-r--r--src/usr/isteps/makefile3
-rw-r--r--src/usr/isteps/mem_utils.C8
-rw-r--r--src/usr/isteps/mss/HBconfig2
-rw-r--r--src/usr/isteps/mss/makefile48
-rw-r--r--src/usr/isteps/mss/runtime/makefile4
-rw-r--r--src/usr/isteps/nest/makefile1
-rw-r--r--src/usr/isteps/nvdimm/ReadMe.md278
-rw-r--r--src/usr/isteps/nvdimm/bpm_update.C4108
-rw-r--r--src/usr/isteps/nvdimm/bpm_update.H1078
-rw-r--r--src/usr/isteps/nvdimm/errlud_nvdimm.C48
-rw-r--r--src/usr/isteps/nvdimm/errlud_nvdimm.H33
-rw-r--r--src/usr/isteps/nvdimm/nvdimm.C5026
-rw-r--r--src/usr/isteps/nvdimm/nvdimm.H344
-rw-r--r--src/usr/isteps/nvdimm/nvdimm.mk5
-rw-r--r--src/usr/isteps/nvdimm/nvdimmErrorLog.C1317
-rw-r--r--src/usr/isteps/nvdimm/nvdimmErrorLog.H108
-rw-r--r--src/usr/isteps/nvdimm/nvdimm_update.C687
-rw-r--r--src/usr/isteps/nvdimm/nvdimm_update.H54
-rwxr-xr-xsrc/usr/isteps/nvdimm/nvdimmdd.C532
-rwxr-xr-xsrc/usr/isteps/nvdimm/nvdimmdd.H124
-rw-r--r--src/usr/isteps/nvdimm/plugins/errludP_nvdimm.H79
-rw-r--r--src/usr/isteps/nvdimm/plugins/nvdimmUdParserFactory.H10
-rw-r--r--src/usr/isteps/nvdimm/runtime/nvdimm_rt.C1222
-rw-r--r--src/usr/isteps/openpower_vddr.C3
-rw-r--r--src/usr/isteps/pm/occCheckstop.C13
-rw-r--r--src/usr/isteps/pm/pm_common.C32
-rw-r--r--src/usr/isteps/pm/pm_common.H6
-rw-r--r--src/usr/isteps/pm/runtime/rt_pm.C8
-rw-r--r--src/usr/isteps/pm/runtime/test/firmwareRequestTest.H200
-rw-r--r--src/usr/isteps/pm/runtime/test/pmtestRt.H4
-rw-r--r--src/usr/isteps/tod/runtime/rt_todintf.C4
-rw-r--r--src/usr/isteps/ucd/updateUcdFlash.C1
-rw-r--r--src/usr/lpc/lpcdd.C1
-rw-r--r--src/usr/makefile1
-rw-r--r--src/usr/mbox/mailboxsp.C3
-rw-r--r--src/usr/mmio/makefile12
-rw-r--r--src/usr/mmio/mmio.C1198
-rw-r--r--src/usr/mmio/mmio.H6
-rw-r--r--src/usr/mmio/mmio_explorer.C474
-rw-r--r--src/usr/mmio/mmio_explorer.H90
-rw-r--r--src/usr/mmio/runtime/makefile33
-rw-r--r--src/usr/mmio/runtime/rt_mmio.C108
-rw-r--r--src/usr/mmio/test/makefile7
-rw-r--r--src/usr/mmio/test/mmiotest.H277
-rw-r--r--src/usr/pnor/ast_mboxdd.C3
-rw-r--r--src/usr/pnor/ast_mboxdd.H3
-rw-r--r--src/usr/pnor/norflash.H3
-rw-r--r--src/usr/pnor/pnor_common.C90
-rw-r--r--src/usr/pnor/pnor_ipmidd.C3
-rw-r--r--src/usr/pnor/pnor_ipmidd.H3
-rw-r--r--src/usr/pnor/pnor_mboxdd.C3
-rw-r--r--src/usr/pnor/pnor_mboxdd.H3
-rw-r--r--src/usr/pnor/pnor_sfcdd.C5
-rw-r--r--src/usr/pnor/pnor_sfcdd.H3
-rw-r--r--src/usr/pnor/pnor_utils.C31
-rw-r--r--src/usr/pnor/pnor_utils.H3
-rw-r--r--src/usr/pnor/pnorrp.C22
-rw-r--r--src/usr/pnor/pnorrp.H1
-rw-r--r--src/usr/pnor/runtime/rt_pnor.C7
-rw-r--r--src/usr/pnor/sfc_ast2400.H3
-rw-r--r--src/usr/pnor/sfc_ast2500.H3
-rw-r--r--src/usr/pnor/sfc_ast2X00.H3
-rw-r--r--src/usr/pnor/spnorrp.C218
-rw-r--r--src/usr/pnor/spnorrp.H14
-rw-r--r--src/usr/pnor/test/pnorrptest.H7
-rw-r--r--src/usr/pnor/test/pnorutilsTest.H43
-rw-r--r--src/usr/runtime/customize_attrs_for_payload.C283
-rw-r--r--src/usr/runtime/hdatstructs.H7
-rw-r--r--src/usr/runtime/populate_hbruntime.C155
-rw-r--r--src/usr/runtime/test/makefile2
-rw-r--r--src/usr/runtime/test/testpreverifiedlidmgr.H10
-rw-r--r--src/usr/sbe/sbe_update.C127
-rw-r--r--src/usr/sbe/test/sbeupdatetest.H1
-rw-r--r--src/usr/sbeio/runtime/makefile3
-rw-r--r--src/usr/sbeio/runtime/rt_sbeio.C9
-rw-r--r--src/usr/sbeio/runtime/sbeio_nvdimm_operation.C (renamed from src/import/chips/p9/procedures/hwp/memory/lib/fir/memdiags_fir.H)66
-rw-r--r--src/usr/sbeio/runtime/test/sbeioAttrOverrideTests.H8
-rw-r--r--src/usr/sbeio/runtime/test/sbeiotestRt.H26
-rw-r--r--src/usr/sbeio/sbe_continueMpipl.C3
-rw-r--r--src/usr/sbeio/sbe_coreStateControl.C3
-rw-r--r--src/usr/sbeio/sbe_getSBEFFDC.C3
-rw-r--r--src/usr/sbeio/sbe_memRegionMgr.C3
-rw-r--r--src/usr/sbeio/sbe_psuQuiesce.C3
-rw-r--r--src/usr/sbeio/sbe_psuReadSeeprom.C3
-rw-r--r--src/usr/sbeio/sbe_secureHwp.C3
-rw-r--r--src/usr/sbeio/sbe_securityListBinDump.C1
-rw-r--r--src/usr/sbeio/sbe_setFFDCAddr.C3
-rw-r--r--src/usr/sbeio/sbe_stashKeyAddr.C3
-rw-r--r--src/usr/sbeio/sbe_systemConfig.C3
-rw-r--r--src/usr/sbeio/test/sbe_getsbeffdctest.H10
-rw-r--r--src/usr/sbeio/test/sbe_retry_handler_test.H9
-rw-r--r--src/usr/scom/handleSpecialWakeup.C8
-rw-r--r--src/usr/scom/runtime/rt_scom.C18
-rw-r--r--src/usr/scom/runtime/test/testscom_rt.H25
-rw-r--r--src/usr/scom/scom.C3
-rw-r--r--src/usr/scom/scomtrans.C37
-rw-r--r--src/usr/scom/test/scomtest.H9
-rw-r--r--src/usr/secureboot/HBconfig14
-rw-r--r--src/usr/secureboot/README.md64
-rw-r--r--src/usr/secureboot/base/README.md60
-rw-r--r--src/usr/secureboot/base/securerommgr.C3
-rw-r--r--src/usr/secureboot/base/service.C3
-rw-r--r--src/usr/secureboot/base/settings.C3
-rw-r--r--src/usr/secureboot/common/README.md33
-rw-r--r--src/usr/secureboot/common/containerheader.C3
-rw-r--r--src/usr/secureboot/ext/README.md24
-rw-r--r--src/usr/secureboot/ext/drtm.C1
-rw-r--r--src/usr/secureboot/ext/makefile3
-rw-r--r--src/usr/secureboot/ext/phys_presence.C479
-rw-r--r--src/usr/secureboot/ext/service_ext.C5
-rw-r--r--src/usr/secureboot/node_comm/README.md97
-rw-r--r--src/usr/secureboot/node_comm/node_comm.H5
-rw-r--r--src/usr/secureboot/node_comm/node_comm_dd.H3
-rw-r--r--src/usr/secureboot/node_comm/node_comm_exchange.C117
-rw-r--r--src/usr/secureboot/node_comm/node_comm_transfer.C5
-rw-r--r--src/usr/secureboot/node_comm/node_comm_transfer.H1
-rw-r--r--src/usr/secureboot/runtime/README.md21
-rw-r--r--src/usr/secureboot/runtime/rt_secureboot.C5
-rw-r--r--src/usr/secureboot/runtime/test/testsecureboot_rt.H5
-rw-r--r--src/usr/secureboot/smf/test/testsmf.H21
-rw-r--r--src/usr/secureboot/trusted/README.md74
-rw-r--r--src/usr/secureboot/trusted/base/trustedboot_base.C3
-rwxr-xr-xsrc/usr/secureboot/trusted/test/trustedbootTest.H1
-rw-r--r--src/usr/secureboot/trusted/trustedboot.C1
-rw-r--r--src/usr/secureboot/trusted/trustedbootCmds.C1
-rw-r--r--src/usr/targeting/attrPlatOverride.C100
-rwxr-xr-xsrc/usr/targeting/attrrp.C1
-rw-r--r--src/usr/targeting/common/Targets.pm688
-rw-r--r--src/usr/targeting/common/associationmanager.C10
-rw-r--r--src/usr/targeting/common/attributeTank.C255
-rw-r--r--src/usr/targeting/common/common.mk3
-rwxr-xr-xsrc/usr/targeting/common/genHDATstructures.pl2
-rwxr-xr-xsrc/usr/targeting/common/genHwsvMrwXml.pl12
-rw-r--r--src/usr/targeting/common/hbrt_target.C101
-rwxr-xr-xsrc/usr/targeting/common/processMrw.pl234
-rw-r--r--src/usr/targeting/common/target.C22
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types.xml474
-rwxr-xr-xsrc/usr/targeting/common/xmltohb/attribute_types_hb.xml273
-rw-r--r--src/usr/targeting/common/xmltohb/hb_customized_attrs.xml97
-rw-r--r--src/usr/targeting/common/xmltohb/simics_AXONE.system.xml12785
-rw-r--r--src/usr/targeting/common/xmltohb/simics_CUMULUS.system.xml134
-rw-r--r--src/usr/targeting/common/xmltohb/simics_CUMULUS_CDIMM.system.xml130
-rw-r--r--src/usr/targeting/common/xmltohb/target_types.xml490
-rw-r--r--src/usr/targeting/common/xmltohb/target_types_hb.xml52
-rwxr-xr-xsrc/usr/targeting/common/xmltohb/xmltohb.pl289
-rw-r--r--src/usr/targeting/hostboot_common.mk5
-rw-r--r--src/usr/targeting/makefile3
-rw-r--r--src/usr/targeting/runtime/attrPlatOverride_rt.C5
-rw-r--r--src/usr/targeting/runtime/makefile3
-rw-r--r--src/usr/targeting/runtime/rt_startup.C4
-rw-r--r--src/usr/targeting/runtime/rt_targeting.C59
-rw-r--r--src/usr/targeting/runtime/test/testtargeting.H12
-rwxr-xr-xsrc/usr/targeting/targetservicestart.C105
-rw-r--r--src/usr/targeting/targplatutil.C3
-rw-r--r--src/usr/targeting/test/makefile4
-rw-r--r--src/usr/targeting/test/testAttribute.H1271
-rw-r--r--src/usr/targeting/test/testTargetUtil.H458
-rw-r--r--src/usr/targeting/test/testtargeting.H156
-rw-r--r--src/usr/targeting/xmltohb/fapi_utils.pl7
-rwxr-xr-xsrc/usr/targeting/xmltohb/makefile25
-rw-r--r--src/usr/testcore/kernel/misctest.H27
-rw-r--r--src/usr/testcore/kernel/vmmpagetest.H38
-rw-r--r--src/usr/testcore/lib/stltest.H32
-rw-r--r--src/usr/testcore/rtloader/loader.H1016
-rw-r--r--src/usr/trace/bufferpage.C4
-rw-r--r--src/usr/trace/daemon/daemon.C3
-rw-r--r--src/usr/trace/runtime/rt_rsvdtracebuffer.C154
-rw-r--r--src/usr/trace/runtime/rt_rsvdtracebuffer.H79
-rw-r--r--src/usr/trace/runtime/rt_rsvdtracebufservice.C8
-rw-r--r--src/usr/trace/runtime/test/testrsvdtracebuf.H270
-rw-r--r--src/usr/trace/service.C3
-rw-r--r--src/usr/util/runtime/rt_cmds.C164
-rw-r--r--src/usr/util/runtime/rt_fwnotify.C767
-rw-r--r--src/usr/util/runtime/rt_fwreq_helper.C283
-rw-r--r--src/usr/util/runtime/test/testlidmgr_rt.H3
-rw-r--r--src/usr/util/runtime/test/testruncommand.H3
-rw-r--r--src/usr/util/runtime/utillidmgr_rt.C23
-rw-r--r--src/usr/util/test/threadpool.H134
-rw-r--r--src/usr/util/threadpool.C54
-rw-r--r--src/usr/util/utillidmgr.C3
-rw-r--r--src/usr/util/utillidpnor.C13
-rw-r--r--src/usr/vfs/vfsrp.C7
-rw-r--r--src/usr/vfs/vfsrp.H2
-rw-r--r--src/usr/vpd/HBconfig13
-rw-r--r--src/usr/vpd/cvpd.C1
-rw-r--r--src/usr/vpd/cvpd.H3
-rwxr-xr-xsrc/usr/vpd/dimmPres.C3
-rw-r--r--src/usr/vpd/dvpd.C1
-rw-r--r--src/usr/vpd/dvpd.H3
-rw-r--r--src/usr/vpd/errlud_vpd.C10
-rw-r--r--src/usr/vpd/ipvpd.C202
-rw-r--r--src/usr/vpd/ipvpd.H108
-rw-r--r--src/usr/vpd/makefile1
-rw-r--r--src/usr/vpd/mvpd.C3
-rw-r--r--src/usr/vpd/ocmb_spd.C368
-rw-r--r--src/usr/vpd/ocmb_spd.H102
-rw-r--r--src/usr/vpd/pvpd.C6
-rw-r--r--src/usr/vpd/pvpd.H3
-rw-r--r--src/usr/vpd/rtvpd_load.C18
-rw-r--r--src/usr/vpd/runtime/rt_vpd.C4
-rw-r--r--src/usr/vpd/spd.C851
-rwxr-xr-xsrc/usr/vpd/spd.H107
-rw-r--r--src/usr/vpd/spdDDR3.H136
-rwxr-xr-xsrc/usr/vpd/spdDDR4.H138
-rwxr-xr-xsrc/usr/vpd/spdDDR4_DDIMM.H141
-rwxr-xr-xsrc/usr/vpd/test/dvpdtest.H7
-rwxr-xr-xsrc/usr/vpd/test/spdtest.H130
-rwxr-xr-xsrc/usr/vpd/vpd.C410
-rw-r--r--src/usr/vpd/vpd.mk1
-rw-r--r--src/usr/vpd/vpd_common.C4
-rw-r--r--src/usr/xscom/test/xscomtest.H15
-rw-r--r--src/usr/xscom/xscom.C7
1328 files changed, 142422 insertions, 44339 deletions
diff --git a/.gitignore b/.gitignore
index 52c97e3b2..42e066d38 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,9 @@ hbsandboxrc
*.__afs*
*~
_SYNCAPP/
+gcov_report
+lcov_data
+standalone/
+objdump/
+*.cppcheck
+cpptools/
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 000000000..eecd170a4
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "libmctp"]
+ path = src/import/libmctp
+ url = https://github.com/openbmc/libmctp
+
+ # We want this submodule to be cloned automatically when
+ # the Hostboot repo is recursively clone.
diff --git a/makefile b/makefile
index 16217fd5d..b1ab6e467 100644
--- a/makefile
+++ b/makefile
@@ -45,6 +45,16 @@ IMAGE_PASS_POST += cscope ctags
endif
IMAGE_PASS_POST += check_istep_modules
+# Variables used when running cppcheck tool.
+# The actual commands are stored in CXX_CHECK and C_CHECK, which are created as
+# dummy variables here, but will be set to the actual tool in the "cppcheck" rule
+BUILDCPPCHECK := $(PROJECT_ROOT)/src/build/tools/build-cppcheck
+CPPCHECKTOOL := $(PROJECT_ROOT)/src/build/tools/cpptools/cppcheck/cppcheck
+CPPCHECKFLAGS := --inline-suppr --error-exitcode=1 --template='Error CPPCHECK {file}: line {line}\nSyntax error string: {id}\n{message}'
+CPPCHECK := $(CPPCHECKTOOL) $(CPPCHECKFLAGS)
+export CXX_CHECK ?= true
+export C_CHECK ?= true
+
include ./config.mk
.PHONY: docs
@@ -56,14 +66,38 @@ docs: src/build/doxygen/doxygen.conf
citest:
src/build/citest/cxxtest-start.sh
+gcov: HOSTBOOT_PROFILE := 1
+
+export HOSTBOOT_PROFILE
+
.PHONY: gcov
gcov:
- rm -rf obj/gcov/*
- $(MAKE) gcov_pass
- find obj/gcov/ -size 0c | xargs rm # Delete empty files.
- genhtml obj/gcov/*.lcov -o obj/gcov/html --prefix `pwd` \
- --title `git describe --dirty`
- @echo "View GCOV results with: firefox obj/gcov/html/index.html"
+ @echo Building Hostboot with profiling enabled.
+ $(MAKE)
+ @echo Run simics and execute the hb-Gcov command at the end of the simulation to extract gcov data.
+ @echo Then you can "make lcov" to generate the coverage report.
+
+.PHONY: lcov
+lcov:
+ rm -f obj/lcov_data
+ lcov -c --dir . -o obj/lcov_data --gcov-tool $(GCOV)
+ rm -rf obj/gcov_report
+ genhtml obj/lcov_data -o obj/gcov_report --ignore-errors source
+ @echo Coverage report now available in obj/gcov_report
+
+.PHONY: cppcheck
+cppcheck:
+ @echo Building with CPPCHECK tool
+# TODO RTC: 215692
+ ${BUILDCPPCHECK}
+ export CXX_CHECK="$(CPPCHECK) $(filter -D%, $(CXXFLAGS)) $(INCFLAGS)" && \
+ export C_CHECK="$(CPPCHECK) $(filter -D%, $(CFLAGS)) $(INCFLAGS)" && \
+ export DOCPPCHECK=1 && \
+ ${MAKE}
+
+.PHONY: gcda_clean
+gcda_clean:
+ find -name '*.gcda' -exec rm -f {} \;
$(GENDIR)/hwp_id.html :
$(ROOTPATH)/src/build/tools/hwp_id.pl -i -l > $@
diff --git a/src/bootloader/bl_pnorAccess.C b/src/bootloader/bl_pnorAccess.C
index 89183754a..ac49e010b 100644
--- a/src/bootloader/bl_pnorAccess.C
+++ b/src/bootloader/bl_pnorAccess.C
@@ -57,32 +57,8 @@ void bl_pnorAccess::readTOC(uint8_t i_tocBuffer[PNOR::TOC_SIZE],
BOOTLOADER_TRACE(BTLDR_TRC_PA_READTOC_ZEROSECTION_RTN);
- //make sure that the buffer is not null
- PNOR::checkForNullBuffer(i_tocBuffer, o_errCode, l_ffs_hdr);
-
- if(o_errCode != PNOR::NO_ERROR)
- {
- BOOTLOADER_TRACE_W_BRK(BTLDR_TRC_PA_READTOC_CHKNULLBUFFER_NULL);
- // Always TI if NULL pointer is passed in
- /*@
- * @errortype
- * @moduleid Bootloader::MOD_PNORACC_READTOC
- * @reasoncode Bootloader::RC_CHK_NULL_BUFFER
- * @userdata1[0:15] TI_WITH_SRC
- * @userdata1[16:31] TI_BOOTLOADER
- * @userdata1[32:63] Failing address = 0
- * @userdata2[0:31] Pointer to TOC buffer
- * @userdata2[32:63] Error code
- * @devdesc Invalid TOC buffer pointer
- * @custdesc A problem occurred while running processor
- * boot code.
- */
- bl_terminate(Bootloader::MOD_PNORACC_READTOC,
- Bootloader::RC_CHK_NULL_BUFFER,
- reinterpret_cast<uint64_t>(i_tocBuffer),
- o_errCode);
- break;
- }
+ // Create a convenient way to access the ffs_hdr struct
+ l_ffs_hdr = reinterpret_cast<ffs_hdr*>(i_tocBuffer);
BOOTLOADER_TRACE(BTLDR_TRC_PA_READTOC_CHECKNULLBUFFER_RTN);
@@ -233,8 +209,25 @@ void bl_pnorAccess::findTOC(uint64_t i_lpcBar, PNOR::SectionData_t * o_TOC,
//PNOR error found
o_errCode = PNOR::LPC_ERR;
BOOTLOADER_TRACE(BTLDR_TRC_PA_FINDTOC_TOC1_LPC_ERR);
- //@TODO RTC:203989 Add LPC Error/Status Reg as part of FFDC
- terminateExecuteTI();
+ /*@
+ * @errortype
+ * @moduleid Bootloader::MOD_PNORACC_FINDTOC
+ * @reasoncode Bootloader::RC_LPC_ERR
+ * @userdata1[0:15] TI_WITH_SRC
+ * @userdata1[16:31] TI_BOOTLOADER
+ * @userdata1[32:63] Failing address = 0
+ * @userdata2[0:31] LPC error/status
+ * @userdata2[32:63] Error code
+ * @devdesc LPC error detected.
+ * @custdesc A problem occurred while running processor
+ * boot code.
+ */
+ bl_terminate(Bootloader::MOD_PNORACC_FINDTOC,
+ Bootloader::RC_LPC_ERR,
+ (*l_val),
+ o_errCode,
+ true);
+ break;
}
//Copy Table of Contents from PNOR flash to a local buffer
@@ -293,10 +286,24 @@ void bl_pnorAccess::findTOC(uint64_t i_lpcBar, PNOR::SectionData_t * o_TOC,
(g_blData->blToHbData.lpcBAR + LPC::LPCHC_FW_SPACE))
{
BOOTLOADER_TRACE_W_BRK(BTLDR_TRC_PA_FINDTOC_READTOC_ERR);
-
- // TI with data from readTOC
- terminateExecuteTI();
-
+ /*@
+ * @errortype
+ * @moduleid Bootloader::MOD_PNORACC_FINDTOC
+ * @reasoncode Bootloader::RC_TOC_NOT_FOUND_ERR
+ * @userdata1[0:15] TI_WITH_SRC
+ * @userdata1[16:31] TI_BOOTLOADER
+ * @userdata1[32:63] Failing address = 0
+ * @userdata2 MMIO Address
+ * @devdesc TOC not found
+ * @custdesc A problem occurred while running processor
+ * boot code.
+ */
+ bl_terminate(Bootloader::MOD_PNORACC_FINDTOC,
+ Bootloader::RC_TOC_NOT_FOUND_ERR,
+ // Extract the l_mmioAddr address among 2 - 32 bits
+ (l_mmioAddr >> 32),
+ l_mmioAddr,
+ true);
break;
}
}
diff --git a/src/bootloader/bootloader.C b/src/bootloader/bootloader.C
index eb1cb8743..2a2634055 100644
--- a/src/bootloader/bootloader.C
+++ b/src/bootloader/bootloader.C
@@ -46,7 +46,6 @@
#include <limits.h>
#include <securerom/ROM.H>
-#include <config.h>
#include <secureboot/secure_reasoncodes.H>
#include <p9_sbe_hb_structures.H>
@@ -555,10 +554,11 @@ namespace Bootloader{
writeScratchReg(MMIO_SCRATCH_HOSTBOOT_ACTIVE,
hostboot_string);
- //Determine if P9N or P9C and apply URMOR hack
+ //All variants of P9 need to apply URMOR hack
uint64_t l_urmor_hack_required = 0x0;
PVR_t l_pvr(getPVR());
- if((l_pvr.chipFamily == PVR_t::P9_ALL))
+ if((l_pvr.chipFamily == PVR_t::P9_ALL)
+ ||((l_pvr.chipFamily == PVR_t::P9_AXONE)))
{
l_urmor_hack_required = 1;
}
diff --git a/src/bootloader/makefile b/src/bootloader/makefile
index 1ff44222c..6d49d2bc1 100644
--- a/src/bootloader/makefile
+++ b/src/bootloader/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2015,2017
+# Contributors Listed Below - COPYRIGHT 2015,2019
# [+] International Business Machines Corp.
#
#
@@ -24,6 +24,9 @@
# IBM_PROLOG_END_TAG
ROOTPATH = ../..
+# Bootloader omitted from profiling to keep size down
+HOSTBOOT_PROFILE=
+
EXTRAINCDIR += ${ROOTPATH}/src/usr/pnor/
EXTRAINCDIR += ${ROOTPATH}/src/usr/lpc/
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/
diff --git a/src/build/beam/core/assert.C b/src/build/beam/core/assert.C
index c7186668f..183e1847d 100644
--- a/src/build/beam/core/assert.C
+++ b/src/build/beam/core/assert.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2014 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -20,5 +22,7 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+// cppcheck-suppress syntaxError
>>>ERROR5___assert_d9b551657c952063
+
>>>ERROR5___assert_941b08c17c952063
diff --git a/src/build/beam/core/pagemgr.C b/src/build/beam/core/pagemgr.C
index 54779d750..2cde4394d 100644
--- a/src/build/beam/core/pagemgr.C
+++ b/src/build/beam/core/pagemgr.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2014 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -20,5 +22,6 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+// cppcheck-suppress syntaxError
>>>MISTAKE5__initialize_7639026bb95510e7
>>>MISTAKE5__initialize_2d381016b95510e7
diff --git a/src/build/beam/core/stacksegment.C b/src/build/beam/core/stacksegment.C
index cfc2cf308..e7bd9eb21 100644
--- a/src/build/beam/core/stacksegment.C
+++ b/src/build/beam/core/stacksegment.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2014 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -20,4 +22,5 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+// cppcheck-suppress syntaxError
>>>ERROR8_~StackSegment_b791f4a2ac177b6
diff --git a/src/build/beam/hwp/mvpdRingFuncs.C b/src/build/beam/hwp/mvpdRingFuncs.C
index 5c113e990..50f58dc83 100644
--- a/src/build/beam/hwp/mvpdRingFuncs.C
+++ b/src/build/beam/hwp/mvpdRingFuncs.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -20,5 +22,6 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+// cppcheck-suppress syntaxError
>>>MISTAKE17_mbvpdValidateRecordKeyword_d149f58f1505
>>>MISTAKE5_mbvpdRingFunc_b48fca4f6c313e21
diff --git a/src/build/beam/i2c/i2c.C b/src/build/beam/i2c/i2c.C
index 6bc1a97f4..1d2632b8f 100644
--- a/src/build/beam/i2c/i2c.C
+++ b/src/build/beam/i2c/i2c.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2014 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -20,4 +22,6 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+// cppcheck-suppress syntaxError
>>>MISTAKE17_i2cSetupMasters_8697e17e1505
+
diff --git a/src/build/beam/prdf/prdfBitKey.C b/src/build/beam/prdf/prdfBitKey.C
index b1618ebe9..0d9d67938 100644
--- a/src/build/beam/prdf/prdfBitKey.C
+++ b/src/build/beam/prdf/prdfBitKey.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2014 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -20,5 +22,6 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+// cppcheck-suppress syntaxError
>>>MISTAKE17_operator==_f7028aed1505
>>>MISTAKE17_operator==_70cd34271505
diff --git a/src/build/beam/prdf/prdfPegasusConfigurator.C b/src/build/beam/prdf/prdfPegasusConfigurator.C
index 956ed90b2..e19a1b881 100644
--- a/src/build/beam/prdf/prdfPegasusConfigurator.C
+++ b/src/build/beam/prdf/prdfPegasusConfigurator.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2014 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -20,5 +22,6 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+// cppcheck-suppress syntaxError
>>>MISTAKE17_addPllDomainsToSystem_954f5e401505
>>>MISTAKE17_addPllDomainsToSystem_c01c04751505
diff --git a/src/build/beam/targeting/targetservice.C b/src/build/beam/targeting/targetservice.C
index 4e069351d..029876273 100644
--- a/src/build/beam/targeting/targetservice.C
+++ b/src/build/beam/targeting/targetservice.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -20,5 +22,6 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+// cppcheck-suppress syntaxError
>>>MISTAKE5_queryMasterProcChipTargetHandle_2745d8d11505
>>>MISTAKE5_queryMasterProcChipTargetHandle_da38b67e1505
diff --git a/src/build/buildpnor/PnorUtils.pm b/src/build/buildpnor/PnorUtils.pm
index 3a8d22df2..e5ecbb150 100644
--- a/src/build/buildpnor/PnorUtils.pm
+++ b/src/build/buildpnor/PnorUtils.pm
@@ -39,6 +39,7 @@ my $TRAC_ERR = 0;
my $g_trace = 1;
use XML::Simple;
+
################################################################################
# Set PREFERRED_PARSER to XML::Parser. Otherwise it uses XML::SAX which contains
# bugs that result in XML parse errors that can be fixed by adjusting white-
@@ -53,7 +54,8 @@ use constant PAGE_SIZE => 4096;
################################################################################
sub loadPnorLayout
{
- my ($i_pnorFile, $i_pnorLayoutRef, $i_physicalOffsets, $i_testRun) = @_;
+ my ($i_pnorFile, $i_pnorLayoutRef, $i_physicalOffsets, $i_testRun,
+ $i_outputLayoutLocation) = @_;
my $this_func = (caller(0))[3];
unless(-e $i_pnorFile)
@@ -90,6 +92,10 @@ sub loadPnorLayout
my $numOfSides = scalar (@{$metadataEl->{side}});
my $sideSize = ($imageSize)/($numOfSides);
+ my $currOffset = 0;
+ my $sectionNum = 0;
+ my $isStartingPartition = 1;
+
trace(2, " $this_func: metadata: imageSize = $imageSize, blockSize=$blockSize, arrangement = $arrangement, numOfSides: $numOfSides, sideSize: $sideSize, tocSize: $tocSize");
#determine the TOC offsets from the arrangement and side Information
@@ -170,9 +176,44 @@ sub loadPnorLayout
$physicalOffset = getNumber($physicalOffset);
$physicalRegionSize = getNumber($physicalRegionSize);
+ # if at first section, set starting offset
+ if ($isStartingPartition == 1)
+ {
+ $currOffset = $physicalOffset;
+ $isStartingPartition = 0;
+ }
+
+ # if physical offset does not exist, calculate it and create new element
+ my $hexOffset;
+ if ($physicalOffset == 0)
+ {
+ $physicalOffset = $currOffset;
+ $hexOffset = sprintf("0x%X", $physicalOffset);
+ trace(3, "$this_func: Calculated physicalOffset = $physicalOffset, for eyeCatch = $eyeCatch");
+ push @{$xml->{section}->[$sectionNum]->{physicalOffset}}, $hexOffset;
+ $currOffset = $currOffset + $physicalRegionSize;
+ }
+ else
+ {
+ # if sections overlap, throw error
+ if ($physicalOffset < $currOffset)
+ {
+ $hexOffset = sprintf("0x%X", $physicalOffset);
+ die "ERROR: Collision between sections detected at offset ".$hexOffset."";
+ }
+ $currOffset = $physicalOffset + $physicalRegionSize;
+ }
+ $sectionNum = $sectionNum + 1;
+
+ # align partition by minimum boundary
+ if ($currOffset % PAGE_SIZE != 0)
+ {
+ $currOffset = $currOffset + (PAGE_SIZE - $currOffset % PAGE_SIZE);
+ }
+
if($physicalRegionSize + $physicalOffset > $imageSize)
{
- die "ERROR: $this_func: Image size ($imageSize) smaller than $eyeCatch's offset + $eyeCatch's size (".($physicalOffset + $physicalRegionSize)."). Aborting! ";
+ die "ERROR: $this_func: Image size ($imageSize) smaller than ".$eyeCatch."'s offset + ".$eyeCatch."'s size (".($physicalOffset + $physicalRegionSize)."). Aborting! ";
}
if (exists $$i_pnorLayoutRef{sections}{$physicalOffset})
@@ -215,6 +256,42 @@ sub loadPnorLayout
checkForOverlap($i_pnorLayoutRef);
}
+ # Write xml with offsets to new file if $i_outputLayoutLocation
+ # argument is supplied
+ if (defined $i_outputLayoutLocation && $i_outputLayoutLocation ne "")
+ {
+ my $filename = basename($i_pnorFile, ".xml");
+ $filename = "${i_outputLayoutLocation}/${filename}WithOffsets.xml";
+
+ # writing to new file with error handling
+ eval
+ {
+ print XMLout($xml, RootName => "pnor", OutputFile => $filename);
+ 1;
+ }
+ or do
+ {
+ my $err = $@;
+ die "ERROR: $this_func: Failed to create new XML file with corrected offsets, error = $err";
+ };
+
+ # Write out a helper file for our simics scripts
+ print "\nlocation = " . ${i_outputLayoutLocation} . "\n";
+ my $simfilename = "${i_outputLayoutLocation}/simpnor.py";
+ open(SIM_FILE,'>',$simfilename) or die("($simfilename) could not be opened.");
+ print SIM_FILE "def hb_get_pnor_offset(partname):\n";
+ print SIM_FILE " toc_dict={}\n";
+ #Iterate over the <section> elements.
+ foreach my $sectionEl (@{$xml->{section}})
+ {
+ my $eyeCatch = $sectionEl->{eyeCatch}[0];
+ my $physicalOffset = $sectionEl->{physicalOffset}[0];
+ print SIM_FILE " toc_dict[\"$eyeCatch\"]=$physicalOffset\n";
+ }
+ print SIM_FILE " return toc_dict[partname]\n";
+ close SIM_FILE;
+ }
+
return 0;
}
@@ -353,6 +430,8 @@ sub checkSpaceConstraints
my %sectionHash = %{$$i_pnorLayoutRef{sections}};
+ print "Note: the following metrics are not a true representation of section utilization, since some sections are substantially padded before applying ECC\n";
+
for $key ( keys %{$i_binFiles})
{
my $filesize = -s $$i_binFiles{$key};
@@ -366,18 +445,17 @@ sub checkSpaceConstraints
my $eyeCatch = $sectionHash{$layoutKey}{eyeCatch};
my $physicalRegionSize = $sectionHash{$layoutKey}{physicalRegionSize};
- my $pctUtilized = sprintf("%.2f", $filesize / $physicalRegionSize * 100);
my $freeBytes = $physicalRegionSize - $filesize;
- print "$eyeCatch is $pctUtilized% utilized ($freeBytes of $physicalRegionSize bytes free)\n";
+ print "$eyeCatch section size: $physicalRegionSize, bytes used: $filesize, bytes unused: $freeBytes\n";
if($filesize > $physicalRegionSize)
{
# If this is a test run increase HBI size by PAGE_SIZE until all test
# cases fit
- if ($testRun && $eyeCatch eq "HBI")
+ if ( $testRun && ($eyeCatch eq "HBI") )
{
- print "$this_func: Adjusting HBI size - ran out of space for test cases\n";
- adjustHbiPhysSize(\%sectionHash, $layoutKey, $filesize);
+ print "Adjusting HBI size - ran out of space for test cases\n";
+ adjustSecPhysSize(\%sectionHash, $layoutKey, $filesize);
}
else
{
@@ -388,36 +466,43 @@ sub checkSpaceConstraints
trace(1, "Done checkSpaceConstraints");
}
-
-###############################################################################
-# adjustHbiPhysSize - Adjust HBI physical size when running test cases and fix
-# up physical offsets of partitions after it
-################################################################################
-sub adjustHbiPhysSize
+# sub adjustSecPhysSize
+#
+# Adjust section physical size when running test cases and fix up physical
+# offsets between partitions (for example HBI and all partitions that follow)
+#
+# @param [in] i_sectionHashRef - PNOR layout as a hash table reference
+# @param [in] i_initPartKey - key of initial partition whose physical size will
+# be adjusted
+# @param [in] i_filesize - final file size of partition (note: actual final size
+# may be larger than this as the size is adjusted by increments of PAGE_SIZE)
+# @return - N/A
+#
+sub adjustSecPhysSize
{
- my ($i_sectionHashRef, $i_hbiKey, $i_filesize) = @_;
+ my ($i_sectionHashRef, $i_initPartKey, $i_filesize) = @_;
my $this_func = (caller(0))[3];
my %sectionHash = %$i_sectionHashRef;
- # Increment HBI physical size by PAGE_SIZE until the HBI file can fit
- my $hbi_old = $sectionHash{$i_hbiKey}{physicalRegionSize};
- while ($i_filesize > $sectionHash{$i_hbiKey}{physicalRegionSize})
+ # Increment initial partition physical size by PAGE_SIZE until the initial
+ # partition file can fit
+ my $initPart_old = $sectionHash{$i_initPartKey}{physicalRegionSize};
+ while ($i_filesize > $sectionHash{$i_initPartKey}{physicalRegionSize})
{
- $sectionHash{$i_hbiKey}{physicalRegionSize} += PAGE_SIZE;
+ $sectionHash{$i_initPartKey}{physicalRegionSize} += PAGE_SIZE;
}
- my $hbi_move = $sectionHash{$i_hbiKey}{physicalRegionSize} - $hbi_old;
- my $hbi_end = $sectionHash{$i_hbiKey}{physicalRegionSize} + $hbi_move;
+ my $initPart_move = $sectionHash{$i_initPartKey}{physicalRegionSize} - $initPart_old;
- # Fix up physical offset affected by HBI size change
+ # Fix up physical offsets affected by initial partition size change
foreach my $section (keys %sectionHash)
{
- # Only fix partitions after HBI
+ # Only fix partitions after initial partition
if ( $sectionHash{$section}{physicalOffset} >
- $sectionHash{$i_hbiKey}{physicalOffset} )
+ $sectionHash{$i_initPartKey}{physicalOffset} )
{
my $origoffset = $sectionHash{$section}{physicalOffset};
- $sectionHash{$section}{physicalOffset} += $hbi_move;
+ $sectionHash{$section}{physicalOffset} += $initPart_move;
trace(3, "$this_func: Section $sectionHash{$section}{eyeCatch} : " . sprintf("%X",$origoffset) . " --> " . sprintf("%X",$sectionHash{$section}{physicalOffset}));
}
else
@@ -562,7 +647,6 @@ sub checkForOverlap
}
}
-
###############################################################################
# Display Pnor Layout - Display XML pnor layout more simply
################################################################################
diff --git a/src/build/buildpnor/bpm-utils/LICENSE_PROLOG b/src/build/buildpnor/bpm-utils/LICENSE_PROLOG
new file mode 100644
index 000000000..e57b55f75
--- /dev/null
+++ b/src/build/buildpnor/bpm-utils/LICENSE_PROLOG
@@ -0,0 +1,24 @@
+This is an automatically generated prolog.
+
+$SOURCE_BEGIN_TAG $filename $SOURCE_END_TAG
+
+OpenPOWER $projectName Project
+
+$copyrightStr $copyrightYear
+$copyright_Contributors
+
+Copyright (c) 2019 SMART Modular Technologies, Inc.
+All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
diff --git a/src/build/buildpnor/bpm-utils/imageCrc.c b/src/build/buildpnor/bpm-utils/imageCrc.c
new file mode 100644
index 000000000..8df98a2d3
--- /dev/null
+++ b/src/build/buildpnor/bpm-utils/imageCrc.c
@@ -0,0 +1,479 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/build/buildpnor/bpm-utils/imageCrc.c $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Copyright (c) 2019 SMART Modular Technologies, Inc. */
+/* All Rights Reserved. */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
+/* See the License for the specific language governing permissions and */
+/* limitations under the License. */
+/* */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+//#define DEBUG
+
+//
+// The BPM / SCAP firmware images always will be in one of
+// the two address ranges:
+//
+// Range:(0xA000 - 0xFFFF). Start = 0xA000; Length = 0x6000 (24K)
+// Range:(0x8000 - 0xFFFF). Start = 0x8000; Length = 0x8000 (32K)
+//
+#define FW_MAINIMAGE_START_ADDRESS_8000 (0x8000)
+#define FW_MAINIMAGE_START_ADDRESS_A000 (0xA000)
+#define FW_MAINIMAGE_LAST_ADDRESS (0xFFFF)
+
+//
+// Maximum possible length of the firmware image
+//
+#define FW_MAINIMAGE_MAX_LENGTH (0x8000)
+#define CRC_SIGNATURE_LO (0xAA)
+#define CRC_SIGNATURE_HI (0x55)
+
+#define ADDRESS_CRC_SIGNATURE (0xFF7A) // @FF7A = 0xAA, @FF7B = 0x55
+#define ADDRESS_IMAGE_START (0xFF7C) // @FF7C = Start_Lo, @FF7D = Start_Hi
+#define ADDRESS_IMAGE_CRC (0xFF7E) // @FF7E = CRC_Lo, @FF7F = CRC_Hi
+#define ADDRESS_RESET_VECTOR (0xFFFE) // @FFFE, FFFF
+#define LENGTH_IMAGE_CRC (0x2)
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+
+typedef struct _CRC_CONTEXT {
+ uint16_t mainImageStartAddress;
+ uint16_t mainImageTotalLength;
+} CRC_CONTEXT;
+
+typedef struct _OFFSET_LIST {
+ uint32_t count;
+ uint32_t offset[4];
+} OFFSET_LIST;
+
+char* readNextHex(const char* pLine, uint32_t *value);
+
+uint16_t resetCrc(void);
+
+uint16_t updateCrc(uint8_t byte);
+
+uint16_t calculateCrc(uint8_t* pData, int length);
+
+bool
+parseLine(const char* pLine,
+ uint32_t *mMemoryAddress,
+ CRC_CONTEXT *context,
+ uint8_t *mainImageData);
+
+uint16_t mCrc = 0;
+
+void
+dumpImageData(uint8_t *data, uint32_t dataLength, OFFSET_LIST *offsetToSkipList)
+{
+ bool dontPrint = false;
+
+ uint32_t i, c;
+ uint32_t offsetToSkipCount = 0;
+
+ if (offsetToSkipList != NULL) {
+ offsetToSkipCount = offsetToSkipList->count;
+ }
+
+ printf("MainImageData:\n");
+
+ for (i = 1; i < dataLength - 1; ++i) {
+
+ //
+ // Don't print some of the offsets, when requested
+ //
+ dontPrint = false;
+ for (c = 0; c < offsetToSkipCount; c++) {
+ if ((i - 1) == offsetToSkipList->offset[c]) {
+ dontPrint = true;
+ break;
+ }
+ }
+
+ if (dontPrint) {
+ printf(" ");
+ } else {
+ printf(" %02x", data[i - 1]);
+ }
+
+ if ((i % 16) == 0) {
+ printf("\n");
+ }
+ }
+
+ printf("\n");
+}
+
+uint16_t
+resetCrc(void)
+{
+ mCrc = 0xFFFF;
+ return mCrc;
+}
+
+uint16_t
+updateCrc(uint8_t byte)
+{
+ bool x;
+ int i;
+
+ for (i = 0; i < 8; ++i) {
+ x = ((mCrc & 0x8000 ? 1 : 0) ^ (byte & 0x80 ? 1 : 0)) ? true : false;
+ mCrc <<= 1;
+ if (x)
+ mCrc ^= 0x1021;
+ byte <<= 1;
+ }
+ return mCrc;
+}
+
+uint16_t
+calculateCrc(uint8_t* pData, int length)
+{
+ //resetCrc();
+ for (; length; --length, ++pData) {
+ updateCrc(*pData);
+ }
+ return mCrc;
+}
+
+char*
+readNextHex(const char* pLine, uint32_t *pValue)
+{
+ uint32_t value = 0;
+
+ // Skip leading white space
+ while (*pLine != '\0' && *pLine <= ' ') {
+ ++pLine;
+ }
+
+ if (*pLine == '\0')
+ return NULL;
+
+ while (true) {
+ if (*pLine >= '0' && *pLine <= '9') {
+ value <<= 4;
+ value += *pLine - '0';
+ } else if (*pLine >= 'a' && *pLine <= 'f') {
+ value <<= 4;
+ value += 0xa + *pLine - 'a';
+ } else if (*pLine >= 'A' && *pLine <= 'F') {
+ value <<= 4;
+ value += 0xA + *pLine - 'A';
+ } else {
+ break;
+ }
+ ++pLine;
+ }
+
+ *pValue = value;
+ return (char*)pLine;
+}
+
+bool
+parseLine(const char* pLine,
+ uint32_t *mMemoryAddress,
+ CRC_CONTEXT *context,
+ uint8_t *mainImageData)
+{
+ uint8_t data[0x100];
+ int dataLength = 0;
+ uint32_t value;
+
+ uint32_t offsetToCopy = 0;
+#ifdef DEBUG
+ int i;
+#endif
+
+ if (*pLine == '@') {
+ // This is a memory address
+ if (readNextHex(pLine + 1, &value) != NULL) {
+ *mMemoryAddress = (uint16_t) value;
+#ifdef DEBUG
+ printf("@Memory Address: 0x%x\n", *mMemoryAddress);
+#endif // DEBUG
+
+ //
+ // Initialize the Context when the firmware image
+ // start address is detected.
+ //
+ if ((*mMemoryAddress == FW_MAINIMAGE_START_ADDRESS_8000) ||
+ (*mMemoryAddress == FW_MAINIMAGE_START_ADDRESS_A000)) {
+
+ context->mainImageStartAddress = value;
+ context->mainImageTotalLength = (FW_MAINIMAGE_LAST_ADDRESS - value) + 1;
+
+ printf("Context: Image Start Address = 0x%x; Image Length = %d (0x%x) \n",
+ context->mainImageStartAddress, context->mainImageTotalLength, context->mainImageTotalLength);
+ }
+ }
+
+ } else if (*pLine == 'q' || *pLine == 'Q') {
+#ifdef DEBUG
+ printf("Done\n");
+ printf("Memory Address: 0x%x\n", *mMemoryAddress);
+#endif // DEBUG
+ return true;
+ } else {
+ do {
+ pLine = readNextHex(pLine, &value);
+
+ if (pLine != NULL) {
+ data[dataLength++] = value;
+ }
+
+ } while (pLine != NULL);
+
+ if (dataLength & 1) {
+ // Keep even byte alignment by padding
+ data[dataLength++] = 0xFF;
+ }
+
+#ifdef DEBUG
+ printf("Write data (%04x) dataLength (0x%x):",
+ *mMemoryAddress, dataLength);
+ for (i = 0; i < dataLength; ++i) {
+ printf(" %02x", data[i]);
+ }
+ printf("\n");
+#endif // DEBUG
+
+ //
+ // added by rananth to calculate the CRC of the main image data.
+ //
+ if ((*mMemoryAddress >= context->mainImageStartAddress) &&
+ (*mMemoryAddress <
+ (context->mainImageStartAddress + context->mainImageTotalLength)))
+ {
+
+ if ( (context->mainImageStartAddress != 0)
+ && (context->mainImageTotalLength != 0) &&
+ (mainImageData != NULL)) {
+
+ //
+ // Copy the main image data bytes (Range: @8000, 0x8000) to the
+ // passed in data buffer.
+ //
+ offsetToCopy = *mMemoryAddress - context->mainImageStartAddress;
+ memcpy(mainImageData + offsetToCopy, data, dataLength);
+
+#ifdef DEBUG
+ printf("Copy data (%04x) dataLength (0x%x):",
+ offsetToCopy, dataLength);
+ printf("\n");
+#endif // DEBUG
+
+ }
+ }
+
+ *mMemoryAddress += dataLength;
+ }
+
+ return true;
+}
+
+
+int
+ProcessFile(char *pFilename, bool verbose)
+{
+ char buffer[0x100];
+ int length;
+ int line;
+
+ uint8_t *mainImageData = 0;
+
+ uint32_t mMemoryAddress = 0;
+ uint32_t crc = 0;
+ uint32_t offsetToSkip;
+ uint32_t offsetToInsert;
+ uint32_t firstPortion = 0;
+ uint32_t secondPortion = 0;
+
+ CRC_CONTEXT context;
+ OFFSET_LIST offsetList;
+
+ // Count the number of lines in the file and use that for progress
+ FILE* pFile = fopen(pFilename, "r");
+ if (!pFile) {
+ printf("Unable to open file %s\n", pFilename);
+ return false;
+ }
+ for (line = 0; !feof(pFile); ++line) {
+ if (fgets(buffer, sizeof(buffer), pFile) == NULL) {
+ break;
+ }
+ }
+
+
+ // Rewind to the beginning of the file
+ fseek(pFile, 0, SEEK_SET);
+
+ //
+ // allocate memory for the main image data
+ //
+ mainImageData = (uint8_t *) malloc(FW_MAINIMAGE_MAX_LENGTH);
+ memset(mainImageData, 0xFF, FW_MAINIMAGE_MAX_LENGTH);
+
+ memset(&context, 0, sizeof(CRC_CONTEXT));
+
+ // Process the lines
+ for (line = 0; !feof(pFile); ++line) {
+ if (fgets(buffer, sizeof(buffer), pFile) == NULL) {
+ break;
+ }
+
+ length = strlen(buffer);
+
+ // Strip off any terminating carriage return/line feed
+ for (; length > 0 && buffer[length - 1] < ' '; --length);
+ buffer[length] = '\0';
+
+ if ( !parseLine((const char*) buffer,
+ &mMemoryAddress,
+ &context,
+ mainImageData) ) {
+ printf("False returned by parseLine \n");
+ break;
+ }
+ }
+
+ if (verbose) {
+
+ printf("==============================================\n");
+ printf("Dump & CRC before selective skip (@FF7E, 2) (@FFFE, 2) \n");
+ printf("==============================================\n");
+
+ dumpImageData(mainImageData, context.mainImageTotalLength, NULL);
+
+ crc = calculateCrc(mainImageData, context.mainImageTotalLength);
+
+ printf("Total Length = %d (0x%x). Final CRC = 0x%x \n",
+ context.mainImageTotalLength, context.mainImageTotalLength, crc);
+
+ }
+
+ //
+ // Insert the Signature (if not already present)
+ //
+ offsetToInsert = ADDRESS_CRC_SIGNATURE - context.mainImageStartAddress;
+ if (mainImageData[offsetToInsert] != CRC_SIGNATURE_LO) {
+ mainImageData[offsetToInsert] = CRC_SIGNATURE_LO;
+ }
+
+ if (mainImageData[offsetToInsert + 1] = CRC_SIGNATURE_HI) {
+ mainImageData[offsetToInsert + 1] = CRC_SIGNATURE_HI;
+ }
+
+ offsetToInsert = ADDRESS_IMAGE_START - context.mainImageStartAddress;
+ mainImageData[offsetToInsert] = (context.mainImageStartAddress & 0xFF); // Lo Byte
+ mainImageData[offsetToInsert + 1] = (context.mainImageStartAddress & 0xFF00) >> 8; // Hi Byte
+
+ //
+ // Skip the following locations for CRC calculation.
+ //
+ // 1. @FF7E, 2
+ // 2. @FFFE, 2
+ //
+ offsetToSkip = ADDRESS_IMAGE_CRC - context.mainImageStartAddress;
+ mainImageData[offsetToSkip] = 0xFF;
+ mainImageData[offsetToSkip + 1] = 0xFF;
+
+ offsetToSkip = ADDRESS_RESET_VECTOR - context.mainImageStartAddress;
+ mainImageData[offsetToSkip] = 0xFF;
+ mainImageData[offsetToSkip + 1] = 0xFF;
+
+ printf("\n");
+ printf("====================================================================================\n");
+ printf("Dump & CRC after Insert (@FF7A, 2) (@FF7C, 2) & Selective skip (@FF7E, 2) (@FFFE, 2) \n");
+ printf("====================================================================================\n");
+
+ memset(&offsetList, 0, sizeof(OFFSET_LIST));
+ offsetList.count = 4;
+ offsetList.offset[0] = ADDRESS_IMAGE_CRC - context.mainImageStartAddress;
+ offsetList.offset[1] = ADDRESS_IMAGE_CRC - context.mainImageStartAddress + 1;
+ offsetList.offset[2] = ADDRESS_RESET_VECTOR - context.mainImageStartAddress;
+ offsetList.offset[3] = ADDRESS_RESET_VECTOR - context.mainImageStartAddress + 1;
+
+ if (verbose) {
+ dumpImageData(mainImageData, context.mainImageTotalLength, &offsetList);
+ }
+
+ // Reset
+ resetCrc();
+
+ firstPortion = ADDRESS_IMAGE_CRC - context.mainImageStartAddress;
+ secondPortion = ADDRESS_RESET_VECTOR - (ADDRESS_IMAGE_CRC + LENGTH_IMAGE_CRC);
+
+ printf("firstPortion: Start = 0x%x Length = %d (0x%x)\n", 0, firstPortion, firstPortion);
+ printf("secondPortion: Start = 0x%x Length = %d (0x%x)\n", firstPortion + 2, secondPortion, secondPortion);
+
+ crc = calculateCrc(mainImageData, firstPortion);
+ crc = calculateCrc(mainImageData + firstPortion + 2, secondPortion);
+
+ printf("Total Length = %d (0x%x). Final CRC = 0x%x \n",
+ (firstPortion + secondPortion), (firstPortion + secondPortion), crc);
+
+ //
+ // Generate the CRC signature lines to be inserted to the firmware image file
+ //
+ printf("---\n");
+ printf("@%x\n", ADDRESS_CRC_SIGNATURE);
+ printf("%02x %02x %02x %02x %02x %02x \n",
+ mainImageData[ADDRESS_CRC_SIGNATURE - context.mainImageStartAddress],
+ mainImageData[ADDRESS_CRC_SIGNATURE - context.mainImageStartAddress + 1],
+ mainImageData[ADDRESS_IMAGE_START - context.mainImageStartAddress],
+ mainImageData[ADDRESS_IMAGE_START - context.mainImageStartAddress + 1],
+ (crc & 0xFF),
+ ((crc & 0xFF00) >> 8));
+ printf("---\n");
+
+
+ free(mainImageData);
+ fclose(pFile);
+}
+
+
+int main(int argc, char *argv[])
+{
+ bool verbose = false;
+
+ if (argc < 2) {
+ printf("Usage: %s <filename> [-v]\n", argv[0]);
+ return -1;
+ }
+
+ if (argc > 2) {
+ if (!strcmp(argv[2], "-v")) {
+ verbose = true;
+ }
+ }
+
+ printf("Processing %s. Verbose=%d \n", argv[1], verbose);
+
+ resetCrc();
+ ProcessFile(argv[1], verbose);
+ return 0;
+}
diff --git a/src/build/buildpnor/bpm-utils/insertBpmFwCrc.py b/src/build/buildpnor/bpm-utils/insertBpmFwCrc.py
new file mode 100755
index 000000000..0631ec5d2
--- /dev/null
+++ b/src/build/buildpnor/bpm-utils/insertBpmFwCrc.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/buildpnor/bpm-utils/insertBpmFwCrc.py $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Copyright (c) 2019 SMART Modular Technologies, Inc.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+# IBM_PROLOG_END_TAG
+
+import os, sys, time, datetime, glob
+from subprocess import Popen, PIPE
+import shlex
+
+#
+# Function to insert the CRC signature in the
+# firmware image file, inFile, and to generate the
+# signature file, outFile.
+#
+def InsertCrcSignature(inFile, outFile, crcProgram):
+
+ #
+ # Open the outFile
+ #
+ try:
+ print("\nOpening outFile = %s" % outFile)
+ outFileObj = open(outFile, "w")
+ except Exception as e:
+ print "\nException {0} occured, args: {1!r}".format(type(e).__name__, e.args)
+ sys.exit(999)
+
+ #
+ # Read from the inFile and copy the data to the outFile.
+ #
+ # At the right address, insert the SignatureFile data
+ # @FF7A
+ # AA 55 [Start_Lo] [Start_Hi] [Crc_Lo] [Crc_Hi]
+ #
+ # generated from the imageCrc tool, to the outFile.
+ #
+ # The address insertion has to be in the proper ascending order of
+ # addresses given in the inFile in to the outFile.
+ #
+ # For example the outFile should have the following:
+ # =================================================
+ # ...
+ # @8000 / @A000 << The firmware start address is always either one of them.
+ # ....
+ # ....
+ # @FF7A <<<< The "@" addresses must be in ascending order in the Firmware Image file.
+ # AA 55 [Start_Lo] [Start_Hi] [Crc_Lo] [Crc_Hi]
+ #
+ # ....
+ # @FFDA
+ # ....
+
+ # Call imageCrc here
+ proc = Popen([crcProgram, inFile], stdout=PIPE, stderr=PIPE)
+ out,err = proc.communicate()
+ exitCode = proc.returncode
+
+ if exitCode:
+ print "\nCRC generation using imageCrc utility for {0} failed, below are stdout and stderr".format(inFile)
+ print "Command stdout - \n{0}".format(out)
+ print "Command stderr - \n{0}".format(err)
+ sys.exit(999)
+ else:
+ print "\nCRC generation using imageCrc utility successful"
+ print "Command output - \n{0}".format(out)
+
+ # Parse through output of imageCrc and get addr and signature
+ splitLines_crc = out.splitlines()
+ for counter in range(0, len(splitLines_crc)):
+
+ if splitLines_crc[counter].startswith("@"):
+ crcAddressLine = splitLines_crc[counter]
+ crcSignature = splitLines_crc[counter+1].strip().upper()
+
+ # Open infile here
+ # Keep reading infile lines, when read address > the address in signature,
+ # insert signature there
+ try:
+ crcWritten = 0
+ print("\nOpening inFile = %s and writing to outFile now..." % inFile)
+ with open(inFile, "r") as ins:
+ #
+ # TODO: Have the logic to insert the signature from the
+ # SignatureFile inserted at the correct location in the
+ # outFile.
+ #
+
+ for line in ins:
+ if line.startswith("@"):
+ inputFileAddr = line.strip()
+ # If crc already in input file, check if it is equal to calculate value
+ # If equal, write only once, if not equal, write calculated value
+ if crcWritten == 0 and inputFileAddr == crcAddressLine:
+ outFileObj.write(line.strip()+' \n')
+ if ins.next().upper() == crcSignature:
+ print "Correct crc already present at {0} in input file, will skip writing calculated crc again to output file".format(inputFileAddr)
+ else:
+ print "Incorrect crc present at {0} in input file, will write calculated crc {1} to output file".format(inputFileAddr, crcSignature)
+ outFileObj.write(crcSignature+' \n')
+ crcWritten = 1
+ continue
+ # If crc not present, then write calculated value
+ elif crcWritten == 0 and inputFileAddr > crcAddressLine:
+ outFileObj.write(crcAddressLine+'\n')
+ outFileObj.write(crcSignature+' \n')
+ crcWritten = 1
+ outFileObj.write(inputFileAddr.strip()+'\n')
+ else:
+ outFileObj.write(line.strip()+' \n')
+
+ except Exception as e:
+ print "\nException {0} occured, args: {1!r}".format(type(e).__name__, e.args)
+ sys.exit(999)
+
+ print("\nClosing Files\n")
+ outFileObj.close()
+
+## End of insertCrcSignature #########
+
+
+#
+# Main
+#
+if __name__ == '__main__':
+
+ inFile=""
+ outFile=""
+ crcProgram=""
+
+ if (len(sys.argv) < 4):
+ print "\nUsage: %s <IN FILE> <OUT FILE> <CRC PROGRAM>\n" % sys.argv[0]
+ sys.exit(1)
+ else:
+ #
+ # Name of the firmware image file without the signature
+ #
+ inFile = sys.argv[1]
+ if '/' not in inFile:
+ inFile = os.getcwd() + '/' + inFile
+
+ if not os.path.exists(inFile) or os.path.getsize(inFile) == 0:
+ print "\nInput File {0} does not exist or is zero in size".format(inFile)
+ #
+ # Name of the firmware image file to be generated with the signature
+ #
+ outFile = sys.argv[2]
+ if '/' not in outFile:
+ outFile = os.getcwd() + '/' + outFile
+
+ if os.path.exists(outFile):
+ print "\nOutput File {0} already exists, will be overwritten".format(outFile)
+
+ #
+ # Name of the CRC calculation program to be used to calculate the
+ # firmware image CRC
+ #
+ crcProgram = sys.argv[3]
+ if '/' not in crcProgram:
+ crcProgram = os.getcwd() + '/' + crcProgram
+
+ if not os.path.exists(crcProgram) or os.path.getsize(crcProgram) == 0:
+ print "\nCRC Program {0} does not exist or is zero in size".format(crcProgram)
+
+ #
+ # Call the function to insert the CRC signature
+ #
+ InsertCrcSignature(inFile, outFile, crcProgram)
diff --git a/src/build/buildpnor/buildBpmFlashImages.pl b/src/build/buildpnor/buildBpmFlashImages.pl
new file mode 100755
index 000000000..72219e3d9
--- /dev/null
+++ b/src/build/buildpnor/buildBpmFlashImages.pl
@@ -0,0 +1,878 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/buildpnor/buildBpmFlashImages.pl $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+use strict;
+use warnings;
+use File::Basename;
+use Getopt::Long;
+use Pod::Usage;
+
+my $progName = File::Basename::basename $0;
+my $outputDir=".";
+my $bpmUtilScript="./bpm-utils/insertBpmFwCrc.py";
+my $bpmCrcProgram="./bpm-utils/imageCrc";
+my @files;
+my $cfgHelp=0;
+my $cfgMan=0;
+my $verbose=0;
+
+GetOptions("output-dir=s" => \$outputDir,
+ "bpm-util-script=s" => \$bpmUtilScript,
+ "bpm-crc-program=s" => \$bpmCrcProgram,
+ "image=s" => \@files,
+ "help" => \$cfgHelp,
+ "verbose" => \$verbose,
+ "man" => \$cfgMan ) || pod2usage(-verbose => 0);
+
+pod2usage(-verbose => 1) if $cfgHelp;
+pod2usage(-verbose => 2) if $cfgMan;
+
+# Verify that there aren't any duplicate files in the array of input file names.
+# This is done by creating an anonymous hash of all the file names and comparing
+# the number of keys in the hash to the number of files in @files. If they are
+# not equal then there is a duplicate file of the same name in the input file
+# array.
+if (keys %{{ map {$_, 1} @files }} != @files)
+{
+ die "One or more non-unique --image arguments supplied";
+}
+
+# Verify that there are no duplicate image files of different versions in the
+# input --image arguments. This is done by creating an anonymous hash of all the
+# output file names that would be generated based on the images given and then
+# comparing the number of keys in that hash to the number of original file
+# names. If the number keys and elements of @files aren't equal then there are
+# two images for the same NVDIMM type of different versions present in the
+# input and this is not allowed.
+if (keys %{{map { (generateOutputNameAndVersion($_))[0], 1} @files}} != @files)
+{
+ die "One or more --image arguments are different versions of the same ".
+ "image. Please remove the unused versions.";
+}
+
+if($verbose)
+{
+ print "Output dir = $outputDir\n";
+ print "Input images:\n";
+}
+
+for my $file (@files)
+{
+ if ($verbose)
+ {
+ print " $file\n";
+ }
+
+ generateConfigImage($file,$outputDir);
+ generateFirmwareImage($file,$outputDir);
+}
+
+################################################################################
+# @brief Processes an input file to pull information from its name and content
+# to be used when preparing the output file's binary image. This function
+# will only emit the binaries for the firmware portion of the BPM update.
+# The final binary will be organized in the following way:
+# Byte 1: Major version number (MM)
+# Byte 2: Minor version number (mm)
+# Byte 3-4: N number of blocks in the file (NN NN)
+# Byte 5-EOF: Blocks of the form:
+# BLOCK_SIZE Byte 1: X number of bytes in block excluding
+# this byte. (XX)
+# ADDRESS_OFFSET Byte 2-3: Original address offset of the
+# first data byte. (AD DR)
+# DATA_BYTES Byte 4-X: Firmware data bytes (DD)
+#
+# Example file output:
+# 01 03 00 01 06 80 00 6a 14 31 80
+# MM mm NN NN XX AD DR DD DD DD DD
+#
+# @param[in] i_fileName Name of file
+# @param[in] i_outputDir Dir to emit binary to
+#
+# @return N/A
+################################################################################
+sub generateFirmwareImage
+{
+ my ($i_fileName, $i_outputDir) = @_;
+ my $this_func = (caller(0))[3];
+
+ my $intermediateFileName = generateIntermediateImage($i_fileName,$i_outputDir);
+
+ open my $inputFileHandle, '<:encoding(UTF-8)', $intermediateFileName
+ or die "Failed to open $intermediateFileName";
+
+ my ($name, @version) = generateOutputNameAndVersion($i_fileName);
+
+ my $imageFile = $i_outputDir . "/" . $name . "FW.bin";
+
+ open my $outputFileHandle, '>:raw', $imageFile
+ or die "Failed to open $imageFile";
+
+ # Indicates whether or not we're in the firmware section of the image file.
+ my $inFirmwareSection = undef;
+
+ # Keep track of the number of blocks we'll be writing to the output file.
+ my $numberOfBlocks = 0;
+
+ # This is the starting address of the first byte of the payload data.
+ my $currentAddress = 0;
+
+ # The address offsets in the file are prefixed with the @ symbol.
+ use constant ADDRESS_LINE => "\@";
+ use constant FW_START_ADDRESS_8000 => "\@8000";
+ use constant FW_START_ADDRESS_A000 => "\@A000";
+
+ # Spec for BPM updates says that the maximum size for the data portion of
+ # the payload is 16 bytes
+ use constant MAXIMUM_DATA_BYTES_FOR_PAYLOAD => 16;
+
+ # Ensure that the diamond operator ( <> ) is searching for \n to determine
+ # where the end of a line is in the image file.
+ local $/ = "\n";
+
+ my $blocks = undef;
+ while (my $line = <$inputFileHandle>)
+ {
+ # Strip off the end-of-line character \n and optionally \r if it exists.
+ # Since the image files were created on a windows OS and this script
+ # runs on linux this will not be handled properly by chomp.
+ $line =~ s/\r?\n$//;
+
+ # The end of the firmware data section is marked by a 'q'
+ if (substr($line, 0, 1) eq "q")
+ {
+ last;
+ }
+
+ # There are two possible addresses where the firmware data section can
+ # start: @8000 or @A000. Ignore all data until we reach either of those
+ # addresses since it's only after that, that the firmware data begins.
+ if (substr($line, 0, 1) eq ADDRESS_LINE)
+ {
+ $currentAddress = hex substr($line, 1, 4);
+ if ($verbose)
+ {
+ printf("Found address offset: 0x%04x\n", $currentAddress);
+ }
+
+ if ( ($line eq FW_START_ADDRESS_8000)
+ || ($line eq FW_START_ADDRESS_A000))
+ {
+ $inFirmwareSection = 1;
+ }
+ next;
+ }
+
+ # Don't process lines that aren't firmware data.
+ if (not $inFirmwareSection)
+ {
+ next;
+ }
+
+ # Process the line into blocks of the form: size, address offset, bytes
+ # Size: The size of the block.
+ # Note: The size here is only the size of the block itself. It does not
+ # have any correspondence to the final payload size which will be
+ # calculated during payload construction in hostboot code.
+ # Address offset: The address offset of the first byte of payload data.
+ # This will be reused during payload construction in
+ # hostboot code.
+ # Bytes: The payload data. This is the firmware data to be written to
+ # the BPM.
+
+ # The length of the payload data. The maximum size of payload data is 16
+ # bytes which is conveniently the maximum size of any line in the file
+ # minus spaces and carriage return/line feeds.
+ my $dataLength = calculateDataLength($line);
+
+ if ($dataLength > MAXIMUM_DATA_BYTES_FOR_PAYLOAD)
+ {
+ die "$dataLength exceeds the maximum size for the data portion of" .
+ "the payload (". MAXIMUM_DATA_BYTES_FOR_PAYLOAD .")";
+ }
+
+ # total size of the block is the number of bytes from the dataLength
+ # plus two more for the address size.
+ my $blockSize = $dataLength + 2;
+
+ # Pack the block size
+ # uint8_t
+ $blocks .= pack("C", $blockSize);
+
+ # Pack the starting address offset of the firmware data bytes
+ # uint16_t
+ $blocks .= pack("n", $currentAddress);
+
+ # Pack the payload data.
+ # Since the line is a string where each byte is an ASCII representation
+ # of the hex data separated by spaces, we must split the line by the
+ # space character and then write each byte string one at a time. Hence,
+ # the template "(H2)*". Each element is processed with the H2 part and
+ # the * just says to do this for all elements in the array emitted by
+ # split.
+ $blocks .= pack("(H2)*", split(/ /, $line));
+
+ # Increment the address offset by the number of firmware data
+ # bytes processed.
+ $currentAddress += $dataLength;
+
+ ++$numberOfBlocks;
+ }
+
+ if ($verbose)
+ {
+ print "number of blocks: $numberOfBlocks\n";
+ }
+
+ if (!defined($blocks))
+ {
+ die "Unable to process image file: $intermediateFileName";
+ }
+
+ # Write the version information to the file.
+ print $outputFileHandle pack("(H2)*", @version)
+ or die "Failed to write to output file: $imageFile";
+
+ # Write the number of blocks in the file.
+ # uint16_t
+ print $outputFileHandle pack("n", $numberOfBlocks)
+ or die "Failed to write to output file: $imageFile";
+
+ # Write the blocks to the file
+ print $outputFileHandle $blocks
+ or die "Failed to write to output file: $imageFile";
+
+ close $inputFileHandle
+ or die "Failed to close input file: $intermediateFileName";
+ unlink $intermediateFileName
+ or die "Failed to remove temporary file $intermediateFileName";
+ close $outputFileHandle
+ or die "Failed to close output file: $imageFile";
+}
+
+################################################################################
+# @brief Processes an input file to pull information from its name and content
+# to be used when preparing the output file's binary image. This function
+# will only emit the binaries for the configuration data portion of the
+# BPM update.
+# The final binary will be organized in the following way:
+# Byte 1: Major version number (MM)
+# Byte 2: Minor version number (mm)
+# Byte 3: N number of fragments in the file (NN)
+# Byte 4-EOF: Fragments of the form:
+# FRAGMENT_SIZE Byte 1: X number of bytes in fragment data
+# section. (XX)
+# INDEX_OFFSET Byte 2-3: Each BPM's config section is unique
+# to itself. So, during update the
+# contents of a BPM's config data
+# will be dumped into a buffer.
+# These bytes will be used as an
+# offset into that buffer from which
+# overwritting will take place.
+# (IN DX)
+# DATA_BYTES Byte 4-X: Configuration data bytes (DD)
+#
+# Example file output:
+# 01 05 01 04 01 28 6a 14 31 80
+# MM mm NN XX IN DX DD DD DD DD
+#
+# @algorithm Each BPM has a config data section unique to itself so the data
+# on each BPM must be dumped into a buffer and then "merged" with
+# the config data from the update. The config data section is
+# divided into 4 segments. A, B, C, and D. These segments appear
+# in reverse order. Since it is known which "fragments" of each
+# segment has to be updated this function will extract those
+# fragments from the update file and organize them as described
+# above so that hostboot can handle the rest.
+#
+# SegmentDataFromBPM: Copy of the segment data taken from the BPM (dump)
+#
+# SegmentDataFromFWImage: Copy of the segment data from the firmware image file.
+# This could be the firmware image to be upgraded to or
+# to be downgraded to. These are what will become
+# fragments.
+#
+# Segment Address Data Source
+# =====================================
+# D 1800 - 187F <---- [SegmentDataFromFWImage: 1800 - 187F]
+#
+# C 1880 - 18FF <---- [SegmentDataFromBPM: 1880 - 18FF]
+#
+# B 1900 - 197F <---- [SegmentDataFromBPM: 1900 - 1927]
+# [SegmentDataFromFWImage: 1928 - 1979]
+# [SegmentDataFromBPM: 197A - 197D]
+# [SegmentDataFromFWImage: 197E - 197F]
+#
+# A 1980 - 19FF <---- [SegmentDataFromBPM: 1980 - 19FF]
+#
+# @param[in] i_fileName Name of file
+# @param[in] i_outputDir Dir to emit binary to
+#
+# @return N/A
+################################################################################
+sub generateConfigImage
+{
+ my ($i_fileName, $i_outputDir) = @_;
+ my $this_func = (caller(0))[3];
+
+ open my $inputFileHandle, '<:encoding(UTF-8)', $i_fileName
+ or die "Failed to open $i_fileName";
+
+ my ($name, @version) = generateOutputNameAndVersion($i_fileName);
+
+ my $imageFile = $i_outputDir . "/" . $name . "CONFIG.bin";
+
+ open my $outputFileHandle, '>:raw', $imageFile
+ or die "Failed to open $imageFile";
+
+ # Indicates whether or not we're in the config section of the image file.
+ my $inConfigSection = undef;
+
+ # Keep track of the number of fragments we'll be writing to the output file.
+ my $numberOfFragments = 0;
+
+ # Used to keep track of which byte is the current byte being looked at in
+ # the file.
+ my $currentAddress = 0;
+
+ # The address offsets in the file are prefixed with the @ symbol.
+ use constant ADDRESS_LINE => "\@";
+ use constant CONFIG_START_ADDRESS_MARKER => "\@1800";
+ use constant CONFIG_START_ADDRESS => 0x1800;
+
+ # Segment data start addresses relative to config data start address.
+ use constant SEGMENT_D_START_ADDRESS => 0x000;
+ use constant SEGMENT_C_START_ADDRESS => 0x080;
+ use constant SEGMENT_B_START_ADDRESS => 0x100;
+ use constant SEGMENT_A_START_ADDRESS => 0x180;
+
+ # Spec for BPM updates says that the maximum size for the data portion of
+ # the payload is 16 bytes
+ use constant MAXIMUM_DATA_BYTES_FOR_PAYLOAD => 16;
+
+ my $fragments = undef;
+ my $fragmentData = undef;
+ my $fragmentSize = 0;
+
+ # The offset into the segment data where the fragment data will be written.
+ # In hostboot code, this will be a 512 byte buffer that holds a dump of the
+ # BPM's unique segment data.
+ my $fragmentOffset = SEGMENT_D_START_ADDRESS;
+
+ # Ensure that the diamond operator ( <> ) is searching for \n to determine
+ # where the end of a line is in the image file.
+ local $/ = "\n";
+
+ while (my $line = <$inputFileHandle>)
+ {
+ # Strip off the end-of-line character \n and optionally \r if it exists.
+ # Since the image files were created on a windows OS and this script
+ # runs on linux this will not be handled properly by chomp.
+ $line =~ s/\r?\n$//;
+
+ # Look for @1800 starting address marker.
+ #
+ # If found, start reading the data from the file until the next "@"
+ # marker or "q" starting markers are found.
+ #
+ # It is possible that the input file might not have the distinct @1800
+ # marker. In that case, the [currentAddress] variable is used to track
+ # the 0x1800 address in the input file.
+ if (substr($line, 0, 1) eq "q")
+ {
+ last;
+ }
+
+ if (substr($line, 0, 1) eq ADDRESS_LINE)
+ {
+ $currentAddress = hex substr($line, 1);
+ if ($verbose)
+ {
+ printf("Found address offset: 0x%04x\n", $currentAddress);
+ }
+
+ if ($line eq CONFIG_START_ADDRESS_MARKER)
+ {
+ $inConfigSection = 1;
+ }
+ next;
+ }
+
+ # Process the line into fragments of the form: size, address offset,
+ # and bytes.
+ #
+ # Size: The size of the fragment data.
+ # Note: The size only corresponds to the size of the fragment data
+ # itself. In hostboot code, this size will indicate how much of
+ # the BPM's segment data will be overwritten for the given
+ # fragment.
+ # Address offset: The address offset of the start byte of segment data.
+ # This will be used to determine where to start
+ # overwritting segment data from the BPM config dump.
+ # Bytes: The bytes to write to the BPM config data dump buffer.
+
+ # The length of the line. The maximum size of any line is 16 bytes.
+ my $dataLength = calculateDataLength($line);
+
+ if ($dataLength > MAXIMUM_DATA_BYTES_FOR_PAYLOAD)
+ {
+ die "$dataLength exceeds the maximum size for the data portion of" .
+ "the payload (". MAXIMUM_DATA_BYTES_FOR_PAYLOAD .")";
+ }
+
+ # If the CONFIG_START_ADDRESS_MARKER is missing from the file then this
+ # will serve as the backup method to locating the config data within the
+ # image file. Otherwise, this will always evaluate to false.
+ if (($currentAddress + $dataLength) == CONFIG_START_ADDRESS)
+ {
+ # The next line is the start of the config data section of the
+ # image. So, skip the current line and move into the config section.
+ $inConfigSection = 1;
+ $currentAddress += $dataLength;
+ next;
+ }
+
+ # Don't process lines that aren't config data.
+ if (not $inConfigSection)
+ {
+ next;
+ }
+
+ # Create Segment D fragment. For Segment D, the entire segment is
+ # required to be updated during the firmware update. So, create a
+ # fragment that encompasses the whole segment.
+ if ($currentAddress < CONFIG_START_ADDRESS + SEGMENT_C_START_ADDRESS)
+ {
+ # Increase the fragmentSize by the amount being appended to the
+ # fragment.
+ $fragmentSize += $dataLength;
+
+ # Pack the fragment data.
+ # Since the line is a string where each byte is an ASCII
+ # representation of the hex data separated by spaces, we
+ # must split the line by the space character and then write
+ # each byte string one at a time. Hence, the template
+ # "(H2)*". Each element is processed with the H2 part and
+ # the * just says to do this for all elements in the array
+ # emitted by split.
+ $fragmentData .= pack("(H2)*", split(/ /, $line));
+
+ if($currentAddress ==
+ (CONFIG_START_ADDRESS + SEGMENT_C_START_ADDRESS - 0x10))
+ {
+ $fragments .= createFragment($fragmentSize,
+ $fragmentOffset,
+ $fragmentData,
+ $numberOfFragments);
+ }
+ }
+ # Segment C is skipped over implicitly since there is no segment data in
+ # segment C that needs to be applied to the BPM.
+ elsif ( ($currentAddress >=
+ (CONFIG_START_ADDRESS + SEGMENT_B_START_ADDRESS))
+ && ($currentAddress <
+ (CONFIG_START_ADDRESS + SEGMENT_A_START_ADDRESS)))
+ {
+ # Work on Segment B data. There will be two fragments created for
+ # this segment.
+ # Fragment 1: [0x1928 - 0x1979]
+ # Fragment 2: [0x197E - 0x197F]
+ my $createFragment = 0;
+
+ # According to SMART's documentation, each segment must be 8 lines
+ # of 16 byte rows. Since we are searching for a specific region in
+ # segment B to create a fragment from we bound the fragment packing
+ # code by the borders of that region.
+ if ( ($currentAddress >=
+ (CONFIG_START_ADDRESS + SEGMENT_B_START_ADDRESS + 0x20))
+ && ($currentAddress <
+ (CONFIG_START_ADDRESS + SEGMENT_B_START_ADDRESS + 0x80)))
+ {
+ # Only need bytes from [0x1928 to 0x1979] to form Fragment 1.
+ # If we are not on the bounds of the fragment then we can simply
+ # pack the data and update the size.
+ # Otherwise, we must do some extra trimming.
+ if ($currentAddress ==
+ (CONFIG_START_ADDRESS + SEGMENT_B_START_ADDRESS + 0x20))
+ {
+ # This is the begining of Fragment 1's range. Trim off the
+ # bytes with offsets less than 0x1928.
+
+ # Set the fragmentOffset to the start of the range
+ $fragmentOffset = SEGMENT_B_START_ADDRESS
+ + 0x28;
+
+ # Split the line into individual bytes and only pack
+ # required bytes.
+ my @bytes = split(/ /, $line);
+
+ # Drop the first eight bytes since they aren't in the range.
+ splice @bytes, 0, 8;
+
+ $fragmentSize += scalar @bytes;
+
+ $fragmentData .= pack("(H2)*", @bytes);
+
+ # Since this is the begining of Fragment 1, there is still
+ # data left to be appended to this fragment. So don't call
+ # createFragment().
+ }
+ elsif ($currentAddress ==
+ (CONFIG_START_ADDRESS + SEGMENT_B_START_ADDRESS + 0x70))
+ {
+ # This is the last line in the range of Fragment 1 and the
+ # only line where Fragment 2 data is. So, trimming is
+ # required to finalize Fragment 1 and create Fragment 2.
+
+ # Start by finishing off Fragment 1.
+ # Split the line into individual bytes and only pack
+ # required bytes.
+ my @bytes = split(/ /, $line);
+
+ # Drop the last six bytes since they aren't
+ # in range [0x1928-0x1979]
+ splice @bytes, 10, 6;
+
+ $fragmentSize += scalar @bytes;
+
+ $fragmentData .= pack("(H2)*", @bytes);
+
+ # Now that Fragment 1 is completed, create the fragment and
+ # append it to the list of fragments.
+ $fragments .= createFragment($fragmentSize,
+ $fragmentOffset,
+ $fragmentData,
+ $numberOfFragments);
+
+ # Now work on Fragment 2.
+ # Only need bytes from [0x197E to 0x197F] to form Fragment 2
+
+ # Set the fragmentOffset
+ $fragmentOffset = SEGMENT_B_START_ADDRESS
+ + 0x7E;
+
+ # Split the line into individual bytes and only pack
+ # required bytes.
+ @bytes = split(/ /, $line);
+
+ # Drop the first 14 bytes since they aren't in
+ # range [0x197E to 0x197F]
+ splice @bytes, 0, 14;
+
+ $fragmentSize += scalar @bytes;
+
+ $fragmentData .= pack("(H2)*", @bytes);
+
+ # Fragment 2 is complete. Create the fragment and append to
+ # list of fragments.
+ $fragments .= createFragment($fragmentSize,
+ $fragmentOffset,
+ $fragmentData,
+ $numberOfFragments);
+
+ }
+ else
+ {
+ # We are not on a fragment boundary, so append the full line
+ # of data to Fragment 1.
+
+ # Increase the fragmentSize by the amount being appended to
+ # the fragment.
+ $fragmentSize += $dataLength;
+
+ # Pack the fragment data.
+ # Since the line is a string where each byte is an ASCII
+ # representation of the hex data separated by spaces, we
+ # must split the line by the space character and then write
+ # each byte string one at a time. Hence, the template
+ # "(H2)*". Each element is processed with the H2 part and
+ # the * just says to do this for all elements in the array
+ # emitted by split.
+ $fragmentData .= pack("(H2)*", split(/ /, $line));
+ }
+ }
+ }
+ elsif ($currentAddress >=
+ (CONFIG_START_ADDRESS + SEGMENT_A_START_ADDRESS))
+ {
+ # Don't need to create fragments in Segment A.
+ last;
+ }
+
+ # Increment the address offset by the number of firmware data
+ # bytes processed.
+ $currentAddress += $dataLength;
+ }
+
+ if ($verbose)
+ {
+ print "number of fragments: $numberOfFragments\n";
+ }
+
+ if (!defined($fragments))
+ {
+ die "Unable to process image file: $i_fileName";
+ }
+
+ # Write the version information to the file.
+ print $outputFileHandle pack("(H2)*", @version)
+ or die "Failed to write to output file: $imageFile";
+
+ # Write the number of fragments in the file.
+ # uint16_t
+ print $outputFileHandle pack("n", $numberOfFragments)
+ or die "Failed to write to output file: $imageFile";
+
+ # Write the fragments to the file
+ print $outputFileHandle $fragments
+ or die "Failed to write to output file: $imageFile";
+
+ close $inputFileHandle
+ or die "Failed to close input file: $i_fileName";
+ close $outputFileHandle
+ or die "Failed to close output file: $imageFile";
+}
+
+################################################################################
+# @brief Transforms the input file name into the output file name and extracts
+# the version info from the file name since that info is not present in
+# the image file itself.
+#
+# @param[in] i_fileName Name of file
+#
+# @return An array that contains the filename as the first
+# element and the version info array as the second.
+################################################################################
+sub generateOutputNameAndVersion
+{
+ # Input Parameter
+ my $i_fileName = shift;
+
+ # Parse the file name into its filename, path, and suffix.
+ my ($name, $path, $suffix) = fileparse($i_fileName, ".txt");
+
+ # Split the filename by underscore to access the information contained in
+ # the file name.
+ # According to the spec an example filename would be of the form:
+ # S R C A80 6 2 IBM H 01 1 B _FULL_ FW_Rev1.03_02282019.txt
+ # ^ ^ ^
+ # 1: Number of NVDIMM interfaces (1 = 32GB, 2 = 16GB)
+ # _FULL_: The image contains the firmware and configuration data.
+ # Rev1.03: Version of this image file
+ my @fileNameComponents = split(/_/, $name);
+
+ # The NVDIMM interface types supported
+ my %nvdimmTypes = ( 1 => "32GB",
+ 2 => "16GB", );
+
+ # Extract the NVDIMM Interface number from filename
+ my $nvdimmInterfaceNumber = substr($fileNameComponents[0], -2, 1);
+
+ # Convert interface number to the appropriate human-readable type
+ my $nvdimmType = "";
+ if (exists($nvdimmTypes{$nvdimmInterfaceNumber}))
+ {
+ $nvdimmType = $nvdimmTypes{$nvdimmInterfaceNumber};
+ }
+ else
+ {
+ die "NVDIMM Interface Type $nvdimmInterfaceNumber Unsupported";
+ }
+
+ # Extract the version from the filename and convert it to a two one byte hex
+ # strings.
+ my @versionComponents = split(/\./, $name);
+ my @version =
+ sprintf("%.2X", substr($versionComponents[0], -2, 2) =~ /([0-9]+)/g);
+ push(@version,
+ sprintf("%.2X", substr($versionComponents[1], 0, 2) =~ /([0-9]+)/g));
+
+
+ if ($verbose)
+ {
+ print "\tNVDIMM Type -> ". $nvdimmType ."\n";
+ print "\tVersion Info -> Major: " . $version[0] .
+ " Minor: " . $version[1] . "\n";
+ }
+
+ return ($nvdimmType."-NVDIMM-BPM-", @version);
+
+}
+
+################################################################################
+# @brief Processes input image file to generate CRC signature, firmware start
+# address, and calculated CRC bytes at address marker @FF7A. This
+# function simply calls SMART's supplied python script to perform the
+# operations. This intermediate file is only used during the firmware
+# binary generation.
+#
+# @param[in] i_fileName Name of file
+#
+# @return txt file name The temporary file that has the calculated CRC
+################################################################################
+sub generateIntermediateImage
+{
+ my ($i_fileName, $i_outputDir) = @_;
+
+ # Parse the file name into its filename, path, and suffix.
+ my ($name, $path, $suffix) = fileparse($i_fileName, ".txt");
+
+ # Parse the file name into its filename, path, and suffix.
+ my ($utilName, $utilPath, $utilSuffix) = fileparse($bpmUtilScript, ".txt");
+
+ my $intermediateFileName = $i_outputDir . $name . ".crc";
+
+ # Call the python script which will insert the CRC
+ my $pythonReturn = system($bpmUtilScript,
+ $i_fileName,
+ $intermediateFileName,
+ $bpmCrcProgram);
+
+ return $intermediateFileName;
+
+}
+
+################################################################################
+# @brief Creates a new fragment by packing the fragment size, offset, and data;
+# then it cleans up the fragment parameters so that the caller doesn't
+# have to.
+#
+# @param[in] io_fragmentSize The size of the fragment data section.
+# @param[in] i_fragmentOffset The offset into the BPM config dump buffer
+# that this fragment should begin overwritting
+# at.
+# @param[in] io_fragmentData The partial config segment data from the
+# flash image to be written to the BPM during
+# the update procedure.
+# @param[in] io_numberOfFragments This parameter incremented by this function
+# so the caller can keep track of how many
+# fragments have been created so far. However,
+# due to the messiness of perl syntax this
+# parameter is created as a visual reference
+# only and not used directly.
+#
+# @return The created fragment
+################################################################################
+sub createFragment
+{
+ my ($io_fragmentSize,
+ $i_fragmentOffset,
+ $io_fragmentData,
+ $io_numberOfFragments) = @_;
+
+ # Pack the fragment size
+ # uint8_t
+ my $fragment .= pack("C", $io_fragmentSize);
+
+ # Pack the BPM dump offset.
+ # uint16_t
+ $fragment .= pack("n", $i_fragmentOffset);
+
+ # Pack the fragment data
+ $fragment .= $io_fragmentData;
+
+ # Keep track of number of fragments in output
+ $_[3]++; # $io_numberOfFragments
+
+ # Reset variables
+ $_[2] = undef; # $io_fragmentData
+ $_[0] = 0; # $io_fragmentSize
+
+ return $fragment;
+}
+
+################################################################################
+# @brief Calculates the data length of the line by stripping all spaces for it
+# dividing by the number of bytes on the line.
+#
+# @param[in] i_line The line to calculate the length on.
+#
+# @return The number of bytes on the line (length).
+################################################################################
+sub calculateDataLength
+{
+ my $i_line = shift;
+
+ # Strip all the spaces from the line.
+ $i_line =~ s/\s+//g;
+
+ # Each line is plain text where each byte is separated by spaces.
+ # To determine how many bytes are on the line, divide by characters per byte
+ use constant CHARS_PER_BYTE => 2;
+ my $dataLength = length($i_line) / CHARS_PER_BYTE;
+
+ return $dataLength;
+}
+
+__END__
+
+=head1 NAME
+
+buildBpmFlashImage.pl
+
+=head1 SYNOPSIS
+
+buildBpmFlashImage.pl [..]
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<--help>
+
+Prints a brief help message and exits.
+
+=item B<--man>
+
+Prints the manual page and exits.
+
+=item B<--output-dir>
+
+Path to directory to emit the output files to.
+
+=item B<--image>
+
+File containing a BPM flash update script. More than one --image
+argument can be provided. If no images are supplied, the script will do
+nothing.
+
+=back
+
+=head1 DESCRIPTION
+
+B<buildBpmFlashImage.pl> will process a set of one or more BPM flash update
+scripts in .txt format by transforming the lines of text into blocks of binary
+data of the form BLOCK_SIZE, ADDRESS_OFFSET, PAYLOAD. The final binary output by
+this script will have the first 2 bytes be the version info (first byte Major,
+second Minor), then followed by two bytes that give the number of blocks in the
+file, and the remainder of the file will be blocks organized in the following
+way:
+
+BLOCK_SIZE is the number of bytes following the BLOCK_SIZE byte.
+ADDRESS_OFFSET is the offset the PAYLOAD data originally came from within the .txt file.
+PAYLOAD is the data, along with the ADDRESS_OFFSET, that will be used to construct the payloads to send to the BPM to perform the update.
+
+=cut
diff --git a/src/build/buildpnor/buildpnor.pl b/src/build/buildpnor/buildpnor.pl
index 227e8fe0f..eb76f868f 100755
--- a/src/build/buildpnor/buildpnor.pl
+++ b/src/build/buildpnor/buildpnor.pl
@@ -6,7 +6,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2018
+# Contributors Listed Below - COPYRIGHT 2012,2019
# [+] International Business Machines Corp.
#
#
@@ -56,6 +56,7 @@ my %SideOptions = (
B => "B",
sideless => "sideless",
);
+my $editedLayoutLocation = "";
if ($#ARGV < 0) {
usage();
@@ -95,6 +96,10 @@ for (my $i=0; $i < $#ARGV + 1; $i++)
elsif($ARGV[$i] =~ /--test/) {
$testRun = 1;
}
+ elsif($ARGV[$i] =~ /--editedLayoutLocation/) {
+ $editedLayoutLocation = $ARGV[++$i];
+ trace(2, "Location where the edited layout file will be placed: $editedLayoutLocation");
+ }
else {
traceErr("Unrecognized Input: $ARGV[$i]");
exit 1;
@@ -112,7 +117,8 @@ if (-e $pnorBinName)
}
#Load PNOR Layout XML file
-loadPnorLayout($pnorLayoutFile, \%pnorLayout, \%PhysicalOffsets, $testRun);
+loadPnorLayout($pnorLayoutFile, \%pnorLayout, \%PhysicalOffsets, $testRun,
+ $editedLayoutLocation);
#Verify all the section files exist
verifyFilesExist(\%pnorLayout, \%binFiles);
@@ -621,6 +627,7 @@ print <<"ENDUSAGE";
--fpartCmd invoke string for executing the fpart tool
--fcpCmd invoke string for executing the fcp tool
--test Output test-only sections.
+ --editedLayoutLocation <directory> Location to place edited layout file
Current Limitations:
--TOC Records must be 4 or 8 bytes in length
diff --git a/src/build/buildpnor/defaultPnorLayout.xml b/src/build/buildpnor/defaultPnorLayout.xml
index bb59a60fa..6e7c88e3d 100644
--- a/src/build/buildpnor/defaultPnorLayout.xml
+++ b/src/build/buildpnor/defaultPnorLayout.xml
@@ -89,7 +89,6 @@ Layout Description
<section>
<description>Guard Data (20K)</description>
<eyeCatch>GUARD</eyeCatch>
- <physicalOffset>0x2C000</physicalOffset>
<physicalRegionSize>0x5000</physicalRegionSize>
<side>sideless</side>
<ecc/>
@@ -98,7 +97,7 @@ Layout Description
<description>DIMM JEDEC (288K)</description>
<eyeCatch>DJVPD</eyeCatch>
<!--NOTE: MUST update standalone.simics if offset changes -->
- <physicalOffset>0x31000</physicalOffset>
+ <physicalOffset>0x31000</physicalOffset>
<physicalRegionSize>0x48000</physicalRegionSize>
<side>sideless</side>
<ecc/>
@@ -124,7 +123,6 @@ Layout Description
<section>
<description>Hostboot Base (1MB)</description>
<eyeCatch>HBB</eyeCatch>
- <physicalOffset>0x151000</physicalOffset>
<physicalRegionSize>0x100000</physicalRegionSize>
<side>sideless</side>
<sha512Version/>
@@ -133,7 +131,6 @@ Layout Description
<section>
<description>Hostboot Data (2MB)</description>
<eyeCatch>HBD</eyeCatch>
- <physicalOffset>0x251000</physicalOffset>
<physicalRegionSize>0x200000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
@@ -142,7 +139,6 @@ Layout Description
<section>
<description>Hostboot Extended image (14.22MB w/o ECC)</description>
<eyeCatch>HBI</eyeCatch>
- <physicalOffset>0x451000</physicalOffset>
<physicalRegionSize>0x1000000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
@@ -151,7 +147,6 @@ Layout Description
<section>
<description>SBE-IPL (Staging Area) (752K)</description>
<eyeCatch>SBE</eyeCatch>
- <physicalOffset>0x1451000</physicalOffset>
<physicalRegionSize>0xBC000</physicalRegionSize>
<sha512perEC/>
<sha512Version/>
@@ -161,7 +156,6 @@ Layout Description
<section>
<description>HCODE Ref Image (1.125MB)</description>
<eyeCatch>HCODE</eyeCatch>
- <physicalOffset>0x150D000</physicalOffset>
<physicalRegionSize>0x120000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
@@ -170,17 +164,15 @@ Layout Description
<section>
<description>Hostboot Runtime Services for Sapphire (7.0MB)</description>
<eyeCatch>HBRT</eyeCatch>
- <physicalOffset>0x162D000</physicalOffset>
<physicalRegionSize>0x700000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
<ecc/>
</section>
<section>
- <description>Payload (19.875MB)</description>
+ <description>Payload (6MB)</description>
<eyeCatch>PAYLOAD</eyeCatch>
- <physicalOffset>0x1D2D000</physicalOffset>
- <physicalRegionSize>0x13E0000</physicalRegionSize>
+ <physicalRegionSize>0x0600000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
<ecc/>
@@ -188,7 +180,6 @@ Layout Description
<section>
<description>Special PNOR Test Space (36K)</description>
<eyeCatch>TEST</eyeCatch>
- <physicalOffset>0x310D000</physicalOffset>
<physicalRegionSize>0x9000</physicalRegionSize>
<testonly/>
<side>sideless</side>
@@ -199,7 +190,6 @@ Layout Description
from skipping header. Signing is forced in build pnor phase -->
<description>Special PNOR Test Space with Header (36K)</description>
<eyeCatch>TESTRO</eyeCatch>
- <physicalOffset>0x3116000</physicalOffset>
<physicalRegionSize>0x9000</physicalRegionSize>
<side>sideless</side>
<testonly/>
@@ -210,7 +200,6 @@ Layout Description
<section>
<description>Hostboot Bootloader (28K)</description>
<eyeCatch>HBBL</eyeCatch>
- <physicalOffset>0x311F000</physicalOffset>
<!-- Physical Size includes Header rounded to ECC valid size -->
<!-- Max size of actual HBBL content is 20K and 22.5K with ECC -->
<physicalRegionSize>0x7000</physicalRegionSize>
@@ -219,17 +208,8 @@ Layout Description
<ecc/>
</section>
<section>
- <description>Global Data (36K)</description>
- <eyeCatch>GLOBAL</eyeCatch>
- <physicalOffset>0x3126000</physicalOffset>
- <physicalRegionSize>0x9000</physicalRegionSize>
- <side>sideless</side>
- <ecc/>
- </section>
- <section>
<description>Ref Image Ring Overrides (20K)</description>
<eyeCatch>RINGOVD</eyeCatch>
- <physicalOffset>0x312F000</physicalOffset>
<physicalRegionSize>0x5000</physicalRegionSize>
<side>sideless</side>
<ecc/>
@@ -237,7 +217,6 @@ Layout Description
<section>
<description>SecureBoot Key Transition Partition (16K)</description>
<eyeCatch>SBKT</eyeCatch>
- <physicalOffset>0x3134000</physicalOffset>
<physicalRegionSize>0x4000</physicalRegionSize>
<side>sideless</side>
<ecc/>
@@ -245,7 +224,6 @@ Layout Description
<section>
<description>OCC Lid (1.125M)</description>
<eyeCatch>OCC</eyeCatch>
- <physicalOffset>0x3138000</physicalOffset>
<physicalRegionSize>0x120000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
@@ -256,7 +234,6 @@ Layout Description
<!-- We need 266KB per module sort, going to support
40 tables by default, plus ECC -->
<eyeCatch>WOFDATA</eyeCatch>
- <physicalOffset>0x3258000</physicalOffset>
<!-- TODO RTC: 208004
Reduced by MB total to allow HBI + tests to
fit in PNOR, need to increase back 1 MB once HBI size
@@ -269,7 +246,6 @@ Layout Description
<section>
<description>FIRDATA (12K)</description>
<eyeCatch>FIRDATA</eyeCatch>
- <physicalOffset>0x3E58000</physicalOffset>
<physicalRegionSize>0x3000</physicalRegionSize>
<side>sideless</side>
<ecc/>
@@ -277,7 +253,6 @@ Layout Description
<section>
<description>Memory Data (128K)</description>
<eyeCatch>MEMD</eyeCatch>
- <physicalOffset>0x3E5B000</physicalOffset>
<physicalRegionSize>0x20000</physicalRegionSize>
<side>sideless</side>
<sha512Version/>
@@ -286,7 +261,6 @@ Layout Description
<section>
<description>Secureboot Test Load (12K)</description>
<eyeCatch>TESTLOAD</eyeCatch>
- <physicalOffset>0x3E7B000</physicalOffset>
<physicalRegionSize>0x3000</physicalRegionSize>
<side>sideless</side>
<sha512Version/>
@@ -295,7 +269,6 @@ Layout Description
<section>
<description>Centaur Hw Ref Image (12K)</description>
<eyeCatch>CENHWIMG</eyeCatch>
- <physicalOffset>0x3E7E000</physicalOffset>
<physicalRegionSize>0x3000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
@@ -304,7 +277,6 @@ Layout Description
<section>
<description>Secure Boot (144K)</description>
<eyeCatch>SECBOOT</eyeCatch>
- <physicalOffset>0x3E81000</physicalOffset>
<physicalRegionSize>0x24000</physicalRegionSize>
<side>sideless</side>
<ecc/>
@@ -313,7 +285,6 @@ Layout Description
<section>
<description>Open CAPI Memory Buffer (OCMB) Firmware (300K)</description>
<eyeCatch>OCMBFW</eyeCatch>
- <physicalOffset>0x3EA5000</physicalOffset>
<physicalRegionSize>0x4B000</physicalRegionSize>
<side>sideless</side>
<sha512Version/>
@@ -323,7 +294,6 @@ Layout Description
<section>
<description>HDAT Data (16K)</description>
<eyeCatch>HDAT</eyeCatch>
- <physicalOffset>0x3EF0000</physicalOffset>
<physicalRegionSize>0x4000</physicalRegionSize>
<side>sideless</side>
<sha512Version/>
diff --git a/src/build/buildpnor/genPnorImages.pl b/src/build/buildpnor/genPnorImages.pl
index 4782b7e8f..cc3b4f5e9 100755
--- a/src/build/buildpnor/genPnorImages.pl
+++ b/src/build/buildpnor/genPnorImages.pl
@@ -61,6 +61,11 @@ my $programName = File::Basename::basename $0;
my @systemBinFiles = ();
my %pnorLayout = ();
my %PhysicalOffsets = ();
+my %partitionUtilHash;
+
+# percentage utilization threshold, if crossed display warning message
+# that partition is almost full
+use constant CRITICAL_THRESHOLD => 85.00;
# Truncate SHA to n bytes
use constant SHA_TRUNCATE_SIZE => 32;
@@ -74,6 +79,7 @@ use constant VFS_MODULE_TABLE_MAX_SIZE => VFS_EXTENDED_MODULE_MAX
# Flag parameter string passed into signing tools
# Note spaces before/after are critical.
use constant OP_SIGNING_FLAG => " --flags ";
+use constant SW_FLAG_HAS_A_HPT => 0x80000000;
# Security bits HW flag strings
use constant OP_BUILD_FLAG => 0x80000000;
use constant FIPS_BUILD_FLAG => 0x40000000;
@@ -120,6 +126,7 @@ my $sign_mode = $DEVELOPMENT;
my $hwKeyHashFile = "";
my $hb_standalone="";
my $buildType="";
+my $editedLayoutLocation="";
# @TODO RTC 170650: Set default to 0 after all environments provide external
# control over this policy, plus remove '!' from 'lab-security-override'
@@ -142,6 +149,7 @@ GetOptions("binDir:s" => \$bin_dir,
"lab-security-override!" => \$labSecurityOverride,
"emit-eccless" => \$emitEccless,
"build-type:s" => \$buildType,
+ "editedLayoutLocation:s" => \$editedLayoutLocation,
"help" => \$help);
if ($help)
@@ -385,7 +393,8 @@ if ($build_all && $secureboot)
}
#Load PNOR Layout XML file
-loadPnorLayout($pnorLayoutFile, \%pnorLayout, \%PhysicalOffsets, $testRun);
+loadPnorLayout($pnorLayoutFile, \%pnorLayout, \%PhysicalOffsets, $testRun,
+ $editedLayoutLocation);
# Generate final images for each system's bin files.
foreach my $binFilesCSV (@systemBinFiles)
@@ -408,6 +417,17 @@ foreach my $binFilesCSV (@systemBinFiles)
manipulateImages(\%pnorLayout, \%binFiles, $system_target);
}
+# display percentage utilization data for each eyecatch
+foreach my $key (keys %partitionUtilHash) {
+
+ print "$key is $partitionUtilHash{$key}{pctUtilized} utilized ($partitionUtilHash{$key}{freeBytes} of $partitionUtilHash{$key}{physicalRegionSize} bytes free)\n";
+
+ # if percentage is greater than critical threshold, surface warning
+ if ($partitionUtilHash{$key}{pctUtilized} > CRITICAL_THRESHOLD) {
+ print "Warning: Percent utilization for $key shows that partition is almost full.\n";
+ }
+}
+
################################################################################
# Subroutines
################################################################################
@@ -451,6 +471,7 @@ sub partitionDepSort
################################################################################
# manipulateImages - Perform any ECC/padding/sha/signing manipulations
################################################################################
+
sub manipulateImages
{
my ($i_pnorLayoutRef, $i_binFilesRef, $system_target) = @_;
@@ -464,7 +485,10 @@ sub manipulateImages
# Partitions that have a hash page table at the beginning of the section
# for secureboot purposes.
- my %hashPageTablePartitions = (HBI => 1);
+ # TODO: add back SBE and HCODE as per story 209485
+ my %hashPageTablePartitions = (HBI => 1,
+ WOFDATA => 1,
+ MEMD => 1);
if($ENV{'RM_HASH_PAGE_TABLE'})
{
undef %hashPageTablePartitions;
@@ -483,7 +507,16 @@ sub manipulateImages
instructionStartStackPointer => 0);
my $layoutKey = findLayoutKeyByEyeCatch($key, \%$i_pnorLayoutRef);
+
+ # Skip if binary file isn't included in the PNOR layout file
+ if ($layoutKey eq -1)
+ {
+ print "Warning: skipping $key since it is NOT in the PNOR layout file\n";
+ next;
+ }
+
my $eyeCatch = $sectionHash{$layoutKey}{eyeCatch};
+ my $physicalRegionSize = $sectionHash{$layoutKey}{physicalRegionSize};
my %tempImages = (
HDR_PHASE => "$bin_dir/$parallelPrefix.$eyeCatch.temp.hdr.bin",
TEMP_SHA_IMG => "$bin_dir/$parallelPrefix.$eyeCatch.temp.sha.bin",
@@ -506,24 +539,23 @@ sub manipulateImages
# Sections that have secureboot support. Secureboot still must be
# enabled for secureboot actions on these partitions to occur.
my $isNormalSecure = ($eyeCatch eq "HBBL");
- $isNormalSecure ||= ($eyeCatch eq "SBE");
- $isNormalSecure ||= ($eyeCatch eq "MEMD");
$isNormalSecure ||= ($eyeCatch eq "HBRT");
$isNormalSecure ||= ($eyeCatch eq "PAYLOAD");
$isNormalSecure ||= ($eyeCatch eq "OCC");
- $isNormalSecure ||= ($eyeCatch eq "CAPP");
$isNormalSecure ||= ($eyeCatch eq "BOOTKERNEL");
- $isNormalSecure ||= ($eyeCatch eq "HCODE");
- $isNormalSecure ||= ($eyeCatch eq "CENHWIMG");
- $isNormalSecure ||= ($eyeCatch eq "WOFDATA");
$isNormalSecure ||= ($eyeCatch eq "IMA_CATALOG");
$isNormalSecure ||= ($eyeCatch eq "TESTRO");
$isNormalSecure ||= ($eyeCatch eq "TESTLOAD");
$isNormalSecure ||= ($eyeCatch eq "VERSION");
+ $isNormalSecure ||= ($eyeCatch eq "CENHWIMG");
+ $isNormalSecure ||= ($eyeCatch eq "SBE");
+ $isNormalSecure ||= ($eyeCatch eq "HCODE");
my $isSpecialSecure = ($eyeCatch eq "HBB");
$isSpecialSecure ||= ($eyeCatch eq "HBD");
$isSpecialSecure ||= ($eyeCatch eq "HBI");
+ $isSpecialSecure ||= ($eyeCatch eq "WOFDATA");
+ $isSpecialSecure ||= ($eyeCatch eq "MEMD");
# Used to indicate security is supported in firmware
my $secureSupported = $isNormalSecure || $isSpecialSecure;
@@ -662,6 +694,9 @@ sub manipulateImages
else
{
run_command("cp $tempImages{hashPageTable} $tempImages{PAYLOAD_TEXT}");
+ # Hash table generated so need to set sw-flags
+ my $hex_sw_flag = sprintf("0x%08X", SW_FLAG_HAS_A_HPT);
+ $CUR_OPEN_SIGN_REQUEST .= " --sw-flags $hex_sw_flag ";
}
run_command("$CUR_OPEN_SIGN_REQUEST "
@@ -734,6 +769,22 @@ sub manipulateImages
setCallerHwHdrFields(\%callerHwHdrFields, $tempImages{HDR_PHASE});
+
+ # store binary file size + header size in hash
+
+ # If section will passed through ecc, include this in size calculation
+ if( ($sectionHash{$layoutKey}{ecc} eq "yes") )
+ {
+ $partitionUtilHash{$eyeCatch}{logicalFileSize} = $callerHwHdrFields{totalContainerSize} * (9/8);
+ }
+ else
+ {
+ $partitionUtilHash{$eyeCatch}{logicalFileSize} = $callerHwHdrFields{totalContainerSize};
+ }
+ $partitionUtilHash{$eyeCatch}{pctUtilized} = sprintf("%.2f", $partitionUtilHash{$eyeCatch}{logicalFileSize} / $physicalRegionSize * 100);
+ $partitionUtilHash{$eyeCatch}{freeBytes} = $physicalRegionSize - $partitionUtilHash{$eyeCatch}{logicalFileSize};
+ $partitionUtilHash{$eyeCatch}{physicalRegionSize} = $physicalRegionSize;
+
# Padding Phase
if ($eyeCatch eq "HBI" && $testRun)
{
@@ -1258,6 +1309,7 @@ print <<"ENDUSAGE";
switch (separated with a space and not
including the single quotes). OpenPower is
the default.
+ --editedLayoutLocation <directory> Location to place edited layout file
Current Limitations:
- Issues with dependency on ENGD build for certain files such as SBE. This is why [--build-all | --install-all ] are used.
diff --git a/src/build/buildpnor/memd_creation.pl b/src/build/buildpnor/memd_creation.pl
index c4f551b03..b33981ad6 100755
--- a/src/build/buildpnor/memd_creation.pl
+++ b/src/build/buildpnor/memd_creation.pl
@@ -66,7 +66,7 @@ pod2usage(-verbose => 2) if $man;
if($memd_dir)
{
print "Reading files from $memd_dir\n";
- @memd_files = glob($memd_dir . '/*');
+ @memd_files = glob($memd_dir . '/*vpd');
}
elsif(@memd_files)
{
diff --git a/src/build/buildpnor/pkgOcmbFw.pl b/src/build/buildpnor/pkgOcmbFw.pl
index eb5d8f953..b7fdb90cf 100755
--- a/src/build/buildpnor/pkgOcmbFw.pl
+++ b/src/build/buildpnor/pkgOcmbFw.pl
@@ -89,6 +89,13 @@
#
###############################################################################
+# ******************WARNING**********************
+#
+# THIS FILE MUST BE KEPT IN SYNC WITH
+# src/include/usr/expupd/ocmbFwImage_const.H
+#
+# ******************WARNING**********************
+
use strict;
use File::Basename;
use Digest::SHA qw(sha512);
diff --git a/src/build/buildpnor/pnorLayoutAxone.xml b/src/build/buildpnor/pnorLayoutAxone.xml
index 150bab112..274439a39 100644
--- a/src/build/buildpnor/pnorLayoutAxone.xml
+++ b/src/build/buildpnor/pnorLayoutAxone.xml
@@ -86,26 +86,31 @@ Layout Description
<ecc/>
</section>
<section>
+ <!-- NOTE must be before images that are likely to change like HBI,
+ also mustupdate standalone.simics if EECACHE offset changes-->
+ <description>Eeprom Cache(512K)</description>
+ <eyeCatch>EECACHE</eyeCatch>
+ <physicalOffset>0x2C000</physicalOffset>
+ <physicalRegionSize>0x80000</physicalRegionSize>
+ <side>sideless</side>
+ <ecc/>
+ </section>
+ <section>
<description>Guard Data (20K)</description>
<eyeCatch>GUARD</eyeCatch>
- <physicalOffset>0x2C000</physicalOffset>
<physicalRegionSize>0x5000</physicalRegionSize>
<side>sideless</side>
<ecc/>
</section>
<section>
- <description>Module VPD (576K)</description>
- <eyeCatch>MVPD</eyeCatch>
- <!--NOTE: MUST update standalone.simics if offset changes -->
- <physicalOffset>0x31000</physicalOffset>
- <physicalRegionSize>0x90000</physicalRegionSize>
+ <description>Attributes</description>
+ <eyeCatch>ATTR_TMP</eyeCatch>
+ <physicalRegionSize>0x4000</physicalRegionSize>
<side>sideless</side>
- <ecc/>
</section>
<section>
<description>Hostboot Base (1MB)</description>
<eyeCatch>HBB</eyeCatch>
- <physicalOffset>0xC1000</physicalOffset>
<physicalRegionSize>0x100000</physicalRegionSize>
<side>sideless</side>
<sha512Version/>
@@ -114,17 +119,15 @@ Layout Description
<section>
<description>Hostboot Data (2MB)</description>
<eyeCatch>HBD</eyeCatch>
- <physicalOffset>0x1C1000</physicalOffset>
<physicalRegionSize>0x200000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
<ecc/>
</section>
<section>
- <description>Hostboot Extended image (14.22MB w/o ECC)</description>
+ <description>Hostboot Extended image (17.77MB w/o ECC)</description>
<eyeCatch>HBI</eyeCatch>
- <physicalOffset>0x3C1000</physicalOffset>
- <physicalRegionSize>0x1000000</physicalRegionSize>
+ <physicalRegionSize>0x1400000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
<ecc/>
@@ -132,7 +135,6 @@ Layout Description
<section>
<description>SBE-IPL (Staging Area) (752K)</description>
<eyeCatch>SBE</eyeCatch>
- <physicalOffset>0x13C1000</physicalOffset>
<physicalRegionSize>0xBC000</physicalRegionSize>
<sha512perEC/>
<sha512Version/>
@@ -142,26 +144,23 @@ Layout Description
<section>
<description>HCODE Ref Image (1.125MB)</description>
<eyeCatch>HCODE</eyeCatch>
- <physicalOffset>0x147D000</physicalOffset>
<physicalRegionSize>0x120000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
<ecc/>
</section>
<section>
- <description>Hostboot Runtime Services for Sapphire (7.0MB)</description>
+ <description>Hostboot Runtime Services for Sapphire (8.0MB)</description>
<eyeCatch>HBRT</eyeCatch>
- <physicalOffset>0x159D000</physicalOffset>
- <physicalRegionSize>0x700000</physicalRegionSize>
+ <physicalRegionSize>0x800000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
<ecc/>
</section>
<section>
- <description>Payload (19.875MB)</description>
+ <description>Payload (16KB)</description>
<eyeCatch>PAYLOAD</eyeCatch>
- <physicalOffset>0x1C9D000</physicalOffset>
- <physicalRegionSize>0x13E0000</physicalRegionSize>
+ <physicalRegionSize>0x4000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
<ecc/>
@@ -169,7 +168,6 @@ Layout Description
<section>
<description>Special PNOR Test Space (36K)</description>
<eyeCatch>TEST</eyeCatch>
- <physicalOffset>0x307D000</physicalOffset>
<physicalRegionSize>0x9000</physicalRegionSize>
<testonly/>
<side>sideless</side>
@@ -180,7 +178,6 @@ Layout Description
from skipping header. Signing is forced in build pnor phase -->
<description>Special PNOR Test Space with Header (36K)</description>
<eyeCatch>TESTRO</eyeCatch>
- <physicalOffset>0x3086000</physicalOffset>
<physicalRegionSize>0x9000</physicalRegionSize>
<side>sideless</side>
<testonly/>
@@ -191,7 +188,6 @@ Layout Description
<section>
<description>Hostboot Bootloader (28K)</description>
<eyeCatch>HBBL</eyeCatch>
- <physicalOffset>0x308F000</physicalOffset>
<!-- Physical Size includes Header rounded to ECC valid size -->
<!-- Max size of actual HBBL content is 20K and 22.5K with ECC -->
<physicalRegionSize>0x7000</physicalRegionSize>
@@ -200,17 +196,8 @@ Layout Description
<ecc/>
</section>
<section>
- <description>Global Data (36K)</description>
- <eyeCatch>GLOBAL</eyeCatch>
- <physicalOffset>0x3096000</physicalOffset>
- <physicalRegionSize>0x9000</physicalRegionSize>
- <side>sideless</side>
- <ecc/>
- </section>
- <section>
<description>Ref Image Ring Overrides (20K)</description>
<eyeCatch>RINGOVD</eyeCatch>
- <physicalOffset>0x309F000</physicalOffset>
<physicalRegionSize>0x5000</physicalRegionSize>
<side>sideless</side>
<ecc/>
@@ -218,7 +205,6 @@ Layout Description
<section>
<description>SecureBoot Key Transition Partition (16K)</description>
<eyeCatch>SBKT</eyeCatch>
- <physicalOffset>0x30A4000</physicalOffset>
<physicalRegionSize>0x4000</physicalRegionSize>
<side>sideless</side>
<ecc/>
@@ -226,18 +212,16 @@ Layout Description
<section>
<description>OCC Lid (1.125M)</description>
<eyeCatch>OCC</eyeCatch>
- <physicalOffset>0x30A8000</physicalOffset>
<physicalRegionSize>0x120000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
<ecc/>
</section>
<section>
- <description>VFRT data for WOF (12MB)</description>
+ <description>VFRT data for WOF (6MB)</description>
<!-- We need 266KB per module sort, going to support
40 tables by default, plus ECC -->
<eyeCatch>WOFDATA</eyeCatch>
- <physicalOffset>0x31C8000</physicalOffset>
<physicalRegionSize>0x600000</physicalRegionSize>
<side>sideless</side>
<sha512Version/>
@@ -246,52 +230,30 @@ Layout Description
<section>
<description>FIRDATA (12K)</description>
<eyeCatch>FIRDATA</eyeCatch>
- <physicalOffset>0x37C8000</physicalOffset>
<physicalRegionSize>0x3000</physicalRegionSize>
<side>sideless</side>
<ecc/>
</section>
<section>
- <description>Memory Data (128K)</description>
- <eyeCatch>MEMD</eyeCatch>
- <physicalOffset>0x37CB000</physicalOffset>
- <physicalRegionSize>0x20000</physicalRegionSize>
- <side>sideless</side>
- <sha512Version/>
- <ecc/>
- </section>
- <section>
<description>Secureboot Test Load (12K)</description>
<eyeCatch>TESTLOAD</eyeCatch>
- <physicalOffset>0x37EB000</physicalOffset>
<physicalRegionSize>0x3000</physicalRegionSize>
<side>sideless</side>
<sha512Version/>
<ecc/>
</section>
<section>
- <description>Centaur Hw Ref Image (12K)</description>
- <eyeCatch>CENHWIMG</eyeCatch>
- <physicalOffset>0x37EE000</physicalOffset>
- <physicalRegionSize>0x3000</physicalRegionSize>
- <sha512Version/>
- <side>sideless</side>
- <ecc/>
- </section>
- <section>
<description>Secure Boot (144K)</description>
<eyeCatch>SECBOOT</eyeCatch>
- <physicalOffset>0x37F1000</physicalOffset>
<physicalRegionSize>0x24000</physicalRegionSize>
<side>sideless</side>
<ecc/>
<preserved/>
</section>
<section>
- <description>Open CAPI Memory Buffer (OCMB) Firmware (300K)</description>
+ <description>Open CAPI Memory Buffer (OCMB) Firmware (1164K)</description>
<eyeCatch>OCMBFW</eyeCatch>
- <physicalOffset>0x3815000</physicalOffset>
- <physicalRegionSize>0x4B000</physicalRegionSize>
+ <physicalRegionSize>0x123000</physicalRegionSize>
<side>sideless</side>
<sha512Version/>
<readOnly/>
@@ -300,18 +262,9 @@ Layout Description
<section>
<description>HDAT Data (16K)</description>
<eyeCatch>HDAT</eyeCatch>
- <physicalOffset>0x3860000</physicalOffset>
<physicalRegionSize>0x4000</physicalRegionSize>
<side>sideless</side>
<sha512Version/>
<ecc/>
</section>
- <section>
- <description>Eeprom Cache(512K)</description>
- <eyeCatch>EECACHE</eyeCatch>
- <physicalOffset>0x3864000</physicalOffset>
- <physicalRegionSize>0x80000</physicalRegionSize>
- <side>sideless</side>
- <ecc/>
- </section>
</pnor>
diff --git a/src/build/buildpnor/pnorLayoutFSP.xml b/src/build/buildpnor/pnorLayoutFSP.xml
index a842001c3..9569e479f 100644
--- a/src/build/buildpnor/pnorLayoutFSP.xml
+++ b/src/build/buildpnor/pnorLayoutFSP.xml
@@ -168,10 +168,10 @@ Layout Description - Used when building an FSP driver
<ecc/>
</section>
<section>
- <description>Hostboot Runtime Services for Sapphire (6MB)</description>
+ <description>Hostboot Runtime Services for Sapphire (8MB)</description>
<eyeCatch>HBRT</eyeCatch>
<physicalOffset>0x162D000</physicalOffset>
- <physicalRegionSize>0x600000</physicalRegionSize>
+ <physicalRegionSize>0x800000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
<ecc/>
@@ -179,7 +179,7 @@ Layout Description - Used when building an FSP driver
<section>
<description>Hostboot Bootloader (28K)</description>
<eyeCatch>HBBL</eyeCatch>
- <physicalOffset>0x1C2D000</physicalOffset>
+ <physicalOffset>0x1E2D000</physicalOffset>
<!-- Physical Size includes Header rounded to ECC valid size -->
<!-- Max size of actual HBBL content is 20K and 22.5K with ECC -->
<physicalRegionSize>0x7000</physicalRegionSize>
@@ -188,17 +188,9 @@ Layout Description - Used when building an FSP driver
<ecc/>
</section>
<section>
- <description>Global Data (36K)</description>
- <eyeCatch>GLOBAL</eyeCatch>
- <physicalOffset>0x1C34000</physicalOffset>
- <physicalRegionSize>0x9000</physicalRegionSize>
- <side>sideless</side>
- <ecc/>
- </section>
- <section>
<description>Ref Image Ring Overrides (20K)</description>
<eyeCatch>RINGOVD</eyeCatch>
- <physicalOffset>0x1C3D000</physicalOffset>
+ <physicalOffset>0x1E34000</physicalOffset>
<physicalRegionSize>0x5000</physicalRegionSize>
<side>sideless</side>
<ecc/>
@@ -206,7 +198,7 @@ Layout Description - Used when building an FSP driver
<section>
<description>SecureBoot Key Transition Partition (16K)</description>
<eyeCatch>SBKT</eyeCatch>
- <physicalOffset>0x1C42000</physicalOffset>
+ <physicalOffset>0x1E39000</physicalOffset>
<physicalRegionSize>0x4000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
@@ -215,7 +207,7 @@ Layout Description - Used when building an FSP driver
<section>
<description>OCC Lid (1.125M)</description>
<eyeCatch>OCC</eyeCatch>
- <physicalOffset>0x1C46000</physicalOffset>
+ <physicalOffset>0x1E3D000</physicalOffset>
<physicalRegionSize>0x120000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
@@ -226,7 +218,7 @@ Layout Description - Used when building an FSP driver
<!-- We need 266KB per module sort, going to support
40 tables by default, plus ECC -->
<eyeCatch>WOFDATA</eyeCatch>
- <physicalOffset>0x1D66000</physicalOffset>
+ <physicalOffset>0x1F5D000</physicalOffset>
<physicalRegionSize>0xC00000</physicalRegionSize>
<side>sideless</side>
<sha512Version/>
@@ -235,7 +227,7 @@ Layout Description - Used when building an FSP driver
<section>
<description>Memory Data (128K)</description>
<eyeCatch>MEMD</eyeCatch>
- <physicalOffset>0x2966000</physicalOffset>
+ <physicalOffset>0x2B5D000</physicalOffset>
<physicalRegionSize>0x20000</physicalRegionSize>
<side>sideless</side>
<sha512Version/>
@@ -244,7 +236,7 @@ Layout Description - Used when building an FSP driver
<section>
<description>Centaur Hw Ref Image (12K)</description>
<eyeCatch>CENHWIMG</eyeCatch>
- <physicalOffset>0x2986000</physicalOffset>
+ <physicalOffset>0x2B7D000</physicalOffset>
<physicalRegionSize>0x3000</physicalRegionSize>
<sha512Version/>
<side>sideless</side>
@@ -253,7 +245,7 @@ Layout Description - Used when building an FSP driver
<section>
<description>Secure Boot (144K)</description>
<eyeCatch>SECBOOT</eyeCatch>
- <physicalOffset>0x2989000</physicalOffset>
+ <physicalOffset>0x2B80000</physicalOffset>
<physicalRegionSize>0x24000</physicalRegionSize>
<side>sideless</side>
<ecc/>
@@ -262,7 +254,7 @@ Layout Description - Used when building an FSP driver
<section>
<description>Open CAPI Memory Buffer (OCMB) Firmware (300K)</description>
<eyeCatch>OCMBFW</eyeCatch>
- <physicalOffset>0x29AD000</physicalOffset>
+ <physicalOffset>0x2BA4000</physicalOffset>
<physicalRegionSize>0x4B000</physicalRegionSize>
<side>sideless</side>
<sha512Version/>
diff --git a/src/build/citest/autocitest b/src/build/citest/autocitest
index 0cb8d078f..3e29c414f 100755
--- a/src/build/citest/autocitest
+++ b/src/build/citest/autocitest
@@ -154,8 +154,11 @@ waitkb
timestamp=`date +'%H:%M:%S'`
echo "$timestamp Starting autosample test..."
-# see simics license usage
-tail -n 500 /afs/rch/usr4/dlarson/public/stats/lic_usage.txt | grep hindsight
+# see simics license usage.
+hindsight_license=$(echo "hindsight_usage-"`date +%Y`-`date +%B`".log")
+# show last 4 hours. Gives alittle insight to license usage trends.
+#This log file is added to every twenty minutes. There are spaces between each line. 4x2x3=24 lines
+tail -n 24 /gsa/ausgsa/projects/s/simics_test/license_logs/$hindsight_license
# Run set up in current shell
echo "run autosimsetup.."
@@ -333,10 +336,11 @@ while [ $(($modsstarted)) -lt 1 -o $(($modsstarted)) -ne $(($modscompleted)) ];
sleep 20
((loopcount++)) # increment loopcount
echo "loopcount = $loopcount"
-
+ date +'%H:%M:%S'
echo "modscompleted log command"
- echo "autosim $NOWIN --simcmd \"print ((system_cmp0.phys_mem).read 0x$mods_completed_addr 0x08)\" 1> $SBXHOME/modscompleted.log 2> /dev/null"
- autosim $NOWIN --simcmd "print ((system_cmp0.phys_mem).read 0x$mods_completed_addr 0x08)" 1> $SBXHOME/modscompleted.log 2> /dev/null
+ echo "autosim $NOWIN --simcmd \"print ((system_cmp0.phys_mem).read 0x$mods_completed_addr 0x08)\" 1> $SBXHOME/modscompleted.log 2> /dev/null"
+ autosim $NOWIN --simcmd "print ((system_cmp0.phys_mem).read 0x$mods_completed_addr 0x08)" 1> $SBXHOME/modscompleted.log 2> /dev/null
+ date +'%H:%M:%S'
echo
echo "modscompleted command"
@@ -344,9 +348,11 @@ while [ $(($modsstarted)) -lt 1 -o $(($modsstarted)) -ne $(($modscompleted)) ];
modscompleted=`cat $SBXHOME/modscompleted.log | awk '/0x/ {print strtonum($1)}'`
echo
+ date +'%H:%M:%S'
echo "modsstarted log command"
- echo "autosim $NOWIN --simcmd \"print ((system_cmp0.phys_mem).read 0x$mods_started_addr 0x08)\" 1> $SBXHOME/modsstarted.log 2> /dev/null"
- autosim $NOWIN --simcmd "print ((system_cmp0.phys_mem).read 0x$mods_started_addr 0x08)" 1> $SBXHOME/modsstarted.log 2> /dev/null
+ echo "autosim $NOWIN --simcmd \"print ((system_cmp0.phys_mem).read 0x$mods_started_addr 0x08)\" 1> $SBXHOME/modsstarted.log 2> /dev/null"
+ autosim $NOWIN --simcmd "print ((system_cmp0.phys_mem).read 0x$mods_started_addr 0x08)" 1> $SBXHOME/modsstarted.log 2> /dev/null
+ date +'%H:%M:%S'
echo
echo "modsstarted command"
@@ -356,18 +362,35 @@ while [ $(($modsstarted)) -lt 1 -o $(($modsstarted)) -ne $(($modscompleted)) ];
echo "ModulesStarted:ModulesCompleted => $modsstarted:$modscompleted"
- # @TODO RTC:149210 temporary fix for autosim hangs on real code errors. For some reason
- # when we hit an actual bug and simics halts, the autosim commands hang
- # causing this loop to take >8 hours.
- if [ -z $modsstarted ] && [ -z $modscompleted ]; then
- echo "ERROR: autosim hanging on real code errors, temporarily catching early"
- echo "See archived hbTracMerg for more info"
- exit 1
+ # For code coverage, sometimes simics takes a while to respond as it dumps data.
+ # Allow it to continue if this condition is seen.
+ if [[ -z "${HOSTBOOT_PROFILE}" ]]; then
+ # @TODO RTC:149210 temporary fix for autosim hangs on real code errors. For some reason
+ # when we hit an actual bug and simics halts, the autosim commands hang
+ # causing this loop to take >8 hours.
+ if [ -z $modsstarted ] && [ -z $modscompleted ]; then
+ echo "ERROR: autosim hanging on real code errors, temporarily catching early"
+ echo "See archived hbTracMerg for more info"
+ exit 1
+ fi
+ fi
+
+ if [[ -z "${HOSTBOOT_PROFILE}" ]]; then
+ if [[ "$CHIP" == "AXONE" ]]; then
+ # 75 minutes for axone
+ loop_timeout=225
+ else
+ # 50 minutes by default
+ loop_timeout=150
+ fi
+ else
+ # Increase timeout to 166 minutes for code coverage
+ loop_timeout=500
fi
- if [ "$loopcount" -ge 150 ]; then
+ if [ "$loopcount" -ge "$loop_timeout" ]; then
timestamp=`date +'%H:%M:%S'`
- echo "$timestamp ERROR: timed out after 50 minutes waiting for until test completion"
+ echo "$timestamp ERROR: timed out waiting for until test completion"
autosim $NOWIN --simcmd "hb-Ps with-backtrace"
timeout=$(($modsstarted - $modscompleted))
break
@@ -467,6 +490,15 @@ if [ $? -ne 0 ] ; then
echo "ERROR: Unable to run $?"
fi
+if [[ ! -z "${HOSTBOOT_PROFILE}" ]]; then
+ # After simics test are complete, dump data.
+ echo "====> hb-Gcov..."
+ autosim $NOWIN --simcmd "hb-Gcov" --timeout 300
+ if [ $? -ne 0 ] ; then
+ echo "ERROR: Unable to run $?"
+ fi
+fi
+
########################################################
## done. Stop the simulation
########################################################
diff --git a/src/build/citest/build-script b/src/build/citest/build-script
index 7510d76c9..7198ed5b2 100755
--- a/src/build/citest/build-script
+++ b/src/build/citest/build-script
@@ -24,10 +24,62 @@
#
# IBM_PROLOG_END_TAG
+usage="
+$(basename "$0") [-h|--help] [--skipCxxTests] [--skipCopyrightCheck]
+
+Description:
+ The original use of this script was for the Hostboot standalone CI job,
+ so by default it will run a copyright check, then compile hostboot and
+ populate an ODE sandbox and run the CXX test suite in standalone simics.
+
+ Flags have been added to skip the copyright checks and the cxx tests
+ for cases where we only want to get a populated sandbox.
+
+Expectations:
+ This script is expected to be ran from the top level of the
+ hostboot directory. (ie src/build/citest/build-script <params>). It will
+ look at env variables PROJECT_ROOT, WORKSPACE, SANDBOXNAME, SANDBOXROOT,
+ CHIP, PNOR, CONFIG_FILE, and HOSTBOOT_PROFILE.
+
+Optional Flags:
+ -h|--help shows this help text
+ --skipCxxTests skips the execution of the cxx test suite
+ --skipCopyrightCheck skips the execution of the copyright check
+"
+
if [ -z $PROJECT_ROOT ]; then
source "$WORKSPACE/env.bash"
fi
+while [[ $# -gt 0 ]]
+do
+key="$1"
+
+case $key in
+ --skipCopyrightCheck)
+ SKIP_CR_CHECK=1
+ shift # past argument
+ ;;
+ --skipCxxTests)
+ SKIP_CXX_TESTS=1
+ shift # past argument
+ ;;
+ -h|--help)
+ echo "$usage"
+ exit 0
+ ;;
+ *)
+ echo "
+!!! Invalid argument \"$1\" passed into ${0} !!!!"
+ echo "$usage"
+ exit 22
+ ;;
+esac
+done
+
+echo "SKIP_CR_CHECK = ${SKIP_CR_CHECK}"
+echo "SKIP_CXX_TESTS = ${SKIP_CXX_TESTS}"
+
source "$PROJECT_ROOT/src/build/citest/setup-env"
echo "#--------------------------------"
echo "SANDBOXROOT=$SANDBOXROOT"
@@ -41,32 +93,49 @@ echo "#--------------------------------"
# Force simics into Secure Mode
export SECURITY_HW_POLICY="1"
-# Check copyright.
-check-copyright > copyright.log 2>&1
-if [ $? -eq 0 ]; then
- echo "----Copyright check succeeded."
- cat copyright.log
-else
- echo "----Copyright check failed."
- cat copyright.log
- exit -1
+if [ -z "$SKIP_CR_CHECK" ]; then
+ # Check copyright.
+ check-copyright > copyright.log 2>&1
+ if [ $? -eq 0 ]; then
+ echo "----Copyright check succeeded."
+ cat copyright.log
+ else
+ echo "----Copyright check failed."
+ cat copyright.log
+ exit -1
+ fi
fi
-
# Create simics sandbox.
create-sandbox > create-sandbox.log 2>&1 &
CREATESANDBOX_PID=$!
-my_date=$(date)
-# Build Hostboot.
+# normal build is empty quotes
+build_opt=""
+# code coverage
+if [[ ! -z "${HOSTBOOT_PROFILE}" ]]; then
+ build_opt="gcov"
+# static analysis
+elif [[ ! -z "${HOSTBOOT_CPPCHECK}" ]]; then
+ build_opt="cppcheck"
+ COMPILE_ONLY=1
+fi
+# Build Hostboot
+start_time=$(date)
echo "#--------------------------------"
-printf "\n\n$(date): STARTED running \"make -j32\"\n\n"
+printf "\n\n$(date): STARTED running \"make -j32 $build_opt\"\n\n"
echo "#--------------------------------"
-make -j32 || exit -1
+make -j32 $build_opt || exit -1
+make_rc=$?
echo "#--------------------------------"
-printf "\n\nrc=$?: $(date): FINISHED running (\"make -j32\" was started at $my_date)\n\n"
+printf "\n\nrc=$make_rc: $(date): FINISHED running (\"make -j32 $build_opt\" was started at $start_time)\n\n"
echo "#--------------------------------"
+if [[ ! -z "${COMPILE_ONLY}" ]]; then
+ echo "Compile only"
+ exit $make_rc
+fi
+
# Check sandbox create completion.
wait $CREATESANDBOX_PID
if [ $? -eq 0 ]; then
@@ -79,48 +148,62 @@ else
fi
# Add Hostboot files to simics sandbox.
-my_date=$(date)
+start_time=$(date)
echo "#--------------------------------"
-printf "\n\n$(date): STARTED running populate-sandbox....\n\n"
+printf "\n\n$start_time: STARTED running populate-sandbox....\n\n"
echo "#--------------------------------"
populate-sandbox || exit -1
echo "#--------------------------------"
-printf "\n\nrc=$?: $(date): FINISHED running (\"populate-sandbox\" was started at $my_date)\n\n"
+printf "\n\nrc=$?: $(date): FINISHED running (\"populate-sandbox\" was started at $start_time)\n\n"
echo "#--------------------------------"
-if [ "$CHIP" == "FSPBUILD" ];
-then
- # Start errl parser building.
- my_date=$(date)
- printf "\n\n$(date): STARTED running \"build-errl-parsers\"\n\n"
- build-errl-parsers > errl-parsers.log 2>&1 &
- ERRLPARSERS_PID=$!
-
- # Check errl parser completion.
- wait $ERRLPARSERS_PID
- if [ $? -ne 0 ]; then
- echo "----Error parsers failed."
- cat errl-parsers.log
- exit -1
- else
- printf "\n\n$(date): FINISHED running (\"build-errl-parsers\" was started at $my_date)\n\n"
- fi
-
-
-else
- printf "2) CHIP=$CHIP"
- echo "CHIP3=$CHIP"
-
-
- # Start CxxTest Simics execution.
- my_date=$(date)
- echo "#--------------------------------"
- printf "\n\n$(date): STARTED running cxxtest-start.sh....\n\n"
- echo "#--------------------------------"
- cxxtest-start.sh || exit -1
- echo "#--------------------------------"
- printf "\n\nrc=$?: $(date): FINISHED running (\"cxxtest-start.sh\" was started at $my_date)\n\n"
- echo "#--------------------------------"
+if [ -z "$SKIP_CXX_TESTS" ]; then
+
+ if [ "$CHIP" == "FSPBUILD" ]; then
+ # Start errl parser building.
+ start_time=$(date)
+ printf "\n\n$start_time: STARTED running \"build-errl-parsers\"\n\n"
+ build-errl-parsers > errl-parsers.log 2>&1 &
+ ERRLPARSERS_PID=$!
+
+ # Check errl parser completion.
+ wait $ERRLPARSERS_PID
+ if [ $? -ne 0 ]; then
+ echo "----Error parsers failed."
+ cat errl-parsers.log
+ exit -1
+ else
+ printf "\n\n$(date): FINISHED running (\"build-errl-parsers\" was started at $start_time)\n\n"
+ fi
+
+
+ else
+ printf "2) CHIP=$CHIP"
+ echo "CHIP3=$CHIP"
+
+ # Start CxxTest Simics execution.
+ start_time=$(date)
+ echo "#--------------------------------"
+ printf "\n\n$start_time: STARTED running cxxtest-start.sh....\n\n"
+ echo "#--------------------------------"
+ cxxtest-start.sh || exit -1
+ echo "#--------------------------------"
+ printf "\n\nrc=$?: $(date): FINISHED running (\"cxxtest-start.sh\" was started at $start_time)\n\n"
+ echo "#--------------------------------"
+
+ fi
fi
+if [[ ! -z "${HOSTBOOT_PROFILE}" ]]; then
+ # Generate the code coverage report. Located obj/gcov_report
+ # Jenkins will artifact and can display html report
+ start_time=$(date)
+ echo "#--------------------------------"
+ printf "\n\n$start_time: STARTED running \"make lcov\"\n\n"
+ echo "#--------------------------------"
+ make lcov || exit -1
+ echo "#--------------------------------"
+ printf "\n\nrc=$?: $(date): FINISHED running (\"make lcov\" was started at $start_time)\n\n"
+ echo "#--------------------------------"
+fi
diff --git a/src/build/citest/create-sandbox b/src/build/citest/create-sandbox
index 0018e4422..b07158f02 100755
--- a/src/build/citest/create-sandbox
+++ b/src/build/citest/create-sandbox
@@ -78,11 +78,15 @@ if [ "$MACHINE" != "NIMBUS" ] && [ "$MACHINE" != "CUMULUS" ] && \
[ "$MACHINE" != "CUMULUS_CDIMM" ] && [ "$MACHINE" != "FSPBUILD" ];
then
SIMICS_LEVEL=`cat ${PROJECT_ROOT}/src/build/citest/etc/simbuild`
+ EECACHE_PREBUILT=`cat ${PROJECT_ROOT}/src/build/citest/etc/eecache_prebuilt`
echo "mkdir -p ${SANDBOXBASE}/simics"
execute_in_sandbox "mkdir -p ${SANDBOXBASE}/simics" "ppc"
echo "tar ${SIMICS_LEVEL} -C ${SANDBOXBASE}/simics/"
execute_in_sandbox "tar -xf ${SIMICS_LEVEL} -C ${SANDBOXBASE}/simics/" "ppc"
+ echo "cd ${SANDBOXBASE}/simics/ && ./INSTALL.sh"
execute_in_sandbox "cd ${SANDBOXBASE}/simics/ && ./INSTALL.sh" "ppc"
+ echo "cp ${EECACHE_PREBUILT} ${SANDBOXBASE}/simics/eecache_prebuilt.bin.ecc"
+ execute_in_sandbox "cp ${EECACHE_PREBUILT} ${SANDBOXBASE}/simics/eecache_prebuilt.bin.ecc" "ppc"
else
execute_in_sandbox "start_simics -no_start -machine $MACHINE -batch_mode" \
"ppc" || exit -1
diff --git a/src/build/citest/cxxtest-start.sh b/src/build/citest/cxxtest-start.sh
index dcb25c201..b34c744d8 100755
--- a/src/build/citest/cxxtest-start.sh
+++ b/src/build/citest/cxxtest-start.sh
@@ -38,7 +38,7 @@ if [ "$MACHINE" != "NIMBUS" ] && [ "$MACHINE" != "CUMULUS" ] && \
[ "$MACHINE" != "CUMULUS_CDIMM" ] && [ "$MACHINE" != "FSPBUILD" ];
then
export PATH=$PATH:$SANDBOXBASE/simics/
- export START_SIMICS_CMD="runsim -m $MACHINE hb_script_to_run=$SANDBOXBASE/obj/ppc/simu/scripts/hbfw/startup.simics pnor_img=$SANDBOXBASE/obj/ppc/hbfw/img/axone.pnor sbe_seeprom_img=$SANDBOXBASE/images/ppc/lab/flash/sbe_seeprom_p9a_10.bin.ecc num_procs=1 vpd_proc=vpd/images/99a8c3fe4e5c74798f5bd4212f3d9a2a"
+ export START_SIMICS_CMD="runsim -m $MACHINE hb_script_to_run=$SANDBOXBASE/obj/ppc/simu/scripts/hbfw/startup.simics pnor_img=$SANDBOXBASE/obj/ppc/hbfw/img/axone.pnor sbe_seeprom_img=$SANDBOXBASE/images/ppc/lab/flash/sbe_seeprom_p9a_10.bin.ecc num_procs=2 enable_lpc_console=TRUE"
fi
# Front end to autocitest - script to execute unit tests under simics.
diff --git a/src/build/citest/etc/bbuild b/src/build/citest/etc/bbuild
index 873e0f4bd..a6ac16e07 100644
--- a/src/build/citest/etc/bbuild
+++ b/src/build/citest/etc/bbuild
@@ -1 +1 @@
-/esw/fips930/Builds/b0121a_1904.930
+/esw/fips940/Builds/b0516a_1921.940
diff --git a/src/import/chips/ocmb/gemini/procedures/hwp/memory/00gem_common.mk b/src/build/citest/etc/cppcheck
index 15fcba892..f92ac3604 100644
--- a/src/import/chips/ocmb/gemini/procedures/hwp/memory/00gem_common.mk
+++ b/src/build/citest/etc/cppcheck
@@ -1,7 +1,8 @@
+#!/bin/bash
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
-# $Source: src/import/chips/ocmb/gemini/procedures/hwp/memory/00gem_common.mk $
+# $Source: src/build/citest/etc/cppcheck $
#
# OpenPOWER HostBoot Project
#
@@ -22,3 +23,5 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+
+export CPPCHECK_COMMIT="4939e0c3086151033bd491bb2df72f7728a4c037"
diff --git a/src/build/citest/etc/eecache_prebuilt b/src/build/citest/etc/eecache_prebuilt
new file mode 100644
index 000000000..e7ff59666
--- /dev/null
+++ b/src/build/citest/etc/eecache_prebuilt
@@ -0,0 +1 @@
+/gsa/ausgsa/projects/h/hostboot/eecache_prebuilt/10_02_19_eecache_prebuilt.bin.ecc
diff --git a/src/build/citest/etc/simbuild b/src/build/citest/etc/simbuild
index 31d4a6f2e..ba464d4c5 100644
--- a/src/build/citest/etc/simbuild
+++ b/src/build/citest/etc/simbuild
@@ -1 +1 @@
-/gsa/ausgsa/projects/h/hostboot/simbuild/04_08_19_973eb4_simics.tar.gz
+/gsa/ausgsa/projects/h/hostboot/simbuild/axone/2019-11-11_f0c353_simics.tar.gz
diff --git a/src/build/citest/etc/workarounds.postsimsetup b/src/build/citest/etc/workarounds.postsimsetup
index d904f6c3b..26cc2bd03 100755
--- a/src/build/citest/etc/workarounds.postsimsetup
+++ b/src/build/citest/etc/workarounds.postsimsetup
@@ -6,7 +6,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2011,2019
+# Contributors Listed Below - COPYRIGHT 2011,2020
# [+] International Business Machines Corp.
#
#
@@ -39,5 +39,8 @@ mkdir -p $sb/simu/configs/
grep -v PROC_EC $BACKING_BUILD/src/simu/configs/P9_NIMBUS.config > $sb/simu/configs/P9_NIMBUS.config
echo "SETENV PROC_EC 22" >> $sb/simu/configs/P9_NIMBUS.config
+# TODO RTC:215621
+# remove when simics gets dimmspd.dat updated
+mkdir -p $sb/../simics/import/vpd/
+cp /gsa/ausgsa/projects/h/hostboot/.binary_cache/data/f6f5b778c406883e1b392b311350a1e83583e15a $sb/../simics/import/vpd/dimmspd.dat
-##########################################################################
diff --git a/src/build/citest/setup-env b/src/build/citest/setup-env
index 21133ef67..e82032d8a 100755
--- a/src/build/citest/setup-env
+++ b/src/build/citest/setup-env
@@ -26,6 +26,7 @@
export CITESTPATH=${PROJECT_ROOT}/src/build/citest
export PATH=${CITESTPATH}:${PATH}
+export CXXPATH=/opt/rh/devtoolset-3/root/usr/bin
# Determine backing build.
export BACKING_BUILD=`cat ${CITESTPATH}/etc/bbuild`
diff --git a/src/build/configs/simics_axone.config b/src/build/configs/simics_axone.config
index 3d044edcc..c3f33e583 100644
--- a/src/build/configs/simics_axone.config
+++ b/src/build/configs/simics_axone.config
@@ -1,35 +1,27 @@
-# Force DJVPD read/write to use EEPROM layer instead of VPD cache
-set DJVPD_READ_FROM_HW
-set DJVPD_WRITE_TO_HW
-unset DJVPD_READ_FROM_PNOR
-unset DJVPD_WRITE_TO_PNOR
-
-# Force MEMVPD read/write to PNOR ( No actual hardware )
-set MEMVPD_READ_FROM_PNOR
-set MEMVPD_WRITE_TO_PNOR
-unset MEMVPD_READ_FROM_HW
-unset MEMVPD_WRITE_TO_HW
-
-# Force MVPD read/write to use EEPROM layer instead of VPD cache
-# (not working because shoddy MVPD currently)
-#set MVPD_READ_FROM_HW
-#set MVPD_WRITE_TO_HW
-set MVPD_READ_FROM_PNOR
-set MVPD_WRITE_TO_PNOR
+# Have Planar VPD
+set HAVE_PVPD
+
+# Don't have any memory buffer VPD
+unset HAVE_MBVPD
#set to run cxx testcases during boot
unset EARLY_TESTCASES
-#skip enabling checkstop analysis until OCC is ready in simics
-unset IPLTIME_CHECKSTOP_ANALYSIS
+#Enable checkstop analysis for IPL failures
+set IPLTIME_CHECKSTOP_ANALYSIS
#enable EEPROM caching
set SUPPORT_EEPROM_CACHING
-#Try to keep a list of things this does
-# - skipping setting voltages in istep 8.12, nothing on other side of AVSbus
-# in simics currently.
+# Allows us to put in workarounds specifically for Axone bringup
set AXONE_BRING_UP
# Set this to pull in Axone on code (such as P9A/EXP MSS code)
-set AXONE \ No newline at end of file
+set AXONE
+
+# Enable Console
+set CONSOLE
+set CONSOLE_OUTPUT_ERRORDISPLAY
+
+# OMIs were introduced in Axone and will be in P10 also
+set SUPPORT_OMI
diff --git a/src/build/debug/Hostboot/BlTrace.pm b/src/build/debug/Hostboot/BlTrace.pm
index 5fd8baf18..9d9dc9988 100644
--- a/src/build/debug/Hostboot/BlTrace.pm
+++ b/src/build/debug/Hostboot/BlTrace.pm
@@ -83,6 +83,7 @@ my %traceText = (
"FA" => "PNOR Access getHBBSection findTOC no HBB section",
"FB" => "main verifyBaseImage failed",
"FC" => "main verifyBaseImage secure rom invalid",
+ "FD" => "PNOR Access findTOC handleMMIO LPC ERR returned",
);
sub formatTrace
diff --git a/src/build/debug/Hostboot/Dump.pm b/src/build/debug/Hostboot/Dump.pm
index 705638aa2..90b445df9 100755
--- a/src/build/debug/Hostboot/Dump.pm
+++ b/src/build/debug/Hostboot/Dump.pm
@@ -6,7 +6,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2018
+# Contributors Listed Below - COPYRIGHT 2012,2019
# [+] International Business Machines Corp.
#
#
@@ -106,6 +106,13 @@ sub main
$debug = 1;
}
+ # Parse 'quiet' option.
+ my $quiet = 0;
+ if (defined $args->{"quiet"})
+ {
+ $quiet = 1;
+ }
+
# Check for a different output directory
my $outdir = "./";
if (defined $args->{"outdir"})
@@ -128,7 +135,7 @@ sub main
open( OUTFH, ">$hbDumpFile" ) or die "can't open $hbDumpFile: $!\n";
binmode(OUTFH);
- ::userDisplay "Using HRMOR=". ::getHRMOR() . "\n";
+ ::userDisplay "Using HRMOR=". sprintf("0x%X",::getHRMOR()) . "\n";
# Read memory regions and output to file.
foreach my $state (@{$memory_states{int $memstate}})
@@ -152,7 +159,7 @@ sub main
$curlength = $length_remaining;
}
- ::userDisplay (sprintf "...%x@%x\n", $curlength, $curstart);
+ ::userDisplay (sprintf "...%x@%x\n", $curlength, $curstart) if !$quiet;
my $data = ::readData($curstart, $curlength);
seek OUTFH, $curstart, SEEK_SET;
@@ -187,6 +194,7 @@ sub helpInfo
options => {
"outdir=<path>" => ["Output directory for dump file"],
"debug" => ["More debug output."],
+ "quiet" => ["Less output."],
},
);
}
diff --git a/src/build/debug/Hostboot/Gcov.pm b/src/build/debug/Hostboot/Gcov.pm
index 84df2f9f9..48e71d66b 100755
--- a/src/build/debug/Hostboot/Gcov.pm
+++ b/src/build/debug/Hostboot/Gcov.pm
@@ -1,4 +1,3 @@
-#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
@@ -6,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2015
+# Contributors Listed Below - COPYRIGHT 2012,2019
# [+] International Business Machines Corp.
#
#
@@ -23,15 +22,18 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+#!/usr/bin/perl
use strict;
+use warnings;
use File::Path;
use File::Basename;
+use IO::Handle;
package Hostboot::Gcov;
use Hostboot::_DebugFrameworkVMM qw(NotFound NotPresent getPhysicalAddr);
use Exporter;
-our @EXPORT_OK = ('main');
+our @EXPORT_OK = ('init', 'main', 'parseGcovInfo');
# NOTE:
#
@@ -50,26 +52,37 @@ our @EXPORT_OK = ('main');
use constant GCOV_EXTENDED_IMAGE_ADDRESS => (1024 * 1024 * 1024);
use constant GCOV_INFO_HEAD_SYMBOLNAME => "_gcov_info_head";
+use constant GCOV_INFO_MAGIC_SYMBOLNAME => "_gcov_info_magic";
+use constant GCOV_MAGIC_IDENTIFIER => 0xbeefb055;
-use constant GCOV_INFO_VERSION_OFFSET => 0;
-use constant GCOV_INFO_NEXT_OFFSET => GCOV_INFO_VERSION_OFFSET + 8;
-use constant GCOV_INFO_TIMESTAMP_OFFSET => GCOV_INFO_NEXT_OFFSET + 8;
-use constant GCOV_INFO_FILENAME_OFFSET => GCOV_INFO_TIMESTAMP_OFFSET + 8;
-use constant GCOV_INFO_NFUNCTIONS_OFFSET => GCOV_INFO_FILENAME_OFFSET + 8;
-use constant GCOV_INFO_FUNCTIONS_OFFSET => GCOV_INFO_NFUNCTIONS_OFFSET + 8;
-use constant GCOV_INFO_CTRMASK_OFFSET => GCOV_INFO_FUNCTIONS_OFFSET + 8;
-use constant GCOV_INFO_COUNTS_OFFSET => GCOV_INFO_CTRMASK_OFFSET + 8;
-
-use constant GCOV_FNINFO_IDENT_OFFSET => 0;
-use constant GCOV_FNINFO_CHECKSUM_OFFSET => GCOV_FNINFO_IDENT_OFFSET + 4;
-use constant GCOV_FNINFO_NCTRS_OFFSET => GCOV_FNINFO_CHECKSUM_OFFSET + 4;
+use constant GCOV_COUNTERS_492 => 9;
+use constant SIZEOF_PTR => 8;
+use constant SIZEOF_UINT64 => 8;
-use constant GCOV_CTRINFO_COUNT_OFFSET => 0;
-use constant GCOV_CTRINFO_VALUEPTR_OFFSET => GCOV_CTRINFO_COUNT_OFFSET + 8;
-
-use constant GCOV_GCDA_MAGIC_VALUE => 0x67636461;
use constant GCOV_FUNCTION_TAG => 0x01000000;
use constant GCOV_COUNTERS_TAG => 0x01a10000;
+use constant GCOV_PROGRAM_SUMMARY_TAG => 0xa3000000;
+
+use constant GCOV_GCDA_MAGIC_VALUE => 0x67636461;
+
+# See gcov.h for the structs (gcov_info, gcov_fn_info) from which
+# these offsets derive
+
+use constant GCOV_INFO_VERSION_OFFSET_492 => 0;
+use constant GCOV_INFO_NEXT_OFFSET_492 => 8;
+use constant GCOV_INFO_TIMESTAMP_OFFSET_492 => 16;
+use constant GCOV_INFO_FILENAME_OFFSET_492 => 24;
+use constant GCOV_INFO_MERGE_OFFSET_492 => 32;
+use constant GCOV_INFO_N_FUNCTIONS_OFFSET_492 => 32 + (9 * 8);
+use constant GCOV_INFO_FUNCTIONS_OFFSET_492 => GCOV_INFO_N_FUNCTIONS_OFFSET_492 + 8;
+
+use constant GCOV_FN_INFO_IDENT_OFFSET_492 => 8;
+use constant GCOV_FN_INFO_LINENO_CHECKSUM_OFFSET_492 => 12;
+use constant GCOV_FN_INFO_CFG_CHECKSUM_OFFSET_492 => 16;
+use constant GCOV_FN_INFO_CTR_INFO_OFFSET_492 => 24;
+
+use constant GCOV_CTR_INFO_NUM_OFFSET_492 => 0;
+use constant GCOV_CTR_INFO_VALUES_OFFSET_492 => 8;
# In memory format:
# GCC creates a 'gcov_info' structure for each .o file. The info
@@ -134,20 +147,43 @@ use constant GCOV_COUNTERS_TAG => 0x01a10000;
# uint64_ts, containing instrumented counts, for the preceeding function.
# Global of where we want the output to go.
-our $output_dir;
our $debug_mode;
+our $hbicore_extended_bin_file;
+our $hbicore_extended_bin_file_size;
BEGIN
{
$debug_mode = 0;
- $output_dir = "";
}
-return 1;
+
+sub init
+{
+ # TODO: We need to figure out how to handle reading data from
+ # HBB/HBRT for when those are instrumented. One hurdle is being
+ # able to determine from an address what module it belongs to,
+ # because HBB/HBI/HBRT are not necessarily laid out in memory as
+ # they are in PNOR or anywhere else.
+
+ my $hbicore_extended_bin_fname = "$ENV{SANDBOXROOT}/$ENV{SANDBOXNAME}/src/hbfw/img/hostboot_extended.bin";
+
+ userDebug("Opening " . $hbicore_extended_bin_fname . " for HBI\n");
+
+ unless (open($hbicore_extended_bin_file, "< $hbicore_extended_bin_fname")) {
+ ::userDisplay "Failed to open $hbicore_extended_bin_fname, exiting\n";
+ return 0;
+ }
+
+ binmode($hbicore_extended_bin_file);
+
+ $hbicore_extended_bin_file_size = -s $hbicore_extended_bin_fname;
+
+ return 1;
+}
sub main
{
- # Pick a new output directory based on the time.
- $output_dir = sprintf "gcov.output.%d/", time;
- File::Path::mkpath($output_dir);
+ if (!init()) {
+ return;
+ }
# Find all the hostboot modules.
my @modules = getModules();
@@ -160,7 +196,10 @@ sub main
my $pwd = `pwd`;
chomp $pwd;
- ::userDisplay "GCOV output written to: $pwd/$output_dir\n";
+
+ close $hbicore_extended_bin_file or die;
+
+ ::userDisplay("GCOV info extraction complete.\n");
}
sub parseModuleGcov
@@ -168,8 +207,23 @@ sub parseModuleGcov
my $module = shift;
::userDisplay "Extracting GCOV info for ".$module."\n";
+ # Search for magic symbol.
+ my ($gcov_magic, $unused) =
+ ::findSymbolAddress($module.GCOV_INFO_MAGIC_SYMBOLNAME);
+
+ if (!defined($gcov_magic))
+ {
+ $gcov_magic = 0;
+ }
+
+ if ($gcov_magic == 0 || read32($gcov_magic, 1) != GCOV_MAGIC_IDENTIFIER)
+ {
+ ::userDisplay "\tgcov_magic at address " . (sprintf "0x%x", $gcov_magic) . " is incorrect. Skipped.\n";
+ return;
+ }
+
# Search for gcov_info chain symbol.
- my ($gcov_info, $unused) =
+ my ($gcov_info, $unused2) =
::findSymbolAddress($module.GCOV_INFO_HEAD_SYMBOLNAME);
userDebug("\tFound info at 0x" . (sprintf "%x", $gcov_info) . "\n");
@@ -181,7 +235,7 @@ sub parseModuleGcov
if (($gcov_info eq NotFound) || ($gcov_info eq NotPresent))
{
- ::userDisplay "\tModule data is not present.\n";
+ ::userDisplay "\tModule data is not present, module might have been unloaded, skipping.\n";
return;
}
}
@@ -189,7 +243,7 @@ sub parseModuleGcov
# Check that we found the gcov_info chain.
if ($gcov_info == 0)
{
- ::userDisplay "\tUnable to find gcov_info chain. Skipped.\n";
+ ::userDisplay "\tUnable to find gcov_info chain, module might hvae been unloaded. Skipping.\n";
return;
}
@@ -202,39 +256,44 @@ sub parseGcovInfo
my $info_ptr = shift;
return if (0 eq $info_ptr);
- my $filename = readStr(read64($info_ptr + GCOV_INFO_FILENAME_OFFSET));
- userDebug("\tFile = ".$filename."\n");
+ userDebug("\tReading filename pointer from offset " . (sprintf "0x%x", ($info_ptr + GCOV_INFO_FILENAME_OFFSET_492)) . "\n");
- my $version = read32($info_ptr + GCOV_INFO_VERSION_OFFSET);
- my $stamp = read32($info_ptr + GCOV_INFO_TIMESTAMP_OFFSET);
+ my $filename_addr = read64($info_ptr + GCOV_INFO_FILENAME_OFFSET_492);
- my $func_count = read32($info_ptr + GCOV_INFO_NFUNCTIONS_OFFSET);
- userDebug("\tFunction Count = ".$func_count."\n");
+ userDebug("\tReading filename from offset " . (sprintf "0x%x", $filename_addr) . "\n");
- my $funcs = read64($info_ptr + GCOV_INFO_FUNCTIONS_OFFSET);
- userDebug("\tFunc Address = ".(sprintf "%x", $funcs)."\n");
+ my $filename = readStr($filename_addr);
- my $ctrmask = read32($info_ptr + GCOV_INFO_CTRMASK_OFFSET);
- if ($ctrmask % 2) # Check that COUNTER_ARCS is turned on.
- {
- # COUNTER_ARCS is on. Create file, find arc-values array,
- # parse functions.
+ if ($filename) {
+ ::userDisplay("\tFile = ".$filename."\n");
- my $fd = createGcovFile($filename, $version, $stamp);
+ my $version = read32($info_ptr + GCOV_INFO_VERSION_OFFSET_492);
+ my $stamp = read32($info_ptr + GCOV_INFO_TIMESTAMP_OFFSET_492);
- my $arcs_ptr = read64($info_ptr + GCOV_INFO_COUNTS_OFFSET +
- GCOV_CTRINFO_VALUEPTR_OFFSET);
- parseGcovFuncs($fd, $funcs, $func_count, $ctrmask, $arcs_ptr);
+ my $func_count = read32($info_ptr + GCOV_INFO_N_FUNCTIONS_OFFSET_492);
+ userDebug("\tFunction Count = ".$func_count."\n");
- close $fd;
- }
- else
- {
- userDebug("COUNTER_ARCS is missing!\n");
+ my $funcs = read64($info_ptr + GCOV_INFO_FUNCTIONS_OFFSET_492, 1);
+
+ if ($funcs ne NotFound && $funcs ne NotPresent) {
+ userDebug("\tFunc Address = ".(sprintf "0x%x", $funcs)."\n");
+
+ if ($version ne NotFound && $stamp ne NotFound && $func_count ne NotFound) {
+ my $fd = createGcovFile($filename, $version, $stamp);
+
+ parseGcovFuncs($fd, $funcs, $func_count);
+
+ close $fd or die $!;
+ }
+ } else {
+ userDebug("\tFunc Address is NULL, skipping\n");
+ }
+ } else {
+ userDebug("\tCannot read filename, skipping\n");
}
# Look for next .o in gcov_info chain, parse.
- my $next = read64($info_ptr + GCOV_INFO_NEXT_OFFSET);
+ my $next = read64($info_ptr + GCOV_INFO_NEXT_OFFSET_492);
parseGcovInfo($next);
}
@@ -243,62 +302,95 @@ sub parseGcovFuncs
my $fd = shift;
my $func_ptr = shift;
my $func_count = shift;
- my $mask = shift;
- my $val_ptr = shift;
- my $fn_offset = 0;
+ my $GCOV_COUNTERS_SUMMABLE_492 = 1;
- # Need to calculate the number of counters based on the bits on in
- # the 'mask'. This is used to determine the size of the function
- # descriptor object.
- my $counters = 0;
- {
- my $_mask = $mask;
+ print $fd pack('l', GCOV_PROGRAM_SUMMARY_TAG); # data.program.header.tag
- while (0 != $_mask)
- {
- $counters++;
- $_mask = ($_mask >> 1);
- }
- }
+ # for each GCOV_COUNTERS_SUMMABLE we have ten int32 (num, runs, and bitvector{8})
+ # plus three int64 (sum, max, sum_max) i.e. 10 + 3*2
+ # data.unit.header.length is the number of int32's we have following.
+ print $fd pack('l', 1 + $GCOV_COUNTERS_SUMMABLE_492 * (10 + 3 * 2)); # data.unit.header.length;
- userDebug("\tCounters = ".$counters."\n");
+ print $fd pack('l', 0); # data.summary:object.checksum (must be 0 according to docs)
- # Round up the counter count to the nearest two for alignment of the
- # function descriptor object.
- if ($counters % 2)
- {
- $counters++;
- }
- my $func_size = GCOV_FNINFO_CHECKSUM_OFFSET + 4 * $counters;
+ for (my $i = 0; $i < $GCOV_COUNTERS_SUMMABLE_492; $i++) {
+ print $fd pack('l', 0); # data.summary:object.count-summary.num
+ print $fd pack('l', 0); # data.summary:object.count-summary.runs
+ print $fd pack('l', 0); # data.summary:object.count-summary.sum@lo
+ print $fd pack('l', 0); # data.summary:object.count-summary.sum@hi
+ print $fd pack('l', 0); # data.summary:object.count-summary.max@lo
+ print $fd pack('l', 0); # data.summary:object.count-summary.max@hi
+ print $fd pack('l', 0); # data.summary:object.count-summary.sum_max@lo
+ print $fd pack('l', 0); # data.summary:object.count-summary.sum_max@hi
- userDebug("\tFunction size = ".$func_size."\n");
+ print $fd pack('l8', (0) x 8); # data.summary:object.count-summary.histogram.bitvector{8}
+ }
# Iterate through the functions and parse.
for(my $function = 0; $function < $func_count; $function++)
{
- my $func_off = ($func_ptr + $func_size * $function);
- my $ident = read32($func_off + GCOV_FNINFO_IDENT_OFFSET);
- my $chksum = read32($func_off + GCOV_FNINFO_CHECKSUM_OFFSET);
+ userDebug("\tFunction $function of $func_count\n");
+
+ my $fn_info_ptr = read64($func_ptr + SIZEOF_PTR*$function, 1);
+
+ if (($fn_info_ptr eq NotFound) || ($fn_info_ptr eq NotPresent))
+ {
+ userDebug("\tCannot read function info pointer, skipping\n");
+ next;
+ }
+
+ userDebug("\tfn_info_ptr = " . (sprintf "%x", $fn_info_ptr) . "\n");
+
+ my $ident = read32($fn_info_ptr + GCOV_FN_INFO_IDENT_OFFSET_492, 1);
+ my $lineno_chksum = read32($fn_info_ptr + GCOV_FN_INFO_LINENO_CHECKSUM_OFFSET_492, 1);
+ my $cfg_chksum = read32($fn_info_ptr + GCOV_FN_INFO_CFG_CHECKSUM_OFFSET_492, 1);
+ my $ctr_info_ptr = $fn_info_ptr + GCOV_FN_INFO_CTR_INFO_OFFSET_492;
+
+ if ($ident eq NotFound
+ || $lineno_chksum eq NotFound
+ || $cfg_chksum eq NotFound)
+ {
+ userDebug("Skipping because fn_info structure members are not readable\n");
+ next;
+ }
+
+ my $num_ctrs = read32($ctr_info_ptr + GCOV_CTR_INFO_NUM_OFFSET_492, 1);
+ my $ctrs_ptr = read64($ctr_info_ptr + GCOV_CTR_INFO_VALUES_OFFSET_492, 1);
+
+ if ($ctrs_ptr eq NotFound || $num_ctrs eq NotFound)
+ {
+ userDebug("Skipping because counters length isn't mapped\n");
+ next;
+ }
- userDebug("Ident = ".(sprintf "%x", $ident)."\n");
- userDebug("Chksum = ".(sprintf "%x", $chksum)."\n");
+ my $counters = readData($ctrs_ptr, SIZEOF_UINT64 * $num_ctrs);
+
+ userDebug("Ident = ".(sprintf "0x%x", $ident)."\n");
+ userDebug("lineno Chksum = ".(sprintf "0x%x", $lineno_chksum)."\n");
+ userDebug("cfg Chksum = ".(sprintf "0x%x", $cfg_chksum)."\n");
+ userDebug("Num counters = ".(sprintf "%d", $num_ctrs)."\n");
+ userDebug("ctrs_ptr = ".(sprintf "0x%x", $ctrs_ptr)."\n");
+
+ if (($counters eq NotFound) || ($counters eq NotPresent))
+ {
+ userDebug("Skipping because counter data not resident in memory\n");
+ next;
+ }
print $fd pack('l', GCOV_FUNCTION_TAG); # Write function tag.
- print $fd pack('l', 2); # Write size = 2.
+ print $fd pack('l', 3); # Write size = 3.
print $fd pack('l', $ident); # Write ident.
- print $fd pack('l', $chksum); # Write checksum.
-
- my $nctr_val = read32($func_off + GCOV_FNINFO_NCTRS_OFFSET);
- userDebug("N-Counters = ".$nctr_val."\n");
+ print $fd pack('l', $lineno_chksum); # Write checksum.
+ print $fd pack('l', $cfg_chksum); # Write checksum.
print $fd pack('l', GCOV_COUNTERS_TAG); # Write counter tag.
- print $fd pack('l', $nctr_val * 2); # Write counter length.
+ print $fd pack('l', $num_ctrs * 2); # Write counter length.
# Read each counter value, output.
# Read as one big block for performance reasons.
- my $counters = readData($val_ptr + 8*($fn_offset), 8 * $nctr_val);
- for(my $v_idx = 0; $v_idx < $nctr_val; $v_idx++)
+
+ for(my $v_idx = 0; $v_idx < $num_ctrs; $v_idx++)
{
my $val = substr $counters, 0, 8;
$counters = substr $counters, 8;
@@ -306,15 +398,34 @@ sub parseGcovFuncs
$val = unpack("Q", $val);
userDebug("\tValue[$v_idx] = ".$val."\n");
+ my $preex_read_low = read($fd, my $low_word, 4);
+ my $preex_read_high = read($fd, my $high_word, 4);
+
+ if (!defined($preex_read_low) or !(defined($preex_read_high))) {
+ die;
+ }
+ my $preex_read = $preex_read_low + $preex_read_high;
+
+ if ($preex_read == 8)
+ {
+ my $preex_val = (unpack("l", $high_word) << 32) | unpack("l", $low_word);
+
+ $val += $preex_val;
+ }
+
+ if ($preex_read > 0)
+ {
+ seek $fd, -$preex_read, 1;
+ }
+ else
+ {
+ seek $fd, 0, 2;
+ }
+
print $fd pack('l', $val & 0xFFFFFFFF); # Write lower word.
print $fd pack('l', $val >> 32) ; # Write upper word.
}
-
- # We used up a number of counters, so move the offset forward for
- # the next function.
- $fn_offset += $nctr_val;
}
-
}
# The *.gcda filename found in the gcov_info struct is an absolute path to
@@ -330,16 +441,25 @@ sub createGcovFile
my $version = shift;
my $stamp = shift;
- # Change *./../obj/ into obj/, prepend output_dir.
- $name =~ s/.*\/obj\//obj\//;
- $name = $output_dir.$name;
-
- # Make sure everything after 'obj/' exists (create subdirs).
- my $dir = File::Basename::dirname($name);
- File::Path::mkpath($dir);
+ # if the file exists then we update it, if not we create it
+ my $GCOVFILE;
+ if (-e $name)
+ {
+ if (!open($GCOVFILE, "+<$name"))
+ {
+ ::userDisplay("Failed to open $name for reading/writing gcov information\n");
+ die;
+ }
+ }
+ else
+ {
+ if (!open($GCOVFILE, "+>$name"))
+ {
+ ::userDisplay("Failed to open $name for writing gcov information\n");
+ die;
+ }
+ }
- # Create file.
- open(my $GCOVFILE, "> $name");
binmode($GCOVFILE);
# Write out header.
@@ -377,6 +497,22 @@ sub isVirtualAddress
return ($addr >= GCOV_EXTENDED_IMAGE_ADDRESS);
}
+sub readExtImage
+{
+ my $addr = shift;
+ my $amount = shift;
+
+ if ($addr + $amount >= $hbicore_extended_bin_file_size) {
+ return NotFound;
+ }
+
+ seek $hbicore_extended_bin_file, $addr, 0;
+
+ read $hbicore_extended_bin_file, my ($contents), $amount;
+
+ return $contents;
+}
+
# Utility to read a block of data from eithr memory or using the extended
# image file as a fallback if not present in memory.
use constant PAGESIZE => 4096;
@@ -401,8 +537,13 @@ sub readData
my $paddr = getPhysicalAddr($addr);
if ((NotFound eq $paddr) || (NotPresent eq $paddr))
{
- $paddr = $addr - GCOV_EXTENDED_IMAGE_ADDRESS;
- $result = $result.::readExtImage($paddr, $amount);
+ my $tmpdata = readExtImage($addr - GCOV_EXTENDED_IMAGE_ADDRESS, $amount);
+
+ if ($tmpdata eq NotFound) {
+ return NotFound;
+ }
+
+ $result = $result . $tmpdata;
}
else
{
@@ -423,14 +564,27 @@ sub readData
sub read64
{
my $addr = shift;
+ my $fallback = shift;
+
my $old_addr = $addr;
if (isVirtualAddress($addr))
{
$addr = getPhysicalAddr($addr);
if ((NotFound eq $addr) || (NotPresent eq $addr))
{
+ userDebug((sprintf "0x%x", $old_addr). " not translatable 2\n");
+
+ if (!$fallback) {
+ return NotFound;
+ }
+
$addr = $old_addr - GCOV_EXTENDED_IMAGE_ADDRESS;
- my $result = ::readExtImage($addr, 8);
+ my $result = readExtImage($addr, 8);
+
+ if ($result eq NotFound) {
+ return NotFound;
+ }
+
if (::littleendian()) { $result = reverse($result); }
return unpack("Q", $result);
}
@@ -444,14 +598,25 @@ sub read64
sub read32
{
my $addr = shift;
+ my $fallback = shift;
+
my $old_addr = $addr;
if (isVirtualAddress($addr))
{
$addr = getPhysicalAddr($addr);
if ((NotFound eq $addr) || (NotPresent eq $addr))
{
+ userDebug((sprintf "0x%x", $old_addr). "not translatable 3\n");
+
+ if (!$fallback) {
+ return NotFound;
+ }
+
$addr = $old_addr - GCOV_EXTENDED_IMAGE_ADDRESS;
- my $result = ::readExtImage($addr, 4);
+ my $result = readExtImage($addr, 4);
+ if ($result eq NotFound) {
+ return NotFound;
+ }
if (::littleendian()) { $result = reverse($result); }
return unpack("L", $result);
}
@@ -471,8 +636,10 @@ sub read8
$addr = getPhysicalAddr($addr);
if ((NotFound eq $addr) || (NotPresent eq $addr))
{
+ userDebug((sprintf "0x%x", $addr). "not translatable 4\n");
+
$addr = $old_addr - GCOV_EXTENDED_IMAGE_ADDRESS;
- my $result = ::readExtImage($addr, 1);
+ my $result = readExtImage($addr, 1);
return unpack("C", $result);
}
}
@@ -486,31 +653,82 @@ sub readStr
{
my $addr = shift;
my $old_addr = $addr;
+
if (isVirtualAddress($addr))
{
- $addr = $addr - GCOV_EXTENDED_IMAGE_ADDRESS;
+ userDebug("it is a virtual address, addr is " . (sprintf "%x", $addr) . "\n");
+ my $phys_addr = getPhysicalAddr($addr);
- # Virtual address, so need to read 1 byte at a time from the file.
- my $string = "";
- my $byte = 0;
-
- do
+ if ((NotFound eq $phys_addr) || (NotPresent eq $phys_addr))
{
- $byte = ::readExtImage($addr,1);
- $addr = $addr + 1;
+ userDebug("Translation not found, reading from pnor\n");
+ # Virtual address, so need to read 1 byte at a time from the file.
+ my $string = "";
+ my $byte = 0;
- if (unpack("C",$byte) eq 0)
+ do
{
- return $string;
- }
+ $byte = readExtImage($addr - GCOV_EXTENDED_IMAGE_ADDRESS, 1);
- $string = $string.$byte;
+ if ($byte eq NotFound)
+ {
+ return "";
+ }
- } while (1)
+ $addr = $addr + 1;
+
+ if (unpack("C",$byte) eq 0)
+ {
+ return $string;
+ }
+
+ $string = $string.$byte;
+ } while (1);
+ }
+ else
+ {
+ my $string = "";
+ my $byte = 0;
+
+ do
+ {
+ if (($addr & 0xfff) == 0)
+ {
+ # we have to recalculate the physical address
+ # whenever we cross a page boundary
+ $phys_addr = getPhysicalAddr($addr);
+
+ if ((NotFound eq $phys_addr) || (NotPresent eq $phys_addr))
+ {
+ userDebug((sprintf "0x%x", $addr). "not translatable 10\n");
+ return "";
+ }
+ }
+
+ $byte = read8($phys_addr);
+
+ if ($byte eq NotFound)
+ {
+ userDebug("Cannot read byte from physical address\n");
+ return "";
+ }
+
+ $addr += 1;
+ $phys_addr += 1;
+
+ if ($byte != 0)
+ {
+ $string = $string . pack("C", $byte);
+ }
+ } while ($byte != 0);
+
+ return $string;
+ }
}
else
{
- ::readStr($addr);
+ userDebug("it is NOT a virtual address\n");
+ return ::readStr($addr);
}
}
@@ -531,3 +749,5 @@ sub helpInfo
intro => [ "Extracts the GCOV information."],
);
}
+
+1; # Last expression in a perl module must be truthy.
diff --git a/src/build/debug/Hostboot/GcovModuleUnload.pm b/src/build/debug/Hostboot/GcovModuleUnload.pm
new file mode 100644
index 000000000..1a411cc3c
--- /dev/null
+++ b/src/build/debug/Hostboot/GcovModuleUnload.pm
@@ -0,0 +1,69 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/debug/Hostboot/GcovModuleUnload.pm $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+#!/usr/bin/perl
+use strict;
+use File::Path;
+use File::Basename;
+
+package Hostboot::GcovModuleUnload;
+use Hostboot::Gcov qw(parseGcovInfo init);
+
+use Exporter;
+our @EXPORT_OK = ('main', 'parseGcovInfo');
+
+sub main
+{
+ my ($packName, $args) = @_;
+
+ my $gcov_info_address = $args->{"address"};
+
+ ::userDisplay("Dumping gcov module info from " . (sprintf "0x%x", $gcov_info_address) . "\n");
+
+ if ($gcov_info_address <= 0) {
+ ::userDisplay("Can't dump from NULL\n");
+ return -1;
+ }
+
+ if (!Hostboot::Gcov::init()) {
+ return -2;
+ }
+
+ Hostboot::Gcov::parseGcovInfo($gcov_info_address);
+
+ ::userDisplay("Done.\n");
+
+ return 0;
+}
+
+# Debug tool help info.
+sub helpInfo
+{
+ my %info = (
+ name => "GcovModuleUnload",
+ intro => [ "Extracts the GCOV information from modules as they are being unloaded."],
+ );
+}
+
+1; # Last expression in a perl module must be truthy.
diff --git a/src/build/debug/Hostboot/PrintVMM.pm b/src/build/debug/Hostboot/PrintVMM.pm
index 476262d93..57a57a9e2 100644
--- a/src/build/debug/Hostboot/PrintVMM.pm
+++ b/src/build/debug/Hostboot/PrintVMM.pm
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2018
+# Contributors Listed Below - COPYRIGHT 2012,2020
# [+] International Business Machines Corp.
#
#
@@ -73,7 +73,7 @@ sub main
my @segment_manager_addr = ::findPointer("SGMNTMGR",
"Singleton<SegmentManager>::instance()::instance");
- if (not defined @segment_manager_addr)
+ if (not @segment_manager_addr)
{
::userDisplay " VirtualToPhy: Cannot find Device Segment symbol.\n"; die;
}
diff --git a/src/build/debug/Hostboot/_DebugFrameworkVMM.pm b/src/build/debug/Hostboot/_DebugFrameworkVMM.pm
index 128df4ec7..ca323bd32 100755
--- a/src/build/debug/Hostboot/_DebugFrameworkVMM.pm
+++ b/src/build/debug/Hostboot/_DebugFrameworkVMM.pm
@@ -6,7 +6,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2018
+# Contributors Listed Below - COPYRIGHT 2012,2020
# [+] International Business Machines Corp.
#
#
@@ -404,7 +404,7 @@ sub getPhysicalAddr
"Singleton<SegmentManager>::instance()::instance");
- if (not defined @segment_manager_addr)
+ if (not @segment_manager_addr)
{
::userDisplay " VirtualToPhy: Cannot find SegmentManager symbol.\n";
return NotFound;
diff --git a/src/build/debug/eSEL.pl b/src/build/debug/eSEL.pl
index ddce72f50..ed9ef2335 100755
--- a/src/build/debug/eSEL.pl
+++ b/src/build/debug/eSEL.pl
@@ -6,7 +6,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2017,2018
+# Contributors Listed Below - COPYRIGHT 2017,2019
# [+] International Business Machines Corp.
#
#
@@ -588,6 +588,11 @@ sub DecodeObmcEselData
$timestamp_found = 1;
last;
}
+ elsif($next_line =~ /timestamp/)
+ {
+ $timestamp_found = 2;
+ last;
+ }
elsif($next_line =~ /ESEL/ or
$next_line =~ /20 00 04/) # found the next ESEL
{
@@ -601,16 +606,35 @@ sub DecodeObmcEselData
if($timestamp_found)
{
- # strip the "Timestamp", commas, spaces, and the newline
- $next_line =~ s/"Timestamp"://g;
- $next_line =~ s/,//g;
- $next_line =~ s/ //g;
- chomp $next_line;
-
- # convert to date/time (we are given the timestamp in ms, so divide
- # by 1000 to get s).
- $timestamp =
+ if($timestamp_found == 1)
+ {
+ # strip the "Timestamp", commas, spaces, and the newline
+ $next_line =~ s/"Timestamp"://g;
+ $next_line =~ s/,//g;
+ $next_line =~ s/ //g;
+ chomp $next_line;
+
+ # convert to date/time (we are given the timestamp in ms, so divide
+ # by 1000 to get s).
+ $timestamp =
strftime("%m/%d/%Y %H:%M:%S", localtime($next_line/1000));
+ }
+ elsif($timestamp_found == 2)
+ {
+ # Field format :: "timestamp": "2019-10-31 10:20:50"
+ $next_line =~ s/"timestamp"://g;
+ $next_line =~ s/"//g; #drop the quotes
+ my @tmp1 = split( " ", $next_line ); #break the date and time apart
+ my @df = split( /-/, $tmp1[0] ); #break up the date fields
+ # Convert to :: 11/05/2019 12:25:41
+ $timestamp = "$df[1]/$df[2]/$df[0] $tmp1[1]";
+ ($debug) && print "timestamp> $timestamp \n";
+ }
+ else
+ {
+ die "Bad timestamp\n";
+ }
+
($debug) && print "Timestamp for ESEL #$esel_record_count:$next_line\n";
($debug) && print "Decoded timestamp for ESEL #$esel_record_count:$timestamp\n";
diff --git a/src/build/debug/ffdcExpander b/src/build/debug/ffdcExpander
new file mode 100755
index 000000000..95f7c970f
--- /dev/null
+++ b/src/build/debug/ffdcExpander
@@ -0,0 +1,727 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/debug/ffdcExpander $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2013,2020
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+
+###############################################################################
+# @file ffdcExpander
+# This shell script takes a SYSDUMP file and extracts various debug elements.
+# The caller has the option to post artifacts to a defect.
+#
+# The starting point for this script is at the end of the file.
+###############################################################################
+
+###############################################################################
+# Some helpful constants
+###############################################################################
+FFDC_GUNZIP_TOOL="/bin/gunzip"
+FFDC_DUMP_PARSER="/esw/bin/dumpparser"
+
+
+###############################################################################
+# Some global variables
+###############################################################################
+FFDC_3RD_PARTY_SCRIPT_DIR="/gsa/ausgsa/projects/h/hostboot/optools/" # Location of files updatecq.pl, cqcmd.pl and Slurp.pm
+FFDC_SCRIPT_NAME=$(basename "${0}") # Cache the name of this script
+FFDC_SCRIPT_DIR=$(dirname "${0}") # Location of this script and supporting scripts
+FFDC_SCRIPT_DIR="${FFDC_SCRIPT_DIR}/"
+FFDC_SYSDUMP_FILE_GZ="" # format SYSDUMP.13020B8.20000001.20190725181300.gz
+FFDC_SYSDUMP_FILE="" # format SYSDUMP.13020B8.20000001.20190725181300
+FFDC_HB_DUMP_FILE=""; # format hb.dump.SYSDUMP.13020B8.20000001.20190725181300
+FFDC_FSP_DRIVER_DIR="" # format '/esw/fips922/Builds/b0724a_1931.922'
+FFDC_FSP_DRIVER="" # format 'fips922', 'fips950' , etc
+FFDC_FSP_BUILD_TAG="" # format b0724a_1931.922
+FFDC_DEFECT_NUM="" # format 'SW123456', 'sw123456', 'Sw123456' or 'sW123456'
+FFDC_DEFECT_NUM_CHARS="8" # The number of characters expected in defect including 'SW'
+FFDC_CWD="`pwd -P`/" # The current working directory
+FFDC_DEST_DIR="${FFDC_CWD}" # The destination directory of artifacts, default to CWD
+FFDC_CQ_USER="" # The CQ user ID
+FFDC_CQ_PASS="" # The CQ password
+FFDC_RETURN_VALUE="0" # The return value. Default to success '0'
+FFDC_TIME_STAMP="" # A time stamp is generated to make the files unique
+
+###############################################################################
+# Print the usage line
+#
+# @return 0 if successful, not 0 if a failure occurred
+###############################################################################
+function _ffdcUsage_()
+{
+ echo ""
+ echo " Usage: ${FFDC_SCRIPT_NAME} -g <FFDC_SYSDUMP_FILE.gz> | -s <FFDC_SYSDUMP_FILE> |"
+ echo " -h <HB_FFDC_SYSDUMP_FILE> -b <FSP_BUILD_TAG>"
+ echo " [ OPTIONS ]"
+ echo ""
+ echo " OPTIONS: [ -d <DEST_DIR> ] [ -a <DEFECT_NUM> ] [ -t ]"
+ echo " -t attach a time stamp to the artifacts"
+ echo ""
+ echo " Examples: ${FFDC_SCRIPT_NAME} -g SYSDUMP.13020B8.20000001.20190725181300.raw67117184.gz"
+ echo " ${FFDC_SCRIPT_NAME} -s SYSDUMP.13020B8.20000001.20190725181300.raw67117184"
+ echo " ${FFDC_SCRIPT_NAME} -h hb.dump.SYSDUMP.13020B8.20000001.20190725181300 -b b0724a_1931.922"
+ echo " ${FFDC_SCRIPT_NAME} -s SYSDUMP.13020B8.20000001.20190725181300.raw67117184 -a SW123456 -t"
+ echo " ${FFDC_SCRIPT_NAME} -s SYSDUMP.13020B8.20000001.20190725181300.raw67117184 -d dir"
+ echo ""
+ return 0; # Return success
+}
+
+###############################################################################
+# @brief Get the caller's options and validate them
+#
+# @param [in] $* - All of the caller's inputs after name of script
+#
+# @return 0 if successful, not 0 if a failure occurred
+###############################################################################
+function _getUserInputOptionsAndValidate_()
+{
+ # Default caller options
+ CALLER_SYSDUMP_FILE_GZ=""
+ CALLER_SYSDUMP_FILE=""
+ CALLER_HB_DUMP_FILE=""
+ CALLER_FSP_BUILD_TAG=""
+ CALLER_DEST_DIR=""
+ CALLER_REQUESTS_TIME_STAMP=""
+
+ # Get caller's options
+ FFDC_RETURN_VALUE="22" # Default to 'Invalid argument'
+ MANDATORY_OPTION_CHOSEN="0"
+ echo ""
+ while getopts ts:g:h:b:d:a: option
+ do
+ if [ -n "${option}" ]; then
+ FFDC_RETURN_VALUE="0"; # Found an argument
+ fi
+ case "${option}"
+ in
+ t) CALLER_REQUESTS_TIME_STAMP=1;;
+ s) CALLER_SYSDUMP_FILE=${OPTARG}; MANDATORY_OPTION_CHOSEN="1";;
+ g) CALLER_SYSDUMP_FILE_GZ=${OPTARG}; MANDATORY_OPTION_CHOSEN="1";;
+ h) CALLER_HB_DUMP_FILE=${OPTARG}; MANDATORY_OPTION_CHOSEN="1";;
+ b) CALLER_FSP_BUILD_TAG=${OPTARG};;
+ d) CALLER_DEST_DIR=${OPTARG};;
+ a) CALLER_DEFECT_NUM=${OPTARG};;
+ \?) FFDC_RETURN_VALUE=22;;
+ :) FFDC_RETURN_VALUE=22;;
+ esac
+ done
+
+ # If call to getopts not successful, then propagate error back
+ if [ "$FFDC_RETURN_VALUE" != "0" ]; then
+ _ffdcUsage_
+ return $FFDC_RETURN_VALUE;
+ fi
+
+ # Check for a valid option chosen
+ if [ "$MANDATORY_OPTION_CHOSEN" == "0" ]; then
+ _ffdcUsage_
+ return $FFDC_RETURN_VALUE;
+ fi
+
+ # Check for nonsensical options
+ if [ -n "${CALLER_SYSDUMP_FILE}" ] && [ -n "${CALLER_SYSDUMP_FILE_GZ}" ]; then
+ echo " ERROR: Incompatible options: options -g and -s can't be used together";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi
+
+ if [ -n "${CALLER_SYSDUMP_FILE_GZ}" ] && [ -n "${CALLER_HB_DUMP_FILE}" ]; then
+ echo " ERROR: Incompatible options: options -g and -h can't be used together";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi
+
+ if [ -n "${CALLER_SYSDUMP_FILE_GZ}" ] && [ -n "${CALLER_FSP_BUILD_TAG}" ]; then
+ echo " ERROR: Incompatible options: options -g and -b can't be used together";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi
+
+ if [ -n "${CALLER_SYSDUMP_FILE}" ] && [ -n "${CALLER_FSP_BUILD_TAG}" ]; then
+ echo " ERROR: Incompatible options: options -s and -b can't be used together";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi
+
+ if [ -n "${CALLER_SYSDUMP_FILE}" ] && [ -n "${CALLER_HB_DUMP_FILE}" ]; then
+ echo " ERROR: Incompatible options: options -s and -h can't be used together";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi
+
+ # Verify that if caller is passing in a HB dump file, they must supply the build tag
+ if [ -n "${CALLER_HB_DUMP_FILE}" ] && [ -z "${CALLER_FSP_BUILD_TAG}" ]; then
+ echo " ERROR: Must supply a -b option with the -h option";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi
+
+ if [ -z "${CALLER_HB_DUMP_FILE}" ] && [ -n "${CALLER_FSP_BUILD_TAG}" ]; then
+ echo " ERROR: Must supply a -h option with the -b option";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi
+
+ # If caller requests a time stamp, option -t, then oblige
+ if [ "$CALLER_REQUESTS_TIME_STAMP" == "1" ]; then
+ FFDC_TIME_STAMP=$(date +%s)
+ FFDC_TIME_STAMP="_${FFDC_TIME_STAMP}"
+ fi
+
+ # If caller supplied a gzippped SYSDUMP file, option -g, then confirm it exists
+ if [ -n "${CALLER_SYSDUMP_FILE_GZ}" ]; then
+ if [ ! -e "${CALLER_SYSDUMP_FILE_GZ}" ]; then
+ echo " gzipped SYSDUMP file (${CALLER_SYSDUMP_FILE_GZ}) not found";
+ return 22; # return 'Invalid argument'
+ fi
+
+ # Check if file given is a gzipped file, verify that it ends in .gz
+ if [[ "${CALLER_SYSDUMP_FILE_GZ}" != *\.gz ]]; then
+ echo " ";
+ echo " WARNING: It appears that file (${CALLER_SYSDUMP_FILE_GZ}) is not a gzipped file"
+ while true; do
+ echo ""
+ read -p " Do you wish to continue with file [Y/N] ? " yn
+ case $yn in
+ [Yy] ) break;;
+ [Nn] ) echo " ¯\_(?)_/¯ exiting ..."; echo ""; return 22;; # return 'Invalid argument'
+ * ) echo " Please answer [Y]es or [N]o.";;
+ esac
+ done
+ fi
+
+ # Save caller's gzippped SYSDUMP file, option -g
+ FFDC_SYSDUMP_FILE_GZ="$CALLER_SYSDUMP_FILE_GZ"
+
+ ## Add an absolute path to the gzipped file, if not already an absolute path
+ # Check the first character to see if starting with absolute path
+ FIRST_CHAR="${FFDC_SYSDUMP_FILE_GZ:0:1}"
+ # If first char not a '/' then append an absolute path
+ if [ "${FIRST_CHAR}" != "/" ]; then
+ FFDC_SYSDUMP_FILE_GZ="${FFDC_CWD}${FFDC_SYSDUMP_FILE_GZ}"
+ fi
+ fi # end if [ -n "${CALLER_SYSDUMP_FILE_GZ}" ]; then
+
+
+ # If caller supplied a SYSDUMP file, option -f, then confirm it exists
+ if [ -n "${CALLER_SYSDUMP_FILE}" ]; then
+ if [ ! -e "${CALLER_SYSDUMP_FILE}" ]; then
+ echo " SYSDUMP file (${CALLER_SYSDUMP_FILE}) not found";
+ return 22; # return 'Invalid argument'
+ fi
+
+ # Save caller's SYSDUMP file, option -f
+ FFDC_SYSDUMP_FILE="${CALLER_SYSDUMP_FILE}"
+
+ ## Add an absolute path to the gzipped file, if not already an absolute path
+ # Check the first character to see if starting with absolute path
+ FIRST_CHAR="${FFDC_SYSDUMP_FILE:0:1}"
+ # If first char not a '/' then append an absolute path
+ if [ "${FIRST_CHAR}" != "/" ]; then
+ FFDC_SYSDUMP_FILE="${FFDC_CWD}${FFDC_SYSDUMP_FILE}"
+ fi
+ fi # end if [ -n "${CALLER_SYSDUMP_FILE}" ]; then
+
+
+ # If caller supplied a HB dump file, option -h, then confirm it exists
+ if [ -n "${CALLER_HB_DUMP_FILE}" ]; then
+ if [ ! -e "${CALLER_HB_DUMP_FILE}" ]; then
+ echo " HB dump file (${CALLER_HB_DUMP_FILE}) not found";
+ return 22; # return 'Invalid argument'
+ fi
+
+ # Save caller's HB dump file, option -h
+ FFDC_HB_DUMP_FILE="${CALLER_HB_DUMP_FILE}"
+
+ ## Add an absolute path to the HB dump file, if not already an absolute path
+ # Check the first character to see if starting with absolute path
+ FIRST_CHAR="${FFDC_HB_DUMP_FILE:0:1}"
+ # If first char not a '/' then append an absolute path
+ if [ "${FIRST_CHAR}" != "/" ]; then
+ FFDC_HB_DUMP_FILE="${FFDC_CWD}${FFDC_HB_DUMP_FILE}"
+ fi
+ fi # end if [ -n "${CALLER_HB_DUMP_FILE}" ]; then
+
+
+ # If caller supplied an FSP build tag, option -b, then validate it
+ if [ -n "${CALLER_FSP_BUILD_TAG}" ]; then
+ # Extrapolate the FSP Build Release from the FSP build tag
+ if [[ "${CALLER_FSP_BUILD_TAG}" = *"."* ]]; then
+ FIPS_VERS=$(echo ${CALLER_FSP_BUILD_TAG} | \cut -d"." -f 2)
+ if [ -n "${FIPS_VERS}" ]; then
+ FFDC_FSP_DRIVER="fips${FIPS_VERS}"
+ else
+ echo " ";
+ echo " Build tag (${CALLER_FSP_BUILD_TAG}) appears to be in wrong format";
+ echo " Cannot extrapolate the FIPS version from build tag";
+ return 22; # return 'Invalid argument'
+ fi
+ else
+ echo " ";
+ echo " Build tag (${CALLER_FSP_BUILD_TAG}) appears to be in wrong format";
+ echo " Cannot extrapolate the FIPS version from build tag";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi # end if [[ "${CALLER_FSP_BUILD_TAG}" = *"."* ]]; then
+
+ # Save the caller's FSP build tag
+ FFDC_FSP_BUILD_TAG="${CALLER_FSP_BUILD_TAG}"
+
+ # Save the caller's FSP build tag with the directory to it
+ FFDC_FSP_DRIVER_DIR="/esw/${FFDC_FSP_DRIVER}/Builds/${CALLER_FSP_BUILD_TAG}"
+ fi # end if [ -n "${CALLER_FSP_BUILD_TAG}" ]; then
+
+ # If caller supplied a defect, option -a, just confirm it is in the correct
+ # nomenclature and format
+ if [ -n "${CALLER_DEFECT_NUM}" ]; then
+
+ FFDC_DEFECT_NUM=$(echo ${CALLER_DEFECT_NUM^^})
+ if [[ $FFDC_DEFECT_NUM != SW* ]]; then
+ echo " ERROR: software defect must be preceded with 'SW'";
+ echo " ";
+ return 22; # return 'Invalid argument'
+ fi
+
+ NUM_CHARS=${#FFDC_DEFECT_NUM}
+ if [[ "${NUM_CHARS}" -ne "${FFDC_DEFECT_NUM_CHARS}" ]]; then
+ echo " ERROR: software defect must have a total of ${FFDC_DEFECT_NUM_CHARS} characters, including 'SW'";
+ echo " ";
+ return 22; # return 'Invalid argument'
+ fi
+
+ INTEGER_PART=$(echo ${CALLER_DEFECT_NUM} | sed "s/^SW//g")
+ REG_EXP='^[0-9]+$'
+ if ! [[ $INTEGER_PART =~ $REG_EXP ]]; then
+ echo " ERROR: the characters (${INTEGER_PART}) that follow 'SW' must be an integer";
+ echo " ";
+ return 22; # return 'Invalid argument'
+ fi
+
+ # Prompt username and password for CQ
+ _queryUserPassword_;
+ FFDC_RETURN_VALUE=$?
+ if [ "${FFDC_RETURN_VALUE}" != "0" ]; then
+ echo ""
+ return ${FFDC_RETURN_VALUE}; # Return failure
+ fi
+ fi # end # If caller supplied a defect, option -a, ...
+
+
+ # If caller supplied a destination directory, option -d, then confirm it
+ # exists and determine if it is a relative path or absolute path
+ if [ -n "${CALLER_DEST_DIR}" ]; then
+ if [ ! -e "${CALLER_DEST_DIR}" ]; then
+ echo " Destination directory (${CALLER_DEST_DIR}) not found";
+ while true; do
+ echo ""
+ read -p " Do you wish to ceate it [Y/N] ? " yn
+ case $yn in
+ [Yy] ) break;;
+ [Nn] ) echo " ¯\_(?)_/¯ exiting ..."; echo ""; return 22;; # return 'Invalid argument'
+ * ) echo " Please answer [Y]es or [N]o.";;
+ esac
+ done
+
+ mkdir -p ${CALLER_DEST_DIR}
+ FFDC_RETURN_VALUE=$?
+ if [ "$FFDC_RETURN_VALUE" != "0" ]; then
+ echo ""
+ return $FFDC_RETURN_VALUE; # Propagate failure
+ fi
+ echo " Destination directory (${CALLER_DEST_DIR}) created";
+ echo ""
+ fi
+
+ # Save caller's destination directory option
+ FFDC_DEST_DIR="$CALLER_DEST_DIR"
+ NUM_CHARS=$((${#FFDC_DEST_DIR}-1))
+ LAST_CHAR="${FFDC_DEST_DIR:$NUM_CHARS:1}"
+ # If last char not a '/' then append a '/'
+ if [ "${LAST_CHAR}" != "/" ]; then
+ FFDC_DEST_DIR="${FFDC_DEST_DIR}/"
+ fi
+
+ ## Add an absolute path to the destination directory, if it is not
+ ## already an absolute path.
+ # Inspect the first character to determine path is absolute or not
+ FIRST_CHAR="${FFDC_DEST_DIR:0:1}"
+ # If first char not a '/' then append an absolute path
+ if [ "${FIRST_CHAR}" != "/" ]; then
+ FFDC_DEST_DIR="${FFDC_CWD}${FFDC_DEST_DIR}"
+ fi
+ fi # end if [ -n "${CALLER_DEST_DIR}" ]; then
+
+ return 0; # Return success
+}
+
+###############################################################################
+# @brief Query caller for user name and password
+###############################################################################
+function _queryUserPassword_()
+{
+ if [ -n "${FFDC_DEFECT_NUM}" ]; then
+ read -p 'CQ Username: ' FFDC_CQ_USER
+ read -sp 'CQ Password: ' FFDC_CQ_PASS
+ fi
+
+ return 0;
+}
+
+###############################################################################
+# @brief Unzip the system dump file
+#
+# Example: unzip SYSDUMP.13020B8.20000001.20190725181300.raw67117184.gz =>
+# SYSDUMP.13020B8.20000001.20190725181300.raw67117184
+#
+# @return 0 if successful, not 0 if a failure occurred
+###############################################################################
+function _unzipSysDumpFile_()
+{
+ # Verify that we can get to the dumpparser script
+ if [[ ! -e "${FFDC_GUNZIP_TOOL}" ]]; then
+ echo ""
+ echo " ERROR: Could not find gunzip tool ${FFDC_GUNZIP_TOOL}"
+ echo ""
+ return 2; # Return 'No such file or directory'
+ fi
+
+ ## Extrapolate the SYSDUMP file from the gzipped file
+ # Remove any directories and only get the file name
+ FFDC_SYSDUMP_FILE=$(echo ${FFDC_SYSDUMP_FILE_GZ} | awk -F / '{ print $NF }')
+ # Remove the '.gz' from the gzipped file
+ FFDC_SYSDUMP_FILE=$(echo ${FFDC_SYSDUMP_FILE} | sed "s/\.gz$//")
+ # Prepend the caller's directory
+ FFDC_SYSDUMP_FILE="${FFDC_DEST_DIR}${FFDC_SYSDUMP_FILE}"
+
+ # Check if the SYSDUMP file already exists, if so, ask caller if they wish
+ # to overwrite it
+ if [[ -e "${FFDC_SYSDUMP_FILE}" ]]; then
+ echo ""
+ echo " SYSDUMP file (${FFDC_SYSDUMP_FILE}) already exists ..."
+ while true; do
+ echo ""
+ read -p " Do you wish to override the file and continue [Y/N] ? " yn
+ case $yn in
+ [Yy] ) break;;
+ [Nn] ) echo " Skipping call to ${FFDC_GUNZIP_TOOL} ..."; echo ""; return 0;;
+ * ) echo " Please answer [Y]es or [N]o.";;
+ esac
+ done
+ fi
+
+ # Unzip the gzipped SYSDUMP file
+ echo ""
+ echo " ${FFDC_GUNZIP_TOOL} -c ${FFDC_SYSDUMP_FILE_GZ} > ${FFDC_SYSDUMP_FILE}"
+ `${FFDC_GUNZIP_TOOL} -c ${FFDC_SYSDUMP_FILE_GZ} > ${FFDC_SYSDUMP_FILE}`
+ FFDC_RETURN_VALUE=$?
+ if [ "${FFDC_RETURN_VALUE}" != "0" ]; then
+ echo ""
+ return ${FFDC_RETURN_VALUE}; # Return failure
+ fi
+
+ return 0; # Return success
+}
+
+
+###############################################################################
+# @brief Extract the HB system dump file from the SYSDUMP file
+#
+# Example: /esw/bin/dumpparser -extMem SYSDUMP.13020B8.20000001.20190725181300.raw67117184 =>
+# hb.dump.SYSDUMP.13020B8.20000001.20190725181300
+#
+# @return 0 if successful, not 0 if a failure occurred
+###############################################################################
+function _extractHbSysDumpFile_()
+{
+ # Verify that we can get to the dump parser script
+ if [[ ! -e "${FFDC_DUMP_PARSER}" ]]; then
+ echo ""
+ echo " ERROR: Could not find parser ${FFDC_DUMP_PARSER}"
+ echo ""
+ return 2; # Return 'No such file or directory'
+ fi
+
+ ## Extrapolate the HB dump file name from the SYSDUMP file
+ # Remove any directories and only get the file name
+ FFDC_HB_DUMP_FILE=$(echo ${FFDC_SYSDUMP_FILE} | awk -F / '{ print $NF }')
+ # Remove the .gz from the SYSDUMP, if it exists
+ FFDC_HB_DUMP_FILE=$(echo ${FFDC_HB_DUMP_FILE} | sed "s/\.gz$//")
+ # Remove the postpended '.rawxxx' from the SYSDUMP file, if it exists
+ FFDC_HB_DUMP_FILE=$(echo ${FFDC_HB_DUMP_FILE} | sed "s/\.raw.*$//")
+ # Prepend 'hb.dump.' to file
+ FFDC_HB_DUMP_FILE=$(echo ${FFDC_HB_DUMP_FILE} | sed "s/^/hb.dump./")
+ # Prepend the caller's directory
+ FFDC_HB_DUMP_FILE="${FFDC_DEST_DIR}${FFDC_HB_DUMP_FILE}"
+
+ # Extract the the FSP build info from the SYSDUMP file
+ FSP_BUILD_INFO=$(${FFDC_DUMP_PARSER} -a ${FFDC_SYSDUMP_FILE} | grep "Driver is" | awk '{ print $4 }')
+
+ # Extract the the FSP driver info from the FSP build info
+ FFDC_FSP_DRIVER=$(echo ${FSP_BUILD_INFO} | awk -F / '{ print $1 }')
+
+ # Extract the FSP build tag info from the FSP build info
+ FFDC_FSP_BUILD_TAG=$(echo ${FSP_BUILD_INFO} | awk -F / '{ print $2 }')
+
+ # Create a path to FSP build driver info
+ FFDC_FSP_DRIVER_DIR="/esw/${FFDC_FSP_DRIVER}/Builds/${FFDC_FSP_BUILD_TAG}"
+
+ # Check if the HB dump file already exists, if so, ask caller if they wish
+ # to overwrite it
+ if [[ -e "${FFDC_HB_DUMP_FILE}" ]]; then
+ echo ""
+ echo " HB system dump file (${FFDC_HB_DUMP_FILE}) already exists ..."
+ while true; do
+ echo ""
+ read -p " Do you wish to override the file and continue [Y/N] ? " yn
+ case $yn in
+ [Yy] ) break;;
+ [Nn] ) echo " Skipping call to ${FFDC_DUMP_PARSER} ..."; return 0;;
+ * ) echo " Please answer [Y]es or [N]o.";;
+ esac
+ done
+ fi
+
+ # Change directory to user supplied directory
+ \cd -P ${FFDC_DEST_DIR} ;
+
+ # Parse out the HB dump file using the dump parser
+ echo ""
+ echo " ${FFDC_DUMP_PARSER} -extMem ${FFDC_SYSDUMP_FILE}"
+ ${FFDC_DUMP_PARSER} -extMem ${FFDC_SYSDUMP_FILE}
+
+ FFDC_RETURN_VALUE=$?
+ if [ "${FFDC_RETURN_VALUE}" != "0" ]; then
+ # Return back to current working directory
+ \cd -P ${FFDC_CWD}
+ echo ""
+ return ${FFDC_RETURN_VALUE}; # Return failure
+ fi
+
+ echo " Created file ${FFDC_HB_DUMP_FILE}"
+
+ # Return back to current working directory
+ \cd -P ${FFDC_CWD}
+
+ return 0; # Return success
+}
+
+
+###############################################################################
+# @brief Set the path to the fsp-trace tool
+#
+# @return 0
+###############################################################################
+function _setFSPTracePath_()
+{
+ FFDC_FSP_PATH="/esw/$FFDC_FSP_DRIVER/Builds/built/images/nfs/x86.nfp/bin/"
+ echo ""
+ echo " Using fsp-trace tool: ${FFDC_FSP_PATH}fsp-trace"
+ PATH=${FFDC_FSP_PATH}:$PATH
+
+ # Verify that we can get to the dump parser script
+ if [[ ! -e "${FFDC_FSP_PATH}fsp-trace" ]]; then
+ echo ""
+ echo " ERROR: Could not find fsp trace ${FFDC_DUMP_PARSER}"
+ echo ""
+ return 2; # Return 'No such file or directory'
+ fi
+
+ echo "PATH=${FFDC_FSP_PATH}:\$PATH" >> ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+
+ return 0; # Return success
+}
+
+###############################################################################
+# @brief Extract various HB dump info
+#
+# @param [in] $1 The HB tools directory
+# @param [in] $2 Path to the hb-dump-debug tools directory
+###############################################################################
+function _getInfoFromHBDump_()
+{
+ echo ""
+ echo " Extracting the Trace information from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=Trace --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}TRACE${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=Trace --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}TRACE${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the Printk information from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=Printk --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PRINTK${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=Printk --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PRINTK${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the Errl information (Component/PLID list) from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=Errl --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}ERRL${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=Errl --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}ERRL${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the Errl information (Detailed listing of all Error Logs) from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=Errl --tool-options='display=all' --file=${FFDC_HB_DUMP_FILE} >> ${FFDC_DEST_DIR}ERRL${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=Errl --tool-options='display=all' --file=${FFDC_HB_DUMP_FILE} >> ${FFDC_DEST_DIR}ERRL${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the Ps information from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=Ps --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PS${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=Ps --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PS${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the Ps information from HB dump with backtrace ..."
+ echo " running: $1 --img-path=$2/ --tool=Ps --tool-options="with-backtrace" --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PS_BACKTRACE${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=Ps --tool-options="with-backtrace" --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PS_BACKTRACE${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the MemStats information from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=Ps --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}MEMSTATS${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=MemStats --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}MEMSTATS${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the PageMgr information from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=PageMgr --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PAGEMGR${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=PageMgr --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PAGEMGR${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the BlTrace information from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=BlTrace --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}BLTRACE${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=BlTrace --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}BLTRACE${FFDC_TIME_STAMP}
+}
+
+###############################################################################
+# @brief Extract various HB dump info and post to defect, if caller wishes to
+###############################################################################
+function _getInfoFromHBDumpAndPost_()
+{
+ _setFSPTracePath_
+ FFDC_RETURN_VALUE=$?
+ # If call to _setFSPTracePath_ not successful, then propagate error back
+ if [ "$FFDC_RETURN_VALUE" != "0" ]; then
+ return $FFDC_RETURN_VALUE;
+ fi
+
+ HB_TOOLS_DIR=$FFDC_FSP_DRIVER_DIR/obj/x86.nfp/hbfw/simics
+ HB_DUMP_DEBUG=$HB_TOOLS_DIR/hb-dump-debug
+ _getInfoFromHBDump_ $HB_DUMP_DEBUG $HB_TOOLS_DIR
+
+ # If supplied a defect number, then post a comment to the defect and add
+ # the generated dump files as attachments
+ if [ -n "${FFDC_DEFECT_NUM}" ]; then
+ PATH=${FFDC_3RD_PARTY_SCRIPT_DIR}:$PATH
+ CQFILE=${FFDC_3RD_PARTY_SCRIPT_DIR}updatecq.pl
+
+ echo ""
+ echo -e "\n Adding attachment TRACE${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}TRACE${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS -s "Hostboot dump files stored at $FFDC_DEST_DIR"
+
+ echo -e "\n Adding attachment PRINTK${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}PRINTK${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS
+
+ echo -e "\n Adding attachment ERRL${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}ERRL${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS
+
+ echo -e "\n Adding attachment PS${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}PS${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS
+
+ echo -e "\n Adding attachment PS_BACKTRACE${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}PS_BACKTRACE${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS
+
+ echo -e "\n Adding attachment MEMSTATS${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}MEMSTATS${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS
+
+ echo -e "\n Adding attachment PAGEMGR${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}PAGEMGR${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS
+
+ echo -e "\n Adding attachment BLTRACE${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}BLTRACE${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS
+ fi
+}
+
+
+###############################################################################
+# @brief The main. The real starting place of this script
+#
+# @return 0 if successful, not 0 if a failure occurred
+###############################################################################
+function ffdcExpanderMain()
+{
+ # Get user input options and validate
+ _getUserInputOptionsAndValidate_ $*
+ FFDC_RETURN_VALUE=$?
+ # If call to _getUserInputOptionsAndValidate_ not successful, then propagate error back
+ if [ "$FFDC_RETURN_VALUE" != "0" ]; then
+ return $FFDC_RETURN_VALUE;
+ fi
+
+
+ # If caller supplied a gzipped file then unzip it
+ if [ -n "${FFDC_SYSDUMP_FILE_GZ}" ]; then
+ _unzipSysDumpFile_
+ FFDC_RETURN_VALUE=$?
+ fi
+ # If call to _unzipSysDumpFile_ not successful, then propagate error back
+ if [ "$FFDC_RETURN_VALUE" != "0" ]; then
+ return $FFDC_RETURN_VALUE;
+ fi
+
+
+ # If caller supplied a SYSDUMP file then extract HB dump file
+ if [ -n "${FFDC_SYSDUMP_FILE}" ]; then
+ _extractHbSysDumpFile_ ${FFDC_SYSDUMP_FILE}
+ FFDC_RETURN_VALUE=$?
+ fi
+ # If call to _extractHbSysDumpFile_ not successful, then propagate error back
+ if [ "$FFDC_RETURN_VALUE" != "0" ]; then
+ return $FFDC_RETURN_VALUE;
+ fi
+
+
+ # If caller supplied a HB dump file and a FSP build tag, then retrieve HB info
+ if [ -n "${FFDC_HB_DUMP_FILE}" ] && [ -n "${FFDC_FSP_DRIVER_DIR}" ]; then
+ # Save the FSP build tag as a file for the caller's benefit
+ touch ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ # Add some info data to the file
+ echo ${FFDC_FSP_BUILD_TAG} > ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ echo ${FFDC_FSP_DRIVER} >> ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ echo ${FFDC_FSP_DRIVER_DIR} >> ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+
+ _getInfoFromHBDumpAndPost_ ${FFDC_HB_DUMP_FILE} ${FFDC_FSP_DRIVER_DIR};
+ FFDC_RETURN_VALUE=$?
+ fi
+ # If call to _getInfoFromHBDumpAndPost_ not successful, then propagate error back
+ if [ "$FFDC_RETURN_VALUE" != "0" ]; then
+ return $FFDC_RETURN_VALUE;
+ fi
+
+ echo ""
+ return 0;
+}
+
+
+###############################################################################
+# @brief Call the main starting function, ffdcExpanderMain, the beginning point
+# of this script
+#
+# @return 0 if successful, not 0 if a failure occurred
+###############################################################################
+
+ffdcExpanderMain $*
+exit $?;
+
diff --git a/src/build/debug/simics-debug-framework.py b/src/build/debug/simics-debug-framework.py
index 3176f8cba..fd90806bb 100644
--- a/src/build/debug/simics-debug-framework.py
+++ b/src/build/debug/simics-debug-framework.py
@@ -516,7 +516,7 @@ def magic_instruction_callback(user_arg, cpu, arg):
# Stop the simulation, much like a hard-coded breakpoint
SIM_break_simulation( "Simulation stopped. (hap 7007)" )
- if arg == 7008:
+ if arg == 7008: # MAGIC_RANDOM
cpu.r3 = random.randint(1, 0xffffffffffffffffL)
if arg == 7009: # MAGIC_MEMORYLEAK_FUNCTION
@@ -525,6 +525,10 @@ def magic_instruction_callback(user_arg, cpu, arg):
if arg == 7011: #MAGIC_SIMICS_CHECK
cpu.r3 = 1
print "TimeManager::cv_isSimicsRunning = true"
+ # Clear the dump flag in case it was still set from a previous boot
+ # (this call happens only 1 time and it is very early in the boot)
+ if( os.environ.has_key('HB_DUMP_COMPLETE') ):
+ del os.environ['HB_DUMP_COMPLETE']
if arg == 7012: # MAGIC_LOAD_PAYLOAD
#For P9 the Payload load is much faster due to PNOR
@@ -537,6 +541,17 @@ def magic_instruction_callback(user_arg, cpu, arg):
#SIM_run_alone( run_command, cmd )
print "MAGIC_LOAD_PAYLOAD not implemented\n";
+ if arg == 7014: # MAGIC_HB_DUMP
+ # Collect a hostboot dump
+ # (no args)
+
+ # Make sure we only do 1 dump even though every thread will TI
+ if( not os.environ.has_key('HB_DUMP_COMPLETE') ):
+ print "Generating Hostboot Dump for TI"
+ os.environ['HB_DUMP_COMPLETE']="1"
+ cmd1 = "hb-Dump quiet"
+ SIM_run_alone(run_command, cmd1 )
+
if arg == 7018: # MAGIC_BREAK_ON_ERROR
# Stop the simulation if an env var is set
if( os.environ.has_key('HB_BREAK_ON_ERROR') ):
@@ -573,6 +588,7 @@ def magic_instruction_callback(user_arg, cpu, arg):
percent_s = "%s"
dateCommand = "shell \" date +'%s > TRACE REGS: %d %d' \""%(percent_s,first_num,second_num)
SIM_run_alone(run_command, dateCommand )
+
if arg == 7022: # MAGIC_SET_LOG_LEVEL
if( not os.environ.has_key('ENABLE_HB_SIMICS_LOGS') ):
#print("Skipping Hostboot Simics Logging because ENABLE_HB_SIMICS_LOGS is not set")
@@ -745,7 +761,9 @@ def magic_instruction_callback(user_arg, cpu, arg):
#file = open("hb_trace_debug.dat", "a")
#file.write("%s\n" % (saveCommand))
#file.close()
-
+ if arg == 7056: # MAGIC_GCOV_DUMP_NOW
+ print('Gcov dumping chain from 0x%x' % (cpu.r3,))
+ SIM_run_alone(run_command, 'hb-GcovModuleUnload "address=%d"' % (cpu.r3,))
# Continuous trace: Clear these files.
rc = os.system( "rm -f hbTracMERG" )
@@ -769,4 +787,3 @@ SIM_hap_add_callback_range( "Core_Magic_Instruction", magic_instruction_callback
# Run the registration automatically whenever this script is loaded.
register_hb_debug_framework_tools()
-
diff --git a/src/build/linker/genlist.C b/src/build/linker/genlist.C
index 053f7aaa2..d89fbfaa6 100644
--- a/src/build/linker/genlist.C
+++ b/src/build/linker/genlist.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2015 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -95,6 +95,19 @@ string g_imageName;
* call binutils tools. */
char* g_crossPrefix = NULL;
+ /** Whether we should use cached objdump files (true) or redump the
+ ELF objects (false). */
+bool use_cached_objdump = false;
+
+ /** Print status messages */
+bool verbose = false;
+
+#define VFPRINTF(...) \
+ do { \
+ if (verbose) \
+ fprintf(__VA_ARGS__); \
+ } while (0)
+
int main(int argc, char** argv)
{
// Only parameter allowed is the name of the base image.
@@ -103,6 +116,16 @@ int main(int argc, char** argv)
print_usage();
}
+ verbose = getenv("BUILD_VERBOSE") != NULL;
+
+ use_cached_objdump = getenv("BUILD_FAST") != NULL;
+
+ if (use_cached_objdump) {
+ VFPRINTF(stderr, "Using cached OBJDUMP output\n");
+ } else {
+ VFPRINTF(stderr, "Using fresh OBJDUMP output\n");
+ }
+
// Get base image name from parameters.
g_imageName = argv[1];
add_image_subdir(g_imageName);
@@ -310,18 +333,42 @@ void* read_module_content(void* input)
// Assumes they are in the same subdirectory.
string module_path = g_imageName.substr(0, g_imageName.rfind('/') + 1) +
module;
+ const string objdump_path =
+ g_imageName.substr(0, g_imageName.rfind('/') + 1) + "/objdump/" + module;
+
+ FILE* pipe = NULL;
- // Create the 'objdump' command for finding all the symbols and start as
- // a sub-process.
- // -d - Disassemble sections containing code.
- // -C - Intersparse C code.
- // -S - Demangle symbol names.
- // -j .text, .data, .rodata - Only dump those 3 sections.
- string command = string(g_crossPrefix) +
- string("objdump -dCS -j .text -j .data -j .rodata ") +
- module_path;
- FILE* pipe = popen(command.c_str(), "r");
- if (NULL == pipe) return NULL;
+ VFPRINTF(stderr, "GENLIST: Processing %s\n", module_path.c_str());
+
+ if (use_cached_objdump) {
+ string bzcat_command = "bzcat " + objdump_path + ".objdump";
+ pipe = popen(bzcat_command.c_str(), "r");
+
+ if (NULL == pipe) {
+ VFPRINTF(stderr, "GENLIST: Failed to run %s, falling back to live dump\n",
+ bzcat_command.c_str());
+ }
+ }
+
+ if (pipe == NULL) {
+ // Create the 'objdump' command for finding all the symbols and start as
+ // a sub-process.
+ // -d - Disassemble sections containing code.
+ // -C - Intersparse C code.
+ // -S - Demangle symbol names.
+ // -j .text, .data, .rodata - Only dump those 3 sections.
+ string objdump_command = string(g_crossPrefix) +
+ string("objdump -dCS -j .text -j .data -j .rodata ") +
+ module_path;
+
+ pipe = popen(objdump_command.c_str(), "r");
+
+ if (NULL == pipe) {
+ fprintf(stderr, "GENLIST: Failed to open pipe for objdump: %s\n",
+ objdump_command.c_str());
+ return NULL;
+ }
+ }
// Start result string and add module start header.
string result;
diff --git a/src/build/linker/linker.C b/src/build/linker/linker.C
index a9a9d0f5e..6a8854d83 100644
--- a/src/build/linker/linker.C
+++ b/src/build/linker/linker.C
@@ -112,6 +112,8 @@ struct Section
size_t size;
bfd_byte* data;
+
+ Section() : name(""), vma_offset(0), size(0), data(NULL) {}
};
/**
@@ -123,6 +125,7 @@ struct Object
string name; //!< full path name of file
bfd* image; //!< bfd image of object
Section text; //!< text section of binary
+ Section sfpr; //!< sfpr section of binary
Section rodata; //!< rodata section of binary
Section data; //!< data section of binary
map<string, Symbol> symbols; //!< symbol map
@@ -203,7 +206,7 @@ struct Object
/**
* CTOR default
*/
- Object() : image(NULL), text(), rodata(), data(), offset(0),
+ Object() : image(NULL), text(), rodata(), data(), sfpr(), offset(0),
base_addr(0), iv_output(NULL), tls_module(-1) {}
@@ -213,7 +216,7 @@ struct Object
* @param[in] i_out : output FILE handle
*/
Object(unsigned long i_baseAddr, FILE* i_out)
- : image(NULL), text(), rodata(), data(), offset(0),
+ : image(NULL), text(), rodata(), data(), sfpr(), offset(0),
base_addr(i_baseAddr), iv_output(i_out), tls_module(-1) {}
};
@@ -439,6 +442,8 @@ int main(int argc, char** argv)
// A contained member value might be something like
// _ZZ3fooE3bar.
string sym_name = string((i->c_str())+1);
+ const char* gcovstr = "__gcov";
+ size_t gcovstrlen = strlen(gcovstr);
cout << "Checking weak symbol: " << *i << endl;
@@ -451,6 +456,12 @@ int main(int argc, char** argv)
== j->find("traceData_codeInfo"))
&& (*i != *j))
{
+ if (strncmp((*j).c_str(),
+ gcovstr,
+ gcovstrlen)==0)
+ {
+ continue;
+ }
cout << "\tDuplicate member found: " << *j << endl;
throw std::runtime_error(
string("Duplicate weak symbol with contained "
@@ -586,6 +597,11 @@ bool Object::read_object(const char* i_file)
{
s = &this->text;
}
+ else if (string(".sfpr") ==
+ bfd_get_section_name(image, image_section))
+ {
+ s = &this->sfpr;
+ }
else if (string(".rodata") ==
bfd_get_section_name(image, image_section))
{
@@ -640,6 +656,16 @@ bool Object::write_object()
cout << strerror(error) << endl;
}
+ // Output sfpr section.
+ fseek(iv_output, offset + sfpr.vma_offset, SEEK_SET);
+ if ((0 != sfpr.size) &&
+ (sfpr.size != fwrite(sfpr.data, 1, sfpr.size, iv_output)))
+ {
+ int error = errno;
+ cout << "Error writing to output for sfpr." << endl;
+ cout << strerror(error) << endl;
+ }
+
// Output RODATA section.
fseek(iv_output, offset + rodata.vma_offset, SEEK_SET);
if ((0 != rodata.size) &&
diff --git a/src/build/mkrules/cc.rules.mk b/src/build/mkrules/cc.rules.mk
index c89995f82..409166e29 100644
--- a/src/build/mkrules/cc.rules.mk
+++ b/src/build/mkrules/cc.rules.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2017
+# Contributors Listed Below - COPYRIGHT 2013,2019
# [+] International Business Machines Corp.
#
#
@@ -31,22 +31,71 @@ $(OBJDIR)/%.list : $(OBJDIR)/%.o
$(C2) " OBJDUMP $(notdir $<)"
$(C1)$(OBJDUMP) -rdlCS $< > $@
+# SOURCE_FILE and INCLUDE_DIRS are variables that are either absolute
+# paths to the .C file being compiled and the include directories if
+# we're building with gcov, or else they are relative paths
+# otherwise. The key thing to remember is that they are lazily
+# expanded, so they're relevant to whatever rule they're used in. We
+# don't want to always have absolute paths because of build
+# performance and because it causes the build output with
+# BUILD_VERBOSE to be larger and less readable.
+ifdef HOSTBOOT_PROFILE
+SOURCE_FILE=$(shell readlink -f $<)
+INCLUDE_DIRS=$(shell $(ROOTPATH)/src/build/tools/cflags.sh $(INCFLAGS))
+else
+SOURCE_FILE=$<
+INCLUDE_DIRS=$(INCFLAGS)
+endif
+
+# TODO RTC 215692
+# The following script is used to run the cppcheck tool when enabled. If one
+# cppcheck error is found, the make process will stop here, the error will be
+# printed out to the terminal and stored in a file .`basename $<`.cppcheck in
+# the directory where the original file is located
+ifdef DOCPPCHECK
+ CXX_PRINT=$(C2) " CPPCHECK $(notdir $<)"
+ # NoteL Error code 127 means that the command timed-out. We do not fail
+ # for timeouts
+ CXX_CPPCHECK_COMMAND=$(C1) set -o pipefail && cd `dirname $<` && timeout 2m $(CXX_CHECK) `basename $<` 2>&1 | tee .`basename $<`.cppcheck; exit_code=$$? ; \
+ if [ "$$exit_code" -ne 1 ]; then \
+ rm -f .`basename $<`.cppcheck; \
+ if [ "$$exit_code" -eq 127 ]; then \
+ exit_code=0; \
+ fi; \
+ fi; exit "$$exit_code"
+ C_CPPCHECK_COMMAND=$(C1) set -o pipefail && cd `dirname $<` && timeout 2m $(C_CHECK) `basename $<` 2>&1 | tee .`basename $<`.cppcheck; exit_code=$$? ; \
+ if [ "$$exit_code" -ne 1 ]; then \
+ rm -f .`basename $<`.cppcheck; \
+ if [ "$$exit_code" -eq 127 ]; then \
+ exit_code=0; \
+ fi; \
+ fi; exit "$$exit_code"
+else
+ CXX_PRINT=
+ CXX_CPPCHECK_COMMAND=
+ C_CPPCHECK_COMMAND=
+endif
+
$(OBJDIR)/%.o : %.C
@mkdir -p $(OBJDIR)
$(C2) " CXX $(notdir $<)"
- $(C1)$(CXX) -c $(call FLAGS_FILTER, $(CXXFLAGS), $<) $< \
- -o $@.trace $(INCFLAGS) -iquote .
+ $(C1)$(CXX) -c $(call FLAGS_FILTER, $(CXXFLAGS), $<) $(SOURCE_FILE) \
+ -o $@.trace $(INCLUDE_DIRS) -iquote .
$(C1)$(TRACE_HASHER) $@ $(TRACE_FLAGS)
@rm $@.trace
+ $(CXX_PRINT)
+ $(CXX_CPPCHECK_COMMAND)
# Compiling *.cc files
$(OBJDIR)/%.o : %.cc
@mkdir -p $(OBJDIR)
$(C2) " CXX $(notdir $<)"
- $(C1)$(CXX) -c $(CXXFLAGS) $< -o $@.trace $(INCFLAGS) -iquote .
+ $(C1)$(CXX) -c $(CXXFLAGS) $(SOURCE_FILE) -o $@.trace \
+ $(INCLUDE_DIRS) -iquote .
$(C1)$(TRACE_HASHER) $@ $(TRACE_FLAGS)
@rm $@.trace
-
+ $(CXX_PRINT)
+ $(CXX_CPPCHECK_COMMAND)
$(OBJDIR)/%.o : %.c
@mkdir -p $(OBJDIR)
@@ -54,12 +103,16 @@ $(OBJDIR)/%.o : %.c
# CC_OVERRIDE is set in the makefile of the component
ifndef CC_OVERRIDE
$(C2) " CC $(notdir $<)"
- $(C1)$(CC) -c $(call FLAGS_FILTER, $(CFLAGS), $<) $< \
- -o $@.trace $(INCFLAGS) -iquote .
+ $(C1)$(CC) -c $(call FLAGS_FILTER, $(CFLAGS), $<) $(SOURCE_FILE) \
+ -o $@.trace $(INCLUDE_DIRS) -iquote .
+ $(CXX_PRINT)
+ $(C_CPPCHECK_COMMAND)
else
$(C2) " CXX $(notdir $<)"
- $(C1)$(CXX) -c $(call FLAGS_FILTER, $(CXXFLAGS), $<) $< \
- -o $@.trace $(INCFLAGS) -iquote .
+ $(C1)$(CXX) -c $(call FLAGS_FILTER, $(CXXFLAGS), $<) $(SOURCE_FILE) \
+ -o $@.trace $(INCLUDE_DIRS) -iquote .
+ $(CXX_PRINT)
+ $(CXX_CPPCHECK_COMMAND)
endif
$(C1)$(TRACE_HASHER) $@ $(TRACE_FLAGS)
@rm $@.trace
diff --git a/src/build/mkrules/cflags.env.mk b/src/build/mkrules/cflags.env.mk
index 04ff6fedd..cb25561f8 100644
--- a/src/build/mkrules/cflags.env.mk
+++ b/src/build/mkrules/cflags.env.mk
@@ -28,7 +28,7 @@
# Description:
# Configuration of the compiler, linker, etc. flags.
-OPT_LEVEL ?= -O3
+OPT_LEVEL ?= -Os
ifdef MODULE
COMMONFLAGS += -fPIC -Bsymbolic -Bsymbolic-functions
@@ -38,6 +38,8 @@ CFLAGS += -DNO_INITIALIZER_LIST
CFLAGS += -D__FAPI
endif
+# Force all files to pull in the CONFIG_ variables
+CFLAGS += -include config.h
COMMONFLAGS += $(OPT_LEVEL) -nostdlib
CFLAGS += $(COMMONFLAGS) -mcpu=power7 -nostdinc -g -mno-vsx -mno-altivec\
diff --git a/src/build/mkrules/dist.targets.mk b/src/build/mkrules/dist.targets.mk
index 0d592b838..c925f25b5 100755
--- a/src/build/mkrules/dist.targets.mk
+++ b/src/build/mkrules/dist.targets.mk
@@ -304,6 +304,9 @@ fsp.tar_CONTENTS = \
src/build/buildpnor/genfakeheader.pl \
src/build/buildpnor/genPnorImages.pl \
src/build/buildpnor/buildUcdFlashImages.pl \
+ src/build/buildpnor/buildBpmFlashImages.pl \
+ src/build/buildpnor/bpm-utils/insertBpmFwCrc.py \
+ src/build/buildpnor/bpm-utils/imageCrc.c \
src/build/buildpnor/PnorUtils.pm \
src/build/buildpnor/imprintHwKeyHash \
src/build/buildpnor/pkgOcmbFw.pl \
@@ -357,7 +360,8 @@ fsp.tar_CONTENTS = \
src/include/usr/hwas/common/hwasCallout.H:hwas/ \
src/include/usr/devicefw/driverif.H:devicefw/ \
src/include/usr/devicefw/userif.H:devicefw/ \
- obj/genfiles/plugins/errludattribute.H:plugins/ \
+ obj/genfiles/plugins/errludattributeP_gen.H:plugins/ \
+ src/usr/errl/plugins/errludattributeP.H:plugins/ \
obj/genfiles/plugins/errludtarget.H:plugins/ \
$(addsuffix :plugins/,\
$(call ROOTPATH_WILDCARD,obj/genfiles/plugins/hbfwSrcParse*.C)) \
diff --git a/src/build/mkrules/gcov.env.mk b/src/build/mkrules/gcov.env.mk
index 8ddcd3ef6..edce52a24 100644
--- a/src/build/mkrules/gcov.env.mk
+++ b/src/build/mkrules/gcov.env.mk
@@ -5,7 +5,9 @@
#
# OpenPOWER HostBoot Project
#
-# COPYRIGHT International Business Machines Corp. 2013,2014
+# Contributors Listed Below - COPYRIGHT 2013,2019
+# [+] International Business Machines Corp.
+#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -26,21 +28,44 @@
# Configuration of the GCOV settings.
GCOVDIR = $(ROOTPATH)/obj/gcov
+vpath %.C $(ROOTPATH)/src/sys/prof
ifdef MODULE
-GCOVNAME = $(MODULE).lcov
+
+# Don't profile HBRT modules to keep size down
+ifdef HOSTBOOT_RUNTIME
+HOSTBOOT_PROFILE=
+endif
+
+## We don't want certain modules to be profiled (HBB, HBRT).
+
+# This is replacing spaces with colons so that we can get an exact
+# match on the module name in the list of unprofilable modules with
+# findstring, which otherwise would find matches on "partial"
+# substrings (i.e. we don't want to deprofile module ABC just because
+# module ABCD is blacklisted, so we create a blacklist of modules
+# separated by colons and search for :ABC:).
+null :=
+MODULE_PROFILE_BLACKLIST:=:$(subst ${null} ${null},:,$(BASE_MODULES_GCOV_BLACKLIST) $(RUNTIME_MODULES_GCOV_BLACKLIST)):
+
+ifneq (,$(findstring :$(MODULE):,$(MODULE_PROFILE_BLACKLIST)))
+HOSTBOOT_PROFILE=
+endif
+
+GCOVNAME := $(MODULE).lcov
+
ifndef TESTS
ifdef HOSTBOOT_PROFILE
-vpath %.C $(ROOTPATH)/src/sys/prof
OBJS := gcov.o $(OBJS)
endif
endif
else
-GCOVNAME = $(notdir $(shell pwd)).lcov
+GCOVNAME := $(notdir $(shell pwd)).lcov
endif
-## Disable coverage on test cases, any directory that sets
-## HOSTBOOT_PROFILE_NO_INSTRUMENT or any file that has 'gcov' in the name.
+## Disable coverage on test cases or any directory that sets
+## HOSTBOOT_PROFILE_NO_INSTRUMENT
+
ifndef TESTS
ifdef HOSTBOOT_PROFILE
ifndef HOSTBOOT_PROFILE_NO_INSTRUMENT
@@ -59,5 +84,16 @@ endif
## Reduce the optimization level when profiling is enabled to ensure the
## base image fits in 512k still.
ifdef HOSTBOOT_PROFILE
-OPT_LEVEL = -Os
+# We're not doing this right now because it causes linker errors in
+# various parts of hostboot with or without gcov (i.e. functions that
+# the code relies on being inlined are not; some const statics that
+# aren't defined in a compilation unit have linker references, etc.)
+# and it also causes the image to be generated incorrectly (symbol
+# names are wrong, calls to functions named things like __savegpr_rXX
+# are emitted but the functions themselves aren't and so you end up
+# jumping into an area of zeroes, ...). We should come back to this
+# later and fix, we might be able to profile more of hostboot with the
+# space savings that -Os could give.
+
+#OPT_LEVEL = -Os
endif
diff --git a/src/build/mkrules/hbfw/img/makefile b/src/build/mkrules/hbfw/img/makefile
index 269a52ce5..114cb6384 100755
--- a/src/build/mkrules/hbfw/img/makefile
+++ b/src/build/mkrules/hbfw/img/makefile
@@ -65,6 +65,7 @@ SBEI_OBJPATH = ${HBFW_OBJPATH:S/hbfw\/img/sbei\/sbfw\/img/g}
ENGD_WOFPATH = ${HBFW_OBJPATH:S/hbfw\/img/engd\/wofdata/g}
ENGD_MEMDPATH = ${HBFW_OBJPATH:S/hbfw\/img/engd\/memd/g}
HBFW_SIMPATH = ${HBFW_OBJPATH:S/img/simics/g}
+EDITED_LAYOUT_PATH = ${DUMMY:!pwd!}
#################################################
# Copy Hostboot binary images to obj dir to be grabbed
# during build flash pass and consumption by HWSV.
@@ -113,7 +114,6 @@ TESTRO_FINAL_IMG = TESTRO.bin
TESTLOAD_FINAL_IMG = TESTLOAD.bin
HBEL_FINAL_IMG = HBEL.bin
GUARD_FINAL_IMG = GUARD.bin
-GLOBAL_FINAL_IMG = GLOBAL.bin
DJVPD_FINAL_IMG = DJVPD.bin
MVPD_FINAL_IMG = MVPD.bin
CVPD_FINAL_IMG = CVPD.bin
@@ -126,7 +126,7 @@ EECACHE_FINAL_IMG = EECACHE.bin
OCMBFW_FINAL_IMG = OCMBFW.bin
FINAL_OUTPUT_IMAGES = ${HBBL_FINAL_IMG} ${HBB_FINAL_IMG} ${HBI_FINAL_IMG} \
${HBRT_FINAL_IMG} ${TEST_FINAL_IMG} ${TESTRO_FINAL_IMG} \
- ${HBEL_FINAL_IMG} ${GUARD_FINAL_IMG} ${GLOBAL_FINAL_IMG} \
+ ${HBEL_FINAL_IMG} ${GUARD_FINAL_IMG} \
${DJVPD_FINAL_IMG} ${MVPD_FINAL_IMG} ${CVPD_FINAL_IMG} \
${PAYLOAD_FINAL_IMG} ${RINGOVD_FINAL_IMG} ${SBKT_FINAL_IMG} \
${FIRDATA_FINAL_IMG} ${MEMD_FINAL_IMG} ${EECACHE_FINAL_IMG} \
@@ -214,26 +214,28 @@ BUILD_TYPE_PARAMS = --build-type fspbuild
.endif
# Decide which images to use for each PNOR layout
-GEN_COMMON_BIN_FILES = HBBL=${HBBL_IMG},HBB=${HBB_IMG},HBI=${HBI_IMG},HBRT=${HBRT_IMG},HBEL=EMPTY,GUARD=EMPTY,GLOBAL=EMPTY,MVPD=EMPTY,RINGOVD=EMPTY,SBKT=EMPTY
+GEN_COMMON_BIN_FILES = HBBL=${HBBL_IMG},HBB=${HBB_IMG},HBI=${HBI_IMG},HBRT=${HBRT_IMG},HBEL=EMPTY,GUARD=EMPTY,RINGOVD=EMPTY,SBKT=EMPTY
GEN_STANDALONE_BIN_FILES = ${GEN_COMMON_BIN_FILES},TEST=EMPTY,TESTRO=EMPTY,TESTLOAD=EMPTY,PAYLOAD=EMPTY,FIRDATA=EMPTY
.if (${FAKEPNOR} == "")
# Parameters passed into GEN_PNOR_IMAGE_SCRIPT.
.if (${PNOR_LAYOUT_SELECTED} == "STANDALONE")
- GEN_DEFAULT_BIN_FILES = ${GEN_STANDALONE_BIN_FILES},MEMD=${${ZZ_MEMD_IMG}:P},CVPD=EMPTY,DJVPD=EMPTY
+ GEN_DEFAULT_BIN_FILES = ${GEN_STANDALONE_BIN_FILES},MEMD=${${ZZ_MEMD_IMG}:P},CVPD=EMPTY,DJVPD=EMPTY,MVPD=EMPTY
.elif(${PNOR_LAYOUT_SELECTED} == "AXONE")
- GEN_DEFAULT_BIN_FILES = ${GEN_STANDALONE_BIN_FILES},EECACHE=EMPTY,MEMD=${${ZZ_MEMD_IMG}:P},OCMBFW=${${OCMBFW_IMG}:P}
+ GEN_DEFAULT_BIN_FILES = ${GEN_STANDALONE_BIN_FILES},EECACHE=EMPTY,OCMBFW=${${OCMBFW_IMG}:P}
.else
- GEN_DEFAULT_BIN_FILES = ${GEN_COMMON_BIN_FILES},MEMD=${${ZZ_MEMD_IMG}:P},CVPD=EMPTY,DJVPD=EMPTY
+ GEN_DEFAULT_BIN_FILES = ${GEN_COMMON_BIN_FILES},MEMD=${${ZZ_MEMD_IMG}:P},CVPD=EMPTY,DJVPD=EMPTY,MVPD=EMPTY
.endif
DEFAULT_PARAMS = --build-all --emit-eccless ${TARGET_TEST:b--test} ${HB_STANDALONE:b--hb-standalone} \
${CONFIG_SECUREBOOT:b--secureboot} --systemBinFiles ${GEN_DEFAULT_BIN_FILES} \
--pnorLayout ${PNOR_LAYOUT} ${KEY_TRANSITION_PARAMS} ${CORRUPT_PARAMS} \
- --hwKeyHashFile ${IMPRINT_HW_KEY_HASH}
+ --hwKeyHashFile ${IMPRINT_HW_KEY_HASH} \
+ --editedLayoutLocation ${EDITED_LAYOUT_PATH}
.else
PNOR_LAYOUT = ${pnorLayoutFake.xml:P}
# Parameters passed into GEN_PNOR_IMAGE_SCRIPT.
GEN_DEFAULT_BIN_FILES = HBI=${HBI_IMG},HBEL=EMPTY,MVPD=${${VPO_FAKE_MVPD}:P},DJVPD=${${VPO_FAKE_DJVPD}:P},FIRDATA=EMPTY,MEMD=EMPTY
- DEFAULT_PARAMS = --systemBinFiles ${GEN_DEFAULT_BIN_FILES} --pnorLayout ${PNOR_LAYOUT}
+ DEFAULT_PARAMS = --systemBinFiles ${GEN_DEFAULT_BIN_FILES} --pnorLayout ${PNOR_LAYOUT} \
+ --editedLayoutLocation ${EDITED_LAYOUT_PATH}
.endif
# rule to update hostboot image tags for custom CFM image, only enabled
@@ -375,7 +377,6 @@ AXONE_HCODE_IMG = ${ENGD_SRCPATH:Fp9a.hw_ref_image.bin}
CUMULUS_CENHWIMG_IMG = ${ENGD_SRCPATH:Fcen.hw_ref_image.bin}
NIMBUS_CENHWIMG_IMG = cen.hw_ref_image.bin.fake
-AXONE_CENHWIMG_IMG = cen.hw_ref_image.bin.fake
NIMBUS_OCC_IMG = ${bb}/images/ppc/lab/fs/p9le/rootfs/opt/extucode/81e00430.lid
CUMULUS_OCC_IMG = ${bb}/images/ppc/lab/fs/p9le/rootfs/opt/extucode/81e00430.lid
AXONE_OCC_IMG = ${bb}/images/ppc/lab/fs/p9le/rootfs/opt/extucode/81e00430.lid
@@ -389,6 +390,8 @@ ZEPPELIN_MEMD_IMG = ${ENGD_MEMDPATH:Fzeppelin_memd_output.dat}
FLEETWOOD_MEMD_IMG = ${ENGD_MEMDPATH:Ffleetwood_memd_output.dat}
ZZ_HBD_IMG = ${HBFW_TARGPATH:FZZ_hb_targeting.bin}
ZZ2U_HBD_IMG = ${HBFW_TARGPATH:FZZ-2U_hb_targeting.bin}
+ZZGEN4_HBD_IMG = ${HBFW_TARGPATH:FZZ-GEN4_hb_targeting.bin}
+ZZ2UGEN4_HBD_IMG = ${HBFW_TARGPATH:FZZ-2U-GEN4_hb_targeting.bin}
ZEPPELIN_HBD_IMG = ${HBFW_TARGPATH:FZEPPELIN_hb_targeting.bin}
# Create list of images for each node (in node order)
# genPnorImages will handle multiple HBD=binfile pairs
@@ -409,7 +412,6 @@ CUMULUS_HCODE_FINAL_IMG = CUMULUS.HCODE.bin
AXONE_HCODE_FINAL_IMG = AXONE.HCODE.bin
CUMULUS_CENHWIMG_FINAL_IMG = CUMULUS.CENHWIMG.bin
NIMBUS_CENHWIMG_FINAL_IMG = NIMBUS.CENHWIMG.bin
-AXONE_CENHWIMG_FINAL_IMG = AXONE.CENHWIMG.bin
NIMBUS_SBE_FINAL_IMG = NIMBUS.SBE.bin
CUMULUS_SBE_FINAL_IMG = CUMULUS.SBE.bin
AXONE_SBE_FINAL_IMG = AXONE.SBE.bin
@@ -428,7 +430,8 @@ ZZ_HBD_FINAL_IMG = ZZ.HBD.bin
ZEPPELIN_HBD_FINAL_IMG = ZEPPELIN.HBD.bin
FLEETWOOD_HBD_FINAL_IMGS = FLEETWOOD.HBD_NODE_0.bin,FLEETWOOD.HBD_NODE_1.bin,FLEETWOOD.HBD_NODE_2.bin,FLEETWOOD.HBD_NODE_3.bin,FLEETWOOD_MST.HBD_NODE_0.bin,FLEETWOOD_2N.HBD_NODE_0.bin,FLEETWOOD_2N.HBD_NODE_1.bin,FLEETWOOD_2N.HBD_NODE_2.bin,FLEETWOOD_2N.HBD_NODE_3.bin
ZZ2U_HBD_FINAL_IMG = ZZ-2U.HBD.bin
-
+ZZGEN4_HBD_FINAL_IMG = ZZ-GEN4.HBD.bin
+ZZ2UGEN4_HBD_FINAL_IMG = ZZ-2U-GEN4.HBD.bin
# Decide which PNOR to build
@@ -438,18 +441,20 @@ ZZ2U_HBD_FINAL_IMG = ZZ-2U.HBD.bin
GEN_NIMBUS_BIN_FILES = NIMBUS:SBE=${${NIMBUS_SBE_IMG}:P},HCODE=${${NIMBUS_HCODE_IMG}:P},OCC=${${NIMBUS_OCC_IMG}:P},HBD=${${NIMBUS_HBD_IMG}:P},CENHWIMG=${NIMBUS_CENHWIMG_IMG}
GEN_CUMULUS_BIN_FILES = CUMULUS:SBE=${${CUMULUS_SBE_IMG}:P},HCODE=${${CUMULUS_HCODE_IMG}:P},OCC=${${CUMULUS_OCC_IMG}:P},HBD=${${CUMULUS_HBD_IMG}:P},CENHWIMG=${${CUMULUS_CENHWIMG_IMG}:P}
GEN_CUMULUS_CDIMM_BIN_FILES = CUMULUS_CDIMM:SBE=${${CUMULUS_SBE_IMG}:P},HCODE=${${CUMULUS_HCODE_IMG}:P},OCC=${${CUMULUS_OCC_IMG}:P},HBD=${${CUMULUS_CDIMM_HBD_IMG}:P},CENHWIMG=${${CUMULUS_CENHWIMG_IMG}:P}
- GEN_AXONE_BIN_FILES = AXONE:SBE=${${AXONE_SBE_IMG}:P},HCODE=${${AXONE_HCODE_IMG}:P},OCC=${${AXONE_OCC_IMG}:P},HBD=${${AXONE_HBD_IMG}:P},CENHWIMG=${AXONE_CENHWIMG_IMG}
+ GEN_AXONE_BIN_FILES = AXONE:SBE=${${AXONE_SBE_IMG}:P},HCODE=${${AXONE_HCODE_IMG}:P},OCC=${${AXONE_OCC_IMG}:P},HBD=${${AXONE_HBD_IMG}:P}
.else
GEN_NIMBUS_BIN_FILES = NIMBUS:SBE=${${NIMBUS_SBE_IMG}:P},HCODE=${${NIMBUS_HCODE_IMG}:P},OCC=${${NIMBUS_OCC_IMG}:P},HBD=${${NIMBUS_HBD_IMG}:P},CENHWIMG=${NIMBUS_CENHWIMG_IMG}
GEN_CUMULUS_BIN_FILES = CUMULUS:SBE=${${CUMULUS_SBE_IMG}:P},HCODE=${${CUMULUS_HCODE_IMG}:P},OCC=${${CUMULUS_OCC_IMG}:P},HBD=${${CUMULUS_HBD_IMG}:P},CENHWIMG=${${CUMULUS_CENHWIMG_IMG}:P}
GEN_CUMULUS_CDIMM_BIN_FILES = CUMULUS_CDIMM:SBE=${${CUMULUS_SBE_IMG}:P},HCODE=${${CUMULUS_HCODE_IMG}:P},OCC=${${CUMULUS_OCC_IMG}:P},HBD=${${CUMULUS_CDIMM_HBD_IMG}:P},CENHWIMG=${${CUMULUS_CENHWIMG_IMG}:P}
- GEN_AXONE_BIN_FILES = AXONE:SBE=${${AXONE_SBE_IMG}:P},HCODE=${${AXONE_HCODE_IMG}:P},OCC=${${AXONE_OCC_IMG}:P},HBD=${${AXONE_HBD_IMG}:P},CENHWIMG=${AXONE_CENHWIMG_IMG}
+ GEN_AXONE_BIN_FILES = AXONE:SBE=${${AXONE_SBE_IMG}:P},HCODE=${${AXONE_HCODE_IMG}:P},OCC=${${AXONE_OCC_IMG}:P},HBD=${${AXONE_HBD_IMG}:P}
.endif
GEN_ZZ_BIN_FILES = ZZ:WOFDATA=${${ZZ_WOFDATA_IMG}:P},MEMD=${${ZZ_MEMD_IMG}:P},HBD=${${ZZ_HBD_IMG}:P}
GEN_ZEPPELIN_BIN_FILES = ZEPPELIN:WOFDATA=${${ZEPPELIN_WOFDATA_IMG}:P},MEMD=${${ZEPPELIN_MEMD_IMG}:P},HBD=${${ZEPPELIN_HBD_IMG}:P}
GEN_FLEETWOOD_BIN_FILES = FLEETWOOD:WOFDATA=${${FLEETWOOD_WOFDATA_IMG}:P},MEMD=${${FLEETWOOD_MEMD_IMG}:P},${FLEETWOOD_HBD_IMGS}
GEN_ZZ2U_BIN_FILES = ZZ-2U:WOFDATA=${${ZZ_WOFDATA_IMG}:P},MEMD=${${ZZ_MEMD_IMG}:P},HBD=${${ZZ2U_HBD_IMG}:P}
+ GEN_ZZGEN4_BIN_FILES = ZZ-GEN4:WOFDATA=${${ZZ_WOFDATA_IMG}:P},MEMD=${${ZZ_MEMD_IMG}:P},HBD=${${ZZGEN4_HBD_IMG}:P}
+ GEN_ZZ2UGEN4_BIN_FILES = ZZ-2U-GEN4:WOFDATA=${${ZZ_WOFDATA_IMG}:P},MEMD=${${ZZ_MEMD_IMG}:P},HBD=${${ZZ2UGEN4_HBD_IMG}:P}
SYSTEM_SPECIFIC_PARAMS = --install-all --emit-eccless ${TARGET_TEST:b--test} ${CONFIG_SECUREBOOT:b--secureboot} \
--pnorLayout ${PNOR_LAYOUT} ${CORRUPT_PARAMS} ${HB_STANDALONE:b--hb-standalone} \
@@ -461,18 +466,22 @@ ZZ2U_HBD_FINAL_IMG = ZZ-2U.HBD.bin
--systemBinFiles ${GEN_ZEPPELIN_BIN_FILES} \
--systemBinFiles ${GEN_FLEETWOOD_BIN_FILES} \
--systemBinFiles ${GEN_ZZ2U_BIN_FILES} \
- --hwKeyHashFile ${IMPRINT_HW_KEY_HASH}
+ --systemBinFiles ${GEN_ZZGEN4_BIN_FILES} \
+ --systemBinFiles ${GEN_ZZ2UGEN4_BIN_FILES} \
+ --hwKeyHashFile ${IMPRINT_HW_KEY_HASH} \
+ --editedLayoutLocation ${EDITED_LAYOUT_PATH}
.else
# Parameters passed into GEN_PNOR_IMAGE_SCRIPT.
GEN_NIMBUS_BIN_FILES = NIMBUS:HCODE=${${NIMBUS_HCODE_IMG}:P},HBD=${${NIMBUS_VPO_HBD_IMG}:P},CENHWIMG=EMPTY
GEN_CUMULUS_BIN_FILES = CUMULUS:HCODE=${${CUMULUS_HCODE_IMG}:P},CENHWIMG=${${CUMULUS_CENHWIMG_IMG}:P}
GEN_CUMULUS_CDIMM_BIN_FILES = CUMULUS:HCODE=${${CUMULUS_HCODE_IMG}:P},CENHWIMG=${${CUMULUS_CENHWIMG_IMG}:P}
- GEN_AXONE_BIN_FILES = AXONE:HCODE=${${AXONE_HCODE_IMG}:P},HBD=${${AXONE_VPO_HBD_IMG}:P},CENHWIMG=EMPTY
+ GEN_AXONE_BIN_FILES = AXONE:HCODE=${${AXONE_HCODE_IMG}:P},HBD=${${AXONE_VPO_HBD_IMG}:P}
SYSTEM_SPECIFIC_PARAMS = --pnorLayout ${PNOR_LAYOUT} \
--systemBinFiles ${GEN_NIMBUS_BIN_FILES} \
--systemBinFiles ${GEN_CUMULUS_BIN_FILES} \
--systemBinFiles ${GEN_AXONE_BIN_FILES} \
- --systemBinFiles ${GEN_CUMULUS_CDIMM_BIN_FILES}
+ --systemBinFiles ${GEN_CUMULUS_CDIMM_BIN_FILES} \
+ --editedLayoutLocation ${EDITED_LAYOUT_PATH}
.endif
gen_system_specific_images_bypass_cache : dump-secureboot-config
@@ -493,14 +502,14 @@ gen_system_specific_images: build_sbe_partitions .PMAKE
.if (${PNOR_LAYOUT_SELECTED} == "FSP")
- HOSTBOOT_DEFAULT_SECTIONS = HBBL=${HBBL_FINAL_IMG},HBB=${HBB_FINAL_IMG},HBI=${HBI_FINAL_IMG},HBRT=${HBRT_FINAL_IMG},HBEL=${HBEL_FINAL_IMG},GUARD=${GUARD_FINAL_IMG},GLOBAL=${GLOBAL_FINAL_IMG},MVPD=${MVPD_FINAL_IMG},RINGOVD=${RINGOVD_FINAL_IMG},SBKT=${SBKT_FINAL_IMG}
+ HOSTBOOT_DEFAULT_SECTIONS = HBBL=${HBBL_FINAL_IMG},HBB=${HBB_FINAL_IMG},HBI=${HBI_FINAL_IMG},HBRT=${HBRT_FINAL_IMG},HBEL=${HBEL_FINAL_IMG},GUARD=${GUARD_FINAL_IMG},MVPD=${MVPD_FINAL_IMG},RINGOVD=${RINGOVD_FINAL_IMG},SBKT=${SBKT_FINAL_IMG}
.else
- HOSTBOOT_DEFAULT_SECTIONS = HBBL=${HBBL_FINAL_IMG},HBB=${HBB_FINAL_IMG},HBI=${HBI_FINAL_IMG},HBRT=${HBRT_FINAL_IMG},TEST=${TEST_FINAL_IMG},TESTRO=${TESTRO_FINAL_IMG},TESTLOAD=${TESTLOAD_FINAL_IMG},HBEL=${HBEL_FINAL_IMG},GUARD=${GUARD_FINAL_IMG},GLOBAL=${GLOBAL_FINAL_IMG},PAYLOAD=${PAYLOAD_FINAL_IMG},MVPD=${MVPD_FINAL_IMG},RINGOVD=${RINGOVD_FINAL_IMG},SBKT=${SBKT_FINAL_IMG},FIRDATA=${FIRDATA_FINAL_IMG}
+ HOSTBOOT_DEFAULT_SECTIONS = HBBL=${HBBL_FINAL_IMG},HBB=${HBB_FINAL_IMG},HBI=${HBI_FINAL_IMG},HBRT=${HBRT_FINAL_IMG},TEST=${TEST_FINAL_IMG},TESTRO=${TESTRO_FINAL_IMG},TESTLOAD=${TESTLOAD_FINAL_IMG},HBEL=${HBEL_FINAL_IMG},GUARD=${GUARD_FINAL_IMG},PAYLOAD=${PAYLOAD_FINAL_IMG},RINGOVD=${RINGOVD_FINAL_IMG},SBKT=${SBKT_FINAL_IMG},FIRDATA=${FIRDATA_FINAL_IMG}
.endif
-NIMBUS_SECT = HBD=${NIMBUS_HBD_FINAL_IMG},SBE=${NIMBUS_SBE_FINAL_IMG},HCODE=${NIMBUS_HCODE_FINAL_IMG},OCC=${NIMBUS_OCC_FINAL_IMG},WOFDATA=${ZZ_WOFDATA_FINAL_IMG},CENHWIMG=${NIMBUS_CENHWIMG_FINAL_IMG},MEMD=${ZZ_MEMD_FINAL_IMG},CVPD=${CVPD_FINAL_IMG},DJVPD=${DJVPD_FINAL_IMG}
-CUMULUS_SECT = HBD=${CUMULUS_HBD_FINAL_IMG},SBE=${CUMULUS_SBE_FINAL_IMG},HCODE=${CUMULUS_HCODE_FINAL_IMG},OCC=${CUMULUS_OCC_FINAL_IMG},WOFDATA=${ZEPPELIN_WOFDATA_FINAL_IMG},CENHWIMG=${CUMULUS_CENHWIMG_FINAL_IMG},MEMD=${ZEPPELIN_MEMD_FINAL_IMG},CVPD=${CVPD_FINAL_IMG},DJVPD=${DJVPD_FINAL_IMG}
-CUMULUS_CDIMM_SECT = HBD=${CUMULUS_CDIMM_HBD_FINAL_IMG},SBE=${CUMULUS_SBE_FINAL_IMG},HCODE=${CUMULUS_HCODE_FINAL_IMG},OCC=${CUMULUS_OCC_FINAL_IMG},WOFDATA=${ZEPPELIN_WOFDATA_FINAL_IMG},CENHWIMG=${CUMULUS_CENHWIMG_FINAL_IMG},MEMD=${MEMD_FINAL_IMG},CVPD=${CVPD_FINAL_IMG},DJVPD=${DJVPD_FINAL_IMG}
-AXONE_SECT = HBD=${AXONE_HBD_FINAL_IMG},SBE=${AXONE_SBE_FINAL_IMG},HCODE=${AXONE_HCODE_FINAL_IMG},OCC=${AXONE_OCC_FINAL_IMG},WOFDATA=${ZEPPELIN_WOFDATA_FINAL_IMG},CENHWIMG=${AXONE_CENHWIMG_FINAL_IMG},EECACHE=${EECACHE_FINAL_IMG},FIRDATA=${FIRDATA_FINAL_IMG},MEMD=${MEMD_FINAL_IMG},OCMBFW=${OCMBFW_FINAL_IMG}
+NIMBUS_SECT = HBD=${NIMBUS_HBD_FINAL_IMG},SBE=${NIMBUS_SBE_FINAL_IMG},HCODE=${NIMBUS_HCODE_FINAL_IMG},OCC=${NIMBUS_OCC_FINAL_IMG},WOFDATA=${ZZ_WOFDATA_FINAL_IMG},CENHWIMG=${NIMBUS_CENHWIMG_FINAL_IMG},MEMD=${ZZ_MEMD_FINAL_IMG},CVPD=${CVPD_FINAL_IMG},DJVPD=${DJVPD_FINAL_IMG},MVPD=${MVPD_FINAL_IMG}
+CUMULUS_SECT = HBD=${CUMULUS_HBD_FINAL_IMG},SBE=${CUMULUS_SBE_FINAL_IMG},HCODE=${CUMULUS_HCODE_FINAL_IMG},OCC=${CUMULUS_OCC_FINAL_IMG},WOFDATA=${ZEPPELIN_WOFDATA_FINAL_IMG},CENHWIMG=${CUMULUS_CENHWIMG_FINAL_IMG},MEMD=${ZEPPELIN_MEMD_FINAL_IMG},CVPD=${CVPD_FINAL_IMG},DJVPD=${DJVPD_FINAL_IMG},MVPD=${MVPD_FINAL_IMG}
+CUMULUS_CDIMM_SECT = HBD=${CUMULUS_CDIMM_HBD_FINAL_IMG},SBE=${CUMULUS_SBE_FINAL_IMG},HCODE=${CUMULUS_HCODE_FINAL_IMG},OCC=${CUMULUS_OCC_FINAL_IMG},WOFDATA=${ZEPPELIN_WOFDATA_FINAL_IMG},CENHWIMG=${CUMULUS_CENHWIMG_FINAL_IMG},MEMD=${MEMD_FINAL_IMG},CVPD=${CVPD_FINAL_IMG},DJVPD=${DJVPD_FINAL_IMG},MVPD=${MVPD_FINAL_IMG}
+AXONE_SECT = HBD=${AXONE_HBD_FINAL_IMG},SBE=${AXONE_SBE_FINAL_IMG},HCODE=${AXONE_HCODE_FINAL_IMG},OCC=${AXONE_OCC_FINAL_IMG},WOFDATA=${ZEPPELIN_WOFDATA_FINAL_IMG},EECACHE=${EECACHE_FINAL_IMG},FIRDATA=${FIRDATA_FINAL_IMG},OCMBFW=${OCMBFW_FINAL_IMG}
.if (${PNOR_LAYOUT_SELECTED} == "AXONE")
@@ -525,7 +534,7 @@ PNOR_IMG_INFO = \
NIMBUS_SECT = HBD=${NIMBUS_HBD_FINAL_IMG},HCODE=${NIMBUS_HCODE_FINAL_IMG},CENHWIMG=${NIMBUS_CENHWIMG_FINAL_IMG}
CUMULUS_SECT = HBD=${CUMULUS_HBD_FINAL_IMG},HCODE=${CUMULUS_HCODE_FINAL_IMG},CENHWIMG=${CUMULUS_CENHWIMG_FINAL_IMG}
CUMULUS_CDIMM_SECT = HBD=${CUMULUS_CDIMM_HBD_FINAL_IMG},HCODE=${CUMULUS_HCODE_FINAL_IMG},CENHWIMG=${CUMULUS_CENHWIMG_FINAL_IMG}
- AXONE_SECT = HBD=${AXONE_HBD_FINAL_IMG},HCODE=${AXONE_HCODE_FINAL_IMG},CENHWIMG=${AXONE_CENHWIMG_FINAL_IMG}
+ AXONE_SECT = HBD=${AXONE_HBD_FINAL_IMG},HCODE=${AXONE_HCODE_FINAL_IMG}
PNOR_IMG_INFO = \
${FAKEPNOR}:${PNOR_LAYOUT}:${NIMBUS_SECT}:${CUMULUS_SECT}:${CUMULUS_CDIMM_SECT},${HOSTBOOT_DEFAULT_SECTIONS},${AXONE_SECT} \
${FIPS_PNOR_INFO}
@@ -562,7 +571,8 @@ ${IMAGE_TARGET}: ${IMAGE_LAYOUT} ${IMAGE_BINS} ${PNOR_BUILD_SCRIPT}
${FAKEPNOR} == ${IMAGE_TARGET})
${PNOR_BUILD_SCRIPT} --pnorOutBin ${IMAGE_TARGET} \
${TARGET_TEST:b--test} --pnorLayout ${IMAGE_LAYOUT} \
- ${IMAGE_BIN_OPTION} --fpartCmd "fpart" --fcpCmd "fcp"
+ ${IMAGE_BIN_OPTION} --fpartCmd "fpart" --fcpCmd "fcp" \
+ --editedLayoutLocation ${EDITED_LAYOUT_PATH}
.endif
.endif
diff --git a/src/build/mkrules/images.rules.mk b/src/build/mkrules/images.rules.mk
index 2a611b030..c6b863d89 100644
--- a/src/build/mkrules/images.rules.mk
+++ b/src/build/mkrules/images.rules.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2017
+# Contributors Listed Below - COPYRIGHT 2013,2019
# [+] International Business Machines Corp.
#
#
@@ -27,14 +27,49 @@
# Description:
# Rules for linking the Hostboot binary images using the custom linker.
+# Folder to store *.objdump files in
+OBJDUMP_FOLDER := $(IMGDIR)/objdump
+
+# Clean up after ourselves
+clean: clean-objdump
+
+.PHONY: clean-objdump
+clean-objdump:
+ $(C2) " MAKE objdump CLEAN"
+ $(C1)rm -rf $(OBJDUMP_FOLDER)
+
ifdef IMGS
_IMGS = $(addprefix $(IMGDIR)/, $(IMGS))
IMAGES += $(addsuffix .bin, $(_IMGS)) $(addsuffix .elf, $(_IMGS))
+ifdef BUILD_FAST
+OBJDUMP_MODULES := $(sort $(foreach img, $(IMGS), $($(img)_MODULES) $($(img)_EXTENDED_MODULES)))
+
+OBJDUMP_BIN_TARGETS := $(addsuffix .elf.objdump, $(IMGS))
+OBJDUMP_LIB_TARGETS := $(addsuffix .so.objdump, $(OBJDUMP_MODULES))
+
+OBJDUMP_TARGETS := $(addprefix $(OBJDUMP_FOLDER)/lib, $(OBJDUMP_LIB_TARGETS))
+OBJDUMP_TARGETS += $(addprefix $(OBJDUMP_FOLDER)/, $(OBJDUMP_BIN_TARGETS))
+
+# Tell make not to delete our objdumps
+.SECONDARY: $(OBJDUMP_TARGETS)
+endif
+
IMAGE_PASS_POST += $(addsuffix .list.bz2, $(_IMGS)) $(addsuffix .syms, $(_IMGS))
CLEAN_TARGETS += $(addsuffix .list.bz2, $(_IMGS)) $(addsuffix .syms, $(_IMGS))
CLEAN_TARGETS += $(addsuffix .lnkout.bz2, $(addprefix $(IMGDIR)/., $(IMGS)))
+$(OBJDUMP_FOLDER):
+ mkdir -p $@
+
+$(OBJDUMP_FOLDER)/%.so.objdump: $(IMGDIR)/%.so $(OBJDUMP_FOLDER)
+ $(C2) " OBJDUMP $(notdir $*)"
+ $(C1)$(OBJDUMP) -dCS -j .text -j .data -j .rodata $< | bzip2 >$@
+
+$(OBJDUMP_FOLDER)/%.elf.objdump: $(IMGDIR)/%.elf $(OBJDUMP_FOLDER)
+ $(C2) " OBJDUMP $(notdir $*)"
+ $(C1)$(OBJDUMP) -dCS -j .text -j .data -j .rodata $< | bzip2 >$@
+
define ELF_template
$$(IMGDIR)/$(1).elf: $$(addprefix $$(OBJDIR)/, $$($(1)_OBJECTS)) \
$$(ROOTPATH)/src/$$($(1)_LDFILE)
@@ -63,7 +98,7 @@ $(IMGDIR)/%.bin: $(IMGDIR)/%.elf \
| bzip2 -zc > $(IMGDIR)/.$*.lnkout.bz2'
$(C1)$(ROOTPATH)/src/build/tools/addimgid $@ $<
-$(IMGDIR)/%.list.bz2 $(IMGDIR)/%.syms: $(IMGDIR)/%.bin
+$(IMGDIR)/%.list.bz2 $(IMGDIR)/%.syms: $(IMGDIR)/%.bin $(OBJDUMP_TARGETS)
$(C2) " GENLIST $(notdir $*)"
$(C1)(cd $(ROOTPATH)&& \
src/build/linker/gensyms $*.bin \
diff --git a/src/build/simics/standalone.simics b/src/build/simics/standalone.simics
index 39a382303..c785dfc44 100755
--- a/src/build/simics/standalone.simics
+++ b/src/build/simics/standalone.simics
@@ -9,10 +9,17 @@ if not defined hb_skip_vpd_preload {$hb_skip_vpd_preload = 0}
if ($hb_mode == 0) { # Axone and beyond
- # this number is no longer provided we have to look it up
- $num_dimms = (dec (list-length((get-master-procs)[0].get-dimms)))
+ # There is no VPD cache on Axone
+ $hb_skip_vpd_preload = 1;
}
+# Load up the pnor parsing function
+try {
+ add-directory $hb_pnor_dir
+ run-python-file (lookup-file simpnor.py)
+ echo "Loaded simpnor.py"
+} except { "No simpnor.py found, using hardcoding PNOR offsets." }
+
# Preload VPD in PNOR unless told not to
if ($hb_skip_vpd_preload == 0) {
@@ -24,8 +31,7 @@ if ($hb_skip_vpd_preload == 0) {
$procChipType=(get-object-list p9_proc)[0]->chip_type
python "os.environ['HB_PROC_CHIP_TYPE'] = \""+$procChipType+"\""
} else {
- $procChipType=($hb_masterproc)->chip_type
- python "os.environ['HB_PROC_CHIP_TYPE'] = \""+$procChipType+"\""
+ python "os.environ['HB_PROC_CHIP_TYPE'] = \""+$proc_chip_type+"\""
}
@@ -54,6 +60,36 @@ if ($hb_skip_vpd_preload == 0) {
} except { echo "ERROR: Failed to preload VPD into PNOR." }
}
+if ($hb_mode == 0) {
+ $eccPreload = (lookup-file "%simics%/eecache_prebuilt.bin.ecc")
+ # NOTE must change offset if PNOR layout changes EECACHE offsets
+ echo " - Loading prebuilt EECACHE "+$eccPreload+" at 0x2C000 in PNOR"
+ ($hb_pnor).load-file $eccPreload 0x2C000
+}
+
+# Look for attribute overrides to load
+try {
+ $attr_tmp = (lookup-file "ATTR_TMP")
+ try {
+ @simenv.attr_tmp_addr = hb_get_pnor_offset("ATTR_TMP")
+ } except {
+ $attr_tmp_addr = 0x000B2000
+ }
+ echo " - Loading ATTR_TMP "+$attr_tmp+" at "+$attr_tmp_addr+" in PNOR"
+ ($hb_pnor).load-file $attr_tmp $attr_tmp_addr
+} except { echo "No attribute overrides found." }
+
+# Look for a guard file to load
+try {
+ $guard = (lookup-file "GUARD")
+ try {
+ @simenv.guard_addr = hb_get_pnor_offset("GUARD")
+ } except {
+ $guard_addr = 0x000AC000
+ }
+ echo " - Loading GUARD "+$guard+" at "+$guard_addr+" in PNOR"
+ ($hb_pnor).load-file $guard $guard_addr
+} except { echo "No gard records found." }
# Turn on all processor cec-chips
if ($hb_mode == 1) {
@@ -108,3 +144,51 @@ if ($hb_mode == 1) {
($hb_masterproc_cecchip).invoke parallel_store FSIMBOX 0x01 "80000000" 32
($hb_masterproc_cecchip).invoke parallel_store FSIMBOX 0x08 "00080000" 32
}
+
+###############################
+#Initialize Explorer Registers
+###############################
+if ($hb_mode == 0) { #Only do this on Axone and later models that have Explorer chip
+
+ # IDEC register consumed by Hostboot
+ # UCHIP(0x2134)=0x110600D2
+ # TODO RTC: 215621 Remove workarounds after simics gets updated
+ set-class-attr ocmb mscc_regs_xcbi_chip_info 0x110600D2
+
+ # Loop over all explorer chips
+ foreach $obj in (get-object-list ocmb -all){
+
+ # RAM1 image ID consumed by Hostboot
+ # UCHIP(0x2200)=0x00000000
+ $obj->mscc_regs_xcbi_ram1[0] = 0x00000000
+
+ # RAM1 hash value registers consumed by Hostboot
+ # This matches the hash of zero-filled 4k file.
+ $obj->mscc_regs_xcbi_ram1[1] = 0x2D23913D
+ $obj->mscc_regs_xcbi_ram1[2] = 0x3759EF01
+ $obj->mscc_regs_xcbi_ram1[3] = 0x704A86B4
+ $obj->mscc_regs_xcbi_ram1[4] = 0xBEE3AC8A
+ $obj->mscc_regs_xcbi_ram1[5] = 0x29002313
+ $obj->mscc_regs_xcbi_ram1[6] = 0xECC98A74
+ $obj->mscc_regs_xcbi_ram1[7] = 0x24425A78
+ $obj->mscc_regs_xcbi_ram1[8] = 0x170F2195
+ $obj->mscc_regs_xcbi_ram1[9] = 0x77822FD7
+ $obj->mscc_regs_xcbi_ram1[10] = 0x7E4AE963
+ $obj->mscc_regs_xcbi_ram1[11] = 0x13547696
+ $obj->mscc_regs_xcbi_ram1[12] = 0xAD7D5949
+ $obj->mscc_regs_xcbi_ram1[13] = 0xB58E12D5
+ $obj->mscc_regs_xcbi_ram1[14] = 0x063EF2EE
+ $obj->mscc_regs_xcbi_ram1[15] = 0x063B5957
+ $obj->mscc_regs_xcbi_ram1[16] = 0x40A3A12D
+
+ # Allow for testing MMIO HW failures
+ # Forces write access to TRACE_TRDATA_CONFIG_0 to fail
+ # in src/usr/mmio/test/mmiotest.H
+ # NOTE: address is left shifted 3 and has MMIO
+ # offset (0x100000000) added.
+ $obj->mmio_regs_mmioerr = 0x0000000140082018
+
+ }
+}
+
+
diff --git a/src/build/simics/startup.simics b/src/build/simics/startup.simics
index a6534be01..440e9562b 100755
--- a/src/build/simics/startup.simics
+++ b/src/build/simics/startup.simics
@@ -48,7 +48,8 @@ if ($hb_mode == 1) {
}
}else{
- $hb_machine = "AXONE"
+ # simics now provides us the chip type (starting w/ p9a )
+ $hb_machine = $proc_chip_type
}
python "os.environ['HB_MACHINE'] = \""+$hb_machine+"\""
@@ -98,9 +99,9 @@ if ($hb_mode == 1) {
($cc).seeprom3.seeprom3_image.set 0x3FED9 0x5A5A5A5A 8 -l
}
} else {
- foreach $cc in (get-object-list proc_hb_standalone) {
- ($cc).seeprom1_image.set 0x3FED9 0x5A5A5A5A 8 -l
- ($cc).seeprom3_image.set 0x3FED9 0x5A5A5A5A 8 -l
+ foreach $proc in (get-all-procs) {
+ ($proc.get-seeprom 1).set 0x3FED9 0x5A5A5A5A 8 -l
+ ($proc.get-seeprom 3).set 0x3FED9 0x5A5A5A5A 8 -l
}
}
@@ -112,6 +113,7 @@ try {
run-python-file (lookup-file hbfw/hb-simdebug.py)
} except { echo "ERROR: Failed to load Hostboot debug tools (hb-simdebug.py)" }
+
# Determine security state
$hw_security=(shell "echo $SECURITY_HW_POLICY")
if($hw_security == "") {
@@ -133,13 +135,27 @@ if($hw_security == "1") {
$jumperApplied=FALSE
}
-# Load jumper state to each processor
-foreach $procX in (get-object-list p9_proc) {
-
+if ($hb_machine == "p9a") {
# Set logical jumper state in SIMICS based on HW policy
# "TRUE"=jumper applied(security disabled, default)
# "FALSE"=jumper removed(security enabled)
- (($procX)->secure_jumper=$jumperApplied)
+
+ # Load jumper state to the master processor
+ $hb_masterproc.set-secure-jumper value = $jumperApplied
+
+ # Load jumper state to all slave processors
+ foreach $procS in ($hb_masterproc.get-slave-procs) {
+ $procS.set-secure-jumper value = $jumperApplied
+ }
+} else {
+ # Load jumper state to each processor
+ foreach $procX in (get-object-list p9_proc) {
+
+ # Set logical jumper state in SIMICS based on HW policy
+ # "TRUE"=jumper applied(security disabled, default)
+ # "FALSE"=jumper removed(security enabled)
+ (($procX)->secure_jumper=$jumperApplied)
+ }
}
if ($hb_mode == 0) {
diff --git a/src/build/tools/addCopyright b/src/build/tools/addCopyright
index 81e871010..1a172a49b 100755
--- a/src/build/tools/addCopyright
+++ b/src/build/tools/addCopyright
@@ -96,6 +96,9 @@ use constant LICENSE_PROLOG => "LICENSE_PROLOG";
# When adding a new company add constant here and to %fileContributorsCompany
use constant IBM => 'International Business Machines Corp.';
use constant GOOGLE => 'Google Inc.';
+use constant INSPUR => 'Inspur Power Systems Corp.';
+use constant SUPERMICRO => 'Super Micro Computer, Inc.';
+use constant YADRO => 'YADRO';
# Create mapping for git contrubitors to companies
my %fileContributorsCompany = (
@@ -103,6 +106,9 @@ my %fileContributorsCompany = (
"ozlabs.org" => IBM,
"google.com" => GOOGLE,
"Google Shared Technology" => GOOGLE,
+ "inspur.com" => INSPUR,
+ "supermicro.com" => SUPERMICRO,
+ "yadro.com" => YADRO,
);
#------------------------------------------------------------------------------
diff --git a/src/build/tools/build-cppcheck b/src/build/tools/build-cppcheck
new file mode 100755
index 000000000..8e19ed429
--- /dev/null
+++ b/src/build/tools/build-cppcheck
@@ -0,0 +1,95 @@
+#!/bin/bash -e
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/tools/build-cppcheck $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+source $PROJECT_ROOT/src/build/citest/etc/cppcheck
+
+update_toolconfig(){
+ echo "commit: $CPPCHECK_COMMIT"
+ echo "gcc version: $(gcc -dumpversion)"
+ echo "S: $(uname -o)"
+ echo "arch: $(uname -m)"
+ echo "$(lsb_release -i)"
+ echo "$(lsb_release -r)"
+}
+
+if [ -n "${OPENPOWER_BUILD}" ]; then
+ exit
+fi
+
+cd $PROJECT_ROOT/src/build/tools
+
+if [[ ! -d "cpptools" ]]; then
+ mkdir cpptools
+fi
+
+cd cpptools
+if [[ ! -d "cppcheck" ]]; then
+ # cppcheck folder does not exist, clone repo for the first time
+ git clone git@github.com:danmar/cppcheck.git
+ cd cppcheck
+ git reset --hard $CPPCHECK_COMMIT #update to cppcheck commit
+ update_toolconfig >.cpp_toollevel
+ SHOULDMAKE=1
+else
+ cd cppcheck
+ if ! cmp -s .cpp_toollevel <(update_toolconfig) ; then
+ # cppcheck repo is not at the
+ # level set in $PROJECT_ROOT/src/build/citest/etc/cppcheck
+ if ! git fetch origin; then
+ cd $PROJECT_ROOT/src/build/tools/cpptools
+ rm -rf cppcheck
+ git clone git@github.com:danmar/cppcheck.git
+ cd cppcheck
+ fi
+ git reset --hard $CPPCHECK_COMMIT
+ update_toolconfig >.cpp_toollevel
+
+ SHOULDMAKE=1
+ fi
+ if [[ ! -f "cppcheck" ]]; then
+ SHOULDMAKE=1
+ fi
+fi
+
+if [ "${SHOULDMAKE}" ]; then
+
+ # Check if CXX is set, if it is not then try to find it with CXXPATH
+ # if CXXPATH does not exist, default to host's g++
+ if [ -z "$CXX" ]; then
+ if [ -z "${CXXPATH}" ]; then
+ export CXX=g++
+ else
+ export CXX=${CXXPATH}/g++
+ fi
+ fi
+
+ make
+
+fi
+
+cd $PROJECT_ROOT
+
+
diff --git a/src/build/tools/cflags.sh b/src/build/tools/cflags.sh
new file mode 100755
index 000000000..0ca39f374
--- /dev/null
+++ b/src/build/tools/cflags.sh
@@ -0,0 +1,68 @@
+#!/bin/bash
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/tools/cflags.sh $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+# The purpose of this script is to convert a series of GCC compiler
+# flags into an equivalent series of flags, but which use absolute
+# paths for include directories (i.e. the "-I" flag) instead of
+# relative paths. We have to do this when GCOV is in use, because it
+# stupidly puts data files in one path but stores paths inside the
+# data files that are relative to some other path. When GCOV then
+# tries to read the source files via these relative paths, it can't
+# find the files. We correct this by converting all paths to source
+# and header files to absolute paths.
+
+if [ ! "$HOSTBOOT_PROFILE" ] ; then
+ echo "$@"
+ exit
+fi
+
+make_path_abs () {
+ local ABSPATH
+ ABSPATH=$(readlink -f "$1")
+
+ if [ $? -ne 0 ] ; then
+ ABSPATH="$1"
+ fi
+
+ echo -n "$ABSPATH"
+}
+
+while [ "$#" -gt 0 ] ; do
+ FLAG="$1"
+
+ if [ "$FLAG" = "-I" ] ; then
+ shift
+ echo -n "-I $(make_path_abs "$1") "
+ elif [ "${FLAG:0:2}" = "-I" ] ; then
+ echo -n "-I $(make_path_abs "${FLAG:2}") "
+ else
+ echo -n "$FLAG "
+ fi
+
+ shift
+done
+
+echo
diff --git a/src/build/tools/eecache_editor.pl b/src/build/tools/eecache_editor.pl
new file mode 100755
index 000000000..262f56376
--- /dev/null
+++ b/src/build/tools/eecache_editor.pl
@@ -0,0 +1,802 @@
+#!/usr/local/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/tools/eecache_editor.pl $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+use strict;
+use Getopt::Long;
+use File::Copy;
+
+
+binmode STDOUT, ':bytes';
+
+my $pnorBinaryPath = "";
+my $eecacheBinaryPath = "";
+my $newImagePath = "";
+my $outFilePath = "./eecache_editor_output.dat";
+my $masterHuid = 0;
+my $port = 0;
+my $engine = 0;
+my $devAddr = 0;
+my $muxHuid = 0;
+my $muxSelect = 0xFF;
+my $eepromSize = 0;
+my $usage = 0;
+my $uniqueId = "";
+my $verbose = 0;
+my $onlyValid = 0;
+my $clearEepromData = 0;
+my $overwrite = 0;
+my $summary = 0;
+my $devOffset = 0xFFFF; # initialized to invalid offset
+
+# Goals of this tool:
+#
+# ** Handle both entire PNOR image as well as single EECACHE section as input **
+#
+# 1) Given masterHuid, port, engine, devAddr, muxSelect lookup cached EEPROM value and replace
+# it with a given binary file. (File size must be <= allocated space)
+#
+# 2) Given a binary pnor/eecache. Print summary of cached eeproms
+#
+# 3) Zero out a given cached eeprom
+#
+# 4) Extract the contents for a given masterHuid, port, engine, devAddr, muxSelect
+
+use constant VERSION_1_TOC_ENTRY_SIZE_BYTES => 17;
+use constant VERSION_1_TOC_ENTRY_SIZE_BITS => (VERSION_1_TOC_ENTRY_SIZE_BYTES * 8) ;
+use constant VERSION_1_NUM_ENTRIES => 50;
+use constant VERSION_1_TOC_SIZE => (VERSION_1_TOC_ENTRY_SIZE_BYTES * VERSION_1_NUM_ENTRIES) + 5;
+
+use constant VERSION_2_TOC_ENTRY_SIZE_BYTES => 18;
+use constant VERSION_2_TOC_ENTRY_SIZE_BITS => (VERSION_2_TOC_ENTRY_SIZE_BYTES * 8) ;
+use constant VERSION_2_NUM_ENTRIES => 50;
+use constant VERSION_2_TOC_SIZE => (VERSION_2_TOC_ENTRY_SIZE_BYTES * VERSION_2_NUM_ENTRIES) + 5;
+
+use constant VERSION_LATEST => 2;
+
+use constant EEPROM_ACCESS_I2C => 1;
+use constant EEPROM_ACCESS_SPI => 2;
+
+
+
+my $eecacheVersion = VERSION_LATEST;
+
+GetOptions("pnor:s" => \$pnorBinaryPath,
+ "eecache:s" => \$eecacheBinaryPath,
+ "newImage:s" => \$newImagePath,
+ "newFile:s" => \$newImagePath,
+ "out:s" => \$outFilePath,
+ "of:s" => \$outFilePath,
+ "masterHuid:o" => \$masterHuid,
+ "port:o" => \$port,
+ "engine:o" => \$engine,
+ "devAddr:o" => \$devAddr,
+ "muxSelect:o" => \$muxSelect,
+ "eepromSize:o" => \$eepromSize,
+ "uniqueId:s" => \$uniqueId,
+ "devOffset:o" => \$devOffset,
+ "version:o" => \$eecacheVersion,
+ "onlyValid" => \$onlyValid,
+ "overwrite" => \$overwrite,
+ "clear" => \$clearEepromData,
+ "verbose" => \$verbose,
+ "usage" => \$usage,
+ "help" => \$usage,
+ "h" => \$usage);
+
+sub print_help()
+{
+ print "--------- EECACHE Editor Tool V 2.0 ---------\n";
+ print "\n";
+ print "Mandatory:\n\n";
+
+ print " --eecache Path to ECC-less eeprom cache section of PNOR (IE : EECACHE.bin )\n\n";
+
+ print "Optional:\n\n";
+
+ print " --clear If a matching eeprom is found, clear out its contents\n";
+ print " --devAddr Device address of desired EEPROM\n";
+ print " --devOffset Offset (KB) of where record begins in eeprom for SPI access\n";
+ print " --engine Engine of I2C/SPI Master desired EEPROM exists on\n";
+ print " --masterHuid HUID of the I2C/SPI Master Target\n";
+ print " --muxSelect Mux Select (if needed) defaults to 0xFF \n";
+ print " --onlyValid If printing summary, only print valid eeprom caches\n";
+ print " --out Full path to desired out file, if not provided defaults to ./eecache_editor_output.dat\n";
+ print " --port Port of I2C Master desired EEPROM exists on\n";
+ print " --uniqueId Combination of unique I2C Slave information, alternative to passing\n";
+ print " information in 1 thing at a time\n";
+ print " --version Version of eecache (default to latest if this isn't provided)\n";
+ print " --verbose Print extra information \n";
+ print " --help Print this information \n";
+ print "\n ";
+ print "Examples: \n\n";
+ print " # prints out info about all eeproms in EECACHE.bin\n";
+ print " eecache_editor.pl --eecache EECACHE.bin\n";
+ print "\n";
+ print " # (I2C) lookup eeprom matching input params and write contents of that EEPROM's cached data to outfile \n";
+ print " eecache_editor.pl --eecache EECACHE.bin --version 1 --port 0 --engine 3 --muxSelect 8 --devAddr 0xa0 --masterHuid 0x50000\n";
+ print "\n";
+ print " # (I2C) lookup eeprom matching input params and clear the contents ( manipulate input binary )\n";
+ print " eecache_editor.pl --eecache EECACHE.bin --port 0 --engine 3 --muxSelect 8 --devAddr 0xa0 --masterHuid 0x50000 --clear\n";
+ print "\n";
+ print " # (I2C) lookup eeprom matching input params and write new image's contents to offset in EECACHE where matching eeprom data exists ( manipulate input binary )\n";
+ print " eecache_editor.pl --eecache EECACHE.bin --port 0 --engine 3 --muxSelect 8 --devAddr 0xa0 --masterHuid 0x50000 --newImage newSPD.dat\n";
+ print "\n";
+ print " # (SPI) lookup eeprom matching input params and write contents of that EEPROM's cached data to outfile \n";
+ print " eecache_editor.pl --eecache EECACHE.bin --engine 3 --devOffset 0xc0 --masterHuid 0x50000\n";
+ print "\n";
+ print " # (SPI) lookup eeprom matching input params and clear the contents ( manipulate input binary )\n";
+ print " eecache_editor.pl --eecache EECACHE.bin --engine 3 --devOffset 0xc0 --masterHuid 0x50000 --clear\n";
+ print "\n";
+ print " # (SPI) lookup eeprom matching input params and write new image's contents to offset in EECACHE where matching eeprom data exists ( manipulate input binary )\n";
+ print " eecache_editor.pl --eecache EECACHE.bin --engine 3 --devOffset 0xc0 --masterHuid 0x50000 --newImage newSPD.dat\n";
+ print "---------------------------------------------\n";
+}
+
+if( $usage )
+{
+ print_help();
+ exit 0;
+}
+
+if( ($pnorBinaryPath eq "") &&
+ ($eecacheBinaryPath eq ""))
+{
+ # Print error saying we need one of these filled in
+ print "ERROR Neither PNOR binary nor EECACHE section binary passed in. Cannot continue.\n\n";
+ print_help();
+ exit 0;
+}
+
+# if PNOR is not empty, ignore eecacheBinary , we will
+# output a full updated pnor since we were provided a pnor.
+# but if no pnor is provided , we will just return and EECACHE sections
+my $inputIsEntirePnor = 0;
+if( $pnorBinaryPath ne "")
+{
+ $inputIsEntirePnor = 1;
+}
+
+if($newImagePath ne "")
+{
+ $overwrite = 1;
+}
+
+if ($eecacheVersion > VERSION_LATEST)
+{
+ print "ERROR: --version $eecacheVersion is greater than max ".VERSION_LATEST."\n\n";
+ print_help();
+ exit 0;
+}
+
+if ($uniqueId eq "")
+{
+ if ($eecacheVersion == VERSION_LATEST)
+ {
+ # devOffset is specific to SPI access so check to see if it is valid
+ if ($devOffset != 0xFFFF)
+ {
+ $uniqueId = sprintf ("%.02X", EEPROM_ACCESS_SPI);
+ $uniqueId .= sprintf ("%.08X", $masterHuid);
+ $uniqueId .= sprintf ("%.02X", $engine);
+ $uniqueId .= sprintf ("%.04X", $devOffset);
+ $uniqueId .= "00"; # blank byte
+ }
+ else
+ {
+ $uniqueId = sprintf ("%.02X", EEPROM_ACCESS_I2C);
+ $uniqueId .= sprintf ("%.08X", $masterHuid);
+ $uniqueId .= sprintf ("%.02X", $port);
+ $uniqueId .= sprintf ("%.02X", $engine);
+ $uniqueId .= sprintf ("%.02X", $devAddr);
+ $uniqueId .= sprintf ("%.02X", $muxSelect);
+ }
+ }
+ elsif ($eecacheVersion == 1)
+ {
+ $uniqueId .= sprintf ("%.08X", $masterHuid);
+ $uniqueId .= sprintf ("%.02X", $port);
+ $uniqueId .= sprintf ("%.02X", $engine);
+ $uniqueId .= sprintf ("%.02X", $devAddr);
+ $uniqueId .= sprintf ("%.02X", $muxSelect);
+ }
+}
+
+my $displayOnly = 0;
+
+unless (isUniqueIdValid($uniqueId))
+{
+ if( $clearEepromData )
+ {
+ print_help();
+ print "\n ERROR: Detecting that user is trying to --clear data without providing what info on what eeprom to clear. Exiting. \n\n";
+ exit 0;
+ }
+ $displayOnly = 1;
+ $verbose = 1;
+}
+else
+{
+ print "\nUnique ID we are looking up: 0x$uniqueId \n\n" ;
+}
+
+# setup input and output files
+my $input_fh;
+my $output_fh;
+
+my $new_fh;
+
+if($inputIsEntirePnor)
+{
+ open $input_fh, '<', $pnorBinaryPath or die "failed to open $pnorBinaryPath: $!\n";
+ if($overwrite)
+ {
+ open $output_fh, '>', $pnorBinaryPath or die "failed to open $pnorBinaryPath: $!\n";
+ }
+ else
+ {
+ open $output_fh, '>', $outFilePath or die "failed to open $outFilePath: $!\n";
+ }
+}
+else
+{
+ open $input_fh, '+<:raw', $eecacheBinaryPath or die "failed to open $eecacheBinaryPath: $!\n";
+ if($overwrite)
+ {
+ $output_fh = $input_fh;
+ }
+ else
+ {
+ open $output_fh, '+>:raw', $outFilePath or die "failed to open $outFilePath: $!\n";
+ copy($eecacheBinaryPath, $outFilePath) ;
+ }
+}
+
+if($newImagePath ne "")
+{
+ open $new_fh, '<', $newImagePath or die "failed to open $newImagePath: $!\n";
+}
+
+
+
+# at this point we should know what we are trying to accomplish :
+#
+# IF ($displayOnly != 0) THEN we will only print a summary
+#
+# ELSE IF ($newImagePath != "") THEN we will write new contents if matching section found
+#
+# ELSE IF ($clear != 0) THEN clear the contents if matching section found
+#
+# ELSE if matching section found, then write contents to outfile
+
+
+
+# TODO handle entire PNOR
+if($inputIsEntirePnor)
+{
+ #find EECACHE offset , seek to there
+}
+else
+{
+ # Parse the larger binary blob to get just the Table of Contents
+ my $eecacheTOC = readEecacheToc($input_fh);
+
+ # The hashRef you key back has members: offset and size
+ # This represents offset and size of eeprom data in given
+ # binary.
+ my $hashRef = parseEecacheToc($eecacheTOC, $uniqueId);
+
+ # if we are doing displayOnly then we are done, we can skip the following logic
+ if(!$displayOnly)
+ {
+ # If the offset is 0, then no match was found
+ if($hashRef->{'entry_offset'} != 0)
+ {
+ if($newImagePath ne "") # if a new image is available try to load it in
+ {
+ my $new_file_size = -s $newImagePath ;
+ my $new_file_data;
+ read($new_fh, $new_file_data, $new_file_size );
+
+ # Verify the new image is the correct size
+ if( $new_file_size != $hashRef->{'entry_size'})
+ {
+ print "ERROR incorrect size, EECACHE is reporting size to be".$hashRef->{'entry_size'}."bytes but file proved is only".$new_file_size." bytes\n";
+ exit 0;
+ }
+
+ # seek to the offset inside EEACHE where this eeprom's cache lives
+ # and write the new file contents
+ seek($output_fh, $hashRef->{'entry_offset'} , 0);
+ print $output_fh $new_file_data;
+ }
+ elsif($clearEepromData) # if we are told to clear the data do that
+ {
+ print "Attempting Clearing starting at $hashRef->{'entry_offset'} $hashRef->{'header_offset'}!!!!!!!!\n";
+ my $byteOfOnes = pack("H2", "FF") ;
+ my $byteOfZeroes = pack("H2", "00") ;
+ seek($output_fh, $hashRef->{'entry_offset'} , 0);
+ for(my $i = 0; $i < $hashRef->{'entry_size'}; $i++)
+ {
+ print $output_fh $byteOfOnes;
+ }
+
+ # seek($output_fh, $hashRef->{'header_offset'} + 16, 0);
+ # print $output_fh $byteOfZeroes;
+ }
+ else
+ {
+ seek($input_fh, $hashRef->{'entry_offset'} , 0);
+ my $cur_pos = tell $input_fh;
+ print "reading $hashRef->{'entry_size'} from $cur_pos\n ";
+ my $cachedData;
+ read($input_fh, $cachedData, $hashRef->{'entry_size'});
+ print $output_fh $cachedData;
+ }
+ }
+ }
+}
+
+close $input_fh;
+close $output_fh;
+
+# End of Main
+exit 0;
+
+
+# Start Subroutines
+
+sub readEecacheToc {
+ my $eecache_fh = shift;
+
+ my $start_location = tell $eecache_fh;
+
+ my $eecache_toc_version = 0;
+
+ read($eecache_fh, $eecache_toc_version, 1) == 1 or die "failed to read single byte from eecache file handle";
+ $eecache_toc_version = unpack 'C', $eecache_toc_version;
+
+ my $eecache_toc;
+
+ if( $eecache_toc_version == 1 )
+ {
+ seek($eecache_fh, $start_location, 0);
+ read($eecache_fh, $eecache_toc, VERSION_1_TOC_SIZE) or die "failed to read ".VERSION_1_TOC_SIZE." bytes from eecache file handle"; ;
+ }
+ elsif ( $eecache_toc_version == 2)
+ {
+ seek($eecache_fh, $start_location, 0);
+ read($eecache_fh, $eecache_toc, VERSION_2_TOC_SIZE) or die "failed to read ".VERSION_2_TOC_SIZE." bytes from eecache file handle"; ;
+ }
+ else
+ {
+ die "Failed to find valid TOC, version found = $eecache_toc_version. Latest version this tool supports is ".VERSION_LATEST;
+ }
+
+ return $eecache_toc;
+}
+
+# Brief : Takes in binary blob representing EECACHE table of contents, as well as
+# a uniqueID to match against, returns hash that contains size and offset of
+# cached eeprom data inside EEACHE section
+#
+# If verbose is set,
+
+sub parseEecacheToc {
+ my $eecacheTOC = shift;
+ my $idToMatch = shift;
+
+ # figure out what version of EECACHE header exists
+ my $headerVersion = 0;
+ my $tocEntrySizeBytes = 0;
+ my $tocEntries = 0;
+
+ my ($version) = unpack('H2', "$eecacheTOC");
+ if ($version == 0x01)
+ {
+ $headerVersion = 1;
+ $tocEntrySizeBytes = VERSION_1_TOC_ENTRY_SIZE_BYTES;
+ $tocEntries = VERSION_1_NUM_ENTRIES;
+ }
+ elsif ($version == 0x02)
+ {
+ $headerVersion = 2;
+ $tocEntrySizeBytes = VERSION_2_TOC_ENTRY_SIZE_BYTES;
+ $tocEntries = VERSION_2_NUM_ENTRIES;
+ }
+ else
+ {
+ die "Unsupported PNOR EECACHE level $version";
+ }
+
+ # verify uniqueId was built against same version as PNOR's EECACHE
+ if (isUniqueIdValid($uniqueId))
+ {
+ unless (($headerVersion == $eecacheVersion))
+ {
+ die "PNOR EECACHE version $headerVersion is not same as expected EECACHE version $eecacheVersion!" .
+ "Maybe changed expected with --version option";
+ }
+ }
+
+ # header entries start after on 6th byte
+ my $headerEntryOffset = 5;
+
+ # this will end up being the return value
+ my %entryInfo;
+ $entryInfo{entry_offset} = 0;
+ $entryInfo{entry_size} = 0;
+ $entryInfo{header_offset} = 0;
+
+ my $totalEntryCount = 0;
+ my $validEntryCount = 0;
+
+ my $matchSummaryString = "";
+
+ # Some common variables between header versions
+ my $internal_offset = 0xFFFF;
+ my $cached_copy_valid = 0;
+ my $cached_copy_size = 0;
+ my $entry_size = 0;
+ my $entry_offset = 0;
+ my $bitFieldByte = 0; # last byte of header
+ my $entryUniqueID = "FFFFFFFFFFFFFFFF";
+
+ use Class::Struct;
+
+ struct I2C_Entry_t => {
+ i2c_master_huid => '$',
+ port => '$',
+ engine => '$',
+ devAddr => '$',
+ mux_select => '$',
+ };
+
+ struct SPI_Entry_t => {
+ spi_master_huid => '$',
+ engine => '$',
+ offset_KB => '$',
+ };
+
+ for(my $i = 0; $i < $tocEntries; $i++)
+ {
+ my $eepromAccess = EEPROM_ACCESS_I2C;
+ my $master_eeprom = 0xFF; # default to invalid master eeprom
+
+ my $entry = substr $eecacheTOC, $headerEntryOffset, $tocEntrySizeBytes;
+
+ # update offset right away so we dont forget
+ $headerEntryOffset += $tocEntrySizeBytes;
+ my $entry_data;
+
+ if ($headerVersion == 1)
+ {
+ ###### VERSION 1 ########
+ # struct completeRecord
+ # {
+ # uint32_t i2c_master_huid; // HUID of i2c Master
+ # uint8_t port; // I2C Port
+ # uint8_t engine; // I2C Engine
+ # uint8_t devAddr; // I2C Device Address
+ # uint8_t mux_select; // Some I2C devices are behind a mux, this says
+ # // what setting on the mux is required
+ # uint32_t cache_copy_size; // Size of data saved in cache (in KB)
+ # uint32_t internal_offset; // offset from start of EECACHE section where cached
+ # // data exists
+ # uint8_t cached_copy_valid : 1, // This bit is set when we think the contents of the
+ # // cache is valid.
+ # unused : 7;
+ #
+ # } PACKED completeRecord;
+ #
+ # struct uniqueRecord
+ # {
+ # uint8_t uniqueID [NUM_BYTE_UNIQUE_ID];
+ # uint8_t metaData [sizeof(completeRecord) - NUM_BYTE_UNIQUE_ID];
+ # } PACKED uniqueRecord;
+
+ # unpack according to src/include/usr/i2c/eeprom_const.H ( pasted above)
+ my @entryFields = unpack('H8 H2 H2 H2 H2 H8 H8 H2', "$entry");
+
+ $entryUniqueID = "@entryFields[0]@entryFields[1]@entryFields[2]@entryFields[3]@entryFields[4]";
+ $eepromAccess = EEPROM_ACCESS_I2C;
+ $entry_data = I2C_Entry_t->new();
+ $entry_data->i2c_master_huid( @entryFields[0] );
+ $entry_data->port ( @entryFields[1] );
+ $entry_data->engine ( @entryFields[2] );
+ $entry_data->devAddr ( @entryFields[3] );
+ $entry_data->mux_select ( @entryFields[4] );
+ $bitFieldByte = @entryFields[7];
+ $cached_copy_valid = (hex( "0x".@entryFields[7]) & 0x80) >> 7;
+
+
+ # if the entry ID is FFFFFFFFFFFFFFFF this indicates
+ # that the entry is not filled out
+ if($entryUniqueID == "FFFFFFFFFFFFFFFF")
+ {
+ next;
+ }
+ $cached_copy_size = @entryFields[5];
+ $internal_offset = @entryFields[6];
+ }
+ elsif ($headerVersion == 2)
+ {
+ ###### VERSION 2 ########
+ # struct completeRecord
+ # {
+ # EepromAccessMethodType accessType; // how to access record
+ # union eepromAccess_t
+ # {
+ # struct i2cAccess_t
+ # {
+ # uint32_t i2c_master_huid; // HUID of i2c Master
+ # uint8_t port; // I2C Port
+ # uint8_t engine; // I2C Engine
+ # uint8_t devAddr; // I2C Device Address
+ # uint8_t mux_select; // Some I2C devices are behind a mux, this says
+ # // what setting on the mux is required
+ # } PACKED i2cAccess;
+ # struct spiAccess_t
+ # {
+ # uint32_t spi_master_huid; // HUID of SPI master
+ # uint8_t engine; // engine specific to eeprom
+ # uint16_t offset_KB; // offset in KB of where record begins in eeprom
+ # } PACKED spiAccess;
+ # } PACKED eepromAccess;
+ # uint32_t cache_copy_size; // Size of data saved in cache (in KB)
+ # uint32_t internal_offset; // offset from start of EECACHE section where cached
+ # // data exists
+ # uint8_t cached_copy_valid : 1, // This bit is set when we think the contents of the
+ # // cache is valid.
+ # master_eeprom : 1, // This bit marks this record as the master one (i.e. look at this one for change)
+ # unused : 6;
+ #
+ # } PACKED completeRecord;
+ #
+ # struct uniqueRecord
+ # {
+ # uint8_t uniqueID [NUM_BYTE_UNIQUE_ID];
+ # uint8_t metaData [sizeof(completeRecord) - NUM_BYTE_UNIQUE_ID];
+ # } PACKED uniqueRecord;
+
+ ($eepromAccess) = unpack('H2', "$entry");
+ if ($eepromAccess == EEPROM_ACCESS_I2C)
+ {
+ # unpack according to src/include/usr/i2c/eeprom_const.H ( pasted above)
+ my @entryFields = unpack('H2 H8 H2 H2 H2 H2 H8 H8 H2', "$entry");
+
+ $entryUniqueID = "@entryFields[0]@entryFields[1]@entryFields[2]@entryFields[3]@entryFields[4]@entryFields[5]";
+
+ $entry_data = I2C_Entry_t->new();
+ $entry_data->i2c_master_huid( @entryFields[1] );
+ $entry_data->port( @entryFields[2] );
+ $entry_data->engine( @entryFields[3] );
+ $entry_data->devAddr( @entryFields[4] );
+ $entry_data->mux_select( @entryFields[5] );
+
+ $cached_copy_size = @entryFields[6];
+ $internal_offset = @entryFields[7];
+
+ $bitFieldByte = @entryFields[8];
+ $cached_copy_valid = (hex("0x".@entryFields[8]) & 0x80) >> 7;
+ $master_eeprom = (hex("0x".@entryFields[8]) & 0x40) >> 6;
+ }
+ elsif ($eepromAccess == EEPROM_ACCESS_SPI)
+ {
+ # unpack according to src/include/usr/i2c/eeprom_const.H ( pasted above)
+ my @entryFields = unpack('H2 H8 H2 H4 H2 H8 H8 H2', "$entry");
+
+ $entryUniqueID = "@entryFields[0]@entryFields[1]@entryFields[2]@entryFields[3]00";
+
+ $entry_data = SPI_Entry_t->new();
+ $entry_data->spi_master_huid( @entryFields[1] );
+ $entry_data->engine( @entryFields[2] );
+ $entry_data->offset_KB( @entryFields[3] );
+
+ # @entryField[4] is just filler
+
+ $cached_copy_size = @entryFields[5];
+ $internal_offset = @entryFields[6];
+
+ $bitFieldByte = @entryFields[7];
+ $cached_copy_valid = (hex("0x".@entryFields[7]) & 0x80) >> 7;
+ $master_eeprom = (hex("0x".@entryFields[7]) & 0x40) >> 6;
+ }
+ else
+ {
+ # entry is not filled out if eepromAccess is not I2C or SPI
+ next;
+ }
+ }
+
+ $totalEntryCount++;
+
+ if(uc $entryUniqueID eq uc $idToMatch)
+ {
+ $entryInfo{entry_offset} = $internal_offset;
+ $entryInfo{entry_size} = $cached_copy_size * 1024; # KB to Bytes
+ $entryInfo{header_offset} = $headerEntryOffset - $tocEntrySizeBytes;
+
+ $matchSummaryString = "ENTRY FOUND ...\n";
+ if ($eepromAccess == EEPROM_ACCESS_I2C)
+ {
+ if ($headerVersion >= 2)
+ {
+ $matchSummaryString .=
+ "accessType = 0x".$eepromAccess." I2C ACCESS\n";
+ }
+ $matchSummaryString .=
+ "Master I2C Huid = 0x". $entry_data->i2c_master_huid ."\n".
+ "Port = 0x". $entry_data->port ."\n".
+ "Engine = 0x". $entry_data->engine ."\n".
+ "Device Address = 0x". $entry_data->devAddr ."\n".
+ "Mux Select = 0x". $entry_data->mux_select ."\n".
+ "Size of Cached Copy (KB) = 0x$cached_copy_size\n".
+ "Offset within EECACHE = 0x$internal_offset\n".
+ "Cached copy valid ? = 0x$cached_copy_valid (1st bit of 0x$bitFieldByte)\n";
+ }
+ else # EEPROM_ACCESS_SPI
+ {
+ if ($headerVersion >= 2)
+ {
+ $matchSummaryString .=
+ "accessType = 0x".$eepromAccess." SPI ACCESS\n";
+ }
+ $matchSummaryString .=
+ "Master SPI Huid = 0x". $entry_data->spi_master_huid ."\n".
+ "Engine = 0x". $entry_data->engine ."\n".
+ "Offset in EEPROM = 0x". $entry_data->offset_KB ."\n".
+ "Size of Cached Copy (KB) = 0x$cached_copy_size\n".
+ "Offset within EECACHE = 0x$internal_offset\n".
+ "Cached copy valid ? = $cached_copy_valid (1st bit of 0x$bitFieldByte)\n";
+ }
+ if ($master_eeprom != 0xFF)
+ {
+ $matchSummaryString .=
+ "EEPROM master ? = $master_eeprom (2nd bit of 0x$bitFieldByte)\n";
+ }
+ $matchSummaryString .=
+ "unique ID = 0x$entryUniqueID \n\n";
+
+ if(!$verbose)
+ {
+ last;
+ }
+ }
+
+ if( !$cached_copy_valid )
+ {
+ # skip if this entry is not valid and told to just
+ # print valid only entries
+ if($onlyValid)
+ {
+ next;
+ }
+ }
+ else
+ {
+ $validEntryCount++;
+ }
+
+ my $entryString = "";
+ if ($eepromAccess == EEPROM_ACCESS_I2C)
+ {
+ if ($headerVersion >= 2)
+ {
+ $entryString .=
+ "accessType = 0x".$eepromAccess." I2C ACCESS\n";
+ }
+ $entryString .=
+ "Master I2C Huid = 0x". $entry_data->i2c_master_huid ."\n".
+ "Port = 0x". $entry_data->port ."\n".
+ "Engine = 0x". $entry_data->engine ."\n".
+ "Device Address = 0x". $entry_data->devAddr ."\n".
+ "Mux Select = 0x". $entry_data->mux_select ."\n".
+ "Size of Cached Copy (KB) = 0x$cached_copy_size\n".
+ "Offset within EECACHE = 0x$internal_offset\n".
+ "Cached copy valid ? = $cached_copy_valid (1st bit of 0x$bitFieldByte)\n";
+ }
+ else
+ {
+ if ($headerVersion >= 2)
+ {
+ $entryString .=
+ "accessType = 0x".$eepromAccess." SPI ACCESS\n";
+ }
+ $entryString .=
+ "Master SPI Huid = 0x". $entry_data->spi_master_huid ."\n".
+ "Engine = 0x". $entry_data->engine ."\n".
+ "Offset in EEPROM = 0x". $entry_data->offset_KB ."\n".
+ "Size of Cached Copy (KB) = 0x$cached_copy_size\n".
+ "Offset within EECACHE = 0x$internal_offset\n".
+ "Cached copy valid ? = $cached_copy_valid (1st bit of 0x$bitFieldByte)\n";
+ }
+
+ if ($master_eeprom != 0xFF)
+ {
+ $entryString .=
+ "EEPROM master ? = $master_eeprom (2nd bit of 0x$bitFieldByte)\n";
+ }
+ $entryString .=
+ "unique ID = 0x$entryUniqueID \n\n";
+
+ printVerbose($entryString);
+ }
+
+ printVerbose(
+ "Summary :\n".
+ " Total Entry Count : $totalEntryCount \n".
+ " Valid Entry Count : $validEntryCount \n".
+ " Max Possible Entries : $tocEntries\n\n");
+
+ if($matchSummaryString ne "")
+ {
+ print $matchSummaryString;
+ }
+ else
+ {
+ # Skip failure message if not looking for a unique id match
+ if (isUniqueIdValid($uniqueId))
+ {
+ print "No Match Found! \n\n";
+ }
+ }
+
+ return \%entryInfo;
+}
+
+
+sub findEepromRecordOffset {
+
+
+
+}
+
+sub printVerbose {
+
+ my $string = shift;
+
+ if($verbose)
+ {
+ print $string;
+ }
+}
+
+sub isUniqueIdValid
+{
+ my ($uniqueId) = @_;
+
+ if( (($eecacheVersion == 1) && ($uniqueId == "00000000000000FF")) ||
+ (($eecacheVersion == 2) && ($uniqueId == "0100000000000000FF")) ||
+ (($eecacheVersion == 2) && ($uniqueId == "020000000000000000")) )
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
diff --git a/src/build/tools/hb b/src/build/tools/hb
index 9576adb0f..9e7e38a48 100755
--- a/src/build/tools/hb
+++ b/src/build/tools/hb
@@ -39,6 +39,7 @@ execute_in_sandbox()
echo $1 > ${SANDBOXBASE}/src/sandbox_execute_cmd
chmod 700 ${SANDBOXBASE}/src/sandbox_execute_cmd
+ echo "Sandbox :: $1"
${WORKON_CMD} -c ./sandbox_execute_cmd
@@ -356,14 +357,16 @@ hb_simsetup()
DRIVER=`cat ${PROJECT_ROOT}/src/build/citest/etc/bbuild`
SIMICS_LEVEL=`cat ${PROJECT_ROOT}/src/build/citest/etc/simbuild`
+ EECACHE_PREBUILT=`cat ${PROJECT_ROOT}/src/build/citest/etc/eecache_prebuilt`
needs_machine_variable
if [ "${MACHINE}" == "AXONE" ]; then
- echo "mkdir -p ${SANDBOXBASE}/simics"
execute_in_sandbox "mkdir -p ${SANDBOXBASE}/simics" "ppc"
- echo "tar ${SIMICS_LEVEL} -C ${SANDBOXBASE}/simics/"
execute_in_sandbox "tar -xf ${SIMICS_LEVEL} -C ${SANDBOXBASE}/simics/" "ppc"
+ echo "cd ${SANDBOXBASE}/simics/ && ./INSTALL.sh"
execute_in_sandbox "cd ${SANDBOXBASE}/simics/ && ./INSTALL.sh" "ppc"
+ echo "cp ${EECACHE_PREBUILT} ${SANDBOXBASE}/simics/eecache_prebuilt.bin.ecc"
+ execute_in_sandbox "cp ${EECACHE_PREBUILT} ${SANDBOXBASE}/simics/eecache_prebuilt.bin.ecc" "ppc"
else
execute_in_sandbox "start_simics -no_start -machine ${MACHINE}" "ppc"
fi
@@ -424,8 +427,19 @@ hb_startsimics()
#export MYDIR=$bb/obj/ppc/hbfw/simics/startup.simics
#then /runsim -m axone -o hb_script_to_run=$MYDIR
export MY_DIR="${SANDBOXBASE}/obj/ppc/simu/scripts/hbfw"
- echo "cd ${SANDBOXBASE}/simics/ && ./runsim -m ${MACHINE} hb_script_to_run=${MY_DIR}/startup.simics pnor_img=${MY_DIR}/../../../hbfw/img/axone.pnor sbe_seeprom_img=${SANDBOXBASE}/images/ppc/lab/flash/sbe_seeprom_p9a_10.bin.ecc num_procs=1 vpd_proc=vpd/images/99a8c3fe4e5c74798f5bd4212f3d9a2a"
- execute_in_sandbox "cd ${SANDBOXBASE}/simics/ && ./runsim -m ${MACHINE} hb_script_to_run=${MY_DIR}/startup.simics pnor_img=${MY_DIR}/../../../hbfw/img/axone.pnor sbe_seeprom_img=${SANDBOXBASE}/images/ppc/lab/flash/sbe_seeprom_p9a_10.bin.ecc num_procs=1 vpd_proc=vpd/images/99a8c3fe4e5c74798f5bd4212f3d9a2a" "ppc"
+ # If '-nre' was passed in as a flag, then do not vexec
+ # also, if $POOL is defined, this indicates are already in
+ # a vexec shell so do not vexec
+ if [ "$*" = "-nre" ] || [ ! -z ${POOL} ]; then
+ VEXEC_STR=" vexec"
+ else
+ VEXEC_STR=""
+ fi
+ export RUNSIMCMD="cd ${SANDBOXBASE}/simics/ &&${VEXEC_STR} ./runsim -m ${MACHINE} hb_script_to_run=${MY_DIR}/startup.simics pnor_img=${MY_DIR}/../../../hbfw/img/axone.pnor sbe_seeprom_img=${SANDBOXBASE}/images/ppc/lab/flash/sbe_seeprom_p9a_10.bin.ecc num_procs=2 enable_lpc_console=TRUE hb_pnor_dir=${MY_DIR}/../../../hbfw/img/"
+ echo "**********"
+ echo $RUNSIMCMD
+ echo "**********"
+ execute_in_sandbox "${RUNSIMCMD} ${SIMICSOPTIONS}" "ppc"
else
execute_in_sandbox \
"start_simics -machine ${MACHINE} ${SIMICSOPTIONS} $*" "ppc"
diff --git a/src/build/tools/listdeps.pl b/src/build/tools/listdeps.pl
index 9bad71ef9..2eaf7a6ad 100755
--- a/src/build/tools/listdeps.pl
+++ b/src/build/tools/listdeps.pl
@@ -229,6 +229,7 @@ my $resident_modules = {
"libexpaccess.so" => '1',
"libnvdimm.so" => '1',
"libmmio.so" => '1',
+ "libsmf.so" => '1',
};
# A list of the dependent libraries in each istep.
diff --git a/src/build/tools/pre-commit b/src/build/tools/pre-commit
index 3dc621bb3..ccf02b80a 100755
--- a/src/build/tools/pre-commit
+++ b/src/build/tools/pre-commit
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
@@ -6,7 +6,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2011,2017
+# Contributors Listed Below - COPYRIGHT 2011,2019
# [+] International Business Machines Corp.
#
#
@@ -35,3 +35,48 @@ else
echo "For more info run './hb --help'"
exit -1
fi
+
+# Run cppcheck if variable is set, if not exit here
+if [[ $DOCPPCHECK -ne 1 ]]; then
+ exit 0
+fi
+
+echo "Running CPPCHECK"
+
+if git rev-parse --verify HEAD >/dev/null 2>&1
+then
+ against=HEAD
+else
+ # This is the hash of the default empty tree in Git.
+ # If for some reason HEAD is not set, then diff'ing against this is like
+ # diff'ing against the very first commit.
+ against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
+${TOOLSDIR}/build-cppcheck
+CPPCHECKTOOL=${TOOLSDIR}/cpptools/cppcheck/cppcheck
+CPPCHECKFLAGS="--inline-suppr --error-exitcode=1"
+CPPCHECK=" ${CPPCHECKTOOL} ${CPPCHECKFLAGS}"
+
+for file in $(git diff-index --cached $against | \
+ grep -E '[MA].*\.(C|c|cpp|cc|cxx)$' | cut -f 2)
+do
+
+ dir="$(dirname $file)"
+ filename="$(basename $file)"
+
+ # TODO RTC 215692
+ # The following command checks for cppcheck errors. All cppcheck errors are
+ # printed to the terminal and stored to a file .${filename}.cppcheck.
+ set -o pipefail && cd ${dir} && timeout 2m ${CPPCHECK} $filename 2>&1 | tee .${filename}.cppcheck; exit_code=$?; \
+ if [ "$exit_code" -ne 1 ]; then \
+ # If exit code does not equal 1 (which is the error code when a cppcheck
+ # error is found) delete the created .cppcheck file.
+ # Note that time-out fails with error code 127.
+ rm -f .${filename}.cppcheck; \
+ fi
+ cd $PROJECT_ROOT
+
+done
+
+exit 0
diff --git a/src/import/chips/centaur/procedures/hwp/memory/lib/shared/dimmConsts.H b/src/import/chips/centaur/procedures/hwp/memory/lib/shared/dimmConsts.H
index 03f1b2a51..ac18feba6 100644
--- a/src/import/chips/centaur/procedures/hwp/memory/lib/shared/dimmConsts.H
+++ b/src/import/chips/centaur/procedures/hwp/memory/lib/shared/dimmConsts.H
@@ -40,6 +40,7 @@ enum consts : size_t
{
MAX_PORTS_PER_MBA = 2, ///< Maximum number of ports on an MBA
MAX_DIMM_PER_PORT = 2, ///< Maximum number of DIMMs attached to an MBA PORT
+ MAX_DIMM_PER_MBA = MAX_DIMM_PER_PORT * MAX_PORTS_PER_MBA, ///< Maximum number of DIMMs attached to an MBA
MAX_MBA_PER_CEN = 2, ///< Maximum number of MBAs on a membuf
MAX_PORTS_PER_CEN = 4, ///< Maximum number of ports on a centaur
MAX_RANKS_PER_DIMM = 4, ///< Maximum number of ranks on a DIMM
diff --git a/src/import/chips/centaur/procedures/hwp/memory/lib/utils/cumulus_find.H b/src/import/chips/centaur/procedures/hwp/memory/lib/utils/cumulus_find.H
new file mode 100644
index 000000000..8adf99b3f
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/lib/utils/cumulus_find.H
@@ -0,0 +1,126 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/centaur/procedures/hwp/memory/lib/utils/cumulus_find.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file cumulus_find.H
+/// @brief Templates for finding things
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_CUMULUS_FIND_H
+#define _MSS_CUMULUS_FIND_H
+
+#include <fapi2.H>
+#include <vector>
+#include <generic/memory/lib/utils/find.H>
+
+namespace mss
+{
+
+///
+/// @brief find the DMI given an MBA
+/// @param[in] i_target the fapi2 target MBA
+/// @return a DMI target.
+///
+template<>
+inline fapi2::Target<fapi2::TARGET_TYPE_DMI> find_target(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
+{
+ return i_target.getParent<fapi2::TARGET_TYPE_MEMBUF_CHIP>().getParent<fapi2::TARGET_TYPE_DMI>();
+}
+
+///
+/// @brief find the PROC given a MEMBUF
+/// @param[in] i_target the fapi2 target MEMBUF
+/// @return a PROC target.
+///
+template<>
+inline fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> find_target(const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>&
+ i_target)
+{
+ return i_target.getParent<fapi2::TARGET_TYPE_DMI>().getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+}
+
+///
+/// @brief find the PROC_CHIP given a MBA
+/// @param[in] i_target the fapi2 target MBA
+/// @return a DMI target.
+///
+template<>
+inline fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> find_target(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
+{
+ return i_target.getParent<fapi2::TARGET_TYPE_MEMBUF_CHIP>()
+ .getParent<fapi2::TARGET_TYPE_DMI>()
+ .getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+}
+
+///
+/// @brief find all the MBA connected to an DMI
+/// @param[in] i_target a fapi2::Target DMI
+/// @return a vector of fapi2::TARGET_TYPE_MBA
+///
+template<>
+inline std::vector< fapi2::Target<fapi2::TARGET_TYPE_MBA> >
+find_targets( const fapi2::Target<fapi2::TARGET_TYPE_DMI>& i_target,
+ fapi2::TargetState i_state )
+{
+ std::vector< fapi2::Target<fapi2::TARGET_TYPE_MBA> > l_mbas;
+
+ for (const auto& membuf_chip : i_target.getChildren<fapi2::TARGET_TYPE_MEMBUF_CHIP>(i_state))
+ {
+ auto l_these_mbas( membuf_chip.getChildren<fapi2::TARGET_TYPE_MBA>(i_state) );
+ l_mbas.insert(l_mbas.end(), l_these_mbas.begin(), l_these_mbas.end());
+ }
+
+ return l_mbas;
+}
+
+///
+/// @brief find all the DIMM connected to a centaur
+/// @param[in] i_target a fapi2::Target TARGET_TYPE_MEMBUF_CHIP
+/// @return a vector of fapi2::TARGET_TYPE_DIMM
+///
+template<>
+inline std::vector< fapi2::Target<fapi2::TARGET_TYPE_DIMM> >
+find_targets( const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_target,
+ fapi2::TargetState i_state )
+{
+ std::vector< fapi2::Target<fapi2::TARGET_TYPE_DIMM> > l_dimms;
+
+ for (const auto& l_mba : i_target.getChildren<fapi2::TARGET_TYPE_MBA>(i_state))
+ {
+ auto l_these_dimms( l_mba.getChildren<fapi2::TARGET_TYPE_DIMM>(i_state) );
+ l_dimms.insert(l_dimms.end(), l_these_dimms.begin(), l_these_dimms.end());
+ }
+
+ return l_dimms;
+}
+
+}// mss
+
+#endif
diff --git a/src/import/chips/centaur/procedures/hwp/memory/lib/utils/mem_size.C b/src/import/chips/centaur/procedures/hwp/memory/lib/utils/mem_size.C
index 465e31779..507618ea1 100644
--- a/src/import/chips/centaur/procedures/hwp/memory/lib/utils/mem_size.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/lib/utils/mem_size.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -28,7 +28,7 @@
#include <lib/shared/dimmConsts.H>
#include <p9c_mss_funcs.H>
#include <generic/memory/lib/utils/memory_size.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/cumulus_find.H>
#include <generic/memory/lib/utils/c_str.H>
///
diff --git a/src/import/chips/centaur/procedures/hwp/memory/mss_dynamic_vid_utils.C b/src/import/chips/centaur/procedures/hwp/memory/mss_dynamic_vid_utils.C
index f8324bb84..7c05e9608 100644
--- a/src/import/chips/centaur/procedures/hwp/memory/mss_dynamic_vid_utils.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/mss_dynamic_vid_utils.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -32,7 +32,7 @@
/// *HWP Consumed by: HB
#include <mss_dynamic_vid_utils.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/cumulus_find.H>
#include <generic/memory/lib/utils/c_str.H>
///
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_cen_plug_rules.H b/src/import/chips/centaur/procedures/hwp/memory/p9c_cen_plug_rules.H
new file mode 100644
index 000000000..c7c22f158
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_cen_plug_rules.H
@@ -0,0 +1,396 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/centaur/procedures/hwp/memory/p9c_cen_plug_rules.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/// @file p9c_cen_plug_ruiles.H
+/// @brief Takes in spd and configures effective attrs
+///
+/// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+/// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+/// *HWP Team: Memory
+/// *HWP Level: 2
+/// *HWP Consumed by: HB
+
+#ifndef P9C_CEN_PLUG_RULES_H_
+#define P9C_CEN_PLUG_RULES_H_
+
+//------------------------------------------------------------------------------
+// My Includes
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+#include <dimmConsts.H>
+#include <generic/memory/lib/utils/c_str.H>
+
+namespace mss
+{
+namespace cen
+{
+
+///
+/// @Brief Enumeration for the attributes to check
+///
+enum attr
+{
+ ROWS = 0,
+ COLS = 1,
+ DENSITY = 2,
+ WIDTH = 3,
+ MASTER_RANKS = 4,
+ NUM_RANKS = 5,
+
+ // Dispatcher parameters
+ START = ROWS,
+ END = NUM_RANKS + 1,
+};
+
+///
+/// @brief Traits class for each attribute
+/// @tparam attribute traits
+///
+template<attr A>
+class attr_traits
+{};
+
+///
+/// @brief Traits class for each attribute - ROWS specialization
+///
+template<>
+class attr_traits<attr::ROWS>
+{
+ public:
+ static constexpr bool IS_DIMM_TYPE = false;
+ static constexpr const char* STR = "ROWS";
+
+ ///
+ /// @brief attribute getter helper
+ /// @param[in] i_target MBA target
+ /// @param[out] o_data data from the attr
+ /// @return fapi2::ReturnCode
+ ///
+ static fapi2::ReturnCode getter(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target, uint8_t& o_data)
+ {
+ return FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_ROWS, i_target, o_data);
+ }
+};
+
+///
+/// @brief Traits class for each attribute - COLS specialization
+///
+template<>
+class attr_traits<attr::COLS>
+{
+ public:
+ static constexpr bool IS_DIMM_TYPE = false;
+ static constexpr const char* STR = "COLS";
+
+ ///
+ /// @brief attribute getter helper
+ /// @param[in] i_target MBA target
+ /// @param[out] o_data data from the attr
+ /// @return fapi2::ReturnCode
+ ///
+ static fapi2::ReturnCode getter(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target, uint8_t& o_data)
+ {
+ return FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_COLS, i_target, o_data);
+ }
+};
+
+///
+/// @brief Traits class for each attribute - DENSITY specialization
+///
+template<>
+class attr_traits<attr::DENSITY>
+{
+ public:
+ static constexpr bool IS_DIMM_TYPE = false;
+ static constexpr const char* STR = "DENSITY";
+
+ ///
+ /// @brief attribute getter helper
+ /// @param[in] i_target MBA target
+ /// @param[out] o_data data from the attr
+ /// @return fapi2::ReturnCode
+ ///
+ static fapi2::ReturnCode getter(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target, uint8_t& o_data)
+ {
+ return FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_DENSITY, i_target, o_data);
+ }
+};
+
+///
+/// @brief Traits class for each attribute - WIDTH specialization
+///
+template<>
+class attr_traits<attr::WIDTH>
+{
+ public:
+ static constexpr bool IS_DIMM_TYPE = false;
+ static constexpr const char* STR = "WIDTH";
+
+ ///
+ /// @brief attribute getter helper
+ /// @param[in] i_target MBA target
+ /// @param[out] o_data data from the attr
+ /// @return fapi2::ReturnCode
+ ///
+ static fapi2::ReturnCode getter(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target, uint8_t& o_data)
+ {
+ return FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_WIDTH, i_target, o_data);
+ }
+};
+
+///
+/// @brief Traits class for each attribute - MASTER_RANKS specialization
+///
+template<>
+class attr_traits<attr::MASTER_RANKS>
+{
+ public:
+ static constexpr bool IS_DIMM_TYPE = true;
+ static constexpr const char* STR = "MASTER_RANKS";
+
+ ///
+ /// @brief attribute getter helper
+ /// @param[in] i_target MBA target
+ /// @param[out] o_data data from the attr
+ /// @return fapi2::ReturnCode
+ ///
+ static fapi2::ReturnCode getter(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target,
+ uint8_t (&o_data)[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT])
+ {
+ return FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_NUM_MASTER_RANKS_PER_DIMM, i_target, o_data);
+ }
+};
+
+
+///
+/// @brief Traits class for each attribute - NUM_RANKS specialization
+///
+template<>
+class attr_traits<attr::NUM_RANKS>
+{
+ public:
+ static constexpr bool IS_DIMM_TYPE = true;
+ static constexpr const char* STR = "NUM_RANKS";
+
+ ///
+ /// @brief attribute getter helper
+ /// @param[in] i_target MBA target
+ /// @param[out] o_data data from the attr
+ /// @return fapi2::ReturnCode
+ ///
+ static fapi2::ReturnCode getter(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target,
+ uint8_t (&o_data)[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT])
+ {
+ return FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_NUM_RANKS_PER_DIMM, i_target, o_data);
+ }
+};
+
+///
+/// @brief Checks if a configuration is balanced for all attr
+/// @param[in] i_data the attribute data for a centaur
+/// @return true if the configuration is balanced
+///
+inline bool is_data_equivalent(const std::vector<uint8_t>& i_data)
+{
+ // Default to a balanced config - if we don't have any MBA's on this centaur, that's balanced
+ bool l_balanced = true;
+
+ // Make sure we have real data
+ if(!i_data.empty())
+ {
+ // Find if the data is all the same
+ const auto l_start = i_data[0];
+ const auto l_it = std::find_if(i_data.begin(), i_data.end(), [&l_start]( const uint8_t& i_rhs) -> bool
+ {
+ return l_start != i_rhs;
+ });
+
+ // Data is balanced if all of data is equal (didn't find an unequal piece of data)
+ l_balanced = l_it == i_data.end();
+ }
+
+ return l_balanced;
+}
+
+///
+/// @brief Assembles the attribute into a vector for processing
+/// @tparam attr A attribute on which to operate
+/// @tparam attr_traits TT traits for the associated attribute
+/// @param[in] i_target centaur target on which to operate
+/// @param[in] std::false_type dispatch helper for MBA attribute types
+/// @param[out] o_data vectorized attribute data
+/// @return fapi2::ReturnCode
+///
+template<attr A, typename TT = attr_traits<A>>
+inline fapi2::ReturnCode vectorize_attr_data(const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_target,
+ std::false_type, std::vector<uint8_t>& o_data)
+{
+ o_data.clear();
+
+ // Loops through all MBA
+ for(const auto& l_mba : i_target.getChildren<fapi2::TARGET_TYPE_MBA>())
+ {
+ // Gets the attribute in question
+ uint8_t l_attr_data = 0;
+ FAPI_TRY(TT::getter(l_mba, l_attr_data));
+ o_data.push_back(l_attr_data);
+ FAPI_DBG("%s adding data0x%02x to vector size:%u for attr %u",
+ mss::spd::c_str(l_mba), l_attr_data, o_data.size(), A);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Assembles the attribute into a vector for processing
+/// @tparam attr A attribute on which to operate
+/// @tparam attr_traits TT traits for the associated attribute
+/// @param[in] i_target centaur target on which to operate
+/// @param[in] std::true_type dispatch helper for DIMM attribute types
+/// @param[out] o_data vectorized attribute data
+/// @return fapi2::ReturnCode
+///
+template<attr A, typename TT = attr_traits<A>>
+inline fapi2::ReturnCode vectorize_attr_data(const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_target,
+ std::true_type, std::vector<uint8_t>& o_data)
+{
+ o_data.clear();
+
+ // Loops through all MBA
+ for(const auto& l_mba : i_target.getChildren<fapi2::TARGET_TYPE_MBA>())
+ {
+ // Gets the attribute in question
+ uint8_t l_attr_data[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0};
+ FAPI_TRY(TT::getter(l_mba, l_attr_data));
+
+ // Loops through all DIMM's so we only get valid data
+ for(const auto& l_dimm : l_mba.getChildren<fapi2::TARGET_TYPE_DIMM>())
+ {
+ uint32_t l_dimm_pos = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FAPI_POS, l_dimm, l_dimm_pos));
+ {
+ // Converts the DIMM pos into the relative position compared to the MBA
+ const auto l_relative_pos = l_dimm_pos % MAX_DIMM_PER_MBA;
+
+ const auto l_port_index = l_relative_pos / MAX_PORTS_PER_MBA;
+ const auto l_dimm_index = l_relative_pos % MAX_DIMM_PER_PORT;
+ o_data.push_back(l_attr_data[l_port_index][l_dimm_index]);
+ FAPI_DBG("%s adding data0x%02x to vector port%u dimm%u size:%u",
+ mss::spd::c_str(l_mba), l_attr_data[l_port_index][l_dimm_index],
+ l_port_index, l_dimm_index, o_data.size());
+ }
+ }
+
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Checks if a configuration for a specific attribute is balanced over both MBA - recursion helper
+/// @tparam attr A the attribute on which to operate
+/// @tparam attr_traits TT traits for the associated attribute
+/// @param[in] i_target centaur target on which to operate
+/// @return fapi2::ReturnCode
+///
+template<attr A, typename TT = attr_traits<A>>
+inline fapi2::ReturnCode check_for_balanced_config_helper(const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_target)
+{
+ // Helper for the FFDC below - FFDC doesnt like constexpr
+ const auto ATTR = A;
+
+ // Vector of attribute data
+ std::vector<uint8_t> l_attr_data;
+
+ // Gets the attribute data
+ FAPI_TRY(vectorize_attr_data<A>(i_target, std::integral_constant<bool, TT::IS_DIMM_TYPE> {},
+ l_attr_data));
+
+ // Assert out if we're not balanced
+ FAPI_ASSERT(is_data_equivalent(l_attr_data),
+ fapi2::CEN_MSS_PLUG_RULES_MBA_MISMATCH()
+ .set_TARGET_CEN(i_target)
+ .set_ATTR(ATTR),
+ "%s has an unbalanced config for %s",
+ mss::c_str(i_target), TT::STR);
+
+ return check_for_balanced_config_helper < static_cast<attr>(A + 1u) > (i_target);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Checks if a configuration for a specific attribute is balanced over both MBA - ending specialization
+/// @param[in] i_target centaur target on which to operate
+/// @return fapi2::ReturnCode
+///
+template<>
+inline fapi2::ReturnCode check_for_balanced_config_helper<attr::END>(const
+ fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_target)
+{
+ FAPI_INF("%s has a balanced configuration between the MBA's", mss::c_str(i_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+///
+/// @brief mss_eff_config_verify_plug_rules(): Verifies plugrules on a per-Centaur basis
+/// @param[in] i_target_mba: the fapi2 target
+/// @return fapi2::ReturnCode
+/// @note We pass in an MBA specifically to see if we're running on MBA23
+/// We only need to run this plug rules test if we have two MBA's
+///
+inline fapi2::ReturnCode mss_eff_config_verify_centaur_plug_rules(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
+{
+ const auto& l_cen = i_target.getParent<fapi2::TARGET_TYPE_MEMBUF_CHIP>();
+ uint8_t l_mba_pos = 0;
+
+ // First, check if we're MBA23 - if not, exit sucessfully
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_target, l_mba_pos));
+
+ if(l_mba_pos % MAX_MBA_PER_CEN == 0)
+ {
+ FAPI_INF("%s is MBA01, exiting succesfully", mss::spd::c_str(i_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ FAPI_INF("%s is MBA23, checking that MBA01's configuration == MBA23's configuration", mss::spd::c_str(i_target));
+
+ return check_for_balanced_config_helper<attr::START>(l_cen);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // ns
+} // cen
+
+#endif
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_bulk_pwr_throttles.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_bulk_pwr_throttles.C
index 06c84da79..02f8a2a1d 100644
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_bulk_pwr_throttles.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_bulk_pwr_throttles.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -67,7 +67,7 @@
#include <p9c_mss_bulk_pwr_throttles.H>
#include <generic/memory/lib/utils/c_str.H>
#include <dimmConsts.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/cumulus_find.H>
#include <generic/memory/lib/utils/count_dimm.H>
//------------------------------------------------------------------------------
// Includes
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.C
index d01c3ccb6..5f0233b2c 100644
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -53,7 +53,7 @@
#include <p9c_mss_draminit_mc.H>
#include <p9c_mss_row_repair.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/cumulus_find.H>
#include <dimmConsts.H>
//----------------------------------------------------------------------
// Address Includes
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.C
index f45a498fd..461d7c576 100755
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.C
@@ -53,7 +53,7 @@
#include <p9c_mss_row_repair.H>
#include <p9c_mss_draminit_training.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/cumulus_find.H>
#include <dimmConsts.H>
#include <delayRegs.H>
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config.C
index bc137313d..5b4c25277 100644
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,6 +39,7 @@
#include <p9c_mss_eff_config_rank_group.H>
#include <p9c_mss_eff_config_shmoo.H>
#include <generic/memory/lib/utils/c_str.H>
+#include <p9c_cen_plug_rules.H>
//------------------------------------------------------------------------------
// Constants
@@ -2725,6 +2726,9 @@ extern "C"
FAPI_TRY(mss_eff_config_shmoo(i_target_mba));
+ // Checks that both MBA's are configured the same
+ FAPI_TRY(mss::cen::mss_eff_config_verify_centaur_plug_rules(i_target_mba));
+
FAPI_INF("mss_eff_config on %s COMPLETE\n", mss::c_str(i_target_mba));
fapi_try_exit:
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config.H b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config.H
index 1c70a3918..e325b9f8a 100644
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config.H
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -45,7 +45,6 @@
#include <dimmConsts.H>
typedef fapi2::ReturnCode (*p9c_mss_eff_config_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_MBA> i_target_mba);
-
///
/// @brief struct mss_eff_config_data
/// @brief holds the the variables used in many function calls
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config_thermal.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config_thermal.C
index c613abb9f..c068389c5 100644
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config_thermal.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_eff_config_thermal.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -45,7 +45,7 @@
#include <generic/memory/lib/utils/c_str.H>
#include <dimmConsts.H>
#include <generic/memory/lib/utils/count_dimm.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/cumulus_find.H>
//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_mrs6_DDR4.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_mrs6_DDR4.C
index 34aef9a4f..b33f4dad9 100755
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_mrs6_DDR4.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_mrs6_DDR4.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -57,6 +57,7 @@ extern "C"
fapi2::ReturnCode p9c_mss_mrs6_DDR4(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
{
uint32_t l_ccs_inst_cnt = 0;
+ fapi2::buffer<uint64_t> l_shadow_data;
for (uint8_t l_port_number = 0; l_port_number < 2; ++l_port_number)
{
@@ -65,6 +66,9 @@ extern "C"
FAPI_TRY(mss_mr6_loader(i_target, l_port_number, l_ccs_inst_cnt), " mrs_load Failed");
}
+ // Get MR0 Shadow reg
+ FAPI_TRY(fapi2::getScom(i_target, 0x8000c01c0301143f, l_shadow_data));
+
// Execute the contents of CCS array
if (l_ccs_inst_cnt > 0)
{
@@ -74,6 +78,17 @@ extern "C"
l_ccs_inst_cnt = 0;
}
+ // Put MR0 Shadow Reg
+ FAPI_INF("Resetting MR0 Shadow registers to %016x", l_shadow_data);
+ FAPI_TRY(fapi2::putScom(i_target, 0x8001c01c0301143f, l_shadow_data));
+ FAPI_TRY(fapi2::putScom(i_target, 0x8000c01c0301143f, l_shadow_data));
+ FAPI_TRY(fapi2::putScom(i_target, 0x8001c11c0301143f, l_shadow_data));
+ FAPI_TRY(fapi2::putScom(i_target, 0x8000c11c0301143f, l_shadow_data));
+ FAPI_TRY(fapi2::putScom(i_target, 0x8001c21c0301143f, l_shadow_data));
+ FAPI_TRY(fapi2::putScom(i_target, 0x8000c21c0301143f, l_shadow_data));
+ FAPI_TRY(fapi2::putScom(i_target, 0x8001c31c0301143f, l_shadow_data));
+ FAPI_TRY(fapi2::putScom(i_target, 0x8000c31c0301143f, l_shadow_data));
+
fapi_try_exit:
return fapi2::current_err;
}
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_rowRepairFuncs.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_rowRepairFuncs.C
index 8362380a7..8323cf8b6 100644
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_rowRepairFuncs.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_rowRepairFuncs.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -23,7 +23,7 @@
/* */
/* IBM_PROLOG_END_TAG */
#include <p9c_mss_rowRepairFuncs.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/cumulus_find.H>
#include <generic/memory/lib/utils/c_str.H>
using namespace fapi2;
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.C
index 19485c13b..c613eb50c 100644
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -26,7 +26,7 @@
#include <cen_gen_scom_addresses.H>
#include <cen_gen_scom_addresses_fld.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/cumulus_find.H>
#include <p9c_mss_funcs.H>
#include <p9c_mss_ddr4_funcs.H>
#include <p9c_mss_rowRepairFuncs.H>
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.C
index d51b829be..868ae2234 100755
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,7 +42,7 @@
#include <p9c_mss_unmask_errors.H>
#include <cen_gen_scom_addresses.H>
#include <fapi2.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/cumulus_find.H>
///
/// @brief Sets action regs and mask settings for pervasive errors to their runtime settings.
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_volt_dimm_count.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_volt_dimm_count.C
index c24fcf6fb..7617253a6 100644
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_volt_dimm_count.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_volt_dimm_count.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,7 +39,7 @@
#include <fapi2.H>
#include <p9c_mss_volt_dimm_count.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/cumulus_find.H>
using fapi2::TARGET_TYPE_MBA;
using fapi2::TARGET_TYPE_DIMM;
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_volt_vddr_offset.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_volt_vddr_offset.C
index 2cd518ef0..f4d959eb4 100644
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_volt_vddr_offset.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_volt_vddr_offset.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -43,7 +43,7 @@
#include <fapi2.H>
#include <p9c_mss_volt_vddr_offset.H>
#include <mss_dynamic_vid_utils.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/cumulus_find.H>
#include <generic/memory/lib/utils/count_dimm.H>
extern "C"
diff --git a/src/import/chips/centaur/procedures/xml/error_info/p9c_memory_mss_eff_config_errors.xml b/src/import/chips/centaur/procedures/xml/error_info/p9c_memory_mss_eff_config_errors.xml
index a42bc0062..ce516875c 100644
--- a/src/import/chips/centaur/procedures/xml/error_info/p9c_memory_mss_eff_config_errors.xml
+++ b/src/import/chips/centaur/procedures/xml/error_info/p9c_memory_mss_eff_config_errors.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2017,2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2017,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -226,10 +226,10 @@
<description>Plug rule violation, one position is empty but other are present
</description>
<FFDC>TARGET_MBA</FFDC>
- <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_0_0</ffdc>
- <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_0_1</ffdc>
- <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_1_0</ffdc>
- <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_1_1</ffdc>
+ <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_0_0</ffdc>
+ <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_0_1</ffdc>
+ <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_1_0</ffdc>
+ <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_1_1</ffdc>
<callout>
<procedure>MEMORY_PLUGGING_ERROR</procedure>
<priority>HIGH</priority>
@@ -257,10 +257,10 @@
<description>Plug rule violation, sides do not match
</description>
<FFDC>TARGET_MBA</FFDC>
- <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_0_0</ffdc>
- <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_0_1</ffdc>
- <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_1_0</ffdc>
- <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_1_1</ffdc>
+ <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_0_0</ffdc>
+ <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_0_1</ffdc>
+ <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_1_0</ffdc>
+ <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_1_1</ffdc>
<callout>
<procedure>MEMORY_PLUGGING_ERROR</procedure>
@@ -290,10 +290,10 @@
<description>Plug rule violation, top and bottom do not match
</description>
<FFDC>TARGET_MBA</FFDC>
- <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_0_0</ffdc>
- <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_0_1</ffdc>
- <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_1_0</ffdc>
- <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_1_1</ffdc>
+ <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_0_0</ffdc>
+ <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_0_1</ffdc>
+ <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_1_0</ffdc>
+ <ffdc>CUR_DIMM_SPD_VALID_U8ARRAY_1_1</ffdc>
<callout>
<procedure>MEMORY_PLUGGING_ERROR</procedure>
@@ -322,10 +322,10 @@
<description>Incompatable DRAM generation
</description>
<FFDC>TARGET_MBA</FFDC>
- <ffdc>DRAM_DEVICE_TYPE_0_0</ffdc>
- <ffdc>DRAM_DEVICE_TYPE_0_1</ffdc>
- <ffdc>DRAM_DEVICE_TYPE_1_0</ffdc>
- <ffdc>DRAM_DEVICE_TYPE_1_1</ffdc>
+ <ffdc>DRAM_DEVICE_TYPE_0_0</ffdc>
+ <ffdc>DRAM_DEVICE_TYPE_0_1</ffdc>
+ <ffdc>DRAM_DEVICE_TYPE_1_0</ffdc>
+ <ffdc>DRAM_DEVICE_TYPE_1_1</ffdc>
<callout>
<procedure>MEMORY_PLUGGING_ERROR</procedure>
@@ -354,10 +354,10 @@
<description>Incompatable DIMM type
</description>
<FFDC>TARGET_MBA</FFDC>
- <ffdc>MODULE_TYPE_0_0</ffdc>
- <ffdc>MODULE_TYPE_0_1</ffdc>
- <ffdc>MODULE_TYPE_1_0</ffdc>
- <ffdc>MODULE_TYPE_1_1</ffdc>
+ <ffdc>MODULE_TYPE_0_0</ffdc>
+ <ffdc>MODULE_TYPE_0_1</ffdc>
+ <ffdc>MODULE_TYPE_1_0</ffdc>
+ <ffdc>MODULE_TYPE_1_1</ffdc>
<callout>
<procedure>MEMORY_PLUGGING_ERROR</procedure>
@@ -386,10 +386,10 @@
<description>Incompatable DIMM ranks
</description>
<FFDC>TARGET_MBA</FFDC>
- <ffdc>NUM_RANKS_0_0</ffdc>
- <ffdc>NUM_RANKS_0_1</ffdc>
- <ffdc>NUM_RANKS_1_0</ffdc>
- <ffdc>NUM_RANKS_1_1</ffdc>
+ <ffdc>NUM_RANKS_0_0</ffdc>
+ <ffdc>NUM_RANKS_0_1</ffdc>
+ <ffdc>NUM_RANKS_1_0</ffdc>
+ <ffdc>NUM_RANKS_1_1</ffdc>
<callout>
<procedure>MEMORY_PLUGGING_ERROR</procedure>
@@ -418,10 +418,10 @@
<description>Incompatable DIMM banks
</description>
<FFDC>TARGET_MBA</FFDC>
- <ffdc>SDRAM_BANKS_0_0</ffdc>
- <ffdc>SDRAM_BANKS_0_1</ffdc>
- <ffdc>SDRAM_BANKS_1_0</ffdc>
- <ffdc>SDRAM_BANKS_1_1</ffdc>
+ <ffdc>SDRAM_BANKS_0_0</ffdc>
+ <ffdc>SDRAM_BANKS_0_1</ffdc>
+ <ffdc>SDRAM_BANKS_1_0</ffdc>
+ <ffdc>SDRAM_BANKS_1_1</ffdc>
<callout>
<procedure>MEMORY_PLUGGING_ERROR</procedure>
@@ -450,10 +450,10 @@
<description>Incompatable DIMM rows
</description>
<FFDC>TARGET_MBA</FFDC>
- <ffdc>SDRAM_ROWS_0_0</ffdc>
- <ffdc>SDRAM_ROWS_0_1</ffdc>
- <ffdc>SDRAM_ROWS_1_0</ffdc>
- <ffdc>SDRAM_ROWS_1_1</ffdc>
+ <ffdc>SDRAM_ROWS_0_0</ffdc>
+ <ffdc>SDRAM_ROWS_0_1</ffdc>
+ <ffdc>SDRAM_ROWS_1_0</ffdc>
+ <ffdc>SDRAM_ROWS_1_1</ffdc>
<callout>
<procedure>MEMORY_PLUGGING_ERROR</procedure>
@@ -482,10 +482,10 @@
<description>Incompatable DIMM columns
</description>
<FFDC>TARGET_MBA</FFDC>
- <ffdc>SDRAM_COLS_0_0</ffdc>
- <ffdc>SDRAM_COLS_0_1</ffdc>
- <ffdc>SDRAM_COLS_1_0</ffdc>
- <ffdc>SDRAM_COLS_1_1</ffdc>
+ <ffdc>SDRAM_COLS_0_0</ffdc>
+ <ffdc>SDRAM_COLS_0_1</ffdc>
+ <ffdc>SDRAM_COLS_1_0</ffdc>
+ <ffdc>SDRAM_COLS_1_1</ffdc>
<callout>
<procedure>MEMORY_PLUGGING_ERROR</procedure>
@@ -514,10 +514,10 @@
<description>Incompatable DRAM primary bus width
</description>
<FFDC>TARGET_MBA</FFDC>
- <ffdc>BUS_WIDTH_0_0</ffdc>
- <ffdc>BUS_WIDTH_0_1</ffdc>
- <ffdc>BUS_WIDTH_1_0</ffdc>
- <ffdc>BUS_WIDTH_1_1</ffdc>
+ <ffdc>BUS_WIDTH_0_0</ffdc>
+ <ffdc>BUS_WIDTH_0_1</ffdc>
+ <ffdc>BUS_WIDTH_1_0</ffdc>
+ <ffdc>BUS_WIDTH_1_1</ffdc>
<callout>
<procedure>MEMORY_PLUGGING_ERROR</procedure>
@@ -575,10 +575,10 @@
<description>Incompatable DRAM width
</description>
<FFDC>TARGET_MBA</FFDC>
- <ffdc>DRAM_WIDTH_0_0</ffdc>
- <ffdc>DRAM_WIDTH_0_1</ffdc>
- <ffdc>DRAM_WIDTH_1_0</ffdc>
- <ffdc>DRAM_WIDTH_1_1</ffdc>
+ <ffdc>DRAM_WIDTH_0_0</ffdc>
+ <ffdc>DRAM_WIDTH_0_1</ffdc>
+ <ffdc>DRAM_WIDTH_1_0</ffdc>
+ <ffdc>DRAM_WIDTH_1_1</ffdc>
<callout>
<procedure>MEMORY_PLUGGING_ERROR</procedure>
@@ -1028,5 +1028,19 @@
</hwpError>
+<hwpError>
+ <rc>RC_CEN_MSS_PLUG_RULES_MBA_MISMATCH</rc>
+ <description>Mismatch found between MBA configurations</description>
+ <FFDC>TARGET_CEN</FFDC>
+ <ffdc>ATTR</ffdc>
+ <callout>
+ <target>TARGET_CEN</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET_CEN</target>
+ </deconfigure>
+</hwpError>
+
</hwpErrors>
diff --git a/src/import/chips/common/utils/chipids.H b/src/import/chips/common/utils/chipids.H
index 5f9a321d6..6e05e21dd 100644
--- a/src/import/chips/common/utils/chipids.H
+++ b/src/import/chips/common/utils/chipids.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -83,7 +83,8 @@ constexpr uint32_t NIMBUS = 0x020D1049;
constexpr uint32_t CUMULUS = 0x020D4049;
constexpr uint32_t AXONE = 0x020D9049;
constexpr uint32_t CENTAUR = 0x06039049;
-constexpr uint32_t EXPLORER = 0x060D2049;
+constexpr uint32_t EXPLORER = 0x060D2000;
+constexpr uint32_t GEMINI = 0x060DC000;
// Shorter 16-bit value (drops Major nibble and 049)
constexpr uint32_t NIMBUS_16 = 0x20D1;
@@ -91,6 +92,7 @@ constexpr uint32_t CUMULUS_16 = 0x20D4;
constexpr uint32_t AXONE_16 = 0x20D9;
constexpr uint32_t CENTAUR_16 = 0x6039;
constexpr uint32_t EXPLORER_16 = 0x60D2;
+constexpr uint32_t GEMINI_16 = 0x60DC;
}; //namespace
@@ -103,9 +105,20 @@ namespace POWER_OCID
constexpr uint16_t EXPLORER = 0x0636;
-// Vendir IDs
+// Vendor IDs
constexpr uint16_t VENDOR_IBM = 0x1014;
}; //namespace
+
+// DMB (Differential Memory Buffer) IDs
+namespace DDIMM_DMB_ID
+{
+
+// DDR4 DDIMM - Bytes [198][199]
+constexpr uint16_t EXPLORER = 0x8029;
+constexpr uint16_t GEMINI = 0x80A4;
+
+};
+
#endif /* _CHIPIDS_H */
diff --git a/src/import/chips/ocmb/common/include/pmic_regs.H b/src/import/chips/ocmb/common/include/pmic_regs.H
new file mode 100644
index 000000000..f3010e727
--- /dev/null
+++ b/src/import/chips/ocmb/common/include/pmic_regs.H
@@ -0,0 +1,154 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/common/include/pmic_regs.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file pmic_regs.H
+/// @brief PMIC Registers
+///
+// *HWP HWP Owner: Mark Pizzutillo <mark.pizzutillo@ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: FSP:HB
+
+#ifndef __PMIC_REGS__
+#define __PMIC_REGS__
+
+#include <lib/utils/pmic_consts.H>
+
+///
+/// @brief Registers for PMIC devices
+/// @class pmicRegs
+/// @tparam P pmic_product
+///
+template<mss::pmic::product P>
+struct pmicRegs;
+
+///
+/// @brief JEDEC Common Registers
+/// @note These registers are not defined with any particular name other than RXX.
+/// Their purposes and bit-mappings are outlined in any of the JEDEC compliant PMIC specs.
+///
+template<>
+struct pmicRegs<mss::pmic::product::JEDEC_COMPLIANT>
+{
+ static constexpr uint8_t BROADCAST = 0x0;
+ /* R00 - R03 RESERVED */
+ static constexpr uint8_t R04 = 0x04;
+ static constexpr uint8_t R05 = 0x05;
+ static constexpr uint8_t R06 = 0x06;
+ /* R07 RESERVED */
+ static constexpr uint8_t R08 = 0x08;
+ static constexpr uint8_t R09 = 0x09;
+ static constexpr uint8_t R0A = 0x0A;
+ static constexpr uint8_t R0B = 0x0B;
+ static constexpr uint8_t R0C = 0x0C;
+ static constexpr uint8_t R0D = 0x0D;
+ static constexpr uint8_t R0E = 0x0E;
+ static constexpr uint8_t R0F = 0x0F;
+ static constexpr uint8_t R10 = 0x10;
+ static constexpr uint8_t R11 = 0x11;
+ static constexpr uint8_t R12 = 0x12;
+ static constexpr uint8_t R13 = 0x13;
+ static constexpr uint8_t R14 = 0x14;
+ static constexpr uint8_t R15 = 0x15;
+ static constexpr uint8_t R16 = 0x16;
+ static constexpr uint8_t R17 = 0x17;
+ static constexpr uint8_t R18 = 0x18;
+ static constexpr uint8_t R19 = 0x19;
+ static constexpr uint8_t R1A = 0x1A;
+ static constexpr uint8_t R1B = 0x1B;
+ static constexpr uint8_t R1C = 0x1C;
+ static constexpr uint8_t R1D = 0x1D;
+ static constexpr uint8_t R1E = 0x1E;
+ static constexpr uint8_t R1F = 0x1F;
+ static constexpr uint8_t R20 = 0x20;
+ static constexpr uint8_t R21_SWA_VOLTAGE_SETTING = 0x21;
+ static constexpr uint8_t R22 = 0x22;
+ static constexpr uint8_t R23_SWB_VOLTAGE_SETTING = 0x23;
+ static constexpr uint8_t R24 = 0x24;
+ static constexpr uint8_t R25_SWC_VOLTAGE_SETTING = 0x25;
+ static constexpr uint8_t R26 = 0x26;
+ static constexpr uint8_t R27_SWD_VOLTAGE_SETTING = 0x27;
+ static constexpr uint8_t R28 = 0x28;
+ static constexpr uint8_t R29 = 0x29;
+ static constexpr uint8_t R2A = 0x2A;
+ static constexpr uint8_t R2B = 0x2B;
+ static constexpr uint8_t R2C = 0x2C;
+ static constexpr uint8_t R2D = 0x2D;
+ static constexpr uint8_t R2E = 0x2E;
+ static constexpr uint8_t R2F = 0x2F;
+ static constexpr uint8_t R30 = 0x30;
+ static constexpr uint8_t R31 = 0x31;
+ static constexpr uint8_t R32 = 0x32;
+ static constexpr uint8_t R33 = 0x33;
+ static constexpr uint8_t R34 = 0x34;
+ static constexpr uint8_t R35 = 0x35;
+ /* R36 RESERVED */
+ static constexpr uint8_t R37_PASSWORD_LOWER_BYTE_0 = 0x37;
+ static constexpr uint8_t R38_PASSWORD_UPPER_BYTE_1 = 0x38;
+ static constexpr uint8_t R39_COMMAND_CODES = 0x39;
+ static constexpr uint8_t R3A = 0x3A;
+ static constexpr uint8_t R3B = 0x3B;
+ static constexpr uint8_t R3C_VENDOR_ID_BYTE_0 = 0x3C;
+ static constexpr uint8_t R3D_VENDOR_ID_BYTE_1 = 0x3D;
+
+ /* ----- DIMM VENDOR REGION ----- */
+
+ /* R3E - R3F RESERVED */
+ static constexpr uint8_t R40_POWER_ON_SEQUENCE_CONFIG_1 = 0x40;
+ static constexpr uint8_t R41_POWER_ON_SEQUENCE_CONFIG_2 = 0x41;
+ static constexpr uint8_t R42_POWER_ON_SEQUENCE_CONFIG_3 = 0x42;
+ static constexpr uint8_t R43_POWER_ON_SEQUENCE_CONFIG_4 = 0x43;
+ /* R44 RESERVED */
+ static constexpr uint8_t R45_SWA_VOLTAGE_SETTING = 0x45;
+ static constexpr uint8_t R46 = 0x46;
+ static constexpr uint8_t R47_SWB_VOLTAGE_SETTING = 0x47;
+ static constexpr uint8_t R48 = 0x48;
+ static constexpr uint8_t R49_SWC_VOLTAGE_SETTING = 0x49;
+ static constexpr uint8_t R4A = 0x4A;
+ static constexpr uint8_t R4B_SWD_VOLTAGE_SETTING = 0x4B;
+ static constexpr uint8_t R4C = 0x4C;
+ static constexpr uint8_t R4D = 0x4D;
+ static constexpr uint8_t R4E = 0x4E;
+ static constexpr uint8_t R4F = 0x4F;
+ static constexpr uint8_t R50 = 0x50;
+ static constexpr uint8_t R51 = 0x51;
+ /* R52 - R57 RESERVED */
+ static constexpr uint8_t R58_POWER_OFF_SEQUENCE_CONFIG_1 = 0x58;
+ static constexpr uint8_t R59_POWER_OFF_SEQUENCE_CONFIG_2 = 0x59;
+ static constexpr uint8_t R5A_POWER_OFF_SEQUENCE_CONFIG_3 = 0x5A;
+ static constexpr uint8_t R5B_POWER_OFF_SEQUENCE_CONFIG_4 = 0x5B;
+ /* R5C RESERVED */
+ static constexpr uint8_t R5D = 0x5D;
+ static constexpr uint8_t R5E = 0x5E;
+ static constexpr uint8_t R5F_PRIMARY_INFERFACE_IO_TYPE = 0x5F;
+ /* R60 - R6C RESERVED */
+ static constexpr uint8_t R6D = 0x6D;
+ static constexpr uint8_t R6E = 0x6E;
+ /* R6F RESERVED */
+};
+
+#endif
diff --git a/src/import/chips/ocmb/common/include/pmic_regs_fld.H b/src/import/chips/ocmb/common/include/pmic_regs_fld.H
new file mode 100644
index 000000000..b5139939a
--- /dev/null
+++ b/src/import/chips/ocmb/common/include/pmic_regs_fld.H
@@ -0,0 +1,193 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/common/include/pmic_regs_fld.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file pmic_regs_fld.H
+/// @brief PMIC Register Fields
+///
+// *HWP HWP Owner: Mark Pizzutillo <mark.pizzutillo@ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: FSP:HB
+
+#ifndef __PMIC_REGS_FLD__
+#define __PMIC_REGS_FLD__
+
+#include <lib/utils/pmic_consts.H>
+
+///
+/// @brief Register fields for PMIC devices
+/// @class pmicFields
+/// @tparam P pmic_product
+///
+template<mss::pmic::product P>
+struct pmicFields;
+
+///
+/// @brief Fields for JEDEC_COMPLIANT PMICs
+///
+template<>
+struct pmicFields<mss::pmic::product::JEDEC_COMPLIANT>
+{
+ static constexpr uint8_t R2F_SECURE_MODE = 0x02;
+ static constexpr uint8_t R32_VR_ENABLE = 0x07;
+ static constexpr uint8_t PMIC_DEVICE = 0x00;
+
+ static constexpr uint8_t SWA_SWB_PHASE_MODE_SELECT = 0x00;
+
+ static constexpr uint8_t SWA_VOLTAGE_RANGE = 0x05;
+ static constexpr uint8_t SWB_VOLTAGE_RANGE = 0x04;
+ static constexpr uint8_t SWC_VOLTAGE_RANGE = 0x03;
+ static constexpr uint8_t SWD_VOLTAGE_RANGE = 0x00;
+
+ static constexpr uint8_t SEQUENCE_ENABLE = 0x07;
+ static constexpr uint8_t SEQUENCE_SWA_ENABLE = 0x06;
+ static constexpr uint8_t SEQUENCE_SWB_ENABLE = 0x05;
+ static constexpr uint8_t SEQUENCE_SWC_ENABLE = 0x04;
+ static constexpr uint8_t SEQUENCE_SWD_ENABLE = 0x03;
+
+ // R04
+ static constexpr uint8_t R04_GLOBAL_ERROR_COUNT = 0x07;
+ static constexpr uint8_t R04_GLOBAL_ERROR_LOG_BUCK_OV_OR_UV = 0x06;
+ static constexpr uint8_t R04_GLOBAL_ERROR_LOG_VIN_BULK_OVER_VOLTAGE = 0x05;
+ static constexpr uint8_t R04_GLOBAL_ERROR_LOG_CRITICAL_TEMPERATURE = 0x04;
+
+ // R05
+ static constexpr uint8_t R05_SWA_POWER_GOOD = 0x06;
+ static constexpr uint8_t R05_SWB_POWER_GOOD = 0x05;
+ static constexpr uint8_t R05_SWC_POWER_GOOD = 0x04;
+ static constexpr uint8_t R05_SWD_POWER_GOOD = 0x03;
+ static constexpr uint8_t R05_PMIC_ERROR_LOG = 0x02; // TK ARRAY
+
+ // R06
+ static constexpr uint8_t R06_SWA_UNDER_VOLTAGE_LOCKOUT = 0x07;
+ static constexpr uint8_t R06_SWB_UNDER_VOLTAGE_LOCKOUT = 0x06;
+ static constexpr uint8_t R06_SWC_UNDER_VOLTAGE_LOCKOUT = 0x05;
+ static constexpr uint8_t R06_SWD_UNDER_VOLTAGE_LOCKOUT = 0x04;
+ static constexpr uint8_t R06_SWA_OVER_VOLTAGE = 0x03;
+ static constexpr uint8_t R06_SWB_OVER_VOLTAGE = 0x02;
+ static constexpr uint8_t R06_SWC_OVER_VOLTAGE = 0x01;
+ static constexpr uint8_t R06_SWD_OVER_VOLTAGE = 0x00;
+
+ // R07 all reserved
+
+ // R08
+ static constexpr uint8_t R08_VIN_BULK_INPUT_PWR_GOOD_STATUS = 0x07;
+ static constexpr uint8_t R08_CRITICAL_TEMP_SHUTDOWN_STATUS = 0x06;
+ static constexpr uint8_t R08_SWA_PWR_GOOD_STATUS = 0x05;
+ static constexpr uint8_t R08_SWB_PWR_GOOD_STATUS = 0x04;
+ static constexpr uint8_t R08_SWC_PWR_GOOD_STATUS = 0x03;
+ static constexpr uint8_t R08_SWD_PWR_GOOD_STATUS = 0x02;
+ static constexpr uint8_t R08_VIN_MGMT_INPUT_OVER_VOLTAGE = 0x01;
+ static constexpr uint8_t R08_VIN_BULK_INPUT_OVER_VOLTAGE = 0x00;
+
+ // R09
+ static constexpr uint8_t R09_PMIC_HIGH_TEMP_WARNING_STATUS = 0x07;
+ static constexpr uint8_t R09_VBIAS_PWR_GOOD_STATUS = 0x06;
+ static constexpr uint8_t R09_VOUT_1_8_V_PWR_GOOD_STATUS = 0x05;
+ static constexpr uint8_t R09_VIN_MGMT_TO_VIN_BULK_SWITCHOVER_STATUS = 0x04;
+ static constexpr uint8_t R09_SWA_HIGH_OUTPUT_CURRENT_CONSUMPTION_WARNING_STATUS = 0x03;
+ static constexpr uint8_t R09_SWB_HIGH_OUTPUT_CURRENT_CONSUMPTION_WARNING_STATUS = 0x02;
+ static constexpr uint8_t R09_SWC_HIGH_OUTPUT_CURRENT_CONSUMPTION_WARNING_STATUS = 0x01;
+ static constexpr uint8_t R09_SWD_HIGH_OUTPUT_CURRENT_CONSUMPTION_WARNING_STATUS = 0x00;
+
+ // R0A
+ static constexpr uint8_t R0A_SWA_OUTPUT_OVER_VOLTAGE_STATUS = 0x07;
+ static constexpr uint8_t R0A_SWB_OUTPUT_OVER_VOLTAGE_STATUS = 0x06;
+ static constexpr uint8_t R0A_SWC_OUTPUT_OVER_VOLTAGE_STATUS = 0x05;
+ static constexpr uint8_t R0A_SWD_OUTPUT_OVER_VOLTAGE_STATUS = 0x04;
+ static constexpr uint8_t R0A_PEC_ERROR_STATUS = 0x03;
+ static constexpr uint8_t R0A_PARITY_ERROR_STATUS = 0x02;
+ static constexpr uint8_t R0A_IBI_STATUS = 0x01; // 0x00 reserved
+
+ // R0B
+ static constexpr uint8_t R0B_SWA_OUTPUT_CURRENT_LIMITER_WARNING_STATUS = 0x07;
+ static constexpr uint8_t R0B_SWB_OUTPUT_CURRENT_LIMITER_WARNING_STATUS = 0x06;
+ static constexpr uint8_t R0B_SWC_OUTPUT_CURRENT_LIMITER_WARNING_STATUS = 0x05;
+ static constexpr uint8_t R0B_SWD_OUTPUT_CURRENT_LIMITER_WARNING_STATUS = 0x04;
+ static constexpr uint8_t R0B_SWA_OUTPUT_UNDER_VOLTAGE_LOCKOUT_STATUS = 0x03;
+ static constexpr uint8_t R0B_SWB_OUTPUT_UNDER_VOLTAGE_LOCKOUT_STATUS = 0x02;
+ static constexpr uint8_t R0B_SWC_OUTPUT_UNDER_VOLTAGE_LOCKOUT_STATUS = 0x01;
+ static constexpr uint8_t R0B_SWD_OUTPUT_UNDER_VOLTAGE_LOCKOUT_STATUS = 0x00;
+
+ // R14
+ static constexpr uint8_t R14_GLOBAL_CLEAR_STATUS = 0x00;
+
+ // R1A
+ static constexpr uint8_t R1A_OUTPUT_POWER_SELECT = 0x01;
+
+ // R1B
+ static constexpr uint8_t R1B_CURRENT_OR_POWER_METER_SELECT = 0x06;
+
+ // R1C/R1D/R1E/R1F - bit positions flipped (0 is for bit7, 1 is for bit6, etc)
+ static constexpr uint8_t HIGH_CURRENT_WARNING_START = 0x00;
+ static constexpr uint8_t HIGH_CURRENT_WARNING_LENGTH = 0x06;
+
+ // R20 - bit positions flipped (0 is for bit7, 1 is for bit6, etc)
+ static constexpr uint8_t R20_SWA_OUTPUT_CURRENT_LIMITER_WARNING_THRESHOLD_SETTING_START = 0x00;
+ static constexpr uint8_t R20_SWB_OUTPUT_CURRENT_LIMITER_WARNING_THRESHOLD_SETTING_START = 0x02;
+ static constexpr uint8_t R20_SWC_OUTPUT_CURRENT_LIMITER_WARNING_THRESHOLD_SETTING_START = 0x04;
+ static constexpr uint8_t R20_SWD_OUTPUT_CURRENT_LIMITER_WARNING_THRESHOLD_SETTING_START = 0x06;
+ static constexpr uint8_t R20_OUTPUT_CURRENT_LIMITER_WARNING_THRESHOLD_SETTING_LENGTH = 0x02;
+
+ // R2B - bit positions flipped (0 is for bit7, 1 is for bit6, etc)
+ static constexpr uint8_t R2B_LDO_1P8_VOLT_SETTING_START = 0x00;
+ static constexpr uint8_t R2B_LDO_1P8_VOLT_SETTING_LENGTH = 0x02;
+ static constexpr uint8_t R2B_LDO_1P1_VOLT_SETTING_START = 0x05;
+ static constexpr uint8_t R2B_LDO_1P1_VOLT_SETTING_LENGTH = 0x02;
+
+ // R2F
+ static constexpr uint8_t R2F_SWA_REGULATOR_CONTROL = 0x06;
+ static constexpr uint8_t R2F_SWB_REGULATOR_CONTROL = 0x05;
+ static constexpr uint8_t R2F_SWC_REGULATOR_CONTROL = 0x04;
+ static constexpr uint8_t R2F_SWD_REGULATOR_CONTROL = 0x03;
+
+ // R3B
+ static constexpr uint8_t R3B_PMIC_CURRENT_CAPABILITY = 0x00;
+
+ // R4F
+ static constexpr uint8_t R4F_SWA_SWB_PHASE_MODE_SELECT = 0x00;
+
+ // R30 - bit positions flipped (0 is for bit7, 1 is for bit6, etc)
+ static constexpr uint8_t R30_ADC_ENABLE = 0x00;
+ static constexpr uint8_t R30_ADC_SELECT_START = 0x01;
+ static constexpr uint8_t R30_ADC_SELECT_LENGTH = 0x04;
+
+ // R31 - bit positions flipped (0 is for bit7, 1 is for bit6, etc)
+ static constexpr uint8_t R31_ADC_READ_SETTING_START = 0x00;
+ static constexpr uint8_t R31_ADC_READ_SETTING_LENGTH = 0x08;
+
+ // R33 - bit positions flipped (0 is for bit7, 1 is for bit6, etc)
+ static constexpr uint8_t R33_TEMPERATURE_SETTING_START = 0x00;
+ static constexpr uint8_t R33_TEMPERATURE_SETTING_LENGTH = 0x03;
+
+ static constexpr uint8_t DELAY_FLD_LENGTH = 3;
+ static constexpr uint8_t VOLTAGE_SETTING_START = 0;
+ static constexpr uint8_t VOLTAGE_SETTING_LENGTH = 7;
+
+};
+
+#endif
diff --git a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_attr_engine_traits.H b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_attr_engine_traits.H
new file mode 100644
index 000000000..ebee62c53
--- /dev/null
+++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_attr_engine_traits.H
@@ -0,0 +1,2486 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_attr_engine_traits.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file pmic_attr_engine_traits.H
+/// @brief Trait class definitions for pmic attrs
+///
+
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP FW Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB:CI
+
+#ifndef _MSS_PMIC_ATTR_ENGINE_TRAITS_H_
+#define _MSS_PMIC_ATTR_ENGINE_TRAITS_H_
+
+#include <fapi2.H>
+#include <lib/utils/pmic_consts.H>
+#include <lib/eff_config/pmic_efd_processing.H>
+#include <generic/memory/lib/data_engine/data_engine_traits_def.H>
+#include <generic/memory/lib/data_engine/data_engine.H>
+#include <generic/memory/lib/spd/spd_facade.H>
+#include <lib/mss_pmic_attribute_getters.H>
+#include <lib/mss_pmic_attribute_setters.H>
+
+namespace mss
+{
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, ATTR_EFF_BASE_CASE partial specialization
+/// NOP for base case needed to trigger partial specialization of attr_engine
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::ATTR_EFF_BASE_CASE> {};
+
+
+//----------------------------------------
+// PMIC 0
+//----------------------------------------
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_MFG_ID partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_MFG_ID>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_MFG_ID_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_MFG_ID_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_MFG_ID;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_mfg_id(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_mfg_id(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.mfg_id_pmic0(o_setting);
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWA_VOLTAGE_SETTING partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWA_VOLTAGE_SETTING>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWA_VOLTAGE_SETTING_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWA_VOLTAGE_SETTING_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWA_VOLTAGE_SETTING;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swa_voltage_setting(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swa_voltage_setting(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_swa_pmic0(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWA_VOLTAGE_RANGE_SELECT partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWA_VOLTAGE_RANGE_SELECT>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWA_VOLTAGE_RANGE_SELECT_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWA_VOLTAGE_RANGE_SELECT_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWA_VOLTAGE_RANGE_SELECT;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swa_voltage_range_select(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swa_voltage_range_select(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_range_swa_pmic0(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWA_VOLTAGE_OFFSET partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWA_VOLTAGE_OFFSET>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWA_VOLTAGE_OFFSET_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWA_VOLTAGE_OFFSET_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWA_VOLTAGE_OFFSET;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swa_voltage_offset(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swa_voltage_offset(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_spd_data.volt_offset_swa_pmic0(l_offset));
+ FAPI_TRY(i_spd_data.volt_offset_direction_swa_pmic0(l_direction));
+
+ o_setting = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWA_SEQUENCE_DELAY partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWA_SEQUENCE_DELAY>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWA_SEQUENCE_DELAY_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWA_SEQUENCE_DELAY_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWA_SEQUENCE_DELAY;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swa_sequence_delay(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swa_sequence_delay(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_delay_swa_pmic0(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWA_SEQUENCE_ORDER partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWA_SEQUENCE_ORDER>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWA_SEQUENCE_ORDER_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWA_SEQUENCE_ORDER_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWA_SEQUENCE_ORDER;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swa_sequence_order(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swa_sequence_order(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_order_swa_pmic0(o_setting);
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWB_VOLTAGE_SETTING partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWB_VOLTAGE_SETTING>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWB_VOLTAGE_SETTING_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWB_VOLTAGE_SETTING_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWB_VOLTAGE_SETTING;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swb_voltage_setting(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swb_voltage_setting(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_swb_pmic0(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWB_VOLTAGE_RANGE_SELECT partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWB_VOLTAGE_RANGE_SELECT>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWB_VOLTAGE_RANGE_SELECT_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWB_VOLTAGE_RANGE_SELECT_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWB_VOLTAGE_RANGE_SELECT;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swb_voltage_range_select(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swb_voltage_range_select(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_range_swb_pmic0(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWB_VOLTAGE_OFFSET partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWB_VOLTAGE_OFFSET>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWB_VOLTAGE_OFFSET_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWB_VOLTAGE_OFFSET_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWB_VOLTAGE_OFFSET;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swb_voltage_offset(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swb_voltage_offset(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_spd_data.volt_offset_swb_pmic0(l_offset));
+ FAPI_TRY(i_spd_data.volt_offset_direction_swb_pmic0(l_direction));
+
+ o_setting = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWB_SEQUENCE_DELAY partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWB_SEQUENCE_DELAY>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWB_SEQUENCE_DELAY_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWB_SEQUENCE_DELAY_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWB_SEQUENCE_DELAY;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swb_sequence_delay(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swb_sequence_delay(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_delay_swb_pmic0(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWB_SEQUENCE_ORDER partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWB_SEQUENCE_ORDER>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWB_SEQUENCE_ORDER_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWB_SEQUENCE_ORDER_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWB_SEQUENCE_ORDER;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swb_sequence_order(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swb_sequence_order(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_order_swb_pmic0(o_setting);
+ }
+};
+
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWC_VOLTAGE_SETTING partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWC_VOLTAGE_SETTING>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWC_VOLTAGE_SETTING_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWC_VOLTAGE_SETTING_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWC_VOLTAGE_SETTING;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swc_voltage_setting(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swc_voltage_setting(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_swc_pmic0(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWC_VOLTAGE_RANGE_SELECT partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWC_VOLTAGE_RANGE_SELECT>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWC_VOLTAGE_RANGE_SELECT_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWC_VOLTAGE_RANGE_SELECT_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWC_VOLTAGE_RANGE_SELECT;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swc_voltage_range_select(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swc_voltage_range_select(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_range_swc_pmic0(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWC_VOLTAGE_OFFSET partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWC_VOLTAGE_OFFSET>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWC_VOLTAGE_OFFSET_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWC_VOLTAGE_OFFSET_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWC_VOLTAGE_OFFSET;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swc_voltage_offset(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swc_voltage_offset(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_spd_data.volt_offset_swc_pmic0(l_offset));
+ FAPI_TRY(i_spd_data.volt_offset_direction_swc_pmic0(l_direction));
+
+ o_setting = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWC_SEQUENCE_DELAY partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWC_SEQUENCE_DELAY>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWC_SEQUENCE_DELAY_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWC_SEQUENCE_DELAY_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWC_SEQUENCE_DELAY;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swc_sequence_delay(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swc_sequence_delay(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_delay_swc_pmic0(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWC_SEQUENCE_ORDER partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWC_SEQUENCE_ORDER>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWC_SEQUENCE_ORDER_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWC_SEQUENCE_ORDER_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWC_SEQUENCE_ORDER;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swc_sequence_order(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swc_sequence_order(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_order_swc_pmic0(o_setting);
+ }
+};
+
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWD_VOLTAGE_SETTING partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWD_VOLTAGE_SETTING>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWD_VOLTAGE_SETTING_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWD_VOLTAGE_SETTING_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWD_VOLTAGE_SETTING;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swd_voltage_setting(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swd_voltage_setting(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_swd_pmic0(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWD_VOLTAGE_RANGE_SELECT partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWD_VOLTAGE_RANGE_SELECT>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWD_VOLTAGE_RANGE_SELECT_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWD_VOLTAGE_RANGE_SELECT_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWD_VOLTAGE_RANGE_SELECT;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swd_voltage_range_select(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swd_voltage_range_select(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_range_swd_pmic0(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWD_VOLTAGE_OFFSET partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWD_VOLTAGE_OFFSET>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWD_VOLTAGE_OFFSET_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWD_VOLTAGE_OFFSET_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWD_VOLTAGE_OFFSET;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swd_voltage_offset(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swd_voltage_offset(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_spd_data.volt_offset_swd_pmic0(l_offset));
+ FAPI_TRY(i_spd_data.volt_offset_direction_swd_pmic0(l_direction));
+
+ o_setting = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWD_SEQUENCE_DELAY partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWD_SEQUENCE_DELAY>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWD_SEQUENCE_DELAY_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWD_SEQUENCE_DELAY_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWD_SEQUENCE_DELAY;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swd_sequence_delay(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swd_sequence_delay(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_delay_swd_pmic0(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SWD_SEQUENCE_ORDER partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SWD_SEQUENCE_ORDER>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SWD_SEQUENCE_ORDER_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SWD_SEQUENCE_ORDER_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SWD_SEQUENCE_ORDER;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_swd_sequence_order(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_swd_sequence_order(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_order_swd_pmic0(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_PHASE_COMB partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_PHASE_COMB>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_PHASE_COMB_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_PHASE_COMB_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_PHASE_COMB;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_phase_comb(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_phase_comb(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.phase_combination_pmic0(o_setting);
+ }
+};
+
+
+//----------------------------------------
+// PMIC 1
+//----------------------------------------
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_MFG_ID partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_MFG_ID>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_MFG_ID_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_MFG_ID_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_MFG_ID;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_mfg_id(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_mfg_id(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.mfg_id_pmic1(o_setting);
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWA_VOLTAGE_SETTING partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWA_VOLTAGE_SETTING>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWA_VOLTAGE_SETTING_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWA_VOLTAGE_SETTING_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWA_VOLTAGE_SETTING;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swa_voltage_setting(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swa_voltage_setting(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_swa_pmic1(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWA_VOLTAGE_RANGE_SELECT partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWA_VOLTAGE_RANGE_SELECT>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWA_VOLTAGE_RANGE_SELECT_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWA_VOLTAGE_RANGE_SELECT_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWA_VOLTAGE_RANGE_SELECT;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swa_voltage_range_select(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swa_voltage_range_select(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_range_swa_pmic1(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWA_VOLTAGE_OFFSET partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWA_VOLTAGE_OFFSET>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWA_VOLTAGE_OFFSET_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWA_VOLTAGE_OFFSET_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWA_VOLTAGE_OFFSET;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swa_voltage_offset(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swa_voltage_offset(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_spd_data.volt_offset_swa_pmic1(l_offset));
+ FAPI_TRY(i_spd_data.volt_offset_direction_swa_pmic1(l_direction));
+
+ o_setting = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWA_SEQUENCE_DELAY partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWA_SEQUENCE_DELAY>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWA_SEQUENCE_DELAY_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWA_SEQUENCE_DELAY_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWA_SEQUENCE_DELAY;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swa_sequence_delay(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swa_sequence_delay(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_delay_swa_pmic1(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWA_SEQUENCE_ORDER partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWA_SEQUENCE_ORDER>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWA_SEQUENCE_ORDER_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWA_SEQUENCE_ORDER_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWA_SEQUENCE_ORDER;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swa_sequence_order(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swa_sequence_order(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_order_swa_pmic1(o_setting);
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWB_VOLTAGE_SETTING partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWB_VOLTAGE_SETTING>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWB_VOLTAGE_SETTING_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWB_VOLTAGE_SETTING_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWB_VOLTAGE_SETTING;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swb_voltage_setting(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swb_voltage_setting(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_swb_pmic1(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWB_VOLTAGE_RANGE_SELECT partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWB_VOLTAGE_RANGE_SELECT>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWB_VOLTAGE_RANGE_SELECT_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWB_VOLTAGE_RANGE_SELECT_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWB_VOLTAGE_RANGE_SELECT;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swb_voltage_range_select(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swb_voltage_range_select(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_range_swb_pmic1(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWB_VOLTAGE_OFFSET partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWB_VOLTAGE_OFFSET>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWB_VOLTAGE_OFFSET_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWB_VOLTAGE_OFFSET_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWB_VOLTAGE_OFFSET;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swb_voltage_offset(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swb_voltage_offset(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_spd_data.volt_offset_swb_pmic1(l_offset));
+ FAPI_TRY(i_spd_data.volt_offset_direction_swb_pmic1(l_direction));
+
+ o_setting = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWB_SEQUENCE_DELAY partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWB_SEQUENCE_DELAY>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWB_SEQUENCE_DELAY_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWB_SEQUENCE_DELAY_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWB_SEQUENCE_DELAY;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swb_sequence_delay(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swb_sequence_delay(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_delay_swb_pmic1(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWB_SEQUENCE_ORDER partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWB_SEQUENCE_ORDER>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWB_SEQUENCE_ORDER_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWB_SEQUENCE_ORDER_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWB_SEQUENCE_ORDER;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swb_sequence_order(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swb_sequence_order(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_order_swb_pmic1(o_setting);
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWC_VOLTAGE_SETTING partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWC_VOLTAGE_SETTING>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWC_VOLTAGE_SETTING_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWC_VOLTAGE_SETTING_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWC_VOLTAGE_SETTING;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swc_voltage_setting(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swc_voltage_setting(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_swc_pmic1(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWC_VOLTAGE_RANGE_SELECT partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWC_VOLTAGE_RANGE_SELECT>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWC_VOLTAGE_RANGE_SELECT_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWC_VOLTAGE_RANGE_SELECT_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWC_VOLTAGE_RANGE_SELECT;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swc_voltage_range_select(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swc_voltage_range_select(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_range_swc_pmic1(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWC_VOLTAGE_OFFSET partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWC_VOLTAGE_OFFSET>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWC_VOLTAGE_OFFSET_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWC_VOLTAGE_OFFSET_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWC_VOLTAGE_OFFSET;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swc_voltage_offset(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swc_voltage_offset(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_spd_data.volt_offset_swc_pmic1(l_offset));
+ FAPI_TRY(i_spd_data.volt_offset_direction_swc_pmic1(l_direction));
+
+ o_setting = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWC_SEQUENCE_DELAY partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWC_SEQUENCE_DELAY>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWC_SEQUENCE_DELAY_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWC_SEQUENCE_DELAY_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWC_SEQUENCE_DELAY;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swc_sequence_delay(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swc_sequence_delay(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_delay_swc_pmic1(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWC_SEQUENCE_ORDER partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWC_SEQUENCE_ORDER>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWC_SEQUENCE_ORDER_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWC_SEQUENCE_ORDER_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWC_SEQUENCE_ORDER;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swc_sequence_order(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swc_sequence_order(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_order_swc_pmic1(o_setting);
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWD_VOLTAGE_SETTING partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWD_VOLTAGE_SETTING>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWD_VOLTAGE_SETTING_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWD_VOLTAGE_SETTING_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWD_VOLTAGE_SETTING;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swd_voltage_setting(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swd_voltage_setting(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_swd_pmic1(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWD_VOLTAGE_RANGE_SELECT partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWD_VOLTAGE_RANGE_SELECT>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWD_VOLTAGE_RANGE_SELECT_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWD_VOLTAGE_RANGE_SELECT_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWD_VOLTAGE_RANGE_SELECT;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swd_voltage_range_select(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swd_voltage_range_select(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_setpoint_range_swd_pmic1(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWD_VOLTAGE_OFFSET partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWD_VOLTAGE_OFFSET>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWD_VOLTAGE_OFFSET_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWD_VOLTAGE_OFFSET_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWD_VOLTAGE_OFFSET;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swd_voltage_offset(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swd_voltage_offset(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_spd_data.volt_offset_swd_pmic1(l_offset));
+ FAPI_TRY(i_spd_data.volt_offset_direction_swd_pmic1(l_direction));
+
+ o_setting = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWD_SEQUENCE_DELAY partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWD_SEQUENCE_DELAY>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWD_SEQUENCE_DELAY_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWD_SEQUENCE_DELAY_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWD_SEQUENCE_DELAY;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swd_sequence_delay(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swd_sequence_delay(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_delay_swd_pmic1(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SWD_SEQUENCE_ORDER partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SWD_SEQUENCE_ORDER>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SWD_SEQUENCE_ORDER_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SWD_SEQUENCE_ORDER_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SWD_SEQUENCE_ORDER;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_swd_sequence_order(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_swd_sequence_order(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.volt_order_swd_pmic1(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_PHASE_COMB partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_PHASE_COMB>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_PHASE_COMB_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_PHASE_COMB_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_PHASE_COMB;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_phase_comb(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_phase_comb(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.phase_combination_pmic1(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC0_SEQUENCE partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC0_SEQUENCE>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC0_SEQUENCE_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC0_SEQUENCE_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC0_SEQUENCE;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic0_sequence(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic0_sequence(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.sequence_pmic0(o_setting);
+ }
+};
+
+//
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note P, pmic::attr_eff_engine_fields, PMIC1_SEQUENCE partial specialization
+///
+template< proc_type P>
+struct attrEngineTraits<P, pmic::attr_eff_engine_fields, pmic::attr_eff_engine_fields::PMIC1_SEQUENCE>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PMIC1_SEQUENCE_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PMIC1_SEQUENCE_TargetType;
+ static constexpr pmic::ffdc_codes FFDC_CODE = pmic::SET_PMIC1_SEQUENCE;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return attr::get_pmic1_sequence(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return attr::set_pmic1_sequence(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.sequence_pmic1(o_setting);
+ }
+};
+
+}//mss
+
+#endif
diff --git a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_efd_processing.C b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_efd_processing.C
new file mode 100644
index 000000000..32e3157cb
--- /dev/null
+++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_efd_processing.C
@@ -0,0 +1,274 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_efd_processing.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file pmic_efd_processing.C
+/// @brief Processing for EFD for eff config
+///
+
+// *HWP HWP Owner: Mark Pizzutillo Mark.Pizzutillo@ibm.com>
+// *HWP FW Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB:CI
+
+#include <fapi2.H>
+#include <lib/mss_pmic_attribute_setters.H>
+#include <lib/eff_config/pmic_efd_processing.H>
+#include <lib/utils/pmic_consts.H>
+#include <lib/utils/pmic_common_utils.H>
+
+namespace mss
+{
+namespace pmic
+{
+
+///
+/// @brief Convert unsigned offset from SPD to signed offset for attributes
+///
+/// @param[in] i_offset - unsigned offset
+/// @param[in] i_direction - direction
+/// @return int8_t signed equivalent
+/// @note Should be used with SPD data where the offset is 7 bits such that overflow could not be possible
+///
+int8_t convert_to_signed_offset(const uint8_t i_offset, const uint8_t i_direction)
+{
+ // Since offset value must be 7 bits (from SPD), we can directly cast it to an int8_t
+ int8_t l_signed_offset = static_cast<int8_t>(i_offset);
+
+ if (i_direction == CONSTS::OFFSET_MINUS)
+ {
+ // Can't overflow since signed_offset was only 7 bits
+ l_signed_offset = 0 - l_signed_offset;
+ }
+
+ return l_signed_offset;
+}
+
+namespace efd
+{
+
+using CONSTS = mss::pmic::consts<mss::pmic::product::JEDEC_COMPLIANT>;
+///
+/// @brief Processes the EFD PMIC0 SWA Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic0_swa_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_efd_data->pmic0_swa_offset(l_offset));
+ FAPI_TRY(i_efd_data->pmic0_swa_offset_direction(l_direction));
+ {
+ int8_t l_signed_offset = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+ FAPI_TRY(mss::attr::set_efd_pmic0_swa_voltage_offset(i_target, l_signed_offset));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Processes the EFD PMIC0 SWB Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic0_swb_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_efd_data->pmic0_swb_offset(l_offset));
+ FAPI_TRY(i_efd_data->pmic0_swb_offset_direction(l_offset));
+ {
+ int8_t l_signed_offset = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+ FAPI_TRY(mss::attr::set_efd_pmic0_swb_voltage_offset(i_target, l_signed_offset));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Processes the EFD PMIC0 SWC Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic0_swc_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_efd_data->pmic0_swc_offset(l_offset));
+ FAPI_TRY(i_efd_data->pmic0_swc_offset_direction(l_offset));
+ {
+ int8_t l_signed_offset = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+ FAPI_TRY(mss::attr::set_efd_pmic0_swc_voltage_offset(i_target, l_signed_offset));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Processes the EFD PMIC0 SWD Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic0_swd_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_efd_data->pmic0_swd_offset(l_offset));
+ FAPI_TRY(i_efd_data->pmic0_swd_offset_direction(l_offset));
+ {
+ int8_t l_signed_offset = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+ FAPI_TRY(mss::attr::set_efd_pmic0_swd_voltage_offset(i_target, l_signed_offset));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Processes the EFD PMIC1 SWA Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic1_swa_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_efd_data->pmic1_swa_offset(l_offset));
+ FAPI_TRY(i_efd_data->pmic1_swa_offset_direction(l_offset));
+ {
+ int8_t l_signed_offset = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+ FAPI_TRY(mss::attr::set_efd_pmic1_swa_voltage_offset(i_target, l_signed_offset));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Processes the EFD PMIC1 SWB Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic1_swb_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_efd_data->pmic1_swb_offset(l_offset));
+ FAPI_TRY(i_efd_data->pmic1_swb_offset_direction(l_offset));
+ {
+ int8_t l_signed_offset = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+ FAPI_TRY(mss::attr::set_efd_pmic1_swb_voltage_offset(i_target, l_signed_offset));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Processes the EFD PMIC1 SWC Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic1_swc_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_efd_data->pmic1_swc_offset(l_offset));
+ FAPI_TRY(i_efd_data->pmic1_swc_offset_direction(l_offset));
+ {
+ int8_t l_signed_offset = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+ FAPI_TRY(mss::attr::set_efd_pmic1_swc_voltage_offset(i_target, l_signed_offset));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Processes the EFD PMIC1 SWD Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic1_swd_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ uint8_t l_offset = 0;
+ uint8_t l_direction = 0;
+ FAPI_TRY(i_efd_data->pmic1_swd_offset(l_offset));
+ FAPI_TRY(i_efd_data->pmic1_swd_offset_direction(l_offset));
+ {
+ int8_t l_signed_offset = mss::pmic::convert_to_signed_offset(l_offset, l_direction);
+ FAPI_TRY(mss::attr::set_efd_pmic1_swd_voltage_offset(i_target, l_signed_offset));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Process the EFD data and set attributes
+/// @param[in] i_target DIMM target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode process(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ FAPI_TRY(pmic0_swa_voltage_offset(i_target, i_efd_data));
+ FAPI_TRY(pmic0_swb_voltage_offset(i_target, i_efd_data));
+ FAPI_TRY(pmic0_swc_voltage_offset(i_target, i_efd_data));
+ FAPI_TRY(pmic0_swd_voltage_offset(i_target, i_efd_data));
+
+ FAPI_TRY(pmic1_swa_voltage_offset(i_target, i_efd_data));
+ FAPI_TRY(pmic1_swb_voltage_offset(i_target, i_efd_data));
+ FAPI_TRY(pmic1_swc_voltage_offset(i_target, i_efd_data));
+ FAPI_TRY(pmic1_swd_voltage_offset(i_target, i_efd_data));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // efd
+} // pmic
+} // mss
diff --git a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_efd_processing.H b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_efd_processing.H
new file mode 100644
index 000000000..e09d8087f
--- /dev/null
+++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_efd_processing.H
@@ -0,0 +1,144 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/common/procedures/hwp/pmic/lib/eff_config/pmic_efd_processing.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file pmic_efd_processing.H
+/// @brief Processing for EFD for eff config
+///
+
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP FW Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB:CI
+
+#ifndef _MSS_PMIC_EFD_PROCESSING_H_
+#define _MSS_PMIC_EFD_PROCESSING_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/spd/ddimm/efd_decoder.H>
+
+namespace mss
+{
+namespace pmic
+{
+
+///
+/// @brief Convert unsigned offset from SPD to signed offset for attributes
+///
+/// @param[in] i_offset - unsigned offset
+/// @param[in] i_direction - direction
+/// @return int8_t signed equivalent
+/// @note Should be used with SPD data where the offset is 7 bits such that overflow could not be possible
+///
+int8_t convert_to_signed_offset(const uint8_t i_offset, const uint8_t i_direction);
+
+namespace efd
+{
+
+///
+/// @brief Processes the EFD PMIC0 SWA Voltage Offset & Direction
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic0_swa_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Processes the EFD PMIC0 SWB Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic0_swb_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Processes the EFD PMIC0 SWC Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic0_swc_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Processes the EFD PMIC0 SWD Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic0_swd_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Processes the EFD PMIC1 SWA Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic1_swa_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Processes the EFD PMIC1 SWB Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic1_swb_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Processes the EFD PMIC1 SWC Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic1_swc_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Processes the EFD PMIC1 SWD Voltage Offset
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode pmic1_swd_voltage_offset(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Process the EFD data and set attributes
+/// @param[in] i_target DIMM target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode process(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+} // ns efd
+} // ns exp
+} // ns mss
+#endif
diff --git a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/i2c/i2c_pmic.H b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/i2c/i2c_pmic.H
new file mode 100644
index 000000000..fcd79dec0
--- /dev/null
+++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/i2c/i2c_pmic.H
@@ -0,0 +1,159 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/common/procedures/hwp/pmic/lib/i2c/i2c_pmic.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file pmic_i2c.H
+/// @brief PMIC I2C utility function declarations
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP HWP Backup: Andre A. Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_I2C_PMIC_H_
+#define _MSS_I2C_PMIC_H_
+
+#include <fapi2.H>
+#include <i2c_access.H>
+
+#include <vector>
+#include <lib/utils/pmic_consts.H>
+#include <generic/memory/lib/utils/pos.H>
+#include <generic/memory/lib/utils/c_str.H>
+
+namespace mss
+{
+namespace pmic
+{
+namespace i2c
+{
+
+///
+/// @brief Perform a register write operation on the given PMIC chip
+/// @param[in] i_target the PMIC target
+/// @param[in] i_addr address to write to
+/// @param[in] i_data_buffer buffer of data to write to the register
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+inline fapi2::ReturnCode reg_write(const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_target,
+ const uint8_t i_addr,
+ const fapi2::buffer<uint8_t>& i_data_buffer)
+{
+ std::vector<uint8_t> l_command;
+ l_command.push_back(i_addr);
+ l_command.push_back(uint8_t(i_data_buffer));
+
+ // Use fapi2 putI2c interface to execute command
+ FAPI_TRY(fapi2::putI2c(i_target, l_command),
+ "putI2C returned error for WRITE operation to 0x%.8X on PMIC %s",
+ i_addr, mss::c_str(i_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Perform a register read operation on the given PMIC chip
+/// @param[in] i_target the PMIC target
+/// @param[in] i_addr address to read
+/// @param[out] o_data_buffer buffer of data we will write the contents of the register to
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+inline fapi2::ReturnCode reg_read(const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_target,
+ const uint8_t i_addr,
+ fapi2::buffer<uint8_t>& o_data_buffer)
+{
+ std::vector<uint8_t> l_data;
+ std::vector<uint8_t> l_command;
+ l_command.push_back(i_addr);
+
+ FAPI_TRY(fapi2::getI2c(i_target, mss::pmic::i2c::sizes::DATA_LENGTH, l_command, l_data),
+ "i2C read failed on %s for address 0x%8x", mss::c_str(i_target), i_addr);
+
+ // Flush o_data_buffer to avoid stale data
+ o_data_buffer.flush<0>();
+
+ FAPI_ASSERT( (l_data.size() == mss::pmic::i2c::sizes::DATA_LENGTH),
+ fapi2::I2C_PMIC_INVALID_READ_SIZE()
+ .set_TARGET(i_target)
+ .set_ADDRESS(i_addr)
+ .set_SIZE_REQUESTED(mss::pmic::i2c::sizes::DATA_LENGTH)
+ .set_SIZE_RETURNED(l_data.size()),
+ "PMIC I2C read returned vector size of %u. Expected %u",
+ l_data.size(), mss::pmic::i2c::sizes::DATA_LENGTH,
+ mss::c_str(i_target) );
+
+ o_data_buffer = l_data[0];
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Perform a register write operation after flipping the data buffer
+/// @param[in] i_target the PMIC target
+/// @param[in] i_addr address to write to
+/// @param[in] i_data_buffer buffer of data to flip & write to the register
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note flips buffer from fapi2-style [0:7] to PMIC-style [7:0]
+///
+inline fapi2::ReturnCode reg_write_reverse_buffer(const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_target,
+ const uint8_t i_addr,
+ const fapi2::buffer<uint8_t>& i_data_buffer)
+{
+ // Copy as to not modify original referenced buffer
+ auto l_reg_buffer_copy = i_data_buffer;
+ l_reg_buffer_copy.reverse();
+
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_target, i_addr, l_reg_buffer_copy));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Perform a register read operation on the given PMIC chip, then flip the data buffer
+/// @param[in] i_target the PMIC target
+/// @param[in] i_addr address to read
+/// @param[out] o_data_buffer buffer of data we will write the contents of the register to
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note flips buffer from PMIC-style [7:0], to fapi2-style [0:7]
+///
+inline fapi2::ReturnCode reg_read_reverse_buffer(const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_target,
+ const uint8_t i_addr,
+ fapi2::buffer<uint8_t>& o_data_buffer)
+{
+ FAPI_TRY(mss::pmic::i2c::reg_read(i_target, i_addr, o_data_buffer));
+ o_data_buffer.reverse();
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // i2c
+} // pmic
+} // mss
+
+#endif
diff --git a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_common_utils.C b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_common_utils.C
new file mode 100644
index 000000000..f89559dde
--- /dev/null
+++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_common_utils.C
@@ -0,0 +1,390 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_common_utils.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+
+///
+/// @file pmic_common_utils.C
+/// @brief Utility functions common for several PMIC procedures
+///
+// *HWP HWP Owner: Mark Pizzutillo <mark.pizzutillo@ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include <pmic_regs.H>
+#include <pmic_regs_fld.H>
+#include <lib/i2c/i2c_pmic.H>
+#include <lib/utils/pmic_consts.H>
+#include <lib/utils/pmic_common_utils.H>
+#include <generic/memory/lib/utils/poll.H>
+#include <generic/memory/lib/utils/c_str.H>
+
+namespace mss
+{
+namespace pmic
+{
+
+///
+/// @brief polls PMIC for PBULK PWR_GOOD status
+///
+/// @param[in] i_pmic_target PMIC target
+/// @return fapi2::ReturnCode success if good, error if polling fail or power not good
+///
+fapi2::ReturnCode poll_for_pbulk_good(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target)
+{
+ static constexpr auto J = mss::pmic::product::JEDEC_COMPLIANT;
+ using REGS = pmicRegs<J>;
+ using FIELDS = pmicFields<J>;
+
+ // Using default poll parameters
+ mss::poll_parameters l_poll_params;
+
+ FAPI_ASSERT( mss::poll(i_pmic_target, l_poll_params, [&i_pmic_target]()->bool
+ {
+ fapi2::buffer<uint8_t> l_pbulk_status_buffer;
+
+ FAPI_TRY(mss::pmic::i2c::reg_read_reverse_buffer(i_pmic_target, REGS::R08, l_pbulk_status_buffer),
+ "pmic_enable: Could not read 0x%02hhX on %s ", REGS::R08, mss::c_str(i_pmic_target));
+
+ return l_pbulk_status_buffer.getBit<FIELDS::R08_VIN_BULK_INPUT_PWR_GOOD_STATUS>() ==
+ mss::pmic::consts<mss::pmic::product::JEDEC_COMPLIANT>::PWR_GOOD;
+
+ fapi_try_exit:
+ // No ack, return false and continue polling
+ return false;
+ }),
+ fapi2::MSS_EXP_I2C_POLLING_TIMEOUT().
+ set_TARGET(i_pmic_target),
+ "I2C read from %s either did not ACK or VIN_BULK did not respond with PWR_GOOD status",
+ mss::c_str(i_pmic_target) );
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Unlocks PMIC vendor region
+///
+/// @param[in] i_pmic_target JEDEC-COMPLIANT PMIC to unlock
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode unlock_vendor_region(const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target)
+{
+ using REGS = pmicRegs<mss::pmic::product::JEDEC_COMPLIANT>;
+ using CONSTS = mss::pmic::consts<mss::pmic::product::JEDEC_COMPLIANT>;
+
+ // Unlock
+ const fapi2::buffer<uint8_t> l_password_low(CONSTS::VENDOR_PASSWORD_LOW);
+ const fapi2::buffer<uint8_t> l_password_high(CONSTS::VENDOR_PASSWORD_HIGH);
+ const fapi2::buffer<uint8_t> l_unlock_code(CONSTS::UNLOCK_VENDOR_REGION);
+
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, REGS::R37_PASSWORD_LOWER_BYTE_0, l_password_low));
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, REGS::R38_PASSWORD_UPPER_BYTE_1, l_password_high));
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, REGS::R39_COMMAND_CODES, l_unlock_code));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Locks PMIC vendor region
+///
+/// @param[in] i_pmic_target - JEDEC-COMPLIANT PMIC to lock
+/// @param[in] i_rc - return code from the end of the caller function (if applicable)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff i_rc == SUCCESS && no errors in unlocking, else return current_err
+///
+fapi2::ReturnCode lock_vendor_region(const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::ReturnCode i_rc)
+{
+ using REGS = pmicRegs<mss::pmic::product::JEDEC_COMPLIANT>;
+ using CONSTS = mss::pmic::consts<mss::pmic::product::JEDEC_COMPLIANT>;
+
+ // Lock vendor region, password registers are cleared automatically
+ const fapi2::buffer<uint8_t> l_lock_code(CONSTS::LOCK_VENDOR_REGION);
+ const fapi2::buffer<uint8_t> l_zero_code(0);
+
+ fapi2::ReturnCode l_lock_return_code = fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, REGS::R39_COMMAND_CODES, l_lock_code));
+
+ return i_rc;
+
+fapi_try_exit:
+ // Since we could have 2 possible errors at the same time here, we are letting the caller's i_rc take precedence.
+ // So, if we find an error while locking, we will report it here. We will only "return" this error if the
+ // caller's error is success, as to not overwrite it.
+ FAPI_ERR("Error code 0x%0llx: Error while trying to lock vendor region", uint64_t(fapi2::current_err));
+ return ((i_rc == fapi2::FAPI2_RC_SUCCESS) ? fapi2::current_err : i_rc);
+}
+
+///
+/// @brief Check if PMIC is IDT vendor
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[out] o_is_idt true/false
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+/// @note Can't unit test this properly as R3D is hardcoded in simics
+///
+fapi2::ReturnCode pmic_is_idt(const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_pmic_target, bool& o_is_idt)
+{
+ o_is_idt = false;
+ using REGS = pmicRegs<mss::pmic::product::JEDEC_COMPLIANT>;
+ fapi2::buffer<uint8_t> l_reg_contents;
+
+ FAPI_TRY(mss::pmic::i2c::reg_read(i_pmic_target, REGS::R3D_VENDOR_ID_BYTE_1, l_reg_contents));
+
+ o_is_idt = (l_reg_contents == mss::pmic::vendor::IDT_SHORT);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Check if PMIC is TI vendor
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[out] o_is_ti true/false
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+/// @note Can't unit test this properly as R3D is hardcoded in simics
+///
+fapi2::ReturnCode pmic_is_ti(const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_pmic_target, bool& o_is_ti)
+{
+ o_is_ti = false;
+ using REGS = pmicRegs<mss::pmic::product::JEDEC_COMPLIANT>;
+ fapi2::buffer<uint8_t> l_reg_contents;
+
+ FAPI_TRY(mss::pmic::i2c::reg_read(i_pmic_target, REGS::R3D_VENDOR_ID_BYTE_1, l_reg_contents));
+
+ o_is_ti = (l_reg_contents == mss::pmic::vendor::TI_SHORT);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+namespace status
+{
+
+///
+/// @brief Checks that the PMIC is enabled via VR Enable bit
+///
+/// @param[in] i_ocmb_target OCMB target
+/// @param[in] i_pmic_target PMIC target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode check_for_vr_enable(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_target,
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target)
+{
+ fapi2::buffer<uint8_t> l_vr_enable_buffer;
+
+ FAPI_TRY(mss::pmic::i2c::reg_read_reverse_buffer(i_pmic_target, REGS::R32, l_vr_enable_buffer),
+ "start_vr_enable: Could not read address 0x%02hhX of %s to check for VR Enable",
+ REGS::R32,
+ mss::c_str(i_pmic_target));
+
+ // Make sure we are enabled
+ FAPI_ASSERT(l_vr_enable_buffer.getBit<FIELDS::R32_VR_ENABLE>(),
+ fapi2::PMIC_NOT_ENABLED()
+ .set_PMIC_TARGET(i_pmic_target)
+ .set_OCMB_TARGET(i_ocmb_target),
+ "PMIC %s was not identified as enabled by checking VR Enable bit",
+ mss::c_str(i_pmic_target));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Check the statuses of all PMICs present on the given OCMB chip
+///
+/// @param[in] i_ocmb_target OCMB target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if success, else error code
+/// @note the returned target is only valid if o_errors returns as true. Else, the target is an uninitialized blank target!
+///
+fapi2::ReturnCode check_all_pmics(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_target)
+{
+ const char* l_ocmb_c_str = mss::c_str(i_ocmb_target);
+
+ // Initialize returnable PMIC with a blank target. This blank target won't be used if there's no error.
+ // If there is an error, this will be overwritten with a valid erroneous PMIC
+ bool l_pmic_error = false;
+
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // Start success so we can't log and return the same error in loop logic
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ // Check that the PMICs are enabled and without errors
+ for (const auto& l_pmic : mss::find_targets<fapi2::TARGET_TYPE_PMIC>(i_ocmb_target))
+ {
+ FAPI_TRY(check_for_vr_enable(i_ocmb_target, l_pmic),
+ "PMIC %s did not return enabled status", mss::c_str(l_pmic));
+
+ FAPI_TRY(mss::pmic::status::check_pmic(l_pmic, l_pmic_error));
+
+ FAPI_ASSERT_NOEXIT(!l_pmic_error,
+ fapi2::PMIC_STATUS_ERRORS()
+ .set_OCMB_TARGET(i_ocmb_target)
+ .set_PMIC_TARGET(l_pmic),
+ "PMIC on OCMB %s had one or more status bits set after running pmic_enable(). "
+ "One of possibly several bad PMICs: %s",
+ l_ocmb_c_str, mss::c_str(l_pmic));
+
+ if (l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ fapi2::logError(fapi2::current_err, fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE);
+ }
+
+ // Reset for next loop
+ l_rc = fapi2::current_err;
+ l_pmic_error = false;
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Else, exit on whatever RC we had
+ FAPI_TRY(l_rc);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Check the PMIC's status codes and report back if an error occurred
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[out] o_error true/false
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error
+///
+fapi2::ReturnCode check_pmic(
+ const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_pmic_target,
+ bool& o_error)
+{
+ o_error = false;
+ bool l_pmic_is_idt = false;
+
+ FAPI_TRY(pmic_is_idt(i_pmic_target, l_pmic_is_idt));
+
+ if (l_pmic_is_idt)
+ {
+ // These registers reflect the previous power down cycle of the PMIC. Therefore, they may
+ // not necessarily cause issues on this life. So, we do not need to worry about keeping track if
+ // these failed with l_status_error, but the check_fields() function will still print them out.
+ bool l_status_error = false;
+
+ // if we exit from this try, there were i2c errors
+ FAPI_TRY(mss::pmic::status::check_fields(i_pmic_target, mss::pmic::status::IDT_SPECIFIC_STATUS_FIELDS, l_status_error));
+ }
+
+ {
+ bool l_status_error = false;
+
+ // if we exit from this try, there were i2c errors
+ FAPI_TRY(mss::pmic::status::check_fields(i_pmic_target, mss::pmic::status::STATUS_FIELDS, l_status_error));
+ o_error = l_status_error;
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Clear PMIC status registers
+///
+/// @param[in] i_pmic_target PMIC to clear
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode clear(const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_pmic_target)
+{
+ using REGS = pmicRegs<mss::pmic::product::JEDEC_COMPLIANT>;
+ using FIELDS = pmicFields<mss::pmic::product::JEDEC_COMPLIANT>;
+
+ fapi2::buffer<uint8_t> l_reg_contents;
+ FAPI_TRY(mss::pmic::i2c::reg_read_reverse_buffer(i_pmic_target, REGS::R14, l_reg_contents));
+
+ // Write to clear
+ l_reg_contents.setBit<FIELDS::R14_GLOBAL_CLEAR_STATUS>();
+ FAPI_TRY(mss::pmic::i2c::reg_write_reverse_buffer(i_pmic_target, REGS::R14, l_reg_contents));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Check an individual set of PMIC status codes
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_statuses STATUS object to check
+/// @param[out] o_error At least one error bit was found to be set
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error in case of an I2C read error
+///
+fapi2::ReturnCode check_fields(
+ const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_pmic_target,
+ const std::vector<std::pair<uint8_t, std::vector<status_field>>>& i_statuses,
+ bool& o_error)
+{
+ o_error = false;
+
+ for (const auto& l_reg_bit_pair : i_statuses)
+ {
+ fapi2::buffer<uint8_t> l_reg_contents;
+ FAPI_TRY(mss::pmic::i2c::reg_read_reverse_buffer(i_pmic_target, l_reg_bit_pair.first, l_reg_contents));
+
+ for (const auto& l_status : l_reg_bit_pair.second)
+ {
+ if (l_reg_contents.getBit(l_status.l_reg_field))
+ {
+ // Print it out
+ FAPI_ERR("%s :: REG 0x%02x bit %u was set on %s",
+ l_status.l_error_description,
+ l_reg_bit_pair.first,
+ l_status.l_reg_field,
+ mss::c_str(i_pmic_target));
+ // We don't want to exit out here, errors can be independent of each other and we should check them all.
+ // Since there's no easy way to FFDC each individual error, we will report them here and then worry about
+ // return codes in the caller of this function
+ o_error = true;
+ }
+ }
+
+ l_reg_contents.flush<0>();
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // status
+} // pmic
+} // mss
diff --git a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_common_utils.H b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_common_utils.H
new file mode 100644
index 000000000..1bc3aea1a
--- /dev/null
+++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_common_utils.H
@@ -0,0 +1,337 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_common_utils.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+
+///
+/// @file pmic_common_utils.H
+/// @brief Utility functions common for several PMIC procedures
+///
+// *HWP HWP Owner: Mark Pizzutillo <mark.pizzutillo@ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: FSP:HB
+
+#ifndef __PMIC_COMMON_UTILS_H__
+#define __PMIC_COMMON_UTILS_H__
+
+#include <fapi2.H>
+#include <pmic_regs.H>
+#include <pmic_regs_fld.H>
+#include <lib/utils/pmic_consts.H>
+#include <mss_pmic_attribute_getters.H>
+#include <generic/memory/lib/utils/find.H>
+
+namespace mss
+{
+namespace pmic
+{
+
+// Attribute getter pointer for manufacturer/vendor ID
+typedef fapi2::ReturnCode (*mfg_id_attr_ptr)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint16_t& o_value);
+
+// Manufacturer / Vendor ID
+static constexpr mfg_id_attr_ptr get_mfg_id[] =
+{
+ mss::attr::get_pmic0_mfg_id,
+ mss::attr::get_pmic1_mfg_id,
+};
+
+using REGS = pmicRegs<mss::pmic::product::JEDEC_COMPLIANT>;
+using FIELDS = pmicFields<mss::pmic::product::JEDEC_COMPLIANT>;
+using CONSTS = mss::pmic::consts<mss::pmic::product::JEDEC_COMPLIANT>;;
+
+// Arrays to easily index common parameters by rail
+static constexpr uint8_t const VOLT_SETTING_ACTIVE_REGS[] =
+{
+ REGS::R21_SWA_VOLTAGE_SETTING,
+ REGS::R23_SWB_VOLTAGE_SETTING,
+ REGS::R25_SWC_VOLTAGE_SETTING,
+ REGS::R27_SWD_VOLTAGE_SETTING,
+};
+
+static constexpr uint8_t const VOLT_SETTING_VENDOR_REGS[] =
+{
+ REGS::R45_SWA_VOLTAGE_SETTING,
+ REGS::R47_SWB_VOLTAGE_SETTING,
+ REGS::R49_SWC_VOLTAGE_SETTING,
+ REGS::R4B_SWD_VOLTAGE_SETTING,
+};
+
+static constexpr uint8_t const VOLT_RANGE_FLDS[] =
+{
+ FIELDS::SWA_VOLTAGE_RANGE,
+ FIELDS::SWB_VOLTAGE_RANGE,
+ FIELDS::SWC_VOLTAGE_RANGE,
+ FIELDS::SWD_VOLTAGE_RANGE,
+};
+
+static constexpr uint32_t const VOLT_RANGE_MINS[][CONSTS::NUM_RANGES] =
+{
+ {CONSTS::SWABC_VOLT_RANGE0_MIN, CONSTS::SWABC_VOLT_RANGE1_MIN},
+ {CONSTS::SWABC_VOLT_RANGE0_MIN, CONSTS::SWABC_VOLT_RANGE1_MIN},
+ {CONSTS::SWABC_VOLT_RANGE0_MIN, CONSTS::SWABC_VOLT_RANGE1_MIN},
+ {CONSTS::SWD_VOLT_RANGE0_MIN, CONSTS::SWD_VOLT_RANGE1_MIN},
+};
+
+static constexpr uint32_t const VOLT_RANGE_MAXES[][CONSTS::NUM_RANGES] =
+{
+ {CONSTS::SWABC_VOLT_RANGE0_MAX, CONSTS::SWABC_VOLT_RANGE1_MAX},
+ {CONSTS::SWABC_VOLT_RANGE0_MAX, CONSTS::SWABC_VOLT_RANGE1_MAX},
+ {CONSTS::SWABC_VOLT_RANGE0_MAX, CONSTS::SWABC_VOLT_RANGE1_MAX},
+ {CONSTS::SWD_VOLT_RANGE0_MAX, CONSTS::SWD_VOLT_RANGE1_MAX},
+};
+
+///
+/// @brief Get the valid pmics for id object
+///
+/// @param[in] i_pmic_target
+/// @param[in] i_id
+/// @param[out] o_pmics vector of PMICS matching
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+inline std::vector<fapi2::Target<fapi2::TARGET_TYPE_PMIC>> get_valid_pmics_for_id(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_target,
+ const mss::pmic::id i_id)
+{
+ using CONSTS = mss::pmic::consts<mss::pmic::product::JEDEC_COMPLIANT>;
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_PMIC>> l_output_pmics;
+
+ const auto l_pmics = mss::find_targets<fapi2::TARGET_TYPE_PMIC>(i_ocmb_target);
+
+ for (const auto& l_pmic : l_pmics)
+ {
+ if (mss::index(l_pmic) % CONSTS::NUM_UNIQUE_PMICS == i_id)
+ {
+ l_output_pmics.push_back(l_pmic);
+ }
+ }
+
+ return l_output_pmics;
+}
+
+///
+/// @brief polls PMIC for PBULK PWR_GOOD status
+///
+/// @param[in] i_pmic_target PMIC target
+/// @return fapi2::ReturnCode success if good, error if polling fail or power not good
+///
+fapi2::ReturnCode poll_for_pbulk_good(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target);
+
+///
+/// @brief Unlocks PMIC vendor region
+///
+/// @param[in] i_pmic_target JEDEC-COMPLIANT PMIC to unlock
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode unlock_vendor_region(const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target);
+
+///
+/// @brief Locks PMIC vendor region
+///
+/// @param[in] i_pmic_target - JEDEC-COMPLIANT PMIC to lock
+/// @param[in] i_rc - return code from the end of the caller function (if applicable)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff i_rc == SUCCESS && no errors in unlocking, else return current_err
+///
+fapi2::ReturnCode lock_vendor_region(const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::ReturnCode i_rc = fapi2::FAPI2_RC_SUCCESS);
+
+///
+/// @brief Check if PMIC is IDT vendor
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[out] o_is_idt true/false
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode pmic_is_idt(const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_pmic_target, bool& o_is_idt);
+
+///
+/// @brief Check if PMIC is TI vendor
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[out] o_is_ti true/false
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode pmic_is_ti(const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_pmic_target, bool& o_is_ti);
+
+namespace status
+{
+
+///
+/// @brief Information for each field that we can iterate through
+///
+struct status_field
+{
+ uint8_t l_reg_field;
+ const char* l_error_description;
+};
+
+static const std::vector<std::pair<uint8_t, std::vector<status_field>>> IDT_SPECIFIC_STATUS_FIELDS =
+{
+ {
+ REGS::R04,
+ { {FIELDS::R04_GLOBAL_ERROR_COUNT, "GLOBAL_ERROR_COUNT: >1 error count since last erase operation"},
+ {FIELDS::R04_GLOBAL_ERROR_LOG_BUCK_OV_OR_UV, "GLOBAL_ERROR_LOG: BUCK OV/UV: Error occurred"},
+ {FIELDS::R04_GLOBAL_ERROR_LOG_VIN_BULK_OVER_VOLTAGE, "GLOBAL_ERROR_LOG: VIN_BULK_OVER_VOLTAGE"},
+ {FIELDS::R04_GLOBAL_ERROR_LOG_CRITICAL_TEMPERATURE, "GLOBAL_ERROR_LOG: CRITICAL_TEMPERATURE"},
+ }
+ },
+
+ {
+ REGS::R05,
+ { {FIELDS::R05_SWA_POWER_GOOD, "PMIC POWER ON: SWA_PWR_NOT_GOOD"},
+ {FIELDS::R05_SWB_POWER_GOOD, "PMIC POWER ON: SWB_PWR_NOT_GOOD"},
+ {FIELDS::R05_SWC_POWER_GOOD, "PMIC POWER ON: SWC_PWR_NOT_GOOD"},
+ {FIELDS::R05_SWD_POWER_GOOD, "PMIC POWER ON: SWD_PWR_NOT_GOOD"},
+ }
+ },
+
+ {
+ REGS::R06,
+ { {FIELDS::R06_SWA_UNDER_VOLTAGE_LOCKOUT, "SWA_UNDER_VOLTAGE_LOCKOUT"},
+ {FIELDS::R06_SWB_UNDER_VOLTAGE_LOCKOUT, "SWB_UNDER_VOLTAGE_LOCKOUT"},
+ {FIELDS::R06_SWC_UNDER_VOLTAGE_LOCKOUT, "SWC_UNDER_VOLTAGE_LOCKOUT"},
+ {FIELDS::R06_SWD_UNDER_VOLTAGE_LOCKOUT, "SWD_UNDER_VOLTAGE_LOCKOUT"},
+ {FIELDS::R06_SWA_OVER_VOLTAGE, "SWA_OVER_VOLTAGE"},
+ {FIELDS::R06_SWB_OVER_VOLTAGE, "SWB_OVER_VOLTAGE"},
+ {FIELDS::R06_SWC_OVER_VOLTAGE, "SWC_OVER_VOLTAGE"},
+ {FIELDS::R06_SWD_OVER_VOLTAGE, "SWD_OVER_VOLTAGE"},
+ }
+ }
+};
+
+///
+/// @brief const vector of statuses to check
+///
+static const std::vector<std::pair<uint8_t, std::vector<status_field>>> STATUS_FIELDS =
+{
+ {
+ REGS::R08,
+ { {FIELDS::R08_VIN_BULK_INPUT_PWR_GOOD_STATUS, "VIN_BULK_INPUT_PWR_NOT_GOOD"},
+ {FIELDS::R08_CRITICAL_TEMP_SHUTDOWN_STATUS, "CRITICAL_TEMP_SHUTDOWN"},
+ {FIELDS::R08_SWA_PWR_GOOD_STATUS, "SWA_PWR_NOT_GOOD"},
+ {FIELDS::R08_SWB_PWR_GOOD_STATUS, "SWB_PWR_NOT_GOOD"},
+ {FIELDS::R08_SWC_PWR_GOOD_STATUS, "SWC_PWR_NOT_GOOD"},
+ {FIELDS::R08_SWD_PWR_GOOD_STATUS, "SWD_PWR_NOT_GOOD"},
+ {FIELDS::R08_VIN_MGMT_INPUT_OVER_VOLTAGE, "VIN_MGMT_INPUT_OVER_VOLTAGE"},
+ {FIELDS::R08_VIN_BULK_INPUT_OVER_VOLTAGE, "VIN_BULK_INPUT_OVER_VOLTAGE"},
+ }
+ },
+
+ {
+ REGS::R09,
+ { {FIELDS::R09_PMIC_HIGH_TEMP_WARNING_STATUS, "PMIC Temperature exceeded warning threshold"},
+ {FIELDS::R09_VBIAS_PWR_GOOD_STATUS, "VBIAS_PWR_NOT_GOOD"},
+ {FIELDS::R09_VOUT_1_8_V_PWR_GOOD_STATUS, "VOUT_1.8V_PWR_NOT_GOOD"},
+ {FIELDS::R09_VIN_MGMT_TO_VIN_BULK_SWITCHOVER_STATUS, "VIN_MGMT is removed (using VIN_Bulk)"},
+ {FIELDS::R09_SWA_HIGH_OUTPUT_CURRENT_CONSUMPTION_WARNING_STATUS, "SWA_HIGH_OUTPUT_CURRENT_CONSUMPTION_WARNING"},
+ {FIELDS::R09_SWB_HIGH_OUTPUT_CURRENT_CONSUMPTION_WARNING_STATUS, "SWB_HIGH_OUTPUT_CURRENT_CONSUMPTION_WARNING"},
+ {FIELDS::R09_SWC_HIGH_OUTPUT_CURRENT_CONSUMPTION_WARNING_STATUS, "SWC_HIGH_OUTPUT_CURRENT_CONSUMPTION_WARNING"},
+ {FIELDS::R09_SWD_HIGH_OUTPUT_CURRENT_CONSUMPTION_WARNING_STATUS, "SWD_HIGH_OUTPUT_CURRENT_CONSUMPTION_WARNING"},
+ }
+ },
+
+ {
+ REGS::R0A,
+ { {FIELDS::R0A_SWA_OUTPUT_OVER_VOLTAGE_STATUS, "SWA_OUTPUT_OVER_VOLTAGE"},
+ {FIELDS::R0A_SWB_OUTPUT_OVER_VOLTAGE_STATUS, "SWB_OUTPUT_OVER_VOLTAGE"},
+ {FIELDS::R0A_SWC_OUTPUT_OVER_VOLTAGE_STATUS, "SWC_OUTPUT_OVER_VOLTAGE"},
+ {FIELDS::R0A_SWD_OUTPUT_OVER_VOLTAGE_STATUS, "SWD_OUTPUT_OVER_VOLTAGE"},
+ {FIELDS::R0A_PEC_ERROR_STATUS, "PEC_ERROR"},
+ {FIELDS::R0A_PARITY_ERROR_STATUS, "PARITY_ERROR"},
+ {FIELDS::R0A_IBI_STATUS, "PENDING_IBI"},
+ }
+ },
+
+ {
+ REGS::R0B,
+ { {FIELDS::R0B_SWA_OUTPUT_CURRENT_LIMITER_WARNING_STATUS, "SWA_OUTPUT_CURRENT_LIMITER_EVENT"},
+ {FIELDS::R0B_SWB_OUTPUT_CURRENT_LIMITER_WARNING_STATUS, "SWB_OUTPUT_CURRENT_LIMITER_EVENT"},
+ {FIELDS::R0B_SWC_OUTPUT_CURRENT_LIMITER_WARNING_STATUS, "SWC_OUTPUT_CURRENT_LIMITER_EVENT"},
+ {FIELDS::R0B_SWD_OUTPUT_CURRENT_LIMITER_WARNING_STATUS, "SWD_OUTPUT_CURRENT_LIMITER_EVENT"},
+ {FIELDS::R0B_SWA_OUTPUT_UNDER_VOLTAGE_LOCKOUT_STATUS , "SWA_OUTPUT_UNDER_VOLTAGE_LOCKOUT"},
+ {FIELDS::R0B_SWB_OUTPUT_UNDER_VOLTAGE_LOCKOUT_STATUS , "SWB_OUTPUT_UNDER_VOLTAGE_LOCKOUT"},
+ {FIELDS::R0B_SWC_OUTPUT_UNDER_VOLTAGE_LOCKOUT_STATUS , "SWC_OUTPUT_UNDER_VOLTAGE_LOCKOUT"},
+ {FIELDS::R0B_SWD_OUTPUT_UNDER_VOLTAGE_LOCKOUT_STATUS , "SWD_OUTPUT_UNDER_VOLTAGE_LOCKOUT"},
+ }
+ }
+};
+
+///
+/// @brief Checks that the PMIC is enabled via VR Enable bit
+///
+/// @param[in] i_ocmb_target OCMB target
+/// @param[in] i_pmic_target PMIC target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode check_for_vr_enable(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_target,
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target);
+
+///
+/// @brief Check the statuses of all PMICs present on the given OCMB chip
+///
+/// @param[in] i_ocmb_target OCMB target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if success, else error code
+/// @note the returned target is only valid if o_errors returns as true. Else, the target is an uninitialized blank target!
+///
+fapi2::ReturnCode check_all_pmics(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_target);
+
+///
+/// @brief Check the PMIC's status codes and report back if an error occurred
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[out] o_error true/false
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error
+///
+fapi2::ReturnCode check_pmic(const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_pmic_target, bool& o_error);
+
+///
+/// @brief Clear PMIC status registers
+///
+/// @param[in] i_pmic_target PMIC to clear
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode clear(const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_pmic_target);
+
+///
+/// @brief Check the IDT specific status codes
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_statuses STATUS object to check
+/// @param[out] o_error At least one error bit was found to be set
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error in case of an I2C read error
+///
+fapi2::ReturnCode check_fields(
+ const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_pmic_target,
+ const std::vector<std::pair<uint8_t, std::vector<status_field>>>& i_statuses,
+ bool& o_error);
+
+} // status
+} // pmic
+} // mss
+
+#endif
diff --git a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_consts.H b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_consts.H
new file mode 100644
index 000000000..4cb511dae
--- /dev/null
+++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_consts.H
@@ -0,0 +1,313 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_consts.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file pmic_consts.H
+/// @brief Constants for PMIC procedures / i2C
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP HWP Backup: Andre A. Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: CI
+
+#ifndef MSS_PMIC_CONSTS_H
+#define MSS_PMIC_CONSTS_H
+
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
+namespace mss
+{
+namespace pmic
+{
+
+///
+/// @brief Module height from SPD (1U-4U)
+/// @note these values are taken directly from the SPD.
+///
+enum module_height
+{
+ HEIGHT_1U = 0b000,
+ HEIGHT_2U = 0b001,
+ HEIGHT_4U = 0b100,
+};
+
+///
+/// @brief IDs for PMIC0 or PMIC1
+///
+enum id
+{
+ PMIC0 = 0,
+ PMIC1 = 1,
+ PMIC2 = 2,
+ PMIC3 = 3,
+ UNKNOWN_ID = 4, // default constant for wrapper procedure
+};
+
+///
+/// @brief Constants for pmic product types
+///
+enum product
+{
+ JEDEC_COMPLIANT, // Only JEDEC exists
+};
+
+///
+/// @brief constants for pmic vendor
+///
+enum vendor
+{
+ UNKNOWN_VENDOR,
+ TI = 0x9780,
+ IDT = 0xB380,
+
+ TI_SHORT = 0x97,
+ IDT_SHORT = 0xB3,
+};
+
+///
+/// @brief Constants for pmic rail
+///
+enum rail
+{
+ SWA = 0,
+ SWB = 1,
+ SWC = 2,
+ SWD = 3,
+};
+
+enum class attr_eff_engine_fields
+{
+ // Template recursive base case
+ ATTR_EFF_BASE_CASE = 0,
+
+ PMIC0_SWA_VOLTAGE_SETTING = 1,
+ PMIC0_SWA_VOLTAGE_RANGE_SELECT = 2,
+ PMIC0_SWA_VOLTAGE_OFFSET = 3,
+ PMIC0_SWA_SEQUENCE_DELAY = 4,
+ PMIC0_SWA_SEQUENCE_ORDER = 5,
+
+ PMIC0_SWB_VOLTAGE_SETTING = 6,
+ PMIC0_SWB_VOLTAGE_RANGE_SELECT = 7,
+ PMIC0_SWB_VOLTAGE_OFFSET = 8,
+ PMIC0_SWB_SEQUENCE_DELAY = 9,
+ PMIC0_SWB_SEQUENCE_ORDER = 10,
+
+ PMIC0_SWC_VOLTAGE_SETTING = 11,
+ PMIC0_SWC_VOLTAGE_RANGE_SELECT = 12,
+ PMIC0_SWC_VOLTAGE_OFFSET = 13,
+ PMIC0_SWC_SEQUENCE_DELAY = 14,
+ PMIC0_SWC_SEQUENCE_ORDER = 15,
+
+ PMIC0_SWD_VOLTAGE_SETTING = 16,
+ PMIC0_SWD_VOLTAGE_RANGE_SELECT = 17,
+ PMIC0_SWD_VOLTAGE_OFFSET = 18,
+ PMIC0_SWD_SEQUENCE_DELAY = 19,
+ PMIC0_SWD_SEQUENCE_ORDER = 20,
+
+ PMIC1_SWA_VOLTAGE_SETTING = 21,
+ PMIC1_SWA_VOLTAGE_RANGE_SELECT = 22,
+ PMIC1_SWA_VOLTAGE_OFFSET = 23,
+ PMIC1_SWA_SEQUENCE_DELAY = 24,
+ PMIC1_SWA_SEQUENCE_ORDER = 25,
+
+ PMIC1_SWB_VOLTAGE_SETTING = 26,
+ PMIC1_SWB_VOLTAGE_RANGE_SELECT = 27,
+ PMIC1_SWB_VOLTAGE_OFFSET = 28,
+ PMIC1_SWB_SEQUENCE_DELAY = 29,
+ PMIC1_SWB_SEQUENCE_ORDER = 30,
+
+ PMIC1_SWC_VOLTAGE_SETTING = 31,
+ PMIC1_SWC_VOLTAGE_RANGE_SELECT = 32,
+ PMIC1_SWC_VOLTAGE_OFFSET = 33,
+ PMIC1_SWC_SEQUENCE_DELAY = 34,
+ PMIC1_SWC_SEQUENCE_ORDER = 35,
+
+ PMIC1_SWD_VOLTAGE_SETTING = 36,
+ PMIC1_SWD_VOLTAGE_RANGE_SELECT = 37,
+ PMIC1_SWD_VOLTAGE_OFFSET = 38,
+ PMIC1_SWD_SEQUENCE_DELAY = 39,
+ PMIC1_SWD_SEQUENCE_ORDER = 40,
+
+ PMIC0_PHASE_COMB = 41,
+ PMIC1_PHASE_COMB = 42,
+
+ PMIC0_MFG_ID = 43,
+ PMIC1_MFG_ID = 44,
+ PMIC0_SEQUENCE = 45,
+ PMIC1_SEQUENCE = 46,
+
+ // Dispatcher set to last enum value
+ DISPATCHER = PMIC1_SEQUENCE,
+};
+
+///
+/// @brief explorer ffdc codes
+///
+enum ffdc_codes
+{
+ SET_PMIC0_SWA_VOLTAGE_SETTING = 0x1052,
+ SET_PMIC0_SWA_VOLTAGE_RANGE_SELECT = 0x1053,
+ SET_PMIC0_SWA_VOLTAGE_OFFSET = 0x1054,
+ SET_PMIC0_SWA_SEQUENCE_DELAY = 0x1055,
+ SET_PMIC0_SWA_SEQUENCE_ORDER = 0X1056,
+
+ SET_PMIC0_SWB_VOLTAGE_SETTING = 0x1057,
+ SET_PMIC0_SWB_VOLTAGE_RANGE_SELECT = 0x1058,
+ SET_PMIC0_SWB_VOLTAGE_OFFSET = 0x1059,
+ SET_PMIC0_SWB_SEQUENCE_DELAY = 0x105A,
+ SET_PMIC0_SWB_SEQUENCE_ORDER = 0X105B,
+
+ SET_PMIC0_SWC_VOLTAGE_SETTING = 0x105C,
+ SET_PMIC0_SWC_VOLTAGE_RANGE_SELECT = 0x105D,
+ SET_PMIC0_SWC_VOLTAGE_OFFSET = 0x105E,
+ SET_PMIC0_SWC_SEQUENCE_DELAY = 0x105F,
+ SET_PMIC0_SWC_SEQUENCE_ORDER = 0X1060,
+
+ SET_PMIC0_SWD_VOLTAGE_SETTING = 0x1061,
+ SET_PMIC0_SWD_VOLTAGE_RANGE_SELECT = 0x1062,
+ SET_PMIC0_SWD_VOLTAGE_OFFSET = 0x1063,
+ SET_PMIC0_SWD_SEQUENCE_DELAY = 0x1064,
+ SET_PMIC0_SWD_SEQUENCE_ORDER = 0X1065,
+
+ SET_PMIC1_SWA_VOLTAGE_SETTING = 0x1066,
+ SET_PMIC1_SWA_VOLTAGE_RANGE_SELECT = 0x1067,
+ SET_PMIC1_SWA_VOLTAGE_OFFSET = 0x1068,
+ SET_PMIC1_SWA_SEQUENCE_DELAY = 0x1069,
+ SET_PMIC1_SWA_SEQUENCE_ORDER = 0X106A,
+
+ SET_PMIC1_SWB_VOLTAGE_SETTING = 0x106B,
+ SET_PMIC1_SWB_VOLTAGE_RANGE_SELECT = 0x106C,
+ SET_PMIC1_SWB_VOLTAGE_OFFSET = 0x106D,
+ SET_PMIC1_SWB_SEQUENCE_DELAY = 0x106E,
+ SET_PMIC1_SWB_SEQUENCE_ORDER = 0X106F,
+
+ SET_PMIC1_SWC_VOLTAGE_SETTING = 0x1070,
+ SET_PMIC1_SWC_VOLTAGE_RANGE_SELECT = 0x1071,
+ SET_PMIC1_SWC_VOLTAGE_OFFSET = 0x1072,
+ SET_PMIC1_SWC_SEQUENCE_DELAY = 0x1073,
+ SET_PMIC1_SWC_SEQUENCE_ORDER = 0X1074,
+
+ SET_PMIC1_SWD_VOLTAGE_SETTING = 0x1075,
+ SET_PMIC1_SWD_VOLTAGE_RANGE_SELECT = 0x1076,
+ SET_PMIC1_SWD_VOLTAGE_OFFSET = 0x1077,
+ SET_PMIC1_SWD_SEQUENCE_DELAY = 0x1078,
+ SET_PMIC1_SWD_SEQUENCE_ORDER = 0X1079,
+
+ SET_PMIC0_PHASE_COMB = 0x107A,
+ SET_PMIC1_PHASE_COMB = 0x107B,
+
+ SET_PMIC0_MFG_ID = 0x107C,
+ SET_PMIC1_MFG_ID = 0x107D,
+
+ SET_PMIC0_SEQUENCE = 0x107E,
+ SET_PMIC1_SEQUENCE = 0x107F,
+};
+
+///
+/// @brief constants for PMIC procedures
+///
+/// @tparam P product ID (jedec, etc.)
+///
+template<mss::pmic::product P>
+struct consts;
+
+///
+/// @brief constants for JEDEC_COMPLIANT PMICS
+///
+template<>
+struct consts<mss::pmic::product::JEDEC_COMPLIANT>
+{
+ static constexpr uint8_t RANGE_0 = 0;
+ static constexpr uint8_t RANGE_1 = 1;
+ static constexpr uint8_t NUM_UNIQUE_PMICS = 2; // PMIC0/2, PMIC1/3
+ static constexpr uint8_t NUMBER_OF_RAILS = 4;
+
+ static constexpr uint8_t VENDOR_PASSWORD_LOW = 0x73;
+ static constexpr uint8_t VENDOR_PASSWORD_HIGH = 0x94;
+ static constexpr uint8_t UNLOCK_VENDOR_REGION = 0x40;
+ static constexpr uint8_t LOCK_VENDOR_REGION = 0x00;
+ static constexpr uint8_t BURN_R40_TO_R4F = 0x81;
+ static constexpr uint8_t BURN_R50_TO_R5F = 0x82;
+ static constexpr uint8_t BURN_R60_TO_R6F = 0x85; // TI spec says 0x83, is that a deviation or a typo?
+ static constexpr uint8_t BURN_COMPLETE = 0x5A;
+
+ static constexpr uint8_t PROGRAMMABLE_MODE = 0x01;
+ static constexpr uint8_t SECURE_MODE = 0x00;
+
+ static constexpr uint8_t SINGLE_PHASE = 0x0;
+ static constexpr uint8_t DUAL_PHASE = 0x1;
+
+ static constexpr uint8_t PWR_GOOD = 0x0;
+ static constexpr uint8_t PWR_NOT_GOOD = 0x1;
+
+ // Sequencing
+ static constexpr uint8_t DELAY_LIMIT = 0b1000;
+
+ // Despite the SPD max of 1000, the PMIC can only really support this value
+ static constexpr uint8_t ORDER_LIMIT = 0b0101;
+
+ // Offset voltage from spd (+/-)
+ static constexpr uint8_t OFFSET_PLUS = 0;
+ static constexpr uint8_t OFFSET_MINUS = 1;
+
+ // Shift left 1 to match buffer position
+ static constexpr uint8_t SHIFT_VOLTAGE_FOR_REG = 1;
+
+ static constexpr uint8_t NUM_RANGES = 2; // RANGE0 and RANGE1
+ static constexpr uint8_t MAX_VOLT_BITMAP = 0b01111111;
+ static constexpr uint8_t MAX_DELAY_BITMAP = 0b00000111;
+ static constexpr uint8_t CONVERT_RANGE1_TO_RANGE0 = 40;
+
+ // Values below are in millivolts (mV)
+ static constexpr uint32_t SWABC_VOLT_RANGE0_MIN = 800;
+ static constexpr uint32_t SWABC_VOLT_RANGE0_MAX = 1435;
+ static constexpr uint32_t SWABC_VOLT_RANGE1_MIN = 600;
+ static constexpr uint32_t SWABC_VOLT_RANGE1_MAX = 1235;
+
+ static constexpr uint32_t SWD_VOLT_RANGE0_MIN = 1500;
+ static constexpr uint32_t SWD_VOLT_RANGE0_MAX = 2135;
+ static constexpr uint32_t SWD_VOLT_RANGE1_MIN = 2200;
+ static constexpr uint32_t SWD_VOLT_RANGE1_MAX = 2835;
+
+ static constexpr uint32_t VOLT_STEP = 5;
+};
+
+namespace i2c
+{
+
+///
+/// @brief common PMIC sizes
+///
+enum sizes
+{
+ DATA_LENGTH = 1,
+};
+
+} // i2c
+} // pmic
+} // mss
+
+#endif
diff --git a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.C b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.C
new file mode 100644
index 000000000..26ea9e7ef
--- /dev/null
+++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.C
@@ -0,0 +1,615 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file pmic_enable_utils.C
+/// @brief Utility functions for PMIC enable operation
+///
+// *HWP HWP Owner: Mark Pizzutillo <mark.pizzutillo@ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include <lib/i2c/i2c_pmic.H>
+#include <lib/utils/pmic_enable_utils.H>
+#include <lib/utils/pmic_consts.H>
+#include <lib/utils/pmic_common_utils.H>
+#include <pmic_regs.H>
+#include <pmic_regs_fld.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/utils/index.H>
+#include <generic/memory/lib/utils/find.H>
+#include <mss_pmic_attribute_getters.H>
+#include <mss_generic_attribute_getters.H>
+
+namespace mss
+{
+namespace pmic
+{
+
+///
+/// @breif set VR enable bit for system startup via R32 (not broadcast)
+///
+/// @param[in] i_pmic_target PMIC target
+/// @return fapi2::FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode start_vr_enable(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target)
+{
+ static constexpr auto J = mss::pmic::product::JEDEC_COMPLIANT;
+ using REGS = pmicRegs<J>;
+ using FIELDS = pmicFields<J>;
+
+
+ fapi2::buffer<uint8_t> l_programmable_mode_buffer;
+ fapi2::buffer<uint8_t> l_vr_enable_buffer;
+
+ // Enable programmable mode
+ FAPI_TRY(mss::pmic::i2c::reg_read_reverse_buffer(i_pmic_target, REGS::R2F, l_programmable_mode_buffer),
+ "start_vr_enable: Error reading address 0x%02hhX of %s to enable programmable mode operation",
+ REGS::R2F, mss::c_str(i_pmic_target));
+
+ l_programmable_mode_buffer.writeBit<FIELDS::R2F_SECURE_MODE>(
+ mss::pmic::consts<mss::pmic::product::JEDEC_COMPLIANT>::PROGRAMMABLE_MODE);
+
+ FAPI_TRY(mss::pmic::i2c::reg_write_reverse_buffer(i_pmic_target, REGS::R2F, l_programmable_mode_buffer),
+ "start_vr_enable: Error writing address 0x%02hhX of %s to enable programmable mode operation",
+ REGS::R2F, mss::c_str(i_pmic_target));
+
+ // Start VR Enable
+ // Write 1 to R2F(2)
+ l_vr_enable_buffer.setBit<FIELDS::R32_VR_ENABLE>();
+
+ FAPI_INF("Executing VR_ENABLE for PMIC %s", mss::c_str(i_pmic_target));
+ FAPI_TRY(mss::pmic::i2c::reg_write_reverse_buffer(i_pmic_target, REGS::R32, l_vr_enable_buffer),
+ "start_vr_enable: Could not write to address 0x%02hhX of %s to execute VR Enable",
+ REGS::R32,
+ mss::c_str(i_pmic_target));
+
+ // At this point, the PWR_GOOD pin should begin to rise to high. This can't directly be checked via a register
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief bias PMIC with spd settings for phase combination (SWA, SWB or SWA+SWB)
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_dimm_target - DIMM target of PMIC
+/// @param[in] i_id - PMIC0 or PMIC1
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff no error
+///
+fapi2::ReturnCode bias_with_spd_phase_comb(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm_target,
+ const mss::pmic::id i_id)
+{
+ static constexpr auto J = mss::pmic::product::JEDEC_COMPLIANT;
+ using FIELDS = pmicFields<J>;
+ using REGS = pmicRegs<J>;
+
+ uint8_t l_phase_comb = 0;
+ fapi2::buffer<uint8_t> l_phase;
+ FAPI_TRY(mss::pmic::get_phase_comb[i_id](i_dimm_target, l_phase_comb));
+
+ // Read, replace bit, and then re-write
+ FAPI_TRY(mss::pmic::i2c::reg_read_reverse_buffer(i_pmic_target, REGS::R4F, l_phase));
+ l_phase.writeBit<FIELDS::SWA_SWB_PHASE_MODE_SELECT>(l_phase_comb);
+ FAPI_TRY(mss::pmic::i2c::reg_write_reverse_buffer(i_pmic_target, REGS::R4F, l_phase));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief bias PMIC with SPD settings for voltage ranges
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_dimm_target dimm target of PMIC
+/// @param[in] i_id PMIC0 or PMIC1
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff no error
+///
+fapi2::ReturnCode bias_with_spd_volt_ranges(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm_target,
+ const mss::pmic::id i_id)
+{
+ static constexpr auto J = mss::pmic::product::JEDEC_COMPLIANT;
+ using FIELDS = pmicFields<J>;
+ using REGS = pmicRegs<J>;
+
+ uint8_t l_swa_range = 0;
+ uint8_t l_swb_range = 0;
+ uint8_t l_swc_range = 0;
+ uint8_t l_swd_range = 0;
+
+ fapi2::buffer<uint8_t> l_volt_range_buffer;
+
+ FAPI_TRY(mss::pmic::get_swa_voltage_range_select[i_id](i_dimm_target, l_swa_range));
+ FAPI_TRY(mss::pmic::get_swb_voltage_range_select[i_id](i_dimm_target, l_swb_range));
+ FAPI_TRY(mss::pmic::get_swc_voltage_range_select[i_id](i_dimm_target, l_swc_range));
+ FAPI_TRY(mss::pmic::get_swd_voltage_range_select[i_id](i_dimm_target, l_swd_range));
+
+ // Read in what the register has, as to not overwrite any default values
+ FAPI_TRY(mss::pmic::i2c::reg_read_reverse_buffer(i_pmic_target, REGS::R2B, l_volt_range_buffer));
+
+ // Set the buffer bits appropriately
+ l_volt_range_buffer.writeBit<FIELDS::SWA_VOLTAGE_RANGE>(l_swa_range);
+ l_volt_range_buffer.writeBit<FIELDS::SWB_VOLTAGE_RANGE>(l_swb_range);
+ l_volt_range_buffer.writeBit<FIELDS::SWC_VOLTAGE_RANGE>(l_swc_range);
+ l_volt_range_buffer.writeBit<FIELDS::SWD_VOLTAGE_RANGE>(l_swd_range);
+
+ // Write back to PMIC
+ FAPI_TRY(mss::pmic::i2c::reg_write_reverse_buffer(i_pmic_target, REGS::R2B, l_volt_range_buffer));
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief bias PMIC with SPD settings for startup sequence
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_dimm_target dimm target of PMIC
+/// @param[in] i_id PMIC0 or PMIC1
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff no error
+///
+fapi2::ReturnCode bias_with_spd_startup_seq(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm_target,
+ const mss::pmic::id i_id)
+{
+ static constexpr auto J = mss::pmic::product::JEDEC_COMPLIANT;
+ using REGS = pmicRegs<J>;
+ using CONSTS = mss::pmic::consts<J>;
+
+ // Arrays to key off of rail and PMIC ID
+ static const pmic_attr_ptr* l_get_sequence_order[] = {mss::pmic::get_swa_sequence_order,
+ mss::pmic::get_swb_sequence_order,
+ mss::pmic::get_swc_sequence_order,
+ mss::pmic::get_swd_sequence_order
+ };
+
+ static const pmic_attr_ptr* l_get_sequence_delay[] = {mss::pmic::get_swa_sequence_delay,
+ mss::pmic::get_swb_sequence_delay,
+ mss::pmic::get_swc_sequence_delay,
+ mss::pmic::get_swd_sequence_delay
+ };
+
+ static const std::vector<uint8_t> SEQUENCE_REGS =
+ {
+ 0, // 0 would imply no sequence config (won't occur due to assert in bias_with_spd_startup_seq)
+ REGS::R40_POWER_ON_SEQUENCE_CONFIG_1,
+ REGS::R41_POWER_ON_SEQUENCE_CONFIG_2,
+ REGS::R42_POWER_ON_SEQUENCE_CONFIG_3,
+ REGS::R43_POWER_ON_SEQUENCE_CONFIG_4
+ };
+
+ // Arrays to store the attribute data
+ uint8_t l_sequence_orders[CONSTS::NUMBER_OF_RAILS];
+ uint8_t l_sequence_delays[CONSTS::NUMBER_OF_RAILS];
+
+ // Loop through each rail to populate the order and delay arrays
+ for (uint8_t l_rail_index = mss::pmic::rail::SWA; l_rail_index <= mss::pmic::rail::SWD; ++l_rail_index)
+ {
+ // We know after these FAPI_TRY's that all 4 entries must be populated, else the TRYs fail
+ FAPI_TRY(((l_get_sequence_order[l_rail_index][i_id]))(i_dimm_target, l_sequence_orders[l_rail_index]));
+ FAPI_TRY(((l_get_sequence_delay[l_rail_index][i_id]))(i_dimm_target, l_sequence_delays[l_rail_index]));
+
+ // The SPD allows for up to 8 sequences, but there are only 4 on the PMIC. The SPD defaults never go higher than 2.
+ // We put this check in here as with anything over 4, we don't really know what we can do.
+ FAPI_ASSERT(((l_sequence_orders[l_rail_index] < CONSTS::ORDER_LIMIT)),
+ fapi2::PMIC_ORDER_OUT_OF_RANGE()
+ .set_TARGET(i_pmic_target)
+ .set_RAIL(l_rail_index)
+ .set_ORDER(l_sequence_orders[l_rail_index]),
+ "PMIC sequence order specified by the SPD was out of range for PMIC: %s Rail: %s Order: %u",
+ mss::c_str(i_pmic_target),
+ PMIC_RAIL_NAMES[l_rail_index],
+ l_sequence_orders[l_rail_index]);
+ }
+
+ {
+ fapi2::buffer<uint8_t> l_power_on_sequence_config;
+ uint8_t l_highest_sequence = 0;
+
+ // Zero out sequence registers first
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, REGS::R40_POWER_ON_SEQUENCE_CONFIG_1, l_power_on_sequence_config));
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, REGS::R41_POWER_ON_SEQUENCE_CONFIG_2, l_power_on_sequence_config));
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, REGS::R42_POWER_ON_SEQUENCE_CONFIG_3, l_power_on_sequence_config));
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, REGS::R43_POWER_ON_SEQUENCE_CONFIG_4, l_power_on_sequence_config));
+
+ // Set the registers appropriately. We kind of need to do this greedy algorithm here since
+ // the SPD has fields of sequence per rail, the PMIC wants rails per sequence.
+ // 1. For each rail, set that bit in the corresponding sequence, and enable that sequence
+ // 2. Set that rail bit for each of the following sequences
+ // 3. Record the highest sequence used throughout the run
+ // 4. Clear out registers of sequences higher than the highest used (clear the set rail bits)
+ // We do this because for each rail, we may not know what the highest sequence will be yet.
+ // It makes the most sense to assume all sequences, then clear those that aren't used.
+ for (uint8_t l_rail_index = mss::pmic::rail::SWA; l_rail_index <= mss::pmic::rail::SWD; ++l_rail_index)
+ {
+ static constexpr uint8_t NO_SEQUENCE = 0;
+ const uint8_t l_rail_sequence = l_sequence_orders[l_rail_index];
+
+ if (l_rail_sequence != NO_SEQUENCE) // If 0, it will not be sequenced
+ {
+ // Update the new highest working sequence
+ l_highest_sequence = std::max(l_rail_sequence, l_highest_sequence);
+ // Set the register contents appropriately
+ FAPI_TRY(mss::pmic::set_startup_seq_register(i_pmic_target, l_rail_index,
+ l_rail_sequence, l_sequence_delays[l_rail_index]));
+ }
+
+ // else, zero, do nothing.
+ }
+
+ // Now erase the registers that are higher than our highest sequence (in order to satisfy note 2
+ // for registers R40 - R43):
+ // - 2. If bit [7] = ‘0’, bits [6:3] must be programmed as ‘0000’. If bit [7] = ‘1’,
+ // - at least one of the bits [6:3] must be programmed as ‘1’.
+ for (++l_highest_sequence; l_highest_sequence < SEQUENCE_REGS.size(); ++l_highest_sequence)
+ {
+ fapi2::buffer<uint8_t> l_clear;
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, SEQUENCE_REGS[l_highest_sequence], l_power_on_sequence_config));
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Set the startup seq register with the given parameters
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_rail rail to
+/// @param[in] i_round sequence round 1-4
+/// @param[in] i_delay delay after round
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff no error
+///
+fapi2::ReturnCode set_startup_seq_register(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const uint8_t i_rail,
+ const uint8_t i_round,
+ const uint8_t i_delay)
+{
+ static constexpr auto J = mss::pmic::product::JEDEC_COMPLIANT;
+ using REGS = pmicRegs<J>;
+ using FIELDS = pmicFields<J>;
+ using CONSTS = mss::pmic::consts<J>;
+
+ // PMIC registers are indexed [7:0], so from the buffer point of view, our bit fields need to be flipped
+ static constexpr uint8_t RIGHT_ALIGN_OFFSET = 7;
+
+ // Starts at bit 0 (right aligned) with length 3. So we need to take length 3 from bit 5 in our buffer
+ static constexpr uint8_t DELAY_START = 5;
+
+ static const std::vector<uint8_t> SEQUENCE_REGS =
+ {
+ 0, // 0 would imply no sequence config (won't occur due to assert in bias_with_spd_startup_seq)
+ REGS::R40_POWER_ON_SEQUENCE_CONFIG_1,
+ REGS::R41_POWER_ON_SEQUENCE_CONFIG_2,
+ REGS::R42_POWER_ON_SEQUENCE_CONFIG_3,
+ REGS::R43_POWER_ON_SEQUENCE_CONFIG_4
+ };
+
+ // Manual reversing of sequence bits
+ static const std::vector<uint8_t> SEQUENCE_BITS =
+ {
+ RIGHT_ALIGN_OFFSET - FIELDS::SEQUENCE_SWA_ENABLE,
+ RIGHT_ALIGN_OFFSET - FIELDS::SEQUENCE_SWB_ENABLE,
+ RIGHT_ALIGN_OFFSET - FIELDS::SEQUENCE_SWC_ENABLE,
+ RIGHT_ALIGN_OFFSET - FIELDS::SEQUENCE_SWD_ENABLE
+ };
+
+ fapi2::buffer<uint8_t> l_power_on_sequence_config;
+
+ // Check and make sure the given delay is less than the bitmask (else, we overflow later on)
+ FAPI_ASSERT(i_delay <= CONSTS::MAX_DELAY_BITMAP,
+ fapi2::PMIC_DELAY_OUT_OF_RANGE()
+ .set_TARGET(i_pmic_target)
+ .set_RAIL(i_rail)
+ .set_DELAY(i_delay),
+ "PMIC sequence delay from the SPD attribute was out of range for PMIC: %s Rail: %s Delay: %u Max: %u",
+ mss::c_str(i_pmic_target),
+ PMIC_RAIL_NAMES[i_rail],
+ i_delay,
+ CONSTS::MAX_DELAY_BITMAP);
+
+ // PMIC registers are indexed [7:0], so from the buffer point of view, our bit fields need to be flipped
+ static constexpr uint8_t SEQUENCE_ENABLE_REVERSED = (RIGHT_ALIGN_OFFSET - FIELDS::SEQUENCE_ENABLE);
+
+ FAPI_TRY(mss::pmic::i2c::reg_read(i_pmic_target, SEQUENCE_REGS[i_round], l_power_on_sequence_config));
+
+ // Adding on the sequence delays (which are the far right 3 bits).
+
+ // Note: The SPD has sequence delays per rail NOT per sequence (PMIC is by sequence). Here,
+ // if two rails on the same sequence have different delays, the last rail's delay (ex. SWD) will take precedence.
+ // In other words, they will be made to match. Otherwise, the SPD is flawed.
+ l_power_on_sequence_config.clearBit<DELAY_START, FIELDS::DELAY_FLD_LENGTH>();
+ l_power_on_sequence_config = l_power_on_sequence_config + i_delay;
+
+ FAPI_TRY(l_power_on_sequence_config.setBit(SEQUENCE_BITS[i_rail]));
+ FAPI_TRY(l_power_on_sequence_config.setBit(SEQUENCE_ENABLE_REVERSED));
+
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, SEQUENCE_REGS[i_round], l_power_on_sequence_config));
+
+ // The startup sequence registers after the provided one must set the bits of the rail we just enabled in
+ // the current sequence. So here, we iterate through the remaining sequences and set those bits.
+ // since we don't know the information about all the rails within this one function (others may be
+ // set in later calls to this function) we will set these for each sequence register now, and then
+ // clear them out later when we know exactly which sequences will be enabled and which ones won't
+ for (uint8_t l_round_modify = i_round; l_round_modify < SEQUENCE_REGS.size(); ++l_round_modify)
+ {
+ l_power_on_sequence_config.flush<0>();
+ FAPI_TRY(mss::pmic::i2c::reg_read(i_pmic_target, SEQUENCE_REGS[l_round_modify], l_power_on_sequence_config));
+ FAPI_TRY(l_power_on_sequence_config.setBit(SEQUENCE_BITS[i_rail]));
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, SEQUENCE_REGS[l_round_modify], l_power_on_sequence_config));
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Order PMICs by sequence defined in the SPD
+///
+/// @param[in] i_dimm DIMM target to pull SPD fields from
+/// @param[in] i_dimm_index index of the DIMM target
+/// @param[in] i_pmics_per_dimm number of PMICs per dimm
+/// @param[in,out] io_pmics vector of PMICs that will be re-ordered in place
+/// @return fapi2::ReturnCode
+///
+fapi2::ReturnCode order_pmics_by_sequence(
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM> i_dimm,
+ const uint8_t i_dimm_index,
+ const uint8_t i_pmics_per_dimm,
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_PMIC>>& io_pmics)
+{
+ const auto l_begin_offset = i_dimm_index * i_pmics_per_dimm;
+ const auto l_iterator_begin = io_pmics.begin() + l_begin_offset;
+ const auto l_iterator_end = l_iterator_begin + i_pmics_per_dimm;
+
+ fapi2::ReturnCode l_rc_0_out = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::ReturnCode l_rc_1_out = fapi2::FAPI2_RC_SUCCESS;
+
+ std::sort(l_iterator_begin, l_iterator_end, [&l_rc_0_out, &l_rc_1_out, i_dimm] (
+ const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& l_first_pmic,
+ const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& l_second_pmic) -> bool
+ {
+ // Here we should only be dealing with PMICs of the same DIMM. So we can just check the first one which dimm we're on
+ uint8_t l_sequence_pmic_0 = 0;
+ uint8_t l_sequence_pmic_1 = 0;
+
+ // Need to pull out the RC's manually. Goto's in lambdas apparently don't play nicely
+ fapi2::ReturnCode l_rc_0 = mss::pmic::get_sequence[mss::index(l_first_pmic)](i_dimm, l_sequence_pmic_0);
+ fapi2::ReturnCode l_rc_1 = mss::pmic::get_sequence[mss::index(l_second_pmic)](i_dimm, l_sequence_pmic_1);
+
+ // Hold on to an error if we see one
+ if (l_rc_0 != fapi2::FAPI2_RC_SUCCESS)
+ {
+ l_rc_0_out = l_rc_0;
+ }
+ if (l_rc_1 != fapi2::FAPI2_RC_SUCCESS)
+ {
+ l_rc_1_out = l_rc_1;
+ }
+
+ return l_sequence_pmic_0 < l_sequence_pmic_1;
+ });
+
+ FAPI_TRY(l_rc_0_out, "Error getting sequencing attributes for PMICs associated with DIMM 0 target %s",
+ mss::c_str(i_dimm));
+ FAPI_TRY(l_rc_1_out, "Error getting sequencing attributes for PMICs associated with DIMM 1 target %s",
+ mss::c_str(i_dimm));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Enable pmics using manual mode (direct VR enable, no SPD fields)
+/// @param[in] i_pmics vector of PMICs to enable
+/// @return FAPI2_RC_SUCCESS iff success, else error
+///
+fapi2::ReturnCode enable_manual(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_PMIC>>& i_pmics)
+{
+ using CONSTS = mss::pmic::consts<mss::pmic::product::JEDEC_COMPLIANT>;
+ using REGS = pmicRegs<mss::pmic::product::JEDEC_COMPLIANT>;
+ using FIELDS = pmicFields<mss::pmic::product::JEDEC_COMPLIANT>;
+
+ for (const auto& l_pmic : i_pmics)
+ {
+ fapi2::buffer<uint8_t> l_programmable_mode;
+ l_programmable_mode.writeBit<FIELDS::R2F_SECURE_MODE>(CONSTS::PROGRAMMABLE_MODE);
+
+ FAPI_INF("Enabling PMIC %s with default settings", mss::c_str(l_pmic));
+
+ // Make sure power is applied and we can read the PMIC
+ FAPI_TRY(mss::pmic::poll_for_pbulk_good(l_pmic),
+ "pmic_enable: poll for pbulk good either failed, or returned not good status on PMIC %s",
+ mss::c_str(l_pmic));
+
+ // Enable programmable mode
+ FAPI_TRY(mss::pmic::i2c::reg_write_reverse_buffer(l_pmic, REGS::R2F, l_programmable_mode));
+
+ // Start VR Enable
+ FAPI_TRY(mss::pmic::start_vr_enable(l_pmic),
+ "Error starting VR_ENABLE on PMIC %s", mss::c_str(l_pmic));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+///
+/// @brief Function to enable 1U and 2U pmics
+///
+/// @param[in] i_pmic_target - the pmic target
+/// @param[in] i_dimm_target - the dimm target that the PMIC resides on
+/// @param[in] i_vendor_id - the vendor ID of the PMIC to bias
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS if successful
+///
+fapi2::ReturnCode enable_chip_1U_2U(const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_dimm_target,
+ const uint16_t i_vendor_id)
+{
+ FAPI_INF("Setting PMIC %s settings from SPD", mss::c_str(i_pmic_target));
+
+ // Make sure it is TI or IDT
+ FAPI_ASSERT((i_vendor_id == mss::pmic::vendor::IDT ||
+ i_vendor_id == mss::pmic::vendor::TI),
+ fapi2::PMIC_CHIP_NOT_RECOGNIZED()
+ .set_TARGET(i_pmic_target)
+ .set_VENDOR_ID(i_vendor_id),
+ "Unknown PMIC: %s with vendor ID 0x%04hhX",
+ mss::c_str(i_pmic_target),
+ uint8_t(i_vendor_id) );
+
+ if (i_vendor_id == mss::pmic::vendor::IDT)
+ {
+ FAPI_TRY(mss::pmic::bias_with_spd_settings<mss::pmic::vendor::IDT>(i_pmic_target, i_dimm_target),
+ "enable_chip<IDT, 1U/2U>: Error biasing PMIC %s with SPD settings",
+ mss::c_str(i_pmic_target));
+ }
+ else // assert done in pmic_enable.C that vendor is IDT or TI
+ {
+ FAPI_TRY(mss::pmic::bias_with_spd_settings<mss::pmic::vendor::TI>(i_pmic_target, i_dimm_target),
+ "enable_chip<TI, 1U/2U>: Error biasing PMIC %s with SPD settings",
+ mss::c_str(i_pmic_target));
+ }
+
+ // Start VR Enable
+ FAPI_TRY(mss::pmic::start_vr_enable(i_pmic_target),
+ "Error starting VR_ENABLE on PMIC %s", mss::c_str(i_pmic_target));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Disable PMICs and clear status bits in preparation for enable
+///
+/// @param[in] i_pmics vector of PMIC targets
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode disable_and_reset_pmics(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_PMIC>>& i_pmics)
+{
+ using REGS = pmicRegs<mss::pmic::product::JEDEC_COMPLIANT>;
+ using FIELDS = pmicFields<mss::pmic::product::JEDEC_COMPLIANT>;
+
+ for (const auto& l_pmic : i_pmics)
+ {
+ // First, disable
+ {
+ fapi2::buffer<uint8_t> l_reg_contents;
+
+ // Redundant clearBit, but just so it's clear what we're doing
+ l_reg_contents.clearBit<FIELDS::R32_VR_ENABLE>();
+
+ FAPI_TRY(mss::pmic::i2c::reg_write_reverse_buffer(l_pmic, REGS::R32, l_reg_contents));
+ }
+
+ // Now that it's disabled, let's clear the status bits so errors don't hang over into the next enable
+ {
+ FAPI_TRY(mss::pmic::status::clear(l_pmic));
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+///
+/// @brief Enable PMIC for SPD mode
+///
+/// @param[in] i_pmics vector of PMICs sorted by mss::index
+/// @param[in] i_dimms const vector of DIMMs sorted by mss::index
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode pmic_enable_SPD(
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_PMIC>>& i_pmics,
+ const std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& i_dimms)
+{
+ uint8_t l_module_height = 0;
+ FAPI_TRY(mss::attr::get_dram_module_height(i_dimms[0], l_module_height));
+
+ FAPI_ASSERT(l_module_height == fapi2::ENUM_ATTR_MEM_EFF_DRAM_MODULE_HEIGHT_1U ||
+ l_module_height == fapi2::ENUM_ATTR_MEM_EFF_DRAM_MODULE_HEIGHT_2U,
+ fapi2::PMIC_DIMM_SPD_UNSUPPORTED_MODULE_HEIGHT()
+ .set_TARGET(i_dimms[0])
+ .set_VALUE(l_module_height),
+ "DIMM %s module height attribute not identified as 1U or 2U. "
+ "ENUM_ATTR_MEM_EFF_DRAM_MODULE_HEIGHT of %u . Not supported yet.",
+ mss::c_str(i_dimms[0]), l_module_height);
+
+ // Now we know there are 2 pmics per dimm (for DDIMM only... TK will change with future refactor)
+ static constexpr uint8_t PMICS_PER_DIMM = 2;
+
+ for (uint8_t l_dimm_index = 0; l_dimm_index < i_dimms.size(); ++l_dimm_index)
+ {
+ // The PMICs are in sorted order
+ const auto& l_dimm = i_dimms[l_dimm_index];
+ FAPI_TRY(mss::pmic::order_pmics_by_sequence(l_dimm, l_dimm_index, PMICS_PER_DIMM, i_pmics));
+
+ // Now the PMICs are in the right order of DIMM and the right order by their defined SPD sequence within each dimm
+ // Let's kick off the enables
+ for (const auto& l_pmic : i_pmics)
+ {
+ // Get the corresponding DIMM target to feed to the helpers
+ const auto& l_dimm = i_dimms[mss::index(l_pmic) / PMICS_PER_DIMM];
+ uint16_t l_vendor_id = 0;
+
+ // Get vendor ID
+ FAPI_TRY(mss::pmic::get_mfg_id[mss::index(l_pmic)](l_dimm, l_vendor_id));
+
+ // Poll to make sure PBULK reports good, then we can enable the chip and write/read registers
+ FAPI_TRY(mss::pmic::poll_for_pbulk_good(l_pmic),
+ "pmic_enable: poll for pbulk good either failed, or returned not good status on PMIC %s",
+ mss::c_str(l_pmic));
+
+ // Call the enable procedure
+ FAPI_TRY((mss::pmic::enable_chip_1U_2U(l_pmic, l_dimm, l_vendor_id)),
+ "pmic_enable: Error enabling PMIC %s", mss::c_str(l_pmic));
+ }
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+} // pmic
+} // mss
diff --git a/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.H b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.H
new file mode 100644
index 000000000..9220993b5
--- /dev/null
+++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.H
@@ -0,0 +1,788 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/common/procedures/hwp/pmic/lib/utils/pmic_enable_utils.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file pmic_enable_utils.H
+/// @brief Utility functions for PMIC enable operation
+///
+// *HWP HWP Owner: Mark Pizzutillo <mark.pizzutillo@ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#ifndef __PMIC_ENABLE_UTILS_H__
+#define __PMIC_ENABLE_UTILS_H__
+
+#include <fapi2.H>
+#include <pmic_regs.H>
+#include <pmic_regs_fld.H>
+#include <lib/i2c/i2c_pmic.H>
+#include <lib/utils/pmic_common_utils.H>
+#include <lib/utils/pmic_consts.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/utils/index.H>
+#include <mss_pmic_attribute_getters.H>
+#include <mss_pmic_attribute_setters.H>
+
+namespace mss
+{
+namespace pmic
+{
+/// @brief pointer to PMIC attribute getters for DIMM target
+typedef fapi2::ReturnCode (*pmic_attr_ptr)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value);
+typedef fapi2::ReturnCode (*pmic_attr_ptr_signed)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ int8_t& o_value);
+// Pointers below allow for run-time attribute getter selection by PMIC ID (0,1)
+
+// PMIC0/1 sequence order
+static constexpr pmic_attr_ptr get_sequence[] =
+{
+ mss::attr::get_pmic0_sequence,
+ mss::attr::get_pmic1_sequence
+};
+
+// Voltage Setting
+static constexpr pmic_attr_ptr get_swa_voltage_setting[] =
+{
+ mss::attr::get_pmic0_swa_voltage_setting,
+ mss::attr::get_pmic1_swa_voltage_setting
+};
+static constexpr pmic_attr_ptr get_swb_voltage_setting[] =
+{
+ mss::attr::get_pmic0_swb_voltage_setting,
+ mss::attr::get_pmic1_swb_voltage_setting
+};
+static constexpr pmic_attr_ptr get_swc_voltage_setting[] =
+{
+ mss::attr::get_pmic0_swc_voltage_setting,
+ mss::attr::get_pmic1_swc_voltage_setting
+};
+static constexpr pmic_attr_ptr get_swd_voltage_setting[] =
+{
+ mss::attr::get_pmic0_swd_voltage_setting,
+ mss::attr::get_pmic1_swd_voltage_setting
+};
+
+// Voltage Range Select
+static constexpr pmic_attr_ptr get_swa_voltage_range_select[] =
+{
+ mss::attr::get_pmic0_swa_voltage_range_select,
+ mss::attr::get_pmic1_swa_voltage_range_select
+};
+static constexpr pmic_attr_ptr get_swb_voltage_range_select[] =
+{
+ mss::attr::get_pmic0_swb_voltage_range_select,
+ mss::attr::get_pmic1_swb_voltage_range_select
+};
+static constexpr pmic_attr_ptr get_swc_voltage_range_select[] =
+{
+ mss::attr::get_pmic0_swc_voltage_range_select,
+ mss::attr::get_pmic1_swc_voltage_range_select
+};
+static constexpr pmic_attr_ptr get_swd_voltage_range_select[] =
+{
+ mss::attr::get_pmic0_swd_voltage_range_select,
+ mss::attr::get_pmic1_swd_voltage_range_select
+};
+
+// Voltage Offset
+static constexpr pmic_attr_ptr_signed get_swa_voltage_offset[] =
+{
+ mss::attr::get_pmic0_swa_voltage_offset,
+ mss::attr::get_pmic1_swa_voltage_offset
+};
+static constexpr pmic_attr_ptr_signed get_swb_voltage_offset[] =
+{
+ mss::attr::get_pmic0_swb_voltage_offset,
+ mss::attr::get_pmic1_swb_voltage_offset
+};
+static constexpr pmic_attr_ptr_signed get_swc_voltage_offset[] =
+{
+ mss::attr::get_pmic0_swc_voltage_offset,
+ mss::attr::get_pmic1_swc_voltage_offset
+};
+static constexpr pmic_attr_ptr_signed get_swd_voltage_offset[] =
+{
+ mss::attr::get_pmic0_swd_voltage_offset,
+ mss::attr::get_pmic1_swd_voltage_offset
+};
+
+// Sequence Delay
+static constexpr pmic_attr_ptr get_swa_sequence_delay[] =
+{
+ mss::attr::get_pmic0_swa_sequence_delay,
+ mss::attr::get_pmic1_swa_sequence_delay
+};
+static constexpr pmic_attr_ptr get_swb_sequence_delay[] =
+{
+ mss::attr::get_pmic0_swb_sequence_delay,
+ mss::attr::get_pmic1_swb_sequence_delay
+};
+static constexpr pmic_attr_ptr get_swc_sequence_delay[] =
+{
+ mss::attr::get_pmic0_swc_sequence_delay,
+ mss::attr::get_pmic1_swc_sequence_delay
+};
+static constexpr pmic_attr_ptr get_swd_sequence_delay[] =
+{
+ mss::attr::get_pmic0_swd_sequence_delay,
+ mss::attr::get_pmic1_swd_sequence_delay
+};
+
+// Sequence Order
+static constexpr pmic_attr_ptr get_swa_sequence_order[] =
+{
+ mss::attr::get_pmic0_swa_sequence_order,
+ mss::attr::get_pmic1_swa_sequence_order
+};
+static constexpr pmic_attr_ptr get_swb_sequence_order[] =
+{
+ mss::attr::get_pmic0_swb_sequence_order,
+ mss::attr::get_pmic1_swb_sequence_order
+};
+static constexpr pmic_attr_ptr get_swc_sequence_order[] =
+{
+ mss::attr::get_pmic0_swc_sequence_order,
+ mss::attr::get_pmic1_swc_sequence_order
+};
+static constexpr pmic_attr_ptr get_swd_sequence_order[] =
+{
+ mss::attr::get_pmic0_swd_sequence_order,
+ mss::attr::get_pmic1_swd_sequence_order
+};
+
+// Phase Combination
+static constexpr pmic_attr_ptr get_phase_comb[] =
+{
+ mss::attr::get_pmic0_phase_comb,
+ mss::attr::get_pmic1_phase_comb
+};
+
+// EFD Fields
+
+// Offset
+static constexpr pmic_attr_ptr_signed get_efd_swa_voltage_offset[] =
+{
+ mss::attr::get_efd_pmic0_swa_voltage_offset,
+ mss::attr::get_efd_pmic1_swa_voltage_offset
+};
+
+static constexpr pmic_attr_ptr_signed get_efd_swb_voltage_offset[] =
+{
+ mss::attr::get_efd_pmic0_swb_voltage_offset,
+ mss::attr::get_efd_pmic1_swb_voltage_offset
+};
+
+static constexpr pmic_attr_ptr_signed get_efd_swc_voltage_offset[] =
+{
+ mss::attr::get_efd_pmic0_swc_voltage_offset,
+ mss::attr::get_efd_pmic1_swc_voltage_offset
+};
+
+static constexpr pmic_attr_ptr_signed get_efd_swd_voltage_offset[] =
+{
+ mss::attr::get_efd_pmic0_swd_voltage_offset,
+ mss::attr::get_efd_pmic1_swd_voltage_offset
+};
+
+// These arrays allow us to dynamically choose the right attribute getter at runtime based on the rail and mss::pmic::id
+static const pmic_attr_ptr* get_volt_setting[] =
+{
+ mss::pmic::get_swa_voltage_setting,
+ mss::pmic::get_swb_voltage_setting,
+ mss::pmic::get_swc_voltage_setting,
+ mss::pmic::get_swd_voltage_setting
+};
+
+static const pmic_attr_ptr* get_volt_range_select[] =
+{
+ mss::pmic::get_swa_voltage_range_select,
+ mss::pmic::get_swb_voltage_range_select,
+ mss::pmic::get_swc_voltage_range_select,
+ mss::pmic::get_swd_voltage_range_select
+};
+
+static const pmic_attr_ptr_signed* get_volt_offset[] =
+{
+ mss::pmic::get_swa_voltage_offset,
+ mss::pmic::get_swb_voltage_offset,
+ mss::pmic::get_swc_voltage_offset,
+ mss::pmic::get_swd_voltage_offset
+};
+
+// EFD Offset + Direction functions
+static const pmic_attr_ptr_signed* get_efd_volt_offset[] =
+{
+ mss::pmic::get_efd_swa_voltage_offset,
+ mss::pmic::get_efd_swb_voltage_offset,
+ mss::pmic::get_efd_swc_voltage_offset,
+ mss::pmic::get_efd_swd_voltage_offset
+};
+
+// For output traces
+static const std::vector<const char*> PMIC_RAIL_NAMES = {"SWA", "SWB", "SWC", "SWD"};
+
+// Attribute setter FP type
+typedef fapi2::ReturnCode (*pmic_attr_setter_ptr)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t i_value);
+typedef fapi2::ReturnCode (*pmic_attr_setter_ptr_signed)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ int8_t i_value);
+
+// Voltage Setting
+static constexpr pmic_attr_setter_ptr set_swa_voltage_setting[] =
+{
+ mss::attr::set_pmic0_swa_voltage_setting,
+ mss::attr::set_pmic1_swa_voltage_setting
+};
+static constexpr pmic_attr_setter_ptr set_swb_voltage_setting[] =
+{
+ mss::attr::set_pmic0_swb_voltage_setting,
+ mss::attr::set_pmic1_swb_voltage_setting
+};
+static constexpr pmic_attr_setter_ptr set_swc_voltage_setting[] =
+{
+ mss::attr::set_pmic0_swc_voltage_setting,
+ mss::attr::set_pmic1_swc_voltage_setting
+};
+static constexpr pmic_attr_setter_ptr set_swd_voltage_setting[] =
+{
+ mss::attr::set_pmic0_swd_voltage_setting,
+ mss::attr::set_pmic1_swd_voltage_setting
+};
+
+// Voltage Range Select
+static constexpr pmic_attr_setter_ptr set_swa_voltage_range_select[] =
+{
+ mss::attr::set_pmic0_swa_voltage_range_select,
+ mss::attr::set_pmic1_swa_voltage_range_select
+};
+static constexpr pmic_attr_setter_ptr set_swb_voltage_range_select[] =
+{
+ mss::attr::set_pmic0_swb_voltage_range_select,
+ mss::attr::set_pmic1_swb_voltage_range_select
+};
+static constexpr pmic_attr_setter_ptr set_swc_voltage_range_select[] =
+{
+ mss::attr::set_pmic0_swc_voltage_range_select,
+ mss::attr::set_pmic1_swc_voltage_range_select
+};
+static constexpr pmic_attr_setter_ptr set_swd_voltage_range_select[] =
+{
+ mss::attr::set_pmic0_swd_voltage_range_select,
+ mss::attr::set_pmic1_swd_voltage_range_select
+};
+
+// Voltage Offset
+static constexpr pmic_attr_setter_ptr_signed set_swa_voltage_offset[] =
+{
+ mss::attr::set_pmic0_swa_voltage_offset,
+ mss::attr::set_pmic1_swa_voltage_offset
+};
+static constexpr pmic_attr_setter_ptr_signed set_swb_voltage_offset[] =
+{
+ mss::attr::set_pmic0_swb_voltage_offset,
+ mss::attr::set_pmic1_swb_voltage_offset
+};
+static constexpr pmic_attr_setter_ptr_signed set_swc_voltage_offset[] =
+{
+ mss::attr::set_pmic0_swc_voltage_offset,
+ mss::attr::set_pmic1_swc_voltage_offset
+};
+static constexpr pmic_attr_setter_ptr_signed set_swd_voltage_offset[] =
+{
+ mss::attr::set_pmic0_swd_voltage_offset,
+ mss::attr::set_pmic1_swd_voltage_offset
+};
+
+// Sequence Delay
+static constexpr pmic_attr_setter_ptr set_swa_sequence_delay[] =
+{
+ mss::attr::set_pmic0_swa_sequence_delay,
+ mss::attr::set_pmic1_swa_sequence_delay
+};
+static constexpr pmic_attr_setter_ptr set_swb_sequence_delay[] =
+{
+ mss::attr::set_pmic0_swb_sequence_delay,
+ mss::attr::set_pmic1_swb_sequence_delay
+};
+static constexpr pmic_attr_setter_ptr set_swc_sequence_delay[] =
+{
+ mss::attr::set_pmic0_swc_sequence_delay,
+ mss::attr::set_pmic1_swc_sequence_delay
+};
+static constexpr pmic_attr_setter_ptr set_swd_sequence_delay[] =
+{
+ mss::attr::set_pmic0_swd_sequence_delay,
+ mss::attr::set_pmic1_swd_sequence_delay
+};
+
+// Sequence Order
+static constexpr pmic_attr_setter_ptr set_swa_sequence_order[] =
+{
+ mss::attr::set_pmic0_swa_sequence_order,
+ mss::attr::set_pmic1_swa_sequence_order
+};
+static constexpr pmic_attr_setter_ptr set_swb_sequence_order[] =
+{
+ mss::attr::set_pmic0_swb_sequence_order,
+ mss::attr::set_pmic1_swb_sequence_order
+};
+static constexpr pmic_attr_setter_ptr set_swc_sequence_order[] =
+{
+ mss::attr::set_pmic0_swc_sequence_order,
+ mss::attr::set_pmic1_swc_sequence_order
+};
+static constexpr pmic_attr_setter_ptr set_swd_sequence_order[] =
+{
+ mss::attr::set_pmic0_swd_sequence_order,
+ mss::attr::set_pmic1_swd_sequence_order
+};
+
+// Phase Combination
+static constexpr pmic_attr_setter_ptr set_phase_comb[] =
+{
+ mss::attr::set_pmic0_phase_comb,
+ mss::attr::set_pmic1_phase_comb
+};
+
+// Offset
+static constexpr pmic_attr_setter_ptr_signed set_efd_swa_voltage_offset[] =
+{
+ mss::attr::set_efd_pmic0_swa_voltage_offset,
+ mss::attr::set_efd_pmic1_swa_voltage_offset
+};
+
+static constexpr pmic_attr_setter_ptr_signed set_efd_swb_voltage_offset[] =
+{
+ mss::attr::set_efd_pmic0_swb_voltage_offset,
+ mss::attr::set_efd_pmic1_swb_voltage_offset
+};
+
+static constexpr pmic_attr_setter_ptr_signed set_efd_swc_voltage_offset[] =
+{
+ mss::attr::set_efd_pmic0_swc_voltage_offset,
+ mss::attr::set_efd_pmic1_swc_voltage_offset
+};
+
+static constexpr pmic_attr_setter_ptr_signed set_efd_swd_voltage_offset[] =
+{
+ mss::attr::set_efd_pmic0_swd_voltage_offset,
+ mss::attr::set_efd_pmic1_swd_voltage_offset
+};
+
+//-----------------------------------
+// SPD Biasing functions
+//-----------------------------------
+
+///
+/// @breif set VR enable bit for system startup via R32 (not broadcast)
+///
+/// @param[in] i_pmic_target PMIC target
+/// @return fapi2::FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode start_vr_enable(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target);
+
+///
+/// @brief bias PMIC0 with spd settings for phase combination (SWA, SWB or SWA+SWB)
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_port - port target of PMIC
+/// @param[in] i_dimm_index - DIMM index for PMIC (0,1)
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff no error
+///
+fapi2::ReturnCode bias_with_spd_phase_comb(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm,
+ const mss::pmic::id i_id);
+
+///
+/// @brief bias with SPD settings for voltage ranges
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_port port target of PMIC
+/// @param[in] i_dimm_index DIMM index for PMIC (0,1)
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff no error
+///
+fapi2::ReturnCode bias_with_spd_volt_ranges(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm,
+ const mss::pmic::id i_id);
+
+///
+/// @brief bias with SPD settings for startup sequence
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_port port target of PMIC
+/// @param[in] i_dimm_index DIMM index for PMIC (0,1)
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff no error
+///
+fapi2::ReturnCode bias_with_spd_startup_seq(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm,
+ const mss::pmic::id i_id);
+
+///
+/// @brief Set the startup seq register with the given parameters
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_rail rail to
+/// @param[in] i_round sequence round 1-4
+/// @param[in] i_delay delay after round
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff no error
+///
+fapi2::ReturnCode set_startup_seq_register(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const uint8_t i_rail,
+ const uint8_t i_round,
+ const uint8_t i_delay);
+
+//-----------------------------------
+// Templated SPD Biasing functions
+//-----------------------------------
+
+///
+/// @brief bias with spd settings for voltages
+///
+/// @tparam V mss::pmic::vendor (TI/IDT)
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_dimm_target DIMM target of PMIC
+/// @param[in] i_dimm_index - DIMM index for PMIC (0,1)
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff no error
+///
+template <mss::pmic::vendor V>
+fapi2::ReturnCode bias_with_spd_voltages(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm_target,
+ const mss::pmic::id i_id);
+
+///
+/// @brief Calcuate target voltage for PMIC
+///
+/// @param[in] i_dimm_target DIMM target of PMIC (holds the attributes)
+/// @param[in] i_id ID of pmic (0,1)
+/// @param[in] i_rail RAIL to calculate voltage for
+/// @param[out] o_volt_buffer output buffer
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+inline fapi2::ReturnCode calculate_voltage_write_buffer(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm_target,
+ const mss::pmic::id i_id,
+ const uint8_t i_rail,
+ fapi2::buffer<uint8_t>& o_volt_buffer)
+{
+ uint8_t l_volt = 0;
+ int8_t l_volt_offset = 0;
+ int8_t l_efd_volt_offset = 0;
+
+ // Get the attributes corresponding to the rail and PMIC indices
+ FAPI_TRY(get_volt_setting[i_rail][i_id](i_dimm_target, l_volt));
+ FAPI_TRY(get_volt_offset[i_rail][i_id](i_dimm_target, l_volt_offset));
+ FAPI_TRY(get_efd_volt_offset[i_rail][i_id](i_dimm_target, l_efd_volt_offset));
+
+ // Set output buffer
+ o_volt_buffer = l_volt + l_volt_offset + l_efd_volt_offset;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Order PMICs by sequence defined in the SPD
+///
+/// @param[in] i_dimm DIMM target to pull SPD fields from
+/// @param[in] i_dimm_index index of the DIMM target
+/// @param[in] i_pmics_per_dimm number of PMICs per dimm
+/// @param[in,out] io_pmics vector of PMICs that will be re-ordered in place
+/// @return fapi2::ReturnCode
+///
+fapi2::ReturnCode order_pmics_by_sequence(
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM> i_dimm,
+ const uint8_t i_dimm_index,
+ const uint8_t i_pmics_per_dimm,
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_PMIC>>& io_pmics);
+
+///
+/// @brief Bias with spd voltages for IDT pmic
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_dimm_target DIMM target
+/// @param[in] i_id relative ID of PMIC (0/1)
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+template <>
+inline fapi2::ReturnCode bias_with_spd_voltages<mss::pmic::vendor::IDT>(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm_target,
+ const mss::pmic::id i_id)
+{
+ using CONSTS = mss::pmic::consts<mss::pmic::product::JEDEC_COMPLIANT>;
+
+ for (uint8_t l_rail_index = mss::pmic::rail::SWA; l_rail_index <= mss::pmic::rail::SWD; ++l_rail_index)
+ {
+ fapi2::buffer<uint8_t> l_volt_buffer;
+ FAPI_TRY(calculate_voltage_write_buffer(i_dimm_target, i_id, l_rail_index, l_volt_buffer));
+
+ // Since we have unsigned integers, this should check both underflow and overflow
+ FAPI_ASSERT(l_volt_buffer <= CONSTS::MAX_VOLT_BITMAP,
+ fapi2::PMIC_VOLTAGE_OUT_OF_RANGE()
+ .set_TARGET(i_pmic_target)
+ .set_VOLTAGE_BITMAP(l_volt_buffer)
+ .set_RAIL(mss::pmic::VOLT_SETTING_ACTIVE_REGS[l_rail_index]),
+ "Voltage out of range as determined by SPD voltage +/- offset for %s of %s",
+ PMIC_RAIL_NAMES[l_rail_index], mss::c_str(i_pmic_target) );
+
+ l_volt_buffer = l_volt_buffer << CONSTS::SHIFT_VOLTAGE_FOR_REG;
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, mss::pmic::VOLT_SETTING_ACTIVE_REGS[l_rail_index], l_volt_buffer),
+ "Error writing address 0x%02hhX of PMIC %s", mss::pmic::VOLT_SETTING_ACTIVE_REGS[l_rail_index],
+ mss::c_str(i_pmic_target));
+
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Bias with spd voltages for TI pmic
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_dimm_target DIMM target
+/// @param[in] i_id relative ID of PMIC (0/1)
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+template <>
+inline fapi2::ReturnCode bias_with_spd_voltages<mss::pmic::vendor::TI>(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm_target,
+ const mss::pmic::id i_id)
+{
+ using REGS = pmicRegs<mss::pmic::product::JEDEC_COMPLIANT>;
+ using CONSTS = mss::pmic::consts<mss::pmic::product::JEDEC_COMPLIANT>;
+
+ for (uint8_t l_rail_index = mss::pmic::rail::SWA; l_rail_index <= mss::pmic::rail::SWD; ++l_rail_index)
+ {
+ fapi2::buffer<uint8_t> l_volt_buffer;
+ FAPI_TRY(calculate_voltage_write_buffer(i_dimm_target, i_id, l_rail_index, l_volt_buffer));
+
+ bool l_overflow = false;
+
+ uint8_t l_volt_range_select = 0;
+ FAPI_TRY(get_volt_range_select[l_rail_index][i_id](i_dimm_target, l_volt_range_select));
+
+ // SWD supports a RANGE 1, but NOT SWA-C
+ if (l_rail_index == mss::pmic::rail::SWD)
+ {
+ // Can set range and voltage directly
+ fapi2::buffer<uint8_t> l_volt_range_buffer;
+
+ // Read in what the register has, as to not overwrite any default values
+ FAPI_TRY(mss::pmic::i2c::reg_read_reverse_buffer(i_pmic_target, REGS::R2B, l_volt_range_buffer));
+
+ l_volt_range_buffer.writeBit<FIELDS::SWD_VOLTAGE_RANGE>(l_volt_range_select);
+
+ // Write to PMIC
+ FAPI_TRY(mss::pmic::i2c::reg_write_reverse_buffer(i_pmic_target, REGS::R2B, l_volt_range_buffer));
+ }
+ else
+ {
+ // Check if the range is range 1, in which case we will need to convert to range 0 (thanks TI)
+ if (l_volt_range_select == CONSTS::RANGE_1)
+ {
+ // Convert from RANGE1 -> RANGE0
+
+ // Since both ranges are 5mV (at least they're supposed to be)
+ // we can just subtract the difference between range 1 and 0
+ // which is 600mV -> 800mV
+ // 200mV / 5 = 40
+ uint8_t l_old_voltage = uint8_t(l_volt_buffer);
+ l_volt_buffer = l_volt_buffer - CONSTS::CONVERT_RANGE1_TO_RANGE0;
+
+ // Check for overflow (the old voltage should be larger unless we rolled over)
+ if (l_old_voltage < l_volt_buffer)
+ {
+ // Not using an extra xml error for this as overflow implies PMIC_VOLTAGE_OUT_OF_RANGE anyway.
+ FAPI_ERR("Overflow ocurred when converting SPD Range 1 voltage to TI Range 0");
+ l_overflow = true;
+ }
+ }
+ }
+
+ // Check for overflow due to range conversion (SWA-C), but also due to overflow due to offset attributes
+ FAPI_ASSERT( (!l_overflow) && (l_volt_buffer <= CONSTS::MAX_VOLT_BITMAP),
+ fapi2::PMIC_VOLTAGE_OUT_OF_RANGE()
+ .set_TARGET(i_pmic_target)
+ .set_VOLTAGE_BITMAP(l_volt_buffer)
+ .set_RAIL(mss::pmic::VOLT_SETTING_ACTIVE_REGS[l_rail_index]),
+ "Voltage out of range as determined by SPD voltage +/- offset for %s of %s",
+ PMIC_RAIL_NAMES[l_rail_index], mss::c_str(i_pmic_target) );
+
+ l_volt_buffer = l_volt_buffer << CONSTS::SHIFT_VOLTAGE_FOR_REG;
+ FAPI_TRY(mss::pmic::i2c::reg_write(i_pmic_target, mss::pmic::VOLT_SETTING_ACTIVE_REGS[l_rail_index], l_volt_buffer),
+ "Error writing address 0x%02hhX of PMIC %s", mss::pmic::VOLT_SETTING_ACTIVE_REGS[l_rail_index],
+ mss::c_str(i_pmic_target));
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Bias PMIC from SPD settings per vendor
+///
+/// @tparam V mss::pmic::vendor (IDT/TI)
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_dimm_target DIMM target associated with PMIC
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+template <mss::pmic::vendor V>
+fapi2::ReturnCode bias_with_spd_settings(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm_target);
+
+///
+/// @brief Bias IDT PMIC from SPD settings
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_dimm_target DIMM target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+template<>
+inline fapi2::ReturnCode bias_with_spd_settings<mss::pmic::vendor::IDT>(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm_target)
+{
+ using CONSTS = mss::pmic::consts<mss::pmic::product::JEDEC_COMPLIANT>;
+ // Unlock Vendor Region
+ FAPI_TRY(mss::pmic::unlock_vendor_region(i_pmic_target),
+ "Error unlocking vendor region on PMIC %s", mss::c_str(i_pmic_target));
+
+ {
+ // PMIC position/ID of the OCMB target. There could be 4 total, but we care about whether its PMIC0(2) or PMIC1(3)
+ const mss::pmic::id l_relative_pmic_id = static_cast<mss::pmic::id>(
+ mss::index(i_pmic_target) % CONSTS::NUM_UNIQUE_PMICS);
+
+ // Phase combination
+ FAPI_TRY(mss::pmic::bias_with_spd_phase_comb(i_pmic_target, i_dimm_target, l_relative_pmic_id));
+
+ // Voltage ranges
+ FAPI_TRY(mss::pmic::bias_with_spd_volt_ranges(i_pmic_target, i_dimm_target, l_relative_pmic_id));
+
+ // Voltages
+ FAPI_TRY(mss::pmic::bias_with_spd_voltages<mss::pmic::IDT>(i_pmic_target, i_dimm_target, l_relative_pmic_id));
+
+ // Startup sequence
+ FAPI_TRY(mss::pmic::bias_with_spd_startup_seq(i_pmic_target, i_dimm_target, l_relative_pmic_id));
+ }
+
+fapi_try_exit:
+ // Try to lock vendor region even in the case of an error in this function
+ return mss::pmic::lock_vendor_region(i_pmic_target, fapi2::current_err);
+}
+
+///
+/// @brief Bias TI PMIC from SPD settings
+///
+/// @param[in] i_pmic_target PMIC target
+/// @param[in] i_dimm_target DIMM target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+template<>
+inline fapi2::ReturnCode bias_with_spd_settings<mss::pmic::vendor::TI>(
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::Target<fapi2::TargetType::TARGET_TYPE_DIMM>& i_dimm_target)
+{
+ using CONSTS = mss::pmic::consts<mss::pmic::product::JEDEC_COMPLIANT>;
+ // Unlock Vendor Region
+ FAPI_TRY(mss::pmic::unlock_vendor_region(i_pmic_target),
+ "Error unlocking vendor region on PMIC %s", mss::c_str(i_pmic_target));
+
+ {
+ // PMIC position/ID of the OCMB target. There could be 4 total, but we care about whether its PMIC0(2) or PMIC1(3)
+ const mss::pmic::id l_relative_pmic_id = static_cast<mss::pmic::id>(
+ mss::index(i_pmic_target) % CONSTS::NUM_UNIQUE_PMICS);
+ // Phase combination
+ FAPI_TRY(mss::pmic::bias_with_spd_phase_comb(i_pmic_target, i_dimm_target, l_relative_pmic_id));
+
+ // Voltages
+ // TI pmic only has range 0 for SWA-C. We need to convert anything SPD that says range 1 --> range 0
+ FAPI_TRY(mss::pmic::bias_with_spd_voltages<mss::pmic::TI>(i_pmic_target, i_dimm_target, l_relative_pmic_id));
+
+ // Startup sequence
+ FAPI_TRY(mss::pmic::bias_with_spd_startup_seq(i_pmic_target, i_dimm_target, l_relative_pmic_id));
+ }
+
+fapi_try_exit:
+ // Try to lock vendor region even in the case of an error in this function
+ return mss::pmic::lock_vendor_region(i_pmic_target, fapi2::current_err);
+}
+
+//------------------- ENABLE FUNCTIONS-----------------//
+
+///
+/// @brief Enable pmics using manual mode (direct VR enable, no SPD fields)
+/// @param[in] i_pmics vector of PMICs to enable
+///
+fapi2::ReturnCode enable_manual(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_PMIC>>& i_pmics);
+
+///
+/// @brief Function to enable 1U and 2U pmics
+///
+/// @param[in] i_pmic_target - the pmic target
+/// @param[in] i_dimm_target - the dimm target that the PMIC resides on
+/// @param[in] i_vendor_id - the vendor ID of the PMIC to bias
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS if successful
+///
+fapi2::ReturnCode enable_chip_1U_2U(const fapi2::Target<fapi2::TARGET_TYPE_PMIC>& i_pmic_target,
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_dimm_target,
+ const uint16_t i_vendor_id);
+
+///
+/// @brief Disable PMICs and clear status bits in preparation for enable
+///
+/// @param[in] i_pmics vector of PMIC targets
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode disable_and_reset_pmics(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_PMIC>>& i_pmics);
+
+///
+/// @brief Enable PMIC for SPD mode
+///
+/// @param[in] i_pmics vector of PMICs sorted by mss::index
+/// @param[in] i_dimms const vector of DIMMs sorted by mss::index
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode pmic_enable_SPD(
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_PMIC>>& i_pmics,
+ const std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& i_dimms);
+}
+} // mss
+
+#endif
diff --git a/src/import/chips/ocmb/common/procedures/hwp/pmic/pmic_enable.C b/src/import/chips/ocmb/common/procedures/hwp/pmic/pmic_enable.C
new file mode 100644
index 000000000..eaab19cd5
--- /dev/null
+++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/pmic_enable.C
@@ -0,0 +1,95 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/common/procedures/hwp/pmic/pmic_enable.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file pmic_enable.C
+/// @brief Procedure definition to enable PMIC
+///
+// *HWP HWP Owner: Mark Pizzutillo <mark.pizzutillo@ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include <pmic_enable.H>
+#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/pmic_common_utils.H>
+#include <lib/utils/pmic_enable_utils.H>
+#include <lib/utils/pmic_consts.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/c_str.H>
+
+extern "C"
+{
+ ///
+ /// @brief Enable function for pmic module. Calls appropriate enable func with matching DIMM target
+ /// @param[in] i_target ocmb target
+ /// @param[in] i_mode enable mode operation
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode pmic_enable(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_target,
+ const mss::pmic::enable_mode i_mode)
+ {
+ auto l_dimms = mss::find_targets_sorted_by_index<fapi2::TARGET_TYPE_DIMM>(i_ocmb_target);
+ auto l_pmics = mss::find_targets_sorted_by_index<fapi2::TARGET_TYPE_PMIC>(i_ocmb_target);
+
+ // Check that we have PMICs (we wouldn't on gemini, for example)
+ if (l_pmics.empty())
+ {
+ FAPI_INF("No PMICs to enable on %s, exiting.", mss::c_str(i_ocmb_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Disable PMICs and clear status bits so we are starting at a known off state
+ FAPI_TRY(mss::pmic::disable_and_reset_pmics(l_pmics));
+
+ // // If we're enabling via internal settings, we can just run VR ENABLE down the line
+ if (i_mode == mss::pmic::enable_mode::MANUAL)
+ {
+ FAPI_TRY(mss::pmic::enable_manual(l_pmics));
+ }
+ else
+ {
+ if (!l_dimms.empty())
+ {
+ FAPI_TRY(mss::pmic::pmic_enable_SPD(l_pmics, l_dimms));
+ }
+ }
+
+ // Check that all the PMIC statuses are good post-enable
+ FAPI_TRY(mss::pmic::status::check_all_pmics(i_ocmb_target),
+ "Bad statuses returned, or error checking statuses of PMICs on %s", mss::c_str(i_ocmb_target));
+
+ // If we get here, statuses are good
+ FAPI_INF("All status codes were OK for PMICs on %s", mss::c_str(i_ocmb_target));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+} // extern C
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config_thermal.H b/src/import/chips/ocmb/common/procedures/hwp/pmic/pmic_enable.H
index c54c11787..e709c7f40 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config_thermal.H
+++ b/src/import/chips/ocmb/common/procedures/hwp/pmic/pmic_enable.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config_thermal.H $ */
+/* $Source: src/import/chips/ocmb/common/procedures/hwp/pmic/pmic_enable.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -24,36 +24,48 @@
/* IBM_PROLOG_END_TAG */
///
-/// @file p9a_mss_eff_config_thermal.H
-/// @brief Perform thermal calculations as part of the effective configuration
+/// @file pmic_enable.H
+/// @brief Procedure definition to enable PMIC
///
-// *HWP HWP Owner: Andre A. Marin <aamarin@us.ibm.com>
-// *HWP HWP Backup: Michael Pardeik <pardeik@us.ibm.com>
+// *HWP HWP Owner: Mark Pizzutillo <mark.pizzutillo@ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
// *HWP Team: Memory
-// *HWP Level: 1
+// *HWP Level: 2
// *HWP Consumed by: FSP:HB
-#ifndef P9A_MSS_EFF_CONFIG_THERMAL_H_
-#define P9A_MSS_EFF_CONFIG_THERMAL_H_
+#ifndef __PMIC_ENABLE_H__
+#define __PMIC_ENABLE_H__
#include <fapi2.H>
-#include <vector>
-typedef fapi2::ReturnCode (*p9a_mss_eff_config_thermal_FP_t) (const std::vector
- <fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>>&);
+namespace mss
+{
+namespace pmic
+{
-extern "C"
+///
+/// @brief Different enable operations
+///
+enum enable_mode
{
+ SPD = 0, // Use values from the SPD (default). Overwrite the vendor region with SPD settings
+ MANUAL = 1, // Use voltage settings currently in the vendor region. (Changed via pmic_update, or factory defaults)
+};
+}
+}
+
+typedef fapi2::ReturnCode (*pmic_enable_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&,
+ const mss::pmic::enable_mode);
+extern "C"
+{
///
- /// @brief Perform thermal calculations as part of the effective configuration
- /// @param[in] i_targets vector of ports (e.g., MEM_PORT) all on the same VDDR domain
+ /// @brief enable function for pmic module
+ /// @param[in] i_target ocmb target
+ /// @param[in] i_mode enable mode operation
/// @return FAPI2_RC_SUCCESS iff ok
- /// @note sets ATTR_MSS_MEM_WATT_TARGET, ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT and _PER_SLOT, and ATTR_MSS_PORT_MAXPOWER
///
- fapi2::ReturnCode p9a_mss_eff_config_thermal( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> >&
- i_targets );
-
+ fapi2::ReturnCode pmic_enable(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const mss::pmic::enable_mode i_mode = mss::pmic::enable_mode::SPD);
}
-
#endif
diff --git a/src/import/chips/ocmb/common/procedures/xml/attribute_info/pmic_eff_attributes.xml b/src/import/chips/ocmb/common/procedures/xml/attribute_info/pmic_eff_attributes.xml
new file mode 100644
index 000000000..a2488a6df
--- /dev/null
+++ b/src/import/chips/ocmb/common/procedures/xml/attribute_info/pmic_eff_attributes.xml
@@ -0,0 +1,729 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/import/chips/ocmb/common/procedures/xml/attribute_info/pmic_eff_attributes.xml $ -->
+<!-- -->
+<!-- OpenPOWER HostBoot Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2019 -->
+<!-- [+] International Business Machines Corp. -->
+<!-- -->
+<!-- -->
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); -->
+<!-- you may not use this file except in compliance with the License. -->
+<!-- You may obtain a copy of the License at -->
+<!-- -->
+<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
+<!-- -->
+<!-- Unless required by applicable law or agreed to in writing, software -->
+<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
+<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -->
+<!-- implied. See the License for the specific language governing -->
+<!-- permissions and limitations under the License. -->
+<!-- -->
+<!-- IBM_PROLOG_END_TAG -->
+<attributes>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_MFG_ID</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Manufacturer ID Code
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint16</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_mfg_id</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWA_VOLTAGE_SETTING</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWA Voltage Setting
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swa_voltage_setting</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWA_VOLTAGE_RANGE_SELECT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWA Voltage Range
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swa_voltage_range_select</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWA_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWA Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swa_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWA_SEQUENCE_DELAY</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Delay after the sequence which enables SWA
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swa_sequence_delay</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWA_SEQUENCE_ORDER</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ The sequence at which SWA will be enabled
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swa_sequence_order</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWB_VOLTAGE_SETTING</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWB Voltage Setting
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swb_voltage_setting</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWB_VOLTAGE_RANGE_SELECT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWB Voltage Range
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swb_voltage_range_select</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWB_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWB Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swb_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWB_SEQUENCE_DELAY</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Delay after the sequence which enables SWB
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swb_sequence_delay</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWB_SEQUENCE_ORDER</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ The sequence at which SWB will be enabled
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swb_sequence_order</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWC_VOLTAGE_SETTING</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWC Voltage Setting
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swc_voltage_setting</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWC_VOLTAGE_RANGE_SELECT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWC Voltage Range
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swc_voltage_range_select</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWC_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWC Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swc_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWC_SEQUENCE_DELAY</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Delay after the sequence which enables SWC
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swc_sequence_delay</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWC_SEQUENCE_ORDER</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ The sequence at which SWC will be enabled
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swc_sequence_order</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWD_VOLTAGE_SETTING</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWD Voltage Setting
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swd_voltage_setting</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWD_VOLTAGE_RANGE_SELECT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWD Voltage Range
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swd_voltage_range_select</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWD_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWD Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swd_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWD_SEQUENCE_DELAY</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Delay after the sequence which enables SWD
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swd_sequence_delay</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SWD_SEQUENCE_ORDER</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ The sequence at which SWD will be enabled
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_swd_sequence_order</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_MFG_ID</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Manufacturer ID Code
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint16</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_mfg_id</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWA_VOLTAGE_SETTING</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWA Voltage Setting
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swa_voltage_setting</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWA_VOLTAGE_RANGE_SELECT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWA Voltage Range
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swa_voltage_range_select</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWA_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWA Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swa_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWA_SEQUENCE_DELAY</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Delay after the sequence which enables SWA
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swa_sequence_delay</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWA_SEQUENCE_ORDER</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ The sequence at which SWA will be enabled
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swa_sequence_order</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWB_VOLTAGE_SETTING</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWB Voltage Setting
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swb_voltage_setting</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWB_VOLTAGE_RANGE_SELECT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWB Voltage Range
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swb_voltage_range_select</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWB_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWB Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swb_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWB_SEQUENCE_DELAY</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Delay after the sequence which enables SWB
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swb_sequence_delay</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWB_SEQUENCE_ORDER</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ The sequence at which SWB will be enabled
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swb_sequence_order</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWC_VOLTAGE_SETTING</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWC Voltage Setting
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swc_voltage_setting</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWC_VOLTAGE_RANGE_SELECT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWC Voltage Range
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swc_voltage_range_select</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWC_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWC Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swc_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWC_SEQUENCE_DELAY</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Delay after the sequence which enables SWC
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swc_sequence_delay</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWC_SEQUENCE_ORDER</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ The sequence at which SWC will be enabled
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swc_sequence_order</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWD_VOLTAGE_SETTING</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWD Voltage Setting
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swd_voltage_setting</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWD_VOLTAGE_RANGE_SELECT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWD Voltage Range
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swd_voltage_range_select</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWD_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWD Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swd_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWD_SEQUENCE_DELAY</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Delay after the sequence which enables SWD
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swd_sequence_delay</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SWD_SEQUENCE_ORDER</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ The sequence at which SWD will be enabled
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_swd_sequence_order</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_PHASE_COMB</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Phase configuration for PMIC0
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_phase_comb</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_PHASE_COMB</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Phase configuration for PMIC1
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_phase_comb</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC0_SEQUENCE</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Sequence order to enable PMIC0
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic0_sequence</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_PMIC1_SEQUENCE</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Sequence order to enable PMIC1
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>pmic1_sequence</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_EFD_PMIC0_SWA_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWA Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>efd_pmic0_swa_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_EFD_PMIC0_SWB_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWB Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>efd_pmic0_swb_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_EFD_PMIC0_SWC_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWC Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>efd_pmic0_swc_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_EFD_PMIC0_SWD_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC0 SWD Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>efd_pmic0_swd_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_EFD_PMIC1_SWA_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWA Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>efd_pmic1_swa_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_EFD_PMIC1_SWB_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWB Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>efd_pmic1_swb_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_EFD_PMIC1_SWC_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWC Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>efd_pmic1_swc_voltage_offset</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_EFD_PMIC1_SWD_VOLTAGE_OFFSET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ PMIC1 SWD Voltage Offset (signed, 1 bit increments)
+ </description>
+ <initToZero></initToZero>
+ <valueType>int8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>efd_pmic1_swd_voltage_offset</mssAccessorName>
+ </attribute>
+
+</attributes>
diff --git a/src/import/chips/ocmb/common/procedures/xml/error_info/pmic_errors.xml b/src/import/chips/ocmb/common/procedures/xml/error_info/pmic_errors.xml
new file mode 100644
index 000000000..fdc355620
--- /dev/null
+++ b/src/import/chips/ocmb/common/procedures/xml/error_info/pmic_errors.xml
@@ -0,0 +1,209 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/import/chips/ocmb/common/procedures/xml/error_info/pmic_errors.xml $ -->
+<!-- -->
+<!-- OpenPOWER HostBoot Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2019 -->
+<!-- [+] International Business Machines Corp. -->
+<!-- -->
+<!-- -->
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); -->
+<!-- you may not use this file except in compliance with the License. -->
+<!-- You may obtain a copy of the License at -->
+<!-- -->
+<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
+<!-- -->
+<!-- Unless required by applicable law or agreed to in writing, software -->
+<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
+<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -->
+<!-- implied. See the License for the specific language governing -->
+<!-- permissions and limitations under the License. -->
+<!-- -->
+<!-- IBM_PROLOG_END_TAG -->
+<hwpErrors>
+
+ <hwpError>
+ <rc>RC_I2C_PMIC_INVALID_READ_SIZE</rc>
+ <description>
+ The number of bytes returned from the read did not match
+ the expected value.
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>ADDRESS</ffdc>
+ <ffdc>SIZE_RETURNED</ffdc>
+ <ffdc>SIZE_REQUESTED</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PMIC_CHIP_NOT_RECOGNIZED</rc>
+ <description>
+ The PMIC identifier register contents did not match any known chip.
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>VENDOR_ID</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PMIC_VOLTAGE_OUT_OF_RANGE</rc>
+ <description>
+ The voltage from the SPD and offset combination or bias operation was out of range for the PMIC.
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>VOLTAGE_BITMAP</ffdc>
+ <ffdc>RAIL</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PMIC_ORDER_OUT_OF_RANGE</rc>
+ <description>
+ The sequence order specified by the SPD was out of range for the PMIC (max 4)
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>RAIL</ffdc>
+ <ffdc>ORDER</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PMIC_VOLTAGE_RANGE_SETTING_OUT_OF_RANGE</rc>
+ <description>
+ The PMIC voltage setting range was too large (Valid: 0,1)
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>RAIL</ffdc>
+ <ffdc>RANGE_SETTING</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PMIC_DELAY_OUT_OF_RANGE</rc>
+ <description>
+ The sequence delay specified by the SPD was out of range for the PMIC (max bitmap: 0b111)
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>RAIL</ffdc>
+ <ffdc>DELAY</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PMIC_DIMM_SPD_UNSUPPORTED_MODULE_HEIGHT</rc>
+ <description>
+ The module_height attribute SPD of this DIMM was not identified as 1U or 2U.
+ Other heights (4U) are not supported at this time.
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>VALUE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PMIC_NOT_ENABLED</rc>
+ <description>
+ After running pmic_enable, the PMIC VR Enable bit did not remain set.
+ Therefore, the PMIC did not enable successfully.
+ </description>
+ <ffdc>PMIC_TARGET</ffdc>
+ <ffdc>OCMB_TARGET</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>PMIC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <target>OCMB_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>OCMB_TARGET</target>
+ </deconfigure>
+ <gard>
+ <target>OCMB_TARGET</target>
+ </gard>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_PMIC_STATUS_ERRORS</rc>
+ <description>
+ After running pmic_enable, one or more error status bits were set on the PMICs of this OCMB.
+ </description>
+ <ffdc>OCMB_TARGET</ffdc>
+ <ffdc>PMIC_TARGET</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>PMIC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <target>OCMB_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>OCMB_TARGET</target>
+ </deconfigure>
+ <gard>
+ <target>OCMB_TARGET</target>
+ </gard>
+ </hwpError>
+
+</hwpErrors>
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config_thermal.C b/src/import/chips/ocmb/common/spd_access/pmic_i2c_addr_get.H
index 989fed6ab..f9134ccb4 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config_thermal.C
+++ b/src/import/chips/ocmb/common/spd_access/pmic_i2c_addr_get.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config_thermal.C $ */
+/* $Source: src/import/chips/ocmb/common/spd_access/pmic_i2c_addr_get.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,28 +22,61 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-
///
-/// @file p9a_mss_eff_config_thermal.C
-/// @brief Perform thermal calculations as part of the effective configuration
+/// @file pmic_i2c_addr_get.H
+/// @brief Function to get PMIC i2c addresses given SPD binary
///
-// *HWP HWP Owner: Andre A. Marin <aamarin@us.ibm.com>
-// *HWP HWP Backup: Michael Pardeik <pardeik@us.ibm.com>
+// *HWP HWP Owner: Mark Pizzutillo <mark.pizzutillo@ibm.com>
+// *HWP HWP Owner: Dan Crowell <dcrowell@us.ibm.com>
// *HWP Team: Memory
-// *HWP Level: 1
+// *HWP Level: 2
// *HWP Consumed by: FSP:HB
-// fapi2
-#include <p9a_mss_eff_config_thermal.H>
+///
+/// @brief Get the pmic i2c addrs from the provided spd binary
+///
+/// @param[in] i_spd SPD binary
+/// @param[out] o_pmic0_i2c_addr I2C Address from SPD
+/// @param[out] o_pmic1_i2c_addr I2C Address from SPD
+///
+
+#ifndef __PMIC_I2C_ADDR_GET__
+#define __PMIC_I2C_ADDR_GET__
+
+#include <vector>
+
+constexpr uint16_t SPD_PMIC0_I2C_BYTE = 260;
+constexpr uint16_t SPD_PMIC1_I2C_BYTE = 261;
+
+constexpr uint8_t PMIC0 = 0;
+constexpr uint8_t PMIC1 = 1;
+
+// Mapping from PMIC ID to SPD byte
+static const std::vector<uint16_t> PMIC_I2C_ADDR_VECTOR =
+{
+ SPD_PMIC0_I2C_BYTE, // [0 == PMIC0]
+ SPD_PMIC1_I2C_BYTE // [1 == PMIC1]
+};
///
-/// @brief Perform thermal calculations as part of the effective configuration
-/// @param[in] i_targets vector of ports (e.g., MEM_PORT) all on the same VDDR domain
-/// @return FAPI2_RC_SUCCESS iff ok
-/// @note sets ATTR_MSS_MEM_WATT_TARGET, ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT and _PER_SLOT, and ATTR_MSS_PORT_MAXPOWER
+/// @brief Get the pmic i2c address for the given PMIC ID
///
-fapi2::ReturnCode p9a_mss_eff_config_thermal( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> >&
- i_targets )
+/// @param[in] i_spd SPD binary
+/// @param[in] i_pmic_id PMIC ID (0,1)
+/// @return uint8_t I2C address for the given PMIC ID
+/// @note May need to be changed to support 4U SPD
+///
+inline uint8_t get_pmic_i2c_addr(const char* i_spd, const uint8_t i_pmic_id)
{
- return fapi2::FAPI2_RC_SUCCESS;
+ // Out of range, just return 0. Failsafe so we don't segfault
+ // The caller is responsible for calling this with a valid ID
+ if (i_pmic_id >= PMIC_I2C_ADDR_VECTOR.size())
+ {
+ return 0;
+ }
+
+ const uint16_t l_byte = PMIC_I2C_ADDR_VECTOR[i_pmic_id];
+ return uint8_t(i_spd[l_byte]);
}
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/common/include/exp_data_structs.H b/src/import/chips/ocmb/explorer/common/include/exp_data_structs.H
index df319eff1..2e5fcf906 100644
--- a/src/import/chips/ocmb/explorer/common/include/exp_data_structs.H
+++ b/src/import/chips/ocmb/explorer/common/include/exp_data_structs.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -56,6 +56,10 @@ enum exp_struct_sizes
SENSOR_CACHE_PADDING_SIZE_0 = 3,
SENSOR_CACHE_PADDING_SIZE_1 = 15,
+ // Constants for draminit
+ DRAMINIT_NUM_ADDR_DELAYS = 8,
+ DRAMINIT_STRUCTURE_VERSION = 2,
+
// Training response constants
TIMING_RESPONSE_2D_ARRAY_SIZE = 16,
TRAINING_RESPONSE_NUM_RANKS = 4,
@@ -63,6 +67,11 @@ enum exp_struct_sizes
TRAINING_RESPONSE_NUM_LANES = 80,
TRAINING_RESPONSE_NUM_RC = 27,
TRAINING_RESPONSE_MR6_SIZE = TRAINING_RESPONSE_NUM_RANKS * TRAINING_RESPONSE_NUM_DRAM,
+ RCW_8BIT_CUTOFF = 16,
+ EYE_MIN_MAX_SIZE = 31,
+ DBYTE_N_SIZE = 10,
+ NIBBLE_N_SIZE = 20,
+ BIT_N_SIZE = 8,
};
///
@@ -70,27 +79,29 @@ enum exp_struct_sizes
/// @brief The host command structure
/// @note The HOST uses 64 Byte Command Information Unit (IU) for sending commands to Firmware
///
-typedef struct
+typedef struct __attribute__((packed))
{
// Command Header
- uint8_t cmd_id; // Command type
- uint8_t cmd_flags; // Various flags associated with the command
- uint16_t request_identifier; // The request identifier of this transport request
- uint32_t cmd_length; // Number of bytes following the UI header
- uint32_t cmd_crc; // CRC of command data buffer, if used
- uint32_t host_work_area; // Scratchpad area for Host, FW returns this value as a reponse
- uint32_t cmd_work_area; // Scratchpad area for Firmware, can be used for tracking command progress etc.
- uint32_t padding[CMD_PADDING_SIZE]; // Fill up to the size of one cache line
- uint8_t command_argument[ARGUMENT_SIZE]; // Additional parameters associated with the command
- uint32_t cmd_header_crc; // CRC of 64 bytes of command header
-} host_fw_command_struct;
+ uint8_t cmd_id; // Command type
+ uint8_t cmd_flags; // Various flags associated with the command
+ uint16_t request_identifier; // The request identifier of this transport request
+ uint32_t cmd_length; // Number of bytes following the UI header
+ uint32_t cmd_crc; // CRC of command data buffer, if used
+ uint32_t host_work_area; // Scratchpad area for Host, FW returns this value as a reponse
+ uint32_t cmd_work_area; // Scratchpad area for Firmware, can be used for tracking command progress etc.
+ uint32_t padding[CMD_PADDING_SIZE]; // Fill up to the size of one cache line
+ uint8_t command_argument[ARGUMENT_SIZE]; // Additional parameters associated with the command
+ uint32_t cmd_header_crc; // CRC of 64 bytes of command header
+}
+host_fw_command_struct;
+
///
/// @class host_fw_response_struct
/// @brief The firmware response structure
/// @note The Firmware uses 64 Byte Response Information Unit (IU) for sending responses to HOST
///
-typedef struct
+typedef struct __attribute__((packed))
{
// Response Header
uint8_t response_id; // Response ID - same as Command ID
@@ -102,7 +113,8 @@ typedef struct
uint32_t padding[RSP_PADDING_SIZE]; // Fill up to the size of one cache line
uint8_t response_argument[ARGUMENT_SIZE]; // Additional parameters associated with the response
uint32_t response_header_crc; // CRC of 64 bytes of reponse header
-} host_fw_response_struct;
+}
+host_fw_response_struct;
///
@@ -110,12 +122,16 @@ typedef struct
/// @brief PHY initialization parameters
/// @note PHY FW module requires certain parameters from HOST software
///
-typedef struct user_input_msdg
+typedef struct __attribute__((packed)) user_input_msdg
{
+ uint32_t version_number;
+
// Choose the Dimm type from one of below:
// 0 = UDIMM
// 1 = RDIMM
- // 2 = LRDIMM
+ // 2 = LRDIMM (invalid for explorer)
+ // 3 = MDS-LRDIMM
+ // 4 = MDS
uint16_t DimmType;
// Indicates presence of DRAM at each chip select for PHY. Each
@@ -159,7 +175,7 @@ typedef struct user_input_msdg
// 0 = No Address Mirror.
uint16_t AddrMirror;
- // DRAM Column Addr Width (Valid value: 5,6,7,10)
+ // DRAM Column Addr Width (Valid value: 10)
uint16_t ColumnAddrWidth;
// DRAM Row Addr Width (Valid value: 14,15,16,17,18)
@@ -186,6 +202,16 @@ typedef struct user_input_msdg
// 0 = Normal mode (2-rank);
uint16_t Rank4Mode;
+ // Operate PHY in Encoded QuadCs Mode (only valid for
+ // RDIMM/RLDIMM) (NOT Supported in Explorer) when enabled,
+ // each CA bus drives one RCD in Encoded QuadCs mode.
+ // {cid_a/b[0],csn_a/b[1:0]} are connected to {DC0,DCS1_n,DCS0_n}
+ // to select master ranks. cid_a/b[1] is connected to DC2 to
+ // select up to 2 logic ranks (2H 3DStack)
+ // 1 = Encoded QuadCs Mode
+ // 0 = Direct DualCs Mod
+ uint16_t EncodedQuadCs;
+
// Support 1rank 3DS Device in
// 1 = 1 rank 3DS in DDP board
// PHY are connected to c[0],c[1],c[2] of DRAM);
@@ -206,6 +232,12 @@ typedef struct user_input_msdg
// 0 = Normal DDR4 DRAM;
uint16_t MRAMSupport;
+
+ // 1 = Support MDS 8H DRAM (odt[1] is connected to c[2] of
+ // MDS DRAM);
+ // 0 = Normal Mode;
+ uint16_t MDSSupport;
+
// Number of p-states used
// Always set NumPStates to 1 for Explorer.
// For the fields with Pstate array, only need to fill [0] entry.
@@ -425,7 +457,7 @@ typedef struct user_input_msdg
// Disable Receiver DFE
// PhyEqualization[1] = 0: Enable Driver FFE; = 0:
// Disable Driver FFE
- uint16_t PhyEqualization;
+ uint16_t PhyEqualization[MSDG_MAX_PSTATE];
// Initial VrefDQ (MR6)
// InitVrefDQ[6] = VrefDQ training range (same as MR6[6])
@@ -440,25 +472,43 @@ typedef struct user_input_msdg
uint16_t InitPhyVref[MSDG_MAX_PSTATE];
// Enter desired ODT[3:0] value when writing to ranks
- // OdtWrMapCs[i][3:0] ODT value when writing to rank 0
- // OdtWrMapCs[i][7:4] ODT value when writing to rank 1
- // OdtWrMapCs[i][11:8] ODT value when writing to rank 2
- // OdtWrMapCs[i][15:12] ODT value when writing to rank 3
- // [0] - ODT value for P0
- // [1] - ODT value for P1
- // [2] - ODT value for P2
- // [3] - ODT value for P3
+ // in normal mode (2 rank)
+ // OdtWrMapCs BIT [1:0] ODT_A/B[1:0] value when writing to rank 0
+ // OdtWrMapCs BIT [5:4] ODT_A/B[1:0] value when writing to rank 1
+ // If EncodedQuadCs = 1
+ // OdtWrMapCs BIT [1:0] ODT_A/B[1:0] value when writing to rank 0
+ // OdtWrMapCs BIT [5:4] ODT_A/B[1:0] value when writing to rank 1
+ // OdtWrMapCs BIT [9:8] ODT_A/B[1:0] value when writing to rank 2
+ // OdtWrMapCs BIT [13:12] ODT_A/B[1:0] value when writing to rank 3
+ // If Rank4Mode = 1
+ // OdtWrMapCs BIT [1:0] ODT_A[1:0] value when writing to rank 0
+ // OdtWrMapCs BIT [3:2] ODT_B[1:0] value when writing to rank 0
+ // OdtWrMapCs BIT [5:4] ODT_A[1:0] value when writing to rank 1
+ // OdtWrMapCs BIT [7:6] ODT_B[1:0] value when writing to rank 1
+ // OdtWrMapCs BIT [9:8] ODT_A[1:0] value when writing to rank 2
+ // OdtWrMapCs BIT [11:10] ODT_B[1:0] value when writing to rank 2
+ // OdtWrMapCs BIT [13:12] ODT_A[1:0] value when writing to rank 3
+ // OdtWrMapCs BIT [15:14] ODT_B[1:0] value when writing to rank 3
uint16_t OdtWrMapCs[MSDG_MAX_PSTATE];
- // Enter desired ODT[3:0] value when writing to ranks
- // OdtRdMapCs[i][3:0] ODT value when writing to rank 0
- // OdtRdMapCs[i][7:4] ODT value when writing to rank 1
- // OdtRdMapCs[i][11:8] ODT value when writing to rank 2
- // OdtRdMapCs[i][15:12] ODT value when writing to rank 3
- // [0] - ODT value for P0
- // [1] - ODT value for P1
- // [2] - ODT value for P2
- // [3] - ODT value for P3
+ // Enter desired ODT[3:0] value when reading from ranks
+ // in normal mode (2 rank)
+ // OdtRdMapCs BIT [1:0] ODT_A/B[1:0] value when reading from rank 0
+ // OdtRdMapCs BIT [5:4] ODT_A/B[1:0] value when reading from rank 1
+ // If EncodedQuadCs = 1
+ // OdtRdMapCs BIT [1:0] ODT_A/B[1:0] value when reading from rank 0
+ // OdtRdMapCs BIT [5:4] ODT_A/B[1:0] value when reading from rank 1
+ // OdtRdMapCs BIT [9:8] ODT_A/B[1:0] value when reading from rank 2
+ // OdtRdMapCs BIT [13:12] ODT_A/B[1:0] value when reading from rank 3
+ // If Rank4Mode = 1
+ // OdtRdMapCs BIT [1:0] ODT_A[1:0] value when reading from rank 0
+ // OdtRdMapCs BIT [3:2] ODT_B[1:0] value when reading from rank 0
+ // OdtRdMapCs BIT [5:4] ODT_A[1:0] value when reading from rank 1
+ // OdtRdMapCs BIT [7:6] ODT_B[1:0] value when reading from rank 1
+ // OdtRdMapCs BIT [9:8] ODT_A[1:0] value when reading from rank 2
+ // OdtRdMapCs BIT [11:10] ODT_B[1:0] value when reading from rank 2
+ // OdtRdMapCs BIT [13:12] ODT_A[1:0] value when reading from rank 3
+ // OdtRdMapCs BIT [15:14] ODT_B[1:0] value when reading from rank 3
uint16_t OdtRdMapCs[MSDG_MAX_PSTATE];
// Enable geardown mode during training/dfi_bist.
@@ -527,14 +577,14 @@ typedef struct user_input_msdg
// RcdIBTCtrl[1:0] CA Input Bus Termination
// RcdIBTCtrl[3:2] DCS[3:0]_n Input Bus Termination // RcdIBTCtrl[5:4] DCKE Input Bus Termination
// RcdIBTCtrl[7:6] DODT Input Bus Termination
- uint16_t RcdIBTCtrl;
+ uint16_t RcdIBTCtrl[MSDG_MAX_PSTATE];
// RCD Data Buffer Interface Driver Characteristics (F1RC00)
// RcdDBDic[0] BCOM[3:0],BODT,BCKE, driver strength
// RcdDBDic[1] Reserved
// RcdDBDic[2] BCK_t/BCK_c driver strength
// RcdDBDic[3] Reserved
- uint16_t RcdDBDic;
+ uint16_t RcdDBDic[MSDG_MAX_PSTATE];
// RCD slew rate control (F1RC02,F1RC03,F1RC04,F1RC05)
// RcdSlewRate[1:0] slew rate control of address/command
@@ -544,12 +594,27 @@ typedef struct user_input_msdg
// RcdSlewRate[9:8] slew rate control of Y1_t/c, Y3_t/c
// RcdSlewRate[11:10] slew rate control of Y0_t/c, Y2_t/c
// RcdSlewRate[13:12] slew rate control of BCOM[3:0], BODT, BCKE // RcdSlewRate[15:14] slew rate control of BCK_t/c
- uint16_t RcdSlewRate;
-
- // Enable Special mode for Emulation Support
- // [0] = 0 Normal firmware mode
- // [0] = 1 Emulation firmware mode
- uint16_t EmulationSupport;
+ uint16_t RcdSlewRate[MSDG_MAX_PSTATE];
+
+ // DFIMRL_DDRCLK: Max Read Latency counted by DDR Clock.
+ // dfi_rddata is returned (14 + DFIMRL_DDRCLK) cycles after
+ // dfi_rddata_en is asserted.
+ uint16_t DFIMRL_DDRCLK;
+
+ //ATxDly_A/B[0]: ODT[1],ODT[0],CS_N[0],CS_N[1]
+ //ATxDly_A/B[1]: ADDR[13],ADDR[5],BG[0],CKE[1]
+ //ATxDly_A/B[2]: ADDR[17],ADDR[7],BA[0],ADDR[16]
+ //ATxDly_A/B[3]: ADDR[8],BG[1],CID[1],CID[0]
+ //ATxDly_A/B[4]: ADDR[1],ADDR[9],ADDR[2],CAPARITY
+ //ATxDly_A/B[5]: ADDR[12],ADDR[3],ADDR[4],ADDR[0]
+ //ATxDly_A/B[6]: CKE[0],ADDR[15],ACT_N,ADDR[10]
+ //ATxDly_A/B[7]: ADDR[11],ADDR[6],BA[1],ADDR[14]
+ //7bit A-side AC Delay
+ //ATxDly_A[pstate][NumAnib]
+ uint8_t ATxDly_A[MSDG_MAX_PSTATE][DRAMINIT_NUM_ADDR_DELAYS];
+ //7bit B-side AC Delay
+ //ATxDly_B[pstate][NumAnib]
+ uint8_t ATxDly_B[MSDG_MAX_PSTATE][DRAMINIT_NUM_ADDR_DELAYS];
} user_input_msdg_t;
///
@@ -557,7 +622,7 @@ typedef struct user_input_msdg
/// @brief The sensor cache structure
/// @note The data in the sensor cache is returned in 2 32-byte packets
///
-typedef struct
+typedef struct __attribute__((packed))
{
/*
* Packet 0
@@ -598,14 +663,15 @@ typedef struct
uint8_t initial_packet1; // initial_packet1[0] '1' on first packet1 return, otherwise '0'
// // initial_packet1[1:7] Reserved
uint8_t reserved1[SENSOR_CACHE_PADDING_SIZE_1];
-} sensor_cache_struct;
+}
+sensor_cache_struct;
///
/// @class user_response_timing_msdg_t
/// @brief Contains the command to command timing training results
///
-typedef struct user_response_timing_msdg
+typedef struct __attribute__((packed)) user_response_timing_msdg
{
uint16_t DFIMRL_DDRCLK_trained; // Training result of DFIMRL_DDRCLK parameter (by mrlTraining step).
// DFIMRL_DDRCLK: Max Read Latency counted by DDR Clock. dfi_rddata is returned (14 + DFIMRL_DDRCLK) cycles after dfi_rddata_en is asserted.
@@ -629,7 +695,7 @@ typedef struct user_response_timing_msdg
/// @class user_response_error_msdg
/// @brief Contains the lane failure results
///
-typedef struct user_response_error_msdg
+typedef struct __attribute__((packed)) user_response_error_msdg
{
uint16_t Failure_Lane[TRAINING_RESPONSE_NUM_LANES]; // error code of DQ[n] on Rank 3,2,1 & 0. Rank 0 is in LS Nibble.
//Failure status of training. Each uint16_t field contains the training error code of all 4 ranks on 1 DQ lane.
@@ -651,7 +717,7 @@ typedef struct user_response_error_msdg
/// @class user_response_mrs_msdg_t
/// @brief MRS response structure
///
-typedef struct user_response_mrs_msdg_t
+typedef struct __attribute__((packed)) user_response_mrs_msdg_t
{
uint16_t MR0; // Value of DDR mode register MR0 for all ranks, all devices
uint16_t MR1[TRAINING_RESPONSE_NUM_RANKS]; // Value of DDR mode register MR1 for each rank (up to 4 ranks)
@@ -667,7 +733,7 @@ typedef struct user_response_mrs_msdg_t
/// @class user_response_rc_msdg_t
/// @brief RCD response structure
///
-typedef struct user_response_rc_msdg_t
+typedef struct __attribute__((packed)) user_response_rc_msdg_t
{
uint8_t F0RC_D0[TRAINING_RESPONSE_NUM_RC]; // RCD control words for DIMM0; Invalid for UDIMM
// F0RC_D0[15:0] BIT [3:0]: 4-bit value of F0RC00~F0RC0F
@@ -684,10 +750,92 @@ typedef struct user_response_rc_msdg_t
} user_response_rc_msdg_t;
///
+/// @class train_2d_eye_min_max_msdg_t
+/// @brief Microchip response structure
+///
+typedef struct __attribute__((packed)) train_2d_eye_min_max_msdg
+{
+ //2D training has to run with 1D training results in the delay registers. Horizontally it takes 1D
+ //centered value as starting position and only sweep half of a UI to left and right (1 UI in total).
+ //Vertically it takes preset vref value as starting position and sweep until bit error is detected.
+ //The assumption is that data eye will be enclosed in that range.
+ //eye_max/min contain the max/min VrefDAC0/VrefDQ value which passes test with the Nth step shift
+ //within the 1UI range. The 1D centered RxClkDly/TxDqDly is always normalized to index 15 of the
+ //array.
+ //In train_2d_read_eye_msdg, eye_max/min value represents VrefDAC0 (PHY DQ receiver Vref setting)
+ //Vref = (0.510 + VrefDAC0[6:0] * 0.00385) * VDDQ
+ //In train_2d_write_eye_msdg, eye_max/min value represents VrefDQ (Dram DQ receiver Vref setting)
+ //Vref = (0.450 + VrefDQ[6:0] * 0.0065) * VDDQ
+ uint16_t eye_min[EYE_MIN_MAX_SIZE];
+ uint16_t eye_max[EYE_MIN_MAX_SIZE];
+} train_2d_eye_min_max_msdg_t;
+
+///
+/// @class train_2d_read_eye_msdg_t
+/// @brief Microchip response structure
+///
+typedef struct __attribute__((packed)) train_2d_read_eye_msdg
+{
+ //train_2d_read_eye_msdg_t returns the read eye diagram from point of view of 2D training firmware.
+ //1D training center RxClkDly (per nibble) horizontally (left and right search), 2D training does
+ //sweep on horizontal (RxClkDly) and vertical (VrefDAC0) directions, then decide the center.
+ //2D training has to run with 1D training results in the delay registers. Horizontally it takes 1D
+ //centered value as starting position and only sweep half of a UI to left and right (1 UI in total).
+ //Vertically it takes preset vref value as starting position and sweep until bit error is detected.
+ //The assumption is that data eye will be enclosed in that range.
+ //VrefDAC0[*][*][*] contains the max/min VrefDAC0 value which passes test with the Nth step shift
+ //within the 1UI range. The 1D centered RxClkDly is always normalized to index 15 of the
+ //array.
+ //With both arrays, 2D read eye diagram can be plotted on debug host.
+
+ // VrefDAC0[RANKi][DBYTEn][BITn] Maximum
+ // and minimum passing VrefDAC0 in 2D read training
+ train_2d_eye_min_max_msdg_t VrefDAC0[TRAINING_RESPONSE_NUM_RANKS][DBYTE_N_SIZE][BIT_N_SIZE];
+
+ // VrefDAC0_Center[DBYTEn][BITn] Centered
+ // VrefDAC0 value after 2D read training
+ uint16_t VrefDAC0_Center[DBYTE_N_SIZE][BIT_N_SIZE];
+
+ // RxClkDly_Center[RANKi][NIBBLEn] Centered
+ // RxClkDly location (w.r.t. eye diagram) after 2D
+ // read training
+ uint16_t RxClkDly_Center[TRAINING_RESPONSE_NUM_RANKS][NIBBLE_N_SIZE];
+} train_2d_read_eye_msdg_t;
+
+typedef struct __attribute__((packed)) train_2d_write_eye_msdg
+{
+ //train_2d_write_eye_msdg_t returns the write eye diagram from point of view of 2D training
+ //firmware.
+ //1D training center TxDqDly (per DQ) horizontally (left and right search), 2D training does sweep
+ //on horizontal (TxDqDly) and vertical (VrefDQ) directions, then decide the center.
+ //2D training has to run with 1D training results in the delay registers. Horizontally it takes 1D
+ //centered value as starting position and only sweep half of a UI to left and right (1 UI in total).
+ //Vertically it takes preset vref value as starting position and sweep until bit error is detected.
+ //The assumption is that data eye will be enclosed in that range.
+ //VrefDQ[*][*][*] contains the max/min VrefDQ value which passes test with the Nth step shift within
+ //the 1UI range. The 1D centered TxDqDly is always normalized to index 15 of the array.
+ //With both arrays, 2D read eye diagram can be plotted on debug host.
+
+ // VrefDQ[RANKi][DBYTEn][BITn] Maximum and
+ // minimum passing VrefDQ in 2D write training
+ train_2d_eye_min_max_msdg_t VrefDQ[TRAINING_RESPONSE_NUM_RANKS][DBYTE_N_SIZE][BIT_N_SIZE];
+
+ // VrefDQ_Center[RANKi][NIBBLEn] Centered VrefDQ
+ // value after 2D write training
+ uint16_t VrefDQ_Center[TRAINING_RESPONSE_NUM_RANKS][NIBBLE_N_SIZE];
+
+ // TxDqDly_Center[RANKi][DBYTEn][BITn] Centered
+ // TxDqDly location (w.r.t. eye diagram) after 2D
+ // write training
+ uint16_t TxDqDly_Center[TRAINING_RESPONSE_NUM_RANKS][DBYTE_N_SIZE][BIT_N_SIZE];
+
+} train_2d_write_eye_msdg_t;
+
+///
/// @class user_response_msdg_t
/// @brief Microchip response structure
///
-typedef struct user_response_msdg
+typedef struct __attribute__((packed)) user_response_msdg
{
uint32_t version_number;
user_response_timing_msdg_t tm_resp;
@@ -697,4 +845,34 @@ typedef struct user_response_msdg
} user_response_msdg_t;
+///
+/// @class user_2d_eye_response_1_msdg_t
+/// @brief Microchip response structure
+///
+typedef struct __attribute__((packed)) user_2d_eye_response_1_msdg
+{
+ uint32_t version_number;
+ train_2d_read_eye_msdg_t read_2d_eye_resp;
+ user_response_timing_msdg_t tm_resp;
+ user_response_error_msdg_t err_resp;
+ user_response_mrs_msdg_t mrs_resp;
+ user_response_rc_msdg_t rc_resp;
+
+} user_2d_eye_response_1_msdg_t;
+
+///
+/// @class user_2d_eye_response_2_msdg_t
+/// @brief Microchip response structure
+///
+typedef struct __attribute__((packed)) user_2d_eye_response_2_msdg
+{
+ uint32_t version_number;
+ train_2d_write_eye_msdg_t write_2d_eye_resp;
+ user_response_timing_msdg_t tm_resp;
+ user_response_error_msdg_t err_resp;
+ user_response_mrs_msdg_t mrs_resp;
+ user_response_rc_msdg_t rc_resp;
+
+} user_2d_eye_response_2_msdg_t;
+
#endif
diff --git a/src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses.H b/src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses.H
index 010b81049..66ad88c03 100644
--- a/src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses.H
+++ b/src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses.H
@@ -23,1540 +23,1504 @@
/* */
/* IBM_PROLOG_END_TAG */
+
#ifndef __EXPLR_SCOM_ADDRESSES_H
#define __EXPLR_SCOM_ADDRESSES_H
-static const uint64_t EXPLR_DLX_CMN_CONFIG = 0x0801280Eull;
-
-
-static const uint64_t EXPLR_DLX_DL0_CONFIG0 = 0x08012810ull;
-
-
-static const uint64_t EXPLR_DLX_DL0_CONFIG1 = 0x08012811ull;
-
-
-static const uint64_t EXPLR_DLX_DL0_CYA_BITS = 0x0801281Full;
-
-
-static const uint64_t EXPLR_DLX_DL0_DEBUG_AID = 0x0801281Eull;
-
-
-static const uint64_t EXPLR_DLX_DL0_DLX_CONFIG = 0x08012818ull;
-
-
-static const uint64_t EXPLR_DLX_DL0_DLX_INFO = 0x08012819ull;
-
-
-static const uint64_t EXPLR_DLX_DL0_EDPL_MAX_COUNT = 0x08012815ull;
-
-
-static const uint64_t EXPLR_DLX_DL0_ERROR_ACTION = 0x0801281Dull;
-
-
-static const uint64_t EXPLR_DLX_DL0_ERROR_CAPTURE = 0x08012814ull;
-
-
-static const uint64_t EXPLR_DLX_DL0_ERROR_HOLD = 0x08012813ull;
-
-
-static const uint64_t EXPLR_DLX_DL0_ERROR_MASK = 0x08012812ull;
-
-
-static const uint64_t EXPLR_DLX_DL0_STATUS = 0x08012816ull;
-
-
-static const uint64_t EXPLR_DLX_DL0_TRAINING_STATUS = 0x08012817ull;
-
-
-static const uint64_t EXPLR_DLX_ERR_HOLD_LAT = 0x0801280Bull;
-
-
-static const uint64_t EXPLR_DLX_ERR_MASK_LAT = 0x0801280Aull;
-
-static const uint64_t EXPLR_DLX_MC_OMI_FIR_ACTION0_REG = 0x08012806ull;
+static const uint64_t EXPLR_DLX_CMN_CONFIG = 0x0801280Eull;
-static const uint64_t EXPLR_DLX_MC_OMI_FIR_ACTION1_REG = 0x08012807ull;
+static const uint64_t EXPLR_DLX_DL0_CONFIG0 = 0x08012810ull;
-static const uint64_t EXPLR_DLX_MC_OMI_FIR_MASK_REG = 0x08012803ull;
-static const uint64_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_AND = 0x08012804ull;
+static const uint64_t EXPLR_DLX_DL0_CONFIG1 = 0x08012811ull;
-static const uint64_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_OR = 0x08012805ull;
+static const uint64_t EXPLR_DLX_DL0_CYA_BITS = 0x0801281Full;
-static const uint64_t EXPLR_DLX_MC_OMI_FIR_REG = 0x08012800ull;
-static const uint64_t EXPLR_DLX_MC_OMI_FIR_REG_AND = 0x08012801ull;
+static const uint64_t EXPLR_DLX_DL0_DEBUG_AID = 0x0801281Eull;
-static const uint64_t EXPLR_DLX_MC_OMI_FIR_REG_OR = 0x08012802ull;
+static const uint64_t EXPLR_DLX_DL0_DLX_CONFIG = 0x08012818ull;
-static const uint64_t EXPLR_DLX_MC_OMI_FIR_WOF_REG = 0x08012808ull;
+static const uint64_t EXPLR_DLX_DL0_DLX_INFO = 0x08012819ull;
-static const uint64_t EXPLR_DLX_PMU_CNTR = 0x0801280Full;
+static const uint64_t EXPLR_DLX_DL0_EDPL_MAX_COUNT = 0x08012815ull;
-static const uint64_t EXPLR_MCBIST_CCSARRERRINJQ = 0x080118DEull;
+static const uint64_t EXPLR_DLX_DL0_ERROR_ACTION = 0x0801281Dull;
-static const uint64_t EXPLR_MCBIST_CCS_CNTLQ = 0x080118A5ull;
+static const uint64_t EXPLR_DLX_DL0_ERROR_CAPTURE = 0x08012814ull;
-static const uint64_t EXPLR_MCBIST_CCS_FIXED_DATA0Q = 0x080118E5ull;
+static const uint64_t EXPLR_DLX_DL0_ERROR_HOLD = 0x08012813ull;
-static const uint64_t EXPLR_MCBIST_CCS_FIXED_DATA1Q = 0x080118E6ull;
+static const uint64_t EXPLR_DLX_DL0_ERROR_MASK = 0x08012812ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_00 = 0x08011815ull;
+static const uint64_t EXPLR_DLX_DL0_STATUS = 0x08012816ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_01 = 0x08011816ull;
+static const uint64_t EXPLR_DLX_DL0_TRAINING_STATUS = 0x08012817ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_02 = 0x08011817ull;
+static const uint64_t EXPLR_DLX_ERR_HOLD_LAT = 0x0801280Bull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_03 = 0x08011818ull;
+static const uint64_t EXPLR_DLX_ERR_MASK_LAT = 0x0801280Aull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_04 = 0x08011819ull;
+static const uint64_t EXPLR_DLX_MC_OMI_FIR_ACTION0_REG = 0x08012806ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_05 = 0x0801181Aull;
+static const uint64_t EXPLR_DLX_MC_OMI_FIR_ACTION1_REG = 0x08012807ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_06 = 0x0801181Bull;
+static const uint64_t EXPLR_DLX_MC_OMI_FIR_MASK_REG = 0x08012803ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_07 = 0x0801181Cull;
+static const uint64_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_AND = 0x08012804ull;
+static const uint64_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_OR = 0x08012805ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_08 = 0x0801181Dull;
+static const uint64_t EXPLR_DLX_MC_OMI_FIR_REG = 0x08012800ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_09 = 0x0801181Eull;
+static const uint64_t EXPLR_DLX_MC_OMI_FIR_REG_AND = 0x08012801ull;
+static const uint64_t EXPLR_DLX_MC_OMI_FIR_REG_OR = 0x08012802ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_10 = 0x0801181Full;
+static const uint64_t EXPLR_DLX_MC_OMI_FIR_WOF_REG = 0x08012808ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_11 = 0x08011820ull;
+static const uint64_t EXPLR_DLX_PMU_CNTR = 0x0801280Full;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_12 = 0x08011821ull;
+static const uint64_t EXPLR_MCBIST_CCSARRERRINJQ = 0x080118DEull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_13 = 0x08011822ull;
+static const uint64_t EXPLR_MCBIST_CCS_CNTLQ = 0x080118A5ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_14 = 0x08011823ull;
+static const uint64_t EXPLR_MCBIST_CCS_FIXED_DATA0Q = 0x080118E5ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_15 = 0x08011824ull;
+static const uint64_t EXPLR_MCBIST_CCS_FIXED_DATA1Q = 0x080118E6ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_16 = 0x08011825ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_00 = 0x08011815ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_17 = 0x08011826ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_01 = 0x08011816ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_18 = 0x08011827ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_02 = 0x08011817ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_19 = 0x08011828ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_03 = 0x08011818ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_20 = 0x08011829ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_04 = 0x08011819ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_21 = 0x0801182Aull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_05 = 0x0801181Aull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_22 = 0x0801182Bull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_06 = 0x0801181Bull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_23 = 0x0801182Cull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_07 = 0x0801181Cull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_24 = 0x0801182Dull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_08 = 0x0801181Dull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_25 = 0x0801182Eull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_09 = 0x0801181Eull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_26 = 0x0801182Full;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_10 = 0x0801181Full;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_27 = 0x08011830ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_11 = 0x08011820ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_28 = 0x08011831ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_12 = 0x08011821ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_29 = 0x08011832ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_13 = 0x08011822ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_30 = 0x08011833ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_14 = 0x08011823ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_31 = 0x08011834ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_15 = 0x08011824ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_00 = 0x08011835ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_16 = 0x08011825ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_01 = 0x08011836ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_17 = 0x08011826ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_02 = 0x08011837ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_18 = 0x08011827ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_03 = 0x08011838ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_19 = 0x08011828ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_04 = 0x08011839ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_20 = 0x08011829ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_05 = 0x0801183Aull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_21 = 0x0801182Aull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_06 = 0x0801183Bull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_22 = 0x0801182Bull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_07 = 0x0801183Cull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_23 = 0x0801182Cull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_08 = 0x0801183Dull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_24 = 0x0801182Dull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_09 = 0x0801183Eull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_25 = 0x0801182Eull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_10 = 0x0801183Full;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_26 = 0x0801182Full;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_11 = 0x08011840ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_27 = 0x08011830ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_12 = 0x08011841ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_28 = 0x08011831ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_13 = 0x08011842ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_29 = 0x08011832ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_14 = 0x08011843ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_30 = 0x08011833ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_15 = 0x08011844ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR0_31 = 0x08011834ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_16 = 0x08011845ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_00 = 0x08011835ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_17 = 0x08011846ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_01 = 0x08011836ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_18 = 0x08011847ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_02 = 0x08011837ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_19 = 0x08011848ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_03 = 0x08011838ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_20 = 0x08011849ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_04 = 0x08011839ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_21 = 0x0801184Aull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_05 = 0x0801183Aull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_22 = 0x0801184Bull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_06 = 0x0801183Bull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_23 = 0x0801184Cull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_07 = 0x0801183Cull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_24 = 0x0801184Dull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_08 = 0x0801183Dull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_25 = 0x0801184Eull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_09 = 0x0801183Eull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_26 = 0x0801184Full;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_10 = 0x0801183Full;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_27 = 0x08011850ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_11 = 0x08011840ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_28 = 0x08011851ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_12 = 0x08011841ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_29 = 0x08011852ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_13 = 0x08011842ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_30 = 0x08011853ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_14 = 0x08011843ull;
-static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_31 = 0x08011854ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_15 = 0x08011844ull;
-static const uint64_t EXPLR_MCBIST_CCS_MODEQ = 0x080118A7ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_16 = 0x08011845ull;
-static const uint64_t EXPLR_MCBIST_CCS_STATQ = 0x080118A6ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_17 = 0x08011846ull;
-static const uint64_t EXPLR_MCBIST_DBGCFG0Q = 0x080118E8ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_18 = 0x08011847ull;
-static const uint64_t EXPLR_MCBIST_DBGCFG1Q = 0x080118E9ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_19 = 0x08011848ull;
-static const uint64_t EXPLR_MCBIST_DBGCFG2Q = 0x080118EAull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_20 = 0x08011849ull;
-static const uint64_t EXPLR_MCBIST_DBGCFG3Q = 0x080118EBull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_21 = 0x0801184Aull;
-static const uint64_t EXPLR_MCBIST_DBG_BUS_CFGQ = 0x08011872ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_22 = 0x0801184Bull;
-static const uint64_t EXPLR_MCBIST_ERR_HOLD_LAT = 0x0801180Bull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_23 = 0x0801184Cull;
-static const uint64_t EXPLR_MCBIST_ERR_MASK0Q = 0x08011873ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_24 = 0x0801184Dull;
-static const uint64_t EXPLR_MCBIST_ERR_MASK1Q = 0x08011874ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_25 = 0x0801184Eull;
-static const uint64_t EXPLR_MCBIST_ERR_MASK_LAT = 0x0801180Aull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_26 = 0x0801184Full;
-static const uint64_t EXPLR_MCBIST_MBAUER0Q = 0x0801186Eull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_27 = 0x08011850ull;
-static const uint64_t EXPLR_MCBIST_MBA_MCBERRPT0Q = 0x080118E7ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_28 = 0x08011851ull;
-static const uint64_t EXPLR_MCBIST_MBA_MCBERRPT1Q = 0x080118ECull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_29 = 0x08011852ull;
-static const uint64_t EXPLR_MCBIST_MBECTLQ = 0x08011810ull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_30 = 0x08011853ull;
-static const uint64_t EXPLR_MCBIST_MBMPER0Q = 0x0801186Cull;
+static const uint64_t EXPLR_MCBIST_CCS_INST_ARR1_31 = 0x08011854ull;
-static const uint64_t EXPLR_MCBIST_MBNCER0Q = 0x0801186Aull;
+static const uint64_t EXPLR_MCBIST_CCS_MODEQ = 0x080118A7ull;
-static const uint64_t EXPLR_MCBIST_MBRCER0Q = 0x0801186Bull;
+static const uint64_t EXPLR_MCBIST_CCS_STATQ = 0x080118A6ull;
-static const uint64_t EXPLR_MCBIST_MBSEC0Q = 0x08011855ull;
+static const uint64_t EXPLR_MCBIST_DBGCFG0Q = 0x080118E8ull;
-static const uint64_t EXPLR_MCBIST_MBSEC1Q = 0x08011856ull;
+static const uint64_t EXPLR_MCBIST_DBGCFG1Q = 0x080118E9ull;
-static const uint64_t EXPLR_MCBIST_MBSEVR0Q = 0x0801187Eull;
+static const uint64_t EXPLR_MCBIST_DBGCFG2Q = 0x080118EAull;
-static const uint64_t EXPLR_MCBIST_MBSMODESQ = 0x08011862ull;
+static const uint64_t EXPLR_MCBIST_DBGCFG3Q = 0x080118EBull;
-static const uint64_t EXPLR_MCBIST_MBSMSECQ = 0x08011869ull;
+static const uint64_t EXPLR_MCBIST_DBG_BUS_CFGQ = 0x08011872ull;
-static const uint64_t EXPLR_MCBIST_MBSSYMEC0Q = 0x08011858ull;
+static const uint64_t EXPLR_MCBIST_ERR_HOLD_LAT = 0x0801180Bull;
-static const uint64_t EXPLR_MCBIST_MBSSYMEC1Q = 0x08011859ull;
+static const uint64_t EXPLR_MCBIST_ERR_MASK0Q = 0x08011873ull;
-static const uint64_t EXPLR_MCBIST_MBSSYMEC2Q = 0x0801185Aull;
+static const uint64_t EXPLR_MCBIST_ERR_MASK1Q = 0x08011874ull;
-static const uint64_t EXPLR_MCBIST_MBSSYMEC3Q = 0x0801185Bull;
+static const uint64_t EXPLR_MCBIST_ERR_MASK_LAT = 0x0801180Aull;
-static const uint64_t EXPLR_MCBIST_MBSSYMEC4Q = 0x0801185Cull;
+static const uint64_t EXPLR_MCBIST_MBAUER0Q = 0x0801186Eull;
-static const uint64_t EXPLR_MCBIST_MBSSYMEC5Q = 0x0801185Dull;
+static const uint64_t EXPLR_MCBIST_MBA_MCBERRPT0Q = 0x080118E7ull;
-static const uint64_t EXPLR_MCBIST_MBSSYMEC6Q = 0x0801185Eull;
+static const uint64_t EXPLR_MCBIST_MBA_MCBERRPT1Q = 0x080118ECull;
-static const uint64_t EXPLR_MCBIST_MBSSYMEC7Q = 0x0801185Full;
+static const uint64_t EXPLR_MCBIST_MBECTLQ = 0x08011810ull;
-static const uint64_t EXPLR_MCBIST_MBSSYMEC8Q = 0x08011860ull;
+static const uint64_t EXPLR_MCBIST_MBMPER0Q = 0x0801186Cull;
-static const uint64_t EXPLR_MCBIST_MBSTRQ = 0x08011857ull;
+static const uint64_t EXPLR_MCBIST_MBNCER0Q = 0x0801186Aull;
-static const uint64_t EXPLR_MCBIST_MBUER0Q = 0x0801186Dull;
+static const uint64_t EXPLR_MCBIST_MBRCER0Q = 0x0801186Bull;
-static const uint64_t EXPLR_MCBIST_MBXLT0Q = 0x0801186Full;
+static const uint64_t EXPLR_MCBIST_MBSEC0Q = 0x08011855ull;
-static const uint64_t EXPLR_MCBIST_MBXLT1 = 0x08011870ull;
+static const uint64_t EXPLR_MCBIST_MBSEC1Q = 0x08011856ull;
-static const uint64_t EXPLR_MCBIST_MBXLT2 = 0x08011871ull;
+static const uint64_t EXPLR_MCBIST_MBSEVR0Q = 0x0801187Eull;
-static const uint64_t EXPLR_MCBIST_MCBACQ = 0x080118D5ull;
+static const uint64_t EXPLR_MCBIST_MBSMODESQ = 0x08011862ull;
-static const uint64_t EXPLR_MCBIST_MCBAGRAQ = 0x080118D6ull;
+static const uint64_t EXPLR_MCBIST_MBSMSECQ = 0x08011869ull;
-static const uint64_t EXPLR_MCBIST_MCBAMR0A0Q = 0x080118C8ull;
+static const uint64_t EXPLR_MCBIST_MBSSYMEC0Q = 0x08011858ull;
-static const uint64_t EXPLR_MCBIST_MCBAMR1A0Q = 0x080118C9ull;
+static const uint64_t EXPLR_MCBIST_MBSSYMEC1Q = 0x08011859ull;
-static const uint64_t EXPLR_MCBIST_MCBAMR2A0Q = 0x080118CAull;
+static const uint64_t EXPLR_MCBIST_MBSSYMEC2Q = 0x0801185Aull;
-static const uint64_t EXPLR_MCBIST_MCBAMR3A0Q = 0x080118CBull;
+static const uint64_t EXPLR_MCBIST_MBSSYMEC3Q = 0x0801185Bull;
-static const uint64_t EXPLR_MCBIST_MCBCFGQ = 0x080118E0ull;
+static const uint64_t EXPLR_MCBIST_MBSSYMEC4Q = 0x0801185Cull;
-static const uint64_t EXPLR_MCBIST_MCBDRCRQ = 0x080118BDull;
+static const uint64_t EXPLR_MCBIST_MBSSYMEC5Q = 0x0801185Dull;
-static const uint64_t EXPLR_MCBIST_MCBDRSRQ = 0x080118BCull;
+static const uint64_t EXPLR_MCBIST_MBSSYMEC6Q = 0x0801185Eull;
-static const uint64_t EXPLR_MCBIST_MCBEA0Q = 0x080118CEull;
+static const uint64_t EXPLR_MCBIST_MBSSYMEC7Q = 0x0801185Full;
-static const uint64_t EXPLR_MCBIST_MCBEA1Q = 0x080118CFull;
+static const uint64_t EXPLR_MCBIST_MBSSYMEC8Q = 0x08011860ull;
-static const uint64_t EXPLR_MCBIST_MCBEA2Q = 0x080118D2ull;
+static const uint64_t EXPLR_MCBIST_MBSSYMEC9Q = 0x08011861ull;
-static const uint64_t EXPLR_MCBIST_MCBEA3Q = 0x080118D3ull;
+static const uint64_t EXPLR_MCBIST_MBSTRQ = 0x08011857ull;
-static const uint64_t EXPLR_MCBIST_MCBFD0Q = 0x080118BEull;
+static const uint64_t EXPLR_MCBIST_MBUER0Q = 0x0801186Dull;
-static const uint64_t EXPLR_MCBIST_MCBFD1Q = 0x080118BFull;
+static const uint64_t EXPLR_MCBIST_MBXLT0Q = 0x0801186Full;
-static const uint64_t EXPLR_MCBIST_MCBFD2Q = 0x080118C0ull;
+static const uint64_t EXPLR_MCBIST_MBXLT1 = 0x08011870ull;
-static const uint64_t EXPLR_MCBIST_MCBFD3Q = 0x080118C1ull;
+static const uint64_t EXPLR_MCBIST_MBXLT2 = 0x08011871ull;
-static const uint64_t EXPLR_MCBIST_MCBFD4Q = 0x080118C2ull;
+static const uint64_t EXPLR_MCBIST_MCBACQ = 0x080118D5ull;
-static const uint64_t EXPLR_MCBIST_MCBFD5Q = 0x080118C3ull;
+static const uint64_t EXPLR_MCBIST_MCBAGRAQ = 0x080118D6ull;
-static const uint64_t EXPLR_MCBIST_MCBFD6Q = 0x080118C4ull;
+static const uint64_t EXPLR_MCBIST_MCBAMR0A0Q = 0x080118C8ull;
-static const uint64_t EXPLR_MCBIST_MCBFD7Q = 0x080118C5ull;
+static const uint64_t EXPLR_MCBIST_MCBAMR1A0Q = 0x080118C9ull;
-static const uint64_t EXPLR_MCBIST_MCBFDQ = 0x080118C6ull;
+static const uint64_t EXPLR_MCBIST_MCBAMR2A0Q = 0x080118CAull;
-static const uint64_t EXPLR_MCBIST_MCBFDSPQ = 0x080118C7ull;
+static const uint64_t EXPLR_MCBIST_MCBAMR3A0Q = 0x080118CBull;
-static const uint64_t EXPLR_MCBIST_MCBISTFIRACT0 = 0x08011806ull;
+static const uint64_t EXPLR_MCBIST_MCBCFGQ = 0x080118E0ull;
-static const uint64_t EXPLR_MCBIST_MCBISTFIRACT1 = 0x08011807ull;
+static const uint64_t EXPLR_MCBIST_MCBDRCRQ = 0x080118BDull;
-static const uint64_t EXPLR_MCBIST_MCBISTFIRMASK = 0x08011803ull;
-static const uint64_t EXPLR_MCBIST_MCBISTFIRMASK_AND = 0x08011804ull;
+static const uint64_t EXPLR_MCBIST_MCBDRSRQ = 0x080118BCull;
-static const uint64_t EXPLR_MCBIST_MCBISTFIRMASK_OR = 0x08011805ull;
+static const uint64_t EXPLR_MCBIST_MCBEA0Q = 0x080118CEull;
-static const uint64_t EXPLR_MCBIST_MCBISTFIRQ = 0x08011800ull;
-static const uint64_t EXPLR_MCBIST_MCBISTFIRQ_AND = 0x08011801ull;
+static const uint64_t EXPLR_MCBIST_MCBEA1Q = 0x080118CFull;
-static const uint64_t EXPLR_MCBIST_MCBISTFIRQ_OR = 0x08011802ull;
+static const uint64_t EXPLR_MCBIST_MCBEA2Q = 0x080118D2ull;
-static const uint64_t EXPLR_MCBIST_MCBISTFIRWOF = 0x08011808ull;
+static const uint64_t EXPLR_MCBIST_MCBEA3Q = 0x080118D3ull;
-static const uint64_t EXPLR_MCBIST_MCBLFSRA0Q = 0x080118D4ull;
+static const uint64_t EXPLR_MCBIST_MCBFD0Q = 0x080118BEull;
-static const uint64_t EXPLR_MCBIST_MCBMCATQ = 0x080118D7ull;
+static const uint64_t EXPLR_MCBIST_MCBFD1Q = 0x080118BFull;
-static const uint64_t EXPLR_MCBIST_MCBMR0Q = 0x080118A8ull;
+static const uint64_t EXPLR_MCBIST_MCBFD2Q = 0x080118C0ull;
-static const uint64_t EXPLR_MCBIST_MCBMR1Q = 0x080118A9ull;
+static const uint64_t EXPLR_MCBIST_MCBFD3Q = 0x080118C1ull;
-static const uint64_t EXPLR_MCBIST_MCBMR2Q = 0x080118AAull;
+static const uint64_t EXPLR_MCBIST_MCBFD4Q = 0x080118C2ull;
-static const uint64_t EXPLR_MCBIST_MCBMR3Q = 0x080118ABull;
+static const uint64_t EXPLR_MCBIST_MCBFD5Q = 0x080118C3ull;
-static const uint64_t EXPLR_MCBIST_MCBMR4Q = 0x080118ACull;
+static const uint64_t EXPLR_MCBIST_MCBFD6Q = 0x080118C4ull;
-static const uint64_t EXPLR_MCBIST_MCBMR5Q = 0x080118ADull;
+static const uint64_t EXPLR_MCBIST_MCBFD7Q = 0x080118C5ull;
-static const uint64_t EXPLR_MCBIST_MCBMR6Q = 0x080118AEull;
+static const uint64_t EXPLR_MCBIST_MCBFDQ = 0x080118C6ull;
-static const uint64_t EXPLR_MCBIST_MCBMR7Q = 0x080118DFull;
+static const uint64_t EXPLR_MCBIST_MCBFDSPQ = 0x080118C7ull;
-static const uint64_t EXPLR_MCBIST_MCBPARMQ = 0x080118AFull;
+static const uint64_t EXPLR_MCBIST_MCBISTFIRACT0 = 0x08011806ull;
-static const uint64_t EXPLR_MCBIST_MCBRCRQ = 0x080118B1ull;
+static const uint64_t EXPLR_MCBIST_MCBISTFIRACT1 = 0x08011807ull;
-static const uint64_t EXPLR_MCBIST_MCBRDS0Q = 0x080118B2ull;
+static const uint64_t EXPLR_MCBIST_MCBISTFIRMASK = 0x08011803ull;
-static const uint64_t EXPLR_MCBIST_MCBRDS1Q = 0x080118B3ull;
+static const uint64_t EXPLR_MCBIST_MCBISTFIRMASK_AND = 0x08011804ull;
+static const uint64_t EXPLR_MCBIST_MCBISTFIRMASK_OR = 0x08011805ull;
-static const uint64_t EXPLR_MCBIST_MCBSA0Q = 0x080118CCull;
+static const uint64_t EXPLR_MCBIST_MCBISTFIRQ = 0x08011800ull;
-static const uint64_t EXPLR_MCBIST_MCBSA1Q = 0x080118CDull;
+static const uint64_t EXPLR_MCBIST_MCBISTFIRQ_AND = 0x08011801ull;
+static const uint64_t EXPLR_MCBIST_MCBISTFIRQ_OR = 0x08011802ull;
-static const uint64_t EXPLR_MCBIST_MCBSA2Q = 0x080118D0ull;
+static const uint64_t EXPLR_MCBIST_MCBISTFIRWOF = 0x08011808ull;
-static const uint64_t EXPLR_MCBIST_MCBSA3Q = 0x080118D1ull;
+static const uint64_t EXPLR_MCBIST_MCBLFSRA0Q = 0x080118D4ull;
-static const uint64_t EXPLR_MCBIST_MCBSTATQ = 0x08011866ull;
+static const uint64_t EXPLR_MCBIST_MCBMCATQ = 0x080118D7ull;
-static const uint64_t EXPLR_MCBIST_MCB_CNTLQ = 0x080118DBull;
+static const uint64_t EXPLR_MCBIST_MCBMR0Q = 0x080118A8ull;
-static const uint64_t EXPLR_MCBIST_MCB_CNTLSTATQ = 0x080118DCull;
+static const uint64_t EXPLR_MCBIST_MCBMR1Q = 0x080118A9ull;
-static const uint64_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q = 0x080118DDull;
+static const uint64_t EXPLR_MCBIST_MCBMR2Q = 0x080118AAull;
-static const uint64_t EXPLR_MCBIST_RUNTIMECTRQ = 0x080118B0ull;
+static const uint64_t EXPLR_MCBIST_MCBMR3Q = 0x080118ABull;
-static const uint64_t EXPLR_MCBIST_WATCFG0AQ = 0x08011880ull;
+static const uint64_t EXPLR_MCBIST_MCBMR4Q = 0x080118ACull;
-static const uint64_t EXPLR_MCBIST_WATCFG0BQ = 0x08011881ull;
+static const uint64_t EXPLR_MCBIST_MCBMR5Q = 0x080118ADull;
-static const uint64_t EXPLR_MCBIST_WATCFG0CQ = 0x08011882ull;
+static const uint64_t EXPLR_MCBIST_MCBMR6Q = 0x080118AEull;
-static const uint64_t EXPLR_MCBIST_WATCFG0DQ = 0x08011883ull;
+static const uint64_t EXPLR_MCBIST_MCBMR7Q = 0x080118DFull;
-static const uint64_t EXPLR_MCBIST_WATCFG0EQ = 0x08011884ull;
+static const uint64_t EXPLR_MCBIST_MCBPARMQ = 0x080118AFull;
-static const uint64_t EXPLR_MCBIST_WATCFG1AQ = 0x08011885ull;
+static const uint64_t EXPLR_MCBIST_MCBRCRQ = 0x080118B1ull;
-static const uint64_t EXPLR_MCBIST_WATCFG1BQ = 0x08011886ull;
+static const uint64_t EXPLR_MCBIST_MCBRDS0Q = 0x080118B2ull;
-static const uint64_t EXPLR_MCBIST_WATCFG1CQ = 0x08011887ull;
+static const uint64_t EXPLR_MCBIST_MCBRDS1Q = 0x080118B3ull;
-static const uint64_t EXPLR_MCBIST_WATCFG1DQ = 0x08011888ull;
+static const uint64_t EXPLR_MCBIST_MCBSA0Q = 0x080118CCull;
-static const uint64_t EXPLR_MCBIST_WATCFG1EQ = 0x08011889ull;
+static const uint64_t EXPLR_MCBIST_MCBSA1Q = 0x080118CDull;
-static const uint64_t EXPLR_MCBIST_WATCFG2AQ = 0x0801188Aull;
+static const uint64_t EXPLR_MCBIST_MCBSA2Q = 0x080118D0ull;
-static const uint64_t EXPLR_MCBIST_WATCFG2BQ = 0x0801188Bull;
+static const uint64_t EXPLR_MCBIST_MCBSA3Q = 0x080118D1ull;
-static const uint64_t EXPLR_MCBIST_WATCFG2CQ = 0x0801188Cull;
+static const uint64_t EXPLR_MCBIST_MCBSTATQ = 0x08011866ull;
-static const uint64_t EXPLR_MCBIST_WATCFG2DQ = 0x0801188Dull;
+static const uint64_t EXPLR_MCBIST_MCB_CNTLQ = 0x080118DBull;
-static const uint64_t EXPLR_MCBIST_WATCFG2EQ = 0x0801188Eull;
+static const uint64_t EXPLR_MCBIST_MCB_CNTLSTATQ = 0x080118DCull;
-static const uint64_t EXPLR_MCBIST_WATCFG3AQ = 0x0801188Full;
+static const uint64_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q = 0x080118DDull;
-static const uint64_t EXPLR_MCBIST_WATCFG3BQ = 0x08011890ull;
+static const uint64_t EXPLR_MCBIST_RUNTIMECTRQ = 0x080118B0ull;
-static const uint64_t EXPLR_MCBIST_WATCFG3CQ = 0x08011891ull;
+static const uint64_t EXPLR_MCBIST_WATCFG0AQ = 0x08011880ull;
-static const uint64_t EXPLR_MCBIST_WATCFG3DQ = 0x08011892ull;
+static const uint64_t EXPLR_MCBIST_WATCFG0BQ = 0x08011881ull;
-static const uint64_t EXPLR_MCBIST_WATCFG3EQ = 0x08011893ull;
+static const uint64_t EXPLR_MCBIST_WATCFG0CQ = 0x08011882ull;
-static const uint64_t EXPLR_MMIO_MCFGERR = 0x080108EDull;
+static const uint64_t EXPLR_MCBIST_WATCFG0DQ = 0x08011883ull;
-static const uint64_t EXPLR_MMIO_MCFGERRA = 0x080108ECull;
+static const uint64_t EXPLR_MCBIST_WATCFG0EQ = 0x08011884ull;
-static const uint64_t EXPLR_MMIO_MCHOLD = 0x0801087Bull;
+static const uint64_t EXPLR_MCBIST_WATCFG1AQ = 0x08011885ull;
-static const uint64_t EXPLR_MMIO_MCMASK = 0x0801087Aull;
+static const uint64_t EXPLR_MCBIST_WATCFG1BQ = 0x08011886ull;
-static const uint64_t EXPLR_MMIO_MDBELL = 0x080108E6ull;
+static const uint64_t EXPLR_MCBIST_WATCFG1CQ = 0x08011887ull;
-static const uint64_t EXPLR_MMIO_MDBELLC = 0x080108E7ull;
+static const uint64_t EXPLR_MCBIST_WATCFG1DQ = 0x08011888ull;
-static const uint64_t EXPLR_MMIO_MDEBUG0 = 0x080108EEull;
+static const uint64_t EXPLR_MCBIST_WATCFG1EQ = 0x08011889ull;
-static const uint64_t EXPLR_MMIO_MDEBUG1 = 0x080108EFull;
+static const uint64_t EXPLR_MCBIST_WATCFG2AQ = 0x0801188Aull;
-static const uint64_t EXPLR_MMIO_MENTERP = 0x080108E4ull;
+static const uint64_t EXPLR_MCBIST_WATCFG2BQ = 0x0801188Bull;
-static const uint64_t EXPLR_MMIO_MERRCTL = 0x080108EAull;
+static const uint64_t EXPLR_MCBIST_WATCFG2CQ = 0x0801188Cull;
-static const uint64_t EXPLR_MMIO_MFIR = 0x08010870ull;
-static const uint64_t EXPLR_MMIO_MFIR_AND = 0x08010871ull;
+static const uint64_t EXPLR_MCBIST_WATCFG2DQ = 0x0801188Dull;
-static const uint64_t EXPLR_MMIO_MFIR_OR = 0x08010872ull;
+static const uint64_t EXPLR_MCBIST_WATCFG2EQ = 0x0801188Eull;
-static const uint64_t EXPLR_MMIO_MFIRACT0 = 0x08010876ull;
+static const uint64_t EXPLR_MCBIST_WATCFG3AQ = 0x0801188Full;
-static const uint64_t EXPLR_MMIO_MFIRACT1 = 0x08010877ull;
+static const uint64_t EXPLR_MCBIST_WATCFG3BQ = 0x08011890ull;
-static const uint64_t EXPLR_MMIO_MFIRMASK = 0x08010873ull;
-static const uint64_t EXPLR_MMIO_MFIRMASK_AND = 0x08010874ull;
+static const uint64_t EXPLR_MCBIST_WATCFG3CQ = 0x08011891ull;
-static const uint64_t EXPLR_MMIO_MFIRMASK_OR = 0x08010875ull;
+static const uint64_t EXPLR_MCBIST_WATCFG3DQ = 0x08011892ull;
-static const uint64_t EXPLR_MMIO_MFIRWOF = 0x08010878ull;
+static const uint64_t EXPLR_MCBIST_WATCFG3EQ = 0x08011893ull;
-static const uint64_t EXPLR_MMIO_MHOLD0 = 0x0801087Cull;
+static const uint64_t EXPLR_MMIO_MCFGERR = 0x080108EDull;
-static const uint64_t EXPLR_MMIO_MHOLD1 = 0x0801087Eull;
+static const uint64_t EXPLR_MMIO_MCFGERRA = 0x080108ECull;
-static const uint64_t EXPLR_MMIO_MMASK0 = 0x0801087Dull;
+static const uint64_t EXPLR_MMIO_MCHOLD = 0x0801087Bull;
-static const uint64_t EXPLR_MMIO_MMASK1 = 0x0801087Full;
+static const uint64_t EXPLR_MMIO_MCMASK = 0x0801087Aull;
-static const uint64_t EXPLR_MMIO_MMIOERR = 0x080108E8ull;
+static const uint64_t EXPLR_MMIO_MDBELL = 0x080108E6ull;
-static const uint64_t EXPLR_MMIO_MMIOEWD = 0x080108E9ull;
+static const uint64_t EXPLR_MMIO_MDBELLC = 0x080108E7ull;
-static const uint64_t EXPLR_MMIO_MPIBERR0 = 0x080108FCull;
+static const uint64_t EXPLR_MMIO_MDEBUG0 = 0x080108EEull;
-static const uint64_t EXPLR_MMIO_MPIBERR1 = 0x080108FDull;
+static const uint64_t EXPLR_MMIO_MDEBUG1 = 0x080108EFull;
-static const uint64_t EXPLR_MMIO_MPIBERR2 = 0x080108FEull;
+static const uint64_t EXPLR_MMIO_MENTERP = 0x080108E4ull;
-static const uint64_t EXPLR_MMIO_MPIBERR3 = 0x080108FFull;
+static const uint64_t EXPLR_MMIO_MERRCTL = 0x080108EAull;
-static const uint64_t EXPLR_MMIO_MSCCRNGE = 0x080108E5ull;
+static const uint64_t EXPLR_MMIO_MFIR = 0x08010870ull;
-static const uint64_t EXPLR_MMIO_O0ACTAG_O0FNID = 0x08010831ull;
+static const uint64_t EXPLR_MMIO_MFIR_AND = 0x08010871ull;
+static const uint64_t EXPLR_MMIO_MFIR_OR = 0x08010872ull;
-static const uint64_t EXPLR_MMIO_O0BAR0 = 0x08010802ull;
+static const uint64_t EXPLR_MMIO_MFIRACT0 = 0x08010876ull;
-static const uint64_t EXPLR_MMIO_O0BAR1 = 0x08010803ull;
+static const uint64_t EXPLR_MMIO_MFIRACT1 = 0x08010877ull;
-static const uint64_t EXPLR_MMIO_O0BAR2 = 0x08010804ull;
+static const uint64_t EXPLR_MMIO_MFIRMASK = 0x08010873ull;
-static const uint64_t EXPLR_MMIO_O0CAPPTR_O0ROMBAR = 0x08010806ull;
+static const uint64_t EXPLR_MMIO_MFIRMASK_AND = 0x08010874ull;
+static const uint64_t EXPLR_MMIO_MFIRMASK_OR = 0x08010875ull;
-static const uint64_t EXPLR_MMIO_O0CCD = 0x08010801ull;
+static const uint64_t EXPLR_MMIO_MFIRWOF = 0x08010878ull;
-static const uint64_t EXPLR_MMIO_O0FNVID_O0FNCAP = 0x08010830ull;
+static const uint64_t EXPLR_MMIO_MHOLD0 = 0x0801087Cull;
-static const uint64_t EXPLR_MMIO_O0MBIT_O0DID = 0x08010800ull;
+static const uint64_t EXPLR_MMIO_MHOLD1 = 0x0801087Eull;
-static const uint64_t EXPLR_MMIO_O0SSYSID = 0x08010805ull;
+static const uint64_t EXPLR_MMIO_MMASK0 = 0x0801087Dull;
-static const uint64_t EXPLR_MMIO_O0VSDLXA = 0x08010864ull;
+static const uint64_t EXPLR_MMIO_MMASK1 = 0x0801087Full;
-static const uint64_t EXPLR_MMIO_O0VSDLXB = 0x08010865ull;
+static const uint64_t EXPLR_MMIO_MMIOERR = 0x080108E8ull;
-static const uint64_t EXPLR_MMIO_O0VSFLSH = 0x08010866ull;
+static const uint64_t EXPLR_MMIO_MMIOEWD = 0x080108E9ull;
-static const uint64_t EXPLR_MMIO_O0VSID = 0x08010861ull;
+static const uint64_t EXPLR_MMIO_MPIBERR0 = 0x080108FCull;
-static const uint64_t EXPLR_MMIO_O0VSTLXA = 0x08010862ull;
+static const uint64_t EXPLR_MMIO_MPIBERR1 = 0x080108FDull;
-static const uint64_t EXPLR_MMIO_O0VSTLXB = 0x08010863ull;
+static const uint64_t EXPLR_MMIO_MPIBERR2 = 0x080108FEull;
-static const uint64_t EXPLR_MMIO_O0VSVID_O0VSCAP = 0x08010860ull;
+static const uint64_t EXPLR_MMIO_MPIBERR3 = 0x080108FFull;
-static const uint64_t EXPLR_MMIO_O1ACTAG_O1FNID = 0x080108B1ull;
+static const uint64_t EXPLR_MMIO_MSCCRNGE = 0x080108E5ull;
-static const uint64_t EXPLR_MMIO_O1BAR0 = 0x08010882ull;
+static const uint64_t EXPLR_MMIO_O0ACTAG_O0FNID = 0x08010831ull;
-static const uint64_t EXPLR_MMIO_O1BAR1 = 0x08010883ull;
+static const uint64_t EXPLR_MMIO_O0BAR0 = 0x08010802ull;
-static const uint64_t EXPLR_MMIO_O1BAR2 = 0x08010884ull;
+static const uint64_t EXPLR_MMIO_O0BAR1 = 0x08010803ull;
-static const uint64_t EXPLR_MMIO_O1CAPPTR_O1ROMBAR = 0x08010886ull;
+static const uint64_t EXPLR_MMIO_O0BAR2 = 0x08010804ull;
-static const uint64_t EXPLR_MMIO_O1CCD = 0x08010881ull;
+static const uint64_t EXPLR_MMIO_O0CAPPTR_O0ROMBAR = 0x08010806ull;
-static const uint64_t EXPLR_MMIO_O1FNVID_O1FNCAP = 0x080108B0ull;
+static const uint64_t EXPLR_MMIO_O0CCD = 0x08010801ull;
-static const uint64_t EXPLR_MMIO_O1INFDAT = 0x080108C2ull;
+static const uint64_t EXPLR_MMIO_O0FNVID_O0FNCAP = 0x08010830ull;
-static const uint64_t EXPLR_MMIO_O1INFOFF_O1INFID = 0x080108C1ull;
+static const uint64_t EXPLR_MMIO_O0MBIT_O0DID = 0x08010800ull;
-static const uint64_t EXPLR_MMIO_O1INFVID_O1INFCAP = 0x080108C0ull;
+static const uint64_t EXPLR_MMIO_O0SSYSID = 0x08010805ull;
-static const uint64_t EXPLR_MMIO_O1MBIT_O1DID = 0x08010880ull;
+static const uint64_t EXPLR_MMIO_O0VSDLXA = 0x08010864ull;
-static const uint64_t EXPLR_MMIO_O1SSYSID = 0x08010885ull;
+static const uint64_t EXPLR_MMIO_O0VSDLXB = 0x08010865ull;
-static const uint64_t EXPLR_MMIO_O1VSID = 0x080108E1ull;
+static const uint64_t EXPLR_MMIO_O0VSFLSH = 0x08010866ull;
-static const uint64_t EXPLR_MMIO_O1VSVID_O1VSCAP = 0x080108E0ull;
+static const uint64_t EXPLR_MMIO_O0VSID = 0x08010861ull;
-static const uint64_t EXPLR_MMIO_OAFUVER_ONAME5 = 0x080108F3ull;
+static const uint64_t EXPLR_MMIO_O0VSTLXA = 0x08010862ull;
-static const uint64_t EXPLR_MMIO_OCTRLENB_OCTRLID = 0x080108D1ull;
+static const uint64_t EXPLR_MMIO_O0VSTLXB = 0x08010863ull;
-static const uint64_t EXPLR_MMIO_OCTRLPID = 0x080108D2ull;
+static const uint64_t EXPLR_MMIO_O0VSVID_O0VSCAP = 0x08010860ull;
-static const uint64_t EXPLR_MMIO_OCTRLTAG = 0x080108D3ull;
+static const uint64_t EXPLR_MMIO_O1ACTAG_O1FNID = 0x080108B1ull;
-static const uint64_t EXPLR_MMIO_OCTRLVID_OCTRLCAP = 0x080108D0ull;
+static const uint64_t EXPLR_MMIO_O1BAR0 = 0x08010882ull;
-static const uint64_t EXPLR_MMIO_ODSNHI = 0x08010811ull;
+static const uint64_t EXPLR_MMIO_O1BAR1 = 0x08010883ull;
-static const uint64_t EXPLR_MMIO_ODSNLO_ODSNCAP = 0x08010810ull;
+static const uint64_t EXPLR_MMIO_O1BAR2 = 0x08010884ull;
-static const uint64_t EXPLR_MMIO_OGMMIOOF = 0x080108F4ull;
+static const uint64_t EXPLR_MMIO_O1CAPPTR_O1ROMBAR = 0x08010886ull;
-static const uint64_t EXPLR_MMIO_OGMMIOSZ = 0x080108F5ull;
+static const uint64_t EXPLR_MMIO_O1CCD = 0x08010881ull;
-static const uint64_t EXPLR_MMIO_OMEMADDR = 0x080108F8ull;
+static const uint64_t EXPLR_MMIO_O1FNVID_O1FNCAP = 0x080108B0ull;
-static const uint64_t EXPLR_MMIO_ONAME0_ODESCTML = 0x080108F0ull;
+static const uint64_t EXPLR_MMIO_O1INFDAT = 0x080108C2ull;
-static const uint64_t EXPLR_MMIO_ONAME21 = 0x080108F1ull;
+static const uint64_t EXPLR_MMIO_O1INFOFF_O1INFID = 0x080108C1ull;
-static const uint64_t EXPLR_MMIO_ONAME43 = 0x080108F2ull;
+static const uint64_t EXPLR_MMIO_O1INFVID_O1INFCAP = 0x080108C0ull;
-static const uint64_t EXPLR_MMIO_OPASID = 0x08010890ull;
+static const uint64_t EXPLR_MMIO_O1MBIT_O1DID = 0x08010880ull;
-static const uint64_t EXPLR_MMIO_OPMMIOOF = 0x080108F6ull;
+static const uint64_t EXPLR_MMIO_O1SSYSID = 0x08010885ull;
-static const uint64_t EXPLR_MMIO_OPMMIOST = 0x080108F7ull;
+static const uint64_t EXPLR_MMIO_O1VSID = 0x080108E1ull;
-static const uint64_t EXPLR_MMIO_ORRCAP10 = 0x08010826ull;
+static const uint64_t EXPLR_MMIO_O1VSVID_O1VSCAP = 0x080108E0ull;
-static const uint64_t EXPLR_MMIO_ORRCAP32 = 0x08010827ull;
+static const uint64_t EXPLR_MMIO_OAFUVER_ONAME5 = 0x080108F3ull;
-static const uint64_t EXPLR_MMIO_ORRCAP54 = 0x08010828ull;
+static const uint64_t EXPLR_MMIO_OCTRLENB_OCTRLID = 0x080108D1ull;
-static const uint64_t EXPLR_MMIO_ORRCAP76 = 0x08010829ull;
+static const uint64_t EXPLR_MMIO_OCTRLPID = 0x080108D2ull;
-static const uint64_t EXPLR_MMIO_ORTCAP = 0x08010823ull;
+static const uint64_t EXPLR_MMIO_OCTRLTAG = 0x080108D3ull;
-static const uint64_t EXPLR_MMIO_OSYSMEML = 0x080108FBull;
+static const uint64_t EXPLR_MMIO_OCTRLVID_OCTRLCAP = 0x080108D0ull;
-static const uint64_t EXPLR_MMIO_OTLVID_OTLCAP = 0x08010820ull;
+static const uint64_t EXPLR_MMIO_ODSNHI = 0x08010811ull;
-static const uint64_t EXPLR_MMIO_OTRCFG10 = 0x0801082Aull;
+static const uint64_t EXPLR_MMIO_ODSNLO_ODSNCAP = 0x08010810ull;
-static const uint64_t EXPLR_MMIO_OTRCFG32 = 0x0801082Bull;
+static const uint64_t EXPLR_MMIO_OGMMIOOF = 0x080108F4ull;
-static const uint64_t EXPLR_MMIO_OTRCFG54 = 0x0801082Cull;
+static const uint64_t EXPLR_MMIO_OGMMIOSZ = 0x080108F5ull;
-static const uint64_t EXPLR_MMIO_OTRCFG76 = 0x0801082Dull;
+static const uint64_t EXPLR_MMIO_OMEMADDR = 0x080108F8ull;
-static const uint64_t EXPLR_MMIO_OTTCFG = 0x08010824ull;
+static const uint64_t EXPLR_MMIO_ONAME0_ODESCTML = 0x080108F0ull;
-static const uint64_t EXPLR_MMIO_OVERCAP_OTLID = 0x08010821ull;
+static const uint64_t EXPLR_MMIO_ONAME21 = 0x080108F1ull;
-static const uint64_t EXPLR_MMIO_OVERCFG = 0x08010822ull;
+static const uint64_t EXPLR_MMIO_ONAME43 = 0x080108F2ull;
-static const uint64_t EXPLR_MMIO_OVPD = 0x08010808ull;
+static const uint64_t EXPLR_MMIO_OPASID = 0x08010890ull;
-static const uint64_t EXPLR_MMIO_OWWID10 = 0x080108F9ull;
+static const uint64_t EXPLR_MMIO_OPMMIOOF = 0x080108F6ull;
-static const uint64_t EXPLR_MMIO_OWWID32 = 0x080108FAull;
+static const uint64_t EXPLR_MMIO_OPMMIOST = 0x080108F7ull;
-static const uint64_t EXPLR_MMIO_SCOMEWD = 0x080108EBull;
+static const uint64_t EXPLR_MMIO_ORRCAP10 = 0x08010826ull;
-static const uint64_t EXPLR_MMIO_SNSC_ACTPWRUP = 0x08010855ull;
+static const uint64_t EXPLR_MMIO_ORRCAP32 = 0x08010827ull;
-static const uint64_t EXPLR_MMIO_SNSC_D0THERM = 0x08010852ull;
+static const uint64_t EXPLR_MMIO_ORRCAP54 = 0x08010828ull;
-static const uint64_t EXPLR_MMIO_SNSC_D1THERM = 0x08010853ull;
+static const uint64_t EXPLR_MMIO_ORRCAP76 = 0x08010829ull;
-static const uint64_t EXPLR_MMIO_SNSC_FRAMESR = 0x08010856ull;
+static const uint64_t EXPLR_MMIO_ORTCAP = 0x08010823ull;
-static const uint64_t EXPLR_MMIO_SNSC_HISTOBASELOW = 0x08010857ull;
+static const uint64_t EXPLR_MMIO_OSYSMEML = 0x080108FBull;
-static const uint64_t EXPLR_MMIO_SNSC_HISTOMEDHIGH = 0x08010858ull;
+static const uint64_t EXPLR_MMIO_OTLVID_OTLCAP = 0x08010820ull;
-static const uint64_t EXPLR_MMIO_SNSC_OCTHERM = 0x08010851ull;
+static const uint64_t EXPLR_MMIO_OTRCFG10 = 0x0801082Aull;
-static const uint64_t EXPLR_MMIO_SNSC_RDWR = 0x08010854ull;
+static const uint64_t EXPLR_MMIO_OTRCFG32 = 0x0801082Bull;
-static const uint64_t EXPLR_MMIO_SNSC_STATEREG = 0x08010850ull;
+static const uint64_t EXPLR_MMIO_OTRCFG54 = 0x0801082Cull;
-static const uint64_t EXPLR_RDF_AACR = 0x08011C29ull;
+static const uint64_t EXPLR_MMIO_OTRCFG76 = 0x0801082Dull;
-static const uint64_t EXPLR_RDF_AADR = 0x08011C2Aull;
+static const uint64_t EXPLR_MMIO_OTTCFG = 0x08010824ull;
-static const uint64_t EXPLR_RDF_AAER = 0x08011C2Bull;
+static const uint64_t EXPLR_MMIO_OVERCAP_OTLID = 0x08010821ull;
-static const uint64_t EXPLR_RDF_ACTION0 = 0x08011C06ull;
+static const uint64_t EXPLR_MMIO_OVERCFG = 0x08010822ull;
-static const uint64_t EXPLR_RDF_ACTION1 = 0x08011C07ull;
+static const uint64_t EXPLR_MMIO_OVPD = 0x08010808ull;
-static const uint64_t EXPLR_RDF_CERR0 = 0x08011C0Eull;
+static const uint64_t EXPLR_MMIO_OWWID10 = 0x080108F9ull;
-static const uint64_t EXPLR_RDF_CERR1 = 0x08011C0Full;
+static const uint64_t EXPLR_MMIO_OWWID32 = 0x080108FAull;
-static const uint64_t EXPLR_RDF_CGDR = 0x08011C32ull;
+static const uint64_t EXPLR_MMIO_SCOMEWD = 0x080108EBull;
-static const uint64_t EXPLR_RDF_CTCR = 0x08011C28ull;
+static const uint64_t EXPLR_MMIO_SNSC_ACTPWRUP = 0x08010855ull;
-static const uint64_t EXPLR_RDF_DBGR = 0x08011C2Eull;
+static const uint64_t EXPLR_MMIO_SNSC_D0THERM = 0x08010852ull;
-static const uint64_t EXPLR_RDF_EICR = 0x08011C0Dull;
+static const uint64_t EXPLR_MMIO_SNSC_D1THERM = 0x08010853ull;
-static const uint64_t EXPLR_RDF_ELPR = 0x08011C2Full;
+static const uint64_t EXPLR_MMIO_SNSC_FRAMESR = 0x08010856ull;
-static const uint64_t EXPLR_RDF_ERR_HOLD_LAT = 0x08011C0Bull;
+static const uint64_t EXPLR_MMIO_SNSC_HISTOBASELOW = 0x08010857ull;
-static const uint64_t EXPLR_RDF_ERR_MASK_LAT = 0x08011C0Aull;
+static const uint64_t EXPLR_MMIO_SNSC_HISTOMEDHIGH = 0x08010858ull;
-static const uint64_t EXPLR_RDF_FIR = 0x08011C00ull;
-static const uint64_t EXPLR_RDF_FIR_AND = 0x08011C01ull;
+static const uint64_t EXPLR_MMIO_SNSC_OCTHERM = 0x08010851ull;
-static const uint64_t EXPLR_RDF_FIR_OR = 0x08011C02ull;
+static const uint64_t EXPLR_MMIO_SNSC_RDWR = 0x08010854ull;
-static const uint64_t EXPLR_RDF_FWMS0 = 0x08011C18ull;
+static const uint64_t EXPLR_MMIO_SNSC_STATEREG = 0x08010850ull;
-static const uint64_t EXPLR_RDF_FWMS1 = 0x08011C19ull;
+static const uint64_t EXPLR_RDF_AACR = 0x08011C29ull;
-static const uint64_t EXPLR_RDF_FWMS2 = 0x08011C1Aull;
+static const uint64_t EXPLR_RDF_AADR = 0x08011C2Aull;
-static const uint64_t EXPLR_RDF_FWMS3 = 0x08011C1Bull;
+static const uint64_t EXPLR_RDF_AAER = 0x08011C2Bull;
-static const uint64_t EXPLR_RDF_FWMS4 = 0x08011C1Cull;
+static const uint64_t EXPLR_RDF_ACTION0 = 0x08011C06ull;
-static const uint64_t EXPLR_RDF_FWMS5 = 0x08011C1Dull;
+static const uint64_t EXPLR_RDF_ACTION1 = 0x08011C07ull;
-static const uint64_t EXPLR_RDF_FWMS6 = 0x08011C1Eull;
+static const uint64_t EXPLR_RDF_CERR0 = 0x08011C0Eull;
-static const uint64_t EXPLR_RDF_FWMS7 = 0x08011C1Full;
+static const uint64_t EXPLR_RDF_CERR1 = 0x08011C0Full;
-static const uint64_t EXPLR_RDF_HWMS0 = 0x08011C10ull;
+static const uint64_t EXPLR_RDF_CGDR = 0x08011C32ull;
-static const uint64_t EXPLR_RDF_HWMS1 = 0x08011C11ull;
+static const uint64_t EXPLR_RDF_CTCR = 0x08011C28ull;
-static const uint64_t EXPLR_RDF_HWMS2 = 0x08011C12ull;
+static const uint64_t EXPLR_RDF_DBGR = 0x08011C2Eull;
-static const uint64_t EXPLR_RDF_HWMS3 = 0x08011C13ull;
+static const uint64_t EXPLR_RDF_EICR = 0x08011C0Dull;
-static const uint64_t EXPLR_RDF_HWMS4 = 0x08011C14ull;
+static const uint64_t EXPLR_RDF_ELPR = 0x08011C2Full;
-static const uint64_t EXPLR_RDF_HWMS5 = 0x08011C15ull;
+static const uint64_t EXPLR_RDF_ERR_HOLD_LAT = 0x08011C0Bull;
-static const uint64_t EXPLR_RDF_HWMS6 = 0x08011C16ull;
+static const uint64_t EXPLR_RDF_ERR_MASK_LAT = 0x08011C0Aull;
-static const uint64_t EXPLR_RDF_HWMS7 = 0x08011C17ull;
+static const uint64_t EXPLR_RDF_FIR = 0x08011C00ull;
-static const uint64_t EXPLR_RDF_MASK = 0x08011C03ull;
+static const uint64_t EXPLR_RDF_FIR_AND = 0x08011C01ull;
-static const uint64_t EXPLR_RDF_MASK_AND = 0x08011C04ull;
+static const uint64_t EXPLR_RDF_FIR_OR = 0x08011C02ull;
-static const uint64_t EXPLR_RDF_MASK_OR = 0x08011C05ull;
+static const uint64_t EXPLR_RDF_FWMS0 = 0x08011C18ull;
-static const uint64_t EXPLR_RDF_MASK0 = 0x08011C30ull;
+static const uint64_t EXPLR_RDF_FWMS1 = 0x08011C19ull;
-static const uint64_t EXPLR_RDF_MASK1 = 0x08011C31ull;
+static const uint64_t EXPLR_RDF_FWMS2 = 0x08011C1Aull;
-static const uint64_t EXPLR_RDF_MCBCM = 0x08011C2Cull;
+static const uint64_t EXPLR_RDF_FWMS3 = 0x08011C1Bull;
-static const uint64_t EXPLR_RDF_MSR = 0x08011C0Cull;
+static const uint64_t EXPLR_RDF_FWMS4 = 0x08011C1Cull;
-static const uint64_t EXPLR_RDF_RECR = 0x08011C2Dull;
+static const uint64_t EXPLR_RDF_FWMS5 = 0x08011C1Dull;
-static const uint64_t EXPLR_RDF_RSPAR = 0x08011C20ull;
+static const uint64_t EXPLR_RDF_FWMS6 = 0x08011C1Eull;
-static const uint64_t EXPLR_RDF_WOF = 0x08011C08ull;
+static const uint64_t EXPLR_RDF_FWMS7 = 0x08011C1Full;
-static const uint64_t EXPLR_SRQ_ERR_HOLD_LAT = 0x0801140Bull;
+static const uint64_t EXPLR_RDF_HWMS0 = 0x08011C10ull;
-static const uint64_t EXPLR_SRQ_ERR_MASK_LAT = 0x0801140Aull;
+static const uint64_t EXPLR_RDF_HWMS1 = 0x08011C11ull;
-static const uint64_t EXPLR_SRQ_MBAREF0Q = 0x08011434ull;
+static const uint64_t EXPLR_RDF_HWMS2 = 0x08011C12ull;
-static const uint64_t EXPLR_SRQ_MBAREFAQ = 0x08011438ull;
+static const uint64_t EXPLR_RDF_HWMS3 = 0x08011C13ull;
-static const uint64_t EXPLR_SRQ_MBARPC0Q = 0x08011436ull;
+static const uint64_t EXPLR_RDF_HWMS4 = 0x08011C14ull;
-static const uint64_t EXPLR_SRQ_MBARSVD0 = 0x08011435ull;
+static const uint64_t EXPLR_RDF_HWMS5 = 0x08011C15ull;
-static const uint64_t EXPLR_SRQ_MBASTR0Q = 0x08011437ull;
+static const uint64_t EXPLR_RDF_HWMS6 = 0x08011C16ull;
-static const uint64_t EXPLR_SRQ_MBA_DBG0Q = 0x0801141Eull;
+static const uint64_t EXPLR_RDF_HWMS7 = 0x08011C17ull;
-static const uint64_t EXPLR_SRQ_MBA_DBG1Q = 0x0801141Full;
+static const uint64_t EXPLR_RDF_MASK = 0x08011C03ull;
-static const uint64_t EXPLR_SRQ_MBA_DSM0Q = 0x0801140Cull;
+static const uint64_t EXPLR_RDF_MASK_AND = 0x08011C04ull;
+static const uint64_t EXPLR_RDF_MASK_OR = 0x08011C05ull;
-static const uint64_t EXPLR_SRQ_MBA_ERR_REPORTQ = 0x0801141Cull;
+static const uint64_t EXPLR_RDF_MASK0 = 0x08011C30ull;
-static const uint64_t EXPLR_SRQ_MBA_ERR_REPORTQ_MASK = 0x0801142Bull;
+static const uint64_t EXPLR_RDF_MASK1 = 0x08011C31ull;
-static const uint64_t EXPLR_SRQ_MBA_FARB0Q = 0x08011415ull;
+static const uint64_t EXPLR_RDF_MCBCM = 0x08011C34ull;
-static const uint64_t EXPLR_SRQ_MBA_FARB1Q = 0x08011416ull;
+static const uint64_t EXPLR_RDF_MCBCM2 = 0x08011C35ull;
-static const uint64_t EXPLR_SRQ_MBA_FARB2Q = 0x08011417ull;
+static const uint64_t EXPLR_RDF_MSR = 0x08011C0Cull;
-static const uint64_t EXPLR_SRQ_MBA_FARB3Q = 0x08011418ull;
+static const uint64_t EXPLR_RDF_RECR = 0x08011C2Dull;
-static const uint64_t EXPLR_SRQ_MBA_FARB4Q = 0x08011419ull;
+static const uint64_t EXPLR_RDF_RSPAR = 0x08011C20ull;
-static const uint64_t EXPLR_SRQ_MBA_FARB5Q = 0x0801141Aull;
+static const uint64_t EXPLR_RDF_WOF = 0x08011C08ull;
-static const uint64_t EXPLR_SRQ_MBA_FARB6Q = 0x0801141Bull;
+static const uint64_t EXPLR_SRQ_ERR_HOLD_LAT = 0x0801140Bull;
-static const uint64_t EXPLR_SRQ_MBA_FARB7Q = 0x0801141Dull;
+static const uint64_t EXPLR_SRQ_ERR_MASK_LAT = 0x0801140Aull;
-static const uint64_t EXPLR_SRQ_MBA_FARB8Q = 0x08011420ull;
+static const uint64_t EXPLR_SRQ_MBAREF0Q = 0x08011434ull;
-static const uint64_t EXPLR_SRQ_MBA_FARB9Q = 0x08011411ull;
+static const uint64_t EXPLR_SRQ_MBAREFAQ = 0x08011438ull;
-static const uint64_t EXPLR_SRQ_MBA_PMU0Q = 0x08011439ull;
+static const uint64_t EXPLR_SRQ_MBARPC0Q = 0x08011436ull;
-static const uint64_t EXPLR_SRQ_MBA_PMU1Q = 0x0801143Aull;
+static const uint64_t EXPLR_SRQ_MBARSVD0 = 0x08011435ull;
-static const uint64_t EXPLR_SRQ_MBA_PMU2Q = 0x0801143Bull;
+static const uint64_t EXPLR_SRQ_MBASTR0Q = 0x08011437ull;
-static const uint64_t EXPLR_SRQ_MBA_PMU3Q = 0x0801143Cull;
+static const uint64_t EXPLR_SRQ_MBA_DBG0Q = 0x0801141Eull;
-static const uint64_t EXPLR_SRQ_MBA_PMU4Q = 0x0801143Dull;
+static const uint64_t EXPLR_SRQ_MBA_DBG1Q = 0x0801141Full;
-static const uint64_t EXPLR_SRQ_MBA_PMU5Q = 0x0801143Eull;
+static const uint64_t EXPLR_SRQ_MBA_DSM0Q = 0x0801140Cull;
-static const uint64_t EXPLR_SRQ_MBA_PMU6Q = 0x0801143Full;
+static const uint64_t EXPLR_SRQ_MBA_ERR_REPORTQ = 0x0801141Cull;
-static const uint64_t EXPLR_SRQ_MBA_PMU7Q = 0x08011440ull;
+static const uint64_t EXPLR_SRQ_MBA_ERR_REPORTQ_MASK = 0x0801142Bull;
-static const uint64_t EXPLR_SRQ_MBA_PMU8Q = 0x08011441ull;
+static const uint64_t EXPLR_SRQ_MBA_FARB0Q = 0x08011415ull;
-static const uint64_t EXPLR_SRQ_MBA_RRQ0Q = 0x08011410ull;
+static const uint64_t EXPLR_SRQ_MBA_FARB1Q = 0x08011416ull;
-static const uint64_t EXPLR_SRQ_MBA_SYNCCNTLQ = 0x0801142Aull;
+static const uint64_t EXPLR_SRQ_MBA_FARB2Q = 0x08011417ull;
-static const uint64_t EXPLR_SRQ_MBA_TMR0Q = 0x0801140Dull;
+static const uint64_t EXPLR_SRQ_MBA_FARB3Q = 0x08011418ull;
-static const uint64_t EXPLR_SRQ_MBA_TMR1Q = 0x0801140Eull;
+static const uint64_t EXPLR_SRQ_MBA_FARB4Q = 0x08011419ull;
-static const uint64_t EXPLR_SRQ_MBA_TMR2Q = 0x08011431ull;
+static const uint64_t EXPLR_SRQ_MBA_FARB5Q = 0x0801141Aull;
-static const uint64_t EXPLR_SRQ_MBA_WRQ0Q = 0x0801140Full;
+static const uint64_t EXPLR_SRQ_MBA_FARB6Q = 0x0801141Bull;
-static const uint64_t EXPLR_SRQ_SRQCFG0 = 0x0801142Eull;
+static const uint64_t EXPLR_SRQ_MBA_FARB7Q = 0x0801141Dull;
-static const uint64_t EXPLR_SRQ_SRQFIRQ = 0x08011400ull;
-static const uint64_t EXPLR_SRQ_SRQFIRQ_AND = 0x08011401ull;
+static const uint64_t EXPLR_SRQ_MBA_FARB8Q = 0x08011420ull;
-static const uint64_t EXPLR_SRQ_SRQFIRQ_OR = 0x08011402ull;
+static const uint64_t EXPLR_SRQ_MBA_FARB9Q = 0x08011411ull;
-static const uint64_t EXPLR_SRQ_SRQFIRWOF = 0x08011408ull;
+static const uint64_t EXPLR_SRQ_MBA_PMU0Q = 0x08011439ull;
-static const uint64_t EXPLR_SRQ_SRQFIR_ACTION0 = 0x08011406ull;
+static const uint64_t EXPLR_SRQ_MBA_PMU1Q = 0x0801143Aull;
-static const uint64_t EXPLR_SRQ_SRQFIR_ACTION1 = 0x08011407ull;
+static const uint64_t EXPLR_SRQ_MBA_PMU2Q = 0x0801143Bull;
-static const uint64_t EXPLR_SRQ_SRQFIR_MASK = 0x08011403ull;
-static const uint64_t EXPLR_SRQ_SRQFIR_MASK_AND = 0x08011404ull;
+static const uint64_t EXPLR_SRQ_MBA_PMU3Q = 0x0801143Cull;
-static const uint64_t EXPLR_SRQ_SRQFIR_MASK_OR = 0x08011405ull;
+static const uint64_t EXPLR_SRQ_MBA_PMU4Q = 0x0801143Dull;
-static const uint64_t EXPLR_SRQ_SRQTRAP0 = 0x0801142Cull;
+static const uint64_t EXPLR_SRQ_MBA_PMU5Q = 0x0801143Eull;
-static const uint64_t EXPLR_SRQ_SRQTRAP1 = 0x0801142Dull;
+static const uint64_t EXPLR_SRQ_MBA_PMU6Q = 0x0801143Full;
-static const uint64_t EXPLR_TLXT_ERR_HOLD_LAT = 0x0801240Bull;
+static const uint64_t EXPLR_SRQ_MBA_PMU7Q = 0x08011440ull;
-static const uint64_t EXPLR_TLXT_ERR_MASK_LAT = 0x0801240Aull;
+static const uint64_t EXPLR_SRQ_MBA_PMU8Q = 0x08011441ull;
-static const uint64_t EXPLR_TLXT_TLXCFG0 = 0x0801240Cull;
+static const uint64_t EXPLR_SRQ_MBA_RRQ0Q = 0x08011410ull;
-static const uint64_t EXPLR_TLXT_TLXCFG1 = 0x0801240Dull;
+static const uint64_t EXPLR_SRQ_MBA_SYNCCNTLQ = 0x0801142Aull;
-static const uint64_t EXPLR_TLXT_TLXCFG2 = 0x0801240Eull;
+static const uint64_t EXPLR_SRQ_MBA_TMR0Q = 0x0801140Dull;
-static const uint64_t EXPLR_TLXT_TLXFIRACT0 = 0x08012406ull;
+static const uint64_t EXPLR_SRQ_MBA_TMR1Q = 0x0801140Eull;
-static const uint64_t EXPLR_TLXT_TLXFIRACT1 = 0x08012407ull;
+static const uint64_t EXPLR_SRQ_MBA_TMR2Q = 0x08011431ull;
-static const uint64_t EXPLR_TLXT_TLXFIRMASK = 0x08012403ull;
-static const uint64_t EXPLR_TLXT_TLXFIRMASK_AND = 0x08012404ull;
+static const uint64_t EXPLR_SRQ_MBA_WRQ0Q = 0x0801140Full;
-static const uint64_t EXPLR_TLXT_TLXFIRMASK_OR = 0x08012405ull;
+static const uint64_t EXPLR_SRQ_SRQCFG0 = 0x0801142Eull;
-static const uint64_t EXPLR_TLXT_TLXFIRQ = 0x08012400ull;
-static const uint64_t EXPLR_TLXT_TLXFIRQ_AND = 0x08012401ull;
+static const uint64_t EXPLR_SRQ_SRQFIRQ = 0x08011400ull;
-static const uint64_t EXPLR_TLXT_TLXFIRQ_OR = 0x08012402ull;
+static const uint64_t EXPLR_SRQ_SRQFIRQ_AND = 0x08011401ull;
+static const uint64_t EXPLR_SRQ_SRQFIRQ_OR = 0x08011402ull;
-static const uint64_t EXPLR_TLXT_TLXFIRWOF = 0x08012408ull;
+static const uint64_t EXPLR_SRQ_SRQFIRWOF = 0x08011408ull;
-static const uint64_t EXPLR_TLXT_TLXTINTHLD0 = 0x08012410ull;
+static const uint64_t EXPLR_SRQ_SRQFIR_ACTION0 = 0x08011406ull;
-static const uint64_t EXPLR_TLXT_TLXTINTHLD1 = 0x08012411ull;
+static const uint64_t EXPLR_SRQ_SRQFIR_ACTION1 = 0x08011407ull;
-static const uint64_t EXPLR_TLXT_TLXTINTHLD2 = 0x08012412ull;
+static const uint64_t EXPLR_SRQ_SRQFIR_MASK = 0x08011403ull;
-static const uint64_t EXPLR_TLXT_TLXTINTHLD3 = 0x08012413ull;
+static const uint64_t EXPLR_SRQ_SRQFIR_MASK_AND = 0x08011404ull;
+static const uint64_t EXPLR_SRQ_SRQFIR_MASK_OR = 0x08011405ull;
-static const uint64_t EXPLR_TLXT_TLXTRAP0 = 0x08012424ull;
+static const uint64_t EXPLR_SRQ_SRQTRAP0 = 0x0801142Cull;
-static const uint64_t EXPLR_TLXT_TLXTRAP1 = 0x08012425ull;
+static const uint64_t EXPLR_SRQ_SRQTRAP1 = 0x0801142Dull;
-static const uint64_t EXPLR_TLXT_TLXTTRAP2 = 0x08012426ull;
+static const uint64_t EXPLR_TLXT_ERR_HOLD_LAT = 0x0801240Bull;
-static const uint64_t EXPLR_TLXT_TLXTTRAP3 = 0x08012427ull;
+static const uint64_t EXPLR_TLXT_ERR_MASK_LAT = 0x0801240Aull;
-static const uint64_t EXPLR_TLXT_TLXTTRAP4 = 0x08012428ull;
+static const uint64_t EXPLR_TLXT_TLXCFG0 = 0x0801240Cull;
-static const uint64_t EXPLR_TLXT_TLX_ERR0_REPORTQ = 0x0801241Cull;
+static const uint64_t EXPLR_TLXT_TLXCFG1 = 0x0801240Dull;
-static const uint64_t EXPLR_TLXT_TLX_ERR0_REPORTQ_MASK = 0x08012414ull;
+static const uint64_t EXPLR_TLXT_TLXCFG2 = 0x0801240Eull;
-static const uint64_t EXPLR_TLXT_TLX_ERR1_REPORTQ = 0x0801241Dull;
+static const uint64_t EXPLR_TLXT_TLXFIRACT0 = 0x08012406ull;
-static const uint64_t EXPLR_TLXT_TLX_ERR1_REPORTQ_MASK = 0x08012415ull;
+static const uint64_t EXPLR_TLXT_TLXFIRACT1 = 0x08012407ull;
-static const uint64_t EXPLR_TLXT_TLX_ERR2_REPORTQ = 0x0801241Eull;
+static const uint64_t EXPLR_TLXT_TLXFIRMASK = 0x08012403ull;
-static const uint64_t EXPLR_TLXT_TLX_ERR2_REPORTQ_MASK = 0x08012416ull;
+static const uint64_t EXPLR_TLXT_TLXFIRMASK_AND = 0x08012404ull;
+static const uint64_t EXPLR_TLXT_TLXFIRMASK_OR = 0x08012405ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_ADDR_TRAP_REG = 0x08010003ull;
+static const uint64_t EXPLR_TLXT_TLXFIRQ = 0x08012400ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_ATOMIC_LOCK_MASK_LATCH_REG = 0x08010007ull;
+static const uint64_t EXPLR_TLXT_TLXFIRQ_AND = 0x08012401ull;
+static const uint64_t EXPLR_TLXT_TLXFIRQ_OR = 0x08012402ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1 = 0x080107C1ull;
+static const uint64_t EXPLR_TLXT_TLXFIRWOF = 0x08012408ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_2 = 0x080107C2ull;
+static const uint64_t EXPLR_TLXT_TLXTINTHLD0 = 0x08012410ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_3 = 0x080107C3ull;
+static const uint64_t EXPLR_TLXT_TLXTINTHLD1 = 0x08012411ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1 = 0x080107C4ull;
+static const uint64_t EXPLR_TLXT_TLXTINTHLD2 = 0x08012412ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_2 = 0x080107C5ull;
+static const uint64_t EXPLR_TLXT_TLXTINTHLD3 = 0x08012413ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_3 = 0x080107C6ull;
+static const uint64_t EXPLR_TLXT_TLXTRAP0 = 0x08012424ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG = 0x080107C0ull;
+static const uint64_t EXPLR_TLXT_TLXTRAP1 = 0x08012425ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_MODE_REG_2 = 0x080107CFull;
+static const uint64_t EXPLR_TLXT_TLXTTRAP2 = 0x08012426ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0 = 0x080107CDull;
+static const uint64_t EXPLR_TLXT_TLXTTRAP3 = 0x08012427ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_1 = 0x080107CEull;
+static const uint64_t EXPLR_TLXT_TLXTTRAP4 = 0x08012428ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_DEBUG_TRACE_CONTROL = 0x080107D0ull;
+static const uint64_t EXPLR_TLXT_TLX_ERR0_REPORTQ = 0x0801241Cull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_ERR_HOLD_LAT = 0x08040015ull;
+static const uint64_t EXPLR_TLXT_TLX_ERR0_REPORTQ_MASK = 0x08012414ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_ERR_MASK = 0x08040014ull;
+static const uint64_t EXPLR_TLXT_TLX_ERR1_REPORTQ = 0x0801241Dull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK = 0x0801000Aull;
+static const uint64_t EXPLR_TLXT_TLX_ERR1_REPORTQ_MASK = 0x08012415ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK = 0x08040002ull;
+static const uint64_t EXPLR_TLXT_TLX_ERR2_REPORTQ = 0x0801241Eull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ABORT_ON_ERROR_REG = 0x080F0004ull;
+static const uint64_t EXPLR_TLXT_TLX_ERR2_REPORTQ_MASK = 0x08012416ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG = 0x080F0005ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_ADDR_TRAP_REG = 0x08010003ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG = 0x080F0001ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_ATOMIC_LOCK_MASK_LATCH_REG = 0x08010007ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG = 0x080F0000ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1 = 0x080107C1ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_RESET_REG = 0x080F0003ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_2 = 0x080107C2ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_TIMER_REG = 0x080F0002ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_3 = 0x080107C3ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_HOLD_OUT_REG = 0x0801000Bull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1 = 0x080107C4ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR = 0x0804000Aull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_AND = 0x0804000Bull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_2 = 0x080107C5ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_OR = 0x0804000Cull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_3 = 0x080107C6ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_ACTION0 = 0x08040010ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG = 0x080107C0ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_ACTION1 = 0x08040011ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_MODE_REG_2 = 0x080107CFull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_MASK = 0x0804000Dull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_MASK_AND = 0x0804000Eull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0 = 0x080107CDull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_MASK_OR = 0x0804000Full;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_1 = 0x080107CEull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR = 0x08040018ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_DEBUG_TRACE_CONTROL = 0x080107D0ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_MASK = 0x08040019ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_ERR_HOLD_LAT = 0x08040015ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_MODE_REG = 0x08040008ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_ERR_MASK = 0x08040014ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_MSG_REG = 0x08000001ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK = 0x0801000Aull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ABORT_ON_ERROR_REG = 0x080E0005ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK = 0x08040002ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK2_REG = 0x080E0002ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ABORT_ON_ERROR_REG = 0x080F0004ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG = 0x080E0001ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG = 0x080F0005ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG = 0x080E0000ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG = 0x080F0001ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG2 = 0x080E0004ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG = 0x080F0000ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_TIMER_REG = 0x080E0003ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_RESET_REG = 0x080F0003ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK = 0x08010002ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_TIMER_REG = 0x080F0002ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG = 0x08010000ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_HOLD_OUT_REG = 0x0801000Bull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_PSCOM_STATUS_ERROR_REG = 0x08010001ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR = 0x0804000Aull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_RFIR = 0x08040001ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_AND = 0x0804000Bull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_OR = 0x0804000Cull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_RING_FENCE_MASK_LATCH_REG = 0x08010008ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_ACTION0 = 0x08040010ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_SPATTN_SCOM = 0x08040004ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_SPATTN_SCOM1 = 0x08040005ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_ACTION1 = 0x08040011ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_SPATTN_SCOM2 = 0x08040006ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_MASK = 0x0804000Dull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_SPA_MASK = 0x08040007ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_MASK_AND = 0x0804000Eull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_MASK_OR = 0x0804000Full;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_SUM_MASK_REG = 0x08040017ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR = 0x08040018ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_HI_DATA_REG = 0x08010400ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG = 0x08010401ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_MASK = 0x08040019ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG = 0x08010402ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_0 = 0x08010403ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_MODE_REG = 0x08040008ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_1 = 0x08010404ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_2 = 0x08010405ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_MSG_REG = 0x08000001ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_3 = 0x08010406ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_4 = 0x08010407ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ABORT_ON_ERROR_REG = 0x080E0005ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_5 = 0x08010408ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9 = 0x08010409ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK2_REG = 0x080E0002ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_WRITE_PROTECT_ENABLE_REG = 0x08010005ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG = 0x080E0001ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_WRITE_PROTECT_RINGS_REG = 0x08010006ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG = 0x080E0000ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_XFIR = 0x08040000ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG2 = 0x080E0004ull;
-static const uint64_t EXPLR_TP_MB_UNIT_TOP_XTRA_TRACE_MODE = 0x080107D1ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_TIMER_REG = 0x080E0003ull;
-static const uint64_t EXPLR_WDF_AACR = 0x08012002ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK = 0x08010002ull;
-static const uint64_t EXPLR_WDF_AADR = 0x08012003ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG = 0x08010000ull;
-static const uint64_t EXPLR_WDF_AAER = 0x08012004ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_PSCOM_STATUS_ERROR_REG = 0x08010001ull;
-static const uint64_t EXPLR_WDF_DQS0R = 0x08012000ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_RFIR = 0x08040001ull;
-static const uint64_t EXPLR_WDF_DQS1R = 0x08012001ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_RING_FENCE_MASK_LATCH_REG = 0x08010008ull;
-static const uint64_t EXPLR_WDF_WECR = 0x08012005ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_SPATTN_SCOM = 0x08040004ull;
-static const uint64_t EXPLR_WDF_WERR = 0x08012007ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_SPATTN_SCOM1 = 0x08040005ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_SPATTN_SCOM2 = 0x08040006ull;
-static const uint64_t EXPLR_WDF_WESR = 0x08012006ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_SPA_MASK = 0x08040007ull;
-static const uint64_t EXPLR_WDF_WMSK = 0x08012009ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_SUM_MASK_REG = 0x08040017ull;
-static const uint64_t EXPLR_WDF_WSPAR = 0x08012008ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_HI_DATA_REG = 0x08010400ull;
+//DUPS: 08010400,
-static const uint32_t EXPLR_EFUSE_IMAGE_OUT_0 = 0x20B080ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG = 0x08010401ull;
+//DUPS: 08010401,
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG = 0x08010402ull;
+//DUPS: 08010402,
-static const uint32_t EXPLR_EFUSE_IMAGE_OUT_1 = 0x20B084ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_0 = 0x08010403ull;
+//DUPS: 08010403,
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_1 = 0x08010404ull;
+//DUPS: 08010404,
-static const uint32_t EXPLR_EFUSE_IMAGE_OUT_2 = 0x20B088ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_2 = 0x08010405ull;
+//DUPS: 08010405,
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_3 = 0x08010406ull;
+//DUPS: 08010406,
-static const uint32_t EXPLR_EFUSE_IMAGE_OUT_3 = 0x20B08Cull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_4 = 0x08010407ull;
+//DUPS: 08010407,
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_5 = 0x08010408ull;
+//DUPS: 08010408,
-static const uint32_t EXPLR_EFUSE_PE_DATA_0 = 0x20B090ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9 = 0x08010409ull;
+//DUPS: 08010409,
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_WRITE_PROTECT_ENABLE_REG = 0x08010005ull;
-static const uint32_t EXPLR_EFUSE_PE_DATA_1 = 0x20B094ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_WRITE_PROTECT_RINGS_REG = 0x08010006ull;
-static const uint32_t EXPLR_EFUSE_PE_DATA_2 = 0x20B098ull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_XFIR = 0x08040000ull;
-static const uint32_t EXPLR_EFUSE_PE_DATA_3 = 0x20B09Cull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_XTRA_TRACE_MODE = 0x080107D1ull;
-static const uint32_t EXPLR_EFUSE_PE_DATA_4 = 0x20B0A0ull;
+static const uint64_t EXPLR_WDF_AACR = 0x08012002ull;
-static const uint32_t EXPLR_EFUSE_PE_DATA_5 = 0x20B0A4ull;
+static const uint64_t EXPLR_WDF_AADR = 0x08012003ull;
-static const uint32_t EXPLR_EFUSE_PE_DATA_6 = 0x20B0A8ull;
+static const uint64_t EXPLR_WDF_AAER = 0x08012004ull;
-static const uint32_t EXPLR_EFUSE_PE_DATA_8 = 0x20B0ACull;
+static const uint64_t EXPLR_WDF_DQS0R = 0x08012000ull;
-static const uint32_t EXPLR_EFUSE_PE_DATA_9 = 0x20B0B0ull;
+static const uint64_t EXPLR_WDF_DQS1R = 0x08012001ull;
-static const uint32_t EXPLR_EFUSE_PE_DATA_10 = 0x20B0B4ull;
+static const uint64_t EXPLR_WDF_WECR = 0x08012005ull;
-static const uint32_t EXPLR_EFUSE_PE_DATA_11 = 0x20B0B8ull;
+static const uint64_t EXPLR_WDF_WERR = 0x08012007ull;
-static const uint32_t EXPLR_EFUSE_PE_DATA_12 = 0x20B0BCull;
+static const uint64_t EXPLR_WDF_WESR = 0x08012006ull;
-static const uint32_t EXPLR_EFUSE_PE_DATA_13 = 0x20B0C0ull;
+static const uint64_t EXPLR_WDF_WMSK = 0x08012009ull;
-static const uint32_t EXPLR_EFUSE_PE_DATA_14 = 0x20B0C4ull;
+static const uint64_t EXPLR_WDF_WSPAR = 0x08012008ull;
#endif
diff --git a/src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fixes.H b/src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fixes.H
new file mode 100644
index 000000000..e94c8732a
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fixes.H
@@ -0,0 +1,3297 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fixes.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+
+#ifndef __EXPLR_SCOM_ADDRESSES_FIXES_H
+#define __EXPLR_SCOM_ADDRESSES_FIXES_H
+
+static const uint64_t EXPLR_MIPS_TO_OCMB_INTERRUPT_REGISTER1 = 0x2058ull;
+
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG0_U0_P0 = 0x04040340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG0_U0_P0 = 0x04040230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG0_U0_P0 = 0x04040240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG0_U0_P0 = 0x04040200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG0_U1_P0 = 0x04040740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG0_U1_P0 = 0x04040630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG0_U1_P0 = 0x04040640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG0_U1_P0 = 0x04040600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R0_P0 = 0x04040300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R1_P0 = 0x04040700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R2_P0 = 0x04040b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R3_P0 = 0x04040f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R4_P0 = 0x04041300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R5_P0 = 0x04041700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R6_P0 = 0x04041b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R7_P0 = 0x04041f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R8_P0 = 0x04042300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG0_U0_P0 = 0x04044340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG0_U0_P0 = 0x04044230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG0_U0_P0 = 0x04044240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG0_U0_P0 = 0x04044200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG0_U1_P0 = 0x04044740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG0_U1_P0 = 0x04044630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG0_U1_P0 = 0x04044640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG0_U1_P0 = 0x04044600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R0_P0 = 0x04044300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R1_P0 = 0x04044700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R2_P0 = 0x04044b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R3_P0 = 0x04044f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R4_P0 = 0x04045300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R5_P0 = 0x04045700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R6_P0 = 0x04045b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R7_P0 = 0x04045f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R8_P0 = 0x04046300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG0_U0_P0 = 0x04048340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG0_U0_P0 = 0x04048230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG0_U0_P0 = 0x04048240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG0_U0_P0 = 0x04048200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG0_U1_P0 = 0x04048740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG0_U1_P0 = 0x04048630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG0_U1_P0 = 0x04048640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG0_U1_P0 = 0x04048600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R0_P0 = 0x04048300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R1_P0 = 0x04048700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R2_P0 = 0x04048b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R3_P0 = 0x04048f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R4_P0 = 0x04049300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R5_P0 = 0x04049700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R6_P0 = 0x04049b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R7_P0 = 0x04049f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R8_P0 = 0x0404a300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG0_U0_P0 = 0x0404c340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG0_U0_P0 = 0x0404c230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG0_U0_P0 = 0x0404c240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG0_U0_P0 = 0x0404c200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG0_U1_P0 = 0x0404c740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG0_U1_P0 = 0x0404c630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG0_U1_P0 = 0x0404c640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG0_U1_P0 = 0x0404c600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R0_P0 = 0x0404c300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R1_P0 = 0x0404c700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R2_P0 = 0x0404cb00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R3_P0 = 0x0404cf00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R4_P0 = 0x0404d300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R5_P0 = 0x0404d700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R6_P0 = 0x0404db00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R7_P0 = 0x0404df00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R8_P0 = 0x0404e300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG0_U0_P0 = 0x04050340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG0_U0_P0 = 0x04050230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG0_U0_P0 = 0x04050240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG0_U0_P0 = 0x04050200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG0_U1_P0 = 0x04050740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG0_U1_P0 = 0x04050630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG0_U1_P0 = 0x04050640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG0_U1_P0 = 0x04050600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R0_P0 = 0x04050300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R1_P0 = 0x04050700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R2_P0 = 0x04050b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R3_P0 = 0x04050f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R4_P0 = 0x04051300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R5_P0 = 0x04051700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R6_P0 = 0x04051b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R7_P0 = 0x04051f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R8_P0 = 0x04052300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG0_U0_P0 = 0x04054340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG0_U0_P0 = 0x04054230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG0_U0_P0 = 0x04054240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG0_U0_P0 = 0x04054200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG0_U1_P0 = 0x04054740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG0_U1_P0 = 0x04054630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG0_U1_P0 = 0x04054640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG0_U1_P0 = 0x04054600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R0_P0 = 0x04054300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R1_P0 = 0x04054700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R2_P0 = 0x04054b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R3_P0 = 0x04054f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R4_P0 = 0x04055300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R5_P0 = 0x04055700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R6_P0 = 0x04055b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R7_P0 = 0x04055f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R8_P0 = 0x04056300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG0_U0_P0 = 0x04058340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG0_U0_P0 = 0x04058230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG0_U0_P0 = 0x04058240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG0_U0_P0 = 0x04058200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG0_U1_P0 = 0x04058740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG0_U1_P0 = 0x04058630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG0_U1_P0 = 0x04058640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG0_U1_P0 = 0x04058600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R0_P0 = 0x04058300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R1_P0 = 0x04058700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R2_P0 = 0x04058b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R3_P0 = 0x04058f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R4_P0 = 0x04059300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R5_P0 = 0x04059700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R6_P0 = 0x04059b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R7_P0 = 0x04059f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R8_P0 = 0x0405a300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG0_U0_P0 = 0x0405c340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG0_U0_P0 = 0x0405c230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG0_U0_P0 = 0x0405c240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG0_U0_P0 = 0x0405c200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG0_U1_P0 = 0x0405c740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG0_U1_P0 = 0x0405c630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG0_U1_P0 = 0x0405c640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG0_U1_P0 = 0x0405c600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R0_P0 = 0x0405c300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R1_P0 = 0x0405c700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R2_P0 = 0x0405cb00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R3_P0 = 0x0405cf00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R4_P0 = 0x0405d300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R5_P0 = 0x0405d700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R6_P0 = 0x0405db00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R7_P0 = 0x0405df00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R8_P0 = 0x0405e300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG0_U0_P0 = 0x04060340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG0_U0_P0 = 0x04060230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG0_U0_P0 = 0x04060240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG0_U0_P0 = 0x04060200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG0_U1_P0 = 0x04060740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG0_U1_P0 = 0x04060630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG0_U1_P0 = 0x04060640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG0_U1_P0 = 0x04060600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R0_P0 = 0x04060300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R1_P0 = 0x04060700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R2_P0 = 0x04060b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R3_P0 = 0x04060f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R4_P0 = 0x04061300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R5_P0 = 0x04061700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R6_P0 = 0x04061b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R7_P0 = 0x04061f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R8_P0 = 0x04062300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG0_U0_P0 = 0x04064340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG0_U0_P0 = 0x04064230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG0_U0_P0 = 0x04064240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG0_U0_P0 = 0x04064200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG0_U1_P0 = 0x04064740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG0_U1_P0 = 0x04064630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG0_U1_P0 = 0x04064640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG0_U1_P0 = 0x04064600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R0_P0 = 0x04064300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R1_P0 = 0x04064700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R2_P0 = 0x04064b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R3_P0 = 0x04064f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R4_P0 = 0x04065300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R5_P0 = 0x04065700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R6_P0 = 0x04065b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R7_P0 = 0x04065f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R8_P0 = 0x04066300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG1_U0_P0 = 0x04040344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG1_U0_P0 = 0x04040234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG1_U0_P0 = 0x04040244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG1_U0_P0 = 0x04040204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG1_U1_P0 = 0x04040744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG1_U1_P0 = 0x04040634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG1_U1_P0 = 0x04040644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG1_U1_P0 = 0x04040604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R0_P0 = 0x04040304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R1_P0 = 0x04040704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R2_P0 = 0x04040b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R3_P0 = 0x04040f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R4_P0 = 0x04041304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R5_P0 = 0x04041704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R6_P0 = 0x04041b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R7_P0 = 0x04041f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R8_P0 = 0x04042304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG1_U0_P0 = 0x04044344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG1_U0_P0 = 0x04044234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG1_U0_P0 = 0x04044244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG1_U0_P0 = 0x04044204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG1_U1_P0 = 0x04044744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG1_U1_P0 = 0x04044634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG1_U1_P0 = 0x04044644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG1_U1_P0 = 0x04044604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R0_P0 = 0x04044304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R1_P0 = 0x04044704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R2_P0 = 0x04044b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R3_P0 = 0x04044f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R4_P0 = 0x04045304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R5_P0 = 0x04045704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R6_P0 = 0x04045b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R7_P0 = 0x04045f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R8_P0 = 0x04046304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG1_U0_P0 = 0x04048344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG1_U0_P0 = 0x04048234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG1_U0_P0 = 0x04048244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG1_U0_P0 = 0x04048204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG1_U1_P0 = 0x04048744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG1_U1_P0 = 0x04048634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG1_U1_P0 = 0x04048644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG1_U1_P0 = 0x04048604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R0_P0 = 0x04048304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R1_P0 = 0x04048704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R2_P0 = 0x04048b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R3_P0 = 0x04048f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R4_P0 = 0x04049304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R5_P0 = 0x04049704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R6_P0 = 0x04049b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R7_P0 = 0x04049f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R8_P0 = 0x0404a304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG1_U0_P0 = 0x0404c344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG1_U0_P0 = 0x0404c234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG1_U0_P0 = 0x0404c244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG1_U0_P0 = 0x0404c204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG1_U1_P0 = 0x0404c744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG1_U1_P0 = 0x0404c634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG1_U1_P0 = 0x0404c644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG1_U1_P0 = 0x0404c604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R0_P0 = 0x0404c304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R1_P0 = 0x0404c704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R2_P0 = 0x0404cb04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R3_P0 = 0x0404cf04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R4_P0 = 0x0404d304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R5_P0 = 0x0404d704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R6_P0 = 0x0404db04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R7_P0 = 0x0404df04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R8_P0 = 0x0404e304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG1_U0_P0 = 0x04050344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG1_U0_P0 = 0x04050234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG1_U0_P0 = 0x04050244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG1_U0_P0 = 0x04050204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG1_U1_P0 = 0x04050744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG1_U1_P0 = 0x04050634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG1_U1_P0 = 0x04050644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG1_U1_P0 = 0x04050604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R0_P0 = 0x04050304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R1_P0 = 0x04050704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R2_P0 = 0x04050b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R3_P0 = 0x04050f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R4_P0 = 0x04051304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R5_P0 = 0x04051704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R6_P0 = 0x04051b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R7_P0 = 0x04051f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R8_P0 = 0x04052304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG1_U0_P0 = 0x04054344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG1_U0_P0 = 0x04054234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG1_U0_P0 = 0x04054244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG1_U0_P0 = 0x04054204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG1_U1_P0 = 0x04054744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG1_U1_P0 = 0x04054634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG1_U1_P0 = 0x04054644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG1_U1_P0 = 0x04054604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R0_P0 = 0x04054304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R1_P0 = 0x04054704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R2_P0 = 0x04054b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R3_P0 = 0x04054f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R4_P0 = 0x04055304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R5_P0 = 0x04055704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R6_P0 = 0x04055b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R7_P0 = 0x04055f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R8_P0 = 0x04056304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG1_U0_P0 = 0x04058344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG1_U0_P0 = 0x04058234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG1_U0_P0 = 0x04058244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG1_U0_P0 = 0x04058204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG1_U1_P0 = 0x04058744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG1_U1_P0 = 0x04058634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG1_U1_P0 = 0x04058644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG1_U1_P0 = 0x04058604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R0_P0 = 0x04058304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R1_P0 = 0x04058704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R2_P0 = 0x04058b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R3_P0 = 0x04058f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R4_P0 = 0x04059304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R5_P0 = 0x04059704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R6_P0 = 0x04059b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R7_P0 = 0x04059f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R8_P0 = 0x0405a304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG1_U0_P0 = 0x0405c344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG1_U0_P0 = 0x0405c234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG1_U0_P0 = 0x0405c244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG1_U0_P0 = 0x0405c204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG1_U1_P0 = 0x0405c744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG1_U1_P0 = 0x0405c634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG1_U1_P0 = 0x0405c644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG1_U1_P0 = 0x0405c604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R0_P0 = 0x0405c304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R1_P0 = 0x0405c704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R2_P0 = 0x0405cb04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R3_P0 = 0x0405cf04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R4_P0 = 0x0405d304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R5_P0 = 0x0405d704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R6_P0 = 0x0405db04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R7_P0 = 0x0405df04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R8_P0 = 0x0405e304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG1_U0_P0 = 0x04060344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG1_U0_P0 = 0x04060234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG1_U0_P0 = 0x04060244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG1_U0_P0 = 0x04060204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG1_U1_P0 = 0x04060744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG1_U1_P0 = 0x04060634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG1_U1_P0 = 0x04060644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG1_U1_P0 = 0x04060604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R0_P0 = 0x04060304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R1_P0 = 0x04060704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R2_P0 = 0x04060b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R3_P0 = 0x04060f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R4_P0 = 0x04061304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R5_P0 = 0x04061704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R6_P0 = 0x04061b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R7_P0 = 0x04061f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R8_P0 = 0x04062304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG1_U0_P0 = 0x04064344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG1_U0_P0 = 0x04064234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG1_U0_P0 = 0x04064244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG1_U0_P0 = 0x04064204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG1_U1_P0 = 0x04064744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG1_U1_P0 = 0x04064634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG1_U1_P0 = 0x04064644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG1_U1_P0 = 0x04064604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R0_P0 = 0x04064304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R1_P0 = 0x04064704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R2_P0 = 0x04064b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R3_P0 = 0x04064f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R4_P0 = 0x04065304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R5_P0 = 0x04065704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R6_P0 = 0x04065b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R7_P0 = 0x04065f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R8_P0 = 0x04066304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG2_U0_P0 = 0x04040348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG2_U0_P0 = 0x04040238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG2_U0_P0 = 0x04040248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG2_U0_P0 = 0x04040208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG2_U1_P0 = 0x04040748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG2_U1_P0 = 0x04040638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG2_U1_P0 = 0x04040648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG2_U1_P0 = 0x04040608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R0_P0 = 0x04040308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R1_P0 = 0x04040708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R2_P0 = 0x04040b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R3_P0 = 0x04040f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R4_P0 = 0x04041308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R5_P0 = 0x04041708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R6_P0 = 0x04041b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R7_P0 = 0x04041f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R8_P0 = 0x04042308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG2_U0_P0 = 0x04044348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG2_U0_P0 = 0x04044238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG2_U0_P0 = 0x04044248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG2_U0_P0 = 0x04044208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG2_U1_P0 = 0x04044748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG2_U1_P0 = 0x04044638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG2_U1_P0 = 0x04044648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG2_U1_P0 = 0x04044608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R0_P0 = 0x04044308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R1_P0 = 0x04044708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R2_P0 = 0x04044b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R3_P0 = 0x04044f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R4_P0 = 0x04045308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R5_P0 = 0x04045708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R6_P0 = 0x04045b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R7_P0 = 0x04045f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R8_P0 = 0x04046308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG2_U0_P0 = 0x04048348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG2_U0_P0 = 0x04048238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG2_U0_P0 = 0x04048248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG2_U0_P0 = 0x04048208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG2_U1_P0 = 0x04048748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG2_U1_P0 = 0x04048638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG2_U1_P0 = 0x04048648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG2_U1_P0 = 0x04048608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R0_P0 = 0x04048308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R1_P0 = 0x04048708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R2_P0 = 0x04048b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R3_P0 = 0x04048f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R4_P0 = 0x04049308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R5_P0 = 0x04049708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R6_P0 = 0x04049b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R7_P0 = 0x04049f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R8_P0 = 0x0404a308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG2_U0_P0 = 0x0404c348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG2_U0_P0 = 0x0404c238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG2_U0_P0 = 0x0404c248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG2_U0_P0 = 0x0404c208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG2_U1_P0 = 0x0404c748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG2_U1_P0 = 0x0404c638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG2_U1_P0 = 0x0404c648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG2_U1_P0 = 0x0404c608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R0_P0 = 0x0404c308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R1_P0 = 0x0404c708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R2_P0 = 0x0404cb08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R3_P0 = 0x0404cf08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R4_P0 = 0x0404d308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R5_P0 = 0x0404d708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R6_P0 = 0x0404db08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R7_P0 = 0x0404df08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R8_P0 = 0x0404e308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG2_U0_P0 = 0x04050348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG2_U0_P0 = 0x04050238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG2_U0_P0 = 0x04050248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG2_U0_P0 = 0x04050208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG2_U1_P0 = 0x04050748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG2_U1_P0 = 0x04050638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG2_U1_P0 = 0x04050648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG2_U1_P0 = 0x04050608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R0_P0 = 0x04050308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R1_P0 = 0x04050708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R2_P0 = 0x04050b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R3_P0 = 0x04050f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R4_P0 = 0x04051308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R5_P0 = 0x04051708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R6_P0 = 0x04051b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R7_P0 = 0x04051f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R8_P0 = 0x04052308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG2_U0_P0 = 0x04054348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG2_U0_P0 = 0x04054238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG2_U0_P0 = 0x04054248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG2_U0_P0 = 0x04054208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG2_U1_P0 = 0x04054748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG2_U1_P0 = 0x04054638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG2_U1_P0 = 0x04054648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG2_U1_P0 = 0x04054608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R0_P0 = 0x04054308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R1_P0 = 0x04054708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R2_P0 = 0x04054b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R3_P0 = 0x04054f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R4_P0 = 0x04055308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R5_P0 = 0x04055708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R6_P0 = 0x04055b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R7_P0 = 0x04055f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R8_P0 = 0x04056308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG2_U0_P0 = 0x04058348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG2_U0_P0 = 0x04058238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG2_U0_P0 = 0x04058248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG2_U0_P0 = 0x04058208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG2_U1_P0 = 0x04058748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG2_U1_P0 = 0x04058638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG2_U1_P0 = 0x04058648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG2_U1_P0 = 0x04058608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R0_P0 = 0x04058308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R1_P0 = 0x04058708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R2_P0 = 0x04058b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R3_P0 = 0x04058f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R4_P0 = 0x04059308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R5_P0 = 0x04059708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R6_P0 = 0x04059b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R7_P0 = 0x04059f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R8_P0 = 0x0405a308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG2_U0_P0 = 0x0405c348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG2_U0_P0 = 0x0405c238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG2_U0_P0 = 0x0405c248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG2_U0_P0 = 0x0405c208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG2_U1_P0 = 0x0405c748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG2_U1_P0 = 0x0405c638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG2_U1_P0 = 0x0405c648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG2_U1_P0 = 0x0405c608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R0_P0 = 0x0405c308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R1_P0 = 0x0405c708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R2_P0 = 0x0405cb08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R3_P0 = 0x0405cf08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R4_P0 = 0x0405d308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R5_P0 = 0x0405d708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R6_P0 = 0x0405db08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R7_P0 = 0x0405df08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R8_P0 = 0x0405e308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG2_U0_P0 = 0x04060348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG2_U0_P0 = 0x04060238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG2_U0_P0 = 0x04060248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG2_U0_P0 = 0x04060208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG2_U1_P0 = 0x04060748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG2_U1_P0 = 0x04060638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG2_U1_P0 = 0x04060648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG2_U1_P0 = 0x04060608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R0_P0 = 0x04060308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R1_P0 = 0x04060708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R2_P0 = 0x04060b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R3_P0 = 0x04060f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R4_P0 = 0x04061308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R5_P0 = 0x04061708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R6_P0 = 0x04061b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R7_P0 = 0x04061f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R8_P0 = 0x04062308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG2_U0_P0 = 0x04064348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG2_U0_P0 = 0x04064238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG2_U0_P0 = 0x04064248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG2_U0_P0 = 0x04064208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG2_U1_P0 = 0x04064748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG2_U1_P0 = 0x04064638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG2_U1_P0 = 0x04064648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG2_U1_P0 = 0x04064608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R0_P0 = 0x04064308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R1_P0 = 0x04064708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R2_P0 = 0x04064b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R3_P0 = 0x04064f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R4_P0 = 0x04065308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R5_P0 = 0x04065708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R6_P0 = 0x04065b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R7_P0 = 0x04065f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R8_P0 = 0x04066308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG3_U0_P0 = 0x0404034cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG3_U0_P0 = 0x0404023cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG3_U0_P0 = 0x0404024cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG3_U0_P0 = 0x0404020cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG3_U1_P0 = 0x0404074cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG3_U1_P0 = 0x0404063cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG3_U1_P0 = 0x0404064cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG3_U1_P0 = 0x0404060cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R0_P0 = 0x0404030cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R1_P0 = 0x0404070cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R2_P0 = 0x04040b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R3_P0 = 0x04040f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R4_P0 = 0x0404130cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R5_P0 = 0x0404170cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R6_P0 = 0x04041b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R7_P0 = 0x04041f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R8_P0 = 0x0404230cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG3_U0_P0 = 0x0404434cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG3_U0_P0 = 0x0404423cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG3_U0_P0 = 0x0404424cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG3_U0_P0 = 0x0404420cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG3_U1_P0 = 0x0404474cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG3_U1_P0 = 0x0404463cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG3_U1_P0 = 0x0404464cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG3_U1_P0 = 0x0404460cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R0_P0 = 0x0404430cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R1_P0 = 0x0404470cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R2_P0 = 0x04044b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R3_P0 = 0x04044f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R4_P0 = 0x0404530cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R5_P0 = 0x0404570cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R6_P0 = 0x04045b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R7_P0 = 0x04045f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R8_P0 = 0x0404630cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG3_U0_P0 = 0x0404834cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG3_U0_P0 = 0x0404823cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG3_U0_P0 = 0x0404824cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG3_U0_P0 = 0x0404820cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG3_U1_P0 = 0x0404874cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG3_U1_P0 = 0x0404863cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG3_U1_P0 = 0x0404864cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG3_U1_P0 = 0x0404860cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R0_P0 = 0x0404830cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R1_P0 = 0x0404870cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R2_P0 = 0x04048b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R3_P0 = 0x04048f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R4_P0 = 0x0404930cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R5_P0 = 0x0404970cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R6_P0 = 0x04049b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R7_P0 = 0x04049f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R8_P0 = 0x0404a30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG3_U0_P0 = 0x0404c34cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG3_U0_P0 = 0x0404c23cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG3_U0_P0 = 0x0404c24cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG3_U0_P0 = 0x0404c20cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG3_U1_P0 = 0x0404c74cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG3_U1_P0 = 0x0404c63cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG3_U1_P0 = 0x0404c64cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG3_U1_P0 = 0x0404c60cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R0_P0 = 0x0404c30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R1_P0 = 0x0404c70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R2_P0 = 0x0404cb0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R3_P0 = 0x0404cf0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R4_P0 = 0x0404d30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R5_P0 = 0x0404d70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R6_P0 = 0x0404db0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R7_P0 = 0x0404df0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R8_P0 = 0x0404e30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG3_U0_P0 = 0x0405034cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG3_U0_P0 = 0x0405023cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG3_U0_P0 = 0x0405024cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG3_U0_P0 = 0x0405020cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG3_U1_P0 = 0x0405074cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG3_U1_P0 = 0x0405063cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG3_U1_P0 = 0x0405064cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG3_U1_P0 = 0x0405060cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R0_P0 = 0x0405030cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R1_P0 = 0x0405070cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R2_P0 = 0x04050b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R3_P0 = 0x04050f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R4_P0 = 0x0405130cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R5_P0 = 0x0405170cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R6_P0 = 0x04051b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R7_P0 = 0x04051f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R8_P0 = 0x0405230cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG3_U0_P0 = 0x0405434cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG3_U0_P0 = 0x0405423cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG3_U0_P0 = 0x0405424cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG3_U0_P0 = 0x0405420cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG3_U1_P0 = 0x0405474cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG3_U1_P0 = 0x0405463cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG3_U1_P0 = 0x0405464cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG3_U1_P0 = 0x0405460cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R0_P0 = 0x0405430cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R1_P0 = 0x0405470cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R2_P0 = 0x04054b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R3_P0 = 0x04054f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R4_P0 = 0x0405530cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R5_P0 = 0x0405570cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R6_P0 = 0x04055b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R7_P0 = 0x04055f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R8_P0 = 0x0405630cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG3_U0_P0 = 0x0405834cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG3_U0_P0 = 0x0405823cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG3_U0_P0 = 0x0405824cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG3_U0_P0 = 0x0405820cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG3_U1_P0 = 0x0405874cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG3_U1_P0 = 0x0405863cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG3_U1_P0 = 0x0405864cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG3_U1_P0 = 0x0405860cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R0_P0 = 0x0405830cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R1_P0 = 0x0405870cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R2_P0 = 0x04058b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R3_P0 = 0x04058f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R4_P0 = 0x0405930cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R5_P0 = 0x0405970cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R6_P0 = 0x04059b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R7_P0 = 0x04059f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R8_P0 = 0x0405a30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG3_U0_P0 = 0x0405c34cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG3_U0_P0 = 0x0405c23cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG3_U0_P0 = 0x0405c24cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG3_U0_P0 = 0x0405c20cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG3_U1_P0 = 0x0405c74cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG3_U1_P0 = 0x0405c63cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG3_U1_P0 = 0x0405c64cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG3_U1_P0 = 0x0405c60cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R0_P0 = 0x0405c30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R1_P0 = 0x0405c70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R2_P0 = 0x0405cb0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R3_P0 = 0x0405cf0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R4_P0 = 0x0405d30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R5_P0 = 0x0405d70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R6_P0 = 0x0405db0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R7_P0 = 0x0405df0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R8_P0 = 0x0405e30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG3_U0_P0 = 0x0406034cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG3_U0_P0 = 0x0406023cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG3_U0_P0 = 0x0406024cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG3_U0_P0 = 0x0406020cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG3_U1_P0 = 0x0406074cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG3_U1_P0 = 0x0406063cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG3_U1_P0 = 0x0406064cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG3_U1_P0 = 0x0406060cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R0_P0 = 0x0406030cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R1_P0 = 0x0406070cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R2_P0 = 0x04060b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R3_P0 = 0x04060f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R4_P0 = 0x0406130cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R5_P0 = 0x0406170cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R6_P0 = 0x04061b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R7_P0 = 0x04061f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R8_P0 = 0x0406230cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG3_U0_P0 = 0x0406434cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG3_U0_P0 = 0x0406423cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG3_U0_P0 = 0x0406424cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG3_U0_P0 = 0x0406420cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG3_U1_P0 = 0x0406474cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG3_U1_P0 = 0x0406463cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG3_U1_P0 = 0x0406464cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG3_U1_P0 = 0x0406460cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R0_P0 = 0x0406430cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R1_P0 = 0x0406470cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R2_P0 = 0x04064b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R3_P0 = 0x04064f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R4_P0 = 0x0406530cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R5_P0 = 0x0406570cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R6_P0 = 0x04065b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R7_P0 = 0x04065f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R8_P0 = 0x0406630cull;
+static const uint64_t EXP_DDR4_PHY_ANIB0_ATXDLY_P0 = 0x04000200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB1_ATXDLY_P0 = 0x04004200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB2_ATXDLY_P0 = 0x04008200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB3_ATXDLY_P0 = 0x0400c200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB4_ATXDLY_P0 = 0x04010200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB5_ATXDLY_P0 = 0x04014200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB6_ATXDLY_P0 = 0x04018200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB7_ATXDLY_P0 = 0x0401c200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB8_ATXDLY_P0 = 0x04020200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG0_U0_P1 = 0x04440340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG0_U0_P1 = 0x04440230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG0_U0_P1 = 0x04440240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG0_U0_P1 = 0x04440200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG0_U1_P1 = 0x04440740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG0_U1_P1 = 0x04440630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG0_U1_P1 = 0x04440640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG0_U1_P1 = 0x04440600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R0_P1 = 0x04440300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R1_P1 = 0x04440700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R2_P1 = 0x04440b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R3_P1 = 0x04440f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R4_P1 = 0x04441300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R5_P1 = 0x04441700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R6_P1 = 0x04441b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R7_P1 = 0x04441f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R8_P1 = 0x04442300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG0_U0_P1 = 0x04444340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG0_U0_P1 = 0x04444230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG0_U0_P1 = 0x04444240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG0_U0_P1 = 0x04444200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG0_U1_P1 = 0x04444740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG0_U1_P1 = 0x04444630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG0_U1_P1 = 0x04444640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG0_U1_P1 = 0x04444600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R0_P1 = 0x04444300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R1_P1 = 0x04444700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R2_P1 = 0x04444b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R3_P1 = 0x04444f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R4_P1 = 0x04445300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R5_P1 = 0x04445700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R6_P1 = 0x04445b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R7_P1 = 0x04445f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R8_P1 = 0x04446300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG0_U0_P1 = 0x04448340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG0_U0_P1 = 0x04448230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG0_U0_P1 = 0x04448240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG0_U0_P1 = 0x04448200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG0_U1_P1 = 0x04448740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG0_U1_P1 = 0x04448630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG0_U1_P1 = 0x04448640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG0_U1_P1 = 0x04448600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R0_P1 = 0x04448300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R1_P1 = 0x04448700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R2_P1 = 0x04448b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R3_P1 = 0x04448f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R4_P1 = 0x04449300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R5_P1 = 0x04449700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R6_P1 = 0x04449b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R7_P1 = 0x04449f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R8_P1 = 0x0444a300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG0_U0_P1 = 0x0444c340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG0_U0_P1 = 0x0444c230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG0_U0_P1 = 0x0444c240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG0_U0_P1 = 0x0444c200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG0_U1_P1 = 0x0444c740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG0_U1_P1 = 0x0444c630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG0_U1_P1 = 0x0444c640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG0_U1_P1 = 0x0444c600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R0_P1 = 0x0444c300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R1_P1 = 0x0444c700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R2_P1 = 0x0444cb00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R3_P1 = 0x0444cf00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R4_P1 = 0x0444d300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R5_P1 = 0x0444d700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R6_P1 = 0x0444db00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R7_P1 = 0x0444df00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R8_P1 = 0x0444e300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG0_U0_P1 = 0x04450340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG0_U0_P1 = 0x04450230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG0_U0_P1 = 0x04450240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG0_U0_P1 = 0x04450200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG0_U1_P1 = 0x04450740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG0_U1_P1 = 0x04450630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG0_U1_P1 = 0x04450640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG0_U1_P1 = 0x04450600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R0_P1 = 0x04450300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R1_P1 = 0x04450700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R2_P1 = 0x04450b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R3_P1 = 0x04450f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R4_P1 = 0x04451300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R5_P1 = 0x04451700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R6_P1 = 0x04451b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R7_P1 = 0x04451f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R8_P1 = 0x04452300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG0_U0_P1 = 0x04454340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG0_U0_P1 = 0x04454230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG0_U0_P1 = 0x04454240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG0_U0_P1 = 0x04454200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG0_U1_P1 = 0x04454740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG0_U1_P1 = 0x04454630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG0_U1_P1 = 0x04454640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG0_U1_P1 = 0x04454600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R0_P1 = 0x04454300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R1_P1 = 0x04454700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R2_P1 = 0x04454b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R3_P1 = 0x04454f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R4_P1 = 0x04455300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R5_P1 = 0x04455700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R6_P1 = 0x04455b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R7_P1 = 0x04455f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R8_P1 = 0x04456300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG0_U0_P1 = 0x04458340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG0_U0_P1 = 0x04458230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG0_U0_P1 = 0x04458240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG0_U0_P1 = 0x04458200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG0_U1_P1 = 0x04458740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG0_U1_P1 = 0x04458630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG0_U1_P1 = 0x04458640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG0_U1_P1 = 0x04458600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R0_P1 = 0x04458300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R1_P1 = 0x04458700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R2_P1 = 0x04458b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R3_P1 = 0x04458f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R4_P1 = 0x04459300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R5_P1 = 0x04459700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R6_P1 = 0x04459b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R7_P1 = 0x04459f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R8_P1 = 0x0445a300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG0_U0_P1 = 0x0445c340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG0_U0_P1 = 0x0445c230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG0_U0_P1 = 0x0445c240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG0_U0_P1 = 0x0445c200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG0_U1_P1 = 0x0445c740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG0_U1_P1 = 0x0445c630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG0_U1_P1 = 0x0445c640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG0_U1_P1 = 0x0445c600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R0_P1 = 0x0445c300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R1_P1 = 0x0445c700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R2_P1 = 0x0445cb00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R3_P1 = 0x0445cf00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R4_P1 = 0x0445d300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R5_P1 = 0x0445d700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R6_P1 = 0x0445db00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R7_P1 = 0x0445df00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R8_P1 = 0x0445e300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG0_U0_P1 = 0x04460340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG0_U0_P1 = 0x04460230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG0_U0_P1 = 0x04460240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG0_U0_P1 = 0x04460200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG0_U1_P1 = 0x04460740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG0_U1_P1 = 0x04460630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG0_U1_P1 = 0x04460640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG0_U1_P1 = 0x04460600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R0_P1 = 0x04460300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R1_P1 = 0x04460700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R2_P1 = 0x04460b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R3_P1 = 0x04460f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R4_P1 = 0x04461300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R5_P1 = 0x04461700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R6_P1 = 0x04461b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R7_P1 = 0x04461f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R8_P1 = 0x04462300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG0_U0_P1 = 0x04464340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG0_U0_P1 = 0x04464230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG0_U0_P1 = 0x04464240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG0_U0_P1 = 0x04464200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG0_U1_P1 = 0x04464740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG0_U1_P1 = 0x04464630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG0_U1_P1 = 0x04464640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG0_U1_P1 = 0x04464600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R0_P1 = 0x04464300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R1_P1 = 0x04464700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R2_P1 = 0x04464b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R3_P1 = 0x04464f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R4_P1 = 0x04465300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R5_P1 = 0x04465700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R6_P1 = 0x04465b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R7_P1 = 0x04465f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R8_P1 = 0x04466300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG1_U0_P1 = 0x04440344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG1_U0_P1 = 0x04440234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG1_U0_P1 = 0x04440244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG1_U0_P1 = 0x04440204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG1_U1_P1 = 0x04440744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG1_U1_P1 = 0x04440634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG1_U1_P1 = 0x04440644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG1_U1_P1 = 0x04440604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R0_P1 = 0x04440304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R1_P1 = 0x04440704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R2_P1 = 0x04440b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R3_P1 = 0x04440f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R4_P1 = 0x04441304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R5_P1 = 0x04441704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R6_P1 = 0x04441b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R7_P1 = 0x04441f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R8_P1 = 0x04442304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG1_U0_P1 = 0x04444344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG1_U0_P1 = 0x04444234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG1_U0_P1 = 0x04444244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG1_U0_P1 = 0x04444204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG1_U1_P1 = 0x04444744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG1_U1_P1 = 0x04444634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG1_U1_P1 = 0x04444644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG1_U1_P1 = 0x04444604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R0_P1 = 0x04444304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R1_P1 = 0x04444704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R2_P1 = 0x04444b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R3_P1 = 0x04444f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R4_P1 = 0x04445304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R5_P1 = 0x04445704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R6_P1 = 0x04445b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R7_P1 = 0x04445f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R8_P1 = 0x04446304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG1_U0_P1 = 0x04448344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG1_U0_P1 = 0x04448234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG1_U0_P1 = 0x04448244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG1_U0_P1 = 0x04448204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG1_U1_P1 = 0x04448744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG1_U1_P1 = 0x04448634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG1_U1_P1 = 0x04448644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG1_U1_P1 = 0x04448604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R0_P1 = 0x04448304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R1_P1 = 0x04448704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R2_P1 = 0x04448b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R3_P1 = 0x04448f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R4_P1 = 0x04449304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R5_P1 = 0x04449704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R6_P1 = 0x04449b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R7_P1 = 0x04449f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R8_P1 = 0x0444a304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG1_U0_P1 = 0x0444c344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG1_U0_P1 = 0x0444c234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG1_U0_P1 = 0x0444c244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG1_U0_P1 = 0x0444c204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG1_U1_P1 = 0x0444c744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG1_U1_P1 = 0x0444c634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG1_U1_P1 = 0x0444c644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG1_U1_P1 = 0x0444c604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R0_P1 = 0x0444c304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R1_P1 = 0x0444c704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R2_P1 = 0x0444cb04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R3_P1 = 0x0444cf04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R4_P1 = 0x0444d304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R5_P1 = 0x0444d704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R6_P1 = 0x0444db04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R7_P1 = 0x0444df04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R8_P1 = 0x0444e304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG1_U0_P1 = 0x04450344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG1_U0_P1 = 0x04450234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG1_U0_P1 = 0x04450244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG1_U0_P1 = 0x04450204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG1_U1_P1 = 0x04450744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG1_U1_P1 = 0x04450634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG1_U1_P1 = 0x04450644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG1_U1_P1 = 0x04450604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R0_P1 = 0x04450304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R1_P1 = 0x04450704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R2_P1 = 0x04450b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R3_P1 = 0x04450f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R4_P1 = 0x04451304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R5_P1 = 0x04451704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R6_P1 = 0x04451b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R7_P1 = 0x04451f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R8_P1 = 0x04452304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG1_U0_P1 = 0x04454344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG1_U0_P1 = 0x04454234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG1_U0_P1 = 0x04454244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG1_U0_P1 = 0x04454204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG1_U1_P1 = 0x04454744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG1_U1_P1 = 0x04454634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG1_U1_P1 = 0x04454644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG1_U1_P1 = 0x04454604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R0_P1 = 0x04454304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R1_P1 = 0x04454704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R2_P1 = 0x04454b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R3_P1 = 0x04454f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R4_P1 = 0x04455304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R5_P1 = 0x04455704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R6_P1 = 0x04455b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R7_P1 = 0x04455f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R8_P1 = 0x04456304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG1_U0_P1 = 0x04458344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG1_U0_P1 = 0x04458234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG1_U0_P1 = 0x04458244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG1_U0_P1 = 0x04458204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG1_U1_P1 = 0x04458744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG1_U1_P1 = 0x04458634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG1_U1_P1 = 0x04458644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG1_U1_P1 = 0x04458604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R0_P1 = 0x04458304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R1_P1 = 0x04458704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R2_P1 = 0x04458b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R3_P1 = 0x04458f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R4_P1 = 0x04459304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R5_P1 = 0x04459704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R6_P1 = 0x04459b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R7_P1 = 0x04459f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R8_P1 = 0x0445a304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG1_U0_P1 = 0x0445c344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG1_U0_P1 = 0x0445c234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG1_U0_P1 = 0x0445c244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG1_U0_P1 = 0x0445c204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG1_U1_P1 = 0x0445c744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG1_U1_P1 = 0x0445c634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG1_U1_P1 = 0x0445c644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG1_U1_P1 = 0x0445c604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R0_P1 = 0x0445c304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R1_P1 = 0x0445c704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R2_P1 = 0x0445cb04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R3_P1 = 0x0445cf04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R4_P1 = 0x0445d304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R5_P1 = 0x0445d704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R6_P1 = 0x0445db04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R7_P1 = 0x0445df04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R8_P1 = 0x0445e304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG1_U0_P1 = 0x04460344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG1_U0_P1 = 0x04460234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG1_U0_P1 = 0x04460244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG1_U0_P1 = 0x04460204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG1_U1_P1 = 0x04460744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG1_U1_P1 = 0x04460634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG1_U1_P1 = 0x04460644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG1_U1_P1 = 0x04460604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R0_P1 = 0x04460304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R1_P1 = 0x04460704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R2_P1 = 0x04460b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R3_P1 = 0x04460f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R4_P1 = 0x04461304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R5_P1 = 0x04461704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R6_P1 = 0x04461b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R7_P1 = 0x04461f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R8_P1 = 0x04462304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG1_U0_P1 = 0x04464344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG1_U0_P1 = 0x04464234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG1_U0_P1 = 0x04464244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG1_U0_P1 = 0x04464204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG1_U1_P1 = 0x04464744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG1_U1_P1 = 0x04464634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG1_U1_P1 = 0x04464644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG1_U1_P1 = 0x04464604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R0_P1 = 0x04464304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R1_P1 = 0x04464704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R2_P1 = 0x04464b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R3_P1 = 0x04464f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R4_P1 = 0x04465304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R5_P1 = 0x04465704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R6_P1 = 0x04465b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R7_P1 = 0x04465f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R8_P1 = 0x04466304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG2_U0_P1 = 0x04440348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG2_U0_P1 = 0x04440238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG2_U0_P1 = 0x04440248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG2_U0_P1 = 0x04440208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG2_U1_P1 = 0x04440748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG2_U1_P1 = 0x04440638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG2_U1_P1 = 0x04440648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG2_U1_P1 = 0x04440608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R0_P1 = 0x04440308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R1_P1 = 0x04440708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R2_P1 = 0x04440b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R3_P1 = 0x04440f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R4_P1 = 0x04441308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R5_P1 = 0x04441708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R6_P1 = 0x04441b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R7_P1 = 0x04441f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R8_P1 = 0x04442308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG2_U0_P1 = 0x04444348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG2_U0_P1 = 0x04444238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG2_U0_P1 = 0x04444248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG2_U0_P1 = 0x04444208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG2_U1_P1 = 0x04444748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG2_U1_P1 = 0x04444638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG2_U1_P1 = 0x04444648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG2_U1_P1 = 0x04444608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R0_P1 = 0x04444308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R1_P1 = 0x04444708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R2_P1 = 0x04444b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R3_P1 = 0x04444f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R4_P1 = 0x04445308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R5_P1 = 0x04445708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R6_P1 = 0x04445b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R7_P1 = 0x04445f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R8_P1 = 0x04446308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG2_U0_P1 = 0x04448348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG2_U0_P1 = 0x04448238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG2_U0_P1 = 0x04448248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG2_U0_P1 = 0x04448208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG2_U1_P1 = 0x04448748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG2_U1_P1 = 0x04448638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG2_U1_P1 = 0x04448648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG2_U1_P1 = 0x04448608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R0_P1 = 0x04448308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R1_P1 = 0x04448708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R2_P1 = 0x04448b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R3_P1 = 0x04448f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R4_P1 = 0x04449308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R5_P1 = 0x04449708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R6_P1 = 0x04449b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R7_P1 = 0x04449f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R8_P1 = 0x0444a308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG2_U0_P1 = 0x0444c348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG2_U0_P1 = 0x0444c238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG2_U0_P1 = 0x0444c248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG2_U0_P1 = 0x0444c208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG2_U1_P1 = 0x0444c748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG2_U1_P1 = 0x0444c638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG2_U1_P1 = 0x0444c648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG2_U1_P1 = 0x0444c608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R0_P1 = 0x0444c308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R1_P1 = 0x0444c708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R2_P1 = 0x0444cb08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R3_P1 = 0x0444cf08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R4_P1 = 0x0444d308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R5_P1 = 0x0444d708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R6_P1 = 0x0444db08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R7_P1 = 0x0444df08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R8_P1 = 0x0444e308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG2_U0_P1 = 0x04450348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG2_U0_P1 = 0x04450238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG2_U0_P1 = 0x04450248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG2_U0_P1 = 0x04450208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG2_U1_P1 = 0x04450748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG2_U1_P1 = 0x04450638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG2_U1_P1 = 0x04450648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG2_U1_P1 = 0x04450608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R0_P1 = 0x04450308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R1_P1 = 0x04450708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R2_P1 = 0x04450b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R3_P1 = 0x04450f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R4_P1 = 0x04451308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R5_P1 = 0x04451708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R6_P1 = 0x04451b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R7_P1 = 0x04451f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R8_P1 = 0x04452308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG2_U0_P1 = 0x04454348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG2_U0_P1 = 0x04454238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG2_U0_P1 = 0x04454248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG2_U0_P1 = 0x04454208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG2_U1_P1 = 0x04454748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG2_U1_P1 = 0x04454638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG2_U1_P1 = 0x04454648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG2_U1_P1 = 0x04454608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R0_P1 = 0x04454308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R1_P1 = 0x04454708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R2_P1 = 0x04454b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R3_P1 = 0x04454f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R4_P1 = 0x04455308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R5_P1 = 0x04455708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R6_P1 = 0x04455b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R7_P1 = 0x04455f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R8_P1 = 0x04456308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG2_U0_P1 = 0x04458348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG2_U0_P1 = 0x04458238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG2_U0_P1 = 0x04458248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG2_U0_P1 = 0x04458208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG2_U1_P1 = 0x04458748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG2_U1_P1 = 0x04458638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG2_U1_P1 = 0x04458648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG2_U1_P1 = 0x04458608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R0_P1 = 0x04458308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R1_P1 = 0x04458708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R2_P1 = 0x04458b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R3_P1 = 0x04458f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R4_P1 = 0x04459308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R5_P1 = 0x04459708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R6_P1 = 0x04459b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R7_P1 = 0x04459f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R8_P1 = 0x0445a308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG2_U0_P1 = 0x0445c348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG2_U0_P1 = 0x0445c238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG2_U0_P1 = 0x0445c248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG2_U0_P1 = 0x0445c208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG2_U1_P1 = 0x0445c748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG2_U1_P1 = 0x0445c638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG2_U1_P1 = 0x0445c648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG2_U1_P1 = 0x0445c608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R0_P1 = 0x0445c308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R1_P1 = 0x0445c708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R2_P1 = 0x0445cb08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R3_P1 = 0x0445cf08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R4_P1 = 0x0445d308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R5_P1 = 0x0445d708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R6_P1 = 0x0445db08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R7_P1 = 0x0445df08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R8_P1 = 0x0445e308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG2_U0_P1 = 0x04460348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG2_U0_P1 = 0x04460238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG2_U0_P1 = 0x04460248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG2_U0_P1 = 0x04460208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG2_U1_P1 = 0x04460748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG2_U1_P1 = 0x04460638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG2_U1_P1 = 0x04460648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG2_U1_P1 = 0x04460608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R0_P1 = 0x04460308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R1_P1 = 0x04460708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R2_P1 = 0x04460b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R3_P1 = 0x04460f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R4_P1 = 0x04461308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R5_P1 = 0x04461708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R6_P1 = 0x04461b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R7_P1 = 0x04461f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R8_P1 = 0x04462308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG2_U0_P1 = 0x04464348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG2_U0_P1 = 0x04464238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG2_U0_P1 = 0x04464248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG2_U0_P1 = 0x04464208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG2_U1_P1 = 0x04464748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG2_U1_P1 = 0x04464638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG2_U1_P1 = 0x04464648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG2_U1_P1 = 0x04464608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R0_P1 = 0x04464308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R1_P1 = 0x04464708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R2_P1 = 0x04464b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R3_P1 = 0x04464f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R4_P1 = 0x04465308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R5_P1 = 0x04465708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R6_P1 = 0x04465b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R7_P1 = 0x04465f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R8_P1 = 0x04466308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG3_U0_P1 = 0x0444034cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG3_U0_P1 = 0x0444023cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG3_U0_P1 = 0x0444024cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG3_U0_P1 = 0x0444020cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG3_U1_P1 = 0x0444074cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG3_U1_P1 = 0x0444063cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG3_U1_P1 = 0x0444064cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG3_U1_P1 = 0x0444060cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R0_P1 = 0x0444030cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R1_P1 = 0x0444070cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R2_P1 = 0x04440b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R3_P1 = 0x04440f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R4_P1 = 0x0444130cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R5_P1 = 0x0444170cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R6_P1 = 0x04441b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R7_P1 = 0x04441f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R8_P1 = 0x0444230cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG3_U0_P1 = 0x0444434cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG3_U0_P1 = 0x0444423cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG3_U0_P1 = 0x0444424cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG3_U0_P1 = 0x0444420cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG3_U1_P1 = 0x0444474cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG3_U1_P1 = 0x0444463cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG3_U1_P1 = 0x0444464cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG3_U1_P1 = 0x0444460cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R0_P1 = 0x0444430cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R1_P1 = 0x0444470cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R2_P1 = 0x04444b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R3_P1 = 0x04444f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R4_P1 = 0x0444530cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R5_P1 = 0x0444570cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R6_P1 = 0x04445b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R7_P1 = 0x04445f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R8_P1 = 0x0444630cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG3_U0_P1 = 0x0444834cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG3_U0_P1 = 0x0444823cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG3_U0_P1 = 0x0444824cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG3_U0_P1 = 0x0444820cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG3_U1_P1 = 0x0444874cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG3_U1_P1 = 0x0444863cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG3_U1_P1 = 0x0444864cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG3_U1_P1 = 0x0444860cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R0_P1 = 0x0444830cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R1_P1 = 0x0444870cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R2_P1 = 0x04448b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R3_P1 = 0x04448f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R4_P1 = 0x0444930cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R5_P1 = 0x0444970cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R6_P1 = 0x04449b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R7_P1 = 0x04449f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R8_P1 = 0x0444a30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG3_U0_P1 = 0x0444c34cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG3_U0_P1 = 0x0444c23cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG3_U0_P1 = 0x0444c24cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG3_U0_P1 = 0x0444c20cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG3_U1_P1 = 0x0444c74cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG3_U1_P1 = 0x0444c63cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG3_U1_P1 = 0x0444c64cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG3_U1_P1 = 0x0444c60cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R0_P1 = 0x0444c30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R1_P1 = 0x0444c70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R2_P1 = 0x0444cb0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R3_P1 = 0x0444cf0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R4_P1 = 0x0444d30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R5_P1 = 0x0444d70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R6_P1 = 0x0444db0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R7_P1 = 0x0444df0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R8_P1 = 0x0444e30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG3_U0_P1 = 0x0445034cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG3_U0_P1 = 0x0445023cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG3_U0_P1 = 0x0445024cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG3_U0_P1 = 0x0445020cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG3_U1_P1 = 0x0445074cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG3_U1_P1 = 0x0445063cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG3_U1_P1 = 0x0445064cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG3_U1_P1 = 0x0445060cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R0_P1 = 0x0445030cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R1_P1 = 0x0445070cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R2_P1 = 0x04450b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R3_P1 = 0x04450f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R4_P1 = 0x0445130cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R5_P1 = 0x0445170cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R6_P1 = 0x04451b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R7_P1 = 0x04451f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R8_P1 = 0x0445230cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG3_U0_P1 = 0x0445434cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG3_U0_P1 = 0x0445423cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG3_U0_P1 = 0x0445424cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG3_U0_P1 = 0x0445420cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG3_U1_P1 = 0x0445474cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG3_U1_P1 = 0x0445463cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG3_U1_P1 = 0x0445464cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG3_U1_P1 = 0x0445460cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R0_P1 = 0x0445430cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R1_P1 = 0x0445470cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R2_P1 = 0x04454b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R3_P1 = 0x04454f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R4_P1 = 0x0445530cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R5_P1 = 0x0445570cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R6_P1 = 0x04455b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R7_P1 = 0x04455f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R8_P1 = 0x0445630cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG3_U0_P1 = 0x0445834cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG3_U0_P1 = 0x0445823cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG3_U0_P1 = 0x0445824cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG3_U0_P1 = 0x0445820cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG3_U1_P1 = 0x0445874cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG3_U1_P1 = 0x0445863cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG3_U1_P1 = 0x0445864cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG3_U1_P1 = 0x0445860cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R0_P1 = 0x0445830cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R1_P1 = 0x0445870cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R2_P1 = 0x04458b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R3_P1 = 0x04458f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R4_P1 = 0x0445930cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R5_P1 = 0x0445970cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R6_P1 = 0x04459b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R7_P1 = 0x04459f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R8_P1 = 0x0445a30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG3_U0_P1 = 0x0445c34cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG3_U0_P1 = 0x0445c23cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG3_U0_P1 = 0x0445c24cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG3_U0_P1 = 0x0445c20cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG3_U1_P1 = 0x0445c74cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG3_U1_P1 = 0x0445c63cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG3_U1_P1 = 0x0445c64cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG3_U1_P1 = 0x0445c60cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R0_P1 = 0x0445c30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R1_P1 = 0x0445c70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R2_P1 = 0x0445cb0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R3_P1 = 0x0445cf0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R4_P1 = 0x0445d30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R5_P1 = 0x0445d70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R6_P1 = 0x0445db0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R7_P1 = 0x0445df0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R8_P1 = 0x0445e30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG3_U0_P1 = 0x0446034cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG3_U0_P1 = 0x0446023cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG3_U0_P1 = 0x0446024cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG3_U0_P1 = 0x0446020cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG3_U1_P1 = 0x0446074cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG3_U1_P1 = 0x0446063cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG3_U1_P1 = 0x0446064cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG3_U1_P1 = 0x0446060cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R0_P1 = 0x0446030cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R1_P1 = 0x0446070cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R2_P1 = 0x04460b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R3_P1 = 0x04460f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R4_P1 = 0x0446130cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R5_P1 = 0x0446170cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R6_P1 = 0x04461b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R7_P1 = 0x04461f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R8_P1 = 0x0446230cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG3_U0_P1 = 0x0446434cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG3_U0_P1 = 0x0446423cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG3_U0_P1 = 0x0446424cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG3_U0_P1 = 0x0446420cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG3_U1_P1 = 0x0446474cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG3_U1_P1 = 0x0446463cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG3_U1_P1 = 0x0446464cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG3_U1_P1 = 0x0446460cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R0_P1 = 0x0446430cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R1_P1 = 0x0446470cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R2_P1 = 0x04464b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R3_P1 = 0x04464f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R4_P1 = 0x0446530cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R5_P1 = 0x0446570cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R6_P1 = 0x04465b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R7_P1 = 0x04465f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R8_P1 = 0x0446630cull;
+static const uint64_t EXP_DDR4_PHY_ANIB0_ATXDLY_P1 = 0x04400200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB1_ATXDLY_P1 = 0x04404200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB2_ATXDLY_P1 = 0x04408200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB3_ATXDLY_P1 = 0x0440c200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB4_ATXDLY_P1 = 0x04410200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB5_ATXDLY_P1 = 0x04414200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB6_ATXDLY_P1 = 0x04418200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB7_ATXDLY_P1 = 0x0441c200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB8_ATXDLY_P1 = 0x04420200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG0_U0_P2 = 0x04840340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG0_U0_P2 = 0x04840230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG0_U0_P2 = 0x04840240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG0_U0_P2 = 0x04840200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG0_U1_P2 = 0x04840740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG0_U1_P2 = 0x04840630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG0_U1_P2 = 0x04840640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG0_U1_P2 = 0x04840600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R0_P2 = 0x04840300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R1_P2 = 0x04840700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R2_P2 = 0x04840b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R3_P2 = 0x04840f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R4_P2 = 0x04841300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R5_P2 = 0x04841700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R6_P2 = 0x04841b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R7_P2 = 0x04841f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R8_P2 = 0x04842300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG0_U0_P2 = 0x04844340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG0_U0_P2 = 0x04844230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG0_U0_P2 = 0x04844240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG0_U0_P2 = 0x04844200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG0_U1_P2 = 0x04844740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG0_U1_P2 = 0x04844630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG0_U1_P2 = 0x04844640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG0_U1_P2 = 0x04844600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R0_P2 = 0x04844300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R1_P2 = 0x04844700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R2_P2 = 0x04844b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R3_P2 = 0x04844f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R4_P2 = 0x04845300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R5_P2 = 0x04845700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R6_P2 = 0x04845b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R7_P2 = 0x04845f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R8_P2 = 0x04846300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG0_U0_P2 = 0x04848340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG0_U0_P2 = 0x04848230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG0_U0_P2 = 0x04848240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG0_U0_P2 = 0x04848200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG0_U1_P2 = 0x04848740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG0_U1_P2 = 0x04848630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG0_U1_P2 = 0x04848640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG0_U1_P2 = 0x04848600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R0_P2 = 0x04848300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R1_P2 = 0x04848700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R2_P2 = 0x04848b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R3_P2 = 0x04848f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R4_P2 = 0x04849300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R5_P2 = 0x04849700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R6_P2 = 0x04849b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R7_P2 = 0x04849f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R8_P2 = 0x0484a300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG0_U0_P2 = 0x0484c340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG0_U0_P2 = 0x0484c230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG0_U0_P2 = 0x0484c240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG0_U0_P2 = 0x0484c200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG0_U1_P2 = 0x0484c740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG0_U1_P2 = 0x0484c630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG0_U1_P2 = 0x0484c640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG0_U1_P2 = 0x0484c600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R0_P2 = 0x0484c300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R1_P2 = 0x0484c700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R2_P2 = 0x0484cb00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R3_P2 = 0x0484cf00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R4_P2 = 0x0484d300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R5_P2 = 0x0484d700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R6_P2 = 0x0484db00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R7_P2 = 0x0484df00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R8_P2 = 0x0484e300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG0_U0_P2 = 0x04850340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG0_U0_P2 = 0x04850230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG0_U0_P2 = 0x04850240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG0_U0_P2 = 0x04850200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG0_U1_P2 = 0x04850740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG0_U1_P2 = 0x04850630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG0_U1_P2 = 0x04850640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG0_U1_P2 = 0x04850600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R0_P2 = 0x04850300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R1_P2 = 0x04850700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R2_P2 = 0x04850b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R3_P2 = 0x04850f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R4_P2 = 0x04851300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R5_P2 = 0x04851700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R6_P2 = 0x04851b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R7_P2 = 0x04851f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R8_P2 = 0x04852300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG0_U0_P2 = 0x04854340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG0_U0_P2 = 0x04854230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG0_U0_P2 = 0x04854240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG0_U0_P2 = 0x04854200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG0_U1_P2 = 0x04854740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG0_U1_P2 = 0x04854630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG0_U1_P2 = 0x04854640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG0_U1_P2 = 0x04854600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R0_P2 = 0x04854300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R1_P2 = 0x04854700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R2_P2 = 0x04854b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R3_P2 = 0x04854f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R4_P2 = 0x04855300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R5_P2 = 0x04855700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R6_P2 = 0x04855b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R7_P2 = 0x04855f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R8_P2 = 0x04856300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG0_U0_P2 = 0x04858340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG0_U0_P2 = 0x04858230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG0_U0_P2 = 0x04858240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG0_U0_P2 = 0x04858200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG0_U1_P2 = 0x04858740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG0_U1_P2 = 0x04858630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG0_U1_P2 = 0x04858640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG0_U1_P2 = 0x04858600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R0_P2 = 0x04858300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R1_P2 = 0x04858700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R2_P2 = 0x04858b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R3_P2 = 0x04858f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R4_P2 = 0x04859300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R5_P2 = 0x04859700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R6_P2 = 0x04859b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R7_P2 = 0x04859f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R8_P2 = 0x0485a300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG0_U0_P2 = 0x0485c340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG0_U0_P2 = 0x0485c230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG0_U0_P2 = 0x0485c240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG0_U0_P2 = 0x0485c200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG0_U1_P2 = 0x0485c740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG0_U1_P2 = 0x0485c630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG0_U1_P2 = 0x0485c640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG0_U1_P2 = 0x0485c600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R0_P2 = 0x0485c300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R1_P2 = 0x0485c700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R2_P2 = 0x0485cb00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R3_P2 = 0x0485cf00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R4_P2 = 0x0485d300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R5_P2 = 0x0485d700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R6_P2 = 0x0485db00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R7_P2 = 0x0485df00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R8_P2 = 0x0485e300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG0_U0_P2 = 0x04860340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG0_U0_P2 = 0x04860230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG0_U0_P2 = 0x04860240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG0_U0_P2 = 0x04860200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG0_U1_P2 = 0x04860740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG0_U1_P2 = 0x04860630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG0_U1_P2 = 0x04860640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG0_U1_P2 = 0x04860600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R0_P2 = 0x04860300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R1_P2 = 0x04860700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R2_P2 = 0x04860b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R3_P2 = 0x04860f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R4_P2 = 0x04861300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R5_P2 = 0x04861700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R6_P2 = 0x04861b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R7_P2 = 0x04861f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R8_P2 = 0x04862300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG0_U0_P2 = 0x04864340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG0_U0_P2 = 0x04864230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG0_U0_P2 = 0x04864240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG0_U0_P2 = 0x04864200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG0_U1_P2 = 0x04864740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG0_U1_P2 = 0x04864630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG0_U1_P2 = 0x04864640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG0_U1_P2 = 0x04864600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R0_P2 = 0x04864300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R1_P2 = 0x04864700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R2_P2 = 0x04864b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R3_P2 = 0x04864f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R4_P2 = 0x04865300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R5_P2 = 0x04865700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R6_P2 = 0x04865b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R7_P2 = 0x04865f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R8_P2 = 0x04866300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG1_U0_P2 = 0x04840344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG1_U0_P2 = 0x04840234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG1_U0_P2 = 0x04840244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG1_U0_P2 = 0x04840204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG1_U1_P2 = 0x04840744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG1_U1_P2 = 0x04840634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG1_U1_P2 = 0x04840644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG1_U1_P2 = 0x04840604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R0_P2 = 0x04840304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R1_P2 = 0x04840704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R2_P2 = 0x04840b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R3_P2 = 0x04840f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R4_P2 = 0x04841304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R5_P2 = 0x04841704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R6_P2 = 0x04841b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R7_P2 = 0x04841f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R8_P2 = 0x04842304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG1_U0_P2 = 0x04844344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG1_U0_P2 = 0x04844234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG1_U0_P2 = 0x04844244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG1_U0_P2 = 0x04844204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG1_U1_P2 = 0x04844744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG1_U1_P2 = 0x04844634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG1_U1_P2 = 0x04844644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG1_U1_P2 = 0x04844604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R0_P2 = 0x04844304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R1_P2 = 0x04844704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R2_P2 = 0x04844b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R3_P2 = 0x04844f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R4_P2 = 0x04845304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R5_P2 = 0x04845704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R6_P2 = 0x04845b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R7_P2 = 0x04845f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R8_P2 = 0x04846304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG1_U0_P2 = 0x04848344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG1_U0_P2 = 0x04848234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG1_U0_P2 = 0x04848244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG1_U0_P2 = 0x04848204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG1_U1_P2 = 0x04848744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG1_U1_P2 = 0x04848634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG1_U1_P2 = 0x04848644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG1_U1_P2 = 0x04848604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R0_P2 = 0x04848304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R1_P2 = 0x04848704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R2_P2 = 0x04848b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R3_P2 = 0x04848f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R4_P2 = 0x04849304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R5_P2 = 0x04849704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R6_P2 = 0x04849b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R7_P2 = 0x04849f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R8_P2 = 0x0484a304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG1_U0_P2 = 0x0484c344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG1_U0_P2 = 0x0484c234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG1_U0_P2 = 0x0484c244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG1_U0_P2 = 0x0484c204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG1_U1_P2 = 0x0484c744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG1_U1_P2 = 0x0484c634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG1_U1_P2 = 0x0484c644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG1_U1_P2 = 0x0484c604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R0_P2 = 0x0484c304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R1_P2 = 0x0484c704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R2_P2 = 0x0484cb04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R3_P2 = 0x0484cf04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R4_P2 = 0x0484d304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R5_P2 = 0x0484d704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R6_P2 = 0x0484db04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R7_P2 = 0x0484df04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R8_P2 = 0x0484e304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG1_U0_P2 = 0x04850344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG1_U0_P2 = 0x04850234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG1_U0_P2 = 0x04850244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG1_U0_P2 = 0x04850204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG1_U1_P2 = 0x04850744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG1_U1_P2 = 0x04850634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG1_U1_P2 = 0x04850644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG1_U1_P2 = 0x04850604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R0_P2 = 0x04850304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R1_P2 = 0x04850704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R2_P2 = 0x04850b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R3_P2 = 0x04850f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R4_P2 = 0x04851304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R5_P2 = 0x04851704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R6_P2 = 0x04851b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R7_P2 = 0x04851f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R8_P2 = 0x04852304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG1_U0_P2 = 0x04854344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG1_U0_P2 = 0x04854234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG1_U0_P2 = 0x04854244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG1_U0_P2 = 0x04854204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG1_U1_P2 = 0x04854744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG1_U1_P2 = 0x04854634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG1_U1_P2 = 0x04854644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG1_U1_P2 = 0x04854604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R0_P2 = 0x04854304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R1_P2 = 0x04854704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R2_P2 = 0x04854b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R3_P2 = 0x04854f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R4_P2 = 0x04855304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R5_P2 = 0x04855704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R6_P2 = 0x04855b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R7_P2 = 0x04855f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R8_P2 = 0x04856304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG1_U0_P2 = 0x04858344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG1_U0_P2 = 0x04858234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG1_U0_P2 = 0x04858244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG1_U0_P2 = 0x04858204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG1_U1_P2 = 0x04858744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG1_U1_P2 = 0x04858634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG1_U1_P2 = 0x04858644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG1_U1_P2 = 0x04858604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R0_P2 = 0x04858304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R1_P2 = 0x04858704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R2_P2 = 0x04858b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R3_P2 = 0x04858f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R4_P2 = 0x04859304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R5_P2 = 0x04859704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R6_P2 = 0x04859b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R7_P2 = 0x04859f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R8_P2 = 0x0485a304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG1_U0_P2 = 0x0485c344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG1_U0_P2 = 0x0485c234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG1_U0_P2 = 0x0485c244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG1_U0_P2 = 0x0485c204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG1_U1_P2 = 0x0485c744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG1_U1_P2 = 0x0485c634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG1_U1_P2 = 0x0485c644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG1_U1_P2 = 0x0485c604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R0_P2 = 0x0485c304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R1_P2 = 0x0485c704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R2_P2 = 0x0485cb04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R3_P2 = 0x0485cf04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R4_P2 = 0x0485d304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R5_P2 = 0x0485d704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R6_P2 = 0x0485db04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R7_P2 = 0x0485df04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R8_P2 = 0x0485e304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG1_U0_P2 = 0x04860344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG1_U0_P2 = 0x04860234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG1_U0_P2 = 0x04860244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG1_U0_P2 = 0x04860204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG1_U1_P2 = 0x04860744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG1_U1_P2 = 0x04860634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG1_U1_P2 = 0x04860644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG1_U1_P2 = 0x04860604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R0_P2 = 0x04860304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R1_P2 = 0x04860704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R2_P2 = 0x04860b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R3_P2 = 0x04860f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R4_P2 = 0x04861304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R5_P2 = 0x04861704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R6_P2 = 0x04861b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R7_P2 = 0x04861f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R8_P2 = 0x04862304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG1_U0_P2 = 0x04864344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG1_U0_P2 = 0x04864234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG1_U0_P2 = 0x04864244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG1_U0_P2 = 0x04864204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG1_U1_P2 = 0x04864744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG1_U1_P2 = 0x04864634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG1_U1_P2 = 0x04864644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG1_U1_P2 = 0x04864604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R0_P2 = 0x04864304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R1_P2 = 0x04864704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R2_P2 = 0x04864b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R3_P2 = 0x04864f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R4_P2 = 0x04865304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R5_P2 = 0x04865704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R6_P2 = 0x04865b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R7_P2 = 0x04865f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R8_P2 = 0x04866304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG2_U0_P2 = 0x04840348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG2_U0_P2 = 0x04840238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG2_U0_P2 = 0x04840248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG2_U0_P2 = 0x04840208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG2_U1_P2 = 0x04840748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG2_U1_P2 = 0x04840638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG2_U1_P2 = 0x04840648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG2_U1_P2 = 0x04840608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R0_P2 = 0x04840308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R1_P2 = 0x04840708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R2_P2 = 0x04840b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R3_P2 = 0x04840f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R4_P2 = 0x04841308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R5_P2 = 0x04841708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R6_P2 = 0x04841b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R7_P2 = 0x04841f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R8_P2 = 0x04842308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG2_U0_P2 = 0x04844348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG2_U0_P2 = 0x04844238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG2_U0_P2 = 0x04844248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG2_U0_P2 = 0x04844208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG2_U1_P2 = 0x04844748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG2_U1_P2 = 0x04844638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG2_U1_P2 = 0x04844648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG2_U1_P2 = 0x04844608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R0_P2 = 0x04844308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R1_P2 = 0x04844708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R2_P2 = 0x04844b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R3_P2 = 0x04844f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R4_P2 = 0x04845308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R5_P2 = 0x04845708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R6_P2 = 0x04845b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R7_P2 = 0x04845f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R8_P2 = 0x04846308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG2_U0_P2 = 0x04848348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG2_U0_P2 = 0x04848238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG2_U0_P2 = 0x04848248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG2_U0_P2 = 0x04848208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG2_U1_P2 = 0x04848748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG2_U1_P2 = 0x04848638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG2_U1_P2 = 0x04848648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG2_U1_P2 = 0x04848608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R0_P2 = 0x04848308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R1_P2 = 0x04848708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R2_P2 = 0x04848b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R3_P2 = 0x04848f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R4_P2 = 0x04849308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R5_P2 = 0x04849708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R6_P2 = 0x04849b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R7_P2 = 0x04849f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R8_P2 = 0x0484a308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG2_U0_P2 = 0x0484c348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG2_U0_P2 = 0x0484c238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG2_U0_P2 = 0x0484c248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG2_U0_P2 = 0x0484c208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG2_U1_P2 = 0x0484c748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG2_U1_P2 = 0x0484c638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG2_U1_P2 = 0x0484c648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG2_U1_P2 = 0x0484c608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R0_P2 = 0x0484c308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R1_P2 = 0x0484c708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R2_P2 = 0x0484cb08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R3_P2 = 0x0484cf08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R4_P2 = 0x0484d308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R5_P2 = 0x0484d708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R6_P2 = 0x0484db08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R7_P2 = 0x0484df08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R8_P2 = 0x0484e308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG2_U0_P2 = 0x04850348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG2_U0_P2 = 0x04850238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG2_U0_P2 = 0x04850248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG2_U0_P2 = 0x04850208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG2_U1_P2 = 0x04850748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG2_U1_P2 = 0x04850638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG2_U1_P2 = 0x04850648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG2_U1_P2 = 0x04850608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R0_P2 = 0x04850308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R1_P2 = 0x04850708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R2_P2 = 0x04850b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R3_P2 = 0x04850f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R4_P2 = 0x04851308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R5_P2 = 0x04851708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R6_P2 = 0x04851b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R7_P2 = 0x04851f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R8_P2 = 0x04852308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG2_U0_P2 = 0x04854348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG2_U0_P2 = 0x04854238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG2_U0_P2 = 0x04854248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG2_U0_P2 = 0x04854208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG2_U1_P2 = 0x04854748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG2_U1_P2 = 0x04854638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG2_U1_P2 = 0x04854648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG2_U1_P2 = 0x04854608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R0_P2 = 0x04854308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R1_P2 = 0x04854708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R2_P2 = 0x04854b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R3_P2 = 0x04854f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R4_P2 = 0x04855308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R5_P2 = 0x04855708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R6_P2 = 0x04855b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R7_P2 = 0x04855f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R8_P2 = 0x04856308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG2_U0_P2 = 0x04858348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG2_U0_P2 = 0x04858238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG2_U0_P2 = 0x04858248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG2_U0_P2 = 0x04858208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG2_U1_P2 = 0x04858748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG2_U1_P2 = 0x04858638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG2_U1_P2 = 0x04858648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG2_U1_P2 = 0x04858608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R0_P2 = 0x04858308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R1_P2 = 0x04858708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R2_P2 = 0x04858b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R3_P2 = 0x04858f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R4_P2 = 0x04859308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R5_P2 = 0x04859708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R6_P2 = 0x04859b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R7_P2 = 0x04859f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R8_P2 = 0x0485a308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG2_U0_P2 = 0x0485c348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG2_U0_P2 = 0x0485c238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG2_U0_P2 = 0x0485c248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG2_U0_P2 = 0x0485c208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG2_U1_P2 = 0x0485c748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG2_U1_P2 = 0x0485c638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG2_U1_P2 = 0x0485c648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG2_U1_P2 = 0x0485c608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R0_P2 = 0x0485c308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R1_P2 = 0x0485c708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R2_P2 = 0x0485cb08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R3_P2 = 0x0485cf08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R4_P2 = 0x0485d308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R5_P2 = 0x0485d708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R6_P2 = 0x0485db08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R7_P2 = 0x0485df08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R8_P2 = 0x0485e308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG2_U0_P2 = 0x04860348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG2_U0_P2 = 0x04860238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG2_U0_P2 = 0x04860248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG2_U0_P2 = 0x04860208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG2_U1_P2 = 0x04860748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG2_U1_P2 = 0x04860638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG2_U1_P2 = 0x04860648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG2_U1_P2 = 0x04860608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R0_P2 = 0x04860308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R1_P2 = 0x04860708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R2_P2 = 0x04860b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R3_P2 = 0x04860f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R4_P2 = 0x04861308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R5_P2 = 0x04861708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R6_P2 = 0x04861b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R7_P2 = 0x04861f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R8_P2 = 0x04862308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG2_U0_P2 = 0x04864348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG2_U0_P2 = 0x04864238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG2_U0_P2 = 0x04864248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG2_U0_P2 = 0x04864208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG2_U1_P2 = 0x04864748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG2_U1_P2 = 0x04864638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG2_U1_P2 = 0x04864648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG2_U1_P2 = 0x04864608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R0_P2 = 0x04864308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R1_P2 = 0x04864708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R2_P2 = 0x04864b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R3_P2 = 0x04864f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R4_P2 = 0x04865308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R5_P2 = 0x04865708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R6_P2 = 0x04865b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R7_P2 = 0x04865f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R8_P2 = 0x04866308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG3_U0_P2 = 0x0484034cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG3_U0_P2 = 0x0484023cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG3_U0_P2 = 0x0484024cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG3_U0_P2 = 0x0484020cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG3_U1_P2 = 0x0484074cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG3_U1_P2 = 0x0484063cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG3_U1_P2 = 0x0484064cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG3_U1_P2 = 0x0484060cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R0_P2 = 0x0484030cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R1_P2 = 0x0484070cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R2_P2 = 0x04840b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R3_P2 = 0x04840f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R4_P2 = 0x0484130cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R5_P2 = 0x0484170cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R6_P2 = 0x04841b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R7_P2 = 0x04841f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R8_P2 = 0x0484230cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG3_U0_P2 = 0x0484434cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG3_U0_P2 = 0x0484423cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG3_U0_P2 = 0x0484424cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG3_U0_P2 = 0x0484420cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG3_U1_P2 = 0x0484474cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG3_U1_P2 = 0x0484463cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG3_U1_P2 = 0x0484464cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG3_U1_P2 = 0x0484460cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R0_P2 = 0x0484430cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R1_P2 = 0x0484470cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R2_P2 = 0x04844b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R3_P2 = 0x04844f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R4_P2 = 0x0484530cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R5_P2 = 0x0484570cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R6_P2 = 0x04845b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R7_P2 = 0x04845f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R8_P2 = 0x0484630cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG3_U0_P2 = 0x0484834cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG3_U0_P2 = 0x0484823cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG3_U0_P2 = 0x0484824cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG3_U0_P2 = 0x0484820cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG3_U1_P2 = 0x0484874cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG3_U1_P2 = 0x0484863cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG3_U1_P2 = 0x0484864cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG3_U1_P2 = 0x0484860cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R0_P2 = 0x0484830cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R1_P2 = 0x0484870cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R2_P2 = 0x04848b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R3_P2 = 0x04848f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R4_P2 = 0x0484930cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R5_P2 = 0x0484970cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R6_P2 = 0x04849b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R7_P2 = 0x04849f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R8_P2 = 0x0484a30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG3_U0_P2 = 0x0484c34cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG3_U0_P2 = 0x0484c23cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG3_U0_P2 = 0x0484c24cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG3_U0_P2 = 0x0484c20cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG3_U1_P2 = 0x0484c74cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG3_U1_P2 = 0x0484c63cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG3_U1_P2 = 0x0484c64cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG3_U1_P2 = 0x0484c60cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R0_P2 = 0x0484c30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R1_P2 = 0x0484c70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R2_P2 = 0x0484cb0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R3_P2 = 0x0484cf0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R4_P2 = 0x0484d30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R5_P2 = 0x0484d70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R6_P2 = 0x0484db0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R7_P2 = 0x0484df0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R8_P2 = 0x0484e30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG3_U0_P2 = 0x0485034cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG3_U0_P2 = 0x0485023cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG3_U0_P2 = 0x0485024cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG3_U0_P2 = 0x0485020cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG3_U1_P2 = 0x0485074cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG3_U1_P2 = 0x0485063cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG3_U1_P2 = 0x0485064cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG3_U1_P2 = 0x0485060cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R0_P2 = 0x0485030cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R1_P2 = 0x0485070cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R2_P2 = 0x04850b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R3_P2 = 0x04850f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R4_P2 = 0x0485130cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R5_P2 = 0x0485170cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R6_P2 = 0x04851b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R7_P2 = 0x04851f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R8_P2 = 0x0485230cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG3_U0_P2 = 0x0485434cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG3_U0_P2 = 0x0485423cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG3_U0_P2 = 0x0485424cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG3_U0_P2 = 0x0485420cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG3_U1_P2 = 0x0485474cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG3_U1_P2 = 0x0485463cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG3_U1_P2 = 0x0485464cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG3_U1_P2 = 0x0485460cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R0_P2 = 0x0485430cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R1_P2 = 0x0485470cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R2_P2 = 0x04854b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R3_P2 = 0x04854f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R4_P2 = 0x0485530cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R5_P2 = 0x0485570cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R6_P2 = 0x04855b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R7_P2 = 0x04855f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R8_P2 = 0x0485630cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG3_U0_P2 = 0x0485834cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG3_U0_P2 = 0x0485823cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG3_U0_P2 = 0x0485824cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG3_U0_P2 = 0x0485820cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG3_U1_P2 = 0x0485874cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG3_U1_P2 = 0x0485863cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG3_U1_P2 = 0x0485864cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG3_U1_P2 = 0x0485860cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R0_P2 = 0x0485830cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R1_P2 = 0x0485870cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R2_P2 = 0x04858b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R3_P2 = 0x04858f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R4_P2 = 0x0485930cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R5_P2 = 0x0485970cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R6_P2 = 0x04859b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R7_P2 = 0x04859f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R8_P2 = 0x0485a30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG3_U0_P2 = 0x0485c34cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG3_U0_P2 = 0x0485c23cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG3_U0_P2 = 0x0485c24cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG3_U0_P2 = 0x0485c20cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG3_U1_P2 = 0x0485c74cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG3_U1_P2 = 0x0485c63cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG3_U1_P2 = 0x0485c64cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG3_U1_P2 = 0x0485c60cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R0_P2 = 0x0485c30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R1_P2 = 0x0485c70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R2_P2 = 0x0485cb0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R3_P2 = 0x0485cf0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R4_P2 = 0x0485d30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R5_P2 = 0x0485d70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R6_P2 = 0x0485db0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R7_P2 = 0x0485df0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R8_P2 = 0x0485e30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG3_U0_P2 = 0x0486034cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG3_U0_P2 = 0x0486023cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG3_U0_P2 = 0x0486024cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG3_U0_P2 = 0x0486020cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG3_U1_P2 = 0x0486074cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG3_U1_P2 = 0x0486063cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG3_U1_P2 = 0x0486064cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG3_U1_P2 = 0x0486060cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R0_P2 = 0x0486030cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R1_P2 = 0x0486070cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R2_P2 = 0x04860b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R3_P2 = 0x04860f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R4_P2 = 0x0486130cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R5_P2 = 0x0486170cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R6_P2 = 0x04861b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R7_P2 = 0x04861f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R8_P2 = 0x0486230cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG3_U0_P2 = 0x0486434cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG3_U0_P2 = 0x0486423cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG3_U0_P2 = 0x0486424cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG3_U0_P2 = 0x0486420cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG3_U1_P2 = 0x0486474cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG3_U1_P2 = 0x0486463cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG3_U1_P2 = 0x0486464cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG3_U1_P2 = 0x0486460cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R0_P2 = 0x0486430cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R1_P2 = 0x0486470cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R2_P2 = 0x04864b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R3_P2 = 0x04864f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R4_P2 = 0x0486530cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R5_P2 = 0x0486570cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R6_P2 = 0x04865b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R7_P2 = 0x04865f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R8_P2 = 0x0486630cull;
+static const uint64_t EXP_DDR4_PHY_ANIB0_ATXDLY_P2 = 0x04800200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB1_ATXDLY_P2 = 0x04804200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB2_ATXDLY_P2 = 0x04808200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB3_ATXDLY_P2 = 0x0480c200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB4_ATXDLY_P2 = 0x04810200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB5_ATXDLY_P2 = 0x04814200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB6_ATXDLY_P2 = 0x04818200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB7_ATXDLY_P2 = 0x0481c200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB8_ATXDLY_P2 = 0x04820200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG0_U0_P3 = 0x04c40340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG0_U0_P3 = 0x04c40230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG0_U0_P3 = 0x04c40240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG0_U0_P3 = 0x04c40200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG0_U1_P3 = 0x04c40740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG0_U1_P3 = 0x04c40630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG0_U1_P3 = 0x04c40640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG0_U1_P3 = 0x04c40600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R0_P3 = 0x04c40300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R1_P3 = 0x04c40700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R2_P3 = 0x04c40b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R3_P3 = 0x04c40f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R4_P3 = 0x04c41300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R5_P3 = 0x04c41700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R6_P3 = 0x04c41b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R7_P3 = 0x04c41f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG0_R8_P3 = 0x04c42300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG0_U0_P3 = 0x04c44340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG0_U0_P3 = 0x04c44230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG0_U0_P3 = 0x04c44240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG0_U0_P3 = 0x04c44200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG0_U1_P3 = 0x04c44740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG0_U1_P3 = 0x04c44630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG0_U1_P3 = 0x04c44640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG0_U1_P3 = 0x04c44600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R0_P3 = 0x04c44300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R1_P3 = 0x04c44700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R2_P3 = 0x04c44b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R3_P3 = 0x04c44f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R4_P3 = 0x04c45300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R5_P3 = 0x04c45700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R6_P3 = 0x04c45b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R7_P3 = 0x04c45f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG0_R8_P3 = 0x04c46300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG0_U0_P3 = 0x04c48340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG0_U0_P3 = 0x04c48230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG0_U0_P3 = 0x04c48240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG0_U0_P3 = 0x04c48200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG0_U1_P3 = 0x04c48740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG0_U1_P3 = 0x04c48630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG0_U1_P3 = 0x04c48640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG0_U1_P3 = 0x04c48600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R0_P3 = 0x04c48300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R1_P3 = 0x04c48700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R2_P3 = 0x04c48b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R3_P3 = 0x04c48f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R4_P3 = 0x04c49300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R5_P3 = 0x04c49700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R6_P3 = 0x04c49b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R7_P3 = 0x04c49f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG0_R8_P3 = 0x04c4a300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG0_U0_P3 = 0x04c4c340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG0_U0_P3 = 0x04c4c230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG0_U0_P3 = 0x04c4c240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG0_U0_P3 = 0x04c4c200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG0_U1_P3 = 0x04c4c740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG0_U1_P3 = 0x04c4c630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG0_U1_P3 = 0x04c4c640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG0_U1_P3 = 0x04c4c600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R0_P3 = 0x04c4c300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R1_P3 = 0x04c4c700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R2_P3 = 0x04c4cb00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R3_P3 = 0x04c4cf00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R4_P3 = 0x04c4d300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R5_P3 = 0x04c4d700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R6_P3 = 0x04c4db00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R7_P3 = 0x04c4df00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG0_R8_P3 = 0x04c4e300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG0_U0_P3 = 0x04c50340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG0_U0_P3 = 0x04c50230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG0_U0_P3 = 0x04c50240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG0_U0_P3 = 0x04c50200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG0_U1_P3 = 0x04c50740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG0_U1_P3 = 0x04c50630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG0_U1_P3 = 0x04c50640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG0_U1_P3 = 0x04c50600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R0_P3 = 0x04c50300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R1_P3 = 0x04c50700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R2_P3 = 0x04c50b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R3_P3 = 0x04c50f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R4_P3 = 0x04c51300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R5_P3 = 0x04c51700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R6_P3 = 0x04c51b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R7_P3 = 0x04c51f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG0_R8_P3 = 0x04c52300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG0_U0_P3 = 0x04c54340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG0_U0_P3 = 0x04c54230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG0_U0_P3 = 0x04c54240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG0_U0_P3 = 0x04c54200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG0_U1_P3 = 0x04c54740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG0_U1_P3 = 0x04c54630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG0_U1_P3 = 0x04c54640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG0_U1_P3 = 0x04c54600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R0_P3 = 0x04c54300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R1_P3 = 0x04c54700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R2_P3 = 0x04c54b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R3_P3 = 0x04c54f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R4_P3 = 0x04c55300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R5_P3 = 0x04c55700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R6_P3 = 0x04c55b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R7_P3 = 0x04c55f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG0_R8_P3 = 0x04c56300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG0_U0_P3 = 0x04c58340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG0_U0_P3 = 0x04c58230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG0_U0_P3 = 0x04c58240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG0_U0_P3 = 0x04c58200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG0_U1_P3 = 0x04c58740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG0_U1_P3 = 0x04c58630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG0_U1_P3 = 0x04c58640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG0_U1_P3 = 0x04c58600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R0_P3 = 0x04c58300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R1_P3 = 0x04c58700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R2_P3 = 0x04c58b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R3_P3 = 0x04c58f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R4_P3 = 0x04c59300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R5_P3 = 0x04c59700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R6_P3 = 0x04c59b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R7_P3 = 0x04c59f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG0_R8_P3 = 0x04c5a300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG0_U0_P3 = 0x04c5c340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG0_U0_P3 = 0x04c5c230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG0_U0_P3 = 0x04c5c240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG0_U0_P3 = 0x04c5c200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG0_U1_P3 = 0x04c5c740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG0_U1_P3 = 0x04c5c630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG0_U1_P3 = 0x04c5c640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG0_U1_P3 = 0x04c5c600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R0_P3 = 0x04c5c300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R1_P3 = 0x04c5c700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R2_P3 = 0x04c5cb00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R3_P3 = 0x04c5cf00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R4_P3 = 0x04c5d300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R5_P3 = 0x04c5d700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R6_P3 = 0x04c5db00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R7_P3 = 0x04c5df00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG0_R8_P3 = 0x04c5e300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG0_U0_P3 = 0x04c60340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG0_U0_P3 = 0x04c60230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG0_U0_P3 = 0x04c60240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG0_U0_P3 = 0x04c60200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG0_U1_P3 = 0x04c60740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG0_U1_P3 = 0x04c60630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG0_U1_P3 = 0x04c60640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG0_U1_P3 = 0x04c60600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R0_P3 = 0x04c60300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R1_P3 = 0x04c60700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R2_P3 = 0x04c60b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R3_P3 = 0x04c60f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R4_P3 = 0x04c61300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R5_P3 = 0x04c61700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R6_P3 = 0x04c61b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R7_P3 = 0x04c61f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG0_R8_P3 = 0x04c62300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG0_U0_P3 = 0x04c64340ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG0_U0_P3 = 0x04c64230ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG0_U0_P3 = 0x04c64240ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG0_U0_P3 = 0x04c64200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG0_U1_P3 = 0x04c64740ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG0_U1_P3 = 0x04c64630ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG0_U1_P3 = 0x04c64640ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG0_U1_P3 = 0x04c64600ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R0_P3 = 0x04c64300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R1_P3 = 0x04c64700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R2_P3 = 0x04c64b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R3_P3 = 0x04c64f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R4_P3 = 0x04c65300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R5_P3 = 0x04c65700ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R6_P3 = 0x04c65b00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R7_P3 = 0x04c65f00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG0_R8_P3 = 0x04c66300ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG1_U0_P3 = 0x04c40344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG1_U0_P3 = 0x04c40234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG1_U0_P3 = 0x04c40244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG1_U0_P3 = 0x04c40204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG1_U1_P3 = 0x04c40744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG1_U1_P3 = 0x04c40634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG1_U1_P3 = 0x04c40644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG1_U1_P3 = 0x04c40604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R0_P3 = 0x04c40304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R1_P3 = 0x04c40704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R2_P3 = 0x04c40b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R3_P3 = 0x04c40f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R4_P3 = 0x04c41304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R5_P3 = 0x04c41704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R6_P3 = 0x04c41b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R7_P3 = 0x04c41f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG1_R8_P3 = 0x04c42304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG1_U0_P3 = 0x04c44344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG1_U0_P3 = 0x04c44234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG1_U0_P3 = 0x04c44244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG1_U0_P3 = 0x04c44204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG1_U1_P3 = 0x04c44744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG1_U1_P3 = 0x04c44634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG1_U1_P3 = 0x04c44644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG1_U1_P3 = 0x04c44604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R0_P3 = 0x04c44304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R1_P3 = 0x04c44704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R2_P3 = 0x04c44b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R3_P3 = 0x04c44f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R4_P3 = 0x04c45304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R5_P3 = 0x04c45704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R6_P3 = 0x04c45b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R7_P3 = 0x04c45f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG1_R8_P3 = 0x04c46304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG1_U0_P3 = 0x04c48344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG1_U0_P3 = 0x04c48234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG1_U0_P3 = 0x04c48244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG1_U0_P3 = 0x04c48204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG1_U1_P3 = 0x04c48744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG1_U1_P3 = 0x04c48634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG1_U1_P3 = 0x04c48644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG1_U1_P3 = 0x04c48604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R0_P3 = 0x04c48304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R1_P3 = 0x04c48704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R2_P3 = 0x04c48b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R3_P3 = 0x04c48f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R4_P3 = 0x04c49304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R5_P3 = 0x04c49704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R6_P3 = 0x04c49b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R7_P3 = 0x04c49f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG1_R8_P3 = 0x04c4a304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG1_U0_P3 = 0x04c4c344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG1_U0_P3 = 0x04c4c234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG1_U0_P3 = 0x04c4c244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG1_U0_P3 = 0x04c4c204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG1_U1_P3 = 0x04c4c744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG1_U1_P3 = 0x04c4c634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG1_U1_P3 = 0x04c4c644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG1_U1_P3 = 0x04c4c604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R0_P3 = 0x04c4c304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R1_P3 = 0x04c4c704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R2_P3 = 0x04c4cb04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R3_P3 = 0x04c4cf04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R4_P3 = 0x04c4d304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R5_P3 = 0x04c4d704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R6_P3 = 0x04c4db04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R7_P3 = 0x04c4df04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG1_R8_P3 = 0x04c4e304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG1_U0_P3 = 0x04c50344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG1_U0_P3 = 0x04c50234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG1_U0_P3 = 0x04c50244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG1_U0_P3 = 0x04c50204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG1_U1_P3 = 0x04c50744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG1_U1_P3 = 0x04c50634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG1_U1_P3 = 0x04c50644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG1_U1_P3 = 0x04c50604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R0_P3 = 0x04c50304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R1_P3 = 0x04c50704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R2_P3 = 0x04c50b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R3_P3 = 0x04c50f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R4_P3 = 0x04c51304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R5_P3 = 0x04c51704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R6_P3 = 0x04c51b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R7_P3 = 0x04c51f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG1_R8_P3 = 0x04c52304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG1_U0_P3 = 0x04c54344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG1_U0_P3 = 0x04c54234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG1_U0_P3 = 0x04c54244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG1_U0_P3 = 0x04c54204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG1_U1_P3 = 0x04c54744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG1_U1_P3 = 0x04c54634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG1_U1_P3 = 0x04c54644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG1_U1_P3 = 0x04c54604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R0_P3 = 0x04c54304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R1_P3 = 0x04c54704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R2_P3 = 0x04c54b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R3_P3 = 0x04c54f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R4_P3 = 0x04c55304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R5_P3 = 0x04c55704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R6_P3 = 0x04c55b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R7_P3 = 0x04c55f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG1_R8_P3 = 0x04c56304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG1_U0_P3 = 0x04c58344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG1_U0_P3 = 0x04c58234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG1_U0_P3 = 0x04c58244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG1_U0_P3 = 0x04c58204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG1_U1_P3 = 0x04c58744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG1_U1_P3 = 0x04c58634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG1_U1_P3 = 0x04c58644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG1_U1_P3 = 0x04c58604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R0_P3 = 0x04c58304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R1_P3 = 0x04c58704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R2_P3 = 0x04c58b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R3_P3 = 0x04c58f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R4_P3 = 0x04c59304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R5_P3 = 0x04c59704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R6_P3 = 0x04c59b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R7_P3 = 0x04c59f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG1_R8_P3 = 0x04c5a304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG1_U0_P3 = 0x04c5c344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG1_U0_P3 = 0x04c5c234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG1_U0_P3 = 0x04c5c244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG1_U0_P3 = 0x04c5c204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG1_U1_P3 = 0x04c5c744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG1_U1_P3 = 0x04c5c634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG1_U1_P3 = 0x04c5c644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG1_U1_P3 = 0x04c5c604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R0_P3 = 0x04c5c304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R1_P3 = 0x04c5c704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R2_P3 = 0x04c5cb04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R3_P3 = 0x04c5cf04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R4_P3 = 0x04c5d304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R5_P3 = 0x04c5d704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R6_P3 = 0x04c5db04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R7_P3 = 0x04c5df04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG1_R8_P3 = 0x04c5e304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG1_U0_P3 = 0x04c60344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG1_U0_P3 = 0x04c60234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG1_U0_P3 = 0x04c60244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG1_U0_P3 = 0x04c60204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG1_U1_P3 = 0x04c60744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG1_U1_P3 = 0x04c60634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG1_U1_P3 = 0x04c60644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG1_U1_P3 = 0x04c60604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R0_P3 = 0x04c60304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R1_P3 = 0x04c60704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R2_P3 = 0x04c60b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R3_P3 = 0x04c60f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R4_P3 = 0x04c61304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R5_P3 = 0x04c61704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R6_P3 = 0x04c61b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R7_P3 = 0x04c61f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG1_R8_P3 = 0x04c62304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG1_U0_P3 = 0x04c64344ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG1_U0_P3 = 0x04c64234ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG1_U0_P3 = 0x04c64244ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG1_U0_P3 = 0x04c64204ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG1_U1_P3 = 0x04c64744ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG1_U1_P3 = 0x04c64634ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG1_U1_P3 = 0x04c64644ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG1_U1_P3 = 0x04c64604ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R0_P3 = 0x04c64304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R1_P3 = 0x04c64704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R2_P3 = 0x04c64b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R3_P3 = 0x04c64f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R4_P3 = 0x04c65304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R5_P3 = 0x04c65704ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R6_P3 = 0x04c65b04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R7_P3 = 0x04c65f04ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG1_R8_P3 = 0x04c66304ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG2_U0_P3 = 0x04c40348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG2_U0_P3 = 0x04c40238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG2_U0_P3 = 0x04c40248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG2_U0_P3 = 0x04c40208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG2_U1_P3 = 0x04c40748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG2_U1_P3 = 0x04c40638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG2_U1_P3 = 0x04c40648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG2_U1_P3 = 0x04c40608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R0_P3 = 0x04c40308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R1_P3 = 0x04c40708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R2_P3 = 0x04c40b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R3_P3 = 0x04c40f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R4_P3 = 0x04c41308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R5_P3 = 0x04c41708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R6_P3 = 0x04c41b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R7_P3 = 0x04c41f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG2_R8_P3 = 0x04c42308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG2_U0_P3 = 0x04c44348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG2_U0_P3 = 0x04c44238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG2_U0_P3 = 0x04c44248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG2_U0_P3 = 0x04c44208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG2_U1_P3 = 0x04c44748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG2_U1_P3 = 0x04c44638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG2_U1_P3 = 0x04c44648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG2_U1_P3 = 0x04c44608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R0_P3 = 0x04c44308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R1_P3 = 0x04c44708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R2_P3 = 0x04c44b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R3_P3 = 0x04c44f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R4_P3 = 0x04c45308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R5_P3 = 0x04c45708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R6_P3 = 0x04c45b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R7_P3 = 0x04c45f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG2_R8_P3 = 0x04c46308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG2_U0_P3 = 0x04c48348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG2_U0_P3 = 0x04c48238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG2_U0_P3 = 0x04c48248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG2_U0_P3 = 0x04c48208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG2_U1_P3 = 0x04c48748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG2_U1_P3 = 0x04c48638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG2_U1_P3 = 0x04c48648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG2_U1_P3 = 0x04c48608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R0_P3 = 0x04c48308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R1_P3 = 0x04c48708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R2_P3 = 0x04c48b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R3_P3 = 0x04c48f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R4_P3 = 0x04c49308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R5_P3 = 0x04c49708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R6_P3 = 0x04c49b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R7_P3 = 0x04c49f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG2_R8_P3 = 0x04c4a308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG2_U0_P3 = 0x04c4c348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG2_U0_P3 = 0x04c4c238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG2_U0_P3 = 0x04c4c248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG2_U0_P3 = 0x04c4c208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG2_U1_P3 = 0x04c4c748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG2_U1_P3 = 0x04c4c638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG2_U1_P3 = 0x04c4c648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG2_U1_P3 = 0x04c4c608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R0_P3 = 0x04c4c308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R1_P3 = 0x04c4c708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R2_P3 = 0x04c4cb08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R3_P3 = 0x04c4cf08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R4_P3 = 0x04c4d308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R5_P3 = 0x04c4d708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R6_P3 = 0x04c4db08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R7_P3 = 0x04c4df08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG2_R8_P3 = 0x04c4e308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG2_U0_P3 = 0x04c50348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG2_U0_P3 = 0x04c50238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG2_U0_P3 = 0x04c50248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG2_U0_P3 = 0x04c50208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG2_U1_P3 = 0x04c50748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG2_U1_P3 = 0x04c50638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG2_U1_P3 = 0x04c50648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG2_U1_P3 = 0x04c50608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R0_P3 = 0x04c50308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R1_P3 = 0x04c50708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R2_P3 = 0x04c50b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R3_P3 = 0x04c50f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R4_P3 = 0x04c51308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R5_P3 = 0x04c51708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R6_P3 = 0x04c51b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R7_P3 = 0x04c51f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG2_R8_P3 = 0x04c52308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG2_U0_P3 = 0x04c54348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG2_U0_P3 = 0x04c54238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG2_U0_P3 = 0x04c54248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG2_U0_P3 = 0x04c54208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG2_U1_P3 = 0x04c54748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG2_U1_P3 = 0x04c54638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG2_U1_P3 = 0x04c54648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG2_U1_P3 = 0x04c54608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R0_P3 = 0x04c54308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R1_P3 = 0x04c54708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R2_P3 = 0x04c54b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R3_P3 = 0x04c54f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R4_P3 = 0x04c55308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R5_P3 = 0x04c55708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R6_P3 = 0x04c55b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R7_P3 = 0x04c55f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG2_R8_P3 = 0x04c56308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG2_U0_P3 = 0x04c58348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG2_U0_P3 = 0x04c58238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG2_U0_P3 = 0x04c58248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG2_U0_P3 = 0x04c58208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG2_U1_P3 = 0x04c58748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG2_U1_P3 = 0x04c58638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG2_U1_P3 = 0x04c58648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG2_U1_P3 = 0x04c58608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R0_P3 = 0x04c58308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R1_P3 = 0x04c58708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R2_P3 = 0x04c58b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R3_P3 = 0x04c58f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R4_P3 = 0x04c59308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R5_P3 = 0x04c59708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R6_P3 = 0x04c59b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R7_P3 = 0x04c59f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG2_R8_P3 = 0x04c5a308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG2_U0_P3 = 0x04c5c348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG2_U0_P3 = 0x04c5c238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG2_U0_P3 = 0x04c5c248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG2_U0_P3 = 0x04c5c208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG2_U1_P3 = 0x04c5c748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG2_U1_P3 = 0x04c5c638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG2_U1_P3 = 0x04c5c648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG2_U1_P3 = 0x04c5c608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R0_P3 = 0x04c5c308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R1_P3 = 0x04c5c708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R2_P3 = 0x04c5cb08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R3_P3 = 0x04c5cf08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R4_P3 = 0x04c5d308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R5_P3 = 0x04c5d708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R6_P3 = 0x04c5db08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R7_P3 = 0x04c5df08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG2_R8_P3 = 0x04c5e308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG2_U0_P3 = 0x04c60348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG2_U0_P3 = 0x04c60238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG2_U0_P3 = 0x04c60248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG2_U0_P3 = 0x04c60208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG2_U1_P3 = 0x04c60748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG2_U1_P3 = 0x04c60638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG2_U1_P3 = 0x04c60648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG2_U1_P3 = 0x04c60608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R0_P3 = 0x04c60308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R1_P3 = 0x04c60708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R2_P3 = 0x04c60b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R3_P3 = 0x04c60f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R4_P3 = 0x04c61308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R5_P3 = 0x04c61708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R6_P3 = 0x04c61b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R7_P3 = 0x04c61f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG2_R8_P3 = 0x04c62308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG2_U0_P3 = 0x04c64348ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG2_U0_P3 = 0x04c64238ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG2_U0_P3 = 0x04c64248ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG2_U0_P3 = 0x04c64208ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG2_U1_P3 = 0x04c64748ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG2_U1_P3 = 0x04c64638ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG2_U1_P3 = 0x04c64648ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG2_U1_P3 = 0x04c64608ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R0_P3 = 0x04c64308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R1_P3 = 0x04c64708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R2_P3 = 0x04c64b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R3_P3 = 0x04c64f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R4_P3 = 0x04c65308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R5_P3 = 0x04c65708ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R6_P3 = 0x04c65b08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R7_P3 = 0x04c65f08ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG2_R8_P3 = 0x04c66308ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG3_U0_P3 = 0x04c4034cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG3_U0_P3 = 0x04c4023cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG3_U0_P3 = 0x04c4024cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG3_U0_P3 = 0x04c4020cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQSDLYTG3_U1_P3 = 0x04c4074cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKDLYTG3_U1_P3 = 0x04c4063cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXCLKCDLYTG3_U1_P3 = 0x04c4064cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXENDLYTG3_U1_P3 = 0x04c4060cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R0_P3 = 0x04c4030cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R1_P3 = 0x04c4070cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R2_P3 = 0x04c40b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R3_P3 = 0x04c40f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R4_P3 = 0x04c4130cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R5_P3 = 0x04c4170cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R6_P3 = 0x04c41b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R7_P3 = 0x04c41f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_TXDQDLYTG3_R8_P3 = 0x04c4230cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG3_U0_P3 = 0x04c4434cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG3_U0_P3 = 0x04c4423cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG3_U0_P3 = 0x04c4424cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG3_U0_P3 = 0x04c4420cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQSDLYTG3_U1_P3 = 0x04c4474cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKDLYTG3_U1_P3 = 0x04c4463cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXCLKCDLYTG3_U1_P3 = 0x04c4464cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXENDLYTG3_U1_P3 = 0x04c4460cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R0_P3 = 0x04c4430cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R1_P3 = 0x04c4470cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R2_P3 = 0x04c44b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R3_P3 = 0x04c44f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R4_P3 = 0x04c4530cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R5_P3 = 0x04c4570cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R6_P3 = 0x04c45b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R7_P3 = 0x04c45f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_TXDQDLYTG3_R8_P3 = 0x04c4630cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG3_U0_P3 = 0x04c4834cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG3_U0_P3 = 0x04c4823cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG3_U0_P3 = 0x04c4824cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG3_U0_P3 = 0x04c4820cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQSDLYTG3_U1_P3 = 0x04c4874cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKDLYTG3_U1_P3 = 0x04c4863cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXCLKCDLYTG3_U1_P3 = 0x04c4864cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXENDLYTG3_U1_P3 = 0x04c4860cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R0_P3 = 0x04c4830cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R1_P3 = 0x04c4870cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R2_P3 = 0x04c48b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R3_P3 = 0x04c48f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R4_P3 = 0x04c4930cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R5_P3 = 0x04c4970cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R6_P3 = 0x04c49b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R7_P3 = 0x04c49f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_TXDQDLYTG3_R8_P3 = 0x04c4a30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG3_U0_P3 = 0x04c4c34cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG3_U0_P3 = 0x04c4c23cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG3_U0_P3 = 0x04c4c24cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG3_U0_P3 = 0x04c4c20cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQSDLYTG3_U1_P3 = 0x04c4c74cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKDLYTG3_U1_P3 = 0x04c4c63cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXCLKCDLYTG3_U1_P3 = 0x04c4c64cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXENDLYTG3_U1_P3 = 0x04c4c60cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R0_P3 = 0x04c4c30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R1_P3 = 0x04c4c70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R2_P3 = 0x04c4cb0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R3_P3 = 0x04c4cf0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R4_P3 = 0x04c4d30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R5_P3 = 0x04c4d70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R6_P3 = 0x04c4db0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R7_P3 = 0x04c4df0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_TXDQDLYTG3_R8_P3 = 0x04c4e30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG3_U0_P3 = 0x04c5034cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG3_U0_P3 = 0x04c5023cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG3_U0_P3 = 0x04c5024cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG3_U0_P3 = 0x04c5020cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQSDLYTG3_U1_P3 = 0x04c5074cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKDLYTG3_U1_P3 = 0x04c5063cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXCLKCDLYTG3_U1_P3 = 0x04c5064cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXENDLYTG3_U1_P3 = 0x04c5060cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R0_P3 = 0x04c5030cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R1_P3 = 0x04c5070cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R2_P3 = 0x04c50b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R3_P3 = 0x04c50f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R4_P3 = 0x04c5130cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R5_P3 = 0x04c5170cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R6_P3 = 0x04c51b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R7_P3 = 0x04c51f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_TXDQDLYTG3_R8_P3 = 0x04c5230cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG3_U0_P3 = 0x04c5434cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG3_U0_P3 = 0x04c5423cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG3_U0_P3 = 0x04c5424cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG3_U0_P3 = 0x04c5420cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQSDLYTG3_U1_P3 = 0x04c5474cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKDLYTG3_U1_P3 = 0x04c5463cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXCLKCDLYTG3_U1_P3 = 0x04c5464cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXENDLYTG3_U1_P3 = 0x04c5460cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R0_P3 = 0x04c5430cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R1_P3 = 0x04c5470cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R2_P3 = 0x04c54b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R3_P3 = 0x04c54f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R4_P3 = 0x04c5530cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R5_P3 = 0x04c5570cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R6_P3 = 0x04c55b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R7_P3 = 0x04c55f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_TXDQDLYTG3_R8_P3 = 0x04c5630cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG3_U0_P3 = 0x04c5834cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG3_U0_P3 = 0x04c5823cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG3_U0_P3 = 0x04c5824cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG3_U0_P3 = 0x04c5820cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQSDLYTG3_U1_P3 = 0x04c5874cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKDLYTG3_U1_P3 = 0x04c5863cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXCLKCDLYTG3_U1_P3 = 0x04c5864cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXENDLYTG3_U1_P3 = 0x04c5860cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R0_P3 = 0x04c5830cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R1_P3 = 0x04c5870cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R2_P3 = 0x04c58b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R3_P3 = 0x04c58f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R4_P3 = 0x04c5930cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R5_P3 = 0x04c5970cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R6_P3 = 0x04c59b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R7_P3 = 0x04c59f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_TXDQDLYTG3_R8_P3 = 0x04c5a30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG3_U0_P3 = 0x04c5c34cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG3_U0_P3 = 0x04c5c23cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG3_U0_P3 = 0x04c5c24cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG3_U0_P3 = 0x04c5c20cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQSDLYTG3_U1_P3 = 0x04c5c74cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKDLYTG3_U1_P3 = 0x04c5c63cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXCLKCDLYTG3_U1_P3 = 0x04c5c64cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXENDLYTG3_U1_P3 = 0x04c5c60cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R0_P3 = 0x04c5c30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R1_P3 = 0x04c5c70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R2_P3 = 0x04c5cb0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R3_P3 = 0x04c5cf0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R4_P3 = 0x04c5d30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R5_P3 = 0x04c5d70cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R6_P3 = 0x04c5db0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R7_P3 = 0x04c5df0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_TXDQDLYTG3_R8_P3 = 0x04c5e30cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG3_U0_P3 = 0x04c6034cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG3_U0_P3 = 0x04c6023cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG3_U0_P3 = 0x04c6024cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG3_U0_P3 = 0x04c6020cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQSDLYTG3_U1_P3 = 0x04c6074cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKDLYTG3_U1_P3 = 0x04c6063cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXCLKCDLYTG3_U1_P3 = 0x04c6064cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXENDLYTG3_U1_P3 = 0x04c6060cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R0_P3 = 0x04c6030cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R1_P3 = 0x04c6070cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R2_P3 = 0x04c60b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R3_P3 = 0x04c60f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R4_P3 = 0x04c6130cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R5_P3 = 0x04c6170cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R6_P3 = 0x04c61b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R7_P3 = 0x04c61f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_TXDQDLYTG3_R8_P3 = 0x04c6230cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG3_U0_P3 = 0x04c6434cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG3_U0_P3 = 0x04c6423cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG3_U0_P3 = 0x04c6424cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG3_U0_P3 = 0x04c6420cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQSDLYTG3_U1_P3 = 0x04c6474cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKDLYTG3_U1_P3 = 0x04c6463cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXCLKCDLYTG3_U1_P3 = 0x04c6464cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXENDLYTG3_U1_P3 = 0x04c6460cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R0_P3 = 0x04c6430cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R1_P3 = 0x04c6470cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R2_P3 = 0x04c64b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R3_P3 = 0x04c64f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R4_P3 = 0x04c6530cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R5_P3 = 0x04c6570cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R6_P3 = 0x04c65b0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R7_P3 = 0x04c65f0cull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_TXDQDLYTG3_R8_P3 = 0x04c6630cull;
+static const uint64_t EXP_DDR4_PHY_ANIB0_ATXDLY_P3 = 0x04c00200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB1_ATXDLY_P3 = 0x04c04200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB2_ATXDLY_P3 = 0x04c08200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB3_ATXDLY_P3 = 0x04c0c200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB4_ATXDLY_P3 = 0x04c10200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB5_ATXDLY_P3 = 0x04c14200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB6_ATXDLY_P3 = 0x04c18200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB7_ATXDLY_P3 = 0x04c1c200ull;
+static const uint64_t EXP_DDR4_PHY_ANIB8_ATXDLY_P3 = 0x04c20200ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG0_R0 = 0x040401a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG0_R1 = 0x040405a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG0_R2 = 0x040409a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG0_R3 = 0x04040da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG0_R4 = 0x040411a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG0_R5 = 0x040415a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG0_R6 = 0x040419a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG0_R7 = 0x04041da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG0_R8 = 0x040421a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG0_R0 = 0x040441a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG0_R1 = 0x040445a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG0_R2 = 0x040449a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG0_R3 = 0x04044da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG0_R4 = 0x040451a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG0_R5 = 0x040455a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG0_R6 = 0x040459a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG0_R7 = 0x04045da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG0_R8 = 0x040461a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG0_R0 = 0x040481a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG0_R1 = 0x040485a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG0_R2 = 0x040489a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG0_R3 = 0x04048da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG0_R4 = 0x040491a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG0_R5 = 0x040495a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG0_R6 = 0x040499a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG0_R7 = 0x04049da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG0_R8 = 0x0404a1a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG0_R0 = 0x0404c1a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG0_R1 = 0x0404c5a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG0_R2 = 0x0404c9a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG0_R3 = 0x0404cda0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG0_R4 = 0x0404d1a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG0_R5 = 0x0404d5a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG0_R6 = 0x0404d9a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG0_R7 = 0x0404dda0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG0_R8 = 0x0404e1a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG0_R0 = 0x040501a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG0_R1 = 0x040505a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG0_R2 = 0x040509a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG0_R3 = 0x04050da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG0_R4 = 0x040511a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG0_R5 = 0x040515a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG0_R6 = 0x040519a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG0_R7 = 0x04051da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG0_R8 = 0x040521a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG0_R0 = 0x040541a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG0_R1 = 0x040545a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG0_R2 = 0x040549a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG0_R3 = 0x04054da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG0_R4 = 0x040551a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG0_R5 = 0x040555a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG0_R6 = 0x040559a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG0_R7 = 0x04055da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG0_R8 = 0x040561a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG0_R0 = 0x040581a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG0_R1 = 0x040585a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG0_R2 = 0x040589a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG0_R3 = 0x04058da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG0_R4 = 0x040591a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG0_R5 = 0x040595a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG0_R6 = 0x040599a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG0_R7 = 0x04059da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG0_R8 = 0x0405a1a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG0_R0 = 0x0405c1a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG0_R1 = 0x0405c5a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG0_R2 = 0x0405c9a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG0_R3 = 0x0405cda0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG0_R4 = 0x0405d1a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG0_R5 = 0x0405d5a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG0_R6 = 0x0405d9a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG0_R7 = 0x0405dda0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG0_R8 = 0x0405e1a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG0_R0 = 0x040601a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG0_R1 = 0x040605a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG0_R2 = 0x040609a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG0_R3 = 0x04060da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG0_R4 = 0x040611a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG0_R5 = 0x040615a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG0_R6 = 0x040619a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG0_R7 = 0x04061da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG0_R8 = 0x040621a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG0_R0 = 0x040641a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG0_R1 = 0x040645a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG0_R2 = 0x040649a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG0_R3 = 0x04064da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG0_R4 = 0x040651a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG0_R5 = 0x040655a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG0_R6 = 0x040659a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG0_R7 = 0x04065da0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG0_R8 = 0x040661a0ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG1_R0 = 0x040401a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG1_R1 = 0x040405a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG1_R2 = 0x040409a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG1_R3 = 0x04040da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG1_R4 = 0x040411a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG1_R5 = 0x040415a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG1_R6 = 0x040419a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG1_R7 = 0x04041da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG1_R8 = 0x040421a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG1_R0 = 0x040441a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG1_R1 = 0x040445a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG1_R2 = 0x040449a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG1_R3 = 0x04044da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG1_R4 = 0x040451a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG1_R5 = 0x040455a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG1_R6 = 0x040459a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG1_R7 = 0x04045da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG1_R8 = 0x040461a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG1_R0 = 0x040481a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG1_R1 = 0x040485a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG1_R2 = 0x040489a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG1_R3 = 0x04048da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG1_R4 = 0x040491a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG1_R5 = 0x040495a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG1_R6 = 0x040499a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG1_R7 = 0x04049da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG1_R8 = 0x0404a1a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG1_R0 = 0x0404c1a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG1_R1 = 0x0404c5a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG1_R2 = 0x0404c9a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG1_R3 = 0x0404cda4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG1_R4 = 0x0404d1a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG1_R5 = 0x0404d5a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG1_R6 = 0x0404d9a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG1_R7 = 0x0404dda4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG1_R8 = 0x0404e1a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG1_R0 = 0x040501a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG1_R1 = 0x040505a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG1_R2 = 0x040509a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG1_R3 = 0x04050da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG1_R4 = 0x040511a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG1_R5 = 0x040515a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG1_R6 = 0x040519a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG1_R7 = 0x04051da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG1_R8 = 0x040521a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG1_R0 = 0x040541a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG1_R1 = 0x040545a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG1_R2 = 0x040549a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG1_R3 = 0x04054da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG1_R4 = 0x040551a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG1_R5 = 0x040555a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG1_R6 = 0x040559a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG1_R7 = 0x04055da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG1_R8 = 0x040561a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG1_R0 = 0x040581a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG1_R1 = 0x040585a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG1_R2 = 0x040589a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG1_R3 = 0x04058da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG1_R4 = 0x040591a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG1_R5 = 0x040595a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG1_R6 = 0x040599a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG1_R7 = 0x04059da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG1_R8 = 0x0405a1a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG1_R0 = 0x0405c1a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG1_R1 = 0x0405c5a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG1_R2 = 0x0405c9a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG1_R3 = 0x0405cda4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG1_R4 = 0x0405d1a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG1_R5 = 0x0405d5a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG1_R6 = 0x0405d9a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG1_R7 = 0x0405dda4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG1_R8 = 0x0405e1a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG1_R0 = 0x040601a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG1_R1 = 0x040605a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG1_R2 = 0x040609a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG1_R3 = 0x04060da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG1_R4 = 0x040611a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG1_R5 = 0x040615a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG1_R6 = 0x040619a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG1_R7 = 0x04061da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG1_R8 = 0x040621a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG1_R0 = 0x040641a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG1_R1 = 0x040645a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG1_R2 = 0x040649a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG1_R3 = 0x04064da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG1_R4 = 0x040651a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG1_R5 = 0x040655a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG1_R6 = 0x040659a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG1_R7 = 0x04065da4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG1_R8 = 0x040661a4ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG2_R0 = 0x040401a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG2_R1 = 0x040405a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG2_R2 = 0x040409a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG2_R3 = 0x04040da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG2_R4 = 0x040411a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG2_R5 = 0x040415a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG2_R6 = 0x040419a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG2_R7 = 0x04041da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG2_R8 = 0x040421a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG2_R0 = 0x040441a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG2_R1 = 0x040445a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG2_R2 = 0x040449a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG2_R3 = 0x04044da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG2_R4 = 0x040451a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG2_R5 = 0x040455a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG2_R6 = 0x040459a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG2_R7 = 0x04045da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG2_R8 = 0x040461a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG2_R0 = 0x040481a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG2_R1 = 0x040485a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG2_R2 = 0x040489a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG2_R3 = 0x04048da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG2_R4 = 0x040491a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG2_R5 = 0x040495a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG2_R6 = 0x040499a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG2_R7 = 0x04049da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG2_R8 = 0x0404a1a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG2_R0 = 0x0404c1a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG2_R1 = 0x0404c5a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG2_R2 = 0x0404c9a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG2_R3 = 0x0404cda8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG2_R4 = 0x0404d1a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG2_R5 = 0x0404d5a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG2_R6 = 0x0404d9a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG2_R7 = 0x0404dda8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG2_R8 = 0x0404e1a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG2_R0 = 0x040501a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG2_R1 = 0x040505a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG2_R2 = 0x040509a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG2_R3 = 0x04050da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG2_R4 = 0x040511a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG2_R5 = 0x040515a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG2_R6 = 0x040519a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG2_R7 = 0x04051da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG2_R8 = 0x040521a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG2_R0 = 0x040541a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG2_R1 = 0x040545a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG2_R2 = 0x040549a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG2_R3 = 0x04054da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG2_R4 = 0x040551a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG2_R5 = 0x040555a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG2_R6 = 0x040559a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG2_R7 = 0x04055da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG2_R8 = 0x040561a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG2_R0 = 0x040581a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG2_R1 = 0x040585a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG2_R2 = 0x040589a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG2_R3 = 0x04058da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG2_R4 = 0x040591a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG2_R5 = 0x040595a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG2_R6 = 0x040599a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG2_R7 = 0x04059da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG2_R8 = 0x0405a1a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG2_R0 = 0x0405c1a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG2_R1 = 0x0405c5a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG2_R2 = 0x0405c9a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG2_R3 = 0x0405cda8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG2_R4 = 0x0405d1a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG2_R5 = 0x0405d5a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG2_R6 = 0x0405d9a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG2_R7 = 0x0405dda8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG2_R8 = 0x0405e1a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG2_R0 = 0x040601a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG2_R1 = 0x040605a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG2_R2 = 0x040609a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG2_R3 = 0x04060da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG2_R4 = 0x040611a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG2_R5 = 0x040615a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG2_R6 = 0x040619a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG2_R7 = 0x04061da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG2_R8 = 0x040621a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG2_R0 = 0x040641a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG2_R1 = 0x040645a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG2_R2 = 0x040649a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG2_R3 = 0x04064da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG2_R4 = 0x040651a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG2_R5 = 0x040655a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG2_R6 = 0x040659a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG2_R7 = 0x04065da8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG2_R8 = 0x040661a8ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG3_R0 = 0x040401acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG3_R1 = 0x040405acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG3_R2 = 0x040409acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG3_R3 = 0x04040dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG3_R4 = 0x040411acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG3_R5 = 0x040415acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG3_R6 = 0x040419acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG3_R7 = 0x04041dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_RXPBDLYTG3_R8 = 0x040421acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG3_R0 = 0x040441acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG3_R1 = 0x040445acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG3_R2 = 0x040449acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG3_R3 = 0x04044dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG3_R4 = 0x040451acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG3_R5 = 0x040455acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG3_R6 = 0x040459acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG3_R7 = 0x04045dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_RXPBDLYTG3_R8 = 0x040461acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG3_R0 = 0x040481acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG3_R1 = 0x040485acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG3_R2 = 0x040489acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG3_R3 = 0x04048dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG3_R4 = 0x040491acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG3_R5 = 0x040495acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG3_R6 = 0x040499acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG3_R7 = 0x04049dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_RXPBDLYTG3_R8 = 0x0404a1acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG3_R0 = 0x0404c1acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG3_R1 = 0x0404c5acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG3_R2 = 0x0404c9acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG3_R3 = 0x0404cdacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG3_R4 = 0x0404d1acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG3_R5 = 0x0404d5acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG3_R6 = 0x0404d9acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG3_R7 = 0x0404ddacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_RXPBDLYTG3_R8 = 0x0404e1acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG3_R0 = 0x040501acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG3_R1 = 0x040505acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG3_R2 = 0x040509acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG3_R3 = 0x04050dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG3_R4 = 0x040511acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG3_R5 = 0x040515acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG3_R6 = 0x040519acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG3_R7 = 0x04051dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_RXPBDLYTG3_R8 = 0x040521acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG3_R0 = 0x040541acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG3_R1 = 0x040545acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG3_R2 = 0x040549acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG3_R3 = 0x04054dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG3_R4 = 0x040551acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG3_R5 = 0x040555acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG3_R6 = 0x040559acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG3_R7 = 0x04055dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_RXPBDLYTG3_R8 = 0x040561acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG3_R0 = 0x040581acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG3_R1 = 0x040585acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG3_R2 = 0x040589acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG3_R3 = 0x04058dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG3_R4 = 0x040591acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG3_R5 = 0x040595acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG3_R6 = 0x040599acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG3_R7 = 0x04059dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_RXPBDLYTG3_R8 = 0x0405a1acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG3_R0 = 0x0405c1acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG3_R1 = 0x0405c5acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG3_R2 = 0x0405c9acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG3_R3 = 0x0405cdacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG3_R4 = 0x0405d1acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG3_R5 = 0x0405d5acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG3_R6 = 0x0405d9acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG3_R7 = 0x0405ddacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_RXPBDLYTG3_R8 = 0x0405e1acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG3_R0 = 0x040601acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG3_R1 = 0x040605acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG3_R2 = 0x040609acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG3_R3 = 0x04060dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG3_R4 = 0x040611acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG3_R5 = 0x040615acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG3_R6 = 0x040619acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG3_R7 = 0x04061dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_RXPBDLYTG3_R8 = 0x040621acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG3_R0 = 0x040641acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG3_R1 = 0x040645acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG3_R2 = 0x040649acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG3_R3 = 0x04064dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG3_R4 = 0x040651acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG3_R5 = 0x040655acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG3_R6 = 0x040659acull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG3_R7 = 0x04065dacull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_RXPBDLYTG3_R8 = 0x040661acull;
+static const uint64_t EXPLR_TP_MB_UNIT_TOP_TR1_TRACE_TRCTRL_CONFIG = 0x08010442ull;
+static const uint64_t EXP_APBONLY0_MICROCONTMUXSEL = 0x04340000ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_VREFDAC0_R0 = 0x4040100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_VREFDAC0_R1 = 0x4040500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_VREFDAC0_R2 = 0x4040900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_VREFDAC0_R3 = 0x4040D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_VREFDAC0_R4 = 0x4041100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_VREFDAC0_R5 = 0x4041500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_VREFDAC0_R6 = 0x4041900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_VREFDAC0_R7 = 0x4041D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE0_VREFDAC0_R8 = 0x4042100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_VREFDAC0_R0 = 0x4044100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_VREFDAC0_R1 = 0x4044500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_VREFDAC0_R2 = 0x4044900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_VREFDAC0_R3 = 0x4044D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_VREFDAC0_R4 = 0x4045100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_VREFDAC0_R5 = 0x4045500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_VREFDAC0_R6 = 0x4045900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_VREFDAC0_R7 = 0x4045D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE1_VREFDAC0_R8 = 0x4046100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_VREFDAC0_R0 = 0x4048100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_VREFDAC0_R1 = 0x4048500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_VREFDAC0_R2 = 0x4048900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_VREFDAC0_R3 = 0x4048D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_VREFDAC0_R4 = 0x4049100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_VREFDAC0_R5 = 0x4049500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_VREFDAC0_R6 = 0x4049900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_VREFDAC0_R7 = 0x4049D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE2_VREFDAC0_R8 = 0x404A100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_VREFDAC0_R0 = 0x404C100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_VREFDAC0_R1 = 0x404C500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_VREFDAC0_R2 = 0x404C900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_VREFDAC0_R3 = 0x404CD00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_VREFDAC0_R4 = 0x404D100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_VREFDAC0_R5 = 0x404D500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_VREFDAC0_R6 = 0x404D900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_VREFDAC0_R7 = 0x404DD00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE3_VREFDAC0_R8 = 0x404E100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_VREFDAC0_R0 = 0x4050100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_VREFDAC0_R1 = 0x4050500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_VREFDAC0_R2 = 0x4050900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_VREFDAC0_R3 = 0x4050D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_VREFDAC0_R4 = 0x4051100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_VREFDAC0_R5 = 0x4051500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_VREFDAC0_R6 = 0x4051900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_VREFDAC0_R7 = 0x4051D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE4_VREFDAC0_R8 = 0x4052100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_VREFDAC0_R0 = 0x4054100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_VREFDAC0_R1 = 0x4054500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_VREFDAC0_R2 = 0x4054900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_VREFDAC0_R3 = 0x4054D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_VREFDAC0_R4 = 0x4055100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_VREFDAC0_R5 = 0x4055500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_VREFDAC0_R6 = 0x4055900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_VREFDAC0_R7 = 0x4055D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE5_VREFDAC0_R8 = 0x4056100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_VREFDAC0_R0 = 0x4058100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_VREFDAC0_R1 = 0x4058500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_VREFDAC0_R2 = 0x4058900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_VREFDAC0_R3 = 0x4058D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_VREFDAC0_R4 = 0x4059100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_VREFDAC0_R5 = 0x4059500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_VREFDAC0_R6 = 0x4059900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_VREFDAC0_R7 = 0x4059D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE6_VREFDAC0_R8 = 0x405A100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_VREFDAC0_R0 = 0x405C100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_VREFDAC0_R1 = 0x405C500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_VREFDAC0_R2 = 0x405C900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_VREFDAC0_R3 = 0x405CD00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_VREFDAC0_R4 = 0x405D100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_VREFDAC0_R5 = 0x405D500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_VREFDAC0_R6 = 0x405D900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_VREFDAC0_R7 = 0x405DD00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE7_VREFDAC0_R8 = 0x405E100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_VREFDAC0_R0 = 0x4060100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_VREFDAC0_R1 = 0x4060500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_VREFDAC0_R2 = 0x4060900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_VREFDAC0_R3 = 0x4060D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_VREFDAC0_R4 = 0x4061100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_VREFDAC0_R5 = 0x4061500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_VREFDAC0_R6 = 0x4061900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_VREFDAC0_R7 = 0x4061D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE8_VREFDAC0_R8 = 0x4062100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_VREFDAC0_R0 = 0x4064100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_VREFDAC0_R1 = 0x4064500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_VREFDAC0_R2 = 0x4064900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_VREFDAC0_R3 = 0x4064D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_VREFDAC0_R4 = 0x4065100ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_VREFDAC0_R5 = 0x4065500ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_VREFDAC0_R6 = 0x4065900ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_VREFDAC0_R7 = 0x4065D00ull;
+static const uint64_t EXP_DDR4_PHY_DBYTE9_VREFDAC0_R8 = 0x4066100ull;
+static const uint64_t EXP_DDR4_PHY_DDR_PHY_CONTROL = 0x6000118ull;
+
+
+
+static const uint32_t EXPLR_EFUSE_IMAGE_OUT_0 = 0x20B080ull;
+
+
+static const uint32_t EXPLR_EFUSE_IMAGE_OUT_1 = 0x20B084ull;
+
+
+static const uint32_t EXPLR_EFUSE_IMAGE_OUT_2 = 0x20B088ull;
+
+
+static const uint32_t EXPLR_EFUSE_IMAGE_OUT_3 = 0x20B08Cull;
+
+
+static const uint32_t EXPLR_EFUSE_PE_DATA_0 = 0x20B090ull;
+
+
+static const uint32_t EXPLR_EFUSE_PE_DATA_1 = 0x20B094ull;
+
+
+static const uint32_t EXPLR_EFUSE_PE_DATA_2 = 0x20B098ull;
+
+
+static const uint32_t EXPLR_EFUSE_PE_DATA_3 = 0x20B09Cull;
+
+
+static const uint32_t EXPLR_EFUSE_PE_DATA_4 = 0x20B0A0ull;
+
+
+static const uint32_t EXPLR_EFUSE_PE_DATA_5 = 0x20B0A4ull;
+
+
+static const uint32_t EXPLR_EFUSE_PE_DATA_6 = 0x20B0A8ull;
+
+
+static const uint32_t EXPLR_EFUSE_PE_DATA_8 = 0x20B0ACull;
+
+
+static const uint32_t EXPLR_EFUSE_PE_DATA_9 = 0x20B0B0ull;
+
+
+static const uint32_t EXPLR_EFUSE_PE_DATA_10 = 0x20B0B4ull;
+
+
+static const uint32_t EXPLR_EFUSE_PE_DATA_11 = 0x20B0B8ull;
+
+
+static const uint32_t EXPLR_EFUSE_PE_DATA_12 = 0x20B0BCull;
+
+
+static const uint32_t EXPLR_EFUSE_PE_DATA_13 = 0x20B0C0ull;
+
+
+static const uint32_t EXPLR_EFUSE_PE_DATA_14 = 0x20B0C4ull;
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fld.H b/src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fld.H
index 5b93db5fb..ab747c2bb 100644
--- a/src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fld.H
+++ b/src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fld.H
@@ -27,6096 +27,6258 @@
#define __EXPLR_SCOM_ADDRESSES_FLD_H
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_SPARE = 0 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_SPARE_LEN = 4 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PM_CDR_TIMER = 4 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PM_CDR_TIMER_LEN = 4 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PM_DIDT_TIMER = 8 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PM_DIDT_TIMER_LEN = 4 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PSAVE_STS_ENABLE = 12 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_RECAL_TIMER = 13 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_RECAL_TIMER_LEN = 3 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_1US_TMR = 16 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_1US_TMR_LEN = 12 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_DBG_EN = 28 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_DBG_SEL = 29 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_DBG_SEL_LEN = 3 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_RD_RST = 32 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PRE_SCALAR = 33 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PRE_SCALAR_LEN = 3 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_FREEZE = 36 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PORT_SEL = 37 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PORT_SEL_LEN = 3 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR3_PS = 40 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR3_PS_LEN = 2 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR3_ES = 42 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR3_ES_LEN = 2 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR2_PS = 44 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR2_PS_LEN = 2 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR2_ES = 46 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR2_ES_LEN = 2 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR1_PS = 48 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR1_PS_LEN = 2 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR1_ES = 50 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR1_ES_LEN = 2 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR0_PS = 52 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR0_PS_LEN = 2 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR0_ES = 54 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR0_ES_LEN = 2 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR3_PE = 56 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR2_PE = 57 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR1_PE = 58 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR0_PE = 59 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR3_EN = 60 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR2_EN = 61 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR1_EN = 62 ;
-static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR0_EN = 63 ;
-
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_ENABLE = 0 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_CFG_SPARE = 1 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_CFG_SPARE_LEN = 5 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_CFG_TL_CREDITS = 6 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_CFG_TL_CREDITS_LEN = 6 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_TL_EVENT_ACTIONS = 12 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_TL_EVENT_ACTIONS_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_TL_ERROR_ACTIONS = 16 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_TL_ERROR_ACTIONS_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_FWD_PROGRESS_TIMER = 20 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_FWD_PROGRESS_TIMER_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_REPLAY_RSVD_ENTRIES = 24 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_REPLAY_RSVD_ENTRIES_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_DEBUG_SELECT = 28 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_DEBUG_SELECT_LEN = 3 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_DEBUG_ENABLE = 31 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_DL2TL_DATA_PARITY_INJECT = 32 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_DL2TL_CONTROL_PARITY_INJECT = 33 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_ECC_UE_INJECTION = 34 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_ECC_CE_INJECTION = 35 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_FP_DISABLE = 36 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_UNUSED2 = 37 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_TX_LN_REV_ENA = 38 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_128_130_ENCODING_ENABLED = 39 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_PHY_CNTR_LIMIT = 40 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_PHY_CNTR_LIMIT_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_RUNLANE_OVRD_ENABLE = 44 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_PWRMGT_ENABLE = 45 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_X1_BACKOFF_ENABLE = 46 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_X4_BACKOFF_ENABLE = 47 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_SUPPORTED_MODES = 48 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_SUPPORTED_MODES_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_TRAIN_MODE = 52 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_TRAIN_MODE_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_VERSION = 56 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_VERSION_LEN = 6 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_RETRAIN = 62 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_RESET = 63 ;
-
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_CFG1_SPARE = 0 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_CFG1_SPARE_LEN = 2 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_LANE_WIDTH = 2 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_LANE_WIDTH_LEN = 2 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_PREIPL_PRBS_ENA = 4 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_PREIPL_PRBS_TIME = 5 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_PREIPL_PRBS_TIME_LEN = 3 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_B_HYSTERESIS = 8 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_B_HYSTERESIS_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_A_HYSTERESIS = 12 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_A_HYSTERESIS_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_B_PATTERN_LENGTH = 16 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_B_PATTERN_LENGTH_LEN = 2 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_A_PATTERN_LENGTH = 18 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_A_PATTERN_LENGTH_LEN = 2 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_TX_PERF_DEGRADED = 20 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_TX_PERF_DEGRADED_LEN = 2 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RX_PERF_DEGRADED = 22 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RX_PERF_DEGRADED_LEN = 2 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_TX_LANES_DISABLE = 24 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_TX_LANES_DISABLE_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RX_LANES_DISABLE = 32 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RX_LANES_DISABLE_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_CFG1_SPARE1 = 40 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_CFG1_SPARE1_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RESET_ERR_HLD = 44 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RESET_ERR_CAP = 45 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RESET_TSHD_REG = 46 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RESET_RMT_MSG = 47 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_INJECT_CRC_DIRECTION = 48 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_INJECT_CRC_RATE = 49 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_INJECT_CRC_RATE_LEN = 3 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_INJECT_CRC_LANE = 52 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_INJECT_CRC_LANE_LEN = 3 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_INJECT_CRC_ERROR = 55 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_EDPL_TIME = 56 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_EDPL_TIME_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_EDPL_THRESHOLD = 60 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_EDPL_THRESHOLD_LEN = 3 ;
-static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_EDPL_ENA = 63 ;
-
-static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_BITS0 = 32 ;
-static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_BITS0_LEN = 32 ;
-
-static const uint8_t EXPLR_DLX_DL0_DEBUG_AID_RESERVED = 0 ;
-static const uint8_t EXPLR_DLX_DL0_DEBUG_AID_RESERVED_LEN = 55 ;
-static const uint8_t EXPLR_DLX_DL0_DEBUG_AID_PRBS7_RESET = 55 ;
-static const uint8_t EXPLR_DLX_DL0_DEBUG_AID_PRBS7_STATUS = 56 ;
-static const uint8_t EXPLR_DLX_DL0_DEBUG_AID_PRBS7_STATUS_LEN = 8 ;
-
-static const uint8_t EXPLR_DLX_DL0_DLX_CONFIG_CFG_DLX0 = 32 ;
-static const uint8_t EXPLR_DLX_DL0_DLX_CONFIG_CFG_DLX0_LEN = 32 ;
-
-static const uint8_t EXPLR_DLX_DL0_DLX_INFO_STS = 0 ;
-static const uint8_t EXPLR_DLX_DL0_DLX_INFO_STS_LEN = 64 ;
-
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L7 = 0 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L7_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L6 = 8 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L6_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L5 = 16 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L5_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L4 = 24 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L4_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L3 = 32 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L3_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L2 = 40 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L2_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L1 = 48 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L1_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L0 = 56 ;
-static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L0_LEN = 8 ;
-
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_11 = 16 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_11_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_10 = 20 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_10_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_9 = 24 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_9_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_8 = 28 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_8_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_7 = 32 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_7_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_6 = 36 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_6_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_5 = 40 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_5_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_4 = 44 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_4_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_3 = 48 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_3_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_2 = 52 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_2_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_1 = 56 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_1_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_0 = 60 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_0_LEN = 4 ;
-
-static const uint8_t EXPLR_DLX_DL0_ERROR_CAPTURE_INFO = 1 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_CAPTURE_INFO_LEN = 63 ;
-
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_47 = 16 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_46 = 17 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_45 = 18 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_44 = 19 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_43 = 20 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_42 = 21 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_41 = 22 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_40 = 23 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_39 = 24 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_38 = 25 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_37 = 26 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_36 = 27 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_35 = 28 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_34 = 29 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_33 = 30 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_32 = 31 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_31 = 32 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_30 = 33 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_29 = 34 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_28 = 35 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_27 = 36 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_26 = 37 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_25 = 38 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_24 = 39 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_23 = 40 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_22 = 41 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_21 = 42 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_20 = 43 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_19 = 44 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_18 = 45 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_17 = 46 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_16 = 47 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_15 = 48 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_14 = 49 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_13 = 50 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_12 = 51 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_11 = 52 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_10 = 53 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_09 = 54 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_08 = 55 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_07 = 56 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_06 = 57 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_05 = 58 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_04 = 59 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_03 = 60 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_02 = 61 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_01 = 62 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_00 = 63 ;
-
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_47 = 16 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_46 = 17 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_45 = 18 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_44 = 19 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_43 = 20 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_42 = 21 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_41 = 22 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_40 = 23 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_39 = 24 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_38 = 25 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_37 = 26 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_36 = 27 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_35 = 28 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_34 = 29 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_33 = 30 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_32 = 31 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_31 = 32 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_30 = 33 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_29 = 34 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_28 = 35 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_27 = 36 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_26 = 37 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_25 = 38 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_24 = 39 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_23 = 40 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_22 = 41 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_21 = 42 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_20 = 43 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_19 = 44 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_18 = 45 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_17 = 46 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_16 = 47 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_15 = 48 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_14 = 49 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_13 = 50 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_12 = 51 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_11 = 52 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_10 = 53 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_09 = 54 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_08 = 55 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_07 = 56 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_06 = 57 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_05 = 58 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_04 = 59 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_03 = 60 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_02 = 61 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_01 = 62 ;
-static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_00 = 63 ;
-
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_TRAINED_MODE = 0 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_TRAINED_MODE_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RX_LANE_REVERSED = 4 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_TX_LANE_REVERSED = 5 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RSVD0 = 6 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_ACK_PTRS_EQUAL = 7 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RSVD1 = 8 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RSVD1_LEN = 4 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_REQUESTED_LN_WIDTH = 12 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_REQUESTED_LN_WIDTH_LEN = 2 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_ACTUAL_LN_WIDTH = 14 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_ACTUAL_LN_WIDTH_LEN = 2 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_TX_TRAINED_LANES = 16 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_TX_TRAINED_LANES_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RX_TRAINED_LANES = 24 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RX_TRAINED_LANES_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_ENDPOINT_INFO = 32 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_ENDPOINT_INFO_LEN = 16 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RSVD2 = 48 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_TRAINING_STATE_MACHINE = 49 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_TRAINING_STATE_MACHINE_LEN = 3 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RSVD3 = 52 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RSVD3_LEN = 3 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_DESKEW_DONE = 55 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_LANES_DISABLED = 56 ;
-static const uint8_t EXPLR_DLX_DL0_STATUS_STS_LANES_DISABLED_LEN = 8 ;
-
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_PATTERN_A = 0 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_PATTERN_A_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_PATTERN_B = 8 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_PATTERN_B_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_SYNC_PATTERN = 16 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_SYNC_PATTERN_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_PHY_INIT_DONE = 24 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_PHY_INIT_DONE_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_BLOCK_LOCKED = 32 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_BLOCK_LOCKED_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_TS1 = 40 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_TS1_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_TS2 = 48 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_TS2_LEN = 8 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_TS3 = 56 ;
-static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_TS3_LEN = 8 ;
-
-static const uint8_t EXPLR_DLX_ERR_HOLD_LAT_FIR_MASK_PAR = 0 ;
-static const uint8_t EXPLR_DLX_ERR_HOLD_LAT_FIR_ACTION0_PAR = 1 ;
-static const uint8_t EXPLR_DLX_ERR_HOLD_LAT_FIR_ACTION1_PAR = 2 ;
-
-static const uint8_t EXPLR_DLX_ERR_MASK_LAT_FIR_PAR = 0 ;
-static const uint8_t EXPLR_DLX_ERR_MASK_LAT_FIR_ACTION0_PAR = 1 ;
-static const uint8_t EXPLR_DLX_ERR_MASK_LAT_FIR_ACTION1_PAR = 2 ;
-
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_ACTION0_REG_ACTION0 = 0 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_ACTION0_REG_ACTION0_LEN = 64 ;
-
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_ACTION1_REG_ACTION1 = 0 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_ACTION1_REG_ACTION1_LEN = 64 ;
-
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_DL0_ERROR = 0 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_DL0_ERROR_LEN = 20 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_DL1_ERROR = 20 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_DL1_ERROR_LEN = 20 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_DL2_ERROR = 40 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_DL2_ERROR_LEN = 20 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_PERF_MON_WRAPPED = 60 ;
-
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_FATAL_ERROR = 0 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_DATA_UE = 1 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_FLIT_CE = 2 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_CRC_ERROR = 3 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_NACK = 4 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_X4_MODE = 5 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_EDPL = 6 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_TIMEOUT = 7 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_REMOTE_RETRAIN = 8 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ERROR_RETRAIN = 9 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_EDPL_RETRAIN = 10 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_TRAINED = 11 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR0 = 12 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR1 = 13 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR2 = 14 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR3 = 15 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR4 = 16 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR5 = 17 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR6 = 18 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR7 = 19 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_FATAL_ERROR = 20 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_DATA_UE = 21 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_FLIT_CE = 22 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_CRC_ERROR = 23 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_NACK = 24 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_X4_MODE = 25 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_EDPL = 26 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_TIMEOUT = 27 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_REMOTE_RETRAIN = 28 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ERROR_RETRAIN = 29 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_EDPL_RETRAIN = 30 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_TRAINED = 31 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR0 = 32 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR1 = 33 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR2 = 34 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR3 = 35 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR4 = 36 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR5 = 37 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR6 = 38 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR7 = 39 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_FATAL_ERROR = 40 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_DATA_UE = 41 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_FLIT_CE = 42 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_CRC_ERROR = 43 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_NACK = 44 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_X4_MODE = 45 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_EDPL = 46 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_TIMEOUT = 47 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_REMOTE_RETRAIN = 48 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ERROR_RETRAIN = 49 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_EDPL_RETRAIN = 50 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_TRAINED = 51 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR0 = 52 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR1 = 53 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR2 = 54 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR3 = 55 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR4 = 56 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR5 = 57 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR6 = 58 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR7 = 59 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_PERF_MON_WRAPPED = 60 ;
-
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_WOF_REG_WOF = 0 ;
-static const uint8_t EXPLR_DLX_MC_OMI_FIR_WOF_REG_WOF_LEN = 64 ;
-
-static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU3 = 0 ;
-static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU3_LEN = 16 ;
-static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU2 = 16 ;
-static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU2_LEN = 16 ;
-static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU1 = 32 ;
-static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU1_LEN = 16 ;
-static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU0 = 48 ;
-static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU0_LEN = 16 ;
-
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_ARRAY_CE_ERR_INJ_MODE = 0 ;
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_ARRAY_CE_ERR_INJ = 1 ;
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_ARRAY_UE_ERR_INJ_MODE = 2 ;
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_ARRAY_UE_ERR_INJ = 3 ;
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_RESERVED_4 = 4 ;
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_DISABLE_2N_MODE = 5 ;
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_RESERVED_6_14 = 6 ;
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_RESERVED_6_14_LEN = 9 ;
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_READ_RESPONSE_DELAY_ENABLE = 15 ;
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_LOOP_COUNTER_COMPARE0 = 16 ;
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_LOOP_COUNTER_COMPARE0_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_LOOP_COUNTER_COMPARE1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_LOOP_COUNTER_COMPARE1_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_LOOP_COUNTER_COMPARE2 = 48 ;
-static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_LOOP_COUNTER_COMPARE2_LEN = 16 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_CNTLQ_START = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_CNTLQ_STOP = 1 ;
-static const uint8_t EXPLR_MCBIST_CCS_CNTLQ_UNPAUSE = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_FIXED_DATA0Q_DATA_0_63 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_FIXED_DATA0Q_DATA_0_63_LEN = 64 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_FIXED_DATA1Q_DATA_64_79 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_FIXED_DATA1Q_DATA_64_79_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_FIXED_DATA1Q_NTTM_READ_DELAY = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_FIXED_DATA1Q_NTTM_READ_DELAY_LEN = 16 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ADDRESS_0 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ADDRESS_0_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ADDRESS = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ADDRESS = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ADDRESS = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ADDRESS = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_RESERVED_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_RESERVED_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_RESERVED_28_31 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_RESERVED_28_31_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ADDRESS_0_13 = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ADDRESS_17 = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_BANK_GROUP_1 = 15 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_RESETN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_BANK_0_1 = 17 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_BANK_GROUP_0 = 19 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ACTN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ADDRESS_16 = 21 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ADDRESS_15 = 22 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ADDRESS_14 = 23 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CKE = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CKE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_RESERVED_28 = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_RESERVED_28_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CSN_0_1 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CSN_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CID_0_1 = 34 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CID_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CSN_2_3 = 36 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CSN_2_3_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CID_2 = 38 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_RESERVED_39 = 39 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_NESTED_LOOP_CNT = 40 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_NESTED_LOOP_CNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ODT = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_RESERVED_52_54 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_RESERVED_52_54_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_PAUSE_INSTR = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CAL_TYPE = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CAL_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_PARITY = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_BANK_2 = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_LOOP_BREAK_MODE = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_LOOP_BREAK_MODE_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_IDLES = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_IDLES_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_REPEAT_CMD_CNT = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_REPEAT_CMD_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_READ_OR_WRITE_DATA = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_READ_OR_WRITE_DATA_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_READ_COMPARE_REQUIRED = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_DDR_CAL_RANK = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_DDR_CAL_RANK_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_DDR_CALIBRATION_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_END = 58 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_GOTO_CMD = 59 ;
-static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_GOTO_CMD_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_STOP_ON_ERR = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_UE_DISABLE = 1 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_DATA_COMPARE_BURST_SEL = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_DATA_COMPARE_BURST_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_RESERVED_4_6 = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_RESERVED_4_6_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_TRACE_SELECT_DQBYPASS = 7 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_DDR_CAL_TIMEOUT_CNT = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_DDR_CAL_TIMEOUT_CNT_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_CFG_PARITY_AFTER_CMD = 24 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_NESTED_LOOP_ENABLE = 25 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_COPY_CKE_TO_SPARE_CKE = 26 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_DISABLE_ECC_ARRAY_CHK = 27 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_DISABLE_ECC_ARRAY_CORRECTION = 28 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_CFG_DGEN_FIXED_MODE = 29 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_DDR_CAL_TIMEOUT_CNT_MULT = 30 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_DDR_CAL_TIMEOUT_CNT_MULT_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_0_13 = 32 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_0_13_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_17 = 46 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_GROUP_1 = 47 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_0_1 = 48 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_0_1_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_GROUP_0 = 50 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ACTN = 51 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_16 = 52 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_15 = 53 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_14 = 54 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_NTTM_MODE = 55 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_NTTM_RW_DATA_DLY = 56 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_NTTM_RW_DATA_DLY_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_2 = 60 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_DDR_PARITY_ENABLE = 61 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_PARITY = 62 ;
-static const uint8_t EXPLR_MCBIST_CCS_MODEQ_PAUSE_DISABLE = 63 ;
-
-static const uint8_t EXPLR_MCBIST_CCS_STATQ_IP = 0 ;
-static const uint8_t EXPLR_MCBIST_CCS_STATQ_DONE = 1 ;
-static const uint8_t EXPLR_MCBIST_CCS_STATQ_FAIL = 2 ;
-static const uint8_t EXPLR_MCBIST_CCS_STATQ_FAIL_TYPE = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_STATQ_FAIL_TYPE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_CCS_STATQ_MCBIST_SUBTEST_IP = 6 ;
-static const uint8_t EXPLR_MCBIST_CCS_STATQ_FAIL_RCD = 7 ;
-static const uint8_t EXPLR_MCBIST_CCS_STATQ_PAUSED = 8 ;
-static const uint8_t EXPLR_MCBIST_CCS_STATQ_CE = 9 ;
-
-static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_ENABLE = 0 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_ASYNC_PORT01 = 1 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_ASYNC_PORT01_LEN = 11 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_ASYNC_PORT23 = 12 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_ASYNC_PORT23_LEN = 11 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_MCBIST01 = 23 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_MCBIST01_LEN = 11 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_MCBIST23 = 34 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_MCBIST23_LEN = 11 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG0Q_SCOM_SET_WAT_EXT_TRIGGER = 45 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG0Q_SCOM_SET_WAT_EXT_RESET = 46 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG0Q_SCOM_SET_WAT_EXT_ARM = 47 ;
-
-static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_ENABLE = 0 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_EVENT_TO_INT = 1 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_EVENT_TO_INT_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_TRIGGER_SEL = 3 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_TRIGGER_SEL_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_RESET_SEL = 23 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_RESET_SEL_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_ARM_SEL = 43 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_ARM_SEL_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG1Q_RESERVED_63 = 63 ;
-
-static const uint8_t EXPLR_MCBIST_DBGCFG2Q_CFG_WAT_LOC_EVENT0_SEL = 0 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG2Q_CFG_WAT_LOC_EVENT0_SEL_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG2Q_CFG_WAT_LOC_EVENT1_SEL = 20 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG2Q_CFG_WAT_LOC_EVENT1_SEL_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG2Q_CFG_WAT_LOC_EVENT2_SEL = 40 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG2Q_CFG_WAT_LOC_EVENT2_SEL_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG2Q_RESERVED_60_63 = 60 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG2Q_RESERVED_60_63_LEN = 4 ;
-
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_LOC_EVENT3_SEL = 0 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_LOC_EVENT3_SEL_LEN = 20 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT0_SEL = 20 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT0_SEL_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT1_SEL = 23 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT1_SEL_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT2_SEL = 26 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT2_SEL_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT3_SEL = 29 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT3_SEL_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_OUTPUT_PULSE = 32 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_ACT_MNT_GO_IDLE_PULSE = 33 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_ACT_MNT_GO_IDLE_PULSE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_ACT_SET_SPATTN_PULSE = 37 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_ACT_SET_SPATTN_PULSE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_ACT_FRC_TB_PULSE_PULSE = 41 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_ACT_FRC_TB_PULSE_PULSE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_CNT_VALUE = 45 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_CNT_VALUE_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_TMR_VALUE = 51 ;
-static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_TMR_VALUE_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_A = 0 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_A_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_B = 4 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_B_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_C = 8 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_C_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_D = 12 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_D_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_A = 16 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_A_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_B = 20 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_B_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_C = 24 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_C_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_D = 28 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_D_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TLXR_SHIFT_SEL = 32 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TLXT_SHIFT_SEL = 33 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_WDF_SHIFT_SEL = 34 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_RDF_SHIFT_SEL = 35 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_SRQ_SHIFT_SEL = 36 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_MCB_SHIFT_SEL = 37 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_MMIO_SHIFT_SEL = 38 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DLX_SHIFT_SEL = 39 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE0_TRACE_ERR_SEL = 40 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE0_TRACE_ERR_SEL_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE1_TRACE_ERR_SEL = 44 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE1_TRACE_ERR_SEL_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_SLICE_SEL_A = 48 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_SLICE_SEL_A_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_SLICE_SEL_B = 52 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_SLICE_SEL_B_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_RESERVED_56 = 56 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_GROUP_SEL0 = 57 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_GROUP_SEL0_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_RESERVED_60 = 60 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_GROUP_SEL1 = 61 ;
-static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_GROUP_SEL1_LEN = 3 ;
-
-static const uint8_t EXPLR_MCBIST_ERR_HOLD_LAT_FIR_MASK_PAR = 0 ;
-static const uint8_t EXPLR_MCBIST_ERR_HOLD_LAT_FIR_ACTION0_PAR = 1 ;
-static const uint8_t EXPLR_MCBIST_ERR_HOLD_LAT_FIR_ACTION1_PAR = 2 ;
-
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBECTLQ_PE = 0 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_CCS_STATQ_PE = 1 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_CCS_MODEQ_PE = 2 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_RCD_LRDIM_CNTL_WORD0_15Q_PE = 3 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_CCSARRERRINJQ_PE = 4 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_CCS_FIXED_DATA0Q_PE = 5 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_CCS_FIXED_DATA1Q_PE = 6 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBAMR0A0Q_PE = 7 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBAMR1A0Q_PE = 8 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBAMR2A0Q_PE = 9 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBAMR3A0Q_PE = 10 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBSA0Q_PE = 11 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBSA1Q_PE = 12 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBEA0Q_PE = 13 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBEA1Q_PE = 14 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBSA2Q_PE = 15 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBSA3Q_PE = 16 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBEA2Q_PE = 17 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBEA3Q_PE = 18 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBLFSRA0Q_PE = 19 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBACQ_PE = 20 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBAGRAQ_PE = 21 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBRDS0Q_PE = 22 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBRDS1Q_PE = 23 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBDRSRQ_PE = 24 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBDRCRQ_PE = 25 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD0Q_PE = 26 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD1Q_PE = 27 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD2Q_PE = 28 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD3Q_PE = 29 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD4Q_PE = 30 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD5Q_PE = 31 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD6Q_PE = 32 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD7Q_PE = 33 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFDSPQ_PE = 34 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFDQ_PE = 35 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBPARMQ_PE = 36 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_RUNTIMECTRQ_PE = 37 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBRCRQ_PE = 38 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCB_CNTLSTATQ_PE = 39 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBCFGQ_PE = 40 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBMCATQ_PE = 41 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSEC0Q_PE = 42 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSEC1Q_PE = 43 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSTRQ_PE = 44 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC0Q_PE = 45 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC1Q_PE = 46 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC2Q_PE = 47 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC3Q_PE = 48 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC4Q_PE = 49 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC5Q_PE = 50 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC6Q_PE = 51 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC7Q_PE = 52 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC8Q_PE = 53 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSMODESQ_PE = 54 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBSTATQ_PE = 55 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSMSECQ_PE = 56 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBNCER0Q_PE = 57 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBRCER0Q_PE = 58 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBMPER0Q_PE = 59 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBUER0Q_PE = 60 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBAUER0Q_PE = 61 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_DBG_BUS_CFGQ_PE = 62 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MASK1Q_PE = 63 ;
-
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MASK0Q_PE = 0 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MBSEVR0Q_PE = 1 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_DBGCFG0Q_PE = 2 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_DBGCFG1Q_PE = 3 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_DBGCFG2Q_PE = 4 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_DBGCFG3Q_PE = 5 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG0AQ_PE = 6 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG0BQ_PE = 7 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG0CQ_PE = 8 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG0DQ_PE = 9 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG0EQ_PE = 10 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG1AQ_PE = 11 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG1BQ_PE = 12 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG1CQ_PE = 13 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG1DQ_PE = 14 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG1EQ_PE = 15 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG2AQ_PE = 16 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG2BQ_PE = 17 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG2CQ_PE = 18 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG2DQ_PE = 19 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG2EQ_PE = 20 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG3AQ_PE = 21 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG3BQ_PE = 22 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG3CQ_PE = 23 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG3DQ_PE = 24 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG3EQ_PE = 25 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR0Q_PE = 26 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR1Q_PE = 27 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR2Q_PE = 28 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR3Q_PE = 29 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR4Q_PE = 30 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR5Q_PE = 31 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR6Q_PE = 32 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR7Q_PE = 33 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MBXLT0Q_PE = 34 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MBXLT1Q_PE = 35 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MBXLT2Q_PE = 36 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_CCS_CNTLQ_PE = 37 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCB_CNTLQ_PE = 38 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCB_FIR_CCS = 39 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCB_FIR_MCBFSM = 40 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_CCS_ARRAY_UNCORRECTED_CE = 41 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_CCS_ARRAY_UE = 42 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_CCS_ARRAY_SCOM_ECC = 43 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_RESERVED_44_63 = 44 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_RESERVED_44_63_LEN = 20 ;
-
-static const uint8_t EXPLR_MCBIST_ERR_MASK_LAT_FIR_PAR = 0 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK_LAT_FIR_ACTION0_PAR = 1 ;
-static const uint8_t EXPLR_MCBIST_ERR_MASK_LAT_FIR_ACTION1_PAR = 2 ;
-
-static const uint8_t EXPLR_MCBIST_MBAUER0Q_PORT_0_MAINLINE_AUE_ADDR_TRAP = 0 ;
-static const uint8_t EXPLR_MCBIST_MBAUER0Q_PORT_0_MAINLINE_AUE_ADDR_TRAP_LEN = 38 ;
-static const uint8_t EXPLR_MCBIST_MBAUER0Q_RESERVED_38_39 = 38 ;
-static const uint8_t EXPLR_MCBIST_MBAUER0Q_RESERVED_38_39_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBECTLQ_PE = 0 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_CCS_STATQ_PE = 1 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_CCS_MODEQ_PE = 2 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_RCD_LRDIM_CNTL_WORD0_15Q_PE = 3 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_CCSARRERRINJQ_PE = 4 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_CCS_FIXED_DATA0Q_PE = 5 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_CCS_FIXED_DATA1Q_PE = 6 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBAMR0A0Q_PE = 7 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBAMR1A0Q_PE = 8 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBAMR2A0Q_PE = 9 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBAMR3A0Q_PE = 10 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBSA0Q_PE = 11 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBSA1Q_PE = 12 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBEA0Q_PE = 13 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBEA1Q_PE = 14 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBSA2Q_PE = 15 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBSA3Q_PE = 16 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBEA2Q_PE = 17 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBEA3Q_PE = 18 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBLFSRA0Q_PE = 19 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBACQ_PE = 20 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBAGRAQ_PE = 21 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBRDS0Q_PE = 22 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBRDS1Q_PE = 23 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBDRSRQ_PE = 24 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBDRCRQ_PE = 25 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD0Q_PE = 26 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD1Q_PE = 27 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD2Q_PE = 28 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD3Q_PE = 29 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD4Q_PE = 30 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD5Q_PE = 31 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD6Q_PE = 32 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD7Q_PE = 33 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFDSPQ_PE = 34 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFDQ_PE = 35 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBPARMQ_PE = 36 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_RUNTIMECTRQ_PE = 37 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBRCRQ_PE = 38 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCB_CNTLSTATQ_PE = 39 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBCFGQ_PE = 40 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBMCATQ_PE = 41 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSEC0Q_PE = 42 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSEC1Q_PE = 43 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSTRQ_PE = 44 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC0Q_PE = 45 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC1Q_PE = 46 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC2Q_PE = 47 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC3Q_PE = 48 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC4Q_PE = 49 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC5Q_PE = 50 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC6Q_PE = 51 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC7Q_PE = 52 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC8Q_PE = 53 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSMODESQ_PE = 54 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBSTATQ_PE = 55 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSMSECQ_PE = 56 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBNCER0Q_PE = 57 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBRCER0Q_PE = 58 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBMPER0Q_PE = 59 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBUER0Q_PE = 60 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBAUER0Q_PE = 61 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_DBG_BUS_CFGQ_PE = 62 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_ERR_MASK1Q_PE = 63 ;
-
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_ERR_MASK0Q_PE = 0 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MBSEVR0Q_PE = 1 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_DBGCFG0Q_PE = 2 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_DBGCFG1Q_PE = 3 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_DBGCFG2Q_PE = 4 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_DBGCFG3Q_PE = 5 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG0AQ_PE = 6 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG0BQ_PE = 7 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG0CQ_PE = 8 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG0DQ_PE = 9 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG0EQ_PE = 10 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG1AQ_PE = 11 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG1BQ_PE = 12 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG1CQ_PE = 13 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG1DQ_PE = 14 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG1EQ_PE = 15 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG2AQ_PE = 16 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG2BQ_PE = 17 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG2CQ_PE = 18 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG2DQ_PE = 19 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG2EQ_PE = 20 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG3AQ_PE = 21 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG3BQ_PE = 22 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG3CQ_PE = 23 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG3DQ_PE = 24 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG3EQ_PE = 25 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR0Q_PE = 26 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR1Q_PE = 27 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR2Q_PE = 28 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR3Q_PE = 29 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR4Q_PE = 30 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR5Q_PE = 31 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR6Q_PE = 32 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR7Q_PE = 33 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MBXLT0Q_PE = 34 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MBXLT1Q_PE = 35 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MBXLT2Q_PE = 36 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_CCS_CNTLQ_PE = 37 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCB_CNTLQ_PE = 38 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCB_FIR_CCS_ERR = 39 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCB_FIR_MCBFSM_ERR = 40 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_CCS_ARRAY_UNCORRECTED_CE_ERR = 41 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_CCS_ARRAY_UE_ERR = 42 ;
-static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_CCS_ARRAY_SCOM_ECC_ERR = 43 ;
-
-static const uint8_t EXPLR_MCBIST_MBECTLQ_ATOMIC_ALT_CE_INJ = 0 ;
-static const uint8_t EXPLR_MCBIST_MBECTLQ_ATOMIC_ALT_CHIP_KILL_INJ = 1 ;
-static const uint8_t EXPLR_MCBIST_MBECTLQ_ATOMIC_ALT_UE_INJ = 2 ;
-static const uint8_t EXPLR_MCBIST_MBECTLQ_ATOMIC_ALT_SUE_INJ = 3 ;
-static const uint8_t EXPLR_MCBIST_MBECTLQ_ATOMIC_ALT_INJ_SYM_SEL = 4 ;
-static const uint8_t EXPLR_MCBIST_MBECTLQ_ATOMIC_ALT_INJ_SYM_SEL_LEN = 7 ;
-static const uint8_t EXPLR_MCBIST_MBECTLQ_RESERVE_11 = 11 ;
-static const uint8_t EXPLR_MCBIST_MBECTLQ_SCOM_CMD_REG_INJ_MODE = 12 ;
-static const uint8_t EXPLR_MCBIST_MBECTLQ_SCOM_CMD_REG_INJ = 13 ;
-static const uint8_t EXPLR_MCBIST_MBECTLQ_MCBIST_FSM_INJ_MODE = 14 ;
-static const uint8_t EXPLR_MCBIST_MBECTLQ_MCBIST_FSM_INJ_REG = 15 ;
-static const uint8_t EXPLR_MCBIST_MBECTLQ_CCS_FSM_INJ_MODE = 16 ;
-static const uint8_t EXPLR_MCBIST_MBECTLQ_CCS_FSM_INJ_REG = 17 ;
-static const uint8_t EXPLR_MCBIST_MBECTLQ_RESERVED_18_31 = 18 ;
-static const uint8_t EXPLR_MCBIST_MBECTLQ_RESERVED_18_31_LEN = 14 ;
-
-static const uint8_t EXPLR_MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ADDR_TRAP = 0 ;
-static const uint8_t EXPLR_MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ADDR_TRAP_LEN = 38 ;
-static const uint8_t EXPLR_MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ON_RCE = 38 ;
-static const uint8_t EXPLR_MCBIST_MBMPER0Q_RESERVED_39 = 39 ;
-
-static const uint8_t EXPLR_MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ADDR_TRAP = 0 ;
-static const uint8_t EXPLR_MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ADDR_TRAP_LEN = 38 ;
-static const uint8_t EXPLR_MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ON_RCE = 38 ;
-static const uint8_t EXPLR_MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_IS_TCE = 39 ;
-
-static const uint8_t EXPLR_MCBIST_MBRCER0Q_PORT_0_MAINLINE_RCE_ADDR_TRAP = 0 ;
-static const uint8_t EXPLR_MCBIST_MBRCER0Q_PORT_0_MAINLINE_RCE_ADDR_TRAP_LEN = 38 ;
-static const uint8_t EXPLR_MCBIST_MBRCER0Q_RESERVED_38_39 = 38 ;
-static const uint8_t EXPLR_MCBIST_MBRCER0Q_RESERVED_38_39_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_MBSEC0Q_INTERMITTENT_CE_COUNT = 0 ;
-static const uint8_t EXPLR_MCBIST_MBSEC0Q_INTERMITTENT_CE_COUNT_LEN = 12 ;
-static const uint8_t EXPLR_MCBIST_MBSEC0Q_SOFT_CE_COUNT = 12 ;
-static const uint8_t EXPLR_MCBIST_MBSEC0Q_SOFT_CE_COUNT_LEN = 12 ;
-static const uint8_t EXPLR_MCBIST_MBSEC0Q_HARD_CE_COUNT = 24 ;
-static const uint8_t EXPLR_MCBIST_MBSEC0Q_HARD_CE_COUNT_LEN = 12 ;
-static const uint8_t EXPLR_MCBIST_MBSEC0Q_INTERMITTENT_MCE_COUNT = 36 ;
-static const uint8_t EXPLR_MCBIST_MBSEC0Q_INTERMITTENT_MCE_COUNT_LEN = 12 ;
-static const uint8_t EXPLR_MCBIST_MBSEC0Q_SOFT_MCE_COUNT = 48 ;
-static const uint8_t EXPLR_MCBIST_MBSEC0Q_SOFT_MCE_COUNT_LEN = 12 ;
-
-static const uint8_t EXPLR_MCBIST_MBSEC1Q_HARD_MCE_COUNT = 0 ;
-static const uint8_t EXPLR_MCBIST_MBSEC1Q_HARD_MCE_COUNT_LEN = 12 ;
-static const uint8_t EXPLR_MCBIST_MBSEC1Q_ICE_COUNT = 12 ;
-static const uint8_t EXPLR_MCBIST_MBSEC1Q_ICE_COUNT_LEN = 12 ;
-static const uint8_t EXPLR_MCBIST_MBSEC1Q_UE_COUNT = 24 ;
-static const uint8_t EXPLR_MCBIST_MBSEC1Q_UE_COUNT_LEN = 12 ;
-static const uint8_t EXPLR_MCBIST_MBSEC1Q_AUE = 36 ;
-static const uint8_t EXPLR_MCBIST_MBSEC1Q_AUE_LEN = 12 ;
-static const uint8_t EXPLR_MCBIST_MBSEC1Q_RCE_COUNT = 48 ;
-static const uint8_t EXPLR_MCBIST_MBSEC1Q_RCE_COUNT_LEN = 12 ;
-
-static const uint8_t EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_GALOIS_FIELD = 0 ;
+
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_SPARE = 0 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_SPARE_LEN = 4 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PM_CDR_TIMER = 4 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PM_CDR_TIMER_LEN = 4 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PM_DIDT_TIMER = 8 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PM_DIDT_TIMER_LEN = 4 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PSAVE_STS_ENABLE = 12 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_RECAL_TIMER = 13 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_RECAL_TIMER_LEN = 3 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_1US_TMR = 16 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_1US_TMR_LEN = 12 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_DBG_EN = 28 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_DBG_SEL = 29 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_DBG_SEL_LEN = 3 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_RD_RST = 32 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PRE_SCALAR = 33 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PRE_SCALAR_LEN = 3 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_FREEZE = 36 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PORT_SEL = 37 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_PORT_SEL_LEN = 3 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR3_PS = 40 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR3_PS_LEN = 2 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR3_ES = 42 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR3_ES_LEN = 2 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR2_PS = 44 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR2_PS_LEN = 2 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR2_ES = 46 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR2_ES_LEN = 2 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR1_PS = 48 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR1_PS_LEN = 2 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR1_ES = 50 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR1_ES_LEN = 2 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR0_PS = 52 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR0_PS_LEN = 2 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR0_ES = 54 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR0_ES_LEN = 2 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR3_PE = 56 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR2_PE = 57 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR1_PE = 58 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR0_PE = 59 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR3_EN = 60 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR2_EN = 61 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR1_EN = 62 ;
+static const uint8_t EXPLR_DLX_CMN_CONFIG_CFG_CNTR0_EN = 63 ;
+
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_ENABLE = 0 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_CFG_SPARE = 1 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_CFG_SPARE_LEN = 5 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_CFG_TL_CREDITS = 6 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_CFG_TL_CREDITS_LEN = 6 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_TL_EVENT_ACTIONS = 12 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_TL_EVENT_ACTIONS_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_TL_ERROR_ACTIONS = 16 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_TL_ERROR_ACTIONS_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_FWD_PROGRESS_TIMER = 20 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_FWD_PROGRESS_TIMER_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_REPLAY_RSVD_ENTRIES = 24 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_REPLAY_RSVD_ENTRIES_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_DEBUG_SELECT = 28 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_DEBUG_SELECT_LEN = 3 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_DEBUG_ENABLE = 31 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_DL2TL_DATA_PARITY_INJECT = 32 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_DL2TL_CONTROL_PARITY_INJECT = 33 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_ECC_UE_INJECTION = 34 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_ECC_CE_INJECTION = 35 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_FP_DISABLE = 36 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_UNUSED2 = 37 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_TX_LN_REV_ENA = 38 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_128_130_ENCODING_ENABLED = 39 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_PHY_CNTR_LIMIT = 40 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_PHY_CNTR_LIMIT_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_RUNLANE_OVRD_ENABLE = 44 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_PWRMGT_ENABLE = 45 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_QUARTER_WIDTH_BACKOFF_ENABLE = 46 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_HALF_WIDTH_BACKOFF_ENABLE = 47 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_SUPPORTED_MODES = 48 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_SUPPORTED_MODES_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_TRAIN_MODE = 52 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_TRAIN_MODE_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_VERSION = 56 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_VERSION_LEN = 6 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_RETRAIN = 62 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG0_CFG_RESET = 63 ;
+
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_CFG1_SPARE = 0 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_CFG1_SPARE_LEN = 2 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_LANE_WIDTH = 2 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_LANE_WIDTH_LEN = 2 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_PREIPL_PRBS_ENA = 4 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_PREIPL_PRBS_TIME = 5 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_PREIPL_PRBS_TIME_LEN = 3 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_B_HYSTERESIS = 8 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_B_HYSTERESIS_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_A_HYSTERESIS = 12 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_A_HYSTERESIS_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_B_PATTERN_LENGTH = 16 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_B_PATTERN_LENGTH_LEN = 2 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_A_PATTERN_LENGTH = 18 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_A_PATTERN_LENGTH_LEN = 2 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_TX_PERF_DEGRADED = 20 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_TX_PERF_DEGRADED_LEN = 2 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RX_PERF_DEGRADED = 22 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RX_PERF_DEGRADED_LEN = 2 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_TX_LANES_DISABLE = 24 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_TX_LANES_DISABLE_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RX_LANES_DISABLE = 32 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RX_LANES_DISABLE_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_MACRO_DBG_SEL = 40 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_MACRO_DBG_SEL_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RESET_ERR_HLD = 44 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RESET_ERR_CAP = 45 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RESET_TSHD_REG = 46 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_RESET_RMT_MSG = 47 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_INJECT_CRC_DIRECTION = 48 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_INJECT_CRC_RATE = 49 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_INJECT_CRC_RATE_LEN = 3 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_INJECT_CRC_LANE = 52 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_INJECT_CRC_LANE_LEN = 3 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_INJECT_CRC_ERROR = 55 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_EDPL_TIME = 56 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_EDPL_TIME_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_EDPL_THRESHOLD = 60 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_EDPL_THRESHOLD_LEN = 3 ;
+static const uint8_t EXPLR_DLX_DL0_CONFIG1_CFG_EDPL_ENA = 63 ;
+
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_BITS0 = 32 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_BITS0_LEN = 17 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_KILL_CRC_REPLAY0 = 49 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_RETRAIN_CRC_REPLAY0 = 50 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_PM_DISABLE_EDPL0 = 51 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_RETRAIN_CRC_RETRAIN0 = 52 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_RETRAIN_CRC_RESET0 = 53 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_FRBUF_FULL0 = 54 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_FRBUF_FULL_REPLAY0 = 55 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_PM_RETRAIN0 = 56 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_PM_RESET0 = 57 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_CRC_RETRAIN0 = 58 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_CRC_RESET0 = 59 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_MESO_BUFFER_ENABLE = 60 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_MESO_BUFFER_START = 61 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_MESO_BUFFER_DEPTH = 62 ;
+static const uint8_t EXPLR_DLX_DL0_CYA_BITS_CFG_MESO_BUFFER_DEPTH_LEN = 2 ;
+
+static const uint8_t EXPLR_DLX_DL0_DEBUG_AID_RESERVED = 0 ;
+static const uint8_t EXPLR_DLX_DL0_DEBUG_AID_RESERVED_LEN = 55 ;
+static const uint8_t EXPLR_DLX_DL0_DEBUG_AID_PRBS7_RESET = 55 ;
+static const uint8_t EXPLR_DLX_DL0_DEBUG_AID_PRBS7_STATUS = 56 ;
+static const uint8_t EXPLR_DLX_DL0_DEBUG_AID_PRBS7_STATUS_LEN = 8 ;
+
+static const uint8_t EXPLR_DLX_DL0_DLX_CONFIG_CFG_DLX0 = 32 ;
+static const uint8_t EXPLR_DLX_DL0_DLX_CONFIG_CFG_DLX0_LEN = 32 ;
+
+static const uint8_t EXPLR_DLX_DL0_DLX_INFO_STS = 0 ;
+static const uint8_t EXPLR_DLX_DL0_DLX_INFO_STS_LEN = 64 ;
+
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L7 = 0 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L7_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L6 = 8 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L6_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L5 = 16 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L5_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L4 = 24 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L4_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L3 = 32 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L3_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L2 = 40 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L2_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L1 = 48 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L1_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L0 = 56 ;
+static const uint8_t EXPLR_DLX_DL0_EDPL_MAX_COUNT_L0_LEN = 8 ;
+
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_11 = 16 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_11_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_10 = 20 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_10_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_9 = 24 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_9_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_8 = 28 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_8_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_7 = 32 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_7_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_6 = 36 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_6_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_5 = 40 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_5_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_4 = 44 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_4_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_3 = 48 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_3_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_2 = 52 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_2_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_1 = 56 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_1_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_0 = 60 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_ACTION_FIR_0_LEN = 4 ;
+
+static const uint8_t EXPLR_DLX_DL0_ERROR_CAPTURE_INFO = 1 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_CAPTURE_INFO_LEN = 63 ;
+
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_47 = 16 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_46 = 17 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_45 = 18 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_44 = 19 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_43 = 20 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_42 = 21 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_41 = 22 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_40 = 23 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_39 = 24 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_38 = 25 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_37 = 26 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_36 = 27 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_35 = 28 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_34 = 29 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_33 = 30 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_32 = 31 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_31 = 32 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_30 = 33 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_29 = 34 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_28 = 35 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_27 = 36 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_26 = 37 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_25 = 38 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_24 = 39 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_23 = 40 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_22 = 41 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_21 = 42 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_20 = 43 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_19 = 44 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_18 = 45 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_17 = 46 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_16 = 47 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_15 = 48 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_14 = 49 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_13 = 50 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_12 = 51 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_11 = 52 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_10 = 53 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_09 = 54 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_08 = 55 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_07 = 56 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_06 = 57 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_05 = 58 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_04 = 59 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_03 = 60 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_02 = 61 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_01 = 62 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_HOLD_CERR_00 = 63 ;
+
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_47 = 16 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_46 = 17 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_45 = 18 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_44 = 19 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_43 = 20 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_42 = 21 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_41 = 22 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_40 = 23 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_39 = 24 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_38 = 25 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_37 = 26 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_36 = 27 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_35 = 28 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_34 = 29 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_33 = 30 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_32 = 31 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_31 = 32 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_30 = 33 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_29 = 34 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_28 = 35 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_27 = 36 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_26 = 37 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_25 = 38 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_24 = 39 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_23 = 40 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_22 = 41 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_21 = 42 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_20 = 43 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_19 = 44 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_18 = 45 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_17 = 46 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_16 = 47 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_15 = 48 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_14 = 49 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_13 = 50 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_12 = 51 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_11 = 52 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_10 = 53 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_09 = 54 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_08 = 55 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_07 = 56 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_06 = 57 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_05 = 58 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_04 = 59 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_03 = 60 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_02 = 61 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_01 = 62 ;
+static const uint8_t EXPLR_DLX_DL0_ERROR_MASK_00 = 63 ;
+
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_TRAINED_MODE = 0 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_TRAINED_MODE_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RX_LANE_REVERSED = 4 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_TX_LANE_REVERSED = 5 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RSVD0 = 6 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_ACK_PTRS_EQUAL = 7 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RSVD1 = 8 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RSVD1_LEN = 4 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_REQUESTED_LN_WIDTH = 12 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_REQUESTED_LN_WIDTH_LEN = 2 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_ACTUAL_LN_WIDTH = 14 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_ACTUAL_LN_WIDTH_LEN = 2 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_TX_TRAINED_LANES = 16 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_TX_TRAINED_LANES_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RX_TRAINED_LANES = 24 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RX_TRAINED_LANES_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_ENDPOINT_INFO = 32 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_ENDPOINT_INFO_LEN = 16 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RSVD2 = 48 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_TRAINING_STATE_MACHINE = 49 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_TRAINING_STATE_MACHINE_LEN = 3 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RSVD3 = 52 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_RSVD3_LEN = 3 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_DESKEW_DONE = 55 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_LANES_DISABLED = 56 ;
+static const uint8_t EXPLR_DLX_DL0_STATUS_STS_LANES_DISABLED_LEN = 8 ;
+
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_PATTERN_A = 0 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_PATTERN_A_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_PATTERN_B = 8 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_PATTERN_B_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_SYNC_PATTERN = 16 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_SYNC_PATTERN_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_PHY_INIT_DONE = 24 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_PHY_INIT_DONE_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_BLOCK_LOCKED = 32 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_BLOCK_LOCKED_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_TS1 = 40 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_TS1_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_TS2 = 48 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_TS2_LEN = 8 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_TS3 = 56 ;
+static const uint8_t EXPLR_DLX_DL0_TRAINING_STATUS_STS_RX_TS3_LEN = 8 ;
+
+static const uint8_t EXPLR_DLX_ERR_HOLD_LAT_FIR_MASK_PAR = 0 ;
+static const uint8_t EXPLR_DLX_ERR_HOLD_LAT_FIR_ACTION0_PAR = 1 ;
+static const uint8_t EXPLR_DLX_ERR_HOLD_LAT_FIR_ACTION1_PAR = 2 ;
+
+static const uint8_t EXPLR_DLX_ERR_MASK_LAT_FIR_PAR = 0 ;
+static const uint8_t EXPLR_DLX_ERR_MASK_LAT_FIR_ACTION0_PAR = 1 ;
+static const uint8_t EXPLR_DLX_ERR_MASK_LAT_FIR_ACTION1_PAR = 2 ;
+
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_ACTION0_REG_ACTION0 = 0 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_ACTION0_REG_ACTION0_LEN = 64 ;
+
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_ACTION1_REG_ACTION1 = 0 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_ACTION1_REG_ACTION1_LEN = 64 ;
+
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_DL0_ERROR = 0 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_DL0_ERROR_LEN = 20 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_DL1_ERROR = 20 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_DL1_ERROR_LEN = 20 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_DL2_ERROR = 40 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_DL2_ERROR_LEN = 20 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_PERF_MON_WRAPPED = 60 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_LFIR_PAR_ERR = 62 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_MASK_REG_SCOM_SAT_ERR = 63 ;
+
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_FATAL_ERROR = 0 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_DATA_UE = 1 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_FLIT_CE = 2 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_CRC_ERROR = 3 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_NACK = 4 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_X4_MODE = 5 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_EDPL = 6 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_TIMEOUT = 7 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_REMOTE_RETRAIN = 8 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ERROR_RETRAIN = 9 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_EDPL_RETRAIN = 10 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_TRAINED = 11 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR0 = 12 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR1 = 13 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR2 = 14 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR3 = 15 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR4 = 16 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR5 = 17 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR6 = 18 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL0_ENDPOINT_FIR7 = 19 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_FATAL_ERROR = 20 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_DATA_UE = 21 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_FLIT_CE = 22 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_CRC_ERROR = 23 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_NACK = 24 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_X4_MODE = 25 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_EDPL = 26 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_TIMEOUT = 27 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_REMOTE_RETRAIN = 28 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ERROR_RETRAIN = 29 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_EDPL_RETRAIN = 30 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_TRAINED = 31 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR0 = 32 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR1 = 33 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR2 = 34 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR3 = 35 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR4 = 36 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR5 = 37 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR6 = 38 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL1_ENDPOINT_FIR7 = 39 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_FATAL_ERROR = 40 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_DATA_UE = 41 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_FLIT_CE = 42 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_CRC_ERROR = 43 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_NACK = 44 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_X4_MODE = 45 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_EDPL = 46 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_TIMEOUT = 47 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_REMOTE_RETRAIN = 48 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ERROR_RETRAIN = 49 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_EDPL_RETRAIN = 50 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_TRAINED = 51 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR0 = 52 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR1 = 53 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR2 = 54 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR3 = 55 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR4 = 56 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR5 = 57 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR6 = 58 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_DL2_ENDPOINT_FIR7 = 59 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_PERF_MON_WRAPPED = 60 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_LFIR_PAR_ERR = 62 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_REG_SCOM_SAT_ERR = 63 ;
+
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_WOF_REG_WOF = 0 ;
+static const uint8_t EXPLR_DLX_MC_OMI_FIR_WOF_REG_WOF_LEN = 64 ;
+
+static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU3 = 0 ;
+static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU3_LEN = 16 ;
+static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU2 = 16 ;
+static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU2_LEN = 16 ;
+static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU1 = 32 ;
+static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU1_LEN = 16 ;
+static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU0 = 48 ;
+static const uint8_t EXPLR_DLX_PMU_CNTR_CFG_PMU0_LEN = 16 ;
+
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_ARRAY_CE_ERR_INJ_MODE = 0 ;
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_ARRAY_CE_ERR_INJ = 1 ;
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_ARRAY_UE_ERR_INJ_MODE = 2 ;
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_ARRAY_UE_ERR_INJ = 3 ;
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_RESERVED_4 = 4 ;
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_DISABLE_2N_MODE = 5 ;
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_RESERVED_6_14 = 6 ;
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_RESERVED_6_14_LEN = 9 ;
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_READ_RESPONSE_DELAY_ENABLE = 15 ;
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_LOOP_COUNTER_COMPARE0 = 16 ;
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_LOOP_COUNTER_COMPARE0_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_LOOP_COUNTER_COMPARE1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_LOOP_COUNTER_COMPARE1_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_LOOP_COUNTER_COMPARE2 = 48 ;
+static const uint8_t EXPLR_MCBIST_CCSARRERRINJQ_CCS_LOOP_COUNTER_COMPARE2_LEN = 16 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_CNTLQ_START = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_CNTLQ_STOP = 1 ;
+static const uint8_t EXPLR_MCBIST_CCS_CNTLQ_UNPAUSE = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_FIXED_DATA0Q_DATA_0_63 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_FIXED_DATA0Q_DATA_0_63_LEN = 64 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_FIXED_DATA1Q_DATA_64_79 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_FIXED_DATA1Q_DATA_64_79_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_FIXED_DATA1Q_NTTM_READ_DELAY = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_FIXED_DATA1Q_NTTM_READ_DELAY_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_FIXED_DATA1Q_WRITE_DATA_DELAY = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_FIXED_DATA1Q_WRITE_DATA_DELAY_LEN = 16 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_00_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_01_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_02_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_03_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_04_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_05_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_06_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_07_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_08_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_09_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_10_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_11_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_12_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ADDRESS_0 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ADDRESS_0_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_13_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ADDRESS = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_14_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ADDRESS = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_15_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ADDRESS = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_16_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ADDRESS = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_17_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_18_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_19_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_20_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_21_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_22_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_23_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_24_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_25_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_26_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_27_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_28_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_29_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_RESERVED_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_RESERVED_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_30_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ADDRESS_0_13 = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ADDRESS_17 = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_BANK_GROUP_1 = 15 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_RESETN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_BANK_0_1 = 17 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_BANK_GROUP_0 = 19 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ACTN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ADDRESS_16 = 21 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ADDRESS_15 = 22 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ADDRESS_14 = 23 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CKE = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CKE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_ADDRESS_OP = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_ADDRESS_OP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_RESERVED_30 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_RESERVED_30_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CSN_0_1 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CSN_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CID_0_1 = 34 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CID_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CSN_2_3 = 36 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CSN_2_3_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_CID_2 = 38 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_FORCE_DATA_IMMED = 39 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_NESTED_LOOP_CNT = 40 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_NESTED_LOOP_CNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ODT = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_RESERVED_52_54 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_RESERVED_52_54_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_PAUSE_INSTR = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_VARIABLE_SEL = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_VARIABLE_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_RESERVED_58_59 = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_RESERVED_58_59_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_PARITY = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_DDR_BANK_2 = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_LOOP_BREAK_MODE = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR0_31_LOOP_BREAK_MODE_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_00_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_01_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_02_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_03_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_04_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_05_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_06_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_07_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_08_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_09_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_10_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_11_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_12_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_13_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_14_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_15_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_16_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_17_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_18_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_19_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_20_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_21_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_22_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_23_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_24_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_25_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_26_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_27_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_28_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_29_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_30_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_IDLES = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_IDLES_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_REPEAT_CMD_CNT = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_REPEAT_CMD_CNT_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_READ_OR_WRITE_DATA = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_READ_OR_WRITE_DATA_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_READ_COMPARE_REQUIRED = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_VARIABLE_OP = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_VARIABLE_OP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_END = 58 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_GOTO_CMD = 59 ;
+static const uint8_t EXPLR_MCBIST_CCS_INST_ARR1_31_GOTO_CMD_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_STOP_ON_ERR = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_UE_DISABLE = 1 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_DATA_COMPARE_BURST_SEL = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_DATA_COMPARE_BURST_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_RESERVED_4_6 = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_RESERVED_4_6_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_TRACE_SELECT_DQBYPASS = 7 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_RESERVED_8_23 = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_RESERVED_8_23_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_CFG_PARITY_AFTER_CMD = 24 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_NESTED_LOOP_ENABLE = 25 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_COPY_CKE_TO_SPARE_CKE = 26 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_DISABLE_ECC_ARRAY_CHK = 27 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_DISABLE_ECC_ARRAY_CORRECTION = 28 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_CFG_DGEN_FIXED_MODE = 29 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_RESERVED_30_31 = 30 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_RESERVED_30_31_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_0_13 = 32 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_0_13_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_17 = 46 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_GROUP_1 = 47 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_0_1 = 48 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_0_1_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_GROUP_0 = 50 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ACTN = 51 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_16 = 52 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_15 = 53 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_14 = 54 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_NTTM_MODE = 55 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_NTTM_RW_DATA_DLY = 56 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_NTTM_RW_DATA_DLY_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_2 = 60 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_DDR_PARITY_ENABLE = 61 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_PARITY = 62 ;
+static const uint8_t EXPLR_MCBIST_CCS_MODEQ_PAUSE_DISABLE = 63 ;
+
+static const uint8_t EXPLR_MCBIST_CCS_STATQ_IP = 0 ;
+static const uint8_t EXPLR_MCBIST_CCS_STATQ_DONE = 1 ;
+static const uint8_t EXPLR_MCBIST_CCS_STATQ_FAIL = 2 ;
+static const uint8_t EXPLR_MCBIST_CCS_STATQ_FAIL_TYPE = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_STATQ_FAIL_TYPE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_CCS_STATQ_MCBIST_SUBTEST_IP = 6 ;
+static const uint8_t EXPLR_MCBIST_CCS_STATQ_FAIL_RCD = 7 ;
+static const uint8_t EXPLR_MCBIST_CCS_STATQ_PAUSED = 8 ;
+static const uint8_t EXPLR_MCBIST_CCS_STATQ_CE = 9 ;
+
+static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_ENABLE = 0 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_ASYNC_PORT01 = 1 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_ASYNC_PORT01_LEN = 11 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_ASYNC_PORT23 = 12 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_ASYNC_PORT23_LEN = 11 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_MCBIST01 = 23 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_MCBIST01_LEN = 11 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_MCBIST23 = 34 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG0Q_CFG_DBG_PICK_MCBIST23_LEN = 11 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG0Q_SCOM_SET_WAT_EXT_TRIGGER = 45 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG0Q_SCOM_SET_WAT_EXT_RESET = 46 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG0Q_SCOM_SET_WAT_EXT_ARM = 47 ;
+
+static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_ENABLE = 0 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_EVENT_TO_INT = 1 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_EVENT_TO_INT_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_TRIGGER_SEL = 3 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_TRIGGER_SEL_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_RESET_SEL = 23 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_RESET_SEL_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_ARM_SEL = 43 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG1Q_CFG_WAT_EXT_ARM_SEL_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG1Q_RESERVED_63 = 63 ;
+
+static const uint8_t EXPLR_MCBIST_DBGCFG2Q_CFG_WAT_LOC_EVENT0_SEL = 0 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG2Q_CFG_WAT_LOC_EVENT0_SEL_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG2Q_CFG_WAT_LOC_EVENT1_SEL = 20 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG2Q_CFG_WAT_LOC_EVENT1_SEL_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG2Q_CFG_WAT_LOC_EVENT2_SEL = 40 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG2Q_CFG_WAT_LOC_EVENT2_SEL_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG2Q_RESERVED_60_63 = 60 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG2Q_RESERVED_60_63_LEN = 4 ;
+
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_LOC_EVENT3_SEL = 0 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_LOC_EVENT3_SEL_LEN = 20 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT0_SEL = 20 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT0_SEL_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT1_SEL = 23 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT1_SEL_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT2_SEL = 26 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT2_SEL_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT3_SEL = 29 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_GLOB_EVENT3_SEL_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_OUTPUT_PULSE = 32 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_ACT_MNT_GO_IDLE_PULSE = 33 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_ACT_MNT_GO_IDLE_PULSE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_ACT_SET_SPATTN_PULSE = 37 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_ACT_SET_SPATTN_PULSE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_ACT_FRC_TB_PULSE_PULSE = 41 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_ACT_FRC_TB_PULSE_PULSE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_CNT_VALUE = 45 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_CNT_VALUE_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_TMR_VALUE = 51 ;
+static const uint8_t EXPLR_MCBIST_DBGCFG3Q_CFG_WAT_TMR_VALUE_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_A = 0 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_A_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_B = 4 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_B_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_C = 8 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_C_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_D = 12 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL0_D_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_A = 16 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_A_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_B = 20 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_B_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_C = 24 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_C_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_D = 28 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE_SEL1_D_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TLXR_SHIFT_SEL = 32 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TLXT_SHIFT_SEL = 33 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_WDF_SHIFT_SEL = 34 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_RDF_SHIFT_SEL = 35 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_SRQ_SHIFT_SEL = 36 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_MCB_SHIFT_SEL = 37 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_MMIO_SHIFT_SEL = 38 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DLX_SHIFT_SEL = 39 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE0_TRACE_ERR_SEL = 40 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE0_TRACE_ERR_SEL_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE1_TRACE_ERR_SEL = 44 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_TRACE1_TRACE_ERR_SEL_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_SLICE_SEL_A = 48 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_SLICE_SEL_A_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_SLICE_SEL_B = 52 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_SLICE_SEL_B_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_RESERVED_56 = 56 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_GROUP_SEL0 = 57 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_GROUP_SEL0_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_RESERVED_60 = 60 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_GROUP_SEL1 = 61 ;
+static const uint8_t EXPLR_MCBIST_DBG_BUS_CFGQ_DFI_GROUP_SEL1_LEN = 3 ;
+
+static const uint8_t EXPLR_MCBIST_ERR_HOLD_LAT_FIR_MASK_PAR = 0 ;
+static const uint8_t EXPLR_MCBIST_ERR_HOLD_LAT_FIR_ACTION0_PAR = 1 ;
+static const uint8_t EXPLR_MCBIST_ERR_HOLD_LAT_FIR_ACTION1_PAR = 2 ;
+
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBECTLQ_PE = 0 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_CCS_STATQ_PE = 1 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_CCS_MODEQ_PE = 2 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_RCD_LRDIM_CNTL_WORD0_15Q_PE = 3 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_CCSARRERRINJQ_PE = 4 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_CCS_FIXED_DATA0Q_PE = 5 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_CCS_FIXED_DATA1Q_PE = 6 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBAMR0A0Q_PE = 7 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBAMR1A0Q_PE = 8 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBAMR2A0Q_PE = 9 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBAMR3A0Q_PE = 10 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBSA0Q_PE = 11 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBSA1Q_PE = 12 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBEA0Q_PE = 13 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBEA1Q_PE = 14 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBSA2Q_PE = 15 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBSA3Q_PE = 16 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBEA2Q_PE = 17 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBEA3Q_PE = 18 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBLFSRA0Q_PE = 19 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBACQ_PE = 20 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBAGRAQ_PE = 21 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBRDS0Q_PE = 22 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBRDS1Q_PE = 23 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBDRSRQ_PE = 24 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBDRCRQ_PE = 25 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD0Q_PE = 26 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD1Q_PE = 27 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD2Q_PE = 28 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD3Q_PE = 29 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD4Q_PE = 30 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD5Q_PE = 31 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD6Q_PE = 32 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFD7Q_PE = 33 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFDSPQ_PE = 34 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBFDQ_PE = 35 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBPARMQ_PE = 36 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_RUNTIMECTRQ_PE = 37 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBRCRQ_PE = 38 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCB_CNTLSTATQ_PE = 39 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBCFGQ_PE = 40 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBMCATQ_PE = 41 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSEC0Q_PE = 42 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSEC1Q_PE = 43 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSTRQ_PE = 44 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC0Q_PE = 45 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC1Q_PE = 46 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC2Q_PE = 47 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC3Q_PE = 48 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC4Q_PE = 49 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC5Q_PE = 50 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC6Q_PE = 51 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC7Q_PE = 52 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSSYMEC8Q_PE = 53 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSMODESQ_PE = 54 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MCBSTATQ_PE = 55 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBSMSECQ_PE = 56 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBNCER0Q_PE = 57 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBRCER0Q_PE = 58 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBMPER0Q_PE = 59 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBUER0Q_PE = 60 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MBAUER0Q_PE = 61 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_DBG_BUS_CFGQ_PE = 62 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK0Q_MASK1Q_PE = 63 ;
+
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MASK0Q_PE = 0 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MBSEVR0Q_PE = 1 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_DBGCFG0Q_PE = 2 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_DBGCFG1Q_PE = 3 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_DBGCFG2Q_PE = 4 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_DBGCFG3Q_PE = 5 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG0AQ_PE = 6 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG0BQ_PE = 7 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG0CQ_PE = 8 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG0DQ_PE = 9 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG0EQ_PE = 10 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG1AQ_PE = 11 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG1BQ_PE = 12 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG1CQ_PE = 13 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG1DQ_PE = 14 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG1EQ_PE = 15 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG2AQ_PE = 16 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG2BQ_PE = 17 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG2CQ_PE = 18 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG2DQ_PE = 19 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG2EQ_PE = 20 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG3AQ_PE = 21 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG3BQ_PE = 22 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG3CQ_PE = 23 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG3DQ_PE = 24 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_WATCFG3EQ_PE = 25 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR0Q_PE = 26 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR1Q_PE = 27 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR2Q_PE = 28 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR3Q_PE = 29 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR4Q_PE = 30 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR5Q_PE = 31 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR6Q_PE = 32 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCBMR7Q_PE = 33 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MBXLT0Q_PE = 34 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MBXLT1Q_PE = 35 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MBXLT2Q_PE = 36 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_CCS_CNTLQ_PE = 37 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCB_CNTLQ_PE = 38 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCB_FIR_CCS = 39 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MCB_FIR_MCBFSM = 40 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_CCS_ARRAY_UNCORRECTED_CE = 41 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_CCS_ARRAY_UE = 42 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_CCS_ARRAY_SCOM_ECC = 43 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_MBSSYMEC9Q_PE = 44 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_RESERVED_45_63 = 45 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK1Q_RESERVED_45_63_LEN = 19 ;
+
+static const uint8_t EXPLR_MCBIST_ERR_MASK_LAT_FIR_PAR = 0 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK_LAT_FIR_ACTION0_PAR = 1 ;
+static const uint8_t EXPLR_MCBIST_ERR_MASK_LAT_FIR_ACTION1_PAR = 2 ;
+
+static const uint8_t EXPLR_MCBIST_MBAUER0Q_PORT_0_MAINLINE_AUE_ADDR_TRAP = 0 ;
+static const uint8_t EXPLR_MCBIST_MBAUER0Q_PORT_0_MAINLINE_AUE_ADDR_TRAP_LEN = 38 ;
+static const uint8_t EXPLR_MCBIST_MBAUER0Q_RESERVED_38_39 = 38 ;
+static const uint8_t EXPLR_MCBIST_MBAUER0Q_RESERVED_38_39_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBECTLQ_PE = 0 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_CCS_STATQ_PE = 1 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_CCS_MODEQ_PE = 2 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_RCD_LRDIM_CNTL_WORD0_15Q_PE = 3 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_CCSARRERRINJQ_PE = 4 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_CCS_FIXED_DATA0Q_PE = 5 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_CCS_FIXED_DATA1Q_PE = 6 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBAMR0A0Q_PE = 7 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBAMR1A0Q_PE = 8 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBAMR2A0Q_PE = 9 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBAMR3A0Q_PE = 10 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBSA0Q_PE = 11 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBSA1Q_PE = 12 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBEA0Q_PE = 13 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBEA1Q_PE = 14 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBSA2Q_PE = 15 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBSA3Q_PE = 16 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBEA2Q_PE = 17 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBEA3Q_PE = 18 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBLFSRA0Q_PE = 19 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBACQ_PE = 20 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBAGRAQ_PE = 21 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBRDS0Q_PE = 22 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBRDS1Q_PE = 23 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBDRSRQ_PE = 24 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBDRCRQ_PE = 25 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD0Q_PE = 26 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD1Q_PE = 27 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD2Q_PE = 28 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD3Q_PE = 29 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD4Q_PE = 30 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD5Q_PE = 31 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD6Q_PE = 32 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFD7Q_PE = 33 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFDSPQ_PE = 34 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBFDQ_PE = 35 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBPARMQ_PE = 36 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_RUNTIMECTRQ_PE = 37 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBRCRQ_PE = 38 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCB_CNTLSTATQ_PE = 39 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBCFGQ_PE = 40 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBMCATQ_PE = 41 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSEC0Q_PE = 42 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSEC1Q_PE = 43 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSTRQ_PE = 44 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC0Q_PE = 45 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC1Q_PE = 46 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC2Q_PE = 47 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC3Q_PE = 48 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC4Q_PE = 49 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC5Q_PE = 50 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC6Q_PE = 51 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC7Q_PE = 52 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSSYMEC8Q_PE = 53 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSMODESQ_PE = 54 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MCBSTATQ_PE = 55 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBSMSECQ_PE = 56 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBNCER0Q_PE = 57 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBRCER0Q_PE = 58 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBMPER0Q_PE = 59 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBUER0Q_PE = 60 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_MBAUER0Q_PE = 61 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_DBG_BUS_CFGQ_PE = 62 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT0Q_ERR_MASK1Q_PE = 63 ;
+
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_ERR_MASK0Q_PE = 0 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MBSEVR0Q_PE = 1 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_DBGCFG0Q_PE = 2 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_DBGCFG1Q_PE = 3 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_DBGCFG2Q_PE = 4 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_DBGCFG3Q_PE = 5 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG0AQ_PE = 6 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG0BQ_PE = 7 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG0CQ_PE = 8 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG0DQ_PE = 9 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG0EQ_PE = 10 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG1AQ_PE = 11 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG1BQ_PE = 12 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG1CQ_PE = 13 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG1DQ_PE = 14 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG1EQ_PE = 15 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG2AQ_PE = 16 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG2BQ_PE = 17 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG2CQ_PE = 18 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG2DQ_PE = 19 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG2EQ_PE = 20 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG3AQ_PE = 21 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG3BQ_PE = 22 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG3CQ_PE = 23 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG3DQ_PE = 24 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_WATCFG3EQ_PE = 25 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR0Q_PE = 26 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR1Q_PE = 27 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR2Q_PE = 28 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR3Q_PE = 29 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR4Q_PE = 30 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR5Q_PE = 31 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR6Q_PE = 32 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCBMR7Q_PE = 33 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MBXLT0Q_PE = 34 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MBXLT1Q_PE = 35 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MBXLT2Q_PE = 36 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_CCS_CNTLQ_PE = 37 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCB_CNTLQ_PE = 38 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCB_FIR_CCS_ERR = 39 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MCB_FIR_MCBFSM_ERR = 40 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_CCS_ARRAY_UNCORRECTED_CE_ERR = 41 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_CCS_ARRAY_UE_ERR = 42 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_CCS_ARRAY_SCOM_ECC_ERR = 43 ;
+static const uint8_t EXPLR_MCBIST_MBA_MCBERRPT1Q_MBSSYMEC9Q_PE = 44 ;
+
+static const uint8_t EXPLR_MCBIST_MBECTLQ_ATOMIC_ALT_CE_INJ = 0 ;
+static const uint8_t EXPLR_MCBIST_MBECTLQ_ATOMIC_ALT_CHIP_KILL_INJ = 1 ;
+static const uint8_t EXPLR_MCBIST_MBECTLQ_ATOMIC_ALT_UE_INJ = 2 ;
+static const uint8_t EXPLR_MCBIST_MBECTLQ_ATOMIC_ALT_SUE_INJ = 3 ;
+static const uint8_t EXPLR_MCBIST_MBECTLQ_ATOMIC_ALT_INJ_SYM_SEL = 4 ;
+static const uint8_t EXPLR_MCBIST_MBECTLQ_ATOMIC_ALT_INJ_SYM_SEL_LEN = 7 ;
+static const uint8_t EXPLR_MCBIST_MBECTLQ_RESERVE_11 = 11 ;
+static const uint8_t EXPLR_MCBIST_MBECTLQ_SCOM_CMD_REG_INJ_MODE = 12 ;
+static const uint8_t EXPLR_MCBIST_MBECTLQ_SCOM_CMD_REG_INJ = 13 ;
+static const uint8_t EXPLR_MCBIST_MBECTLQ_MCBIST_FSM_INJ_MODE = 14 ;
+static const uint8_t EXPLR_MCBIST_MBECTLQ_MCBIST_FSM_INJ_REG = 15 ;
+static const uint8_t EXPLR_MCBIST_MBECTLQ_CCS_FSM_INJ_MODE = 16 ;
+static const uint8_t EXPLR_MCBIST_MBECTLQ_CCS_FSM_INJ_REG = 17 ;
+static const uint8_t EXPLR_MCBIST_MBECTLQ_RESERVED_18_31 = 18 ;
+static const uint8_t EXPLR_MCBIST_MBECTLQ_RESERVED_18_31_LEN = 14 ;
+
+static const uint8_t EXPLR_MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ADDR_TRAP = 0 ;
+static const uint8_t EXPLR_MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ADDR_TRAP_LEN = 38 ;
+static const uint8_t EXPLR_MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ON_RCE = 38 ;
+static const uint8_t EXPLR_MCBIST_MBMPER0Q_RESERVED_39 = 39 ;
+
+static const uint8_t EXPLR_MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ADDR_TRAP = 0 ;
+static const uint8_t EXPLR_MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ADDR_TRAP_LEN = 38 ;
+static const uint8_t EXPLR_MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ON_RCE = 38 ;
+static const uint8_t EXPLR_MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_IS_TCE = 39 ;
+
+static const uint8_t EXPLR_MCBIST_MBRCER0Q_PORT_0_MAINLINE_RCE_ADDR_TRAP = 0 ;
+static const uint8_t EXPLR_MCBIST_MBRCER0Q_PORT_0_MAINLINE_RCE_ADDR_TRAP_LEN = 38 ;
+static const uint8_t EXPLR_MCBIST_MBRCER0Q_RESERVED_38_39 = 38 ;
+static const uint8_t EXPLR_MCBIST_MBRCER0Q_RESERVED_38_39_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_MBSEC0Q_INTERMITTENT_CE_COUNT = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSEC0Q_INTERMITTENT_CE_COUNT_LEN = 12 ;
+static const uint8_t EXPLR_MCBIST_MBSEC0Q_SOFT_CE_COUNT = 12 ;
+static const uint8_t EXPLR_MCBIST_MBSEC0Q_SOFT_CE_COUNT_LEN = 12 ;
+static const uint8_t EXPLR_MCBIST_MBSEC0Q_HARD_CE_COUNT = 24 ;
+static const uint8_t EXPLR_MCBIST_MBSEC0Q_HARD_CE_COUNT_LEN = 12 ;
+static const uint8_t EXPLR_MCBIST_MBSEC0Q_INTERMITTENT_MCE_COUNT = 36 ;
+static const uint8_t EXPLR_MCBIST_MBSEC0Q_INTERMITTENT_MCE_COUNT_LEN = 12 ;
+static const uint8_t EXPLR_MCBIST_MBSEC0Q_SOFT_MCE_COUNT = 48 ;
+static const uint8_t EXPLR_MCBIST_MBSEC0Q_SOFT_MCE_COUNT_LEN = 12 ;
+
+static const uint8_t EXPLR_MCBIST_MBSEC1Q_HARD_MCE_COUNT = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSEC1Q_HARD_MCE_COUNT_LEN = 12 ;
+static const uint8_t EXPLR_MCBIST_MBSEC1Q_ICE_COUNT = 12 ;
+static const uint8_t EXPLR_MCBIST_MBSEC1Q_ICE_COUNT_LEN = 12 ;
+static const uint8_t EXPLR_MCBIST_MBSEC1Q_UE_COUNT = 24 ;
+static const uint8_t EXPLR_MCBIST_MBSEC1Q_UE_COUNT_LEN = 12 ;
+static const uint8_t EXPLR_MCBIST_MBSEC1Q_AUE = 36 ;
+static const uint8_t EXPLR_MCBIST_MBSEC1Q_AUE_LEN = 12 ;
+static const uint8_t EXPLR_MCBIST_MBSEC1Q_RCE_COUNT = 48 ;
+static const uint8_t EXPLR_MCBIST_MBSEC1Q_RCE_COUNT_LEN = 12 ;
+
+static const uint8_t EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_GALOIS_FIELD = 0 ;
static const uint8_t EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_GALOIS_FIELD_LEN = 8 ;
static const uint8_t EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_MAGNITUDE_FIELD = 8 ;
static const uint8_t EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_MAGNITUDE_FIELD_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_GALOIS_FIELD = 16 ;
+static const uint8_t EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_GALOIS_FIELD = 16 ;
static const uint8_t EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_GALOIS_FIELD_LEN = 8 ;
static const uint8_t EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_MAGNITUDE_FIELD = 24 ;
static const uint8_t EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_MAGNITUDE_FIELD_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSEVR0Q_RESERVED_32_63 = 32 ;
-static const uint8_t EXPLR_MCBIST_MBSEVR0Q_RESERVED_32_63_LEN = 32 ;
+static const uint8_t EXPLR_MCBIST_MBSEVR0Q_RESERVED_32_63 = 32 ;
+static const uint8_t EXPLR_MCBIST_MBSEVR0Q_RESERVED_32_63_LEN = 32 ;
-static const uint8_t EXPLR_MCBIST_MBSMODESQ_CFG_DDR4E_BLIND_STEER_MODE = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSMODESQ_CFG_DDR4E_BLIND_STEER_MODE = 0 ;
static const uint8_t EXPLR_MCBIST_MBSMODESQ_CFG_MCB_NIB_CNT_PORT_AGNOSTIC_MASK_DIS = 1 ;
-static const uint8_t EXPLR_MCBIST_MBSMODESQ_RESERVE_2_15 = 2 ;
-static const uint8_t EXPLR_MCBIST_MBSMODESQ_RESERVE_2_15_LEN = 14 ;
-
-static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL0_COUNT = 0 ;
-static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL0_COUNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL1_COUNT = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL1_COUNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL2_COUNT = 16 ;
-static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL2_COUNT_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL3_COUNT = 24 ;
-static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL3_COUNT_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_00 = 0 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_00_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_01 = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_01_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_02 = 16 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_02_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_03 = 24 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_03_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_04 = 32 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_04_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_05 = 40 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_05_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_06 = 48 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_06_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_07 = 56 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_07_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_08 = 0 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_08_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_09 = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_09_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_10 = 16 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_10_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_11 = 24 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_11_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_12 = 32 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_12_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_13 = 40 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_13_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_14 = 48 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_14_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_15 = 56 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_15_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_16 = 0 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_16_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_17 = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_17_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_18 = 16 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_18_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_19 = 24 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_19_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_20 = 32 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_20_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_21 = 40 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_21_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_22 = 48 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_22_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_23 = 56 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_23_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_24 = 0 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_24_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_25 = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_25_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_26 = 16 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_26_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_27 = 24 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_27_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_28 = 32 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_28_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_29 = 40 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_29_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_30 = 48 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_30_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_31 = 56 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_31_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_32 = 0 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_32_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_33 = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_33_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_34 = 16 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_34_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_35 = 24 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_35_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_36 = 32 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_36_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_37 = 40 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_37_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_38 = 48 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_38_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_39 = 56 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_39_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_40 = 0 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_40_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_41 = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_41_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_42 = 16 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_42_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_43 = 24 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_43_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_44 = 32 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_44_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_45 = 40 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_45_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_46 = 48 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_46_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_47 = 56 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_47_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_48 = 0 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_48_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_49 = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_49_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_50 = 16 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_50_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_51 = 24 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_51_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_52 = 32 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_52_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_53 = 40 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_53_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_54 = 48 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_54_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_55 = 56 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_55_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_56 = 0 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_56_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_57 = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_57_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_58 = 16 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_58_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_59 = 24 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_59_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_60 = 32 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_60_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_61 = 40 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_61_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_62 = 48 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_62_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_63 = 56 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_63_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_64 = 0 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_64_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_65 = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_65_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_66 = 16 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_66_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_67 = 24 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_67_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_68 = 32 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_68_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_69 = 40 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_69_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_70 = 48 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_70_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_71 = 56 ;
-static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_71_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT = 0 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT = 4 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD = 8 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE = 12 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE = 16 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT = 20 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT = 24 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD = 28 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_SCE = 32 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_RESERVED_33 = 33 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_MPE = 34 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_UE = 35 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_SUE = 36 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_AUE = 37 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_RCD = 38 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_RESERVE_39_52 = 39 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_RESERVE_39_52_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE = 53 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_NCE_SOFT_SYMBOL_COUNT_ENABLE = 55 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_NCE_INTER_SYMBOL_COUNT_ENABLE = 56 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_NCE_HARD_SYMBOL_COUNT_ENABLE = 57 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_MCB_ERROR = 58 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_MCB_LOG_FULL = 59 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_MAINT_RCE_WITH_CE = 60 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_MCE_SOFT_SYMBOL_COUNT_ENABLE = 61 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_MCE_INTER_SYMBOL_COUNT_ENABLE = 62 ;
-static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_MCE_HARD_SYMBOL_COUNT_ENABLE = 63 ;
-
-static const uint8_t EXPLR_MCBIST_MBUER0Q_PORT_0_MAINLINE_UE_ADDR_TRAP = 0 ;
-static const uint8_t EXPLR_MCBIST_MBUER0Q_PORT_0_MAINLINE_UE_ADDR_TRAP_LEN = 38 ;
-static const uint8_t EXPLR_MCBIST_MBUER0Q_RESERVED_38_39 = 38 ;
-static const uint8_t EXPLR_MCBIST_MBUER0Q_RESERVED_38_39_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_VALID = 0 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_D_VALUE = 1 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_12GB_ENABLE = 2 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_3_4 = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_3_4_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_M0_VALID = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_M1_VALID = 6 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_7_8 = 7 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_7_8_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_S0_VALID = 9 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_S1_VALID = 10 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_S2_VALID = 11 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_B2_VALID = 12 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_ROW15_VALID = 13 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_ROW16_VALID = 14 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_ROW17_VALID = 15 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_VALID = 16 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_D_VALUE = 17 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_18_20 = 18 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_18_20_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_M0_VALID = 21 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_M1_VALID = 22 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_23_24 = 23 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_23_24_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_S0_VALID = 25 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_S1_VALID = 26 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_S2_VALID = 27 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_B2_VALID = 28 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_ROW15_VALID = 29 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_ROW16_VALID = 30 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_ROW17_VALID = 31 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_ENAB_ROW_ADDR_HASH = 32 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_D_BIT_MAP = 33 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_D_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_M0_BIT_MAP = 38 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_M0_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_M1_BIT_MAP = 43 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_M1_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_48 = 48 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_R17_BIT_MAP = 49 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_R17_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_R16_BIT_MAP = 54 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_R16_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_R15_BIT_MAP = 59 ;
-static const uint8_t EXPLR_MCBIST_MBXLT0Q_R15_BIT_MAP_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_0_2 = 0 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_0_2_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_S0_BIT_MAP = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_S0_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_8_10 = 8 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_8_10_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_S1_BIT_MAP = 11 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_S1_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_16_18 = 16 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_16_18_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_S2_BIT_MAP = 19 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_S2_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_24_29 = 24 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_24_29_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_COL3_BIT_MAP = 30 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_COL3_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_COL4_BIT_MAP = 35 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_COL4_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_40_42 = 40 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_40_42_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_COL5_BIT_MAP = 43 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_COL5_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_48_50 = 48 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_48_50_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_COL6_BIT_MAP = 51 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_COL6_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_56_58 = 56 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_56_58_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_COL7_BIT_MAP = 59 ;
-static const uint8_t EXPLR_MCBIST_MBXLT1_COL7_BIT_MAP_LEN = 5 ;
-
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_0_2 = 0 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_0_2_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_COL8_BIT_MAP = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_COL8_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_8_10 = 8 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_8_10_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_COL9_BIT_MAP = 11 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_COL9_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_16_18 = 16 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_16_18_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_BANK0_BIT_MAP = 19 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_BANK0_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_24_26 = 24 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_24_26_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_BANK1_BIT_MAP = 27 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_BANK1_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_32_34 = 32 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_32_34_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_BANK2_BIT_MAP = 35 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_BANK2_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_40_42 = 40 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_40_42_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_BANK_GROUP0_BIT_MAP = 43 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_BANK_GROUP0_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_48_50 = 48 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_48_50_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_BANK_GROUP1_BIT_MAP = 51 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_BANK_GROUP1_BIT_MAP_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_56_63 = 56 ;
-static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_56_63_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_MCBACQ_CFG_ADDRESS_COUNTER = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBACQ_CFG_ADDRESS_COUNTER_LEN = 38 ;
-
-static const uint8_t EXPLR_MCBIST_MCBAGRAQ_CFG_FIXED_WIDTH = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBAGRAQ_CFG_FIXED_WIDTH_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAGRAQ_CFG_ADDR_COUNTER_MODE = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAGRAQ_CFG_ADDR_COUNTER_MODE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBAGRAQ_CFG_MAINT_ADDR_MODE_EN = 10 ;
-static const uint8_t EXPLR_MCBIST_MCBAGRAQ_RESERVED_11 = 11 ;
-static const uint8_t EXPLR_MCBIST_MCBAGRAQ_CFG_MAINT_DETECT_SRANK_BOUNDARIES = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBAGRAQ_RESERVED_13_31 = 13 ;
-static const uint8_t EXPLR_MCBIST_MCBAGRAQ_RESERVED_13_31_LEN = 19 ;
-
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_DIMM_SELECT = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_DIMM_SELECT_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK0 = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK0_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK1 = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK1_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_RESERVED_18_23 = 18 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_RESERVED_18_23_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK0 = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK0_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK1 = 30 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK1_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK2 = 36 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK2_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK2 = 42 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK2_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK1 = 48 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK1_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK0 = 54 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK0_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_RESERVED_60_63 = 60 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_RESERVED_60_63_LEN = 4 ;
-
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP1 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP1_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP0 = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP0_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW17 = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW17_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW16 = 18 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW16_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW15 = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW15_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW14 = 30 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW14_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW13 = 36 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW13_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12 = 42 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW11 = 48 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW11_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW10 = 54 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW10_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_RESERVED_60_63 = 60 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_RESERVED_60_63_LEN = 4 ;
-
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW9 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW9_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW8 = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW8_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW7 = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW7_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW6 = 18 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW6_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW5 = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW5_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW4 = 30 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW4_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW3 = 36 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW3_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW2 = 42 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW2_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW1 = 48 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW1_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW0 = 54 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW0_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_RESERVED_60_63 = 60 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_RESERVED_60_63_LEN = 4 ;
-
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL9 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL9_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL8 = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL8_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL7 = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL7_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL6 = 18 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL6_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL5 = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL5_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL4 = 30 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL4_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL3 = 36 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL3_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL2 = 42 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL2_LEN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_RESERVED_48_63 = 48 ;
-static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_RESERVED_48_63_LEN = 16 ;
-
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_RESERVED_0_7 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_RESERVED_0_7_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_CMD_TIMEOUT_MODE = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_CMD_TIMEOUT_MODE_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_RESET_KEEPER = 10 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_CURRENT_ADDR_TRAP_UPDATE_DIS = 11 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_CCS_RETRY_DIS = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_RESERVED_13_33 = 13 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_RESERVED_13_33_LEN = 21 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_RANK = 34 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_RESET_CNTS_START_OF_RANK = 35 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_LOG_COUNTS_IN_TRACE = 36 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_SKIP_INVALID_ADDR_DIMM_DIS = 37 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_EN = 38 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_TIMEBASE_SEL = 39 ;
+static const uint8_t EXPLR_MCBIST_MBSMODESQ_RESERVE_2_15 = 2 ;
+static const uint8_t EXPLR_MCBIST_MBSMODESQ_RESERVE_2_15_LEN = 14 ;
+
+static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL0_COUNT = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL0_COUNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL1_COUNT = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL1_COUNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL2_COUNT = 16 ;
+static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL2_COUNT_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL3_COUNT = 24 ;
+static const uint8_t EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL3_COUNT_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_00 = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_00_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_01 = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_01_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_02 = 16 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_02_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_03 = 24 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_03_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_04 = 32 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_04_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_05 = 40 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_05_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_06 = 48 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_06_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_07 = 56 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_07_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_08 = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_08_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_09 = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_09_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_10 = 16 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_10_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_11 = 24 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_11_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_12 = 32 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_12_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_13 = 40 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_13_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_14 = 48 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_14_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_15 = 56 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC1Q_MODAL_SYMBOL_COUNTER_15_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_16 = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_16_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_17 = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_17_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_18 = 16 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_18_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_19 = 24 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_19_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_20 = 32 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_20_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_21 = 40 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_21_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_22 = 48 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_22_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_23 = 56 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC2Q_MODAL_SYMBOL_COUNTER_23_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_24 = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_24_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_25 = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_25_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_26 = 16 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_26_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_27 = 24 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_27_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_28 = 32 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_28_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_29 = 40 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_29_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_30 = 48 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_30_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_31 = 56 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC3Q_MODAL_SYMBOL_COUNTER_31_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_32 = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_32_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_33 = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_33_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_34 = 16 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_34_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_35 = 24 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_35_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_36 = 32 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_36_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_37 = 40 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_37_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_38 = 48 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_38_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_39 = 56 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC4Q_MODAL_SYMBOL_COUNTER_39_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_40 = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_40_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_41 = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_41_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_42 = 16 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_42_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_43 = 24 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_43_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_44 = 32 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_44_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_45 = 40 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_45_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_46 = 48 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_46_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_47 = 56 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC5Q_MODAL_SYMBOL_COUNTER_47_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_48 = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_48_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_49 = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_49_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_50 = 16 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_50_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_51 = 24 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_51_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_52 = 32 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_52_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_53 = 40 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_53_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_54 = 48 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_54_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_55 = 56 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC6Q_MODAL_SYMBOL_COUNTER_55_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_56 = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_56_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_57 = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_57_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_58 = 16 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_58_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_59 = 24 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_59_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_60 = 32 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_60_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_61 = 40 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_61_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_62 = 48 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_62_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_63 = 56 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC7Q_MODAL_SYMBOL_COUNTER_63_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_64 = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_64_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_65 = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_65_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_66 = 16 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_66_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_67 = 24 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_67_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_68 = 32 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_68_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_69 = 40 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_69_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_70 = 48 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_70_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_71 = 56 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC8Q_MODAL_SYMBOL_COUNTER_71_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT = 4 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE = 12 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE = 16 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT = 20 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT = 24 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD = 28 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_SCE = 32 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_RESERVED_33 = 33 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_MPE = 34 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_UE = 35 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_SUE = 36 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_AUE = 37 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_RCD = 38 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_RESERVE_39_52 = 39 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_RESERVE_39_52_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE = 53 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_NCE_SOFT_SYMBOL_COUNT_ENABLE = 55 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_NCE_INTER_SYMBOL_COUNT_ENABLE = 56 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_NCE_HARD_SYMBOL_COUNT_ENABLE = 57 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_MCB_ERROR = 58 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_MCB_LOG_FULL = 59 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_MAINT_RCE_WITH_CE = 60 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_MCE_SOFT_SYMBOL_COUNT_ENABLE = 61 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_MCE_INTER_SYMBOL_COUNT_ENABLE = 62 ;
+static const uint8_t EXPLR_MCBIST_MBSTRQ_CFG_MCE_HARD_SYMBOL_COUNT_ENABLE = 63 ;
+
+static const uint8_t EXPLR_MCBIST_MBUER0Q_PORT_0_MAINLINE_UE_ADDR_TRAP = 0 ;
+static const uint8_t EXPLR_MCBIST_MBUER0Q_PORT_0_MAINLINE_UE_ADDR_TRAP_LEN = 38 ;
+static const uint8_t EXPLR_MCBIST_MBUER0Q_RESERVED_38_39 = 38 ;
+static const uint8_t EXPLR_MCBIST_MBUER0Q_RESERVED_38_39_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_VALID = 0 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_D_VALUE = 1 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_12GB_ENABLE = 2 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_3_4 = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_3_4_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_M0_VALID = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_M1_VALID = 6 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_7_8 = 7 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_7_8_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_S0_VALID = 9 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_S1_VALID = 10 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_S2_VALID = 11 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_B2_VALID = 12 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_ROW15_VALID = 13 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_ROW16_VALID = 14 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT0_ROW17_VALID = 15 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_VALID = 16 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_D_VALUE = 17 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_18_20 = 18 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_18_20_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_M0_VALID = 21 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_M1_VALID = 22 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_23_24 = 23 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_23_24_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_S0_VALID = 25 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_S1_VALID = 26 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_S2_VALID = 27 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_B2_VALID = 28 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_ROW15_VALID = 29 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_ROW16_VALID = 30 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_SLOT1_ROW17_VALID = 31 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_ENAB_ROW_ADDR_HASH = 32 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_D_BIT_MAP = 33 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_D_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_M0_BIT_MAP = 38 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_M0_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_M1_BIT_MAP = 43 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_M1_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_RESERVED_48 = 48 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_R17_BIT_MAP = 49 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_R17_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_R16_BIT_MAP = 54 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_R16_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_R15_BIT_MAP = 59 ;
+static const uint8_t EXPLR_MCBIST_MBXLT0Q_R15_BIT_MAP_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_0_2 = 0 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_0_2_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_S0_BIT_MAP = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_S0_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_8_10 = 8 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_8_10_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_S1_BIT_MAP = 11 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_S1_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_16_18 = 16 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_16_18_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_S2_BIT_MAP = 19 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_S2_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_24_29 = 24 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_24_29_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_COL3_BIT_MAP = 30 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_COL3_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_COL4_BIT_MAP = 35 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_COL4_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_40_42 = 40 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_40_42_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_COL5_BIT_MAP = 43 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_COL5_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_48_50 = 48 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_48_50_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_COL6_BIT_MAP = 51 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_COL6_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_56_58 = 56 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_RESERVED_56_58_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_COL7_BIT_MAP = 59 ;
+static const uint8_t EXPLR_MCBIST_MBXLT1_COL7_BIT_MAP_LEN = 5 ;
+
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_0_2 = 0 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_0_2_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_COL8_BIT_MAP = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_COL8_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_8_10 = 8 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_8_10_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_COL9_BIT_MAP = 11 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_COL9_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_16_18 = 16 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_16_18_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_BANK0_BIT_MAP = 19 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_BANK0_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_24_26 = 24 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_24_26_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_BANK1_BIT_MAP = 27 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_BANK1_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_32_34 = 32 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_32_34_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_BANK2_BIT_MAP = 35 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_BANK2_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_40_42 = 40 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_40_42_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_BANK_GROUP0_BIT_MAP = 43 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_BANK_GROUP0_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_48_50 = 48 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_48_50_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_BANK_GROUP1_BIT_MAP = 51 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_BANK_GROUP1_BIT_MAP_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_56_63 = 56 ;
+static const uint8_t EXPLR_MCBIST_MBXLT2_RESERVED_56_63_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_MCBACQ_CFG_ADDRESS_COUNTER = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBACQ_CFG_ADDRESS_COUNTER_LEN = 38 ;
+
+static const uint8_t EXPLR_MCBIST_MCBAGRAQ_CFG_FIXED_WIDTH = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBAGRAQ_CFG_FIXED_WIDTH_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAGRAQ_CFG_ADDR_COUNTER_MODE = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAGRAQ_CFG_ADDR_COUNTER_MODE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBAGRAQ_CFG_MAINT_ADDR_MODE_EN = 10 ;
+static const uint8_t EXPLR_MCBIST_MCBAGRAQ_RESERVED_11 = 11 ;
+static const uint8_t EXPLR_MCBIST_MCBAGRAQ_CFG_MAINT_DETECT_SRANK_BOUNDARIES = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBAGRAQ_RESERVED_13_31 = 13 ;
+static const uint8_t EXPLR_MCBIST_MCBAGRAQ_RESERVED_13_31_LEN = 19 ;
+
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_DIMM_SELECT = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_DIMM_SELECT_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK0 = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK0_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK1 = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK1_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_RESERVED_18_23 = 18 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_RESERVED_18_23_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK0 = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK0_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK1 = 30 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK1_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK2 = 36 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK2_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK2 = 42 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK2_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK1 = 48 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK1_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK0 = 54 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK0_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_RESERVED_60_63 = 60 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR0A0Q_RESERVED_60_63_LEN = 4 ;
+
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP1 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP1_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP0 = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP0_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW17 = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW17_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW16 = 18 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW16_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW15 = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW15_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW14 = 30 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW14_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW13 = 36 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW13_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12 = 42 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW11 = 48 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW11_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW10 = 54 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW10_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_RESERVED_60_63 = 60 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR1A0Q_RESERVED_60_63_LEN = 4 ;
+
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW9 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW9_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW8 = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW8_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW7 = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW7_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW6 = 18 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW6_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW5 = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW5_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW4 = 30 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW4_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW3 = 36 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW3_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW2 = 42 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW2_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW1 = 48 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW1_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW0 = 54 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW0_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_RESERVED_60_63 = 60 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR2A0Q_RESERVED_60_63_LEN = 4 ;
+
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL9 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL9_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL8 = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL8_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL7 = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL7_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL6 = 18 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL6_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL5 = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL5_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL4 = 30 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL4_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL3 = 36 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL3_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL2 = 42 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL2_LEN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_RESERVED_48_63 = 48 ;
+static const uint8_t EXPLR_MCBIST_MCBAMR3A0Q_RESERVED_48_63_LEN = 16 ;
+
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_RESERVED_0_7 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_RESERVED_0_7_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_CMD_TIMEOUT_MODE = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_CMD_TIMEOUT_MODE_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_RESET_KEEPER = 10 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_CURRENT_ADDR_TRAP_UPDATE_DIS = 11 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_CCS_RETRY_DIS = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_RESERVED_13_33 = 13 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_RESERVED_13_33_LEN = 21 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_RANK = 34 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_RESET_CNTS_START_OF_RANK = 35 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_LOG_COUNTS_IN_TRACE = 36 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_SKIP_INVALID_ADDR_DIMM_DIS = 37 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_EN = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_TIMEBASE_SEL = 39 ;
static const uint8_t EXPLR_MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_TIMEBASE_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_RAND_ADDR_ALL_ADDR_MODE_EN = 41 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_REF_WAIT_TIME = 42 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_REF_WAIT_TIME_LEN = 14 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_MCB_LEN64 = 56 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_PAUSE_ON_ERROR_MODE = 57 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_PAUSE_ON_ERROR_MODE_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_PAUSE_AFTER_CCS_SUBTEST = 59 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR = 60 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_RAND_ADDR_ALL_ADDR_MODE_EN = 41 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_REF_WAIT_TIME = 42 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_REF_WAIT_TIME_LEN = 14 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_MCB_LEN64 = 56 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_PAUSE_ON_ERROR_MODE = 57 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_CFG_PAUSE_ON_ERROR_MODE_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_PAUSE_AFTER_CCS_SUBTEST = 59 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR = 60 ;
static const uint8_t EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST = 61 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_RESERVED_62_63 = 62 ;
-static const uint8_t EXPLR_MCBIST_MCBCFGQ_RESERVED_62_63_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_ROT = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_ROT_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_ROT_SEED = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_ROT_SEED_LEN = 16 ;
-static const uint8_t EXPLR_MCBIST_MCBDRCRQ_RESERVED_20 = 20 ;
-static const uint8_t EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_SEED_MODE = 21 ;
-static const uint8_t EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_SEED_MODE_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBDRCRQ_RESERVED_23_63 = 23 ;
-static const uint8_t EXPLR_MCBIST_MCBDRCRQ_RESERVED_23_63_LEN = 41 ;
-
-static const uint8_t EXPLR_MCBIST_MCBDRSRQ_CFG_DATA_ROT_SEED = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBDRSRQ_CFG_DATA_ROT_SEED_LEN = 64 ;
-
-static const uint8_t EXPLR_MCBIST_MCBEA0Q_CFG_END_ADDR_0 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBEA0Q_CFG_END_ADDR_0_LEN = 38 ;
-
-static const uint8_t EXPLR_MCBIST_MCBEA1Q_CFG_END_ADDR_1 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBEA1Q_CFG_END_ADDR_1_LEN = 38 ;
-
-static const uint8_t EXPLR_MCBIST_MCBEA2Q_CFG_END_ADDR_2 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBEA2Q_CFG_END_ADDR_2_LEN = 38 ;
-
-static const uint8_t EXPLR_MCBIST_MCBEA3Q_CFG_END_ADDR_3 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBEA3Q_CFG_END_ADDR_3_LEN = 38 ;
-
-static const uint8_t EXPLR_MCBIST_MCBFD0Q_CFG_FIXED_SEED = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBFD0Q_CFG_FIXED_SEED_LEN = 64 ;
-
-static const uint8_t EXPLR_MCBIST_MCBFD1Q_CFG_FIXED_SEED = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBFD1Q_CFG_FIXED_SEED_LEN = 64 ;
-
-static const uint8_t EXPLR_MCBIST_MCBFD2Q_CFG_FIXED_SEED = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBFD2Q_CFG_FIXED_SEED_LEN = 64 ;
-
-static const uint8_t EXPLR_MCBIST_MCBFD3Q_CFG_FIXED_SEED = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBFD3Q_CFG_FIXED_SEED_LEN = 64 ;
-
-static const uint8_t EXPLR_MCBIST_MCBFD4Q_CFG_FIXED_SEED = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBFD4Q_CFG_FIXED_SEED_LEN = 64 ;
-
-static const uint8_t EXPLR_MCBIST_MCBFD5Q_CFG_FIXED_SEED = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBFD5Q_CFG_FIXED_SEED_LEN = 64 ;
-
-static const uint8_t EXPLR_MCBIST_MCBFD6Q_CFG_FIXED_SEED = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBFD6Q_CFG_FIXED_SEED_LEN = 64 ;
-
-static const uint8_t EXPLR_MCBIST_MCBFD7Q_CFG_FIXED_SEED = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBFD7Q_CFG_FIXED_SEED_LEN = 64 ;
-
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED1 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED1_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED2 = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED2_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED3 = 16 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED3_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED4 = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED4_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED5 = 32 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED5_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED6 = 40 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED6_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED7 = 48 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED7_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED8 = 56 ;
-static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED8_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED1 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED1_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED2 = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED2_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED3 = 16 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED3_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED4 = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED4_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED5 = 32 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED5_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED6 = 40 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED6_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED7 = 48 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED7_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED8 = 56 ;
-static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED8_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_MCBISTFIRACT0_FIR_ACTION0 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRACT0_FIR_ACTION0_LEN = 20 ;
-
-static const uint8_t EXPLR_MCBIST_MCBISTFIRACT1_FIR_ACTION1 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRACT1_FIR_ACTION1_LEN = 20 ;
-
-static const uint8_t EXPLR_MCBIST_MCBISTFIRMASK_FIR_MASK = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRMASK_FIR_MASK_LEN = 20 ;
-
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_INVALID_MAINT_ADDRESS = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_COMMAND_ADDRESS_TIMEOUT = 1 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_INTERNAL_FSM_ERROR = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_CCS_ARRAY_UNCORRECT_CE_OR_UE = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_MCBIST_DATA_ERROR = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_HARD_NCE_ETE_ATTN = 5 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_SOFT_NCE_ETE_ATTN = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_INT_NCE_ETE_ATTN = 7 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_RCE_ETE_ATTN = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_ICE_ETE_ATTN = 9 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_MCBIST_PROGRAM_COMPLETE = 10 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_MCBIST_CCS_SUBTEST_DONE = 11 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_WAT_DEBUG_ATTN = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_SCOM_RECOVERABLE_REG_PE = 13 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_SCOM_FATAL_REG_PE = 14 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_WAT_DEBUG_REG_PE = 15 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_RESERVED_16 = 16 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_RESERVED_17 = 17 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_INTERNAL_SCOM_ERROR = 18 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_INTERNAL_SCOM_ERROR_CLONE = 19 ;
-
-static const uint8_t EXPLR_MCBIST_MCBISTFIRWOF_FIR_WOF = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBISTFIRWOF_FIR_WOF_LEN = 20 ;
-
-static const uint8_t EXPLR_MCBIST_MCBLFSRA0Q_CFG_LFSR_MASK_A0 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBLFSRA0Q_CFG_LFSR_MASK_A0_LEN = 38 ;
-static const uint8_t EXPLR_MCBIST_MCBLFSRA0Q_RESERVED_38_63 = 38 ;
-static const uint8_t EXPLR_MCBIST_MCBLFSRA0Q_RESERVED_38_63_LEN = 26 ;
-
-static const uint8_t EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_ADDR_TRAP = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_ADDR_TRAP_LEN = 38 ;
-static const uint8_t EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_PORT_TRAP = 38 ;
-static const uint8_t EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_PORT_TRAP_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_DIMM_TRAP = 40 ;
-
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_OP_TYPE = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_1ST_CMD = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_2ND_CMD = 5 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_3RD_CMD = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_REV_MODE = 7 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_RAND_MODE = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DATA_MODE = 9 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ECC_MODE = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DONE = 13 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_SEL = 14 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_OP_TYPE = 16 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_COMPL_1ST_CMD = 20 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_COMPL_2ND_CMD = 21 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_COMPL_3RD_CMD = 22 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_ADDR_REV_MODE = 23 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_ADDR_RAND_MODE = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_DATA_MODE = 25 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_ECC_MODE = 28 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_DONE = 29 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_ADDR_SEL = 30 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_OP_TYPE = 32 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_COMPL_1ST_CMD = 36 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_COMPL_2ND_CMD = 37 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_COMPL_3RD_CMD = 38 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_ADDR_REV_MODE = 39 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_ADDR_RAND_MODE = 40 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_DATA_MODE = 41 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_ECC_MODE = 44 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_DONE = 45 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_ADDR_SEL = 46 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_OP_TYPE = 48 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_COMPL_1ST_CMD = 52 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_COMPL_2ND_CMD = 53 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_COMPL_3RD_CMD = 54 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_ADDR_REV_MODE = 55 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_ADDR_RAND_MODE = 56 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_DATA_MODE = 57 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_ECC_MODE = 60 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_DONE = 61 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_ADDR_SEL = 62 ;
-static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_ADDR_SEL_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_OP_TYPE = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_COMPL_1ST_CMD = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_COMPL_2ND_CMD = 5 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_COMPL_3RD_CMD = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_ADDR_REV_MODE = 7 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_ADDR_RAND_MODE = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_DATA_MODE = 9 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_ECC_MODE = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_DONE = 13 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_ADDR_SEL = 14 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_OP_TYPE = 16 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_COMPL_1ST_CMD = 20 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_COMPL_2ND_CMD = 21 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_COMPL_3RD_CMD = 22 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_ADDR_REV_MODE = 23 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_ADDR_RAND_MODE = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_DATA_MODE = 25 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_ECC_MODE = 28 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_DONE = 29 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_ADDR_SEL = 30 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_OP_TYPE = 32 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_COMPL_1ST_CMD = 36 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_COMPL_2ND_CMD = 37 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_COMPL_3RD_CMD = 38 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_ADDR_REV_MODE = 39 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_ADDR_RAND_MODE = 40 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_DATA_MODE = 41 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_ECC_MODE = 44 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_DONE = 45 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_ADDR_SEL = 46 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_OP_TYPE = 48 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_COMPL_1ST_CMD = 52 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_COMPL_2ND_CMD = 53 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_COMPL_3RD_CMD = 54 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_ADDR_REV_MODE = 55 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_ADDR_RAND_MODE = 56 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_DATA_MODE = 57 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_ECC_MODE = 60 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_DONE = 61 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_ADDR_SEL = 62 ;
-static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_ADDR_SEL_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_OP_TYPE = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_COMPL_1ST_CMD = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_COMPL_2ND_CMD = 5 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_COMPL_3RD_CMD = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_ADDR_REV_MODE = 7 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_ADDR_RAND_MODE = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_DATA_MODE = 9 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_ECC_MODE = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_DONE = 13 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_ADDR_SEL = 14 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_OP_TYPE = 16 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_COMPL_1ST_CMD = 20 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_COMPL_2ND_CMD = 21 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_COMPL_3RD_CMD = 22 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_ADDR_REV_MODE = 23 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_ADDR_RAND_MODE = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_DATA_MODE = 25 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_ECC_MODE = 28 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_DONE = 29 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_ADDR_SEL = 30 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_OP_TYPE = 32 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_COMPL_1ST_CMD = 36 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_COMPL_2ND_CMD = 37 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_COMPL_3RD_CMD = 38 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_ADDR_REV_MODE = 39 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_ADDR_RAND_MODE = 40 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_DATA_MODE = 41 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_ECC_MODE = 44 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_DONE = 45 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_ADDR_SEL = 46 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_OP_TYPE = 48 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_COMPL_1ST_CMD = 52 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_COMPL_2ND_CMD = 53 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_COMPL_3RD_CMD = 54 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_ADDR_REV_MODE = 55 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_ADDR_RAND_MODE = 56 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_DATA_MODE = 57 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_ECC_MODE = 60 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_DONE = 61 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_ADDR_SEL = 62 ;
-static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_ADDR_SEL_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_OP_TYPE = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_COMPL_1ST_CMD = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_COMPL_2ND_CMD = 5 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_COMPL_3RD_CMD = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_ADDR_REV_MODE = 7 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_ADDR_RAND_MODE = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_DATA_MODE = 9 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_ECC_MODE = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_DONE = 13 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_ADDR_SEL = 14 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_OP_TYPE = 16 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_COMPL_1ST_CMD = 20 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_COMPL_2ND_CMD = 21 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_COMPL_3RD_CMD = 22 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_ADDR_REV_MODE = 23 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_ADDR_RAND_MODE = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_DATA_MODE = 25 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_ECC_MODE = 28 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_DONE = 29 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_ADDR_SEL = 30 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_OP_TYPE = 32 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_COMPL_1ST_CMD = 36 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_COMPL_2ND_CMD = 37 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_COMPL_3RD_CMD = 38 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_ADDR_REV_MODE = 39 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_ADDR_RAND_MODE = 40 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_DATA_MODE = 41 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_ECC_MODE = 44 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_DONE = 45 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_ADDR_SEL = 46 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_OP_TYPE = 48 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_COMPL_1ST_CMD = 52 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_COMPL_2ND_CMD = 53 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_COMPL_3RD_CMD = 54 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_ADDR_REV_MODE = 55 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_ADDR_RAND_MODE = 56 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_DATA_MODE = 57 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_ECC_MODE = 60 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_DONE = 61 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_ADDR_SEL = 62 ;
-static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_ADDR_SEL_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_OP_TYPE = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_COMPL_1ST_CMD = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_COMPL_2ND_CMD = 5 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_COMPL_3RD_CMD = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_ADDR_REV_MODE = 7 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_ADDR_RAND_MODE = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_DATA_MODE = 9 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_ECC_MODE = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_DONE = 13 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_ADDR_SEL = 14 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_OP_TYPE = 16 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_COMPL_1ST_CMD = 20 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_COMPL_2ND_CMD = 21 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_COMPL_3RD_CMD = 22 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_ADDR_REV_MODE = 23 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_ADDR_RAND_MODE = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_DATA_MODE = 25 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_ECC_MODE = 28 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_DONE = 29 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_ADDR_SEL = 30 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_OP_TYPE = 32 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_COMPL_1ST_CMD = 36 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_COMPL_2ND_CMD = 37 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_COMPL_3RD_CMD = 38 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_ADDR_REV_MODE = 39 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_ADDR_RAND_MODE = 40 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_DATA_MODE = 41 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_ECC_MODE = 44 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_DONE = 45 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_ADDR_SEL = 46 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_OP_TYPE = 48 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_COMPL_1ST_CMD = 52 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_COMPL_2ND_CMD = 53 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_COMPL_3RD_CMD = 54 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_ADDR_REV_MODE = 55 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_ADDR_RAND_MODE = 56 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_DATA_MODE = 57 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_ECC_MODE = 60 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_DONE = 61 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_ADDR_SEL = 62 ;
-static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_ADDR_SEL_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_OP_TYPE = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_COMPL_1ST_CMD = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_COMPL_2ND_CMD = 5 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_COMPL_3RD_CMD = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_ADDR_REV_MODE = 7 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_ADDR_RAND_MODE = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_DATA_MODE = 9 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_ECC_MODE = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_DONE = 13 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_ADDR_SEL = 14 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_OP_TYPE = 16 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_COMPL_1ST_CMD = 20 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_COMPL_2ND_CMD = 21 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_COMPL_3RD_CMD = 22 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_ADDR_REV_MODE = 23 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_ADDR_RAND_MODE = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_DATA_MODE = 25 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_ECC_MODE = 28 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_DONE = 29 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_ADDR_SEL = 30 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_OP_TYPE = 32 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_COMPL_1ST_CMD = 36 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_COMPL_2ND_CMD = 37 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_COMPL_3RD_CMD = 38 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_ADDR_REV_MODE = 39 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_ADDR_RAND_MODE = 40 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_DATA_MODE = 41 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_ECC_MODE = 44 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_DONE = 45 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_ADDR_SEL = 46 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_OP_TYPE = 48 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_COMPL_1ST_CMD = 52 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_COMPL_2ND_CMD = 53 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_COMPL_3RD_CMD = 54 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_ADDR_REV_MODE = 55 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_ADDR_RAND_MODE = 56 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_DATA_MODE = 57 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_ECC_MODE = 60 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_DONE = 61 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_ADDR_SEL = 62 ;
-static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_ADDR_SEL_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_OP_TYPE = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_COMPL_1ST_CMD = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_COMPL_2ND_CMD = 5 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_COMPL_3RD_CMD = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_ADDR_REV_MODE = 7 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_ADDR_RAND_MODE = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_DATA_MODE = 9 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_ECC_MODE = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_DONE = 13 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_ADDR_SEL = 14 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_OP_TYPE = 16 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_COMPL_1ST_CMD = 20 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_COMPL_2ND_CMD = 21 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_COMPL_3RD_CMD = 22 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_ADDR_REV_MODE = 23 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_ADDR_RAND_MODE = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_DATA_MODE = 25 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_ECC_MODE = 28 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_DONE = 29 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_ADDR_SEL = 30 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_OP_TYPE = 32 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_COMPL_1ST_CMD = 36 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_COMPL_2ND_CMD = 37 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_COMPL_3RD_CMD = 38 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_ADDR_REV_MODE = 39 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_ADDR_RAND_MODE = 40 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_DATA_MODE = 41 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_ECC_MODE = 44 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_DONE = 45 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_ADDR_SEL = 46 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_OP_TYPE = 48 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_COMPL_1ST_CMD = 52 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_COMPL_2ND_CMD = 53 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_COMPL_3RD_CMD = 54 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_ADDR_REV_MODE = 55 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_ADDR_RAND_MODE = 56 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_DATA_MODE = 57 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_ECC_MODE = 60 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_DONE = 61 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_ADDR_SEL = 62 ;
-static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_ADDR_SEL_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_OP_TYPE = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_COMPL_1ST_CMD = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_COMPL_2ND_CMD = 5 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_COMPL_3RD_CMD = 6 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_ADDR_REV_MODE = 7 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_ADDR_RAND_MODE = 8 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_DATA_MODE = 9 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_ECC_MODE = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_DONE = 13 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_ADDR_SEL = 14 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_OP_TYPE = 16 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_COMPL_1ST_CMD = 20 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_COMPL_2ND_CMD = 21 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_COMPL_3RD_CMD = 22 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_ADDR_REV_MODE = 23 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_ADDR_RAND_MODE = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_DATA_MODE = 25 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_ECC_MODE = 28 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_DONE = 29 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_ADDR_SEL = 30 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_OP_TYPE = 32 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_COMPL_1ST_CMD = 36 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_COMPL_2ND_CMD = 37 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_COMPL_3RD_CMD = 38 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_ADDR_REV_MODE = 39 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_ADDR_RAND_MODE = 40 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_DATA_MODE = 41 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_ECC_MODE = 44 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_DONE = 45 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_ADDR_SEL = 46 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_ADDR_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_OP_TYPE = 48 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_OP_TYPE_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_COMPL_1ST_CMD = 52 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_COMPL_2ND_CMD = 53 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_COMPL_3RD_CMD = 54 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_ADDR_REV_MODE = 55 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_ADDR_RAND_MODE = 56 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_DATA_MODE = 57 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_DATA_MODE_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_ECC_MODE = 60 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_DONE = 61 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_ADDR_SEL = 62 ;
-static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_ADDR_SEL_LEN = 2 ;
-
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_LEN = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_MIN_GAP_TIMEBASE = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_BLIND_STEER = 13 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_BLIND_STEER_LEN = 12 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_MIN_GAP_TIMEBASE_BLIND_STEER = 25 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_RESERVED_26_49 = 26 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_RESERVED_26_49_LEN = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_RANDCMD_WGT = 50 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_RANDCMD_WGT_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_RESERVED_53_59 = 53 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_RESERVED_53_59_LEN = 7 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_EN_RANDCMD_GAP = 60 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_RANDGAP_WGT = 61 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_RANDGAP_WGT_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_BC4_EN = 63 ;
-
-static const uint8_t EXPLR_MCBIST_MCBRCRQ_RESERVED_0_31 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBRCRQ_RESERVED_0_31_LEN = 32 ;
-static const uint8_t EXPLR_MCBIST_MCBRCRQ_CFG_RUNTIME_MCBALL = 32 ;
-static const uint8_t EXPLR_MCBIST_MCBRCRQ_CFG_RUNTIME_SUBTEST = 33 ;
-static const uint8_t EXPLR_MCBIST_MCBRCRQ_CFG_RUNTIME_SUBTEST_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MCBRCRQ_CFG_RUNTIME_OVERHEAD = 38 ;
-static const uint8_t EXPLR_MCBIST_MCBRCRQ_RESERVED_39 = 39 ;
-
-static const uint8_t EXPLR_MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0_LEN = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1 = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1_LEN = 24 ;
-
-static const uint8_t EXPLR_MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2_LEN = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING = 24 ;
-static const uint8_t EXPLR_MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING_LEN = 40 ;
-
-static const uint8_t EXPLR_MCBIST_MCBSA0Q_CFG_START_ADDR_0 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBSA0Q_CFG_START_ADDR_0_LEN = 38 ;
-
-static const uint8_t EXPLR_MCBIST_MCBSA1Q_CFG_START_ADDR_1 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBSA1Q_CFG_START_ADDR_1_LEN = 38 ;
-
-static const uint8_t EXPLR_MCBIST_MCBSA2Q_CFG_START_ADDR_2 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBSA2Q_CFG_START_ADDR_2_LEN = 38 ;
-
-static const uint8_t EXPLR_MCBIST_MCBSA3Q_CFG_START_ADDR_3 = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBSA3Q_CFG_START_ADDR_3_LEN = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_RESERVED_62_63 = 62 ;
+static const uint8_t EXPLR_MCBIST_MCBCFGQ_RESERVED_62_63_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_ROT = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_ROT_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_ROT_SEED = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_ROT_SEED_LEN = 16 ;
+static const uint8_t EXPLR_MCBIST_MCBDRCRQ_RESERVED_20 = 20 ;
+static const uint8_t EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_SEED_MODE = 21 ;
+static const uint8_t EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_SEED_MODE_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBDRCRQ_RESERVED_23_63 = 23 ;
+static const uint8_t EXPLR_MCBIST_MCBDRCRQ_RESERVED_23_63_LEN = 41 ;
+
+static const uint8_t EXPLR_MCBIST_MCBDRSRQ_CFG_DATA_ROT_SEED = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBDRSRQ_CFG_DATA_ROT_SEED_LEN = 64 ;
+
+static const uint8_t EXPLR_MCBIST_MCBEA0Q_CFG_END_ADDR_0 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBEA0Q_CFG_END_ADDR_0_LEN = 38 ;
+
+static const uint8_t EXPLR_MCBIST_MCBEA1Q_CFG_END_ADDR_1 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBEA1Q_CFG_END_ADDR_1_LEN = 38 ;
+
+static const uint8_t EXPLR_MCBIST_MCBEA2Q_CFG_END_ADDR_2 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBEA2Q_CFG_END_ADDR_2_LEN = 38 ;
+
+static const uint8_t EXPLR_MCBIST_MCBEA3Q_CFG_END_ADDR_3 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBEA3Q_CFG_END_ADDR_3_LEN = 38 ;
+
+static const uint8_t EXPLR_MCBIST_MCBFD0Q_CFG_FIXED_SEED = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBFD0Q_CFG_FIXED_SEED_LEN = 64 ;
+
+static const uint8_t EXPLR_MCBIST_MCBFD1Q_CFG_FIXED_SEED = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBFD1Q_CFG_FIXED_SEED_LEN = 64 ;
+
+static const uint8_t EXPLR_MCBIST_MCBFD2Q_CFG_FIXED_SEED = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBFD2Q_CFG_FIXED_SEED_LEN = 64 ;
+
+static const uint8_t EXPLR_MCBIST_MCBFD3Q_CFG_FIXED_SEED = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBFD3Q_CFG_FIXED_SEED_LEN = 64 ;
+
+static const uint8_t EXPLR_MCBIST_MCBFD4Q_CFG_FIXED_SEED = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBFD4Q_CFG_FIXED_SEED_LEN = 64 ;
+
+static const uint8_t EXPLR_MCBIST_MCBFD5Q_CFG_FIXED_SEED = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBFD5Q_CFG_FIXED_SEED_LEN = 64 ;
+
+static const uint8_t EXPLR_MCBIST_MCBFD6Q_CFG_FIXED_SEED = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBFD6Q_CFG_FIXED_SEED_LEN = 64 ;
+
+static const uint8_t EXPLR_MCBIST_MCBFD7Q_CFG_FIXED_SEED = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBFD7Q_CFG_FIXED_SEED_LEN = 64 ;
+
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED1 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED1_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED2 = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED2_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED3 = 16 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED3_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED4 = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED4_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED5 = 32 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED5_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED6 = 40 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED6_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED7 = 48 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED7_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED8 = 56 ;
+static const uint8_t EXPLR_MCBIST_MCBFDQ_CFG_FIXED_SEED8_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED1 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED1_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED2 = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED2_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED3 = 16 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED3_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED4 = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED4_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED5 = 32 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED5_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED6 = 40 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED6_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED7 = 48 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED7_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED8 = 56 ;
+static const uint8_t EXPLR_MCBIST_MCBFDSPQ_CFG_FIXED_SEED8_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_MCBISTFIRACT0_FIR_ACTION0 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRACT0_FIR_ACTION0_LEN = 20 ;
+
+static const uint8_t EXPLR_MCBIST_MCBISTFIRACT1_FIR_ACTION1 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRACT1_FIR_ACTION1_LEN = 20 ;
+
+static const uint8_t EXPLR_MCBIST_MCBISTFIRMASK_FIR_MASK = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRMASK_FIR_MASK_LEN = 20 ;
+
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_INVALID_MAINT_ADDRESS = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_COMMAND_ADDRESS_TIMEOUT = 1 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_INTERNAL_FSM_ERROR = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_CCS_ARRAY_UNCORRECT_CE_OR_UE = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_MCBIST_DATA_ERROR = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_HARD_NCE_ETE_ATTN = 5 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_SOFT_NCE_ETE_ATTN = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_INT_NCE_ETE_ATTN = 7 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_RCE_ETE_ATTN = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_ICE_ETE_ATTN = 9 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_MCBIST_PROGRAM_COMPLETE = 10 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_MCBIST_CCS_SUBTEST_DONE = 11 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_WAT_DEBUG_ATTN = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_SCOM_RECOVERABLE_REG_PE = 13 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_SCOM_FATAL_REG_PE = 14 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_WAT_DEBUG_REG_PE = 15 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_RESERVED_16 = 16 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_RESERVED_17 = 17 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_INTERNAL_SCOM_ERROR = 18 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRQ_INTERNAL_SCOM_ERROR_CLONE = 19 ;
+
+static const uint8_t EXPLR_MCBIST_MCBISTFIRWOF_FIR_WOF = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBISTFIRWOF_FIR_WOF_LEN = 20 ;
+
+static const uint8_t EXPLR_MCBIST_MCBLFSRA0Q_CFG_LFSR_MASK_A0 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBLFSRA0Q_CFG_LFSR_MASK_A0_LEN = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBLFSRA0Q_RESERVED_38_63 = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBLFSRA0Q_RESERVED_38_63_LEN = 26 ;
+
+static const uint8_t EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_ADDR_TRAP = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_ADDR_TRAP_LEN = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_PORT_TRAP = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_PORT_TRAP_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_DIMM_TRAP = 40 ;
+
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_OP_TYPE = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_1ST_CMD = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_2ND_CMD = 5 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_3RD_CMD = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_REV_MODE = 7 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_RAND_MODE = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DATA_MODE = 9 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ECC_MODE = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DONE = 13 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_SEL = 14 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_OP_TYPE = 16 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_COMPL_1ST_CMD = 20 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_COMPL_2ND_CMD = 21 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_COMPL_3RD_CMD = 22 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_ADDR_REV_MODE = 23 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_ADDR_RAND_MODE = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_DATA_MODE = 25 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_ECC_MODE = 28 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_DONE = 29 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_ADDR_SEL = 30 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST01_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_OP_TYPE = 32 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_COMPL_1ST_CMD = 36 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_COMPL_2ND_CMD = 37 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_COMPL_3RD_CMD = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_ADDR_REV_MODE = 39 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_ADDR_RAND_MODE = 40 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_DATA_MODE = 41 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_ECC_MODE = 44 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_DONE = 45 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_ADDR_SEL = 46 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST02_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_OP_TYPE = 48 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_COMPL_1ST_CMD = 52 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_COMPL_2ND_CMD = 53 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_COMPL_3RD_CMD = 54 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_ADDR_REV_MODE = 55 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_ADDR_RAND_MODE = 56 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_DATA_MODE = 57 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_ECC_MODE = 60 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_DONE = 61 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_ADDR_SEL = 62 ;
+static const uint8_t EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST03_ADDR_SEL_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_OP_TYPE = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_COMPL_1ST_CMD = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_COMPL_2ND_CMD = 5 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_COMPL_3RD_CMD = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_ADDR_REV_MODE = 7 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_ADDR_RAND_MODE = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_DATA_MODE = 9 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_ECC_MODE = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_DONE = 13 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_ADDR_SEL = 14 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST04_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_OP_TYPE = 16 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_COMPL_1ST_CMD = 20 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_COMPL_2ND_CMD = 21 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_COMPL_3RD_CMD = 22 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_ADDR_REV_MODE = 23 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_ADDR_RAND_MODE = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_DATA_MODE = 25 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_ECC_MODE = 28 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_DONE = 29 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_ADDR_SEL = 30 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST05_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_OP_TYPE = 32 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_COMPL_1ST_CMD = 36 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_COMPL_2ND_CMD = 37 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_COMPL_3RD_CMD = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_ADDR_REV_MODE = 39 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_ADDR_RAND_MODE = 40 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_DATA_MODE = 41 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_ECC_MODE = 44 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_DONE = 45 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_ADDR_SEL = 46 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST06_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_OP_TYPE = 48 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_COMPL_1ST_CMD = 52 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_COMPL_2ND_CMD = 53 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_COMPL_3RD_CMD = 54 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_ADDR_REV_MODE = 55 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_ADDR_RAND_MODE = 56 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_DATA_MODE = 57 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_ECC_MODE = 60 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_DONE = 61 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_ADDR_SEL = 62 ;
+static const uint8_t EXPLR_MCBIST_MCBMR1Q_MCBIST_CFG_TEST07_ADDR_SEL_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_OP_TYPE = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_COMPL_1ST_CMD = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_COMPL_2ND_CMD = 5 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_COMPL_3RD_CMD = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_ADDR_REV_MODE = 7 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_ADDR_RAND_MODE = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_DATA_MODE = 9 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_ECC_MODE = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_DONE = 13 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_ADDR_SEL = 14 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST08_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_OP_TYPE = 16 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_COMPL_1ST_CMD = 20 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_COMPL_2ND_CMD = 21 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_COMPL_3RD_CMD = 22 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_ADDR_REV_MODE = 23 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_ADDR_RAND_MODE = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_DATA_MODE = 25 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_ECC_MODE = 28 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_DONE = 29 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_ADDR_SEL = 30 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST09_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_OP_TYPE = 32 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_COMPL_1ST_CMD = 36 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_COMPL_2ND_CMD = 37 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_COMPL_3RD_CMD = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_ADDR_REV_MODE = 39 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_ADDR_RAND_MODE = 40 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_DATA_MODE = 41 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_ECC_MODE = 44 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_DONE = 45 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_ADDR_SEL = 46 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST10_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_OP_TYPE = 48 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_COMPL_1ST_CMD = 52 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_COMPL_2ND_CMD = 53 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_COMPL_3RD_CMD = 54 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_ADDR_REV_MODE = 55 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_ADDR_RAND_MODE = 56 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_DATA_MODE = 57 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_ECC_MODE = 60 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_DONE = 61 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_ADDR_SEL = 62 ;
+static const uint8_t EXPLR_MCBIST_MCBMR2Q_MCBIST_CFG_TEST11_ADDR_SEL_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_OP_TYPE = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_COMPL_1ST_CMD = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_COMPL_2ND_CMD = 5 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_COMPL_3RD_CMD = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_ADDR_REV_MODE = 7 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_ADDR_RAND_MODE = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_DATA_MODE = 9 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_ECC_MODE = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_DONE = 13 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_ADDR_SEL = 14 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST12_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_OP_TYPE = 16 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_COMPL_1ST_CMD = 20 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_COMPL_2ND_CMD = 21 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_COMPL_3RD_CMD = 22 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_ADDR_REV_MODE = 23 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_ADDR_RAND_MODE = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_DATA_MODE = 25 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_ECC_MODE = 28 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_DONE = 29 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_ADDR_SEL = 30 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST13_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_OP_TYPE = 32 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_COMPL_1ST_CMD = 36 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_COMPL_2ND_CMD = 37 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_COMPL_3RD_CMD = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_ADDR_REV_MODE = 39 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_ADDR_RAND_MODE = 40 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_DATA_MODE = 41 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_ECC_MODE = 44 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_DONE = 45 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_ADDR_SEL = 46 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST14_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_OP_TYPE = 48 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_COMPL_1ST_CMD = 52 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_COMPL_2ND_CMD = 53 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_COMPL_3RD_CMD = 54 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_ADDR_REV_MODE = 55 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_ADDR_RAND_MODE = 56 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_DATA_MODE = 57 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_ECC_MODE = 60 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_DONE = 61 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_ADDR_SEL = 62 ;
+static const uint8_t EXPLR_MCBIST_MCBMR3Q_MCBIST_CFG_TEST15_ADDR_SEL_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_OP_TYPE = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_COMPL_1ST_CMD = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_COMPL_2ND_CMD = 5 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_COMPL_3RD_CMD = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_ADDR_REV_MODE = 7 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_ADDR_RAND_MODE = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_DATA_MODE = 9 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_ECC_MODE = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_DONE = 13 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_ADDR_SEL = 14 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST16_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_OP_TYPE = 16 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_COMPL_1ST_CMD = 20 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_COMPL_2ND_CMD = 21 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_COMPL_3RD_CMD = 22 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_ADDR_REV_MODE = 23 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_ADDR_RAND_MODE = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_DATA_MODE = 25 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_ECC_MODE = 28 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_DONE = 29 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_ADDR_SEL = 30 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST17_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_OP_TYPE = 32 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_COMPL_1ST_CMD = 36 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_COMPL_2ND_CMD = 37 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_COMPL_3RD_CMD = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_ADDR_REV_MODE = 39 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_ADDR_RAND_MODE = 40 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_DATA_MODE = 41 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_ECC_MODE = 44 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_DONE = 45 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_ADDR_SEL = 46 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST18_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_OP_TYPE = 48 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_COMPL_1ST_CMD = 52 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_COMPL_2ND_CMD = 53 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_COMPL_3RD_CMD = 54 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_ADDR_REV_MODE = 55 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_ADDR_RAND_MODE = 56 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_DATA_MODE = 57 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_ECC_MODE = 60 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_DONE = 61 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_ADDR_SEL = 62 ;
+static const uint8_t EXPLR_MCBIST_MCBMR4Q_MCBIST_CFG_TEST19_ADDR_SEL_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_OP_TYPE = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_COMPL_1ST_CMD = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_COMPL_2ND_CMD = 5 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_COMPL_3RD_CMD = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_ADDR_REV_MODE = 7 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_ADDR_RAND_MODE = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_DATA_MODE = 9 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_ECC_MODE = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_DONE = 13 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_ADDR_SEL = 14 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST20_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_OP_TYPE = 16 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_COMPL_1ST_CMD = 20 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_COMPL_2ND_CMD = 21 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_COMPL_3RD_CMD = 22 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_ADDR_REV_MODE = 23 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_ADDR_RAND_MODE = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_DATA_MODE = 25 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_ECC_MODE = 28 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_DONE = 29 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_ADDR_SEL = 30 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST21_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_OP_TYPE = 32 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_COMPL_1ST_CMD = 36 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_COMPL_2ND_CMD = 37 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_COMPL_3RD_CMD = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_ADDR_REV_MODE = 39 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_ADDR_RAND_MODE = 40 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_DATA_MODE = 41 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_ECC_MODE = 44 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_DONE = 45 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_ADDR_SEL = 46 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST22_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_OP_TYPE = 48 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_COMPL_1ST_CMD = 52 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_COMPL_2ND_CMD = 53 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_COMPL_3RD_CMD = 54 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_ADDR_REV_MODE = 55 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_ADDR_RAND_MODE = 56 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_DATA_MODE = 57 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_ECC_MODE = 60 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_DONE = 61 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_ADDR_SEL = 62 ;
+static const uint8_t EXPLR_MCBIST_MCBMR5Q_MCBIST_CFG_TEST23_ADDR_SEL_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_OP_TYPE = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_COMPL_1ST_CMD = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_COMPL_2ND_CMD = 5 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_COMPL_3RD_CMD = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_ADDR_REV_MODE = 7 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_ADDR_RAND_MODE = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_DATA_MODE = 9 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_ECC_MODE = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_DONE = 13 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_ADDR_SEL = 14 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST24_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_OP_TYPE = 16 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_COMPL_1ST_CMD = 20 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_COMPL_2ND_CMD = 21 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_COMPL_3RD_CMD = 22 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_ADDR_REV_MODE = 23 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_ADDR_RAND_MODE = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_DATA_MODE = 25 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_ECC_MODE = 28 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_DONE = 29 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_ADDR_SEL = 30 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST25_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_OP_TYPE = 32 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_COMPL_1ST_CMD = 36 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_COMPL_2ND_CMD = 37 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_COMPL_3RD_CMD = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_ADDR_REV_MODE = 39 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_ADDR_RAND_MODE = 40 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_DATA_MODE = 41 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_ECC_MODE = 44 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_DONE = 45 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_ADDR_SEL = 46 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST26_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_OP_TYPE = 48 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_COMPL_1ST_CMD = 52 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_COMPL_2ND_CMD = 53 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_COMPL_3RD_CMD = 54 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_ADDR_REV_MODE = 55 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_ADDR_RAND_MODE = 56 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_DATA_MODE = 57 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_ECC_MODE = 60 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_DONE = 61 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_ADDR_SEL = 62 ;
+static const uint8_t EXPLR_MCBIST_MCBMR6Q_MCBIST_CFG_TEST27_ADDR_SEL_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_OP_TYPE = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_COMPL_1ST_CMD = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_COMPL_2ND_CMD = 5 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_COMPL_3RD_CMD = 6 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_ADDR_REV_MODE = 7 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_ADDR_RAND_MODE = 8 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_DATA_MODE = 9 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_ECC_MODE = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_DONE = 13 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_ADDR_SEL = 14 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST28_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_OP_TYPE = 16 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_COMPL_1ST_CMD = 20 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_COMPL_2ND_CMD = 21 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_COMPL_3RD_CMD = 22 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_ADDR_REV_MODE = 23 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_ADDR_RAND_MODE = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_DATA_MODE = 25 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_ECC_MODE = 28 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_DONE = 29 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_ADDR_SEL = 30 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST29_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_OP_TYPE = 32 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_COMPL_1ST_CMD = 36 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_COMPL_2ND_CMD = 37 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_COMPL_3RD_CMD = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_ADDR_REV_MODE = 39 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_ADDR_RAND_MODE = 40 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_DATA_MODE = 41 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_ECC_MODE = 44 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_DONE = 45 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_ADDR_SEL = 46 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST30_ADDR_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_OP_TYPE = 48 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_OP_TYPE_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_COMPL_1ST_CMD = 52 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_COMPL_2ND_CMD = 53 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_COMPL_3RD_CMD = 54 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_ADDR_REV_MODE = 55 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_ADDR_RAND_MODE = 56 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_DATA_MODE = 57 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_DATA_MODE_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_ECC_MODE = 60 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_DONE = 61 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_ADDR_SEL = 62 ;
+static const uint8_t EXPLR_MCBIST_MCBMR7Q_MCBIST_CFG_TEST31_ADDR_SEL_LEN = 2 ;
+
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_LEN = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_MIN_GAP_TIMEBASE = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_BLIND_STEER = 13 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_BLIND_STEER_LEN = 12 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_MIN_GAP_TIMEBASE_BLIND_STEER = 25 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_RESERVED_26_49 = 26 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_RESERVED_26_49_LEN = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_RANDCMD_WGT = 50 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_RANDCMD_WGT_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_RESERVED_53_59 = 53 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_RESERVED_53_59_LEN = 7 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_EN_RANDCMD_GAP = 60 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_RANDGAP_WGT = 61 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_RANDGAP_WGT_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_MCBPARMQ_CFG_BC4_EN = 63 ;
+
+static const uint8_t EXPLR_MCBIST_MCBRCRQ_RESERVED_0_31 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBRCRQ_RESERVED_0_31_LEN = 32 ;
+static const uint8_t EXPLR_MCBIST_MCBRCRQ_CFG_RUNTIME_MCBALL = 32 ;
+static const uint8_t EXPLR_MCBIST_MCBRCRQ_CFG_RUNTIME_SUBTEST = 33 ;
+static const uint8_t EXPLR_MCBIST_MCBRCRQ_CFG_RUNTIME_SUBTEST_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MCBRCRQ_CFG_RUNTIME_OVERHEAD = 38 ;
+static const uint8_t EXPLR_MCBIST_MCBRCRQ_RESERVED_39 = 39 ;
+
+static const uint8_t EXPLR_MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0_LEN = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1 = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1_LEN = 24 ;
+
+static const uint8_t EXPLR_MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2_LEN = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING = 24 ;
+static const uint8_t EXPLR_MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING_LEN = 40 ;
+
+static const uint8_t EXPLR_MCBIST_MCBSA0Q_CFG_START_ADDR_0 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBSA0Q_CFG_START_ADDR_0_LEN = 38 ;
+
+static const uint8_t EXPLR_MCBIST_MCBSA1Q_CFG_START_ADDR_1 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBSA1Q_CFG_START_ADDR_1_LEN = 38 ;
+
+static const uint8_t EXPLR_MCBIST_MCBSA2Q_CFG_START_ADDR_2 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBSA2Q_CFG_START_ADDR_2_LEN = 38 ;
+
+static const uint8_t EXPLR_MCBIST_MCBSA3Q_CFG_START_ADDR_3 = 0 ;
+static const uint8_t EXPLR_MCBIST_MCBSA3Q_CFG_START_ADDR_3_LEN = 38 ;
static const uint8_t EXPLR_MCBIST_MCBSTATQ_MCBIST_LOGGED_ERROR_ON_PORT_INDICATOR = 0 ;
-static const uint8_t EXPLR_MCBIST_MCBSTATQ_RESERVED_1_3 = 1 ;
-static const uint8_t EXPLR_MCBIST_MCBSTATQ_RESERVED_1_3_LEN = 3 ;
-static const uint8_t EXPLR_MCBIST_MCBSTATQ_MCBIST_SUBTEST_NUM_INDICATOR = 4 ;
-static const uint8_t EXPLR_MCBIST_MCBSTATQ_MCBIST_SUBTEST_NUM_INDICATOR_LEN = 5 ;
-static const uint8_t EXPLR_MCBIST_MCBSTATQ_RESERVED_9_15 = 9 ;
-static const uint8_t EXPLR_MCBIST_MCBSTATQ_RESERVED_9_15_LEN = 7 ;
-
-static const uint8_t EXPLR_MCBIST_MCB_CNTLQ_START = 0 ;
-static const uint8_t EXPLR_MCBIST_MCB_CNTLQ_STOP = 1 ;
-static const uint8_t EXPLR_MCBIST_MCB_CNTLQ_RESERVED_2_5 = 2 ;
-static const uint8_t EXPLR_MCBIST_MCB_CNTLQ_RESERVED_2_5_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_MCB_CNTLQ_RESET_TRAP_CNFG = 6 ;
-static const uint8_t EXPLR_MCBIST_MCB_CNTLQ_RESET_ERROR_LOGS = 7 ;
-static const uint8_t EXPLR_MCBIST_MCB_CNTLQ_RESUME_FROM_PAUSE = 8 ;
-
-static const uint8_t EXPLR_MCBIST_MCB_CNTLSTATQ_IP = 0 ;
-static const uint8_t EXPLR_MCBIST_MCB_CNTLSTATQ_DONE = 1 ;
-static const uint8_t EXPLR_MCBIST_MCB_CNTLSTATQ_FAIL = 2 ;
-
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM = 0 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD1 = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD1_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD2 = 8 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD2_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD3 = 12 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD3_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD4 = 16 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD4_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD5 = 20 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD5_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD6 = 24 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD6_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD7 = 28 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD7_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD8 = 32 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD8_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD9 = 36 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD9_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD10 = 40 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD10_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD11 = 44 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD11_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD12 = 48 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD12_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD13 = 52 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD13_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD14 = 56 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD14_LEN = 4 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD15 = 60 ;
-static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD15_LEN = 4 ;
-
-static const uint8_t EXPLR_MCBIST_RUNTIMECTRQ_CFG_RUNTIME_CTR = 0 ;
-static const uint8_t EXPLR_MCBIST_RUNTIMECTRQ_CFG_RUNTIME_CTR_LEN = 37 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_ASEL = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_ASEL_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_BSEL = 8 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_BSEL_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_ABSEL = 16 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_ABSEL_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_ETSEL = 24 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_ETSEL_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_CMSEL = 32 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_CMSEL_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_CYSEL = 40 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_CYSEL_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_WAT_MSKA = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_WAT_MSKA_LEN = 44 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_WAT_ENABLE = 44 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_INT_ARM_MODE = 45 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_EXT_ARM_MODE = 46 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_TIMER_STATE_MODE = 47 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_SET_LEVEL_ON_PULSE = 48 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_RESET_LEVEL_ON_PULSE = 49 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_ENABLE_EXT_RESET_LEVEL = 50 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_STATE_SET_DOM = 51 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_STATE_FOLLOW_LEVEL = 52 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_NOT_PATA_MODE = 53 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_NOT_PATB_MODE = 54 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_NOT_PATA_MODE2 = 55 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_NOT_PATB_MODE2 = 56 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_SLIDE_TRIG = 57 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_TRIGB_DELAY_SEL = 58 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_TRIGB_DELAY_SEL_LEN = 2 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_FORCE_TEST_MODE = 60 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG0CQ_CFG_WAT_MSKB = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0CQ_CFG_WAT_MSKB_LEN = 44 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG0DQ_CFG_WAT_PATA = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0DQ_CFG_WAT_PATA_LEN = 44 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG0EQ_CFG_WAT_PATB = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG0EQ_CFG_WAT_PATB_LEN = 44 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_ASEL = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_ASEL_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_BSEL = 8 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_BSEL_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_ABSEL = 16 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_ABSEL_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_ETSEL = 24 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_ETSEL_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_CMSEL = 32 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_CMSEL_LEN = 8 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_CYSEL = 40 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_CYSEL_LEN = 8 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG1BQ_CFG_WAT_MSKA = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1BQ_CFG_WAT_MSKA_LEN = 44 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1BQ_CFG_WAT_CNTL = 44 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1BQ_CFG_WAT_CNTL_LEN = 17 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG1CQ_CFG_WAT_MSKB = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1CQ_CFG_WAT_MSKB_LEN = 44 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG1DQ_CFG_WAT_PATA = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1DQ_CFG_WAT_PATA_LEN = 44 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG1EQ_CFG_WAT_PATB = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG1EQ_CFG_WAT_PATB_LEN = 44 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG2AQ_CFG_WAT_EVENT_SEL = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG2AQ_CFG_WAT_EVENT_SEL_LEN = 48 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG2BQ_CFG_WAT_MSKA = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG2BQ_CFG_WAT_MSKA_LEN = 44 ;
-static const uint8_t EXPLR_MCBIST_WATCFG2BQ_CFG_WAT_CNTL = 44 ;
-static const uint8_t EXPLR_MCBIST_WATCFG2BQ_CFG_WAT_CNTL_LEN = 17 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG2CQ_CFG_WAT_MSKB = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG2CQ_CFG_WAT_MSKB_LEN = 44 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG2DQ_CFG_WAT_PATA = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG2DQ_CFG_WAT_PATA_LEN = 44 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG2EQ_CFG_WAT_PATB = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG2EQ_CFG_WAT_PATB_LEN = 44 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG3AQ_CFG_WAT_EVENT_SEL = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG3AQ_CFG_WAT_EVENT_SEL_LEN = 48 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG3BQ_CFG_WAT_MSKA = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG3BQ_CFG_WAT_MSKA_LEN = 44 ;
-static const uint8_t EXPLR_MCBIST_WATCFG3BQ_CFG_WAT_CNTL = 44 ;
-static const uint8_t EXPLR_MCBIST_WATCFG3BQ_CFG_WAT_CNTL_LEN = 17 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG3CQ_CFG_WAT_MSKB = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG3CQ_CFG_WAT_MSKB_LEN = 44 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG3DQ_CFG_WAT_PATA = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG3DQ_CFG_WAT_PATA_LEN = 44 ;
-
-static const uint8_t EXPLR_MCBIST_WATCFG3EQ_CFG_WAT_PATB = 0 ;
-static const uint8_t EXPLR_MCBIST_WATCFG3EQ_CFG_WAT_PATB_LEN = 44 ;
-
-static const uint8_t EXPLR_MMIO_MCFGERR_RESP_CODE = 16 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_RESP_CODE_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_BDI = 20 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_ERROR_TYPE = 21 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_ERROR_TYPE_LEN = 3 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_DEVICE = 24 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_DEVICE_LEN = 5 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_FUNCTION = 29 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_FUNCTION_LEN = 3 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_DEV_FUNC_MISMATCH = 32 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_DETECT_BAD_OP = 33 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_TBIT_IS_1 = 34 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_DATA_IS_BAD = 35 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_PL_IS_INVALID = 36 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_BAD_OP_OR_ALIGN = 37 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_ADDR_NO_IMPLEMENTED = 38 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_RDATA_VLD = 39 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_TBIT = 40 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_PLEN = 41 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_PLEN_LEN = 3 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_PORTNUM = 44 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_PORTNUM_LEN = 2 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_DL = 46 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_DL_LEN = 2 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_CAPPTAG = 48 ;
-static const uint8_t EXPLR_MMIO_MCFGERR_CAPPTAG_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_MCFGERRA_ADDR = 0 ;
-static const uint8_t EXPLR_MMIO_MCFGERRA_ADDR_LEN = 64 ;
-
-static const uint8_t EXPLR_MMIO_MCHOLD_FIR_MASK_PAR_ERR = 0 ;
-static const uint8_t EXPLR_MMIO_MCHOLD_FIR_ACTION0_PAR_ERR = 1 ;
-static const uint8_t EXPLR_MMIO_MCHOLD_FIR_ACTION1_PAR_ERR = 2 ;
-
-static const uint8_t EXPLR_MMIO_MCMASK_MASK_FIR_MASK_PAR_ERR = 0 ;
-static const uint8_t EXPLR_MMIO_MCMASK_MASK_FIR_ACTION0_PAR_ERR = 1 ;
-static const uint8_t EXPLR_MMIO_MCMASK_MASK_FIR_ACTION1_PAR_ERR = 2 ;
-
-static const uint8_t EXPLR_MMIO_MDBELL_MDBELL = 0 ;
-
-static const uint8_t EXPLR_MMIO_MDBELLC_MDBELL_MDBELL = 0 ;
-
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGBUS_64_87 = 0 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGBUS_64_87_LEN = 24 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_SPARE = 24 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_SPARE_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL7 = 32 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL7_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL6 = 36 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL6_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL5 = 40 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL5_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL4 = 44 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL4_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL3 = 48 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL3_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL2 = 52 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL2_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL1 = 56 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL1_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL0 = 60 ;
-static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL0_LEN = 4 ;
-
-static const uint8_t EXPLR_MMIO_MDEBUG1_DBGBUS_0_63 = 0 ;
-static const uint8_t EXPLR_MMIO_MDEBUG1_DBGBUS_0_63_LEN = 64 ;
-
-static const uint8_t EXPLR_MMIO_MENTERP_MMIO_ENTERPRISE_MODE = 0 ;
-static const uint8_t EXPLR_MMIO_MENTERP_HALF_DIMM_MODE = 1 ;
-static const uint8_t EXPLR_MMIO_MENTERP_CFG_ENTERPRISE_MODE = 2 ;
-
-static const uint8_t EXPLR_MMIO_MERRCTL_MODE_BITS = 0 ;
-static const uint8_t EXPLR_MMIO_MERRCTL_MODE_BITS_LEN = 44 ;
-static const uint8_t EXPLR_MMIO_MERRCTL_MODE_BITS_44_46 = 44 ;
-static const uint8_t EXPLR_MMIO_MERRCTL_MODE_BITS_44_46_LEN = 3 ;
-static const uint8_t EXPLR_MMIO_MERRCTL_PASID_CHK_DIS = 47 ;
-static const uint8_t EXPLR_MMIO_MERRCTL_ACTAG_CHK_DIS = 48 ;
-static const uint8_t EXPLR_MMIO_MERRCTL_MSCC_RNGE_CHK_DIS = 49 ;
-static const uint8_t EXPLR_MMIO_MERRCTL_MODE_BIT_50 = 50 ;
-static const uint8_t EXPLR_MMIO_MERRCTL_HOLD_ACUM = 51 ;
-static const uint8_t EXPLR_MMIO_MERRCTL_SNSC_MASTER_ENABLE = 52 ;
-static const uint8_t EXPLR_MMIO_MERRCTL_TRAP_CLEAR = 53 ;
-static const uint8_t EXPLR_MMIO_MERRCTL_WDATA_P = 54 ;
-static const uint8_t EXPLR_MMIO_MERRCTL_RNW = 55 ;
-static const uint8_t EXPLR_MMIO_MERRCTL_ADDR = 56 ;
-static const uint8_t EXPLR_MMIO_MERRCTL_ADDR_LEN = 8 ;
-
-static const uint8_t EXPLR_MMIO_MFIR_AFU_DESC_UNIMP = 0 ;
-static const uint8_t EXPLR_MMIO_MFIR_MMIO_ERR = 1 ;
-static const uint8_t EXPLR_MMIO_MFIR_SCOM_ERR = 2 ;
-static const uint8_t EXPLR_MMIO_MFIR_FSM_PERR = 3 ;
-static const uint8_t EXPLR_MMIO_MFIR_FIFO_OVERFLOW = 4 ;
-static const uint8_t EXPLR_MMIO_MFIR_CTL_REG_PERR = 5 ;
-static const uint8_t EXPLR_MMIO_MFIR_INFO_REG_PERR = 6 ;
-static const uint8_t EXPLR_MMIO_MFIR_SNSC_BOTH_STARTS_ERR = 7 ;
-static const uint8_t EXPLR_MMIO_MFIR_SNSC_MULT_SEQ_PERR = 8 ;
-static const uint8_t EXPLR_MMIO_MFIR_SNSC_FSM_PERR = 9 ;
-static const uint8_t EXPLR_MMIO_MFIR_SNSC_REG_PERR = 10 ;
-static const uint8_t EXPLR_MMIO_MFIR_ACTAG_PASID_CFG_ERR = 11 ;
-
-static const uint8_t EXPLR_MMIO_MFIRACT0_FIR_ACTION0 = 0 ;
-static const uint8_t EXPLR_MMIO_MFIRACT0_FIR_ACTION0_LEN = 12 ;
-
-static const uint8_t EXPLR_MMIO_MFIRACT1_FIR_ACTION1 = 0 ;
-static const uint8_t EXPLR_MMIO_MFIRACT1_FIR_ACTION1_LEN = 12 ;
-
-static const uint8_t EXPLR_MMIO_MFIRMASK_FIR_MASK = 0 ;
-static const uint8_t EXPLR_MMIO_MFIRMASK_FIR_MASK_LEN = 12 ;
-
-static const uint8_t EXPLR_MMIO_MFIRWOF_FIR_WOF = 0 ;
-static const uint8_t EXPLR_MMIO_MFIRWOF_FIR_WOF_LEN = 12 ;
-
-static const uint8_t EXPLR_MMIO_MHOLD0_O0MBIT_O0DID_PERR = 0 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O0CCD_PERR = 1 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O0BAR0_PERR = 2 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O0BAR1_PERR = 3 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O0BAR2_PERR = 4 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O0SSYSID_PERR = 5 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O0CAPPTR_O0ROMBAR_PERR = 6 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_OVPD_PERR = 7 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_ODSNLO_ODSNCAP_PERR = 8 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_ODSNHI_PERR = 9 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_OTLVID_OTLCAP_PERR = 10 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_OVERCAP_OTLID_PERR = 11 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_OVERCFG_PERR = 12 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_ORTCAP_PERR = 13 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_OTTCFG_PERR = 14 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_ORRCAP10_PERR = 15 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_ORRCAP32_PERR = 16 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_ORRCAP54_PERR = 17 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_ORRCAP76_PERR = 18 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_OTRCFG10_PERR = 19 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_OTRCFG32_PERR = 20 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_OTRCFG54_PERR = 21 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_OTRCFG76_PERR = 22 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O0FNVID_O0FNCAP_PERR = 23 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O0ACTAG_O0FNID_PERR = 24 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O0VSVID_O0VSCAP_PERR = 25 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O0VSID_PERR = 26 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O1MBIT_O1DID_PERR = 27 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O1CCD_PERR = 28 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O1BAR0_PERR = 29 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O1BAR1_PERR = 30 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O1BAR2_PERR = 31 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O1SSYSID_PERR = 32 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O1CAPPTR_O1ROMBAR_PERR = 33 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_OPASID_PERR = 34 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O1FNVID_O1FNCAP_PERR = 35 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O1ACTAG_O1FNID_PERR = 36 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O1INFVID_O1INFCAP_PERR = 37 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O1INFOFF_O1INFID_PERR = 38 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O1INFDAT_PERR = 39 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_OCTRLVID_OCTRLCAP_PERR = 40 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_OCTRLENB_OCTRLID_PERR = 41 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_OCTRLPID_PERR = 42 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_OCTRLTAG_PERR = 43 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O1VSVID_O1VSCAP_PERR = 44 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_O1VSID_PERR = 45 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_AFU_DESC_UNIMP = 46 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_MMIO_ERR = 47 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_SCOM_ERR = 48 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_SCOM_CCMD_FSMPERR = 49 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_SCOM_CRESP_FSMPERR = 50 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_CTL_MMIO_FSMPERR = 51 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_CTL_CCMD_FSMPERR = 52 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_CTL_CRESP_FSMPERR = 53 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_PIB_FSMPERR = 54 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_CMUX_ARBPERR = 55 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_CFG_CMDFIFO_OVRFLOW = 56 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_CFG_RESPFIFO_OVRFLOW = 57 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_CFGP_FIFO_OVRFLOW = 58 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_MERRCTL_PERR = 59 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_MHOLD1_PERR = 60 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_MMASK1_PERR = 61 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_MDBELL_PERR = 62 ;
-static const uint8_t EXPLR_MMIO_MHOLD0_MSCCRNGE_PERR = 63 ;
-
-static const uint8_t EXPLR_MMIO_MHOLD1_ONAME0_ODESCTML_PERR = 0 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_ONAME21_PERR = 1 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_ONAME43_PERR = 2 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_OAFUVER_ONAME5_PERR = 3 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_OGMMIOOF_PERR = 4 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_OGMMIOSZ_PERR = 5 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_OPMMIOOOF_PERR = 6 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_OPMMIOST_PERR = 7 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_OMEMADDR_PERR = 8 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_OWWID10_PERR = 9 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_OWWID32_PERR = 10 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_MHOLD0_PERR = 11 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_MMASK0_PERR = 12 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_MMIOERR_PERR = 13 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_MMIOEWD_PERR = 14 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_SCOMEWD_PERR = 15 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_MCFGERRA_PERR = 16 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_MCFGERRB_PERR = 17 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_BOTH_STARTS_ERR = 18 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_MULT_SEQ_PERR = 19 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_FSM_PERR = 20 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_OCTHERM_PERR = 21 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_D0THERM_PERR = 22 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_D1THERM_PERR = 23 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_RDWR_PERR = 24 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_ACTPWRUP_PERR = 25 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_FRAMESR_PERR = 26 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_HISTOBASELOW_PERR = 27 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_HISTOBASEHIGH_PERR = 28 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_O0VSTLXA_PERR = 29 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_O0VSTLXB_PERR = 30 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_O0VSDLXA_PERR = 31 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_O0VSDLXB_PERR = 32 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_O0VSFLSH_PERR = 33 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_BAD_FUNC_ACTAG_LENGTH = 34 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_BAD_AFU_ACTAG_LENGTH = 35 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_BAD_FUNC_PASID_LENGTH = 36 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_BAD_AFU_PASID_LENGTH = 37 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_MENTRP_PERR = 38 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_OSYSMEML_PERR = 39 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_MDEBUG0_PERR = 40 ;
-static const uint8_t EXPLR_MMIO_MHOLD1_MDEBUG1_PERR = 41 ;
-
-static const uint8_t EXPLR_MMIO_MMASK0_MSK = 0 ;
-static const uint8_t EXPLR_MMIO_MMASK0_MSK_LEN = 64 ;
-
-static const uint8_t EXPLR_MMIO_MMASK1_MSK = 0 ;
-static const uint8_t EXPLR_MMIO_MMASK1_MSK_LEN = 42 ;
-
-static const uint8_t EXPLR_MMIO_MMIOERR_WDATA_P = 0 ;
-static const uint8_t EXPLR_MMIO_MMIOERR_WDATA_P_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_MMIOERR_INFO = 8 ;
-static const uint8_t EXPLR_MMIO_MMIOERR_INFO_LEN = 16 ;
-static const uint8_t EXPLR_MMIO_MMIOERR_PLEN = 25 ;
-static const uint8_t EXPLR_MMIO_MMIOERR_PLEN_LEN = 3 ;
-static const uint8_t EXPLR_MMIO_MMIOERR_RNW = 28 ;
-static const uint8_t EXPLR_MMIO_MMIOERR_ADDR = 29 ;
-static const uint8_t EXPLR_MMIO_MMIOERR_ADDR_LEN = 35 ;
-
-static const uint8_t EXPLR_MMIO_MMIOEWD_WDATA = 0 ;
-static const uint8_t EXPLR_MMIO_MMIOEWD_WDATA_LEN = 64 ;
-
-static const uint8_t EXPLR_MMIO_MPIBERR0_ERRINFO = 0 ;
-static const uint8_t EXPLR_MMIO_MPIBERR0_ERRINFO_LEN = 64 ;
-
-static const uint8_t EXPLR_MMIO_MPIBERR1_ERRINFO = 0 ;
-static const uint8_t EXPLR_MMIO_MPIBERR1_ERRINFO_LEN = 64 ;
-
-static const uint8_t EXPLR_MMIO_MPIBERR2_ERRINFO = 0 ;
-static const uint8_t EXPLR_MMIO_MPIBERR2_ERRINFO_LEN = 64 ;
-
-static const uint8_t EXPLR_MMIO_MPIBERR3_ERRINFO = 0 ;
-static const uint8_t EXPLR_MMIO_MPIBERR3_ERRINFO_LEN = 64 ;
-
-static const uint8_t EXPLR_MMIO_MSCCRNGE_LOWER = 0 ;
-static const uint8_t EXPLR_MMIO_MSCCRNGE_LOWER_LEN = 29 ;
-static const uint8_t EXPLR_MMIO_MSCCRNGE_UPPER = 32 ;
-static const uint8_t EXPLR_MMIO_MSCCRNGE_UPPER_LEN = 32 ;
-
-static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_ACTAG_BASE = 4 ;
-static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_ACTAG_BASE_LEN = 12 ;
-static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_ACTAG_LENGTH = 20 ;
-static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_ACTAG_LENGTH_LEN = 12 ;
-static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_AFU_PRESENT = 32 ;
-static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_MAX_AFU_INDEX = 34 ;
-static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_MAX_AFU_INDEX_LEN = 6 ;
-static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_FUNCTION_RESET = 40 ;
-static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_DVSEC_ID = 48 ;
-static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_DVSEC_ID_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_O0BAR0_BAR_ADDRESS = 0 ;
-static const uint8_t EXPLR_MMIO_O0BAR0_BAR_ADDRESS_LEN = 60 ;
-static const uint8_t EXPLR_MMIO_O0BAR0_PREFETCHABLE = 60 ;
-static const uint8_t EXPLR_MMIO_O0BAR0_TYPE = 61 ;
-static const uint8_t EXPLR_MMIO_O0BAR0_TYPE_LEN = 2 ;
-static const uint8_t EXPLR_MMIO_O0BAR0_ADDRESS_SPACE = 63 ;
-
-static const uint8_t EXPLR_MMIO_O0BAR1_BAR_ADDRESS = 0 ;
-static const uint8_t EXPLR_MMIO_O0BAR1_BAR_ADDRESS_LEN = 60 ;
-static const uint8_t EXPLR_MMIO_O0BAR1_PREFETCHABLE = 60 ;
-static const uint8_t EXPLR_MMIO_O0BAR1_TYPE = 61 ;
-static const uint8_t EXPLR_MMIO_O0BAR1_TYPE_LEN = 2 ;
-static const uint8_t EXPLR_MMIO_O0BAR1_ADDRESS_SPACE = 63 ;
-
-static const uint8_t EXPLR_MMIO_O0BAR2_BAR_ADDRESS = 0 ;
-static const uint8_t EXPLR_MMIO_O0BAR2_BAR_ADDRESS_LEN = 60 ;
-static const uint8_t EXPLR_MMIO_O0BAR2_PREFETCHABLE = 60 ;
-static const uint8_t EXPLR_MMIO_O0BAR2_TYPE = 61 ;
-static const uint8_t EXPLR_MMIO_O0BAR2_TYPE_LEN = 2 ;
-static const uint8_t EXPLR_MMIO_O0BAR2_ADDRESS_SPACE = 63 ;
-
-static const uint8_t EXPLR_MMIO_O0CAPPTR_O0ROMBAR_ROM_BASE = 32 ;
-static const uint8_t EXPLR_MMIO_O0CAPPTR_O0ROMBAR_ROM_BASE_LEN = 21 ;
-static const uint8_t EXPLR_MMIO_O0CAPPTR_O0ROMBAR_ROM_ENABLE = 63 ;
-
-static const uint8_t EXPLR_MMIO_O0CCD_MULTI_FUNCTION = 8 ;
-static const uint8_t EXPLR_MMIO_O0CCD_CLASS_CODE = 32 ;
-static const uint8_t EXPLR_MMIO_O0CCD_CLASS_CODE_LEN = 24 ;
-static const uint8_t EXPLR_MMIO_O0CCD_REVISION_ID = 56 ;
-static const uint8_t EXPLR_MMIO_O0CCD_REVISION_ID_LEN = 8 ;
-
-static const uint8_t EXPLR_MMIO_O0MBIT_O0DID_CAPABILITIES_LIST = 11 ;
-static const uint8_t EXPLR_MMIO_O0MBIT_O0DID_MEMORY_SPACE = 30 ;
-static const uint8_t EXPLR_MMIO_O0MBIT_O0DID_DEVICE_ID = 32 ;
-static const uint8_t EXPLR_MMIO_O0MBIT_O0DID_DEVICE_ID_LEN = 16 ;
-static const uint8_t EXPLR_MMIO_O0MBIT_O0DID_VENDOR_ID = 48 ;
-static const uint8_t EXPLR_MMIO_O0MBIT_O0DID_VENDOR_ID_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_O0SSYSID_SUBSYSTEM_ID = 0 ;
-static const uint8_t EXPLR_MMIO_O0SSYSID_SUBSYSTEM_ID_LEN = 16 ;
-static const uint8_t EXPLR_MMIO_O0SSYSID_SUBSYSTEM_VENDOR_ID = 16 ;
-static const uint8_t EXPLR_MMIO_O0SSYSID_SUBSYSTEM_VENDOR_ID_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_O0VSDLXA_DLX_PORT1 = 0 ;
-static const uint8_t EXPLR_MMIO_O0VSDLXA_DLX_PORT1_LEN = 32 ;
-static const uint8_t EXPLR_MMIO_O0VSDLXA_DLX_PORT0 = 32 ;
-static const uint8_t EXPLR_MMIO_O0VSDLXA_DLX_PORT0_LEN = 32 ;
-
-static const uint8_t EXPLR_MMIO_O0VSDLXB_DLX_PORT3 = 0 ;
-static const uint8_t EXPLR_MMIO_O0VSDLXB_DLX_PORT3_LEN = 32 ;
-static const uint8_t EXPLR_MMIO_O0VSDLXB_DLX_PORT2 = 32 ;
-static const uint8_t EXPLR_MMIO_O0VSDLXB_DLX_PORT2_LEN = 32 ;
-
-static const uint8_t EXPLR_MMIO_O0VSFLSH_DATA = 0 ;
-static const uint8_t EXPLR_MMIO_O0VSFLSH_DATA_LEN = 32 ;
-static const uint8_t EXPLR_MMIO_O0VSFLSH_CONTROL = 44 ;
-static const uint8_t EXPLR_MMIO_O0VSFLSH_CONTROL_LEN = 20 ;
-
-static const uint8_t EXPLR_MMIO_O0VSID_VENDOR_UNIQUE = 32 ;
-static const uint8_t EXPLR_MMIO_O0VSID_VENDOR_UNIQUE_LEN = 16 ;
-static const uint8_t EXPLR_MMIO_O0VSID_DVSEC_ID = 48 ;
-static const uint8_t EXPLR_MMIO_O0VSID_DVSEC_ID_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_O0VSTLXA_TLX_PORT1 = 0 ;
-static const uint8_t EXPLR_MMIO_O0VSTLXA_TLX_PORT1_LEN = 32 ;
-static const uint8_t EXPLR_MMIO_O0VSTLXA_TLX_PORT0 = 32 ;
-static const uint8_t EXPLR_MMIO_O0VSTLXA_TLX_PORT0_LEN = 32 ;
-
-static const uint8_t EXPLR_MMIO_O0VSTLXB_TLX_PORT3 = 0 ;
-static const uint8_t EXPLR_MMIO_O0VSTLXB_TLX_PORT3_LEN = 32 ;
-static const uint8_t EXPLR_MMIO_O0VSTLXB_TLX_PORT2 = 32 ;
-static const uint8_t EXPLR_MMIO_O0VSTLXB_TLX_PORT2_LEN = 32 ;
-
-static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_ACTAG_BASE = 4 ;
-static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_ACTAG_BASE_LEN = 12 ;
-static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_ACTAG_LENGTH = 20 ;
-static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_ACTAG_LENGTH_LEN = 12 ;
-static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_AFU_PRESENT = 32 ;
-static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_MAX_AFU_INDEX = 34 ;
-static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_MAX_AFU_INDEX_LEN = 6 ;
-static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_FUNCTION_RESET = 40 ;
-static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_DVSEC_ID = 48 ;
-static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_DVSEC_ID_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_O1BAR0_BAR_ADDRESS = 0 ;
-static const uint8_t EXPLR_MMIO_O1BAR0_BAR_ADDRESS_LEN = 29 ;
-static const uint8_t EXPLR_MMIO_O1BAR0_PREFETCHABLE = 60 ;
-static const uint8_t EXPLR_MMIO_O1BAR0_TYPE = 61 ;
-static const uint8_t EXPLR_MMIO_O1BAR0_TYPE_LEN = 2 ;
-static const uint8_t EXPLR_MMIO_O1BAR0_ADDRESS_SPACE = 63 ;
-
-static const uint8_t EXPLR_MMIO_O1BAR1_BAR_ADDRESS = 0 ;
-static const uint8_t EXPLR_MMIO_O1BAR1_BAR_ADDRESS_LEN = 60 ;
-static const uint8_t EXPLR_MMIO_O1BAR1_PREFETCHABLE = 60 ;
-static const uint8_t EXPLR_MMIO_O1BAR1_TYPE = 61 ;
-static const uint8_t EXPLR_MMIO_O1BAR1_TYPE_LEN = 2 ;
-static const uint8_t EXPLR_MMIO_O1BAR1_ADDRESS_SPACE = 63 ;
-
-static const uint8_t EXPLR_MMIO_O1BAR2_BAR_ADDRESS = 0 ;
-static const uint8_t EXPLR_MMIO_O1BAR2_BAR_ADDRESS_LEN = 60 ;
-static const uint8_t EXPLR_MMIO_O1BAR2_PREFETCHABLE = 60 ;
-static const uint8_t EXPLR_MMIO_O1BAR2_TYPE = 61 ;
-static const uint8_t EXPLR_MMIO_O1BAR2_TYPE_LEN = 2 ;
-static const uint8_t EXPLR_MMIO_O1BAR2_ADDRESS_SPACE = 63 ;
-
-static const uint8_t EXPLR_MMIO_O1CAPPTR_O1ROMBAR_ROM_BASE = 32 ;
-static const uint8_t EXPLR_MMIO_O1CAPPTR_O1ROMBAR_ROM_BASE_LEN = 21 ;
-static const uint8_t EXPLR_MMIO_O1CAPPTR_O1ROMBAR_ROM_ENABLE = 63 ;
-
-static const uint8_t EXPLR_MMIO_O1CCD_MULTI_FUNCTION = 8 ;
-static const uint8_t EXPLR_MMIO_O1CCD_CLASS_CODE = 32 ;
-static const uint8_t EXPLR_MMIO_O1CCD_CLASS_CODE_LEN = 24 ;
-static const uint8_t EXPLR_MMIO_O1CCD_REVISION_ID = 56 ;
-static const uint8_t EXPLR_MMIO_O1CCD_REVISION_ID_LEN = 8 ;
-
-static const uint8_t EXPLR_MMIO_O1INFDAT_AFU_DESCRIPTOR_DATA = 32 ;
-static const uint8_t EXPLR_MMIO_O1INFDAT_AFU_DESCRIPTOR_DATA_LEN = 32 ;
-
-static const uint8_t EXPLR_MMIO_O1INFOFF_O1INFID_DATA_VALID = 0 ;
-static const uint8_t EXPLR_MMIO_O1INFOFF_O1INFID_AFU_DESCRIPTOR_OFFSET = 1 ;
-static const uint8_t EXPLR_MMIO_O1INFOFF_O1INFID_AFU_DESCRIPTOR_OFFSET_LEN = 31 ;
-static const uint8_t EXPLR_MMIO_O1INFOFF_O1INFID_AFU_INFO_INDEX = 42 ;
-static const uint8_t EXPLR_MMIO_O1INFOFF_O1INFID_AFU_INFO_INDEX_LEN = 6 ;
-static const uint8_t EXPLR_MMIO_O1INFOFF_O1INFID_DVSEC_ID = 48 ;
-static const uint8_t EXPLR_MMIO_O1INFOFF_O1INFID_DVSEC_ID_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_O1MBIT_O1DID_CAPABILITIES_LIST = 11 ;
-static const uint8_t EXPLR_MMIO_O1MBIT_O1DID_MEMORY_SPACE = 30 ;
-static const uint8_t EXPLR_MMIO_O1MBIT_O1DID_DEVICE_ID = 32 ;
-static const uint8_t EXPLR_MMIO_O1MBIT_O1DID_DEVICE_ID_LEN = 16 ;
-static const uint8_t EXPLR_MMIO_O1MBIT_O1DID_VENDOR_ID = 48 ;
-static const uint8_t EXPLR_MMIO_O1MBIT_O1DID_VENDOR_ID_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_O1SSYSID_SUBSYSTEM_ID = 0 ;
-static const uint8_t EXPLR_MMIO_O1SSYSID_SUBSYSTEM_ID_LEN = 16 ;
-static const uint8_t EXPLR_MMIO_O1SSYSID_SUBSYSTEM_VENDOR_ID = 16 ;
-static const uint8_t EXPLR_MMIO_O1SSYSID_SUBSYSTEM_VENDOR_ID_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_O1VSID_VENDOR_UNIQUE = 32 ;
-static const uint8_t EXPLR_MMIO_O1VSID_VENDOR_UNIQUE_LEN = 16 ;
-static const uint8_t EXPLR_MMIO_O1VSID_DVSEC_ID = 48 ;
-static const uint8_t EXPLR_MMIO_O1VSID_DVSEC_ID_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_VERSION_MAJOR = 0 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_VERSION_MAJOR_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_VERSION_MINOR = 8 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_VERSION_MINOR_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_C_TYPE = 16 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_C_TYPE_LEN = 3 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_M_TYPE = 19 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_M_TYPE_LEN = 3 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_PROFILE = 24 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_PROFILE_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_23 = 32 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_23_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_22 = 40 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_22_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_21 = 48 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_21_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_20 = 56 ;
-static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_20_LEN = 8 ;
-
-static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_AFU_UNIQUE = 0 ;
-static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_AFU_UNIQUE_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_FENCE_AFU = 6 ;
-static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_ENABLE_AFU = 7 ;
-static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_RESET_AFU = 8 ;
-static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_TERMINATE_VALID = 11 ;
-static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_PASID_TERMINATION_VALUE = 12 ;
-static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_PASID_TERMINATION_VALUE_LEN = 20 ;
-static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_AFU_CONTROL_INDEX = 42 ;
-static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_AFU_CONTROL_INDEX_LEN = 6 ;
-static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_DVSEC_ID = 48 ;
-static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_DVSEC_ID_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_OCTRLPID_METADATA_SUPPORTED = 0 ;
-static const uint8_t EXPLR_MMIO_OCTRLPID_METADATA_ENABLED = 1 ;
-static const uint8_t EXPLR_MMIO_OCTRLPID_HTRL = 2 ;
-static const uint8_t EXPLR_MMIO_OCTRLPID_HTRL_LEN = 3 ;
-static const uint8_t EXPLR_MMIO_OCTRLPID_PASID_BASE = 12 ;
-static const uint8_t EXPLR_MMIO_OCTRLPID_PASID_BASE_LEN = 20 ;
-static const uint8_t EXPLR_MMIO_OCTRLPID_PASID_LENGTH_ENABLED = 51 ;
-static const uint8_t EXPLR_MMIO_OCTRLPID_PASID_LENGTH_ENABLED_LEN = 5 ;
-static const uint8_t EXPLR_MMIO_OCTRLPID_PASID_LENGTH_SUPPORTED = 59 ;
-static const uint8_t EXPLR_MMIO_OCTRLPID_PASID_LENGTH_SUPPORTED_LEN = 5 ;
-
-static const uint8_t EXPLR_MMIO_OCTRLTAG_AFU_ACTAG_BASE = 20 ;
-static const uint8_t EXPLR_MMIO_OCTRLTAG_AFU_ACTAG_BASE_LEN = 12 ;
-static const uint8_t EXPLR_MMIO_OCTRLTAG_AFU_ACTAG_LENGTH_ENABLED = 36 ;
-static const uint8_t EXPLR_MMIO_OCTRLTAG_AFU_ACTAG_LENGTH_ENABLED_LEN = 12 ;
-static const uint8_t EXPLR_MMIO_OCTRLTAG_AFU_ACTAG_LENGTH_SUPPORTED = 52 ;
-static const uint8_t EXPLR_MMIO_OCTRLTAG_AFU_ACTAG_LENGTH_SUPPORTED_LEN = 12 ;
-
-static const uint8_t EXPLR_MMIO_ODSNHI_DSN_HIGH = 32 ;
-static const uint8_t EXPLR_MMIO_ODSNHI_DSN_HIGH_LEN = 32 ;
-
-static const uint8_t EXPLR_MMIO_ODSNLO_ODSNCAP_DSN_LOW = 0 ;
-static const uint8_t EXPLR_MMIO_ODSNLO_ODSNCAP_DSN_LOW_LEN = 32 ;
-
-static const uint8_t EXPLR_MMIO_OGMMIOOF_OFFSET = 0 ;
-static const uint8_t EXPLR_MMIO_OGMMIOOF_OFFSET_LEN = 48 ;
-static const uint8_t EXPLR_MMIO_OGMMIOOF_BAR = 61 ;
-static const uint8_t EXPLR_MMIO_OGMMIOOF_BAR_LEN = 3 ;
-
-static const uint8_t EXPLR_MMIO_OGMMIOSZ_SIZE = 32 ;
-static const uint8_t EXPLR_MMIO_OGMMIOSZ_SIZE_LEN = 32 ;
-
-static const uint8_t EXPLR_MMIO_OMEMADDR_ADDR = 0 ;
-static const uint8_t EXPLR_MMIO_OMEMADDR_ADDR_LEN = 64 ;
-
-static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_3 = 0 ;
-static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_3_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_2 = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_2_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_1 = 16 ;
-static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_1_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_0 = 24 ;
-static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_0_LEN = 8 ;
-
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_11 = 0 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_11_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_10 = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_10_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_9 = 16 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_9_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_8 = 24 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_8_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_7 = 32 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_7_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_6 = 40 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_6_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_5 = 48 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_5_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_4 = 56 ;
-static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_4_LEN = 8 ;
-
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_19 = 0 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_19_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_18 = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_18_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_17 = 16 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_17_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_16 = 24 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_16_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_15 = 32 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_15_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_14 = 40 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_14_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_13 = 48 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_13_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_12 = 56 ;
-static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_12_LEN = 8 ;
-
-static const uint8_t EXPLR_MMIO_OPASID_MAX_PASID_WIDTH = 19 ;
-static const uint8_t EXPLR_MMIO_OPASID_MAX_PASID_WIDTH_LEN = 5 ;
-
-static const uint8_t EXPLR_MMIO_OPMMIOOF_OFFSET = 0 ;
-static const uint8_t EXPLR_MMIO_OPMMIOOF_OFFSET_LEN = 48 ;
-static const uint8_t EXPLR_MMIO_OPMMIOOF_BAR = 61 ;
-static const uint8_t EXPLR_MMIO_OPMMIOOF_BAR_LEN = 3 ;
-
-static const uint8_t EXPLR_MMIO_OPMMIOST_MEM_SIZE = 24 ;
-static const uint8_t EXPLR_MMIO_OPMMIOST_MEM_SIZE_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_OPMMIOST_STRIDE = 32 ;
-static const uint8_t EXPLR_MMIO_OPMMIOST_STRIDE_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_55 = 0 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_55_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_54 = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_54_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_53 = 8 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_53_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_52 = 12 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_52_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_51 = 16 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_51_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_50 = 20 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_50_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_49 = 24 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_49_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_48 = 28 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_48_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_63 = 32 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_63_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_62 = 36 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_62_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_61 = 40 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_61_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_60 = 44 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_60_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_59 = 48 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_59_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_58 = 52 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_58_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_57 = 56 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_57_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_56 = 60 ;
-static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_56_LEN = 4 ;
-
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_39 = 0 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_39_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_38 = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_38_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_37 = 8 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_37_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_36 = 12 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_36_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_35 = 16 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_35_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_34 = 20 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_34_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_33 = 24 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_33_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_32 = 28 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_32_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_47 = 32 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_47_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_46 = 36 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_46_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_45 = 40 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_45_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_44 = 44 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_44_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_43 = 48 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_43_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_42 = 52 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_42_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_41 = 56 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_41_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_40 = 60 ;
-static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_40_LEN = 4 ;
-
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_23 = 0 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_23_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_22 = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_22_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_21 = 8 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_21_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_20 = 12 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_20_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_19 = 16 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_19_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_18 = 20 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_18_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_17 = 24 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_17_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_16 = 28 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_16_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_31 = 32 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_31_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_30 = 36 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_30_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_29 = 40 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_29_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_28 = 44 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_28_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_27 = 48 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_27_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_26 = 52 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_26_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_25 = 56 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_25_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_24 = 60 ;
-static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_24_LEN = 4 ;
-
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_7 = 0 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_7_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_6 = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_6_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_5 = 8 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_5_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_4 = 12 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_4_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_3 = 16 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_3_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_2 = 20 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_2_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_1 = 24 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_1_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_0 = 28 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_0_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_15 = 32 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_15_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_14 = 36 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_14_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_13 = 40 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_13_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_12 = 44 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_12_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_11 = 48 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_11_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_10 = 52 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_10_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_9 = 56 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_9_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_8 = 60 ;
-static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_8_LEN = 4 ;
-
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_31 = 0 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_30 = 1 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_29 = 2 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_28 = 3 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_27 = 4 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_26 = 5 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_25 = 6 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_24 = 7 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_23 = 8 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_22 = 9 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_21 = 10 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_20 = 11 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_19 = 12 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_18 = 13 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_17 = 14 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_16 = 15 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_15 = 16 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_14 = 17 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_13 = 18 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_12 = 19 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_11 = 20 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_10 = 21 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_9 = 22 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_8 = 23 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_7 = 24 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_6 = 25 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_5 = 26 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_4 = 27 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_3 = 28 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_2 = 29 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_1 = 30 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_0 = 31 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_63 = 32 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_62 = 33 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_61 = 34 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_60 = 35 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_59 = 36 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_58 = 37 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_57 = 38 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_56 = 39 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_55 = 40 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_54 = 41 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_53 = 42 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_52 = 43 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_51 = 44 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_50 = 45 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_49 = 46 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_48 = 47 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_47 = 48 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_46 = 49 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_45 = 50 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_44 = 51 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_43 = 52 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_42 = 53 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_41 = 54 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_40 = 55 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_39 = 56 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_38 = 57 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_37 = 58 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_36 = 59 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_35 = 60 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_34 = 61 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_33 = 62 ;
-static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_32 = 63 ;
-
-static const uint8_t EXPLR_MMIO_OSYSMEML_SYSLEN = 0 ;
-static const uint8_t EXPLR_MMIO_OSYSMEML_SYSLEN_LEN = 48 ;
-
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_55 = 0 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_55_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_54 = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_54_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_53 = 8 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_53_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_52 = 12 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_52_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_51 = 16 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_51_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_50 = 20 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_50_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_49 = 24 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_49_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_48 = 28 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_48_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_63 = 32 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_63_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_62 = 36 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_62_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_61 = 40 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_61_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_60 = 44 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_60_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_59 = 48 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_59_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_58 = 52 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_58_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_57 = 56 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_57_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_56 = 60 ;
-static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_56_LEN = 4 ;
-
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_39 = 0 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_39_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_38 = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_38_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_37 = 8 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_37_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_36 = 12 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_36_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_35 = 16 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_35_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_34 = 20 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_34_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_33 = 24 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_33_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_32 = 28 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_32_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_47 = 32 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_47_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_46 = 36 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_46_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_45 = 40 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_45_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_44 = 44 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_44_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_43 = 48 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_43_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_42 = 52 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_42_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_41 = 56 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_41_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_40 = 60 ;
-static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_40_LEN = 4 ;
-
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_23 = 0 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_23_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_22 = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_22_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_21 = 8 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_21_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_20 = 12 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_20_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_19 = 16 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_19_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_18 = 20 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_18_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_17 = 24 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_17_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_16 = 28 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_16_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_31 = 32 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_31_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_30 = 36 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_30_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_29 = 40 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_29_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_28 = 44 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_28_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_27 = 48 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_27_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_26 = 52 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_26_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_25 = 56 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_25_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_24 = 60 ;
-static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_24_LEN = 4 ;
-
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_7 = 0 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_7_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_6 = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_6_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_5 = 8 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_5_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_4 = 12 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_4_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_3 = 16 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_3_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_2 = 20 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_2_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_1 = 24 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_1_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_0 = 28 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_0_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_15 = 32 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_15_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_14 = 36 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_14_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_13 = 40 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_13_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_12 = 44 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_12_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_11 = 48 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_11_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_10 = 52 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_10_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_9 = 56 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_9_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_8 = 60 ;
-static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_8_LEN = 4 ;
-
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_31 = 0 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_30 = 1 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_29 = 2 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_28 = 3 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_27 = 4 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_26 = 5 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_25 = 6 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_24 = 7 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_23 = 8 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_22 = 9 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_21 = 10 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_20 = 11 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_19 = 12 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_18 = 13 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_17 = 14 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_16 = 15 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_15 = 16 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_14 = 17 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_13 = 18 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_12 = 19 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_11 = 20 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_10 = 21 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_9 = 22 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_8 = 23 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_7 = 24 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_6 = 25 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_5 = 26 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_4 = 27 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_3 = 28 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_2 = 29 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_1 = 30 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_0 = 31 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_63 = 32 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_62 = 33 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_61 = 34 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_60 = 35 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_59 = 36 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_58 = 37 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_57 = 38 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_56 = 39 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_55 = 40 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_54 = 41 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_53 = 42 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_52 = 43 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_51 = 44 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_50 = 45 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_49 = 46 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_48 = 47 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_47 = 48 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_46 = 49 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_45 = 50 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_44 = 51 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_43 = 52 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_42 = 53 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_41 = 54 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_40 = 55 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_39 = 56 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_38 = 57 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_37 = 58 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_36 = 59 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_35 = 60 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_34 = 61 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_33 = 62 ;
-static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_32 = 63 ;
-
-static const uint8_t EXPLR_MMIO_OVERCAP_OTLID_TL_MAJOR_VERSION_CAPABILITY = 0 ;
-static const uint8_t EXPLR_MMIO_OVERCAP_OTLID_TL_MAJOR_VERSION_CAPABILITY_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_OVERCAP_OTLID_TL_MINOR_VERSION_CAPABILITY = 8 ;
-static const uint8_t EXPLR_MMIO_OVERCAP_OTLID_TL_MINOR_VERSION_CAPABILITY_LEN = 8 ;
-
-static const uint8_t EXPLR_MMIO_OVERCFG_TL_MAJOR_VERSION_CONFIGURATION = 32 ;
-static const uint8_t EXPLR_MMIO_OVERCFG_TL_MAJOR_VERSION_CONFIGURATION_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_OVERCFG_TL_MINOR_VERSION_CONFIGURATION = 40 ;
-static const uint8_t EXPLR_MMIO_OVERCFG_TL_MINOR_VERSION_CONFIGURATION_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_OVERCFG_LONG_BACK_OFF_TIMER = 56 ;
-static const uint8_t EXPLR_MMIO_OVERCFG_LONG_BACK_OFF_TIMER_LEN = 4 ;
-static const uint8_t EXPLR_MMIO_OVERCFG_SHORT_BACK_OFF_TIMER = 60 ;
-static const uint8_t EXPLR_MMIO_OVERCFG_SHORT_BACK_OFF_TIMER_LEN = 4 ;
-
-static const uint8_t EXPLR_MMIO_OVPD_DATA = 0 ;
-static const uint8_t EXPLR_MMIO_OVPD_DATA_LEN = 32 ;
-static const uint8_t EXPLR_MMIO_OVPD_FLAG = 32 ;
-static const uint8_t EXPLR_MMIO_OVPD_ADDRESS = 33 ;
-static const uint8_t EXPLR_MMIO_OVPD_ADDRESS_LEN = 15 ;
-static const uint8_t EXPLR_MMIO_OVPD_NEXT_POINTER = 48 ;
-static const uint8_t EXPLR_MMIO_OVPD_NEXT_POINTER_LEN = 8 ;
-static const uint8_t EXPLR_MMIO_OVPD_CAPABILITY_ID = 56 ;
-static const uint8_t EXPLR_MMIO_OVPD_CAPABILITY_ID_LEN = 8 ;
-
-static const uint8_t EXPLR_MMIO_OWWID10_ID = 0 ;
-static const uint8_t EXPLR_MMIO_OWWID10_ID_LEN = 64 ;
-
-static const uint8_t EXPLR_MMIO_OWWID32_ID = 0 ;
-static const uint8_t EXPLR_MMIO_OWWID32_ID_LEN = 64 ;
-
-static const uint8_t EXPLR_MMIO_SCOMEWD_WDATA = 0 ;
-static const uint8_t EXPLR_MMIO_SCOMEWD_WDATA_LEN = 64 ;
-
-static const uint8_t EXPLR_MMIO_SNSC_ACTPWRUP_ACTSCOUNT = 0 ;
-static const uint8_t EXPLR_MMIO_SNSC_ACTPWRUP_ACTSCOUNT_LEN = 32 ;
-static const uint8_t EXPLR_MMIO_SNSC_ACTPWRUP_POWERUPSCOUNT = 32 ;
-static const uint8_t EXPLR_MMIO_SNSC_ACTPWRUP_POWERUPSCOUNT_LEN = 32 ;
-
-static const uint8_t EXPLR_MMIO_SNSC_D0THERM_ERRORBIT = 47 ;
-static const uint8_t EXPLR_MMIO_SNSC_D0THERM_THERMALDATA = 48 ;
-static const uint8_t EXPLR_MMIO_SNSC_D0THERM_THERMALDATA_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_SNSC_D1THERM_ERRORBIT = 47 ;
-static const uint8_t EXPLR_MMIO_SNSC_D1THERM_THERMALDATA = 48 ;
-static const uint8_t EXPLR_MMIO_SNSC_D1THERM_THERMALDATA_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_SNSC_FRAMESR_FRAMECOUNT = 0 ;
-static const uint8_t EXPLR_MMIO_SNSC_FRAMESR_FRAMECOUNT_LEN = 32 ;
-static const uint8_t EXPLR_MMIO_SNSC_FRAMESR_SELFREFRESHCOUNT = 32 ;
-static const uint8_t EXPLR_MMIO_SNSC_FRAMESR_SELFREFRESHCOUNT_LEN = 8 ;
-
-static const uint8_t EXPLR_MMIO_SNSC_HISTOBASELOW_HISTOGRAMBASECOUNT = 0 ;
-static const uint8_t EXPLR_MMIO_SNSC_HISTOBASELOW_HISTOGRAMBASECOUNT_LEN = 32 ;
-static const uint8_t EXPLR_MMIO_SNSC_HISTOBASELOW_HISTOGRAMLOWCOUNT = 32 ;
-static const uint8_t EXPLR_MMIO_SNSC_HISTOBASELOW_HISTOGRAMLOWCOUNT_LEN = 32 ;
-
-static const uint8_t EXPLR_MMIO_SNSC_HISTOMEDHIGH_HISTOGRAMMEDCOUNT = 0 ;
-static const uint8_t EXPLR_MMIO_SNSC_HISTOMEDHIGH_HISTOGRAMMEDCOUNT_LEN = 32 ;
-static const uint8_t EXPLR_MMIO_SNSC_HISTOMEDHIGH_HISTOGRAMHIGHCOUNT = 32 ;
-static const uint8_t EXPLR_MMIO_SNSC_HISTOMEDHIGH_HISTOGRAMHIGHCOUNT_LEN = 32 ;
-
-static const uint8_t EXPLR_MMIO_SNSC_OCTHERM_ERRORBIT = 47 ;
-static const uint8_t EXPLR_MMIO_SNSC_OCTHERM_THERMALDATA = 48 ;
-static const uint8_t EXPLR_MMIO_SNSC_OCTHERM_THERMALDATA_LEN = 16 ;
-
-static const uint8_t EXPLR_MMIO_SNSC_RDWR_READSCOUNT = 0 ;
-static const uint8_t EXPLR_MMIO_SNSC_RDWR_READSCOUNT_LEN = 32 ;
-static const uint8_t EXPLR_MMIO_SNSC_RDWR_WRITESCOUNT = 32 ;
-static const uint8_t EXPLR_MMIO_SNSC_RDWR_WRITESCOUNT_LEN = 32 ;
-
-static const uint8_t EXPLR_MMIO_SNSC_STATEREG_STREGISTER = 0 ;
-static const uint8_t EXPLR_MMIO_SNSC_STATEREG_STREGISTER_LEN = 22 ;
-
-static const uint8_t EXPLR_RDF_AACR_ADDRESS = 0 ;
-static const uint8_t EXPLR_RDF_AACR_ADDRESS_LEN = 7 ;
-static const uint8_t EXPLR_RDF_AACR_AUTOINC = 7 ;
-
-static const uint8_t EXPLR_RDF_AADR_DATA = 0 ;
-static const uint8_t EXPLR_RDF_AADR_DATA_LEN = 64 ;
-
-static const uint8_t EXPLR_RDF_AAER_DATA = 0 ;
-static const uint8_t EXPLR_RDF_AAER_DATA_LEN = 8 ;
-
-static const uint8_t EXPLR_RDF_ACTION0_FIR = 0 ;
-static const uint8_t EXPLR_RDF_ACTION0_FIR_LEN = 64 ;
-
-static const uint8_t EXPLR_RDF_ACTION1_FIR = 0 ;
-static const uint8_t EXPLR_RDF_ACTION1_FIR_LEN = 64 ;
-
-static const uint8_t EXPLR_RDF_CERR0_MSR_PE = 12 ;
-static const uint8_t EXPLR_RDF_CERR0_EICR_PE = 13 ;
-static const uint8_t EXPLR_RDF_CERR0_HWMSX_PE = 16 ;
-static const uint8_t EXPLR_RDF_CERR0_HWMSX_PE_LEN = 8 ;
-static const uint8_t EXPLR_RDF_CERR0_FWMSX_PE = 24 ;
-static const uint8_t EXPLR_RDF_CERR0_FWMSX_PE_LEN = 8 ;
-static const uint8_t EXPLR_RDF_CERR0_RSPAR_PE = 32 ;
-static const uint8_t EXPLR_RDF_CERR0_AACR_PE = 41 ;
-static const uint8_t EXPLR_RDF_CERR0_MCBCM_PE = 44 ;
-static const uint8_t EXPLR_RDF_CERR0_RECR_PE = 45 ;
-static const uint8_t EXPLR_RDF_CERR0_DBGR_PE = 46 ;
-static const uint8_t EXPLR_RDF_CERR0_MASK0_PE = 48 ;
-static const uint8_t EXPLR_RDF_CERR0_MASK1_PE = 49 ;
-static const uint8_t EXPLR_RDF_CERR0_CGDR_PE = 50 ;
-
-static const uint8_t EXPLR_RDF_CERR1_ECC_CTL_AF_PERR = 0 ;
-static const uint8_t EXPLR_RDF_CERR1_ECC_CTL_TCHN_PERR = 1 ;
-static const uint8_t EXPLR_RDF_CERR1_ECC_CTL_CMPMODE_ERR = 2 ;
-static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_PCX_PERR = 3 ;
-static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_SYND_PERR = 4 ;
-static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_2SYM_PERR = 5 ;
-static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_CPLX_PERR = 6 ;
-static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_EP2_PERR = 7 ;
-static const uint8_t EXPLR_RDF_CERR1_READ_ECC_DATAPATH_PARITY_ERROR = 8 ;
-static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_CMX_PERR = 9 ;
-static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_VP1_PERR = 10 ;
-static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_VP2_PERR = 11 ;
-static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_SYG_PERR = 12 ;
-static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_EF1_PERR = 13 ;
-static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_MK3_PERR = 14 ;
-static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_E1A_PERR = 15 ;
-static const uint8_t EXPLR_RDF_CERR1_UNEXPECTED_RDDATA_VALID = 16 ;
-static const uint8_t EXPLR_RDF_CERR1_MISSING_RDDATA_VALID = 17 ;
-static const uint8_t EXPLR_RDF_CERR1_RBUF_ECC_ERR_CE_DW0 = 20 ;
-static const uint8_t EXPLR_RDF_CERR1_RBUF_ECC_ERR_UE_DW0 = 21 ;
-static const uint8_t EXPLR_RDF_CERR1_RBUF_ECC_ERR_CE_DW1 = 22 ;
-static const uint8_t EXPLR_RDF_CERR1_RBUF_ECC_ERR_UE_DW1 = 23 ;
-static const uint8_t EXPLR_RDF_CERR1_RD_BUFF_ECC_ERR_SYNDROME = 24 ;
-static const uint8_t EXPLR_RDF_CERR1_RD_BUFF_ECC_ERR_SYNDROME_LEN = 8 ;
-
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_PCTL = 0 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_RESP = 1 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_RMW = 2 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_LPTR = 3 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_AHASH = 4 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_STG = 5 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_OUT = 6 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_TLM = 7 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_BD = 8 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_DCMP = 9 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_RBCTL = 10 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_RBRMW = 11 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_RBTRC = 12 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_MPE = 13 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_CONF = 14 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_HWMS = 15 ;
-static const uint8_t EXPLR_RDF_CGDR_PSDIS_ZERO_SYND = 16 ;
-static const uint8_t EXPLR_RDF_CGDR_PSDIS_SAME_MARKS = 17 ;
-static const uint8_t EXPLR_RDF_CGDR_PSDIS_SAME_STEER = 18 ;
-static const uint8_t EXPLR_RDF_CGDR_CGDIS_SPARE = 19 ;
-
-static const uint8_t EXPLR_RDF_CTCR_MPE_TIMER = 0 ;
-static const uint8_t EXPLR_RDF_CTCR_MPE_TIMER_LEN = 6 ;
-static const uint8_t EXPLR_RDF_CTCR_MPE_TIMEBASE = 6 ;
-static const uint8_t EXPLR_RDF_CTCR_MPE_TIMEBASE_LEN = 3 ;
-static const uint8_t EXPLR_RDF_CTCR_UE_TIMER = 9 ;
-static const uint8_t EXPLR_RDF_CTCR_UE_TIMER_LEN = 6 ;
-static const uint8_t EXPLR_RDF_CTCR_UE_TIMEBASE = 15 ;
-static const uint8_t EXPLR_RDF_CTCR_UE_TIMEBASE_LEN = 3 ;
-static const uint8_t EXPLR_RDF_CTCR_UE_LOCKOUT_ENABLE = 18 ;
-
-static const uint8_t EXPLR_RDF_DBGR_PRIMARY_SELECT = 0 ;
-static const uint8_t EXPLR_RDF_DBGR_PRIMARY_SELECT_LEN = 4 ;
-static const uint8_t EXPLR_RDF_DBGR_SECONDARY_SELECT = 4 ;
-static const uint8_t EXPLR_RDF_DBGR_SECONDARY_SELECT_LEN = 4 ;
-static const uint8_t EXPLR_RDF_DBGR_EPX_CHIP = 8 ;
-static const uint8_t EXPLR_RDF_DBGR_EPX_SYMS = 9 ;
-static const uint8_t EXPLR_RDF_DBGR_TRACE_ALWAYS = 10 ;
-static const uint8_t EXPLR_RDF_DBGR_WAT_ENABLE = 11 ;
-static const uint8_t EXPLR_RDF_DBGR_WAT_ACTION_SELECT = 12 ;
-static const uint8_t EXPLR_RDF_DBGR_WAT_SOURCE = 13 ;
-static const uint8_t EXPLR_RDF_DBGR_WAT_SOURCE_LEN = 2 ;
-
-static const uint8_t EXPLR_RDF_EICR_ADDRESS = 0 ;
-static const uint8_t EXPLR_RDF_EICR_ADDRESS_LEN = 37 ;
-static const uint8_t EXPLR_RDF_EICR_RESERVED = 37 ;
-static const uint8_t EXPLR_RDF_EICR_PERSIST = 38 ;
-static const uint8_t EXPLR_RDF_EICR_PERSIST_LEN = 2 ;
-static const uint8_t EXPLR_RDF_EICR_REGION = 40 ;
-static const uint8_t EXPLR_RDF_EICR_REGION_LEN = 3 ;
-static const uint8_t EXPLR_RDF_EICR_TYPE = 43 ;
-static const uint8_t EXPLR_RDF_EICR_TYPE_LEN = 5 ;
-static const uint8_t EXPLR_RDF_EICR_MISC = 48 ;
-static const uint8_t EXPLR_RDF_EICR_MISC_LEN = 6 ;
-
-static const uint8_t EXPLR_RDF_ELPR_LOG_FULL = 0 ;
-static const uint8_t EXPLR_RDF_ELPR_LOG_POINTER = 2 ;
-static const uint8_t EXPLR_RDF_ELPR_LOG_POINTER_LEN = 6 ;
-
-static const uint8_t EXPLR_RDF_ERR_HOLD_LAT_FIR_MASK_PAR = 0 ;
-static const uint8_t EXPLR_RDF_ERR_HOLD_LAT_FIR_ACTION0_PAR = 1 ;
-static const uint8_t EXPLR_RDF_ERR_HOLD_LAT_FIR_ACTION1_PAR = 2 ;
-
-static const uint8_t EXPLR_RDF_ERR_MASK_LAT_FIR_PAR = 0 ;
-static const uint8_t EXPLR_RDF_ERR_MASK_LAT_FIR_ACTION0_PAR = 1 ;
-static const uint8_t EXPLR_RDF_ERR_MASK_LAT_FIR_ACTION1_PAR = 2 ;
-
-static const uint8_t EXPLR_RDF_FIR_MAINLINE_MPE_RANK_0_TO_7 = 0 ;
-static const uint8_t EXPLR_RDF_FIR_MAINLINE_MPE_RANK_0_TO_7_LEN = 8 ;
-static const uint8_t EXPLR_RDF_FIR_MAINLINE_NCE = 8 ;
-static const uint8_t EXPLR_RDF_FIR_MAINLINE_TCE = 9 ;
-static const uint8_t EXPLR_RDF_FIR_MAINLINE_SCE = 10 ;
-static const uint8_t EXPLR_RDF_FIR_MAINLINE_MCE = 11 ;
-static const uint8_t EXPLR_RDF_FIR_MAINLINE_SUE = 12 ;
-static const uint8_t EXPLR_RDF_FIR_MAINLINE_AUE = 13 ;
-static const uint8_t EXPLR_RDF_FIR_MAINLINE_UE = 14 ;
-static const uint8_t EXPLR_RDF_FIR_MAINLINE_RCD = 15 ;
-static const uint8_t EXPLR_RDF_FIR_MAINLINE_IAUE = 16 ;
-static const uint8_t EXPLR_RDF_FIR_MAINLINE_IUE = 17 ;
-static const uint8_t EXPLR_RDF_FIR_MAINLINE_IRCD = 18 ;
-static const uint8_t EXPLR_RDF_FIR_MAINLINE_IMPE = 19 ;
-static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_MPE_RANK_0_TO_7 = 20 ;
-static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_MPE_RANK_0_TO_7_LEN = 8 ;
-static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_NCE = 28 ;
-static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_TCE = 29 ;
-static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_SCE = 30 ;
-static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_MCE = 31 ;
-static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_SUE = 32 ;
-static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_AUE = 33 ;
-static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_UE = 34 ;
-static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_RCD = 35 ;
-static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_IAUE = 36 ;
-static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_IUE = 37 ;
-static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_IRCD = 38 ;
-static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_IMPE = 39 ;
-static const uint8_t EXPLR_RDF_FIR_RDDATA_VALID_ERROR = 40 ;
-static const uint8_t EXPLR_RDF_FIR_SCOM_PARITY_CLASS_STATUS = 41 ;
-static const uint8_t EXPLR_RDF_FIR_SCOM_PARITY_CLASS_RECOVERABLE = 42 ;
-static const uint8_t EXPLR_RDF_FIR_SCOM_PARITY_CLASS_UNRECOVERABLE = 43 ;
-static const uint8_t EXPLR_RDF_FIR_ECC_CORRECTOR_INTERNAL_PARITY_ERROR = 44 ;
-static const uint8_t EXPLR_RDF_FIR_ECC_RBUF_CE_DW0 = 45 ;
-static const uint8_t EXPLR_RDF_FIR_ECC_RBUF_CE_DW1 = 46 ;
-static const uint8_t EXPLR_RDF_FIR_ECC_RBUF_UE_DW0 = 47 ;
-static const uint8_t EXPLR_RDF_FIR_ECC_RBUF_UE_DW1 = 48 ;
-static const uint8_t EXPLR_RDF_FIR_RESERVED_49_59 = 49 ;
-static const uint8_t EXPLR_RDF_FIR_RESERVED_49_59_LEN = 11 ;
-static const uint8_t EXPLR_RDF_FIR_SCOM_PARITY_DEBUG_WAT = 60 ;
-static const uint8_t EXPLR_RDF_FIR_RESERVED = 61 ;
-static const uint8_t EXPLR_RDF_FIR_INTERNAL_SCOM_ERROR = 62 ;
-static const uint8_t EXPLR_RDF_FIR_INTERNAL_SCOM_ERROR_COPY = 63 ;
-
-static const uint8_t EXPLR_RDF_FWMS0_MARK = 0 ;
-static const uint8_t EXPLR_RDF_FWMS0_MARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_FWMS0_TYPE = 8 ;
-static const uint8_t EXPLR_RDF_FWMS0_REGION = 9 ;
-static const uint8_t EXPLR_RDF_FWMS0_REGION_LEN = 3 ;
-static const uint8_t EXPLR_RDF_FWMS0_ADDRESS = 12 ;
-static const uint8_t EXPLR_RDF_FWMS0_ADDRESS_LEN = 11 ;
-static const uint8_t EXPLR_RDF_FWMS0_EXIT_1 = 23 ;
-
-static const uint8_t EXPLR_RDF_FWMS1_MARK = 0 ;
-static const uint8_t EXPLR_RDF_FWMS1_MARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_FWMS1_TYPE = 8 ;
-static const uint8_t EXPLR_RDF_FWMS1_REGION = 9 ;
-static const uint8_t EXPLR_RDF_FWMS1_REGION_LEN = 3 ;
-static const uint8_t EXPLR_RDF_FWMS1_ADDRESS = 12 ;
-static const uint8_t EXPLR_RDF_FWMS1_ADDRESS_LEN = 11 ;
-static const uint8_t EXPLR_RDF_FWMS1_EXIT_1 = 23 ;
-
-static const uint8_t EXPLR_RDF_FWMS2_MARK = 0 ;
-static const uint8_t EXPLR_RDF_FWMS2_MARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_FWMS2_TYPE = 8 ;
-static const uint8_t EXPLR_RDF_FWMS2_REGION = 9 ;
-static const uint8_t EXPLR_RDF_FWMS2_REGION_LEN = 3 ;
-static const uint8_t EXPLR_RDF_FWMS2_ADDRESS = 12 ;
-static const uint8_t EXPLR_RDF_FWMS2_ADDRESS_LEN = 11 ;
-static const uint8_t EXPLR_RDF_FWMS2_EXIT_1 = 23 ;
-
-static const uint8_t EXPLR_RDF_FWMS3_MARK = 0 ;
-static const uint8_t EXPLR_RDF_FWMS3_MARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_FWMS3_TYPE = 8 ;
-static const uint8_t EXPLR_RDF_FWMS3_REGION = 9 ;
-static const uint8_t EXPLR_RDF_FWMS3_REGION_LEN = 3 ;
-static const uint8_t EXPLR_RDF_FWMS3_ADDRESS = 12 ;
-static const uint8_t EXPLR_RDF_FWMS3_ADDRESS_LEN = 11 ;
-static const uint8_t EXPLR_RDF_FWMS3_EXIT_1 = 23 ;
-
-static const uint8_t EXPLR_RDF_FWMS4_MARK = 0 ;
-static const uint8_t EXPLR_RDF_FWMS4_MARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_FWMS4_TYPE = 8 ;
-static const uint8_t EXPLR_RDF_FWMS4_REGION = 9 ;
-static const uint8_t EXPLR_RDF_FWMS4_REGION_LEN = 3 ;
-static const uint8_t EXPLR_RDF_FWMS4_ADDRESS = 12 ;
-static const uint8_t EXPLR_RDF_FWMS4_ADDRESS_LEN = 11 ;
-static const uint8_t EXPLR_RDF_FWMS4_EXIT_1 = 23 ;
-
-static const uint8_t EXPLR_RDF_FWMS5_MARK = 0 ;
-static const uint8_t EXPLR_RDF_FWMS5_MARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_FWMS5_TYPE = 8 ;
-static const uint8_t EXPLR_RDF_FWMS5_REGION = 9 ;
-static const uint8_t EXPLR_RDF_FWMS5_REGION_LEN = 3 ;
-static const uint8_t EXPLR_RDF_FWMS5_ADDRESS = 12 ;
-static const uint8_t EXPLR_RDF_FWMS5_ADDRESS_LEN = 11 ;
-static const uint8_t EXPLR_RDF_FWMS5_EXIT_1 = 23 ;
-
-static const uint8_t EXPLR_RDF_FWMS6_MARK = 0 ;
-static const uint8_t EXPLR_RDF_FWMS6_MARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_FWMS6_TYPE = 8 ;
-static const uint8_t EXPLR_RDF_FWMS6_REGION = 9 ;
-static const uint8_t EXPLR_RDF_FWMS6_REGION_LEN = 3 ;
-static const uint8_t EXPLR_RDF_FWMS6_ADDRESS = 12 ;
-static const uint8_t EXPLR_RDF_FWMS6_ADDRESS_LEN = 11 ;
-static const uint8_t EXPLR_RDF_FWMS6_EXIT_1 = 23 ;
-
-static const uint8_t EXPLR_RDF_FWMS7_MARK = 0 ;
-static const uint8_t EXPLR_RDF_FWMS7_MARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_FWMS7_TYPE = 8 ;
-static const uint8_t EXPLR_RDF_FWMS7_REGION = 9 ;
-static const uint8_t EXPLR_RDF_FWMS7_REGION_LEN = 3 ;
-static const uint8_t EXPLR_RDF_FWMS7_ADDRESS = 12 ;
-static const uint8_t EXPLR_RDF_FWMS7_ADDRESS_LEN = 11 ;
-static const uint8_t EXPLR_RDF_FWMS7_EXIT_1 = 23 ;
-
-static const uint8_t EXPLR_RDF_HWMS0_CHIPMARK = 0 ;
-static const uint8_t EXPLR_RDF_HWMS0_CHIPMARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_HWMS0_CONFIRMED = 8 ;
-static const uint8_t EXPLR_RDF_HWMS0_EXIT_1 = 9 ;
-
-static const uint8_t EXPLR_RDF_HWMS1_CHIPMARK = 0 ;
-static const uint8_t EXPLR_RDF_HWMS1_CHIPMARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_HWMS1_CONFIRMED = 8 ;
-static const uint8_t EXPLR_RDF_HWMS1_EXIT_1 = 9 ;
-
-static const uint8_t EXPLR_RDF_HWMS2_CHIPMARK = 0 ;
-static const uint8_t EXPLR_RDF_HWMS2_CHIPMARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_HWMS2_CONFIRMED = 8 ;
-static const uint8_t EXPLR_RDF_HWMS2_EXIT_1 = 9 ;
-
-static const uint8_t EXPLR_RDF_HWMS3_CHIPMARK = 0 ;
-static const uint8_t EXPLR_RDF_HWMS3_CHIPMARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_HWMS3_CONFIRMED = 8 ;
-static const uint8_t EXPLR_RDF_HWMS3_EXIT_1 = 9 ;
-
-static const uint8_t EXPLR_RDF_HWMS4_CHIPMARK = 0 ;
-static const uint8_t EXPLR_RDF_HWMS4_CHIPMARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_HWMS4_CONFIRMED = 8 ;
-static const uint8_t EXPLR_RDF_HWMS4_EXIT_1 = 9 ;
-
-static const uint8_t EXPLR_RDF_HWMS5_CHIPMARK = 0 ;
-static const uint8_t EXPLR_RDF_HWMS5_CHIPMARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_HWMS5_CONFIRMED = 8 ;
-static const uint8_t EXPLR_RDF_HWMS5_EXIT_1 = 9 ;
-
-static const uint8_t EXPLR_RDF_HWMS6_CHIPMARK = 0 ;
-static const uint8_t EXPLR_RDF_HWMS6_CHIPMARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_HWMS6_CONFIRMED = 8 ;
-static const uint8_t EXPLR_RDF_HWMS6_EXIT_1 = 9 ;
-
-static const uint8_t EXPLR_RDF_HWMS7_CHIPMARK = 0 ;
-static const uint8_t EXPLR_RDF_HWMS7_CHIPMARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_HWMS7_CONFIRMED = 8 ;
-static const uint8_t EXPLR_RDF_HWMS7_EXIT_1 = 9 ;
-
-static const uint8_t EXPLR_RDF_MASK_FIR = 0 ;
-static const uint8_t EXPLR_RDF_MASK_FIR_LEN = 64 ;
-
-static const uint8_t EXPLR_RDF_MASK0_MSR_PE = 12 ;
-static const uint8_t EXPLR_RDF_MASK0_EICR_PE = 13 ;
-static const uint8_t EXPLR_RDF_MASK0_HWMSX_PE = 16 ;
-static const uint8_t EXPLR_RDF_MASK0_HWMSX_PE_LEN = 8 ;
-static const uint8_t EXPLR_RDF_MASK0_FWMSX_PE = 24 ;
-static const uint8_t EXPLR_RDF_MASK0_FWMSX_PE_LEN = 8 ;
-static const uint8_t EXPLR_RDF_MASK0_RSPAR_PE = 32 ;
-static const uint8_t EXPLR_RDF_MASK0_CTCR_PE = 40 ;
-static const uint8_t EXPLR_RDF_MASK0_AACR_PE = 41 ;
-static const uint8_t EXPLR_RDF_MASK0_MCBCM_PE = 44 ;
-static const uint8_t EXPLR_RDF_MASK0_RECR_PE = 45 ;
-static const uint8_t EXPLR_RDF_MASK0_DBGR_PE = 46 ;
-static const uint8_t EXPLR_RDF_MASK0_MASK0_PE = 48 ;
-static const uint8_t EXPLR_RDF_MASK0_MASK1_PE = 49 ;
-static const uint8_t EXPLR_RDF_MASK0_CGDR_PE = 50 ;
-
-static const uint8_t EXPLR_RDF_MASK1_ECC_CTL_AF_PERR = 0 ;
-static const uint8_t EXPLR_RDF_MASK1_ECC_CTL_TCHN_PERR = 1 ;
-static const uint8_t EXPLR_RDF_MASK1_ECC_CTL_CMPMODE_ERR = 2 ;
-static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_PCX_PERR = 3 ;
-static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_SYND_PERR = 4 ;
-static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_2SYM_PERR = 5 ;
-static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_CPLX_PERR = 6 ;
-static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_EP2_PERR = 7 ;
-static const uint8_t EXPLR_RDF_MASK1_READ_ECC_DATAPATH_PARITY_ERROR = 8 ;
-static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_CMX_PERR = 9 ;
-static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_VP1_PERR = 10 ;
-static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_VP2_PERR = 11 ;
-static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_SYG_PERR = 12 ;
-static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_EF1_PERR = 13 ;
-static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_MK3_PERR = 14 ;
-static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_E1A_PERR = 15 ;
-static const uint8_t EXPLR_RDF_MASK1_UNEXPECTED_RDDATA_VALID = 16 ;
-static const uint8_t EXPLR_RDF_MASK1_MISSING_RDDATA_VALID = 17 ;
-
-static const uint8_t EXPLR_RDF_MCBCM_MCBIST_HALF_COMPARE_MASK = 0 ;
-static const uint8_t EXPLR_RDF_MCBCM_MCBIST_HALF_COMPARE_MASK_LEN = 40 ;
-static const uint8_t EXPLR_RDF_MCBCM_MCBIST_MASK_COVERAGE_SELECTOR = 40 ;
-static const uint8_t EXPLR_RDF_MCBCM_MCBIST_TRAP_NONSTOP = 41 ;
-static const uint8_t EXPLR_RDF_MCBCM_MCBIST_TRAP_CE_ENABLE = 42 ;
-static const uint8_t EXPLR_RDF_MCBCM_MCBIST_TRAP_MPE_ENABLE = 43 ;
-static const uint8_t EXPLR_RDF_MCBCM_MCBIST_TRAP_UE_ENABLE = 44 ;
-
-static const uint8_t EXPLR_RDF_MSR_CHIPMARK = 8 ;
-static const uint8_t EXPLR_RDF_MSR_CHIPMARK_LEN = 8 ;
-static const uint8_t EXPLR_RDF_MSR_RANK = 16 ;
-static const uint8_t EXPLR_RDF_MSR_RANK_LEN = 3 ;
-
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DISABLE_MEMORY_ECC_CHECK_CORRECT = 0 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DISABLE_MEMORY_ECC_CORRECT = 1 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DISABLE_MARK_STORE_WRITE = 2 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DISABLE_UE_RETRY = 3 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_ITAG_METADATA_ENABLE = 4 ;
-static const uint8_t EXPLR_RDF_RECR_DISABLE_RCD_CHECK = 5 ;
-static const uint8_t EXPLR_RDF_RECR_DISABLE_RDDATA_VALID_CHECK = 6 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DISABLE_UTC_EXIT_INCREASE = 8 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_EXIT_OVERRIDE = 9 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_EXIT_OVERRIDE_LEN = 2 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_HWMARK_EXIT1 = 11 ;
-static const uint8_t EXPLR_RDF_RECR_CAPPTAG_BYPASS_BIT_ENABLE = 14 ;
-static const uint8_t EXPLR_RDF_RECR_CAPPTAG_RETRY_BIT_ENABLE = 15 ;
-static const uint8_t EXPLR_RDF_RECR_CAPPTAG_BYPASS_BIT_SELECT = 16 ;
-static const uint8_t EXPLR_RDF_RECR_CAPPTAG_BYPASS_BIT_SELECT_LEN = 4 ;
-static const uint8_t EXPLR_RDF_RECR_CAPPTAG_RETRY_BIT_SELECT = 20 ;
-static const uint8_t EXPLR_RDF_RECR_CAPPTAG_RETRY_BIT_SELECT_LEN = 4 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DISABLE_MPE_CONFIRM = 25 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_ENABLE_UE_NOISE_WINDOW = 26 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_ENABLE_TCE_CORRECTION = 27 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_ENABLE_CHIPMARKED_SCE_NCE = 28 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_USE_ADDRESS_HASH = 29 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DATA_INVERSION = 30 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DATA_INVERSION_LEN = 2 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DISABLE_PIPE_NOERR_CLOCK_GATING = 32 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_MAINT_NO_RETRY_UE = 33 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_MAINT_NO_RETRY_MPE = 34 ;
-static const uint8_t EXPLR_RDF_RECR_MBSECCQ_ENABLE_BYPASS_MARK_PLACE = 39 ;
-static const uint8_t EXPLR_RDF_RECR_CFG_MAINT_USE_TIMERS = 40 ;
-static const uint8_t EXPLR_RDF_RECR_HWMS_RANK_SELECT = 41 ;
-static const uint8_t EXPLR_RDF_RECR_HWMS_RANK_SELECT_LEN = 6 ;
-
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R0_LEFT = 0 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R0_LEFT_LEN = 5 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R0_RIGHT = 5 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R0_RIGHT_LEN = 5 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R1_LEFT = 10 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R1_LEFT_LEN = 5 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R1_RIGHT = 15 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R1_RIGHT_LEN = 5 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R2_LEFT = 20 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R2_LEFT_LEN = 5 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R2_RIGHT = 25 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R2_RIGHT_LEN = 5 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R3_LEFT = 30 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R3_LEFT_LEN = 5 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R3_RIGHT = 35 ;
-static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R3_RIGHT_LEN = 5 ;
-
-static const uint8_t EXPLR_RDF_WOF_FIR = 0 ;
-static const uint8_t EXPLR_RDF_WOF_FIR_LEN = 64 ;
-
-static const uint8_t EXPLR_SRQ_ERR_HOLD_LAT_FIR_MASK_PAR = 0 ;
-static const uint8_t EXPLR_SRQ_ERR_HOLD_LAT_FIR_ACTION0_PAR = 1 ;
-static const uint8_t EXPLR_SRQ_ERR_HOLD_LAT_FIR_ACTION1_PAR = 2 ;
-
-static const uint8_t EXPLR_SRQ_ERR_MASK_LAT_FIR_PAR = 0 ;
-static const uint8_t EXPLR_SRQ_ERR_MASK_LAT_FIR_ACTION0_PAR = 1 ;
-static const uint8_t EXPLR_SRQ_ERR_MASK_LAT_FIR_ACTION1_PAR = 2 ;
-
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_ENABLE = 0 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_INTERVAL_TIMEBASE_SELECT = 1 ;
+static const uint8_t EXPLR_MCBIST_MCBSTATQ_RESERVED_1_3 = 1 ;
+static const uint8_t EXPLR_MCBIST_MCBSTATQ_RESERVED_1_3_LEN = 3 ;
+static const uint8_t EXPLR_MCBIST_MCBSTATQ_MCBIST_SUBTEST_NUM_INDICATOR = 4 ;
+static const uint8_t EXPLR_MCBIST_MCBSTATQ_MCBIST_SUBTEST_NUM_INDICATOR_LEN = 5 ;
+static const uint8_t EXPLR_MCBIST_MCBSTATQ_RESERVED_9_15 = 9 ;
+static const uint8_t EXPLR_MCBIST_MCBSTATQ_RESERVED_9_15_LEN = 7 ;
+
+static const uint8_t EXPLR_MCBIST_MCB_CNTLQ_START = 0 ;
+static const uint8_t EXPLR_MCBIST_MCB_CNTLQ_STOP = 1 ;
+static const uint8_t EXPLR_MCBIST_MCB_CNTLQ_RESERVED_2_5 = 2 ;
+static const uint8_t EXPLR_MCBIST_MCB_CNTLQ_RESERVED_2_5_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_MCB_CNTLQ_RESET_TRAP_CNFG = 6 ;
+static const uint8_t EXPLR_MCBIST_MCB_CNTLQ_RESET_ERROR_LOGS = 7 ;
+static const uint8_t EXPLR_MCBIST_MCB_CNTLQ_RESUME_FROM_PAUSE = 8 ;
+
+static const uint8_t EXPLR_MCBIST_MCB_CNTLSTATQ_IP = 0 ;
+static const uint8_t EXPLR_MCBIST_MCB_CNTLSTATQ_DONE = 1 ;
+static const uint8_t EXPLR_MCBIST_MCB_CNTLSTATQ_FAIL = 2 ;
+
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM = 0 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD1 = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD1_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD2 = 8 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD2_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD3 = 12 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD3_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD4 = 16 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD4_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD5 = 20 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD5_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD6 = 24 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD6_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD7 = 28 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD7_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD8 = 32 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD8_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD9 = 36 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD9_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD10 = 40 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD10_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD11 = 44 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD11_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD12 = 48 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD12_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD13 = 52 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD13_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD14 = 56 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD14_LEN = 4 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD15 = 60 ;
+static const uint8_t EXPLR_MCBIST_RCD_LRDIM_CNTL_WORD0_15Q_LRDIMM_WORD15_LEN = 4 ;
+
+static const uint8_t EXPLR_MCBIST_RUNTIMECTRQ_CFG_RUNTIME_CTR = 0 ;
+static const uint8_t EXPLR_MCBIST_RUNTIMECTRQ_CFG_RUNTIME_CTR_LEN = 37 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_ASEL = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_ASEL_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_BSEL = 8 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_BSEL_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_ABSEL = 16 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_ABSEL_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_ETSEL = 24 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_ETSEL_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_CMSEL = 32 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_CMSEL_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_CYSEL = 40 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0AQ_CFG_WAT_EVENT_CYSEL_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_WAT_MSKA = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_WAT_MSKA_LEN = 44 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_WAT_ENABLE = 44 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_INT_ARM_MODE = 45 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_EXT_ARM_MODE = 46 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_TIMER_STATE_MODE = 47 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_SET_LEVEL_ON_PULSE = 48 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_RESET_LEVEL_ON_PULSE = 49 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_ENABLE_EXT_RESET_LEVEL = 50 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_STATE_SET_DOM = 51 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_STATE_FOLLOW_LEVEL = 52 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_NOT_PATA_MODE = 53 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_NOT_PATB_MODE = 54 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_NOT_PATA_MODE2 = 55 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_NOT_PATB_MODE2 = 56 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_SLIDE_TRIG = 57 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_TRIGB_DELAY_SEL = 58 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_TRIGB_DELAY_SEL_LEN = 2 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0BQ_CFG_FORCE_TEST_MODE = 60 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG0CQ_CFG_WAT_MSKB = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0CQ_CFG_WAT_MSKB_LEN = 44 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG0DQ_CFG_WAT_PATA = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0DQ_CFG_WAT_PATA_LEN = 44 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG0EQ_CFG_WAT_PATB = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG0EQ_CFG_WAT_PATB_LEN = 44 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_ASEL = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_ASEL_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_BSEL = 8 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_BSEL_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_ABSEL = 16 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_ABSEL_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_ETSEL = 24 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_ETSEL_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_CMSEL = 32 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_CMSEL_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_CYSEL = 40 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1AQ_CFG_WAT_EVENT_CYSEL_LEN = 8 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG1BQ_CFG_WAT_MSKA = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1BQ_CFG_WAT_MSKA_LEN = 44 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1BQ_CFG_WAT_CNTL = 44 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1BQ_CFG_WAT_CNTL_LEN = 17 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG1CQ_CFG_WAT_MSKB = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1CQ_CFG_WAT_MSKB_LEN = 44 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG1DQ_CFG_WAT_PATA = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1DQ_CFG_WAT_PATA_LEN = 44 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG1EQ_CFG_WAT_PATB = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG1EQ_CFG_WAT_PATB_LEN = 44 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG2AQ_CFG_WAT_EVENT_SEL = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG2AQ_CFG_WAT_EVENT_SEL_LEN = 48 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG2BQ_CFG_WAT_MSKA = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG2BQ_CFG_WAT_MSKA_LEN = 44 ;
+static const uint8_t EXPLR_MCBIST_WATCFG2BQ_CFG_WAT_CNTL = 44 ;
+static const uint8_t EXPLR_MCBIST_WATCFG2BQ_CFG_WAT_CNTL_LEN = 17 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG2CQ_CFG_WAT_MSKB = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG2CQ_CFG_WAT_MSKB_LEN = 44 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG2DQ_CFG_WAT_PATA = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG2DQ_CFG_WAT_PATA_LEN = 44 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG2EQ_CFG_WAT_PATB = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG2EQ_CFG_WAT_PATB_LEN = 44 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG3AQ_CFG_WAT_EVENT_SEL = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG3AQ_CFG_WAT_EVENT_SEL_LEN = 48 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG3BQ_CFG_WAT_MSKA = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG3BQ_CFG_WAT_MSKA_LEN = 44 ;
+static const uint8_t EXPLR_MCBIST_WATCFG3BQ_CFG_WAT_CNTL = 44 ;
+static const uint8_t EXPLR_MCBIST_WATCFG3BQ_CFG_WAT_CNTL_LEN = 17 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG3CQ_CFG_WAT_MSKB = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG3CQ_CFG_WAT_MSKB_LEN = 44 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG3DQ_CFG_WAT_PATA = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG3DQ_CFG_WAT_PATA_LEN = 44 ;
+
+static const uint8_t EXPLR_MCBIST_WATCFG3EQ_CFG_WAT_PATB = 0 ;
+static const uint8_t EXPLR_MCBIST_WATCFG3EQ_CFG_WAT_PATB_LEN = 44 ;
+
+static const uint8_t EXPLR_MMIO_MCFGERR_RESP_CODE = 16 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_RESP_CODE_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_BDI = 20 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_ERROR_TYPE = 21 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_ERROR_TYPE_LEN = 3 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_DEVICE = 24 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_DEVICE_LEN = 5 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_FUNCTION = 29 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_FUNCTION_LEN = 3 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_DEV_FUNC_MISMATCH = 32 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_DETECT_BAD_OP = 33 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_TBIT_IS_1 = 34 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_DATA_IS_BAD = 35 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_PL_IS_INVALID = 36 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_BAD_OP_OR_ALIGN = 37 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_ADDR_NO_IMPLEMENTED = 38 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_RDATA_VLD = 39 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_TBIT = 40 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_PLEN = 41 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_PLEN_LEN = 3 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_PORTNUM = 44 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_PORTNUM_LEN = 2 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_DL = 46 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_DL_LEN = 2 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_CAPPTAG = 48 ;
+static const uint8_t EXPLR_MMIO_MCFGERR_CAPPTAG_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_MCFGERRA_ADDR = 0 ;
+static const uint8_t EXPLR_MMIO_MCFGERRA_ADDR_LEN = 64 ;
+
+static const uint8_t EXPLR_MMIO_MCHOLD_FIR_MASK_PAR_ERR = 0 ;
+static const uint8_t EXPLR_MMIO_MCHOLD_FIR_ACTION0_PAR_ERR = 1 ;
+static const uint8_t EXPLR_MMIO_MCHOLD_FIR_ACTION1_PAR_ERR = 2 ;
+
+static const uint8_t EXPLR_MMIO_MCMASK_MASK_FIR_MASK_PAR_ERR = 0 ;
+static const uint8_t EXPLR_MMIO_MCMASK_MASK_FIR_ACTION0_PAR_ERR = 1 ;
+static const uint8_t EXPLR_MMIO_MCMASK_MASK_FIR_ACTION1_PAR_ERR = 2 ;
+
+static const uint8_t EXPLR_MMIO_MDBELL_MDBELL = 0 ;
+
+static const uint8_t EXPLR_MMIO_MDBELLC_MDBELL_MDBELL = 0 ;
+
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGBUS_64_87 = 0 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGBUS_64_87_LEN = 24 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_SPARE = 24 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_SPARE_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL7 = 32 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL7_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL6 = 36 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL6_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL5 = 40 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL5_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL4 = 44 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL4_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL3 = 48 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL3_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL2 = 52 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL2_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL1 = 56 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL1_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL0 = 60 ;
+static const uint8_t EXPLR_MMIO_MDEBUG0_DBGSEL0_LEN = 4 ;
+
+static const uint8_t EXPLR_MMIO_MDEBUG1_DBGBUS_0_63 = 0 ;
+static const uint8_t EXPLR_MMIO_MDEBUG1_DBGBUS_0_63_LEN = 64 ;
+
+static const uint8_t EXPLR_MMIO_MENTERP_MMIO_ENTERPRISE_MODE = 0 ;
+static const uint8_t EXPLR_MMIO_MENTERP_HALF_DIMM_MODE = 1 ;
+static const uint8_t EXPLR_MMIO_MENTERP_CFG_ENTERPRISE_MODE = 2 ;
+
+static const uint8_t EXPLR_MMIO_MERRCTL_MODE_BITS = 0 ;
+static const uint8_t EXPLR_MMIO_MERRCTL_MODE_BITS_LEN = 44 ;
+static const uint8_t EXPLR_MMIO_MERRCTL_MODE_BITS_44_46 = 44 ;
+static const uint8_t EXPLR_MMIO_MERRCTL_MODE_BITS_44_46_LEN = 3 ;
+static const uint8_t EXPLR_MMIO_MERRCTL_PASID_CHK_DIS = 47 ;
+static const uint8_t EXPLR_MMIO_MERRCTL_ACTAG_CHK_DIS = 48 ;
+static const uint8_t EXPLR_MMIO_MERRCTL_MSCC_RNGE_CHK_DIS = 49 ;
+static const uint8_t EXPLR_MMIO_MERRCTL_MODE_BIT_50 = 50 ;
+static const uint8_t EXPLR_MMIO_MERRCTL_HOLD_ACUM = 51 ;
+static const uint8_t EXPLR_MMIO_MERRCTL_SNSC_MASTER_ENABLE = 52 ;
+static const uint8_t EXPLR_MMIO_MERRCTL_TRAP_CLEAR = 53 ;
+static const uint8_t EXPLR_MMIO_MERRCTL_WDATA_P = 54 ;
+static const uint8_t EXPLR_MMIO_MERRCTL_RNW = 55 ;
+static const uint8_t EXPLR_MMIO_MERRCTL_ADDR = 56 ;
+static const uint8_t EXPLR_MMIO_MERRCTL_ADDR_LEN = 8 ;
+
+static const uint8_t EXPLR_MMIO_MFIR_AFU_DESC_UNIMP = 0 ;
+static const uint8_t EXPLR_MMIO_MFIR_MMIO_ERR = 1 ;
+static const uint8_t EXPLR_MMIO_MFIR_SCOM_ERR = 2 ;
+static const uint8_t EXPLR_MMIO_MFIR_FSM_PERR = 3 ;
+static const uint8_t EXPLR_MMIO_MFIR_FIFO_OVERFLOW = 4 ;
+static const uint8_t EXPLR_MMIO_MFIR_CTL_REG_PERR = 5 ;
+static const uint8_t EXPLR_MMIO_MFIR_INFO_REG_PERR = 6 ;
+static const uint8_t EXPLR_MMIO_MFIR_SNSC_BOTH_STARTS_ERR = 7 ;
+static const uint8_t EXPLR_MMIO_MFIR_SNSC_MULT_SEQ_PERR = 8 ;
+static const uint8_t EXPLR_MMIO_MFIR_SNSC_FSM_PERR = 9 ;
+static const uint8_t EXPLR_MMIO_MFIR_SNSC_REG_PERR = 10 ;
+static const uint8_t EXPLR_MMIO_MFIR_ACTAG_PASID_CFG_ERR = 11 ;
+
+static const uint8_t EXPLR_MMIO_MFIRACT0_FIR_ACTION0 = 0 ;
+static const uint8_t EXPLR_MMIO_MFIRACT0_FIR_ACTION0_LEN = 12 ;
+
+static const uint8_t EXPLR_MMIO_MFIRACT1_FIR_ACTION1 = 0 ;
+static const uint8_t EXPLR_MMIO_MFIRACT1_FIR_ACTION1_LEN = 12 ;
+
+static const uint8_t EXPLR_MMIO_MFIRMASK_FIR_MASK = 0 ;
+static const uint8_t EXPLR_MMIO_MFIRMASK_FIR_MASK_LEN = 12 ;
+
+static const uint8_t EXPLR_MMIO_MFIRWOF_FIR_WOF = 0 ;
+static const uint8_t EXPLR_MMIO_MFIRWOF_FIR_WOF_LEN = 12 ;
+
+static const uint8_t EXPLR_MMIO_MHOLD0_O0MBIT_O0DID_PERR = 0 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O0CCD_PERR = 1 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O0BAR0_PERR = 2 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O0BAR1_PERR = 3 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O0BAR2_PERR = 4 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O0SSYSID_PERR = 5 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O0CAPPTR_O0ROMBAR_PERR = 6 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_OVPD_PERR = 7 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_ODSNLO_ODSNCAP_PERR = 8 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_ODSNHI_PERR = 9 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_OTLVID_OTLCAP_PERR = 10 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_OVERCAP_OTLID_PERR = 11 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_OVERCFG_PERR = 12 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_ORTCAP_PERR = 13 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_OTTCFG_PERR = 14 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_ORRCAP10_PERR = 15 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_ORRCAP32_PERR = 16 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_ORRCAP54_PERR = 17 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_ORRCAP76_PERR = 18 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_OTRCFG10_PERR = 19 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_OTRCFG32_PERR = 20 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_OTRCFG54_PERR = 21 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_OTRCFG76_PERR = 22 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O0FNVID_O0FNCAP_PERR = 23 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O0ACTAG_O0FNID_PERR = 24 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O0VSVID_O0VSCAP_PERR = 25 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O0VSID_PERR = 26 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O1MBIT_O1DID_PERR = 27 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O1CCD_PERR = 28 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O1BAR0_PERR = 29 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O1BAR1_PERR = 30 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O1BAR2_PERR = 31 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O1SSYSID_PERR = 32 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O1CAPPTR_O1ROMBAR_PERR = 33 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_OPASID_PERR = 34 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O1FNVID_O1FNCAP_PERR = 35 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O1ACTAG_O1FNID_PERR = 36 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O1INFVID_O1INFCAP_PERR = 37 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O1INFOFF_O1INFID_PERR = 38 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O1INFDAT_PERR = 39 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_OCTRLVID_OCTRLCAP_PERR = 40 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_OCTRLENB_OCTRLID_PERR = 41 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_OCTRLPID_PERR = 42 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_OCTRLTAG_PERR = 43 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O1VSVID_O1VSCAP_PERR = 44 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_O1VSID_PERR = 45 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_AFU_DESC_UNIMP = 46 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_MMIO_ERR = 47 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_SCOM_ERR = 48 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_SCOM_CCMD_FSMPERR = 49 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_SCOM_CRESP_FSMPERR = 50 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_CTL_MMIO_FSMPERR = 51 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_CTL_CCMD_FSMPERR = 52 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_CTL_CRESP_FSMPERR = 53 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_PIB_FSMPERR = 54 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_CMUX_ARBPERR = 55 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_CFG_CMDFIFO_OVRFLOW = 56 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_CFG_RESPFIFO_OVRFLOW = 57 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_CFGP_FIFO_OVRFLOW = 58 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_MERRCTL_PERR = 59 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_MHOLD1_PERR = 60 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_MMASK1_PERR = 61 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_MDBELL_PERR = 62 ;
+static const uint8_t EXPLR_MMIO_MHOLD0_MSCCRNGE_PERR = 63 ;
+
+static const uint8_t EXPLR_MMIO_MHOLD1_ONAME0_ODESCTML_PERR = 0 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_ONAME21_PERR = 1 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_ONAME43_PERR = 2 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_OAFUVER_ONAME5_PERR = 3 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_OGMMIOOF_PERR = 4 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_OGMMIOSZ_PERR = 5 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_OPMMIOOOF_PERR = 6 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_OPMMIOST_PERR = 7 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_OMEMADDR_PERR = 8 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_OWWID10_PERR = 9 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_OWWID32_PERR = 10 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_MHOLD0_PERR = 11 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_MMASK0_PERR = 12 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_MMIOERR_PERR = 13 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_MMIOEWD_PERR = 14 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_SCOMEWD_PERR = 15 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_MCFGERRA_PERR = 16 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_MCFGERRB_PERR = 17 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_BOTH_STARTS_ERR = 18 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_MULT_SEQ_PERR = 19 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_FSM_PERR = 20 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_OCTHERM_PERR = 21 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_D0THERM_PERR = 22 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_D1THERM_PERR = 23 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_RDWR_PERR = 24 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_ACTPWRUP_PERR = 25 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_FRAMESR_PERR = 26 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_HISTOBASELOW_PERR = 27 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_SNSC_HISTOBASEHIGH_PERR = 28 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_O0VSTLXA_PERR = 29 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_O0VSTLXB_PERR = 30 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_O0VSDLXA_PERR = 31 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_O0VSDLXB_PERR = 32 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_O0VSFLSH_PERR = 33 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_BAD_FUNC_ACTAG_LENGTH = 34 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_BAD_AFU_ACTAG_LENGTH = 35 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_BAD_FUNC_PASID_LENGTH = 36 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_BAD_AFU_PASID_LENGTH = 37 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_MENTRP_PERR = 38 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_OSYSMEML_PERR = 39 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_MDEBUG0_PERR = 40 ;
+static const uint8_t EXPLR_MMIO_MHOLD1_MDEBUG1_PERR = 41 ;
+
+static const uint8_t EXPLR_MMIO_MMASK0_MSK = 0 ;
+static const uint8_t EXPLR_MMIO_MMASK0_MSK_LEN = 64 ;
+
+static const uint8_t EXPLR_MMIO_MMASK1_MSK = 0 ;
+static const uint8_t EXPLR_MMIO_MMASK1_MSK_LEN = 42 ;
+
+static const uint8_t EXPLR_MMIO_MMIOERR_WDATA_P = 0 ;
+static const uint8_t EXPLR_MMIO_MMIOERR_WDATA_P_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_MMIOERR_INFO = 8 ;
+static const uint8_t EXPLR_MMIO_MMIOERR_INFO_LEN = 16 ;
+static const uint8_t EXPLR_MMIO_MMIOERR_PLEN = 25 ;
+static const uint8_t EXPLR_MMIO_MMIOERR_PLEN_LEN = 3 ;
+static const uint8_t EXPLR_MMIO_MMIOERR_RNW = 28 ;
+static const uint8_t EXPLR_MMIO_MMIOERR_ADDR = 29 ;
+static const uint8_t EXPLR_MMIO_MMIOERR_ADDR_LEN = 35 ;
+
+static const uint8_t EXPLR_MMIO_MMIOEWD_WDATA = 0 ;
+static const uint8_t EXPLR_MMIO_MMIOEWD_WDATA_LEN = 64 ;
+
+static const uint8_t EXPLR_MMIO_MPIBERR0_ERRINFO = 0 ;
+static const uint8_t EXPLR_MMIO_MPIBERR0_ERRINFO_LEN = 64 ;
+
+static const uint8_t EXPLR_MMIO_MPIBERR1_ERRINFO = 0 ;
+static const uint8_t EXPLR_MMIO_MPIBERR1_ERRINFO_LEN = 64 ;
+
+static const uint8_t EXPLR_MMIO_MPIBERR2_ERRINFO = 0 ;
+static const uint8_t EXPLR_MMIO_MPIBERR2_ERRINFO_LEN = 64 ;
+
+static const uint8_t EXPLR_MMIO_MPIBERR3_ERRINFO = 0 ;
+static const uint8_t EXPLR_MMIO_MPIBERR3_ERRINFO_LEN = 64 ;
+
+static const uint8_t EXPLR_MMIO_MSCCRNGE_LOWER = 0 ;
+static const uint8_t EXPLR_MMIO_MSCCRNGE_LOWER_LEN = 29 ;
+static const uint8_t EXPLR_MMIO_MSCCRNGE_UPPER = 32 ;
+static const uint8_t EXPLR_MMIO_MSCCRNGE_UPPER_LEN = 32 ;
+
+static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_ACTAG_BASE = 4 ;
+static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_ACTAG_BASE_LEN = 12 ;
+static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_ACTAG_LENGTH = 20 ;
+static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_ACTAG_LENGTH_LEN = 12 ;
+static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_AFU_PRESENT = 32 ;
+static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_MAX_AFU_INDEX = 34 ;
+static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_MAX_AFU_INDEX_LEN = 6 ;
+static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_FUNCTION_RESET = 40 ;
+static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_DVSEC_ID = 48 ;
+static const uint8_t EXPLR_MMIO_O0ACTAG_O0FNID_DVSEC_ID_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_O0BAR0_BAR_ADDRESS = 0 ;
+static const uint8_t EXPLR_MMIO_O0BAR0_BAR_ADDRESS_LEN = 60 ;
+static const uint8_t EXPLR_MMIO_O0BAR0_PREFETCHABLE = 60 ;
+static const uint8_t EXPLR_MMIO_O0BAR0_TYPE = 61 ;
+static const uint8_t EXPLR_MMIO_O0BAR0_TYPE_LEN = 2 ;
+static const uint8_t EXPLR_MMIO_O0BAR0_ADDRESS_SPACE = 63 ;
+
+static const uint8_t EXPLR_MMIO_O0BAR1_BAR_ADDRESS = 0 ;
+static const uint8_t EXPLR_MMIO_O0BAR1_BAR_ADDRESS_LEN = 60 ;
+static const uint8_t EXPLR_MMIO_O0BAR1_PREFETCHABLE = 60 ;
+static const uint8_t EXPLR_MMIO_O0BAR1_TYPE = 61 ;
+static const uint8_t EXPLR_MMIO_O0BAR1_TYPE_LEN = 2 ;
+static const uint8_t EXPLR_MMIO_O0BAR1_ADDRESS_SPACE = 63 ;
+
+static const uint8_t EXPLR_MMIO_O0BAR2_BAR_ADDRESS = 0 ;
+static const uint8_t EXPLR_MMIO_O0BAR2_BAR_ADDRESS_LEN = 60 ;
+static const uint8_t EXPLR_MMIO_O0BAR2_PREFETCHABLE = 60 ;
+static const uint8_t EXPLR_MMIO_O0BAR2_TYPE = 61 ;
+static const uint8_t EXPLR_MMIO_O0BAR2_TYPE_LEN = 2 ;
+static const uint8_t EXPLR_MMIO_O0BAR2_ADDRESS_SPACE = 63 ;
+
+static const uint8_t EXPLR_MMIO_O0CAPPTR_O0ROMBAR_ROM_BASE = 32 ;
+static const uint8_t EXPLR_MMIO_O0CAPPTR_O0ROMBAR_ROM_BASE_LEN = 21 ;
+static const uint8_t EXPLR_MMIO_O0CAPPTR_O0ROMBAR_ROM_ENABLE = 63 ;
+
+static const uint8_t EXPLR_MMIO_O0CCD_MULTI_FUNCTION = 8 ;
+static const uint8_t EXPLR_MMIO_O0CCD_CLASS_CODE = 32 ;
+static const uint8_t EXPLR_MMIO_O0CCD_CLASS_CODE_LEN = 24 ;
+static const uint8_t EXPLR_MMIO_O0CCD_REVISION_ID = 56 ;
+static const uint8_t EXPLR_MMIO_O0CCD_REVISION_ID_LEN = 8 ;
+
+static const uint8_t EXPLR_MMIO_O0MBIT_O0DID_CAPABILITIES_LIST = 11 ;
+static const uint8_t EXPLR_MMIO_O0MBIT_O0DID_MEMORY_SPACE = 30 ;
+static const uint8_t EXPLR_MMIO_O0MBIT_O0DID_DEVICE_ID = 32 ;
+static const uint8_t EXPLR_MMIO_O0MBIT_O0DID_DEVICE_ID_LEN = 16 ;
+static const uint8_t EXPLR_MMIO_O0MBIT_O0DID_VENDOR_ID = 48 ;
+static const uint8_t EXPLR_MMIO_O0MBIT_O0DID_VENDOR_ID_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_O0SSYSID_SUBSYSTEM_ID = 0 ;
+static const uint8_t EXPLR_MMIO_O0SSYSID_SUBSYSTEM_ID_LEN = 16 ;
+static const uint8_t EXPLR_MMIO_O0SSYSID_SUBSYSTEM_VENDOR_ID = 16 ;
+static const uint8_t EXPLR_MMIO_O0SSYSID_SUBSYSTEM_VENDOR_ID_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_O0VSDLXA_DLX_PORT1 = 0 ;
+static const uint8_t EXPLR_MMIO_O0VSDLXA_DLX_PORT1_LEN = 32 ;
+static const uint8_t EXPLR_MMIO_O0VSDLXA_DLX_PORT0 = 32 ;
+static const uint8_t EXPLR_MMIO_O0VSDLXA_DLX_PORT0_LEN = 32 ;
+
+static const uint8_t EXPLR_MMIO_O0VSDLXB_DLX_PORT3 = 0 ;
+static const uint8_t EXPLR_MMIO_O0VSDLXB_DLX_PORT3_LEN = 32 ;
+static const uint8_t EXPLR_MMIO_O0VSDLXB_DLX_PORT2 = 32 ;
+static const uint8_t EXPLR_MMIO_O0VSDLXB_DLX_PORT2_LEN = 32 ;
+
+static const uint8_t EXPLR_MMIO_O0VSFLSH_DATA = 0 ;
+static const uint8_t EXPLR_MMIO_O0VSFLSH_DATA_LEN = 32 ;
+static const uint8_t EXPLR_MMIO_O0VSFLSH_CONTROL = 44 ;
+static const uint8_t EXPLR_MMIO_O0VSFLSH_CONTROL_LEN = 20 ;
+
+static const uint8_t EXPLR_MMIO_O0VSID_VENDOR_UNIQUE = 32 ;
+static const uint8_t EXPLR_MMIO_O0VSID_VENDOR_UNIQUE_LEN = 16 ;
+static const uint8_t EXPLR_MMIO_O0VSID_DVSEC_ID = 48 ;
+static const uint8_t EXPLR_MMIO_O0VSID_DVSEC_ID_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_O0VSTLXA_TLX_PORT1 = 0 ;
+static const uint8_t EXPLR_MMIO_O0VSTLXA_TLX_PORT1_LEN = 32 ;
+static const uint8_t EXPLR_MMIO_O0VSTLXA_TLX_PORT0 = 32 ;
+static const uint8_t EXPLR_MMIO_O0VSTLXA_TLX_PORT0_LEN = 32 ;
+
+static const uint8_t EXPLR_MMIO_O0VSTLXB_TLX_PORT3 = 0 ;
+static const uint8_t EXPLR_MMIO_O0VSTLXB_TLX_PORT3_LEN = 32 ;
+static const uint8_t EXPLR_MMIO_O0VSTLXB_TLX_PORT2 = 32 ;
+static const uint8_t EXPLR_MMIO_O0VSTLXB_TLX_PORT2_LEN = 32 ;
+
+static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_ACTAG_BASE = 4 ;
+static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_ACTAG_BASE_LEN = 12 ;
+static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_ACTAG_LENGTH = 20 ;
+static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_ACTAG_LENGTH_LEN = 12 ;
+static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_AFU_PRESENT = 32 ;
+static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_MAX_AFU_INDEX = 34 ;
+static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_MAX_AFU_INDEX_LEN = 6 ;
+static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_FUNCTION_RESET = 40 ;
+static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_DVSEC_ID = 48 ;
+static const uint8_t EXPLR_MMIO_O1ACTAG_O1FNID_DVSEC_ID_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_O1BAR0_BAR_ADDRESS = 0 ;
+static const uint8_t EXPLR_MMIO_O1BAR0_BAR_ADDRESS_LEN = 29 ;
+static const uint8_t EXPLR_MMIO_O1BAR0_PREFETCHABLE = 60 ;
+static const uint8_t EXPLR_MMIO_O1BAR0_TYPE = 61 ;
+static const uint8_t EXPLR_MMIO_O1BAR0_TYPE_LEN = 2 ;
+static const uint8_t EXPLR_MMIO_O1BAR0_ADDRESS_SPACE = 63 ;
+
+static const uint8_t EXPLR_MMIO_O1BAR1_BAR_ADDRESS = 0 ;
+static const uint8_t EXPLR_MMIO_O1BAR1_BAR_ADDRESS_LEN = 60 ;
+static const uint8_t EXPLR_MMIO_O1BAR1_PREFETCHABLE = 60 ;
+static const uint8_t EXPLR_MMIO_O1BAR1_TYPE = 61 ;
+static const uint8_t EXPLR_MMIO_O1BAR1_TYPE_LEN = 2 ;
+static const uint8_t EXPLR_MMIO_O1BAR1_ADDRESS_SPACE = 63 ;
+
+static const uint8_t EXPLR_MMIO_O1BAR2_BAR_ADDRESS = 0 ;
+static const uint8_t EXPLR_MMIO_O1BAR2_BAR_ADDRESS_LEN = 60 ;
+static const uint8_t EXPLR_MMIO_O1BAR2_PREFETCHABLE = 60 ;
+static const uint8_t EXPLR_MMIO_O1BAR2_TYPE = 61 ;
+static const uint8_t EXPLR_MMIO_O1BAR2_TYPE_LEN = 2 ;
+static const uint8_t EXPLR_MMIO_O1BAR2_ADDRESS_SPACE = 63 ;
+
+static const uint8_t EXPLR_MMIO_O1CAPPTR_O1ROMBAR_ROM_BASE = 32 ;
+static const uint8_t EXPLR_MMIO_O1CAPPTR_O1ROMBAR_ROM_BASE_LEN = 21 ;
+static const uint8_t EXPLR_MMIO_O1CAPPTR_O1ROMBAR_ROM_ENABLE = 63 ;
+
+static const uint8_t EXPLR_MMIO_O1CCD_MULTI_FUNCTION = 8 ;
+static const uint8_t EXPLR_MMIO_O1CCD_CLASS_CODE = 32 ;
+static const uint8_t EXPLR_MMIO_O1CCD_CLASS_CODE_LEN = 24 ;
+static const uint8_t EXPLR_MMIO_O1CCD_REVISION_ID = 56 ;
+static const uint8_t EXPLR_MMIO_O1CCD_REVISION_ID_LEN = 8 ;
+
+static const uint8_t EXPLR_MMIO_O1INFDAT_AFU_DESCRIPTOR_DATA = 32 ;
+static const uint8_t EXPLR_MMIO_O1INFDAT_AFU_DESCRIPTOR_DATA_LEN = 32 ;
+
+static const uint8_t EXPLR_MMIO_O1INFOFF_O1INFID_DATA_VALID = 0 ;
+static const uint8_t EXPLR_MMIO_O1INFOFF_O1INFID_AFU_DESCRIPTOR_OFFSET = 1 ;
+static const uint8_t EXPLR_MMIO_O1INFOFF_O1INFID_AFU_DESCRIPTOR_OFFSET_LEN = 31 ;
+static const uint8_t EXPLR_MMIO_O1INFOFF_O1INFID_AFU_INFO_INDEX = 42 ;
+static const uint8_t EXPLR_MMIO_O1INFOFF_O1INFID_AFU_INFO_INDEX_LEN = 6 ;
+static const uint8_t EXPLR_MMIO_O1INFOFF_O1INFID_DVSEC_ID = 48 ;
+static const uint8_t EXPLR_MMIO_O1INFOFF_O1INFID_DVSEC_ID_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_O1MBIT_O1DID_CAPABILITIES_LIST = 11 ;
+static const uint8_t EXPLR_MMIO_O1MBIT_O1DID_MEMORY_SPACE = 30 ;
+static const uint8_t EXPLR_MMIO_O1MBIT_O1DID_DEVICE_ID = 32 ;
+static const uint8_t EXPLR_MMIO_O1MBIT_O1DID_DEVICE_ID_LEN = 16 ;
+static const uint8_t EXPLR_MMIO_O1MBIT_O1DID_VENDOR_ID = 48 ;
+static const uint8_t EXPLR_MMIO_O1MBIT_O1DID_VENDOR_ID_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_O1SSYSID_SUBSYSTEM_ID = 0 ;
+static const uint8_t EXPLR_MMIO_O1SSYSID_SUBSYSTEM_ID_LEN = 16 ;
+static const uint8_t EXPLR_MMIO_O1SSYSID_SUBSYSTEM_VENDOR_ID = 16 ;
+static const uint8_t EXPLR_MMIO_O1SSYSID_SUBSYSTEM_VENDOR_ID_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_O1VSID_VENDOR_UNIQUE = 32 ;
+static const uint8_t EXPLR_MMIO_O1VSID_VENDOR_UNIQUE_LEN = 16 ;
+static const uint8_t EXPLR_MMIO_O1VSID_DVSEC_ID = 48 ;
+static const uint8_t EXPLR_MMIO_O1VSID_DVSEC_ID_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_VERSION_MAJOR = 0 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_VERSION_MAJOR_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_VERSION_MINOR = 8 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_VERSION_MINOR_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_C_TYPE = 16 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_C_TYPE_LEN = 3 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_M_TYPE = 19 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_AFU_M_TYPE_LEN = 3 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_PROFILE = 24 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_PROFILE_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_23 = 32 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_23_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_22 = 40 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_22_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_21 = 48 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_21_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_20 = 56 ;
+static const uint8_t EXPLR_MMIO_OAFUVER_ONAME5_NAME_SPACE_20_LEN = 8 ;
+
+static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_AFU_UNIQUE = 0 ;
+static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_AFU_UNIQUE_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_FENCE_AFU = 6 ;
+static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_ENABLE_AFU = 7 ;
+static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_RESET_AFU = 8 ;
+static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_TERMINATE_VALID = 11 ;
+static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_PASID_TERMINATION_VALUE = 12 ;
+static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_PASID_TERMINATION_VALUE_LEN = 20 ;
+static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_AFU_CONTROL_INDEX = 42 ;
+static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_AFU_CONTROL_INDEX_LEN = 6 ;
+static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_DVSEC_ID = 48 ;
+static const uint8_t EXPLR_MMIO_OCTRLENB_OCTRLID_DVSEC_ID_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_OCTRLPID_METADATA_SUPPORTED = 0 ;
+static const uint8_t EXPLR_MMIO_OCTRLPID_METADATA_ENABLED = 1 ;
+static const uint8_t EXPLR_MMIO_OCTRLPID_HTRL = 2 ;
+static const uint8_t EXPLR_MMIO_OCTRLPID_HTRL_LEN = 3 ;
+static const uint8_t EXPLR_MMIO_OCTRLPID_PASID_BASE = 12 ;
+static const uint8_t EXPLR_MMIO_OCTRLPID_PASID_BASE_LEN = 20 ;
+static const uint8_t EXPLR_MMIO_OCTRLPID_PASID_LENGTH_ENABLED = 51 ;
+static const uint8_t EXPLR_MMIO_OCTRLPID_PASID_LENGTH_ENABLED_LEN = 5 ;
+static const uint8_t EXPLR_MMIO_OCTRLPID_PASID_LENGTH_SUPPORTED = 59 ;
+static const uint8_t EXPLR_MMIO_OCTRLPID_PASID_LENGTH_SUPPORTED_LEN = 5 ;
+
+static const uint8_t EXPLR_MMIO_OCTRLTAG_AFU_ACTAG_BASE = 20 ;
+static const uint8_t EXPLR_MMIO_OCTRLTAG_AFU_ACTAG_BASE_LEN = 12 ;
+static const uint8_t EXPLR_MMIO_OCTRLTAG_AFU_ACTAG_LENGTH_ENABLED = 36 ;
+static const uint8_t EXPLR_MMIO_OCTRLTAG_AFU_ACTAG_LENGTH_ENABLED_LEN = 12 ;
+static const uint8_t EXPLR_MMIO_OCTRLTAG_AFU_ACTAG_LENGTH_SUPPORTED = 52 ;
+static const uint8_t EXPLR_MMIO_OCTRLTAG_AFU_ACTAG_LENGTH_SUPPORTED_LEN = 12 ;
+
+static const uint8_t EXPLR_MMIO_ODSNHI_DSN_HIGH = 32 ;
+static const uint8_t EXPLR_MMIO_ODSNHI_DSN_HIGH_LEN = 32 ;
+
+static const uint8_t EXPLR_MMIO_ODSNLO_ODSNCAP_DSN_LOW = 0 ;
+static const uint8_t EXPLR_MMIO_ODSNLO_ODSNCAP_DSN_LOW_LEN = 32 ;
+
+static const uint8_t EXPLR_MMIO_OGMMIOOF_OFFSET = 0 ;
+static const uint8_t EXPLR_MMIO_OGMMIOOF_OFFSET_LEN = 48 ;
+static const uint8_t EXPLR_MMIO_OGMMIOOF_BAR = 61 ;
+static const uint8_t EXPLR_MMIO_OGMMIOOF_BAR_LEN = 3 ;
+
+static const uint8_t EXPLR_MMIO_OGMMIOSZ_SIZE = 32 ;
+static const uint8_t EXPLR_MMIO_OGMMIOSZ_SIZE_LEN = 32 ;
+
+static const uint8_t EXPLR_MMIO_OMEMADDR_ADDR = 0 ;
+static const uint8_t EXPLR_MMIO_OMEMADDR_ADDR_LEN = 64 ;
+
+static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_3 = 0 ;
+static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_3_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_2 = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_2_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_1 = 16 ;
+static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_1_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_0 = 24 ;
+static const uint8_t EXPLR_MMIO_ONAME0_ODESCTML_NAME_SPACE_0_LEN = 8 ;
+
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_11 = 0 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_11_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_10 = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_10_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_9 = 16 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_9_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_8 = 24 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_8_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_7 = 32 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_7_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_6 = 40 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_6_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_5 = 48 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_5_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_4 = 56 ;
+static const uint8_t EXPLR_MMIO_ONAME21_NAME_SPACE_4_LEN = 8 ;
+
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_19 = 0 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_19_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_18 = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_18_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_17 = 16 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_17_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_16 = 24 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_16_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_15 = 32 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_15_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_14 = 40 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_14_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_13 = 48 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_13_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_12 = 56 ;
+static const uint8_t EXPLR_MMIO_ONAME43_NAME_SPACE_12_LEN = 8 ;
+
+static const uint8_t EXPLR_MMIO_OPASID_MAX_PASID_WIDTH = 19 ;
+static const uint8_t EXPLR_MMIO_OPASID_MAX_PASID_WIDTH_LEN = 5 ;
+
+static const uint8_t EXPLR_MMIO_OPMMIOOF_OFFSET = 0 ;
+static const uint8_t EXPLR_MMIO_OPMMIOOF_OFFSET_LEN = 48 ;
+static const uint8_t EXPLR_MMIO_OPMMIOOF_BAR = 61 ;
+static const uint8_t EXPLR_MMIO_OPMMIOOF_BAR_LEN = 3 ;
+
+static const uint8_t EXPLR_MMIO_OPMMIOST_MEM_SIZE = 24 ;
+static const uint8_t EXPLR_MMIO_OPMMIOST_MEM_SIZE_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_OPMMIOST_STRIDE = 32 ;
+static const uint8_t EXPLR_MMIO_OPMMIOST_STRIDE_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_55 = 0 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_55_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_54 = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_54_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_53 = 8 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_53_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_52 = 12 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_52_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_51 = 16 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_51_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_50 = 20 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_50_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_49 = 24 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_49_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_48 = 28 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_48_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_63 = 32 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_63_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_62 = 36 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_62_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_61 = 40 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_61_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_60 = 44 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_60_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_59 = 48 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_59_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_58 = 52 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_58_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_57 = 56 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_57_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_56 = 60 ;
+static const uint8_t EXPLR_MMIO_ORRCAP10_TEMPLATE_56_LEN = 4 ;
+
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_39 = 0 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_39_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_38 = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_38_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_37 = 8 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_37_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_36 = 12 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_36_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_35 = 16 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_35_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_34 = 20 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_34_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_33 = 24 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_33_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_32 = 28 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_32_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_47 = 32 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_47_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_46 = 36 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_46_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_45 = 40 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_45_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_44 = 44 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_44_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_43 = 48 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_43_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_42 = 52 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_42_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_41 = 56 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_41_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_40 = 60 ;
+static const uint8_t EXPLR_MMIO_ORRCAP32_TEMPLATE_40_LEN = 4 ;
+
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_23 = 0 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_23_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_22 = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_22_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_21 = 8 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_21_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_20 = 12 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_20_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_19 = 16 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_19_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_18 = 20 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_18_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_17 = 24 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_17_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_16 = 28 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_16_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_31 = 32 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_31_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_30 = 36 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_30_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_29 = 40 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_29_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_28 = 44 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_28_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_27 = 48 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_27_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_26 = 52 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_26_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_25 = 56 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_25_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_24 = 60 ;
+static const uint8_t EXPLR_MMIO_ORRCAP54_TEMPLATE_24_LEN = 4 ;
+
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_7 = 0 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_7_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_6 = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_6_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_5 = 8 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_5_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_4 = 12 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_4_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_3 = 16 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_3_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_2 = 20 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_2_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_1 = 24 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_1_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_0 = 28 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_0_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_15 = 32 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_15_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_14 = 36 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_14_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_13 = 40 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_13_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_12 = 44 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_12_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_11 = 48 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_11_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_10 = 52 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_10_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_9 = 56 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_9_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_8 = 60 ;
+static const uint8_t EXPLR_MMIO_ORRCAP76_TEMPLATE_8_LEN = 4 ;
+
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_31 = 0 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_30 = 1 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_29 = 2 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_28 = 3 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_27 = 4 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_26 = 5 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_25 = 6 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_24 = 7 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_23 = 8 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_22 = 9 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_21 = 10 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_20 = 11 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_19 = 12 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_18 = 13 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_17 = 14 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_16 = 15 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_15 = 16 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_14 = 17 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_13 = 18 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_12 = 19 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_11 = 20 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_10 = 21 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_9 = 22 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_8 = 23 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_7 = 24 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_6 = 25 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_5 = 26 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_4 = 27 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_3 = 28 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_2 = 29 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_1 = 30 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_0 = 31 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_63 = 32 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_62 = 33 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_61 = 34 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_60 = 35 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_59 = 36 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_58 = 37 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_57 = 38 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_56 = 39 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_55 = 40 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_54 = 41 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_53 = 42 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_52 = 43 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_51 = 44 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_50 = 45 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_49 = 46 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_48 = 47 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_47 = 48 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_46 = 49 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_45 = 50 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_44 = 51 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_43 = 52 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_42 = 53 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_41 = 54 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_40 = 55 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_39 = 56 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_38 = 57 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_37 = 58 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_36 = 59 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_35 = 60 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_34 = 61 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_33 = 62 ;
+static const uint8_t EXPLR_MMIO_ORTCAP_TEMPLATE_32 = 63 ;
+
+static const uint8_t EXPLR_MMIO_OSYSMEML_SYSLEN = 0 ;
+static const uint8_t EXPLR_MMIO_OSYSMEML_SYSLEN_LEN = 48 ;
+
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_55 = 0 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_55_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_54 = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_54_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_53 = 8 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_53_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_52 = 12 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_52_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_51 = 16 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_51_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_50 = 20 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_50_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_49 = 24 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_49_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_48 = 28 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_48_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_63 = 32 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_63_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_62 = 36 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_62_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_61 = 40 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_61_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_60 = 44 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_60_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_59 = 48 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_59_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_58 = 52 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_58_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_57 = 56 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_57_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_56 = 60 ;
+static const uint8_t EXPLR_MMIO_OTRCFG10_TEMPLATE_56_LEN = 4 ;
+
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_39 = 0 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_39_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_38 = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_38_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_37 = 8 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_37_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_36 = 12 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_36_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_35 = 16 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_35_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_34 = 20 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_34_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_33 = 24 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_33_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_32 = 28 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_32_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_47 = 32 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_47_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_46 = 36 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_46_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_45 = 40 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_45_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_44 = 44 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_44_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_43 = 48 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_43_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_42 = 52 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_42_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_41 = 56 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_41_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_40 = 60 ;
+static const uint8_t EXPLR_MMIO_OTRCFG32_TEMPLATE_40_LEN = 4 ;
+
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_23 = 0 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_23_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_22 = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_22_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_21 = 8 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_21_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_20 = 12 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_20_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_19 = 16 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_19_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_18 = 20 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_18_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_17 = 24 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_17_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_16 = 28 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_16_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_31 = 32 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_31_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_30 = 36 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_30_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_29 = 40 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_29_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_28 = 44 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_28_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_27 = 48 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_27_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_26 = 52 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_26_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_25 = 56 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_25_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_24 = 60 ;
+static const uint8_t EXPLR_MMIO_OTRCFG54_TEMPLATE_24_LEN = 4 ;
+
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_7 = 0 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_7_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_6 = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_6_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_5 = 8 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_5_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_4 = 12 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_4_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_3 = 16 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_3_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_2 = 20 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_2_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_1 = 24 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_1_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_0 = 28 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_0_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_15 = 32 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_15_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_14 = 36 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_14_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_13 = 40 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_13_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_12 = 44 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_12_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_11 = 48 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_11_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_10 = 52 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_10_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_9 = 56 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_9_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_8 = 60 ;
+static const uint8_t EXPLR_MMIO_OTRCFG76_TEMPLATE_8_LEN = 4 ;
+
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_31 = 0 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_30 = 1 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_29 = 2 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_28 = 3 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_27 = 4 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_26 = 5 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_25 = 6 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_24 = 7 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_23 = 8 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_22 = 9 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_21 = 10 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_20 = 11 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_19 = 12 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_18 = 13 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_17 = 14 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_16 = 15 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_15 = 16 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_14 = 17 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_13 = 18 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_12 = 19 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_11 = 20 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_10 = 21 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_9 = 22 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_8 = 23 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_7 = 24 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_6 = 25 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_5 = 26 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_4 = 27 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_3 = 28 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_2 = 29 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_1 = 30 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_0 = 31 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_63 = 32 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_62 = 33 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_61 = 34 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_60 = 35 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_59 = 36 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_58 = 37 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_57 = 38 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_56 = 39 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_55 = 40 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_54 = 41 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_53 = 42 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_52 = 43 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_51 = 44 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_50 = 45 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_49 = 46 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_48 = 47 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_47 = 48 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_46 = 49 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_45 = 50 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_44 = 51 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_43 = 52 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_42 = 53 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_41 = 54 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_40 = 55 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_39 = 56 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_38 = 57 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_37 = 58 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_36 = 59 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_35 = 60 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_34 = 61 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_33 = 62 ;
+static const uint8_t EXPLR_MMIO_OTTCFG_TEMPLATE_32 = 63 ;
+
+static const uint8_t EXPLR_MMIO_OVERCAP_OTLID_TL_MAJOR_VERSION_CAPABILITY = 0 ;
+static const uint8_t EXPLR_MMIO_OVERCAP_OTLID_TL_MAJOR_VERSION_CAPABILITY_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_OVERCAP_OTLID_TL_MINOR_VERSION_CAPABILITY = 8 ;
+static const uint8_t EXPLR_MMIO_OVERCAP_OTLID_TL_MINOR_VERSION_CAPABILITY_LEN = 8 ;
+
+static const uint8_t EXPLR_MMIO_OVERCFG_TL_MAJOR_VERSION_CONFIGURATION = 32 ;
+static const uint8_t EXPLR_MMIO_OVERCFG_TL_MAJOR_VERSION_CONFIGURATION_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_OVERCFG_TL_MINOR_VERSION_CONFIGURATION = 40 ;
+static const uint8_t EXPLR_MMIO_OVERCFG_TL_MINOR_VERSION_CONFIGURATION_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_OVERCFG_LONG_BACK_OFF_TIMER = 56 ;
+static const uint8_t EXPLR_MMIO_OVERCFG_LONG_BACK_OFF_TIMER_LEN = 4 ;
+static const uint8_t EXPLR_MMIO_OVERCFG_SHORT_BACK_OFF_TIMER = 60 ;
+static const uint8_t EXPLR_MMIO_OVERCFG_SHORT_BACK_OFF_TIMER_LEN = 4 ;
+
+static const uint8_t EXPLR_MMIO_OVPD_DATA = 0 ;
+static const uint8_t EXPLR_MMIO_OVPD_DATA_LEN = 32 ;
+static const uint8_t EXPLR_MMIO_OVPD_FLAG = 32 ;
+static const uint8_t EXPLR_MMIO_OVPD_ADDRESS = 33 ;
+static const uint8_t EXPLR_MMIO_OVPD_ADDRESS_LEN = 15 ;
+static const uint8_t EXPLR_MMIO_OVPD_NEXT_POINTER = 48 ;
+static const uint8_t EXPLR_MMIO_OVPD_NEXT_POINTER_LEN = 8 ;
+static const uint8_t EXPLR_MMIO_OVPD_CAPABILITY_ID = 56 ;
+static const uint8_t EXPLR_MMIO_OVPD_CAPABILITY_ID_LEN = 8 ;
+
+static const uint8_t EXPLR_MMIO_OWWID10_ID = 0 ;
+static const uint8_t EXPLR_MMIO_OWWID10_ID_LEN = 64 ;
+
+static const uint8_t EXPLR_MMIO_OWWID32_ID = 0 ;
+static const uint8_t EXPLR_MMIO_OWWID32_ID_LEN = 64 ;
+
+static const uint8_t EXPLR_MMIO_SCOMEWD_WDATA = 0 ;
+static const uint8_t EXPLR_MMIO_SCOMEWD_WDATA_LEN = 64 ;
+
+static const uint8_t EXPLR_MMIO_SNSC_ACTPWRUP_ACTSCOUNT = 0 ;
+static const uint8_t EXPLR_MMIO_SNSC_ACTPWRUP_ACTSCOUNT_LEN = 32 ;
+static const uint8_t EXPLR_MMIO_SNSC_ACTPWRUP_POWERUPSCOUNT = 32 ;
+static const uint8_t EXPLR_MMIO_SNSC_ACTPWRUP_POWERUPSCOUNT_LEN = 32 ;
+
+static const uint8_t EXPLR_MMIO_SNSC_D0THERM_PRESENTBIT = 45 ;
+static const uint8_t EXPLR_MMIO_SNSC_D0THERM_VALIDBIT = 46 ;
+static const uint8_t EXPLR_MMIO_SNSC_D0THERM_ERRORBIT = 47 ;
+static const uint8_t EXPLR_MMIO_SNSC_D0THERM_THERMALDATA = 48 ;
+static const uint8_t EXPLR_MMIO_SNSC_D0THERM_THERMALDATA_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_SNSC_D1THERM_PRESENTBIT = 45 ;
+static const uint8_t EXPLR_MMIO_SNSC_D1THERM_VALIDBIT = 46 ;
+static const uint8_t EXPLR_MMIO_SNSC_D1THERM_ERRORBIT = 47 ;
+static const uint8_t EXPLR_MMIO_SNSC_D1THERM_THERMALDATA = 48 ;
+static const uint8_t EXPLR_MMIO_SNSC_D1THERM_THERMALDATA_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_SNSC_FRAMESR_FRAMECOUNT = 0 ;
+static const uint8_t EXPLR_MMIO_SNSC_FRAMESR_FRAMECOUNT_LEN = 32 ;
+static const uint8_t EXPLR_MMIO_SNSC_FRAMESR_SELFREFRESHCOUNT = 32 ;
+static const uint8_t EXPLR_MMIO_SNSC_FRAMESR_SELFREFRESHCOUNT_LEN = 8 ;
+
+static const uint8_t EXPLR_MMIO_SNSC_HISTOBASELOW_HISTOGRAMBASECOUNT = 0 ;
+static const uint8_t EXPLR_MMIO_SNSC_HISTOBASELOW_HISTOGRAMBASECOUNT_LEN = 32 ;
+static const uint8_t EXPLR_MMIO_SNSC_HISTOBASELOW_HISTOGRAMLOWCOUNT = 32 ;
+static const uint8_t EXPLR_MMIO_SNSC_HISTOBASELOW_HISTOGRAMLOWCOUNT_LEN = 32 ;
+
+static const uint8_t EXPLR_MMIO_SNSC_HISTOMEDHIGH_HISTOGRAMMEDCOUNT = 0 ;
+static const uint8_t EXPLR_MMIO_SNSC_HISTOMEDHIGH_HISTOGRAMMEDCOUNT_LEN = 32 ;
+static const uint8_t EXPLR_MMIO_SNSC_HISTOMEDHIGH_HISTOGRAMHIGHCOUNT = 32 ;
+static const uint8_t EXPLR_MMIO_SNSC_HISTOMEDHIGH_HISTOGRAMHIGHCOUNT_LEN = 32 ;
+
+static const uint8_t EXPLR_MMIO_SNSC_OCTHERM_PRESENTBIT = 45 ;
+static const uint8_t EXPLR_MMIO_SNSC_OCTHERM_VALIDBIT = 46 ;
+static const uint8_t EXPLR_MMIO_SNSC_OCTHERM_ERRORBIT = 47 ;
+static const uint8_t EXPLR_MMIO_SNSC_OCTHERM_THERMALDATA = 48 ;
+static const uint8_t EXPLR_MMIO_SNSC_OCTHERM_THERMALDATA_LEN = 16 ;
+
+static const uint8_t EXPLR_MMIO_SNSC_RDWR_READSCOUNT = 0 ;
+static const uint8_t EXPLR_MMIO_SNSC_RDWR_READSCOUNT_LEN = 32 ;
+static const uint8_t EXPLR_MMIO_SNSC_RDWR_WRITESCOUNT = 32 ;
+static const uint8_t EXPLR_MMIO_SNSC_RDWR_WRITESCOUNT_LEN = 32 ;
+
+static const uint8_t EXPLR_MMIO_SNSC_STATEREG_STREGISTER = 0 ;
+static const uint8_t EXPLR_MMIO_SNSC_STATEREG_STREGISTER_LEN = 22 ;
+
+static const uint8_t EXPLR_RDF_AACR_ADDRESS = 0 ;
+static const uint8_t EXPLR_RDF_AACR_ADDRESS_LEN = 7 ;
+static const uint8_t EXPLR_RDF_AACR_AUTOINC = 7 ;
+
+static const uint8_t EXPLR_RDF_AADR_DATA = 0 ;
+static const uint8_t EXPLR_RDF_AADR_DATA_LEN = 64 ;
+
+static const uint8_t EXPLR_RDF_AAER_DATA = 0 ;
+static const uint8_t EXPLR_RDF_AAER_DATA_LEN = 8 ;
+
+static const uint8_t EXPLR_RDF_ACTION0_FIR = 0 ;
+static const uint8_t EXPLR_RDF_ACTION0_FIR_LEN = 64 ;
+
+static const uint8_t EXPLR_RDF_ACTION1_FIR = 0 ;
+static const uint8_t EXPLR_RDF_ACTION1_FIR_LEN = 64 ;
+
+static const uint8_t EXPLR_RDF_CERR0_MSR_PE = 12 ;
+static const uint8_t EXPLR_RDF_CERR0_EICR_PE = 13 ;
+static const uint8_t EXPLR_RDF_CERR0_HWMSX_PE = 16 ;
+static const uint8_t EXPLR_RDF_CERR0_HWMSX_PE_LEN = 8 ;
+static const uint8_t EXPLR_RDF_CERR0_FWMSX_PE = 24 ;
+static const uint8_t EXPLR_RDF_CERR0_FWMSX_PE_LEN = 8 ;
+static const uint8_t EXPLR_RDF_CERR0_RSPAR_PE = 32 ;
+static const uint8_t EXPLR_RDF_CERR0_AACR_PE = 41 ;
+static const uint8_t EXPLR_RDF_CERR0_RECR_PE = 45 ;
+static const uint8_t EXPLR_RDF_CERR0_DBGR_PE = 46 ;
+static const uint8_t EXPLR_RDF_CERR0_MASK0_PE = 48 ;
+static const uint8_t EXPLR_RDF_CERR0_MASK1_PE = 49 ;
+static const uint8_t EXPLR_RDF_CERR0_CGDR_PE = 50 ;
+static const uint8_t EXPLR_RDF_CERR0_MCBCM_PE = 52 ;
+static const uint8_t EXPLR_RDF_CERR0_MCBCM2_PE = 53 ;
+
+static const uint8_t EXPLR_RDF_CERR1_ECC_CTL_AF_PERR = 0 ;
+static const uint8_t EXPLR_RDF_CERR1_ECC_CTL_TCHN_PERR = 1 ;
+static const uint8_t EXPLR_RDF_CERR1_ECC_CTL_CMPMODE_ERR = 2 ;
+static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_PCX_PERR = 3 ;
+static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_SYND_PERR = 4 ;
+static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_2SYM_PERR = 5 ;
+static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_CPLX_PERR = 6 ;
+static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_EP2_PERR = 7 ;
+static const uint8_t EXPLR_RDF_CERR1_READ_ECC_DATAPATH_PARITY_ERROR = 8 ;
+static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_CMX_PERR = 9 ;
+static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_VP1_PERR = 10 ;
+static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_VP2_PERR = 11 ;
+static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_SYG_PERR = 12 ;
+static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_EF1_PERR = 13 ;
+static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_MK3_PERR = 14 ;
+static const uint8_t EXPLR_RDF_CERR1_ECC_PIPE_E1A_PERR = 15 ;
+static const uint8_t EXPLR_RDF_CERR1_UNEXPECTED_RDDATA_VALID = 16 ;
+static const uint8_t EXPLR_RDF_CERR1_MISSING_RDDATA_VALID = 17 ;
+static const uint8_t EXPLR_RDF_CERR1_SUE_01_DETECT = 18 ;
+static const uint8_t EXPLR_RDF_CERR1_SUE_10_DETECT = 19 ;
+static const uint8_t EXPLR_RDF_CERR1_RBUF_ECC_ERR_CE_DW0 = 20 ;
+static const uint8_t EXPLR_RDF_CERR1_RBUF_ECC_ERR_UE_DW0 = 21 ;
+static const uint8_t EXPLR_RDF_CERR1_RBUF_ECC_ERR_CE_DW1 = 22 ;
+static const uint8_t EXPLR_RDF_CERR1_RBUF_ECC_ERR_UE_DW1 = 23 ;
+static const uint8_t EXPLR_RDF_CERR1_RD_BUFF_ECC_ERR_SYNDROME = 24 ;
+static const uint8_t EXPLR_RDF_CERR1_RD_BUFF_ECC_ERR_SYNDROME_LEN = 8 ;
+
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_PCTL = 0 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_RESP = 1 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_RMW = 2 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_LPTR = 3 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_AHASH = 4 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_STG = 5 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_OUT = 6 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_TLM = 7 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_BD = 8 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_DCMP = 9 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_RBCTL = 10 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_RBRMW = 11 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_RBTRC = 12 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_MPE = 13 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_CONF = 14 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_HWMS = 15 ;
+static const uint8_t EXPLR_RDF_CGDR_PSDIS_ZERO_SYND = 16 ;
+static const uint8_t EXPLR_RDF_CGDR_PSDIS_SAME_MARKS = 17 ;
+static const uint8_t EXPLR_RDF_CGDR_PSDIS_SAME_STEER = 18 ;
+static const uint8_t EXPLR_RDF_CGDR_CGDIS_SPARE = 19 ;
+
+static const uint8_t EXPLR_RDF_CTCR_MPE_TIMER = 0 ;
+static const uint8_t EXPLR_RDF_CTCR_MPE_TIMER_LEN = 6 ;
+static const uint8_t EXPLR_RDF_CTCR_MPE_TIMEBASE = 6 ;
+static const uint8_t EXPLR_RDF_CTCR_MPE_TIMEBASE_LEN = 3 ;
+static const uint8_t EXPLR_RDF_CTCR_UE_TIMER = 9 ;
+static const uint8_t EXPLR_RDF_CTCR_UE_TIMER_LEN = 6 ;
+static const uint8_t EXPLR_RDF_CTCR_UE_TIMEBASE = 15 ;
+static const uint8_t EXPLR_RDF_CTCR_UE_TIMEBASE_LEN = 3 ;
+static const uint8_t EXPLR_RDF_CTCR_UE_LOCKOUT_ENABLE = 18 ;
+
+static const uint8_t EXPLR_RDF_DBGR_PRIMARY_SELECT = 0 ;
+static const uint8_t EXPLR_RDF_DBGR_PRIMARY_SELECT_LEN = 4 ;
+static const uint8_t EXPLR_RDF_DBGR_SECONDARY_SELECT = 4 ;
+static const uint8_t EXPLR_RDF_DBGR_SECONDARY_SELECT_LEN = 4 ;
+static const uint8_t EXPLR_RDF_DBGR_EPX_CHIP = 8 ;
+static const uint8_t EXPLR_RDF_DBGR_EPX_SYMS = 9 ;
+static const uint8_t EXPLR_RDF_DBGR_TRACE_ALWAYS = 10 ;
+static const uint8_t EXPLR_RDF_DBGR_WAT_ENABLE = 11 ;
+static const uint8_t EXPLR_RDF_DBGR_WAT_ACTION_SELECT = 12 ;
+static const uint8_t EXPLR_RDF_DBGR_WAT_SOURCE = 13 ;
+static const uint8_t EXPLR_RDF_DBGR_WAT_SOURCE_LEN = 2 ;
+
+static const uint8_t EXPLR_RDF_EICR_ADDRESS = 0 ;
+static const uint8_t EXPLR_RDF_EICR_ADDRESS_LEN = 37 ;
+static const uint8_t EXPLR_RDF_EICR_RESERVED = 37 ;
+static const uint8_t EXPLR_RDF_EICR_PERSIST = 38 ;
+static const uint8_t EXPLR_RDF_EICR_PERSIST_LEN = 2 ;
+static const uint8_t EXPLR_RDF_EICR_REGION = 40 ;
+static const uint8_t EXPLR_RDF_EICR_REGION_LEN = 3 ;
+static const uint8_t EXPLR_RDF_EICR_TYPE = 43 ;
+static const uint8_t EXPLR_RDF_EICR_TYPE_LEN = 5 ;
+static const uint8_t EXPLR_RDF_EICR_MISC = 48 ;
+static const uint8_t EXPLR_RDF_EICR_MISC_LEN = 6 ;
+
+static const uint8_t EXPLR_RDF_ELPR_LOG_FULL = 0 ;
+static const uint8_t EXPLR_RDF_ELPR_LOG_POINTER = 2 ;
+static const uint8_t EXPLR_RDF_ELPR_LOG_POINTER_LEN = 6 ;
+
+static const uint8_t EXPLR_RDF_ERR_HOLD_LAT_FIR_MASK_PAR = 0 ;
+static const uint8_t EXPLR_RDF_ERR_HOLD_LAT_FIR_ACTION0_PAR = 1 ;
+static const uint8_t EXPLR_RDF_ERR_HOLD_LAT_FIR_ACTION1_PAR = 2 ;
+
+static const uint8_t EXPLR_RDF_ERR_MASK_LAT_FIR_PAR = 0 ;
+static const uint8_t EXPLR_RDF_ERR_MASK_LAT_FIR_ACTION0_PAR = 1 ;
+static const uint8_t EXPLR_RDF_ERR_MASK_LAT_FIR_ACTION1_PAR = 2 ;
+
+static const uint8_t EXPLR_RDF_FIR_MAINLINE_MPE_RANK_0_TO_7 = 0 ;
+static const uint8_t EXPLR_RDF_FIR_MAINLINE_MPE_RANK_0_TO_7_LEN = 8 ;
+static const uint8_t EXPLR_RDF_FIR_MAINLINE_NCE = 8 ;
+static const uint8_t EXPLR_RDF_FIR_MAINLINE_TCE = 9 ;
+static const uint8_t EXPLR_RDF_FIR_MAINLINE_SCE = 10 ;
+static const uint8_t EXPLR_RDF_FIR_MAINLINE_MCE = 11 ;
+static const uint8_t EXPLR_RDF_FIR_MAINLINE_SUE = 12 ;
+static const uint8_t EXPLR_RDF_FIR_MAINLINE_AUE = 13 ;
+static const uint8_t EXPLR_RDF_FIR_MAINLINE_UE = 14 ;
+static const uint8_t EXPLR_RDF_FIR_MAINLINE_RCD = 15 ;
+static const uint8_t EXPLR_RDF_FIR_MAINLINE_IAUE = 16 ;
+static const uint8_t EXPLR_RDF_FIR_MAINLINE_IUE = 17 ;
+static const uint8_t EXPLR_RDF_FIR_MAINLINE_IRCD = 18 ;
+static const uint8_t EXPLR_RDF_FIR_MAINLINE_IMPE = 19 ;
+static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_MPE_RANK_0_TO_7 = 20 ;
+static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_MPE_RANK_0_TO_7_LEN = 8 ;
+static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_NCE = 28 ;
+static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_TCE = 29 ;
+static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_SCE = 30 ;
+static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_MCE = 31 ;
+static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_SUE = 32 ;
+static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_AUE = 33 ;
+static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_UE = 34 ;
+static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_RCD = 35 ;
+static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_IAUE = 36 ;
+static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_IUE = 37 ;
+static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_IRCD = 38 ;
+static const uint8_t EXPLR_RDF_FIR_MAINTENANCE_IMPE = 39 ;
+static const uint8_t EXPLR_RDF_FIR_RDDATA_VALID_ERROR = 40 ;
+static const uint8_t EXPLR_RDF_FIR_SCOM_PARITY_CLASS_STATUS = 41 ;
+static const uint8_t EXPLR_RDF_FIR_SCOM_PARITY_CLASS_RECOVERABLE = 42 ;
+static const uint8_t EXPLR_RDF_FIR_SCOM_PARITY_CLASS_UNRECOVERABLE = 43 ;
+static const uint8_t EXPLR_RDF_FIR_ECC_CORRECTOR_INTERNAL_PARITY_ERROR = 44 ;
+static const uint8_t EXPLR_RDF_FIR_ECC_RBUF_CE_DW0 = 45 ;
+static const uint8_t EXPLR_RDF_FIR_ECC_RBUF_CE_DW1 = 46 ;
+static const uint8_t EXPLR_RDF_FIR_ECC_RBUF_UE_DW0 = 47 ;
+static const uint8_t EXPLR_RDF_FIR_ECC_RBUF_UE_DW1 = 48 ;
+static const uint8_t EXPLR_RDF_FIR_RESERVED_49_59 = 49 ;
+static const uint8_t EXPLR_RDF_FIR_RESERVED_49_59_LEN = 11 ;
+static const uint8_t EXPLR_RDF_FIR_SCOM_PARITY_DEBUG_WAT = 60 ;
+static const uint8_t EXPLR_RDF_FIR_RESERVED = 61 ;
+static const uint8_t EXPLR_RDF_FIR_INTERNAL_SCOM_ERROR = 62 ;
+static const uint8_t EXPLR_RDF_FIR_INTERNAL_SCOM_ERROR_COPY = 63 ;
+
+static const uint8_t EXPLR_RDF_FWMS0_MARK = 0 ;
+static const uint8_t EXPLR_RDF_FWMS0_MARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_FWMS0_TYPE = 8 ;
+static const uint8_t EXPLR_RDF_FWMS0_REGION = 9 ;
+static const uint8_t EXPLR_RDF_FWMS0_REGION_LEN = 3 ;
+static const uint8_t EXPLR_RDF_FWMS0_ADDRESS = 12 ;
+static const uint8_t EXPLR_RDF_FWMS0_ADDRESS_LEN = 11 ;
+static const uint8_t EXPLR_RDF_FWMS0_EXIT_1 = 23 ;
+
+static const uint8_t EXPLR_RDF_FWMS1_MARK = 0 ;
+static const uint8_t EXPLR_RDF_FWMS1_MARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_FWMS1_TYPE = 8 ;
+static const uint8_t EXPLR_RDF_FWMS1_REGION = 9 ;
+static const uint8_t EXPLR_RDF_FWMS1_REGION_LEN = 3 ;
+static const uint8_t EXPLR_RDF_FWMS1_ADDRESS = 12 ;
+static const uint8_t EXPLR_RDF_FWMS1_ADDRESS_LEN = 11 ;
+static const uint8_t EXPLR_RDF_FWMS1_EXIT_1 = 23 ;
+
+static const uint8_t EXPLR_RDF_FWMS2_MARK = 0 ;
+static const uint8_t EXPLR_RDF_FWMS2_MARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_FWMS2_TYPE = 8 ;
+static const uint8_t EXPLR_RDF_FWMS2_REGION = 9 ;
+static const uint8_t EXPLR_RDF_FWMS2_REGION_LEN = 3 ;
+static const uint8_t EXPLR_RDF_FWMS2_ADDRESS = 12 ;
+static const uint8_t EXPLR_RDF_FWMS2_ADDRESS_LEN = 11 ;
+static const uint8_t EXPLR_RDF_FWMS2_EXIT_1 = 23 ;
+
+static const uint8_t EXPLR_RDF_FWMS3_MARK = 0 ;
+static const uint8_t EXPLR_RDF_FWMS3_MARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_FWMS3_TYPE = 8 ;
+static const uint8_t EXPLR_RDF_FWMS3_REGION = 9 ;
+static const uint8_t EXPLR_RDF_FWMS3_REGION_LEN = 3 ;
+static const uint8_t EXPLR_RDF_FWMS3_ADDRESS = 12 ;
+static const uint8_t EXPLR_RDF_FWMS3_ADDRESS_LEN = 11 ;
+static const uint8_t EXPLR_RDF_FWMS3_EXIT_1 = 23 ;
+
+static const uint8_t EXPLR_RDF_FWMS4_MARK = 0 ;
+static const uint8_t EXPLR_RDF_FWMS4_MARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_FWMS4_TYPE = 8 ;
+static const uint8_t EXPLR_RDF_FWMS4_REGION = 9 ;
+static const uint8_t EXPLR_RDF_FWMS4_REGION_LEN = 3 ;
+static const uint8_t EXPLR_RDF_FWMS4_ADDRESS = 12 ;
+static const uint8_t EXPLR_RDF_FWMS4_ADDRESS_LEN = 11 ;
+static const uint8_t EXPLR_RDF_FWMS4_EXIT_1 = 23 ;
+
+static const uint8_t EXPLR_RDF_FWMS5_MARK = 0 ;
+static const uint8_t EXPLR_RDF_FWMS5_MARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_FWMS5_TYPE = 8 ;
+static const uint8_t EXPLR_RDF_FWMS5_REGION = 9 ;
+static const uint8_t EXPLR_RDF_FWMS5_REGION_LEN = 3 ;
+static const uint8_t EXPLR_RDF_FWMS5_ADDRESS = 12 ;
+static const uint8_t EXPLR_RDF_FWMS5_ADDRESS_LEN = 11 ;
+static const uint8_t EXPLR_RDF_FWMS5_EXIT_1 = 23 ;
+
+static const uint8_t EXPLR_RDF_FWMS6_MARK = 0 ;
+static const uint8_t EXPLR_RDF_FWMS6_MARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_FWMS6_TYPE = 8 ;
+static const uint8_t EXPLR_RDF_FWMS6_REGION = 9 ;
+static const uint8_t EXPLR_RDF_FWMS6_REGION_LEN = 3 ;
+static const uint8_t EXPLR_RDF_FWMS6_ADDRESS = 12 ;
+static const uint8_t EXPLR_RDF_FWMS6_ADDRESS_LEN = 11 ;
+static const uint8_t EXPLR_RDF_FWMS6_EXIT_1 = 23 ;
+
+static const uint8_t EXPLR_RDF_FWMS7_MARK = 0 ;
+static const uint8_t EXPLR_RDF_FWMS7_MARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_FWMS7_TYPE = 8 ;
+static const uint8_t EXPLR_RDF_FWMS7_REGION = 9 ;
+static const uint8_t EXPLR_RDF_FWMS7_REGION_LEN = 3 ;
+static const uint8_t EXPLR_RDF_FWMS7_ADDRESS = 12 ;
+static const uint8_t EXPLR_RDF_FWMS7_ADDRESS_LEN = 11 ;
+static const uint8_t EXPLR_RDF_FWMS7_EXIT_1 = 23 ;
+
+static const uint8_t EXPLR_RDF_HWMS0_CHIPMARK = 0 ;
+static const uint8_t EXPLR_RDF_HWMS0_CHIPMARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_HWMS0_CONFIRMED = 8 ;
+static const uint8_t EXPLR_RDF_HWMS0_EXIT_1 = 9 ;
+
+static const uint8_t EXPLR_RDF_HWMS1_CHIPMARK = 0 ;
+static const uint8_t EXPLR_RDF_HWMS1_CHIPMARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_HWMS1_CONFIRMED = 8 ;
+static const uint8_t EXPLR_RDF_HWMS1_EXIT_1 = 9 ;
+
+static const uint8_t EXPLR_RDF_HWMS2_CHIPMARK = 0 ;
+static const uint8_t EXPLR_RDF_HWMS2_CHIPMARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_HWMS2_CONFIRMED = 8 ;
+static const uint8_t EXPLR_RDF_HWMS2_EXIT_1 = 9 ;
+
+static const uint8_t EXPLR_RDF_HWMS3_CHIPMARK = 0 ;
+static const uint8_t EXPLR_RDF_HWMS3_CHIPMARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_HWMS3_CONFIRMED = 8 ;
+static const uint8_t EXPLR_RDF_HWMS3_EXIT_1 = 9 ;
+
+static const uint8_t EXPLR_RDF_HWMS4_CHIPMARK = 0 ;
+static const uint8_t EXPLR_RDF_HWMS4_CHIPMARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_HWMS4_CONFIRMED = 8 ;
+static const uint8_t EXPLR_RDF_HWMS4_EXIT_1 = 9 ;
+
+static const uint8_t EXPLR_RDF_HWMS5_CHIPMARK = 0 ;
+static const uint8_t EXPLR_RDF_HWMS5_CHIPMARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_HWMS5_CONFIRMED = 8 ;
+static const uint8_t EXPLR_RDF_HWMS5_EXIT_1 = 9 ;
+
+static const uint8_t EXPLR_RDF_HWMS6_CHIPMARK = 0 ;
+static const uint8_t EXPLR_RDF_HWMS6_CHIPMARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_HWMS6_CONFIRMED = 8 ;
+static const uint8_t EXPLR_RDF_HWMS6_EXIT_1 = 9 ;
+
+static const uint8_t EXPLR_RDF_HWMS7_CHIPMARK = 0 ;
+static const uint8_t EXPLR_RDF_HWMS7_CHIPMARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_HWMS7_CONFIRMED = 8 ;
+static const uint8_t EXPLR_RDF_HWMS7_EXIT_1 = 9 ;
+
+static const uint8_t EXPLR_RDF_MASK_FIR = 0 ;
+static const uint8_t EXPLR_RDF_MASK_FIR_LEN = 64 ;
+
+static const uint8_t EXPLR_RDF_MASK0_MSR_PE = 12 ;
+static const uint8_t EXPLR_RDF_MASK0_EICR_PE = 13 ;
+static const uint8_t EXPLR_RDF_MASK0_HWMSX_PE = 16 ;
+static const uint8_t EXPLR_RDF_MASK0_HWMSX_PE_LEN = 8 ;
+static const uint8_t EXPLR_RDF_MASK0_FWMSX_PE = 24 ;
+static const uint8_t EXPLR_RDF_MASK0_FWMSX_PE_LEN = 8 ;
+static const uint8_t EXPLR_RDF_MASK0_RSPAR_PE = 32 ;
+static const uint8_t EXPLR_RDF_MASK0_CTCR_PE = 40 ;
+static const uint8_t EXPLR_RDF_MASK0_AACR_PE = 41 ;
+static const uint8_t EXPLR_RDF_MASK0_RECR_PE = 45 ;
+static const uint8_t EXPLR_RDF_MASK0_DBGR_PE = 46 ;
+static const uint8_t EXPLR_RDF_MASK0_MASK0_PE = 48 ;
+static const uint8_t EXPLR_RDF_MASK0_MASK1_PE = 49 ;
+static const uint8_t EXPLR_RDF_MASK0_CGDR_PE = 50 ;
+static const uint8_t EXPLR_RDF_MASK0_MCBCM_PE = 52 ;
+static const uint8_t EXPLR_RDF_MASK0_MCBCM2_PE = 53 ;
+
+static const uint8_t EXPLR_RDF_MASK1_ECC_CTL_AF_PERR = 0 ;
+static const uint8_t EXPLR_RDF_MASK1_ECC_CTL_TCHN_PERR = 1 ;
+static const uint8_t EXPLR_RDF_MASK1_ECC_CTL_CMPMODE_ERR = 2 ;
+static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_PCX_PERR = 3 ;
+static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_SYND_PERR = 4 ;
+static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_2SYM_PERR = 5 ;
+static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_CPLX_PERR = 6 ;
+static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_EP2_PERR = 7 ;
+static const uint8_t EXPLR_RDF_MASK1_READ_ECC_DATAPATH_PARITY_ERROR = 8 ;
+static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_CMX_PERR = 9 ;
+static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_VP1_PERR = 10 ;
+static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_VP2_PERR = 11 ;
+static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_SYG_PERR = 12 ;
+static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_EF1_PERR = 13 ;
+static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_MK3_PERR = 14 ;
+static const uint8_t EXPLR_RDF_MASK1_ECC_PIPE_E1A_PERR = 15 ;
+static const uint8_t EXPLR_RDF_MASK1_UNEXPECTED_RDDATA_VALID = 16 ;
+static const uint8_t EXPLR_RDF_MASK1_MISSING_RDDATA_VALID = 17 ;
+static const uint8_t EXPLR_RDF_MASK1_SUE_01_DETECT = 18 ;
+static const uint8_t EXPLR_RDF_MASK1_SUE_10_DETECT = 19 ;
+
+static const uint8_t EXPLR_RDF_MCBCM_MCBIST_HALF_COMPARE_MASK = 0 ;
+static const uint8_t EXPLR_RDF_MCBCM_MCBIST_HALF_COMPARE_MASK_LEN = 40 ;
+static const uint8_t EXPLR_RDF_MCBCM_MCBIST_MASK_COVERAGE_SELECTOR = 40 ;
+static const uint8_t EXPLR_RDF_MCBCM_MCBIST_TRAP_NONSTOP = 41 ;
+static const uint8_t EXPLR_RDF_MCBCM_MCBIST_TRAP_CE_ENABLE = 42 ;
+static const uint8_t EXPLR_RDF_MCBCM_MCBIST_TRAP_MPE_ENABLE = 43 ;
+static const uint8_t EXPLR_RDF_MCBCM_MCBIST_TRAP_UE_ENABLE = 44 ;
+
+static const uint8_t EXPLR_RDF_MSR_CHIPMARK = 8 ;
+static const uint8_t EXPLR_RDF_MSR_CHIPMARK_LEN = 8 ;
+static const uint8_t EXPLR_RDF_MSR_RANK = 16 ;
+static const uint8_t EXPLR_RDF_MSR_RANK_LEN = 3 ;
+
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DISABLE_MEMORY_ECC_CHECK_CORRECT = 0 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DISABLE_MEMORY_ECC_CORRECT = 1 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DISABLE_MARK_STORE_WRITE = 2 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DISABLE_UE_RETRY = 3 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_ITAG_METADATA_ENABLE = 4 ;
+static const uint8_t EXPLR_RDF_RECR_DISABLE_RCD_CHECK = 5 ;
+static const uint8_t EXPLR_RDF_RECR_DISABLE_RDDATA_VALID_CHECK = 6 ;
+static const uint8_t EXPLR_RDF_RECR_ENABLE_BAD_DATA_ON_SUE = 7 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DISABLE_UTC_EXIT_INCREASE = 8 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_EXIT_OVERRIDE = 9 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_EXIT_OVERRIDE_LEN = 2 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_HWMARK_EXIT1 = 11 ;
+static const uint8_t EXPLR_RDF_RECR_DISABLE_EXIT_0_DELAY_0 = 12 ;
+static const uint8_t EXPLR_RDF_RECR_DISABLE_MPE_CORRECTION = 13 ;
+static const uint8_t EXPLR_RDF_RECR_CAPPTAG_BYPASS_BIT_ENABLE = 14 ;
+static const uint8_t EXPLR_RDF_RECR_CAPPTAG_RETRY_BIT_ENABLE = 15 ;
+static const uint8_t EXPLR_RDF_RECR_CAPPTAG_BYPASS_BIT_SELECT = 16 ;
+static const uint8_t EXPLR_RDF_RECR_CAPPTAG_BYPASS_BIT_SELECT_LEN = 4 ;
+static const uint8_t EXPLR_RDF_RECR_CAPPTAG_RETRY_BIT_SELECT = 20 ;
+static const uint8_t EXPLR_RDF_RECR_CAPPTAG_RETRY_BIT_SELECT_LEN = 4 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_ENABLE_MPE_NOISE_WINDOW = 24 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DISABLE_MPE_CONFIRM = 25 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_ENABLE_UE_NOISE_WINDOW = 26 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_ENABLE_TCE_CORRECTION = 27 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_ENABLE_CHIPMARKED_SCE_NCE = 28 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_USE_ADDRESS_HASH = 29 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DATA_INVERSION = 30 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DATA_INVERSION_LEN = 2 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_DISABLE_PIPE_NOERR_CLOCK_GATING = 32 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_MAINT_NO_RETRY_UE = 33 ;
+static const uint8_t EXPLR_RDF_RECR_MBSECCQ_MAINT_NO_RETRY_MPE = 34 ;
+static const uint8_t EXPLR_RDF_RECR_RETRY_UNMARKED_ERRORS = 35 ;
+static const uint8_t EXPLR_RDF_RECR_CFG_MAINT_USE_TIMERS = 40 ;
+static const uint8_t EXPLR_RDF_RECR_HWMS_RANK_SELECT = 41 ;
+static const uint8_t EXPLR_RDF_RECR_HWMS_RANK_SELECT_LEN = 6 ;
+
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R0_LEFT = 0 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R0_LEFT_LEN = 5 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R0_RIGHT = 5 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R0_RIGHT_LEN = 5 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R1_LEFT = 10 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R1_LEFT_LEN = 5 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R1_RIGHT = 15 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R1_RIGHT_LEN = 5 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R2_LEFT = 20 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R2_LEFT_LEN = 5 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R2_RIGHT = 25 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R2_RIGHT_LEN = 5 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R3_LEFT = 30 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R3_LEFT_LEN = 5 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R3_RIGHT = 35 ;
+static const uint8_t EXPLR_RDF_RSPAR_CFG_STEERING_R3_RIGHT_LEN = 5 ;
+
+static const uint8_t EXPLR_RDF_WOF_FIR = 0 ;
+static const uint8_t EXPLR_RDF_WOF_FIR_LEN = 64 ;
+
+static const uint8_t EXPLR_SRQ_ERR_HOLD_LAT_FIR_MASK_PAR = 0 ;
+static const uint8_t EXPLR_SRQ_ERR_HOLD_LAT_FIR_ACTION0_PAR = 1 ;
+static const uint8_t EXPLR_SRQ_ERR_HOLD_LAT_FIR_ACTION1_PAR = 2 ;
+
+static const uint8_t EXPLR_SRQ_ERR_MASK_LAT_FIR_PAR = 0 ;
+static const uint8_t EXPLR_SRQ_ERR_MASK_LAT_FIR_ACTION0_PAR = 1 ;
+static const uint8_t EXPLR_SRQ_ERR_MASK_LAT_FIR_ACTION1_PAR = 2 ;
+
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_ENABLE = 0 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_INTERVAL_TIMEBASE_SELECT = 1 ;
static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_INTERVAL_TIMEBASE_SELECT_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_PER_BANK_REFRESH = 3 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_RESERVED_4 = 4 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_PRIORITY_THRESHOLD = 5 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_PRIORITY_THRESHOLD_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_INTERVAL = 8 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_INTERVAL_LEN = 11 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_RESET_INTERVAL = 19 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_RESET_INTERVAL_LEN = 11 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_TRFC = 30 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_TRFC_LEN = 10 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFR_TSV_STACK = 40 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFR_TSV_STACK_LEN = 10 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFR_CHECK_INTERVAL = 50 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFR_CHECK_INTERVAL_LEN = 11 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_TRFC_STACK_GATE_ALL_REF = 61 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_RESERVED_62_63 = 62 ;
-static const uint8_t EXPLR_SRQ_MBAREF0Q_RESERVED_62_63_LEN = 2 ;
-
-static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_STATIC_IDLE_DLY = 0 ;
-static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_STATIC_IDLE_DLY_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_LP_SUB_CNT = 4 ;
-static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_LP_SUB_CNT_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_REFRESH_HP_RANK_BLOCK_ENABLE = 6 ;
-static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_HP_WR_GATE_LP_REF_DIS = 7 ;
-static const uint8_t EXPLR_SRQ_MBAREFAQ_RESERVED_8_9 = 8 ;
-static const uint8_t EXPLR_SRQ_MBAREFAQ_RESERVED_8_9_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_REF_BLOCK_STOP_DLY = 10 ;
-static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_REF_BLOCK_STOP_DLY_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_TSTAB = 16 ;
-static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_TSTAB_LEN = 13 ;
-static const uint8_t EXPLR_SRQ_MBAREFAQ_RESERVED_29_31 = 29 ;
-static const uint8_t EXPLR_SRQ_MBAREFAQ_RESERVED_29_31_LEN = 3 ;
-
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_LP_CTRL_ENABLE = 0 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_LP_DATA_ENABLE = 1 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_MIN_MAX_DOMAINS_ENABLE = 2 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_MIN_MAX_DOMAINS = 3 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_MIN_MAX_DOMAINS_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_AVAIL = 6 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_AVAIL_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PDN_PUP = 11 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PDN_PUP_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_PDN = 16 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_PDN_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_QUAD_RANK_ENC = 21 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_MIN_DOMAIN_REDUCTION_ENABLE = 22 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_MIN_DOMAIN_REDUCTION_TIME = 23 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_MIN_DOMAIN_REDUCTION_TIME_LEN = 10 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_AFTER_ACTIVATE_WAIT_ENABLE = 33 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_AFTER_ACTIVATE_WAIT_TIME = 34 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_AFTER_ACTIVATE_WAIT_TIME_LEN = 8 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_CONC_LP_DATA_DISABLE = 42 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_MIN_DOMAIN_REDUCTION_CNT_REFR_INT = 43 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_EMER_MIN_MAX_DOMAIN = 44 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_EMER_MIN_MAX_DOMAIN_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_ALL_WRITES_PENDING = 47 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_ALWAYS_WAIT_ACT_TIME = 48 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_TLP_RESP = 49 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_TLP_RESP_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_TLP_WAKEUP = 54 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_TLP_WAKEUP_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_CONC_CCS_STR_EN = 59 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_RESERVED_60_63 = 60 ;
-static const uint8_t EXPLR_SRQ_MBARPC0Q_RESERVED_60_63_LEN = 4 ;
-
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_STR_ENABLE = 0 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_DIS_CLK_IN_STR = 1 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_ENTER_STR_TIME = 2 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_ENTER_STR_TIME_LEN = 10 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TCKESR = 12 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TCKESR_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TCKSRE = 17 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TCKSRE_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TCKSRX = 22 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TCKSRX_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TXSDLL = 27 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TXSDLL_LEN = 11 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TRFC_COUNTER_DIS = 38 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TRFC_COUNTER_DIS_LEN = 8 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_SAFE_REFRESH_INTERVAL = 46 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_SAFE_REFRESH_INTERVAL_LEN = 11 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_OCC_DEADMAN_TIMER_SEL = 57 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_OCC_DEADMAN_TIMER_SEL_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_OCC_DEADMAN_TB_SEL = 61 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_FORCE_STR = 62 ;
-static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_EPOW_DISABLE = 63 ;
-
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_ENABLE = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL0 = 1 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL0_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL1 = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL1_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL2 = 7 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL2_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL3 = 10 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL3_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL4 = 13 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL4_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL5 = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL5_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL6 = 19 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL6_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL7 = 22 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL7_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP0_FLIP = 25 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP1_FLIP = 26 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP2_FLIP = 27 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP3_FLIP = 28 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP4_FLIP = 29 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP5_FLIP = 30 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP6_FLIP = 31 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP7_FLIP = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_RESERVED_33_47 = 33 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_RESERVED_33_47_LEN = 15 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_WAT_FARB_RRQ_GT = 48 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_WAT_FARB_RRQ_GT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_WAT_FARB_WRQ_GT = 52 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_WAT_FARB_WRQ_GT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_WAT_FARB_REF_GT = 56 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_WAT_FARB_REF_GT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_RESERVED_60_63 = 60 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG0Q_RESERVED_60_63_LEN = 4 ;
-
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_FORCE_WR_ENTRY0_HP = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_FORCE_WR_ENTRY0_HP_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_FORCE_RD_ENTRY0_HP = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_FORCE_RD_ENTRY0_HP_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_FP_DIS = 8 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_FP_DIS_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_DIS_RD_PG = 12 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_DIS_RD_PG_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_DIS_WR_PG = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_DIS_WR_PG_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_PUP_ALL = 20 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_PUP_ALL_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_EXIT_STR = 24 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_EXIT_STR_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_REF_HP = 28 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_REF_HP_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_REF_SYNC = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_REF_SYNC_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_REF_SAFE = 36 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_REF_SAFE_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_RESERVED_40_43 = 40 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_RESERVED_40_43_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_MCBIST_GT = 44 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_MCBIST_GT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_NCF_RM_INVALID_CMD = 48 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_NCF_RM_INVALID_CMD_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_SET_FIR = 52 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_SET_FIR_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_EMER_TH = 56 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_EMER_TH_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_START_RECOVERY = 60 ;
-static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_START_RECOVERY_LEN = 4 ;
-
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RODT_START_DLY = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RODT_START_DLY_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RODT_END_DLY = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RODT_END_DLY_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WODT_START_DLY = 12 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WODT_START_DLY_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WODT_END_DLY = 18 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WODT_END_DLY_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRDONE_DLY = 24 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRDONE_DLY_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRDATA_DLY = 30 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRDATA_DLY_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RDTAG_DLY = 36 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RDTAG_DLY_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RDCSLAT_DLY = 42 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RDCSLAT_DLY_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RDDATA_EN_DLY = 47 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RDDATA_EN_DLY_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRCSLAT_DLY = 52 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRCSLAT_DLY_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRDATA_EN_DLY = 57 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRDATA_EN_DLY_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_RESERVED_62_63 = 62 ;
-static const uint8_t EXPLR_SRQ_MBA_DSM0Q_RESERVED_62_63_LEN = 2 ;
-
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_PC_PCFSM_1HOT = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_STRFSM_1HOT = 1 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_FARB_RECVFSM_1HOT = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_PC_PE = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_RRQ_PE = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_WRQ_PE = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_DSM_PE = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_TMR_PE = 7 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_FARB_PE = 8 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_WRQ_HANG = 9 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_RRQ_HANG = 10 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_FARB_CMD_PE_HOLD_OUT = 11 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_DSM_CMD_PE_HOLD_OUT = 12 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_UE = 13 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_UE_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_TBD = 15 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_TBD_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_MCB_LOGIC_ERROR = 17 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_MCB_LOGIC_ERROR_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_LOGIC_ERROR = 22 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_LOGIC_ERROR_LEN = 15 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_MCB_PARITY_ERROR = 37 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_MCB_PARITY_ERROR_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_PARITY_ERROR = 42 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_PARITY_ERROR_LEN = 11 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_CE = 53 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_CE_LEN = 4 ;
-
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_MASK_ERRMASK = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_MASK_ERRMASK_LEN = 57 ;
-
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_MISR_BLOCK = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_MISR_BLOCK_LEN = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_MISR_FEEDBACK_ENABLE = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_2N_ADDR = 17 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_DDP_ADDR_MODE = 18 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_PLANAR_ADDR_MODE = 19 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_ACT_SAME_RANK_HOLD_TIME = 20 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_ACT_SAME_RANK_HOLD_TIME_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_MAX_READS_IN_A_ROW = 24 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_MAX_READS_IN_A_ROW_LEN = 7 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_MAX_WRITES_IN_A_ROW = 31 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_MAX_WRITES_IN_A_ROW_LEN = 7 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_PARITY_AFTER_CMD = 38 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_INJECT_PARITY_ERR_WEN = 39 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_INJECT_PARITY_ERR_ADDR5 = 40 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_BW_WINDOW_SIZE = 41 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_BW_WINDOW_SIZE_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_PARITY_DETECT_TIME = 43 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_PARITY_DETECT_TIME_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_RCD_PROTECTION_TIME = 48 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_RCD_PROTECTION_TIME_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_DISABLE_RCD_RECOVERY = 54 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_WAIT_FOR_INIT_COMPLETE = 55 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_FARB_CLOSE_ALL_PAGES = 56 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_PORT_FAIL_DISABLE = 57 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_RESERVED_58 = 58 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_INJECT_PARITY_ERR_CONSTANT = 59 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_FINISH_WR_BEFORE_RD = 60 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_OPT_RD_SIZE = 61 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_OPT_RD_SIZE_LEN = 3 ;
-
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S0_CID = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S0_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S1_CID = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S1_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S2_CID = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S2_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S3_CID = 9 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S3_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S4_CID = 12 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S4_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S5_CID = 15 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S5_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S6_CID = 18 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S6_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S7_CID = 21 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S7_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S0_CID = 24 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S0_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S1_CID = 27 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S1_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S2_CID = 30 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S2_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S3_CID = 33 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S3_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S4_CID = 36 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S4_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S5_CID = 39 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S5_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S6_CID = 42 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S6_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S7_CID = 45 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S7_CID_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_DIS_SMDR = 48 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_DDR4_PARITY_ON_CID_DIS = 49 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_READ_2CYC_PREAMBLE_EN = 50 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_WRITE_2CYC_PREAMBLE_EN = 51 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_RDCSGAP_DLY = 52 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_RDCSGAP_DLY_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_WRCSGAP_DLY = 55 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_WRCSGAP_DLY_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_RSV0 = 58 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_RSV0_LEN = 6 ;
-
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK0_RD_ODT = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK0_RD_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK1_RD_ODT = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK1_RD_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK2_RD_ODT = 8 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK2_RD_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK3_RD_ODT = 12 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK3_RD_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK4_RD_ODT = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK4_RD_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK5_RD_ODT = 20 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK5_RD_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK6_RD_ODT = 24 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK6_RD_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK7_RD_ODT = 28 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK7_RD_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK0_WR_ODT = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK0_WR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK1_WR_ODT = 36 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK1_WR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK2_WR_ODT = 40 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK2_WR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK3_WR_ODT = 44 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK3_WR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK4_WR_ODT = 48 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK4_WR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK5_WR_ODT = 52 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK5_WR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK6_WR_ODT = 56 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK6_WR_ODT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK7_WR_ODT = 60 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK7_WR_ODT_LEN = 4 ;
-
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_N_PER_SLOT = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_N_PER_SLOT_LEN = 15 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_N_PER_PORT = 15 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_N_PER_PORT_LEN = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_M = 31 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_M_LEN = 14 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_RAS_WEIGHT = 45 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_RAS_WEIGHT_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_CAS_WEIGHT = 48 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_CAS_WEIGHT_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_RESERVED_51 = 51 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_RESERVED_52 = 52 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_CHANGE_AFTER_SYNC = 53 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_RESERVED_54_63 = 54 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB3Q_RESERVED_54_63_LEN = 10 ;
-
-static const uint8_t EXPLR_SRQ_MBA_FARB4Q_CFG_NOISE_WAIT_TIME = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB4Q_CFG_NOISE_WAIT_TIME_LEN = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB4Q_CFG_PRECHARGE_WAIT_TIME = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB4Q_CFG_PRECHARGE_WAIT_TIME_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB4Q_CFG_SIM_FAST_NOISE_WINDOW = 22 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB4Q_RESERVED_23_26 = 23 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB4Q_RESERVED_23_26_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB4Q_EMERGENCY_N = 27 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB4Q_EMERGENCY_N_LEN = 15 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB4Q_EMERGENCY_M = 42 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB4Q_EMERGENCY_M_LEN = 14 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB4Q_RESERVED_56_63 = 56 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB4Q_RESERVED_56_63_LEN = 8 ;
-
-static const uint8_t EXPLR_SRQ_MBA_FARB5Q_RESERVED_0_3 = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB5Q_RESERVED_0_3_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB5Q_CFG_DDR_RESETN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB5Q_CFG_CCS_ADDR_MUX_SEL = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB5Q_CFG_CCS_INST_RESET_ENABLE = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB5Q_RESERVED_7_15 = 7 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB5Q_RESERVED_7_15_LEN = 9 ;
-
-static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_BW_SNAPSHOT = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_BW_SNAPSHOT_LEN = 11 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_CKE_PUP_STATE = 11 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_CKE_PUP_STATE_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_STR_STATE = 15 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_RRQ_DEPTH = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_RRQ_DEPTH_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_WRQ_DEPTH = 21 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_WRQ_DEPTH_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_RCD_PARITY_DLY = 26 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_RCD_PARITY_DLY_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_EVENT = 31 ;
-
-static const uint8_t EXPLR_SRQ_MBA_FARB7Q_EMER_THROTTLE_IP = 0 ;
-
-static const uint8_t EXPLR_SRQ_MBA_FARB8Q_SAFE_REFRESH_MODE = 0 ;
-
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_ENABLE = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_INTERVAL_TB = 1 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_INTERVAL_TB_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_INTERVAL = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_INTERVAL_LEN = 9 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_RESERVED_12 = 12 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_RUN_LENGTH = 13 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_RUN_LENGTH_LEN = 8 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_RUN_LENGTH_TB = 21 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_RUN_LENGTH_TB_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_RESERVED_23_31 = 23 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_RESERVED_23_31_LEN = 9 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_ENABLE = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_INTERVAL_TB = 33 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_INTERVAL_TB_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_INTERVAL = 35 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_INTERVAL_LEN = 9 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_FIXED_RUN_LENGTH_EN = 44 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_RUN_LENGTH = 45 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_RUN_LENGTH_LEN = 10 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_CTRLUPD_MIN = 55 ;
-static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_CTRLUPD_MIN_LEN = 9 ;
-
-static const uint8_t EXPLR_SRQ_MBA_PMU0Q_READ_COUNT = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU0Q_READ_COUNT_LEN = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU0Q_WRITE_COUNT = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU0Q_WRITE_COUNT_LEN = 32 ;
-
-static const uint8_t EXPLR_SRQ_MBA_PMU1Q_ACTIVATE_COUNT = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU1Q_ACTIVATE_COUNT_LEN = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU1Q_PU_COUNTS = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU1Q_PU_COUNTS_LEN = 32 ;
-
-static const uint8_t EXPLR_SRQ_MBA_PMU2Q_FRAME_COUNT = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU2Q_FRAME_COUNT_LEN = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU2Q_STR_EXIT_COUNT = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU2Q_STR_EXIT_COUNT_LEN = 8 ;
-
-static const uint8_t EXPLR_SRQ_MBA_PMU3Q_LOW_IDLE_THRESHOLD = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU3Q_LOW_IDLE_THRESHOLD_LEN = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU3Q_MED_IDLE_THRESHOLD = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU3Q_MED_IDLE_THRESHOLD_LEN = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU3Q_HIGH_IDLE_THRESHOLD = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU3Q_HIGH_IDLE_THRESHOLD_LEN = 32 ;
-
-static const uint8_t EXPLR_SRQ_MBA_PMU4Q_BASE_IDLE_COUNT = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU4Q_BASE_IDLE_COUNT_LEN = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU4Q_LOW_IDLE_COUNT = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU4Q_LOW_IDLE_COUNT_LEN = 32 ;
-
-static const uint8_t EXPLR_SRQ_MBA_PMU5Q_MED_IDLE_COUNT = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU5Q_MED_IDLE_COUNT_LEN = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU5Q_HIGH_IDLE_COUNT = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU5Q_HIGH_IDLE_COUNT_LEN = 32 ;
-
-static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT0_COUNTER = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT0_COUNTER_LEN = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT1_COUNTER = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT1_COUNTER_LEN = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT2_COUNTER = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT2_COUNTER_LEN = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT3_COUNTER = 48 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT3_COUNTER_LEN = 16 ;
-
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT0_SELECT = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT0_SELECT_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT1_SELECT = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT1_SELECT_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT2_SELECT = 12 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT2_SELECT_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT3_SELECT = 18 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT3_SELECT_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C0 = 24 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C0_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C1 = 26 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C1_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C2 = 28 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C2_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C3 = 30 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C3_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CASCADE = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CASCADE_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_FREEZE = 35 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PMU_START_RESET = 36 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PMU_START_NO_RESET = 37 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PMU_STOP = 38 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_RESET_PMU6_WHEN_READ = 39 ;
-
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_TYPE = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_TYPE_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_MRANK_MATCH_EN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_SRANK_MATCH_EN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_BG_MATCH_EN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_BANK_MATCH_EN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_MRANK = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_MRANK_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_SRANK = 9 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_SRANK_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_BG = 12 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_BG_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_BANK = 14 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_BANK_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_TYPE = 17 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_TYPE_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_MRANK_MATCH_EN = 19 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_SRANK_MATCH_EN = 20 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_BG_MATCH_EN = 21 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_BANK_MATCH_EN = 22 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_MRANK = 23 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_MRANK_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_SRANK = 26 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_SRANK_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_BG = 29 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_BG_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_BANK = 31 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_BANK_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_TYPE = 34 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_TYPE_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_MRANK_MATCH_EN = 36 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_SRANK_MATCH_EN = 37 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_BG_MATCH_EN = 38 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_BANK_MATCH_EN = 39 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_MRANK = 40 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_MRANK_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_SRANK = 43 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_SRANK_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_BG = 46 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_BG_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_BANK = 48 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_BANK_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_RESERVED_51_63 = 51 ;
-static const uint8_t EXPLR_SRQ_MBA_PMU8Q_RESERVED_51_63_LEN = 13 ;
-
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RRQ_SKIP_LIMIT = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RRQ_SKIP_LIMIT_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RRQ_FIFO_MODE = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RRQ_SINGLE_THREAD_MODE = 7 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_RESERVED_8_10 = 8 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_RESERVED_8_10_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_DISABLE_RD_PG_MODE = 11 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_DISABLE_FAST_ACT = 12 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RD_IDLE_ALLOW_WR = 13 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RD_IDLE_ALLOW_WR_LEN = 11 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RDBUFF_CAPACITY_LIMIT = 24 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RDBUFF_CAPACITY_LIMIT_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_SRQ_RRQ_DBG_SEL = 30 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_SRQ_RRQ_DBG_SEL_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_RESERVED_34_56 = 34 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_RESERVED_34_56_LEN = 23 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RRQ_ACT_NUM_READS_PENDING = 57 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RRQ_ACT_NUM_READS_PENDING_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_DISABLE_FAST_ACT_FIFO = 61 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RRQ_ENTRY0_ENABLE = 62 ;
-static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_CRIT_OW_FIRST_EN = 63 ;
-
-static const uint8_t EXPLR_SRQ_MBA_SYNCCNTLQ_SYNC_REF_EN = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_SYNCCNTLQ_SYNC_PC_EN = 1 ;
-static const uint8_t EXPLR_SRQ_MBA_SYNCCNTLQ_SYNC_TIMEBASE_EN = 2 ;
-static const uint8_t EXPLR_SRQ_MBA_SYNCCNTLQ_RESERVED_3_7 = 3 ;
-static const uint8_t EXPLR_SRQ_MBA_SYNCCNTLQ_RESERVED_3_7_LEN = 5 ;
-
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RRDM_DLY = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RRDM_DLY_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RRSMSR_DLY = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RRSMSR_DLY_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RRSMDR_DLY = 8 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RRSMDR_DLY_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RROP_DLY = 12 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RROP_DLY_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWDM_DLY = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWDM_DLY_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWSMSR_DLY = 20 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWSMSR_DLY_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWSMDR_DLY = 24 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWSMDR_DLY_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWOP_DLY = 28 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWOP_DLY_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RWDM_DLY = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RWDM_DLY_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RWSMSR_DLY = 37 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RWSMSR_DLY_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RWSMDR_DLY = 42 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RWSMDR_DLY_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WRDM_DLY = 47 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WRDM_DLY_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WRSMSR_DLY = 51 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WRSMSR_DLY_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WRSMDR_DLY = 57 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WRSMDR_DLY_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RESERVED_63 = 63 ;
-
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_RRSBG_DLY = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_RRSBG_DLY_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_WRSBG_DLY = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_WRSBG_DLY_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TFAW = 10 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TFAW_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRCD = 16 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRCD_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRP = 21 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRP_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRAS = 26 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRAS_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_SRQ_TMR_DBG_SEL = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_SRQ_TMR_DBG_SEL_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_RESERVED_37_40 = 37 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_RESERVED_37_40_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_WR2PRE = 41 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_WR2PRE_LEN = 7 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_RD2PRE = 48 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_RD2PRE_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_TRRD = 52 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_TRRD_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_TRRD_SBG = 56 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_TRRD_SBG_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_ACT_TO_DIFF_RANK_DLY = 60 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_ACT_TO_DIFF_RANK_DLY_LEN = 4 ;
-
-static const uint8_t EXPLR_SRQ_MBA_TMR2Q_CFG_BANK_BUSY_FSM_DIS = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR2Q_CFG_BANK_BUSY_FSM_DIS_LEN = 20 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR2Q_CFG_BANK_BUSY_OPEN_PAGE_DIS = 20 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR2Q_CFG_BANK_BUSY_OPEN_PAGE_DIS_LEN = 12 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR2Q_RESERVED_32_63 = 32 ;
-static const uint8_t EXPLR_SRQ_MBA_TMR2Q_RESERVED_32_63_LEN = 32 ;
-
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRITE_HW_MARK = 0 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRITE_HW_MARK_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_FIFO_MODE = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_DISABLE_WR_PG_MODE = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_ENTRY0_HP_DLY = 7 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_ENTRY0_HP_DLY_LEN = 12 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_FLUSH_WR_RANK = 19 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_ENABLE_NON_HP_WR = 20 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_ENTRY0_MIN_FOR_RRQ_IDLE_WR = 21 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_ENTRY0_MIN_FOR_RRQ_IDLE_WR_LEN = 12 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRITE_LW_MARK = 33 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRITE_LW_MARK_LEN = 5 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_SKIP_LIMIT = 38 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_SKIP_LIMIT_LEN = 6 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_SINGLE_THREAD_MODE = 44 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_RQ_HANG_THRESHOLD = 45 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_RQ_HANG_THRESHOLD_LEN = 8 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_SKIP_RRQ_ENTRIES_DIS = 53 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_RESERVED_54 = 54 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_ACT_NUM_WRITES_PENDING = 55 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_ACT_NUM_WRITES_PENDING_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_ALLOW_NEW_PAGE_COMMIT = 59 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_SRQ_WRQ_DBG_SEL = 60 ;
-static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_SRQ_WRQ_DBG_SEL_LEN = 4 ;
-
-static const uint8_t EXPLR_SRQ_SRQCFG0_MODE_ECC_CHK_DIS = 0 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_MODE_ECC_COR_DIS = 1 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_RMW_RBUF_PTR_MASK = 2 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_RMW_RBUF_PTR_MASK_LEN = 14 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_MCB_PAUSE = 16 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_MCB_CREDIT_UPDATE = 17 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_MCB_CRD_INIT = 18 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_MCB_CRD_INIT_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_TRACE_UPDATE = 22 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_CLEAR = 23 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_HOLD_ACUM = 24 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_ERR_INJ0 = 25 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_ERR_INJ1 = 26 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_TBD0 = 27 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_NCF_CGT_DIS = 28 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_NCF_CGT_DIS_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_SRQCFG0_NCF_DRAM_CMD_FLUSH_EN = 31 ;
-
-static const uint8_t EXPLR_SRQ_SRQFIRQ_MBA_RECOVERABLE_ERROR = 0 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_MBA_NONRECOVERABLE_ERROR = 1 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_REFRESH_OVERRUN = 2 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_WAT_ERROR = 3 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_RCD_PARITY_ERROR = 4 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_NCF_MCB_LOGIC_ERROR = 5 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_EMERGENCY_THROTTLE = 6 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_NCF_MCB_PARITY_ERROR = 7 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_DDR_MBA_EVENT_N = 8 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_WRQ_RRQ_HANG_ERR = 9 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_SM_1HOT_ERR = 10 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_REG_PARITY_ERROR = 11 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_CMD_PARITY_ERROR = 12 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_PORT_FAIL = 13 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_INFO_REG_PARITY_ERROR = 14 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_DEBUG_PARITY_ERROR = 15 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR0 = 16 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR1 = 17 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR2 = 18 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR3 = 19 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR4 = 20 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR5 = 21 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR6 = 22 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR7 = 23 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_NCF_UE = 24 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_TBD_FREE = 25 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_NCF_LOGIC_ERROR = 26 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_NCF_PARITY_ERROR = 27 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_NCF_CORR_ERROR = 28 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_INTERNAL_SCOM_ERROR = 29 ;
-static const uint8_t EXPLR_SRQ_SRQFIRQ_INTERNAL_SCOM_ERROR_COPY = 30 ;
-
-static const uint8_t EXPLR_SRQ_SRQFIRWOF_FIR_WOF = 0 ;
-static const uint8_t EXPLR_SRQ_SRQFIRWOF_FIR_WOF_LEN = 31 ;
-
-static const uint8_t EXPLR_SRQ_SRQFIR_ACTION0_FIR = 0 ;
-static const uint8_t EXPLR_SRQ_SRQFIR_ACTION0_FIR_LEN = 31 ;
-
-static const uint8_t EXPLR_SRQ_SRQFIR_ACTION1_FIR = 0 ;
-static const uint8_t EXPLR_SRQ_SRQFIR_ACTION1_FIR_LEN = 31 ;
-
-static const uint8_t EXPLR_SRQ_SRQFIR_MASK_MBA = 0 ;
-static const uint8_t EXPLR_SRQ_SRQFIR_MASK_MBA_LEN = 31 ;
-
-static const uint8_t EXPLR_SRQ_SRQTRAP0_DEBUG_BUS = 0 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP0_DEBUG_BUS_LEN = 64 ;
-
-static const uint8_t EXPLR_SRQ_SRQTRAP1_DEBUG_BUS = 0 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_DEBUG_BUS_LEN = 24 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_NCF_SYNDROME = 24 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_NCF_SYNDROME_LEN = 8 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_REFBLK_SYNDROME = 32 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_REFBLK_SYNDROME_LEN = 8 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_NCF_INVALID_CMD_CODE = 40 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_NCF_INVALID_CMD_CODE_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_REFBLK_INVALID_CMD_CODE = 44 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_REFBLK_INVALID_CMD_CODE_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_MCB_CREDITS = 48 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_MCB_CREDITS_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_NCF_FSM_ENCODE = 52 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_NCF_FSM_ENCODE_LEN = 4 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_REFBLK_FSM_ENCODE = 56 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_REFBLK_FSM_ENCODE_LEN = 3 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_MCB_STATUS = 59 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_MCB_STATUS_LEN = 2 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_TBD = 61 ;
-static const uint8_t EXPLR_SRQ_SRQTRAP1_TBD_LEN = 3 ;
-
-static const uint8_t EXPLR_TLXT_ERR_HOLD_LAT_FIR_MASK_PAR = 0 ;
-static const uint8_t EXPLR_TLXT_ERR_HOLD_LAT_FIR_ACTION0_PAR = 1 ;
-static const uint8_t EXPLR_TLXT_ERR_HOLD_LAT_FIR_ACTION1_PAR = 2 ;
-
-static const uint8_t EXPLR_TLXT_ERR_MASK_LAT_FIR_PAR = 0 ;
-static const uint8_t EXPLR_TLXT_ERR_MASK_LAT_FIR_ACTION0_PAR = 1 ;
-static const uint8_t EXPLR_TLXT_ERR_MASK_LAT_FIR_ACTION1_PAR = 2 ;
-
-static const uint8_t EXPLR_TLXT_TLXCFG0_TRAP_CLEAR = 0 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_EARLY_WDONE_DISABLE = 1 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_EARLY_WDONE_DISABLE_LEN = 2 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_TRAP_UPDATE = 3 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_HOLD_ACUM = 4 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_TBD = 5 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_TBD_LEN = 5 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_DCP1_RETURN_PAUSE = 10 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_DCP1_CREDIT_UPDATE = 11 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_VC0_RETURN_PAUSE = 12 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_VC0_CREDIT_UPDATE = 13 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_VC1_RETURN_PAUSE = 14 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_VC1_CREDIT_UPDATE = 15 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_DCP1_INIT = 16 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_DCP1_INIT_LEN = 16 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_VC0_INIT = 32 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_VC0_INIT_LEN = 16 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_VC1_INIT = 48 ;
-static const uint8_t EXPLR_TLXT_TLXCFG0_VC1_INIT_LEN = 16 ;
-
-static const uint8_t EXPLR_TLXT_TLXCFG1_SLOW_CLOCK = 0 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_SHUTDOWN_MODE = 1 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_SHUTDOWN_MODE_LEN = 2 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_SHUTDOWN_ON_OPT_ERR = 3 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_SHUTDOWN_ON_MMIO_BAD = 4 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_SHUTDOWN_ON_DFLOW_ERR = 5 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_SHUTDOWN_ON_BAR0_BAD = 6 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_RESERVED = 7 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TLXR_DEBSEL_LO = 8 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TLXR_DEBSEL_LO_LEN = 4 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TLXR_DEBSEL_HI = 12 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TLXR_DEBSEL_HI_LEN = 4 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_DBG_DIAL = 16 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_DBG_DIAL_LEN = 16 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_HI_BW_THRESHOLD = 32 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_HI_BW_THRESHOLD_LEN = 3 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_MID_BW_THRESHOLD = 35 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_MID_BW_THRESHOLD_LEN = 3 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_HI_BW_DIS = 38 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_MID_BW_ENAB = 39 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_HI_BW_ENAB_RD_THRESH = 40 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_LOW_LAT_RD_DIS = 41 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_CLK_GATE_DIS = 42 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_CFEI_ENAB = 43 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_CFEI_PERSIST = 44 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_CFEI_BIT0 = 45 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_CFEI_BIT1 = 46 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TBD = 47 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_0 = 48 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_0_LEN = 4 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_1 = 52 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_1_LEN = 4 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_2 = 56 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_2_LEN = 4 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_3 = 60 ;
-static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_3_LEN = 4 ;
-
-static const uint8_t EXPLR_TLXT_TLXCFG2_TLXC_WAT_EN_REG = 0 ;
-static const uint8_t EXPLR_TLXT_TLXCFG2_TLXC_WAT_EN_REG_LEN = 24 ;
-static const uint8_t EXPLR_TLXT_TLXCFG2_TBD = 24 ;
-static const uint8_t EXPLR_TLXT_TLXCFG2_TBD_LEN = 40 ;
-
-static const uint8_t EXPLR_TLXT_TLXFIRACT0_FIR_ACTION0 = 0 ;
-static const uint8_t EXPLR_TLXT_TLXFIRACT0_FIR_ACTION0_LEN = 30 ;
-
-static const uint8_t EXPLR_TLXT_TLXFIRACT1_FIR_ACTION1 = 0 ;
-static const uint8_t EXPLR_TLXT_TLXFIRACT1_FIR_ACTION1_LEN = 30 ;
-
-static const uint8_t EXPLR_TLXT_TLXFIRMASK_FIR_MASK = 0 ;
-static const uint8_t EXPLR_TLXT_TLXFIRMASK_FIR_MASK_LEN = 30 ;
-
-static const uint8_t EXPLR_TLXT_TLXFIRQ_INFO_REG_PARITY_ERROR = 0 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_CTRL_REG_PARITY_ERROR = 1 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLX_VC0_MAX_CRD_ERROR = 2 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLX_VC1_MAX_CRD_ERROR = 3 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLX_DCP0_MAX_CRD_ERROR = 4 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLX_DCP1_MAX_CRD_ERROR = 5 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_CREDIT_MGMT_ERROR = 6 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_CREDIT_MGMT_PERROR = 7 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXT_PARITY_ERROR = 8 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXT_RECOVERABLE_ERROR = 9 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXT_CONFIG_ERROR = 10 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXT_INFORMATIONAL_PERROR = 11 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXT_HARD_ERROR = 12 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_RESERVED_10 = 13 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_RESERVED_10_LEN = 3 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_SHUTDOWN = 16 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_BAR0_OR_MMIO_NF = 17 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_OC_MALFORMED = 18 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_OC_PROTOCOL_ERROR = 19 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_ADDR_XLAT = 20 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_METADATA_UNC_DPERR = 21 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_OC_UNSUPPORTED = 22 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_OC_FATAL = 23 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_CONTROL_ERROR = 24 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_INTERNAL_ERROR = 25 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_INFORMATIONAL = 26 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_TRACE_STOP = 27 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_INTERNAL_SCOM_ERROR = 28 ;
-static const uint8_t EXPLR_TLXT_TLXFIRQ_INTERNAL_SCOM_ERROR_CLONE = 29 ;
-
-static const uint8_t EXPLR_TLXT_TLXFIRWOF_FIR_WOF = 0 ;
-static const uint8_t EXPLR_TLXT_TLXFIRWOF_FIR_WOF_LEN = 30 ;
-
-static const uint8_t EXPLR_TLXT_TLXTINTHLD0_TLXT_INTHLD_0_REG = 0 ;
-static const uint8_t EXPLR_TLXT_TLXTINTHLD0_TLXT_INTHLD_0_REG_LEN = 64 ;
-
-static const uint8_t EXPLR_TLXT_TLXTINTHLD1_TLXT_INTHLD_1_REG = 0 ;
-static const uint8_t EXPLR_TLXT_TLXTINTHLD1_TLXT_INTHLD_1_REG_LEN = 64 ;
-
-static const uint8_t EXPLR_TLXT_TLXTINTHLD2_TLXT_INTHLD_2_REG = 0 ;
-static const uint8_t EXPLR_TLXT_TLXTINTHLD2_TLXT_INTHLD_2_REG_LEN = 64 ;
-
-static const uint8_t EXPLR_TLXT_TLXTINTHLD3_TLXT_INTHLD_3_REG = 0 ;
-static const uint8_t EXPLR_TLXT_TLXTINTHLD3_TLXT_INTHLD_3_REG_LEN = 64 ;
-
-static const uint8_t EXPLR_TLXT_TLXTRAP0_DEBUG_BUS = 0 ;
-static const uint8_t EXPLR_TLXT_TLXTRAP0_DEBUG_BUS_LEN = 64 ;
-
-static const uint8_t EXPLR_TLXT_TLXTRAP1_DEBUG_BUS = 0 ;
-static const uint8_t EXPLR_TLXT_TLXTRAP1_DEBUG_BUS_LEN = 64 ;
-
-static const uint8_t EXPLR_TLXT_TLXTTRAP2_DEBUG_BUS = 0 ;
-static const uint8_t EXPLR_TLXT_TLXTTRAP2_DEBUG_BUS_LEN = 64 ;
-
-static const uint8_t EXPLR_TLXT_TLXTTRAP3_DEBUG_BUS = 0 ;
-static const uint8_t EXPLR_TLXT_TLXTTRAP3_DEBUG_BUS_LEN = 64 ;
-
-static const uint8_t EXPLR_TLXT_TLXTTRAP4_DEBUG_BUS = 0 ;
-static const uint8_t EXPLR_TLXT_TLXTTRAP4_DEBUG_BUS_LEN = 64 ;
-
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_TLXR_UNUSED = 0 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_TLXR_UNUSED_LEN = 5 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SPARE_7 = 5 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_TLXR_SHUTDOWN = 6 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_MMIO_BAD_WR_RESP_NF = 7 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAR0_PERR_NF = 8 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAD_TEMPLATE_OPCODE_COMBO = 9 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SPARE_6 = 10 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAD_CREDIT_RETURN_SLOT = 11 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAD_TEMPLATE_0_FORMAT = 12 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_RESERVED_FIELD_VALUE = 13 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_DATA_SEQ_ERR = 14 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_RD_BDY_ERR = 15 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_WR_BDY_ERR = 16 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SPARE_5 = 17 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAD_INTRP_RESP_TAG = 18 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAD_MEMCTL = 19 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SPARE_4 = 20 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SPARE_3 = 21 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SPARE_2 = 22 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_ADDRESS_DROPPED = 23 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_ADDR_XLAT_ERROR_RD = 24 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_ADDR_XLAT_ERROR_WR = 25 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_PATTERN_CORRUPT = 26 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_DATAFLOW_PERR_NF = 27 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_METADATA_UNC = 28 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_PR_RD_DDR = 29 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_RD_MEM = 30 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_WRITE = 31 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_PR_LENGTH = 32 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_PAD_MEM = 33 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_PAD_MEM_LEN_ERR = 34 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_WRITE_LENGTH = 35 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_READ_LENGTH = 36 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_OPCODE = 37 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_TEMPLATE = 38 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_DATA_CARRIER = 39 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BUFF_CNTL_PERR = 40 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_D_LIST_UNC = 41 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_TAGSTORE_UNC = 42 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_B_MGMT_3 = 43 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SPARE_1 = 44 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_FLIT_PERR = 45 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_MMIO_WD_PERR = 46 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_MMIO_WD_INV = 47 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SRQ_WD_PERR = 48 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SRQ_WD_INV = 49 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_D_LIST_UNDERFLOW = 50 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_DATAFLOW_PERR_F = 51 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_D_LIST_OVERFLOW = 52 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_MMIO_BAD_WR_RESP_F = 53 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAR0_PERR_F = 54 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_B_MGMT_1 = 55 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_B_MGMT_2 = 56 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_ADDR_XLATE_HOLE = 57 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAD_DATA_RXD = 58 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_METADATA_CORR = 59 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_TAG_BUFFER_CORR = 60 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_D_LIST_CORR = 61 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_EPOW_SIGNALLED = 62 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_TRACE_STOP = 63 ;
-
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_MASK_ERRMASK = 0 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_MASK_ERRMASK_LEN = 64 ;
-
-static const uint8_t EXPLR_TLXT_TLX_ERR1_REPORTQ_TLXT_PERRORS = 0 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR1_REPORTQ_TLXT_PERRORS_LEN = 37 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR1_REPORTQ_TLXT_ERRORS = 37 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR1_REPORTQ_TLXT_ERRORS_LEN = 27 ;
-
-static const uint8_t EXPLR_TLXT_TLX_ERR1_REPORTQ_MASK_ERRMASK = 0 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR1_REPORTQ_MASK_ERRMASK_LEN = 64 ;
-
-static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_TLXC_PERRORS = 0 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_TLXC_PERRORS_LEN = 8 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_TLXC_ERRORS = 8 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_TLXC_ERRORS_LEN = 6 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_INTHLD_PERROR = 14 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_INTHLD_PERROR_LEN = 4 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_TLXC_SPARE = 18 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_TLXC_SPARE_LEN = 14 ;
-
-static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_MASK_ERRMASK = 0 ;
-static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_MASK_ERRMASK_LEN = 32 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_PER_BANK_REFRESH = 3 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_RESERVED_4 = 4 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_PRIORITY_THRESHOLD = 5 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_PRIORITY_THRESHOLD_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_INTERVAL = 8 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_INTERVAL_LEN = 11 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_RESET_INTERVAL = 19 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_RESET_INTERVAL_LEN = 11 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_TRFC = 30 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_TRFC_LEN = 10 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFR_TSV_STACK = 40 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFR_TSV_STACK_LEN = 10 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFR_CHECK_INTERVAL = 50 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_REFR_CHECK_INTERVAL_LEN = 11 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_CFG_TRFC_STACK_GATE_ALL_REF = 61 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_RESERVED_62_63 = 62 ;
+static const uint8_t EXPLR_SRQ_MBAREF0Q_RESERVED_62_63_LEN = 2 ;
+
+static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_STATIC_IDLE_DLY = 0 ;
+static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_STATIC_IDLE_DLY_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_LP_SUB_CNT = 4 ;
+static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_LP_SUB_CNT_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_REFRESH_HP_RANK_BLOCK_ENABLE = 6 ;
+static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_HP_WR_GATE_LP_REF_DIS = 7 ;
+static const uint8_t EXPLR_SRQ_MBAREFAQ_RESERVED_8_9 = 8 ;
+static const uint8_t EXPLR_SRQ_MBAREFAQ_RESERVED_8_9_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_REF_BLOCK_STOP_DLY = 10 ;
+static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_REF_BLOCK_STOP_DLY_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_TSTAB = 16 ;
+static const uint8_t EXPLR_SRQ_MBAREFAQ_CFG_TSTAB_LEN = 13 ;
+static const uint8_t EXPLR_SRQ_MBAREFAQ_RESERVED_29_31 = 29 ;
+static const uint8_t EXPLR_SRQ_MBAREFAQ_RESERVED_29_31_LEN = 3 ;
+
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_LP_CTRL_ENABLE = 0 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_LP_DATA_ENABLE = 1 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_MIN_MAX_DOMAINS_ENABLE = 2 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_MIN_MAX_DOMAINS = 3 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_MIN_MAX_DOMAINS_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_AVAIL = 6 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_AVAIL_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PDN_PUP = 11 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PDN_PUP_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_PDN = 16 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_PDN_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_QUAD_RANK_ENC = 21 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_MIN_DOMAIN_REDUCTION_ENABLE = 22 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_MIN_DOMAIN_REDUCTION_TIME = 23 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_MIN_DOMAIN_REDUCTION_TIME_LEN = 10 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_AFTER_ACTIVATE_WAIT_ENABLE = 33 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_AFTER_ACTIVATE_WAIT_TIME = 34 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_AFTER_ACTIVATE_WAIT_TIME_LEN = 8 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_CONC_LP_DATA_DISABLE = 42 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_MIN_DOMAIN_REDUCTION_CNT_REFR_INT = 43 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_EMER_MIN_MAX_DOMAIN = 44 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_EMER_MIN_MAX_DOMAIN_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_PUP_ALL_WRITES_PENDING = 47 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_ALWAYS_WAIT_ACT_TIME = 48 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_TLP_RESP = 49 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_TLP_RESP_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_TLP_WAKEUP = 54 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_TLP_WAKEUP_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_CFG_CONC_CCS_STR_EN = 59 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_RESERVED_60_63 = 60 ;
+static const uint8_t EXPLR_SRQ_MBARPC0Q_RESERVED_60_63_LEN = 4 ;
+
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_STR_ENABLE = 0 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_DIS_CLK_IN_STR = 1 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_ENTER_STR_TIME = 2 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_ENTER_STR_TIME_LEN = 10 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TCKESR = 12 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TCKESR_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TCKSRE = 17 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TCKSRE_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TCKSRX = 22 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TCKSRX_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TXSDLL = 27 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TXSDLL_LEN = 11 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TRFC_COUNTER_DIS = 38 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_TRFC_COUNTER_DIS_LEN = 8 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_SAFE_REFRESH_INTERVAL = 46 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_SAFE_REFRESH_INTERVAL_LEN = 11 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_OCC_DEADMAN_TIMER_SEL = 57 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_OCC_DEADMAN_TIMER_SEL_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_OCC_DEADMAN_TB_SEL = 61 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_FORCE_STR = 62 ;
+static const uint8_t EXPLR_SRQ_MBASTR0Q_CFG_EPOW_DISABLE = 63 ;
+
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_ENABLE = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL0 = 1 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL0_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL1 = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL1_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL2 = 7 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL2_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL3 = 10 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL3_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL4 = 13 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL4_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL5 = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL5_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL6 = 19 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL6_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL7 = 22 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SEL7_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP0_FLIP = 25 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP1_FLIP = 26 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP2_FLIP = 27 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP3_FLIP = 28 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP4_FLIP = 29 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP5_FLIP = 30 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP6_FLIP = 31 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_DBG_SRQ_SETUP7_FLIP = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_RESERVED_33_47 = 33 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_RESERVED_33_47_LEN = 15 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_WAT_FARB_RRQ_GT = 48 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_WAT_FARB_RRQ_GT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_WAT_FARB_WRQ_GT = 52 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_WAT_FARB_WRQ_GT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_WAT_FARB_REF_GT = 56 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_CFG_WAT_FARB_REF_GT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_RESERVED_60_63 = 60 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG0Q_RESERVED_60_63_LEN = 4 ;
+
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_FORCE_WR_ENTRY0_HP = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_FORCE_WR_ENTRY0_HP_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_FORCE_RD_ENTRY0_HP = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_FORCE_RD_ENTRY0_HP_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_FP_DIS = 8 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_FP_DIS_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_DIS_RD_PG = 12 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_DIS_RD_PG_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_DIS_WR_PG = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_DIS_WR_PG_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_PUP_ALL = 20 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_PUP_ALL_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_EXIT_STR = 24 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_EXIT_STR_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_REF_HP = 28 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_REF_HP_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_REF_SYNC = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_REF_SYNC_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_REF_SAFE = 36 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_REF_SAFE_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_RESERVED_40_43 = 40 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_RESERVED_40_43_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_MCBIST_GT = 44 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_MCBIST_GT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_NCF_RM_INVALID_CMD = 48 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_NCF_RM_INVALID_CMD_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_SET_FIR = 52 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_SET_FIR_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_EMER_TH = 56 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_EMER_TH_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_START_RECOVERY = 60 ;
+static const uint8_t EXPLR_SRQ_MBA_DBG1Q_CFG_WAT_START_RECOVERY_LEN = 4 ;
+
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RODT_START_DLY = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RODT_START_DLY_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RODT_END_DLY = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RODT_END_DLY_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WODT_START_DLY = 12 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WODT_START_DLY_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WODT_END_DLY = 18 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WODT_END_DLY_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRDONE_DLY = 24 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRDONE_DLY_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRDATA_DLY = 30 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRDATA_DLY_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RDTAG_DLY = 36 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RDTAG_DLY_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RDCSLAT_DLY = 42 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RDCSLAT_DLY_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RDDATA_EN_DLY = 47 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RDDATA_EN_DLY_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRCSLAT_DLY = 52 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRCSLAT_DLY_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRDATA_EN_DLY = 57 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_WRDATA_EN_DLY_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RDTAG_DLY_MSB = 62 ;
+static const uint8_t EXPLR_SRQ_MBA_DSM0Q_CFG_RDTAG_DLY_MSB_LEN = 2 ;
+
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_PC_PCFSM_1HOT = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_STRFSM_1HOT = 1 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_FARB_RECVFSM_1HOT = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_PC_PE = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_RRQ_PE = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_WRQ_PE = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_DSM_PE = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_TMR_PE = 7 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_FARB_PE = 8 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_WRQ_HANG = 9 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_RRQ_HANG = 10 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_FARB_CMD_PE_HOLD_OUT = 11 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_DSM_CMD_PE_HOLD_OUT = 12 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_UE = 13 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_UE_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_TBD = 15 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_TBD_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_MCB_LOGIC_ERROR = 17 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_MCB_LOGIC_ERROR_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_LOGIC_ERROR = 22 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_LOGIC_ERROR_LEN = 15 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_MCB_PARITY_ERROR = 37 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_MCB_PARITY_ERROR_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_PARITY_ERROR = 42 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_PARITY_ERROR_LEN = 11 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_CE = 53 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_NCF_CE_LEN = 4 ;
+
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_MASK_ERRMASK = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_ERR_REPORTQ_MASK_ERRMASK_LEN = 57 ;
+
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_CID2_AS_PAR_ENABLE = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_QUAD_RANK_ENC_4DATA_CSN_ENABLE = 1 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_RESERVED_2_15 = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_RESERVED_2_15_LEN = 14 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_INIT_START = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_2N_ADDR = 17 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_DDP_ADDR_MODE = 18 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_PLANAR_ADDR_MODE = 19 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_ACT_SAME_RANK_HOLD_TIME = 20 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_ACT_SAME_RANK_HOLD_TIME_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_MAX_READS_IN_A_ROW = 24 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_MAX_READS_IN_A_ROW_LEN = 7 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_MAX_WRITES_IN_A_ROW = 31 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_MAX_WRITES_IN_A_ROW_LEN = 7 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_PARITY_AFTER_CMD = 38 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_HYNIX_MDS_MODE = 39 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_INJECT_PARITY_ERR_ADDR5 = 40 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_BW_WINDOW_SIZE = 41 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_BW_WINDOW_SIZE_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_RESERVED_43_47 = 43 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_RESERVED_43_47_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_RCD_PROTECTION_TIME = 48 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_RCD_PROTECTION_TIME_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_DISABLE_RCD_RECOVERY = 54 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_WAIT_FOR_INIT_COMPLETE = 55 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_FARB_CLOSE_ALL_PAGES = 56 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_PORT_FAIL_DISABLE = 57 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_DBG_HALF_DIMM = 58 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_INJECT_PARITY_ERR_CONSTANT = 59 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_FINISH_WR_BEFORE_RD = 60 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_OPT_RD_SIZE = 61 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB0Q_CFG_OPT_RD_SIZE_LEN = 3 ;
+
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S0_CID = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S0_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S1_CID = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S1_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S2_CID = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S2_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S3_CID = 9 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S3_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S4_CID = 12 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S4_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S5_CID = 15 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S5_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S6_CID = 18 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S6_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S7_CID = 21 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT0_S7_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S0_CID = 24 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S0_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S1_CID = 27 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S1_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S2_CID = 30 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S2_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S3_CID = 33 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S3_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S4_CID = 36 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S4_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S5_CID = 39 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S5_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S6_CID = 42 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S6_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S7_CID = 45 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_SLOT1_S7_CID_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_DIS_SMDR = 48 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_DDR4_PARITY_ON_CID_DIS = 49 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_READ_2CYC_PREAMBLE_EN = 50 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_WRITE_2CYC_PREAMBLE_EN = 51 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_RDCSGAP_DLY = 52 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_RDCSGAP_DLY_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_WRCSGAP_DLY = 55 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_WRCSGAP_DLY_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_RDCSLAT_DLY_MSB = 58 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_RDCSLAT_DLY_MSB_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_RDDATA_EN_DLY_MSB = 61 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB1Q_CFG_RDDATA_EN_DLY_MSB_LEN = 3 ;
+
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK0_RD_ODT = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK0_RD_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK1_RD_ODT = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK1_RD_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK2_RD_ODT = 8 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK2_RD_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK3_RD_ODT = 12 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK3_RD_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK4_RD_ODT = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK4_RD_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK5_RD_ODT = 20 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK5_RD_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK6_RD_ODT = 24 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK6_RD_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK7_RD_ODT = 28 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK7_RD_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK0_WR_ODT = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK0_WR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK1_WR_ODT = 36 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK1_WR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK2_WR_ODT = 40 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK2_WR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK3_WR_ODT = 44 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK3_WR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK4_WR_ODT = 48 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK4_WR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK5_WR_ODT = 52 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK5_WR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK6_WR_ODT = 56 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK6_WR_ODT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK7_WR_ODT = 60 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB2Q_CFG_RANK7_WR_ODT_LEN = 4 ;
+
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_N_PER_SLOT = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_N_PER_SLOT_LEN = 15 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_N_PER_PORT = 15 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_N_PER_PORT_LEN = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_M = 31 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_M_LEN = 14 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_RAS_WEIGHT = 45 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_RAS_WEIGHT_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_CAS_WEIGHT = 48 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_CAS_WEIGHT_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_RESERVED_51 = 51 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_RESERVED_52 = 52 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_CFG_NM_CHANGE_AFTER_SYNC = 53 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_RESERVED_54_63 = 54 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB3Q_RESERVED_54_63_LEN = 10 ;
+
+static const uint8_t EXPLR_SRQ_MBA_FARB4Q_CFG_NOISE_WAIT_TIME = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB4Q_CFG_NOISE_WAIT_TIME_LEN = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB4Q_CFG_PRECHARGE_WAIT_TIME = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB4Q_CFG_PRECHARGE_WAIT_TIME_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB4Q_CFG_SIM_FAST_NOISE_WINDOW = 22 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB4Q_RESERVED_23_26 = 23 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB4Q_RESERVED_23_26_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB4Q_EMERGENCY_N = 27 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB4Q_EMERGENCY_N_LEN = 15 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB4Q_EMERGENCY_M = 42 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB4Q_EMERGENCY_M_LEN = 14 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB4Q_RESERVED_56_63 = 56 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB4Q_RESERVED_56_63_LEN = 8 ;
+
+static const uint8_t EXPLR_SRQ_MBA_FARB5Q_RESERVED_0_3 = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB5Q_RESERVED_0_3_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB5Q_CFG_DDR_RESETN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB5Q_CFG_CCS_ADDR_MUX_SEL = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB5Q_CFG_CCS_INST_RESET_ENABLE = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB5Q_RESERVED_7_15 = 7 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB5Q_RESERVED_7_15_LEN = 9 ;
+
+static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_BW_SNAPSHOT = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_BW_SNAPSHOT_LEN = 11 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_CKE_PUP_STATE = 11 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_CKE_PUP_STATE_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_STR_STATE = 15 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_RRQ_DEPTH = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_RRQ_DEPTH_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_WRQ_DEPTH = 21 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_WRQ_DEPTH_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_RCD_PARITY_DLY = 26 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_RCD_PARITY_DLY_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_EVENT = 31 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB6Q_CFG_INIT_COMPLETE = 32 ;
+
+static const uint8_t EXPLR_SRQ_MBA_FARB7Q_EMER_THROTTLE_IP = 0 ;
+
+static const uint8_t EXPLR_SRQ_MBA_FARB8Q_SAFE_REFRESH_MODE = 0 ;
+
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_ENABLE = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_INTERVAL_TB = 1 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_INTERVAL_TB_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_INTERVAL = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_INTERVAL_LEN = 9 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_RESERVED_12 = 12 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_RUN_LENGTH = 13 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_RUN_LENGTH_LEN = 8 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_RUN_LENGTH_TB = 21 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_RUN_LENGTH_TB_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_RESERVED_23_28 = 23 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_RESERVED_23_28_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_CTRLUPD_SINGLE_REQ = 29 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_CTRLUPD_AFTER_PHY_INT = 30 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_CTRLUPD_AFTER_ERR = 31 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_ENABLE = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_INTERVAL_TB = 33 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_INTERVAL_TB_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_INTERVAL = 35 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_INTERVAL_LEN = 9 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_FIXED_RUN_LENGTH_EN = 44 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_RUN_LENGTH = 45 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_RUN_LENGTH_LEN = 10 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_CTRLUPD_MIN = 55 ;
+static const uint8_t EXPLR_SRQ_MBA_FARB9Q_CFG_MC_PER_CAL_CTRLUPD_MIN_LEN = 9 ;
+
+static const uint8_t EXPLR_SRQ_MBA_PMU0Q_READ_COUNT = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU0Q_READ_COUNT_LEN = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU0Q_WRITE_COUNT = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU0Q_WRITE_COUNT_LEN = 32 ;
+
+static const uint8_t EXPLR_SRQ_MBA_PMU1Q_ACTIVATE_COUNT = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU1Q_ACTIVATE_COUNT_LEN = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU1Q_PU_COUNTS = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU1Q_PU_COUNTS_LEN = 32 ;
+
+static const uint8_t EXPLR_SRQ_MBA_PMU2Q_FRAME_COUNT = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU2Q_FRAME_COUNT_LEN = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU2Q_STR_EXIT_COUNT = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU2Q_STR_EXIT_COUNT_LEN = 8 ;
+
+static const uint8_t EXPLR_SRQ_MBA_PMU3Q_LOW_IDLE_THRESHOLD = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU3Q_LOW_IDLE_THRESHOLD_LEN = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU3Q_MED_IDLE_THRESHOLD = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU3Q_MED_IDLE_THRESHOLD_LEN = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU3Q_HIGH_IDLE_THRESHOLD = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU3Q_HIGH_IDLE_THRESHOLD_LEN = 32 ;
+
+static const uint8_t EXPLR_SRQ_MBA_PMU4Q_BASE_IDLE_COUNT = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU4Q_BASE_IDLE_COUNT_LEN = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU4Q_LOW_IDLE_COUNT = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU4Q_LOW_IDLE_COUNT_LEN = 32 ;
+
+static const uint8_t EXPLR_SRQ_MBA_PMU5Q_MED_IDLE_COUNT = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU5Q_MED_IDLE_COUNT_LEN = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU5Q_HIGH_IDLE_COUNT = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU5Q_HIGH_IDLE_COUNT_LEN = 32 ;
+
+static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT0_COUNTER = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT0_COUNTER_LEN = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT1_COUNTER = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT1_COUNTER_LEN = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT2_COUNTER = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT2_COUNTER_LEN = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT3_COUNTER = 48 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU6Q_EVENT3_COUNTER_LEN = 16 ;
+
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT0_SELECT = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT0_SELECT_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT1_SELECT = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT1_SELECT_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT2_SELECT = 12 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT2_SELECT_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT3_SELECT = 18 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_EVENT3_SELECT_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C0 = 24 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C0_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C1 = 26 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C1_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C2 = 28 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C2_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C3 = 30 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PRESCALER_C3_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CASCADE = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CASCADE_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_FREEZE = 35 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PMU_START_RESET = 36 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PMU_START_NO_RESET = 37 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_PMU_STOP = 38 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU7Q_CFG_RESET_PMU6_WHEN_READ = 39 ;
+
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_TYPE = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_TYPE_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_MRANK_MATCH_EN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_SRANK_MATCH_EN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_BG_MATCH_EN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_BANK_MATCH_EN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_MRANK = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_MRANK_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_SRANK = 9 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_SRANK_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_BG = 12 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_BG_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_BANK = 14 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD0_BANK_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_TYPE = 17 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_TYPE_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_MRANK_MATCH_EN = 19 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_SRANK_MATCH_EN = 20 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_BG_MATCH_EN = 21 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_BANK_MATCH_EN = 22 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_MRANK = 23 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_MRANK_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_SRANK = 26 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_SRANK_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_BG = 29 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_BG_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_BANK = 31 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD1_BANK_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_TYPE = 34 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_TYPE_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_MRANK_MATCH_EN = 36 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_SRANK_MATCH_EN = 37 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_BG_MATCH_EN = 38 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_BANK_MATCH_EN = 39 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_MRANK = 40 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_MRANK_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_SRANK = 43 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_SRANK_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_BG = 46 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_BG_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_BANK = 48 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_CFG_CMD2_BANK_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_RESERVED_51_63 = 51 ;
+static const uint8_t EXPLR_SRQ_MBA_PMU8Q_RESERVED_51_63_LEN = 13 ;
+
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RRQ_SKIP_LIMIT = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RRQ_SKIP_LIMIT_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RRQ_FIFO_MODE = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RRQ_SINGLE_THREAD_MODE = 7 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_RESERVED_8_10 = 8 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_RESERVED_8_10_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_DISABLE_RD_PG_MODE = 11 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_DISABLE_FAST_ACT = 12 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RD_IDLE_ALLOW_WR = 13 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RD_IDLE_ALLOW_WR_LEN = 11 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RDBUFF_CAPACITY_LIMIT = 24 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RDBUFF_CAPACITY_LIMIT_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_SRQ_RRQ_DBG_SEL = 30 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_SRQ_RRQ_DBG_SEL_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_RESERVED_34_56 = 34 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_RESERVED_34_56_LEN = 23 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RRQ_ACT_NUM_READS_PENDING = 57 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RRQ_ACT_NUM_READS_PENDING_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_DISABLE_FAST_ACT_FIFO = 61 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_RRQ_ENTRY0_ENABLE = 62 ;
+static const uint8_t EXPLR_SRQ_MBA_RRQ0Q_CFG_CRIT_OW_FIRST_EN = 63 ;
+
+static const uint8_t EXPLR_SRQ_MBA_SYNCCNTLQ_SYNC_REF_EN = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_SYNCCNTLQ_SYNC_PC_EN = 1 ;
+static const uint8_t EXPLR_SRQ_MBA_SYNCCNTLQ_SYNC_TIMEBASE_EN = 2 ;
+static const uint8_t EXPLR_SRQ_MBA_SYNCCNTLQ_RESERVED_3_7 = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_SYNCCNTLQ_RESERVED_3_7_LEN = 5 ;
+
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RRDM_DLY = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RRDM_DLY_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RRSMSR_DLY = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RRSMSR_DLY_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RRSMDR_DLY = 8 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RRSMDR_DLY_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RROP_DLY = 12 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RROP_DLY_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWDM_DLY = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWDM_DLY_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWSMSR_DLY = 20 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWSMSR_DLY_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWSMDR_DLY = 24 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWSMDR_DLY_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWOP_DLY = 28 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WWOP_DLY_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RWDM_DLY = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RWDM_DLY_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RWSMSR_DLY = 37 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RWSMSR_DLY_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RWSMDR_DLY = 42 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RWSMDR_DLY_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WRDM_DLY = 47 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WRDM_DLY_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WRSMSR_DLY = 51 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WRSMSR_DLY_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WRSMDR_DLY = 57 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_WRSMDR_DLY_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR0Q_RESERVED_63 = 63 ;
+
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_RRSBG_DLY = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_RRSBG_DLY_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_WRSBG_DLY = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_WRSBG_DLY_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TFAW = 10 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TFAW_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRCD = 16 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRCD_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRP = 21 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRP_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRAS = 26 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRAS_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRAS_MSB = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRCD_MSB = 33 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_TRP_MSB = 34 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_RD2PRE_MSB = 35 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_RD2PRE_MSB_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_WR2PRE_MSB = 39 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_RESERVED_40 = 40 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_WR2PRE = 41 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_WR2PRE_LEN = 7 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_RD2PRE = 48 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_RD2PRE_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_TRRD = 52 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_TRRD_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_TRRD_SBG = 56 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_TRRD_SBG_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_ACT_TO_DIFF_RANK_DLY = 60 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR1Q_CFG_ACT_TO_DIFF_RANK_DLY_LEN = 4 ;
+
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_CFG_BANK_BUSY_FSM_DIS = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_CFG_BANK_BUSY_FSM_DIS_LEN = 20 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_CFG_BANK_BUSY_OPEN_PAGE_DIS = 20 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_CFG_BANK_BUSY_OPEN_PAGE_DIS_LEN = 12 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_CFG_SRQ_TMR_DBG_SEL = 32 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_CFG_SRQ_TMR_DBG_SEL_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_RESERVED_37_39 = 37 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_RESERVED_37_39_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_CFG_READ_WRITE_SWITCH_DLY = 40 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_CFG_READ_WRITE_SWITCH_DLY_LEN = 8 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_CFG_WRITE_READ_SWITCH_DLY = 48 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_CFG_WRITE_READ_SWITCH_DLY_LEN = 8 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_REFRESH_RESET_RANK = 56 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_REFRESH_RESET_RANK_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_RESERVED_62_63 = 62 ;
+static const uint8_t EXPLR_SRQ_MBA_TMR2Q_RESERVED_62_63_LEN = 2 ;
+
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRITE_HW_MARK = 0 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRITE_HW_MARK_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_FIFO_MODE = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_DISABLE_WR_PG_MODE = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_ENTRY0_HP_DLY = 7 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_ENTRY0_HP_DLY_LEN = 12 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_FLUSH_WR_RANK = 19 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_ENABLE_NON_HP_WR = 20 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_ENTRY0_MIN_FOR_RRQ_IDLE_WR = 21 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_ENTRY0_MIN_FOR_RRQ_IDLE_WR_LEN = 12 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRITE_LW_MARK = 33 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRITE_LW_MARK_LEN = 5 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_SKIP_LIMIT = 38 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_SKIP_LIMIT_LEN = 6 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_SINGLE_THREAD_MODE = 44 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_RQ_HANG_THRESHOLD = 45 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_RQ_HANG_THRESHOLD_LEN = 8 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_SKIP_RRQ_ENTRIES_DIS = 53 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_RESERVED_54 = 54 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_ACT_NUM_WRITES_PENDING = 55 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_ACT_NUM_WRITES_PENDING_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_WRQ_ALLOW_NEW_PAGE_COMMIT = 59 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_SRQ_WRQ_DBG_SEL = 60 ;
+static const uint8_t EXPLR_SRQ_MBA_WRQ0Q_CFG_SRQ_WRQ_DBG_SEL_LEN = 4 ;
+
+static const uint8_t EXPLR_SRQ_SRQCFG0_MODE_ECC_CHK_DIS = 0 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_MODE_ECC_COR_DIS = 1 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_RMW_RBUF_PTR_MASK = 2 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_RMW_RBUF_PTR_MASK_LEN = 14 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_MCB_PAUSE = 16 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_MCB_CREDIT_UPDATE = 17 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_MCB_CRD_INIT = 18 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_MCB_CRD_INIT_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_TRACE_UPDATE = 22 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_CLEAR = 23 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_HOLD_ACUM = 24 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_ERR_INJ0 = 25 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_ERR_INJ1 = 26 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_TBD0 = 27 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_NCF_CGT_DIS = 28 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_NCF_CGT_DIS_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_SRQCFG0_NCF_DRAM_CMD_FLUSH_EN = 31 ;
+
+static const uint8_t EXPLR_SRQ_SRQFIRQ_MBA_RECOVERABLE_ERROR = 0 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_MBA_NONRECOVERABLE_ERROR = 1 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_REFRESH_OVERRUN = 2 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_WAT_ERROR = 3 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_RCD_PARITY_ERROR = 4 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_NCF_MCB_LOGIC_ERROR = 5 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_EMERGENCY_THROTTLE = 6 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_NCF_MCB_PARITY_ERROR = 7 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_DDR_MBA_EVENT_N = 8 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_WRQ_RRQ_HANG_ERR = 9 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_SM_1HOT_ERR = 10 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_REG_PARITY_ERROR = 11 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_CMD_PARITY_ERROR = 12 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_PORT_FAIL = 13 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_INFO_REG_PARITY_ERROR = 14 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_DEBUG_PARITY_ERROR = 15 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR0 = 16 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR1 = 17 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR2 = 18 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR3 = 19 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR4 = 20 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR5 = 21 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR6 = 22 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_WDF_ERROR7 = 23 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_NCF_UE = 24 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_TBD_FREE = 25 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_NCF_LOGIC_ERROR = 26 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_NCF_PARITY_ERROR = 27 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_NCF_CORR_ERROR = 28 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_INTERNAL_SCOM_ERROR = 29 ;
+static const uint8_t EXPLR_SRQ_SRQFIRQ_INTERNAL_SCOM_ERROR_COPY = 30 ;
+
+static const uint8_t EXPLR_SRQ_SRQFIRWOF_FIR_WOF = 0 ;
+static const uint8_t EXPLR_SRQ_SRQFIRWOF_FIR_WOF_LEN = 31 ;
+
+static const uint8_t EXPLR_SRQ_SRQFIR_ACTION0_FIR = 0 ;
+static const uint8_t EXPLR_SRQ_SRQFIR_ACTION0_FIR_LEN = 31 ;
+
+static const uint8_t EXPLR_SRQ_SRQFIR_ACTION1_FIR = 0 ;
+static const uint8_t EXPLR_SRQ_SRQFIR_ACTION1_FIR_LEN = 31 ;
+
+static const uint8_t EXPLR_SRQ_SRQFIR_MASK_MBA = 0 ;
+static const uint8_t EXPLR_SRQ_SRQFIR_MASK_MBA_LEN = 31 ;
+
+static const uint8_t EXPLR_SRQ_SRQTRAP0_DEBUG_BUS = 0 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP0_DEBUG_BUS_LEN = 64 ;
+
+static const uint8_t EXPLR_SRQ_SRQTRAP1_DEBUG_BUS = 0 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_DEBUG_BUS_LEN = 24 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_NCF_SYNDROME = 24 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_NCF_SYNDROME_LEN = 8 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_REFBLK_SYNDROME = 32 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_REFBLK_SYNDROME_LEN = 8 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_NCF_INVALID_CMD_CODE = 40 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_NCF_INVALID_CMD_CODE_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_REFBLK_INVALID_CMD_CODE = 44 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_REFBLK_INVALID_CMD_CODE_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_MCB_CREDITS = 48 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_MCB_CREDITS_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_NCF_FSM_ENCODE = 52 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_NCF_FSM_ENCODE_LEN = 4 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_REFBLK_FSM_ENCODE = 56 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_REFBLK_FSM_ENCODE_LEN = 3 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_MCB_STATUS = 59 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_MCB_STATUS_LEN = 2 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_TBD = 61 ;
+static const uint8_t EXPLR_SRQ_SRQTRAP1_TBD_LEN = 3 ;
+
+static const uint8_t EXPLR_TLXT_ERR_HOLD_LAT_FIR_MASK_PAR = 0 ;
+static const uint8_t EXPLR_TLXT_ERR_HOLD_LAT_FIR_ACTION0_PAR = 1 ;
+static const uint8_t EXPLR_TLXT_ERR_HOLD_LAT_FIR_ACTION1_PAR = 2 ;
+
+static const uint8_t EXPLR_TLXT_ERR_MASK_LAT_FIR_PAR = 0 ;
+static const uint8_t EXPLR_TLXT_ERR_MASK_LAT_FIR_ACTION0_PAR = 1 ;
+static const uint8_t EXPLR_TLXT_ERR_MASK_LAT_FIR_ACTION1_PAR = 2 ;
+
+static const uint8_t EXPLR_TLXT_TLXCFG0_TRAP_CLEAR = 0 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_EARLY_WDONE_DISABLE = 1 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_EARLY_WDONE_DISABLE_LEN = 2 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_TRAP_UPDATE = 3 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_HOLD_ACUM = 4 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_TBD = 5 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_TBD_LEN = 5 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_DCP1_RETURN_PAUSE = 10 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_DCP1_CREDIT_UPDATE = 11 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_VC0_RETURN_PAUSE = 12 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_VC0_CREDIT_UPDATE = 13 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_VC1_RETURN_PAUSE = 14 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_VC1_CREDIT_UPDATE = 15 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_DCP1_INIT = 16 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_DCP1_INIT_LEN = 16 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_VC0_INIT = 32 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_VC0_INIT_LEN = 16 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_VC1_INIT = 48 ;
+static const uint8_t EXPLR_TLXT_TLXCFG0_VC1_INIT_LEN = 16 ;
+
+static const uint8_t EXPLR_TLXT_TLXCFG1_SLOW_CLOCK = 0 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_SHUTDOWN_MODE = 1 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_SHUTDOWN_MODE_LEN = 2 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_SHUTDOWN_ON_OPT_ERR = 3 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_SHUTDOWN_ON_MMIO_BAD = 4 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_SHUTDOWN_ON_DFLOW_ERR = 5 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_SHUTDOWN_ON_BAR0_BAD = 6 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_IGNORE_A4_ON_PR_RD = 7 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_TLXR_DEBSEL_LO = 8 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_TLXR_DEBSEL_LO_LEN = 4 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_TLXR_DEBSEL_HI = 12 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_TLXR_DEBSEL_HI_LEN = 4 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_DBG_DIAL = 16 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_DBG_DIAL_LEN = 16 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_HI_BW_THRESHOLD = 32 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_HI_BW_THRESHOLD_LEN = 3 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_MID_BW_THRESHOLD = 35 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_MID_BW_THRESHOLD_LEN = 3 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_HI_BW_DIS = 38 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_MID_BW_ENAB = 39 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_HI_BW_ENAB_RD_THRESH = 40 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_LOW_LAT_RD_DIS = 41 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_CLK_GATE_DIS = 42 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_CFEI_ENAB = 43 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_CFEI_PERSIST = 44 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_CFEI_BIT0 = 45 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_CFEI_BIT1 = 46 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_LOW_LAT_DEGRADE_DIS = 47 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_0 = 48 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_0_LEN = 4 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_1 = 52 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_1_LEN = 4 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_2 = 56 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_2_LEN = 4 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_3 = 60 ;
+static const uint8_t EXPLR_TLXT_TLXCFG1_TLXT_INTRP_CMDFLAG_3_LEN = 4 ;
+
+static const uint8_t EXPLR_TLXT_TLXCFG2_TLXC_WAT_EN_REG = 0 ;
+static const uint8_t EXPLR_TLXT_TLXCFG2_TLXC_WAT_EN_REG_LEN = 24 ;
+static const uint8_t EXPLR_TLXT_TLXCFG2_XSTOP_RD_GATE_DIS = 24 ;
+static const uint8_t EXPLR_TLXT_TLXCFG2_TBD = 25 ;
+static const uint8_t EXPLR_TLXT_TLXCFG2_TBD_LEN = 39 ;
+
+static const uint8_t EXPLR_TLXT_TLXFIRACT0_FIR_ACTION0 = 0 ;
+static const uint8_t EXPLR_TLXT_TLXFIRACT0_FIR_ACTION0_LEN = 30 ;
+
+static const uint8_t EXPLR_TLXT_TLXFIRACT1_FIR_ACTION1 = 0 ;
+static const uint8_t EXPLR_TLXT_TLXFIRACT1_FIR_ACTION1_LEN = 30 ;
+
+static const uint8_t EXPLR_TLXT_TLXFIRMASK_FIR_MASK = 0 ;
+static const uint8_t EXPLR_TLXT_TLXFIRMASK_FIR_MASK_LEN = 30 ;
+
+static const uint8_t EXPLR_TLXT_TLXFIRQ_INFO_REG_PARITY_ERROR = 0 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_CTRL_REG_PARITY_ERROR = 1 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLX_VC0_MAX_CRD_ERROR = 2 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLX_VC1_MAX_CRD_ERROR = 3 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLX_DCP0_MAX_CRD_ERROR = 4 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLX_DCP3_MAX_CRD_ERROR = 5 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_CREDIT_MGMT_ERROR = 6 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_CREDIT_MGMT_PERROR = 7 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXT_PARITY_ERROR = 8 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXT_RECOVERABLE_ERROR = 9 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXT_CONFIG_ERROR = 10 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXT_INFORMATIONAL_PERROR = 11 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXT_HARD_ERROR = 12 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_RESERVED_10 = 13 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_RESERVED_10_LEN = 3 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_SHUTDOWN = 16 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_BAR0_OR_MMIO_NF = 17 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_OC_MALFORMED = 18 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_OC_PROTOCOL_ERROR = 19 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_ADDR_XLAT = 20 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_METADATA_UNC_DPERR = 21 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_OC_UNSUPPORTED = 22 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_OC_FATAL = 23 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_CONTROL_ERROR = 24 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_INTERNAL_ERROR = 25 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_INFORMATIONAL = 26 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_TLXR_TRACE_STOP = 27 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_INTERNAL_SCOM_ERROR = 28 ;
+static const uint8_t EXPLR_TLXT_TLXFIRQ_INTERNAL_SCOM_ERROR_CLONE = 29 ;
+
+static const uint8_t EXPLR_TLXT_TLXFIRWOF_FIR_WOF = 0 ;
+static const uint8_t EXPLR_TLXT_TLXFIRWOF_FIR_WOF_LEN = 30 ;
+
+static const uint8_t EXPLR_TLXT_TLXTINTHLD0_TLXT_INTHLD_0_REG = 0 ;
+static const uint8_t EXPLR_TLXT_TLXTINTHLD0_TLXT_INTHLD_0_REG_LEN = 64 ;
+
+static const uint8_t EXPLR_TLXT_TLXTINTHLD1_TLXT_INTHLD_1_REG = 0 ;
+static const uint8_t EXPLR_TLXT_TLXTINTHLD1_TLXT_INTHLD_1_REG_LEN = 64 ;
+
+static const uint8_t EXPLR_TLXT_TLXTINTHLD2_TLXT_INTHLD_2_REG = 0 ;
+static const uint8_t EXPLR_TLXT_TLXTINTHLD2_TLXT_INTHLD_2_REG_LEN = 64 ;
+
+static const uint8_t EXPLR_TLXT_TLXTINTHLD3_TLXT_INTHLD_3_REG = 0 ;
+static const uint8_t EXPLR_TLXT_TLXTINTHLD3_TLXT_INTHLD_3_REG_LEN = 64 ;
+
+static const uint8_t EXPLR_TLXT_TLXTRAP0_DEBUG_BUS = 0 ;
+static const uint8_t EXPLR_TLXT_TLXTRAP0_DEBUG_BUS_LEN = 64 ;
+
+static const uint8_t EXPLR_TLXT_TLXTRAP1_DEBUG_BUS = 0 ;
+static const uint8_t EXPLR_TLXT_TLXTRAP1_DEBUG_BUS_LEN = 64 ;
+
+static const uint8_t EXPLR_TLXT_TLXTTRAP2_DEBUG_BUS = 0 ;
+static const uint8_t EXPLR_TLXT_TLXTTRAP2_DEBUG_BUS_LEN = 64 ;
+
+static const uint8_t EXPLR_TLXT_TLXTTRAP3_DEBUG_BUS = 0 ;
+static const uint8_t EXPLR_TLXT_TLXTTRAP3_DEBUG_BUS_LEN = 64 ;
+
+static const uint8_t EXPLR_TLXT_TLXTTRAP4_DEBUG_BUS = 0 ;
+static const uint8_t EXPLR_TLXT_TLXTTRAP4_DEBUG_BUS_LEN = 64 ;
+
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_TLXR_UNUSED = 0 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_TLXR_UNUSED_LEN = 5 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SPARE_7 = 5 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_TLXR_SHUTDOWN = 6 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_MMIO_BAD_WR_RESP_NF = 7 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAR0_PERR_NF = 8 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAD_TEMPLATE_OPCODE_COMBO = 9 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SPARE_6 = 10 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAD_CREDIT_RETURN_SLOT = 11 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAD_TEMPLATE_0_FORMAT = 12 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_RESERVED_FIELD_VALUE = 13 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_DATA_SEQ_ERR = 14 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_RD_BDY_ERR = 15 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_WR_BDY_ERR = 16 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SPARE_5 = 17 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAD_INTRP_RESP_TAG = 18 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAD_MEMCTL = 19 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SPARE_4 = 20 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SPARE_3 = 21 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SPARE_2 = 22 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_ADDRESS_DROPPED = 23 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_ADDR_XLAT_ERROR_RD = 24 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_ADDR_XLAT_ERROR_WR = 25 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_PATTERN_CORRUPT = 26 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_DATAFLOW_PERR_NF = 27 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_METADATA_UNC = 28 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_PR_RD_DDR = 29 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_RD_MEM = 30 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_WRITE = 31 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_PR_LENGTH = 32 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_PAD_MEM = 33 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_PAD_MEM_LEN_ERR = 34 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_WRITE_LENGTH = 35 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_READ_LENGTH = 36 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_OPCODE = 37 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_TEMPLATE = 38 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_UNSUPPORTED_DATA_CARRIER = 39 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BUFF_CNTL_PERR = 40 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_D_LIST_UNC = 41 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_TAGSTORE_UNC = 42 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_B_MGMT_3 = 43 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SPARE_1 = 44 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_FLIT_PERR = 45 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_MMIO_WD_PERR = 46 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_MMIO_WD_INV = 47 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SRQ_WD_PERR = 48 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_SRQ_WD_INV = 49 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_D_LIST_UNDERFLOW = 50 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_DATAFLOW_PERR_F = 51 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_D_LIST_OVERFLOW = 52 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_MMIO_BAD_WR_RESP_F = 53 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAR0_PERR_F = 54 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_B_MGMT_1 = 55 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_B_MGMT_2 = 56 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_ADDR_XLATE_HOLE = 57 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_BAD_DATA_RXD = 58 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_METADATA_CORR = 59 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_TAG_BUFFER_CORR = 60 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_D_LIST_CORR = 61 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_EPOW_SIGNALLED = 62 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_TRACE_STOP = 63 ;
+
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_MASK_ERRMASK = 0 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR0_REPORTQ_MASK_ERRMASK_LEN = 64 ;
+
+static const uint8_t EXPLR_TLXT_TLX_ERR1_REPORTQ_TLXT_PERRORS = 0 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR1_REPORTQ_TLXT_PERRORS_LEN = 37 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR1_REPORTQ_TLXT_ERRORS = 37 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR1_REPORTQ_TLXT_ERRORS_LEN = 27 ;
+
+static const uint8_t EXPLR_TLXT_TLX_ERR1_REPORTQ_MASK_ERRMASK = 0 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR1_REPORTQ_MASK_ERRMASK_LEN = 64 ;
+
+static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_TLXC_PERRORS = 0 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_TLXC_PERRORS_LEN = 8 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_TLXC_ERRORS = 8 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_TLXC_ERRORS_LEN = 6 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_INTHLD_PERROR = 14 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_INTHLD_PERROR_LEN = 4 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_DATA_TAKEN_BUT_NOT_VALID = 18 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_INTRP_REQ_SM_PERRORS = 19 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_INTRP_REQ_SM_PERRORS_LEN = 4 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_TL_2SL_4SL_PKT_FULL_PERR = 23 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_TLXC_SPARE = 24 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_TLXC_SPARE_LEN = 8 ;
+
+static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_MASK_ERRMASK = 0 ;
+static const uint8_t EXPLR_TLXT_TLX_ERR2_REPORTQ_MASK_ERRMASK_LEN = 32 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ADDR_TRAP_REG_PCB_ADDRESS_OF_LAST_TRANSACTION_WITH_ERROR = 0 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ADDR_TRAP_REG_PCB_ADDRESS_OF_LAST_TRANSACTION_WITH_ERROR_LEN = 16 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ADDR_TRAP_REG_PCB_READ_NOTWRITE_OF_LAST_TRANSACTION_WITH_ERROR = 16 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_ADDR_TRAP_REG_RESERVED_LAST_LT = 17 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_ADDR_TRAP_REG_RESERVED_LAST_LT = 17 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ADDR_TRAP_REG_SERIAL2PARALLEL_STATE_MACHINE_AT_TIME_OF_ERROR = 18 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ADDR_TRAP_REG_SERIAL2PARALLEL_STATE_MACHINE_AT_TIME_OF_ERROR_LEN = 13 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ADDR_TRAP_REG_SATELLITE_ACKNOWLEDGE_BIT_RETURN_PARITY = 31 ;
@@ -6124,38 +6286,38 @@ static const uint8_t EXPLR_TP_MB_UNIT_TOP_ADDR_TRAP_REG_SATELLITE_ACKNOWLEDGE_BI
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ADDR_TRAP_REG_SATELLITE_ACKNOWLEDGE_BIT_ACCESS_VIOLATION = 33 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ADDR_TRAP_REG_SATELLITE_ACKNOWLEDGE_BIT_INVALID_REGISTER = 34 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_ATOMIC_LOCK_MASK_LATCH_REG_MASK = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_ATOMIC_LOCK_MASK_LATCH_REG_MASK_LEN = 32 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_ATOMIC_LOCK_MASK_LATCH_REG_MASK = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_ATOMIC_LOCK_MASK_LATCH_REG_MASK_LEN = 32 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_COND1_SEL_A = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_COND1_SEL_A = 0 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_COND1_SEL_A_LEN = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_COND1_SEL_B = 8 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_COND1_SEL_B = 8 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_COND1_SEL_B_LEN = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_COND2_SEL_A = 16 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_COND2_SEL_A = 16 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_COND2_SEL_A_LEN = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_COND2_SEL_B = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_COND2_SEL_B = 24 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_COND2_SEL_B_LEN = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_C1_INAROW_MODE = 32 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_C1_INAROW_MODE = 32 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_AND_TRIGGER_MODE1 = 33 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_NOT_TRIGGER_MODE1 = 34 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_EDGE_TRIGGER_MODE1 = 35 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_UNUSED = 36 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_UNUSED_LEN = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_C2_INAROW_MODE = 39 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_UNUSED = 36 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_UNUSED_LEN = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_C2_INAROW_MODE = 39 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_AND_TRIGGER_MODE2 = 40 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_NOT_TRIGGER_MODE2 = 41 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_EDGE_TRIGGER_MODE2 = 42 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_UNUSED_2 = 43 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_UNUSED_2_LEN = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_UNUSED_2 = 43 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_UNUSED_2_LEN = 3 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_COND3_ENABLE_RESET = 46 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_EXACT_TO_MODE = 47 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_EXACT_TO_MODE = 47 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_RESET_C2TIMER_ON_C1 = 48 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_RESET_C3_ON_C0 = 49 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_SLOW_TO_MODE = 50 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_RESET_C3_ON_C0 = 49 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_SLOW_TO_MODE = 50 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_EXACT_RESET_C3_ON_TO = 51 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_C1_COUNT_LT = 52 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_C1_COUNT_LT = 52 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_C1_COUNT_LT_LEN = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_C2_COUNT_LT = 56 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_C2_COUNT_LT = 56 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_C2_COUNT_LT_LEN = 4 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_RESET_C3_SELECT = 60 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_1_RESET_C3_SELECT_LEN = 3 ;
@@ -6168,38 +6330,38 @@ static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_2_CROSS_COUPLE_SELE
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_2_CROSS_COUPLE_SELECT_A_LEN = 5 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_2_CROSS_COUPLE_SELECT_B = 15 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_2_CROSS_COUPLE_SELECT_B_LEN = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_2_TO_CMP_LT = 20 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_2_TO_CMP_LT_LEN = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_2_TO_CMP_LT = 20 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST1_COND_REG_2_TO_CMP_LT_LEN = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_COND1_SEL_A = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_COND1_SEL_A = 0 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_COND1_SEL_A_LEN = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_COND1_SEL_B = 8 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_COND1_SEL_B = 8 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_COND1_SEL_B_LEN = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_COND2_SEL_A = 16 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_COND2_SEL_A = 16 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_COND2_SEL_A_LEN = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_COND2_SEL_B = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_COND2_SEL_B = 24 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_COND2_SEL_B_LEN = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_C1_INAROW_MODE = 32 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_C1_INAROW_MODE = 32 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_AND_TRIGGER_MODE1 = 33 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_NOT_TRIGGER_MODE1 = 34 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_EDGE_TRIGGER_MODE1 = 35 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_UNUSED = 36 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_UNUSED_LEN = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_C2_INAROW_MODE = 39 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_UNUSED = 36 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_UNUSED_LEN = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_C2_INAROW_MODE = 39 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_AND_TRIGGER_MODE2 = 40 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_NOT_TRIGGER_MODE2 = 41 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_EDGE_TRIGGER_MODE2 = 42 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_UNUSED_2 = 43 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_UNUSED_2_LEN = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_UNUSED_2 = 43 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_UNUSED_2_LEN = 3 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_COND3_ENABLE_RESET = 46 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_EXACT_TO_MODE = 47 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_EXACT_TO_MODE = 47 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_RESET_C2TIMER_ON_C1 = 48 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_RESET_C3_ON_C0 = 49 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_SLOW_TO_MODE = 50 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_RESET_C3_ON_C0 = 49 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_SLOW_TO_MODE = 50 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_EXACT_RESET_C3_ON_TO = 51 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_C1_COUNT_LT = 52 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_C1_COUNT_LT = 52 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_C1_COUNT_LT_LEN = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_C2_COUNT_LT = 56 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_C2_COUNT_LT = 56 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_C2_COUNT_LT_LEN = 4 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_RESET_C3_SELECT = 60 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_1_RESET_C3_SELECT_LEN = 3 ;
@@ -6212,24 +6374,24 @@ static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_2_CROSS_COUPLE_SELE
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_2_CROSS_COUPLE_SELECT_A_LEN = 5 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_2_CROSS_COUPLE_SELECT_B = 15 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_2_CROSS_COUPLE_SELECT_B_LEN = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_2_TO_CMP_LT = 20 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_2_TO_CMP_LT_LEN = 24 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_GLB_BRCST = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_GLB_BRCST_LEN = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_TRACE_SEL = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_TRACE_SEL_LEN = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_TRIG_SEL = 6 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_TRIG_SEL_LEN = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_2_TO_CMP_LT = 20 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_INST2_COND_REG_2_TO_CMP_LT_LEN = 24 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_GLB_BRCST = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_GLB_BRCST_LEN = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_TRACE_SEL = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_TRACE_SEL_LEN = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_TRIG_SEL = 6 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_TRIG_SEL_LEN = 2 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_STOP_ON_XSTOP_SELECTION = 8 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_STOP_ON_RECOV_ERR_SELECTION = 9 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_STOP_ON_SPATTN_SELECTION = 10 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_FREEZE_SEL = 11 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_SYNC_BRCST = 12 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_SYNC_BRCST_LEN = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_TRACE_RUN_STATUS = 17 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_TRACE_RUN_STATUS_LEN = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_IS_FROZEN_STATUS = 19 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_FREEZE_SEL = 11 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_SYNC_BRCST = 12 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_SYNC_BRCST_LEN = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_TRACE_RUN_STATUS = 17 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_TRACE_RUN_STATUS_LEN = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_IS_FROZEN_STATUS = 19 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_INST1_CONDITION_HISTORY_STATUS = 20 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_INST1_CONDITION_HISTORY_STATUS_LEN = 3 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_INST2_CONDITION_HISTORY_STATUS = 23 ;
@@ -6241,17 +6403,17 @@ static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_MODE_REG_INST4_CONDITION_HISTORY_S
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_MODE_REG_2_RUNN_COUNT_COMPARE_VALUE = 0 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_MODE_REG_2_RUNN_COUNT_COMPARE_VALUE_LEN = 16 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_MODE_REG_2_IMM_FREEZE = 16 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_MODE_REG_2_STOP_ON_ERR = 17 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_MODE_REG_2_IMM_FREEZE = 16 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_MODE_REG_2_STOP_ON_ERR = 17 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_MODE_REG_2_BANK_ON_RUNN_MATCH = 18 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_MODE_REG_2_FORCE_TEST = 19 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_MODE_REG_2_ACCUM_HIST = 20 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_MODE_REG_2_FORCE_TEST = 19 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_MODE_REG_2_ACCUM_HIST = 20 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_MODE_REG_2_FRZ_COUNT_ON_FRZ = 21 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST1_COND3_ENABLE = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST2_COND3_ENABLE = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST3_COND3_ENABLE = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST4_COND3_ENABLE = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST1_COND3_ENABLE = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST2_COND3_ENABLE = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST3_COND3_ENABLE = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST4_COND3_ENABLE = 3 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST1_SLOW_LFSR_MODE = 4 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST2_SLOW_LFSR_MODE = 5 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST3_SLOW_LFSR_MODE = 6 ;
@@ -6268,20 +6430,20 @@ static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST2_CONDITION2_TRIG_
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST2_CONDITION2_TRIG_SEL_LEN = 2 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST2_C2_TIMEOUT_TRIG_SEL = 18 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_INST2_C2_TIMEOUT_TRIG_SEL_LEN = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_EXT_TRIG_ON_STOP = 32 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_EXT_TRIG_ON_FREEZE = 33 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_CORE_RAS0_TRIG_SEL = 34 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_EXT_TRIG_ON_STOP = 32 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_EXT_TRIG_ON_FREEZE = 33 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_CORE_RAS0_TRIG_SEL = 34 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_CORE_RAS0_TRIG_SEL_LEN = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_CORE_RAS1_TRIG_SEL = 39 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_CORE_RAS1_TRIG_SEL = 39 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_CORE_RAS1_TRIG_SEL_LEN = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_PC_TP_TRIG_SEL = 44 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_PC_TP_TRIG_SEL_LEN = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_ARM_SEL = 46 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_ARM_SEL_LEN = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_TRIG0_LEVEL_SEL = 50 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_TRIG0_LEVEL_SEL_LEN = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_TRIG1_LEVEL_SEL = 54 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_TRIG1_LEVEL_SEL_LEN = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_PC_TP_TRIG_SEL = 44 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_PC_TP_TRIG_SEL_LEN = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_ARM_SEL = 46 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_ARM_SEL_LEN = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_TRIG0_LEVEL_SEL = 50 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_TRIG0_LEVEL_SEL_LEN = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_TRIG1_LEVEL_SEL = 54 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_0_TRIG1_LEVEL_SEL_LEN = 4 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_1_INST1_CONDITION1_ACTION_DO = 0 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_1_INST1_CONDITION1_ACTION_DO_LEN = 2 ;
@@ -6315,23 +6477,23 @@ static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_1_INST2_CHECKSTOP_MODE_L
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DBG_TRACE_REG_1_INST2_CHECKSTOP_MODE_SELECTOR = 55 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DEBUG_TRACE_CONTROL_SCOM_TRACE_START = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_DEBUG_TRACE_CONTROL_SCOM_TRACE_STOP = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_DEBUG_TRACE_CONTROL_SCOM_TRACE_STOP = 1 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_DEBUG_TRACE_CONTROL_SCOM_TRACE_RESET = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_HOLD_LAT_FIR_MASK_PAR = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_HOLD_LAT_FIR_ACTION0_PAR = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_HOLD_LAT_FIR_ACTION1_PAR = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_HOLD_LAT_FIR_MASK_PAR = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_HOLD_LAT_FIR_ACTION0_PAR = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_HOLD_LAT_FIR_ACTION1_PAR = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_MASK_FIR_PAR = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_MASK_FIR_ACTION0_PAR = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_MASK_FIR_ACTION1_PAR = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_MASK_FIR_PAR = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_MASK_FIR_ACTION0_PAR = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_MASK_FIR_ACTION1_PAR = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_PCB_WDATA_PARITY_ERROR = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_PCB_WDATA_PARITY_ERROR = 0 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_PCB_ADDRESS_PARITY_ERROR = 1 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_DL_RETURN_WDATA_PARITY_ERROR = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_DL_RETURN_P0_ERROR = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_UL_RDATA_PARITY_ERROR = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_UL_P0_ERROR = 5 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_DL_RETURN_P0_ERROR = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_UL_RDATA_PARITY_ERROR = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_UL_P0_ERROR = 5 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_PARITY_ERROR_ON_INTERFACE_MACHINE = 6 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_PARITY_ERROR_ON_P2S_MACHINE = 7 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_TIMEOUT_WHILE_WAITING_FOR_ULCCH = 8 ;
@@ -6341,26 +6503,26 @@ static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_PSCOM_PARALLEL_WRITE_NVLD
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_PSCOM_PARALLEL_READ_NVLD = 12 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_PSCOM_PARALLEL_ADDR_INVALID = 13 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_PCB_COMMAND_PARITY_ERROR = 14 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_GENERAL_TIMEOUT = 15 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_GENERAL_TIMEOUT = 15 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_SATELLITE_ACKNOWLEDGE_ACCESS_VIOLATION = 16 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_ERR_RPT_MASK_SATELLITE_ACKNOWLEDGE_INVALID_REGISTER = 17 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN0 = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN1 = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN2 = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN3 = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN4 = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN5 = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN6 = 6 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN7 = 7 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN8 = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN9 = 9 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN10 = 10 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN11 = 11 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN12 = 12 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN14 = 13 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN14_LEN = 13 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN26 = 26 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN0 = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN1 = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN2 = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN3 = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN4 = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN5 = 5 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN6 = 6 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN7 = 7 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN8 = 8 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN9 = 9 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN10 = 10 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN11 = 11 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN12 = 12 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN14 = 13 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN14_LEN = 13 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_FIR_MASK_IN26 = 26 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ABORT_ON_ERROR_REG_MASK_READ_ADDR_P = 0 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ABORT_ON_ERROR_REG_MASK_WRITE_ADDR_P = 1 ;
@@ -6380,8 +6542,15 @@ static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_FIRST_PR_
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_FIRST_PR_WR_DATA_ERR = 11 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_SECOND_PR_WR_ADDRESS_ERR = 12 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_SECOND_PR_WR_DATA_ERR = 13 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_RESERVED = 14 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_RESERVED_LEN = 18 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_ERR_ON_FSM = 14 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_ERR_ON_SM1_STATE = 15 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_ERR_ON_AXI2PCB = 16 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_ERR_ON_AXI2PCB_MASK = 17 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_ERR_ON_AXI2PCB_TIMER = 18 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_ERR_ON_AXI2PCB_ABORT_ON = 19 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_ERR_ON = 20 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_RESERVED = 21 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_RESERVED_LEN = 11 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_SLAVE_ADDR = 32 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_AXI_PARITY_ERROR_REG_SLAVE_ADDR_LEN = 32 ;
@@ -6390,10 +6559,10 @@ static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PARITY_RSP_DATA
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PARITY_RSP_DATA_1 = 2 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PARITY_RSP_DATA_2 = 3 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PARITY_RSP_DATA_3 = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_TIMEOUT = 5 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_TIMEOUT = 5 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_INT_ADDR_ACCESS = 6 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PIB2GIF = 7 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PCB_ERR_CODE = 8 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PIB2GIF = 7 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PCB_ERR_CODE = 8 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PCB_ERR_CODE_LEN = 3 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_AXI_READ_ADDR_PARITY = 11 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_AXI_WRITE_ADDR_PARITY = 12 ;
@@ -6402,158 +6571,216 @@ static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_AXI_WRITE_DATA_
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_AXI_WRITE_DATA_PARITY_15_8 = 15 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_AXI_WRITE_DATA_PARITY_7_0 = 16 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PIB2GIF_PARITY = 17 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PARITY_RSP_INFO = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PARITY_RSP_DATA_0 = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PARITY_RSP_DATA_1 = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PARITY_RSP_DATA_2 = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PARITY_RSP_DATA_3 = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_TIMEOUT = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_INT_ADDR_ACCESS = 6 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_INVALID_ACCESS = 7 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PCB_ERR_CODE = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PCB_ERR_CODE_LEN = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PARITY_ON_STATE_MACHINE = 18 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PARITY_ON_SM1 = 19 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PARITY_ON = 21 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PARITY_ON_TIMER = 22 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PARITY_ON_ABORT_ON = 23 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_MASK_REG_PARITY_ON_PARITY = 24 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PARITY_RSP_INFO = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PARITY_RSP_DATA_0 = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PARITY_RSP_DATA_1 = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PARITY_RSP_DATA_2 = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PARITY_RSP_DATA_3 = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_TIMEOUT = 5 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_INT_ADDR_ACCESS = 6 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_INVALID_ACCESS = 7 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PCB_ERR_CODE = 8 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PCB_ERR_CODE_LEN = 3 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_AXI_READ_ADDR_PARITY = 11 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_AXI_WRITE_ADDR_PARITY = 12 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_AXI_WRITE_DATA_PARITY_31_24 = 13 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_AXI_WRITE_DATA_PARITY_23_16 = 14 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_AXI_WRITE_DATA_PARITY_15_8 = 15 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_AXI_WRITE_DATA_PARITY_7_0 = 16 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PIB2GIF_PARITY = 17 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG_PIB2GIF_PARITY = 17 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_RESET_REG_RESET_STATEMACHINE = 63 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_TIMER_REG_COUNT = 48 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_TIMER_REG_COUNT_LEN = 16 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_HOLD_OUT_REG_SPARE_LATCH_UNUSED = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_HOLD_OUT_REG_OUT = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_HOLD_OUT_REG_OUT_LEN = 18 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN0 = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN1 = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN2 = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN3 = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN4 = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN5 = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN6 = 6 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN7 = 7 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN8 = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN9 = 9 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN10 = 10 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN10_LEN = 53 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_ACTION0_IN = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_ACTION0_IN_LEN = 63 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_ACTION1_IN = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_ACTION1_IN_LEN = 63 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_MASK_LFIR_IN = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_MASK_LFIR_IN_LEN = 63 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN0 = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN1 = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN2 = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN3 = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN4 = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN5 = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN6 = 6 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN7 = 7 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN8 = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN9 = 9 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN10 = 10 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN11 = 11 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN12 = 12 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN13 = 13 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN14 = 14 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN15 = 15 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN16 = 16 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN17 = 17 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN18 = 18 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN19 = 19 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN20 = 20 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN21 = 21 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN22 = 22 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_MASK_IN = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_MASK_IN_LEN = 22 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN0 = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN1 = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN2 = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN3 = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN4 = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN5 = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN6 = 6 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN7 = 7 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN8 = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN9 = 9 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN10 = 10 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN11 = 11 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN = 12 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN_LEN = 4 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_0 = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_1 = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_2 = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_3 = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_4 = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_5 = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_6 = 6 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_7 = 7 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_8 = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_9 = 9 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_PCS_GPBC_IRQ_106 = 10 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_MOORTEC_PVT = 11 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_PCS_GPBC_IRQ_111 = 12 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_PCS_GPBC_IRQ_112 = 13 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_TOP_DIGITAL_IO__FAIL_N = 14 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_PROC_SS__TOP_FATAL = 15 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_PROC_SS__TOP_NON_FATAL = 16 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_7 = 17 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_6 = 18 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_5 = 19 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_4 = 20 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_3 = 21 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_2 = 22 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_1 = 23 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_0 = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_TOP_DIGITAL_IO__DDR_EVENTB = 25 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_DDR4_PHY__FATAL = 26 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_DDR4_PHY__NON_FATAL = 27 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_DDR4_PHY__DDR_PHY_IRQ0 = 28 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_7__FATAL = 29 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_6__FATAL = 30 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_5__FATAL = 31 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_4__FATAL = 32 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_3__FATAL = 33 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_2__FATAL = 34 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_1__FATAL = 35 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_0__FATAL = 36 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_7__NON_FATAL = 37 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_6__NON_FATAL = 38 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_5__NON_FATAL = 39 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_4__NON_FATAL = 40 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_3__NON_FATAL = 41 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_2__NON_FATAL = 42 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_1__NON_FATAL = 43 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_0__NON_FATAL = 44 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_7__SERDES_INT = 45 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_6__SERDES_INT = 46 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_5__SERDES_INT = 47 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_4__SERDES_INT = 48 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_3__SERDES_INT = 49 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_2__SERDES_INT = 50 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_1__SERDES_INT = 51 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_0__SERDES_INT = 52 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_TIMER_REG_COUNT = 48 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_GIF2PCB_TIMER_REG_COUNT_LEN = 16 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_HOLD_OUT_REG_SPARE_LATCH_UNUSED = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_HOLD_OUT_REG_OUT = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_HOLD_OUT_REG_OUT_LEN = 18 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN0 = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN1 = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN2 = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN3 = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN4 = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN5 = 5 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN6 = 6 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN7 = 7 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN8 = 8 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN9 = 9 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_UNUSED_0 = 10 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_UNUSED_1 = 11 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_UNUSED_2 = 12 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_UNUSED_3 = 13 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_UNUSED_4 = 14 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_UNUSED_5 = 15 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_UNUSED_6 = 16 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_UNUSED_7 = 17 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_UNUSED_8 = 18 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_DLL_IRQ = 19 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_PCS_GPBC_IRQ_106 = 20 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_MOORTEC_PVT = 21 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_PCS_GPBC_IRQ_111 = 22 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_PCS_GPBC_IRQ_112 = 23 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_TOP_DIGITAL_IO__FAIL_N = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_PROC_SS__TOP_FATAL = 25 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_PROC_SS__TOP_NON_FATAL = 26 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_OCMB_DOORBELL_INT_7 = 27 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_OCMB_DOORBELL_INT_6 = 28 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_OCMB_DOORBELL_INT_5 = 29 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_OCMB_DOORBELL_INT_4 = 30 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_OCMB_DOORBELL_INT_3 = 31 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_OCMB_DOORBELL_INT_2 = 32 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_OCMB_DOORBELL_INT_1 = 33 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_OCMB_DOORBELL_INT_0 = 34 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_TOP_DIGITAL_IO__DDR_EVENTB = 35 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_DDR4_PHY__FATAL = 36 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_DDR4_PHY__NON_FATAL = 37 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_DDR4_PHY__DDR_PHY_IRQ0 = 38 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_7__FATAL = 39 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_6__FATAL = 40 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_5__FATAL = 41 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_4__FATAL = 42 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_3__FATAL = 43 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_2__FATAL = 44 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_1__FATAL = 45 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_0__FATAL = 46 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_7__NON_FATAL = 47 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_6__NON_FATAL = 48 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_5__NON_FATAL = 49 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_4__NON_FATAL = 50 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_3__NON_FATAL = 51 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_2__NON_FATAL = 52 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_1__NON_FATAL = 53 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_0__NON_FATAL = 54 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_7__SERDES_INT = 55 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_6__SERDES_INT = 56 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_5__SERDES_INT = 57 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_4__SERDES_INT = 58 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_3__SERDES_INT = 59 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_2__SERDES_INT = 60 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_1__SERDES_INT = 61 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_FOXHOUND_LANE_0__SERDES_INT = 62 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_IN63 = 63 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_ACTION0_IN = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_ACTION0_IN_LEN = 64 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_ACTION1_IN = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_ACTION1_IN_LEN = 64 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_MASK_LFIR_IN = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_MASK_LFIR_IN_LEN = 64 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN0 = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN1 = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN2 = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN3 = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN4 = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN5 = 5 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN6 = 6 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN7 = 7 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN8 = 8 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN9 = 9 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN10 = 10 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN11 = 11 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN12 = 12 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN13 = 13 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN14 = 14 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN15 = 15 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN16 = 16 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN17 = 17 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN18 = 18 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN19 = 19 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN20 = 20 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN21 = 21 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_ERR_IN22 = 22 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_MASK_IN = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_LOCAL_XSTOP_MASK_IN_LEN = 22 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN0 = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN1 = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN2 = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN3 = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN4 = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN5 = 5 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN6 = 6 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN7 = 7 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN8 = 8 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN9 = 9 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN10 = 10 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN11 = 11 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN = 12 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MODE_REG_IN_LEN = 4 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_0 = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_1 = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_2 = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_3 = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_4 = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_5 = 5 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_6 = 6 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_7 = 7 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_UNUSED_8 = 8 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_DLL_IRQ = 9 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_PCS_GPBC_IRQ_106 = 10 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_MOORTEC_PVT = 11 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_PCS_GPBC_IRQ_111 = 12 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_PCS_GPBC_IRQ_112 = 13 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_TOP_DIGITAL_IO__FAIL_N = 14 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_PROC_SS__TOP_FATAL = 15 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_PROC_SS__TOP_NON_FATAL = 16 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_7 = 17 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_6 = 18 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_5 = 19 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_4 = 20 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_3 = 21 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_2 = 22 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_1 = 23 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_OCMB_DOORBELL_INT_0 = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_TOP_DIGITAL_IO__DDR_EVENTB = 25 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_DDR4_PHY__FATAL = 26 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_DDR4_PHY__NON_FATAL = 27 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_DDR4_PHY__DDR_PHY_IRQ0 = 28 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_7__FATAL = 29 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_6__FATAL = 30 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_5__FATAL = 31 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_4__FATAL = 32 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_3__FATAL = 33 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_2__FATAL = 34 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_1__FATAL = 35 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_0__FATAL = 36 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_7__NON_FATAL = 37 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_6__NON_FATAL = 38 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_5__NON_FATAL = 39 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_4__NON_FATAL = 40 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_3__NON_FATAL = 41 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_2__NON_FATAL = 42 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_1__NON_FATAL = 43 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_0__NON_FATAL = 44 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_7__SERDES_INT = 45 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_6__SERDES_INT = 46 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_5__SERDES_INT = 47 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_4__SERDES_INT = 48 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_3__SERDES_INT = 49 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_2__SERDES_INT = 50 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_1__SERDES_INT = 51 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_MSG_REG_FOXHOUND_LANE_0__SERDES_INT = 52 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ABORT_ON_ERROR_REG_MASK_READ_ADDR_P = 61 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ABORT_ON_ERROR_REG_MASK_WRITE_ADDR_P = 62 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ABORT_ON_ERROR_REG_MASK_WRITE_DATA_P = 63 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK2_REG_ERROR_MASK2_REG = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK2_REG_ERROR_MASK2_REG_LEN = 64 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK2_REG_MASK_TP_MSG = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK2_REG_MASK_TP_MSG_LEN = 64 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_PARITY_REQ_DATA_0 = 0 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_PARITY_REQ_DATA_1 = 1 ;
@@ -6562,65 +6789,83 @@ static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_PARITY_REQ_DATA
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_PARITY_REQ_ADDR_0 = 4 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_PARITY_REQ_ADDR_1 = 5 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_PARITY_REQ_CTRL = 6 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_TIMEOUT = 7 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_TIMEOUT = 7 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_INT_ADDR_ACCESS = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_GIF2PCB = 32 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_GIF2PCB_LEN = 7 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_REQ_DATA_0 = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_REQ_DATA_1 = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_REQ_DATA_2 = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_REQ_DATA_3 = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_REQ_ADDR_0 = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_REQ_ADDR_1 = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_REQ_CTRL = 6 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_TIMEOUT = 7 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_INT_ADDR_ACCESS = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_ERROR_REG_UNUSED1 = 9 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_ERROR_REG_UNUSED1_LEN = 23 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_GIF2PCB = 32 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_GIF2PCB_LEN = 14 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_GIF2PCB_ERROR_REG = 46 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_GIF2PCB_ERROR_REG_LEN = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_ERROR_REG_UNUSED2 = 50 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_PARITY_ON_FSM = 9 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_PARITY_ON_REG0 = 10 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_PARITY_ON_REG1 = 11 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_PARITY_ON_REG2 = 12 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_PARITY_ON_REG3 = 13 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_PARITY_ON_REG4 = 14 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_PARITY_ON_REG5 = 15 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_INVALID_ADDRESS = 16 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_MASK_ERROR_REG_UNUSED1 = 17 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_MASK_ERROR_REG_UNUSED1_LEN = 15 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_GIF2PCB = 32 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_GIF2PCB_LEN = 18 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_MASK_ERROR_REG_UNUSED2 = 50 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_MASK_REG_MASK_ERROR_REG_UNUSED2_LEN = 14 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_REQ_DATA_0 = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_REQ_DATA_1 = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_REQ_DATA_2 = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_REQ_DATA_3 = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_REQ_ADDR_0 = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_REQ_ADDR_1 = 5 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_REQ_CTRL = 6 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_TIMEOUT = 7 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_INT_ADDR_ACCESS = 8 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_ON_FSM = 9 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_ON_REG0 = 10 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_ON_REG1 = 11 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_ON_REG2 = 12 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_ON_REG3 = 13 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_ON_REG4 = 14 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_PARITY_ON_REG5 = 15 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_INVALID_ADDRESS = 16 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_ERROR_REG_UNUSED1 = 17 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_ERROR_REG_UNUSED1_LEN = 15 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_GIF2PCB = 32 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_GIF2PCB_LEN = 18 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_ERROR_REG_UNUSED2 = 50 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG_ERROR_REG_UNUSED2_LEN = 14 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG2_TP_MSG_REG = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG2_TP_MSG_REG_LEN = 64 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG2_TP_MSG_REG = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG2_TP_MSG_REG_LEN = 64 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_TIMER_REG_COUNT = 48 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_TIMER_REG_COUNT_LEN = 16 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_TIMER_REG_COUNT = 48 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PIB2GIF_TIMER_REG_COUNT_LEN = 16 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_PCB_WDATA_PARITY = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_PCB_ADDRESS_PARITY = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_PCB_WDATA_PARITY = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_PCB_ADDRESS_PARITY = 1 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_DL_RETURN_WDATA_PARITY = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_DL_RETURN_P0 = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_UL_RDATA_PARITY = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_UL_P0 = 5 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_DL_RETURN_P0 = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_UL_RDATA_PARITY = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_UL_P0 = 5 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_PARITY_ON_INTERFACE_MACHINE = 6 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_PARITY_ON_P2S_MACHINE = 7 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_TIMEOUT_WHILE_WAITING_FOR_ULCCH = 8 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_TIMEOUT_WHILE_WAITING_FOR_DLDCH_RETURN = 9 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_TIMEOUT_WHILE_WAITING_FOR_ULDCH = 10 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_PARALLEL_WRITE_NVLD = 11 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_PARALLEL_READ_NVLD = 12 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_PARALLEL_READ_NVLD = 12 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_PARALLEL_ADDR_INVALID = 13 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_PCB_COMMAND_PARITY = 14 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_GENERAL_TIMEOUT = 15 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_PCB_COMMAND_PARITY = 14 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_GENERAL_TIMEOUT = 15 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_SATELLITE_ACKNOWLEDGE_ACCESS_VIOLATION = 16 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_ERROR_MASK_SATELLITE_ACKNOWLEDGE_INVALID_REGISTER = 17 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_ABORT_ON_PCB_ADDR_PARITY_ERROR = 0 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_ABORT_ON_PCB_WDATA_PARITY_ERROR = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_UNUSED_BIT_2 = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_UNUSED_BIT_2 = 2 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_ABORT_ON_DL_RETURN_WDATA_PARITY_ERROR = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_WATCHDOG_ENABLE = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_SCOM_HANG_LIMIT = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_SCOM_HANG_LIMIT_LEN = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_FORCE_ALL_RINGS = 7 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_WATCHDOG_ENABLE = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_SCOM_HANG_LIMIT = 5 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_SCOM_HANG_LIMIT_LEN = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_FORCE_ALL_RINGS = 7 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_FSM_SELFRESET_ON_STATEVEC_PARITYERROR_ENABLE = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_RESERVED_LT = 9 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_RESERVED_LT_LEN = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_RESERVED_LT = 9 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_MODE_REG_RESERVED_LT_LEN = 3 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_STATUS_ERROR_REG_ACCUMULATED_PCB_WDATA_PARITY = 0 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_STATUS_ERROR_REG_ACCUMULATED_PCB_ADDRESS_PARITY = 1 ;
@@ -6662,74 +6907,74 @@ static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_STATUS_ERROR_REG_TRAPPED_GENERAL
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_STATUS_ERROR_REG_TRAPPED_SATELLITE_ACKNOWLEDGE_ACCESS_VIOLATION = 34 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_PSCOM_STATUS_ERROR_REG_TRAPPED_SATELLITE_ACKNOWLEDGE_INVALID_REGISTER = 35 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN0 = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_LFIR_RECOV_ERR = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN4 = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN5 = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN6 = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN7 = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN8 = 6 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN9 = 7 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN10 = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN11 = 9 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN12 = 10 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN13 = 11 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN14 = 12 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN14_LEN = 12 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_RING_FENCE_MASK_LATCH_REG_ENABLE = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN0 = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_LFIR_RECOV_ERR = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN4 = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN5 = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN6 = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN7 = 5 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN8 = 6 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN9 = 7 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN10 = 8 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN11 = 9 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN12 = 10 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN13 = 11 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN14 = 12 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RFIR_IN14_LEN = 12 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_RING_FENCE_MASK_LATCH_REG_ENABLE = 1 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_RING_FENCE_MASK_LATCH_REG_ENABLE_LEN = 31 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN0 = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN1 = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN2 = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN3 = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN4 = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN5 = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN6 = 6 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN7 = 7 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN8 = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN9 = 9 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPA_MASK_IN = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPA_MASK_IN_LEN = 10 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_SUM_MASK_REG_SMASK_IN = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_SUM_MASK_REG_SMASK_IN_LEN = 5 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_HI_DATA_REG_DATA = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_HI_DATA_REG_DATA_LEN = 64 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_DATA = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_DATA_LEN = 32 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_ADDRESS = 32 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_ADDRESS_LEN = 10 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_LAST_BANK = 42 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_LAST_BANK_LEN = 9 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_LAST_BANK_VALID = 51 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_WRITE_ON_RUN = 52 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_RUNNING = 53 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_HOLD_ADDRESS = 54 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_HOLD_ADDRESS_LEN = 10 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN0 = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN1 = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN2 = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN3 = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN4 = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN5 = 5 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN6 = 6 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN7 = 7 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN8 = 8 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPATTN_IN9 = 9 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPA_MASK_IN = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_SPA_MASK_IN_LEN = 10 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_SUM_MASK_REG_SMASK_IN = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_SUM_MASK_REG_SMASK_IN_LEN = 5 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_HI_DATA_REG_DATA = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_HI_DATA_REG_DATA_LEN = 64 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_DATA = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_DATA_LEN = 32 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_ADDRESS = 32 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_ADDRESS_LEN = 10 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_LAST_BANK = 42 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_LAST_BANK_LEN = 9 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_LAST_BANK_VALID = 51 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_WRITE_ON_RUN = 52 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_RUNNING = 53 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_HOLD_ADDRESS = 54 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_LO_DATA_REG_HOLD_ADDRESS_LEN = 10 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_STORE_ON_TRIG_MODE = 0 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_WRITE_ON_RUN_MODE = 1 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_EXTEND_TRIG_MODE = 2 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_EXTEND_TRIG_MODE_LEN = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_BANK_MODE = 10 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_ENH_MODE = 11 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_BANK_MODE = 10 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_ENH_MODE = 11 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_LOCAL_CLOCK_GATE_CONTROL = 12 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_LOCAL_CLOCK_GATE_CONTROL_LEN = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_SELECT_CONTROL = 14 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_SELECT_CONTROL = 14 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_SELECT_CONTROL_LEN = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_RUN_HOLD_OFF = 18 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_RUN_STATUS = 19 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_RUN_STICKY = 20 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_RUN_HOLD_OFF = 18 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_RUN_STATUS = 19 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_RUN_STICKY = 20 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_DISABLE_BANK_EDGE_DETECT = 21 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_TRA_MASTER_CLOCK_ENABLE = 22 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_DISABLE_RD_ACT = 23 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_TRA_MUX_SEL = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_CONTROL_UNUSED = 25 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_DISABLE_RD_ACT = 23 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_TRA_MUX_SEL = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_CONTROL_UNUSED = 25 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRCTRL_CONFIG_CONTROL_UNUSED_LEN = 3 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_0_CMP_MSK_LT_B_TO_63 = 0 ;
@@ -6738,41 +6983,41 @@ static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_0_CMP_MSK_LT_B_TO_
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_1_CMP_MSK_LT_B_64_TO_87 = 0 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_1_CMP_MSK_LT_B_64_TO_87_LEN = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_2_PATTERNA = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_2_PATTERNA_LEN = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_2_PATTERNB = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_2_PATTERNB_LEN = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_2_PATTERNA = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_2_PATTERNA_LEN = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_2_PATTERNB = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_2_PATTERNB_LEN = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_3_PATTERNC = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_3_PATTERNC_LEN = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_3_PATTERND = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_3_PATTERND_LEN = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_3_PATTERNC = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_3_PATTERNC_LEN = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_3_PATTERND = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_3_PATTERND_LEN = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_4_MASKA = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_4_MASKA_LEN = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_4_MASKB = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_4_MASKB_LEN = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_4_MASKA = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_4_MASKA_LEN = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_4_MASKB = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_4_MASKB_LEN = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_5_MASKC = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_5_MASKC_LEN = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_5_MASKD = 24 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_5_MASKD_LEN = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_5_MASKC = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_5_MASKC_LEN = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_5_MASKD = 24 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_5_MASKD_LEN = 24 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_DISABLE_COMPRESSION = 0 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_ERROR_BIT_COMPRESSION_CARE_MASK = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_MATCHA_MUXSEL = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_MATCHA_MUXSEL = 2 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_MATCHA_MUXSEL_LEN = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_MATCHB_MUXSEL = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_MATCHB_MUXSEL = 4 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_MATCHB_MUXSEL_LEN = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_MATCHC_MUXSEL = 6 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_MATCHC_MUXSEL = 6 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_MATCHC_MUXSEL_LEN = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_MATCHD_MUXSEL = 8 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_MATCHD_MUXSEL = 8 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_MATCHD_MUXSEL_LEN = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_TRIG0_OR_MASK = 10 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_TRIG0_OR_MASK = 10 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_TRIG0_OR_MASK_LEN = 4 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_TRIG0_AND_MASK = 14 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_TRIG0_AND_MASK_LEN = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_TRIG1_OR_MASK = 18 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_TRIG1_OR_MASK = 18 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_TRIG1_OR_MASK_LEN = 4 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_TRIG1_AND_MASK = 22 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_TRIG1_AND_MASK_LEN = 4 ;
@@ -6782,174 +7027,172 @@ static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_MATCH_NOT_MODE =
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_MATCH_NOT_MODE_LEN = 4 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_ERROR_CMP_MASK = 32 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_ERROR_CMP_PATTERN = 33 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_TRIG0_ERR_CMP = 34 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_TRIG1_ERR_CMP = 35 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_TRIG0_ERR_CMP = 34 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_TRIG1_ERR_CMP = 35 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_DD1_STRETCH_TRIGGER_PULSES = 36 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_UNIT_TC_TRA_FIR_ERR = 37 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_SPARE_LT = 38 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_SPARE_LT_LEN = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_SPARE_LT = 38 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_9_SPARE_LT_LEN = 2 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_WRITE_PROTECT_ENABLE_REG_RING_LOCKING = 0 ;
static const uint8_t EXPLR_TP_MB_UNIT_TOP_WRITE_PROTECT_ENABLE_REG_RESERVED_RING_LOCKING = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_WRITE_PROTECT_RINGS_REG_RINGS = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_WRITE_PROTECT_RINGS_REG_RINGS_LEN = 32 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN0 = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN1 = 1 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN2 = 2 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN3 = 3 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN4 = 4 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN5 = 5 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN6 = 6 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN7 = 7 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN8 = 8 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN9 = 9 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN10 = 10 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN11 = 11 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN12 = 12 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN13 = 13 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN14 = 14 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN14_LEN = 12 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN26 = 26 ;
-
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XTRA_TRACE_MODE_DATA = 0 ;
-static const uint8_t EXPLR_TP_MB_UNIT_TOP_XTRA_TRACE_MODE_DATA_LEN = 64 ;
-
-static const uint8_t EXPLR_WDF_AACR_BUFFER = 0 ;
-static const uint8_t EXPLR_WDF_AACR_ADDRESS = 1 ;
-static const uint8_t EXPLR_WDF_AACR_ADDRESS_LEN = 9 ;
-static const uint8_t EXPLR_WDF_AACR_AUTOINC = 10 ;
-static const uint8_t EXPLR_WDF_AACR_ECCGEN = 11 ;
-static const uint8_t EXPLR_WDF_AACR_PASSTHRU = 12 ;
-
-static const uint8_t EXPLR_WDF_AADR_DATA = 0 ;
-static const uint8_t EXPLR_WDF_AADR_DATA_LEN = 64 ;
-
-static const uint8_t EXPLR_WDF_AAER_META_ECC_SPARE = 0 ;
-static const uint8_t EXPLR_WDF_AAER_META_ECC_SPARE_LEN = 16 ;
-
-static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE0_SWIZZLE = 0 ;
-static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE0_SWIZZLE_LEN = 11 ;
-static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE1_SWIZZLE = 11 ;
-static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE1_SWIZZLE_LEN = 11 ;
-static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE2_SWIZZLE = 22 ;
-static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE2_SWIZZLE_LEN = 11 ;
-static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE3_SWIZZLE = 33 ;
-static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE3_SWIZZLE_LEN = 11 ;
-static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE4_SWIZZLE = 44 ;
-static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE4_SWIZZLE_LEN = 11 ;
-
-static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE5_SWIZZLE = 0 ;
-static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE5_SWIZZLE_LEN = 11 ;
-static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE6_SWIZZLE = 11 ;
-static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE6_SWIZZLE_LEN = 11 ;
-static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE7_SWIZZLE = 22 ;
-static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE7_SWIZZLE_LEN = 11 ;
-static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE8_SWIZZLE = 33 ;
-static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE8_SWIZZLE_LEN = 11 ;
-static const uint8_t EXPLR_WDF_DQS1R_CFG_ODD_RANK_SWIZZLE_EN = 44 ;
-static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE9_SWIZZLE = 45 ;
-static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE9_SWIZZLE_LEN = 11 ;
-
-static const uint8_t EXPLR_WDF_WECR_CFG_WDF_ECC_CHK_DISABLE = 0 ;
-static const uint8_t EXPLR_WDF_WECR_CFG_WDF_ECC_COR_DISABLE = 1 ;
-static const uint8_t EXPLR_WDF_WECR_CFG_CRC_MODE_EN = 2 ;
-static const uint8_t EXPLR_WDF_WECR_CFG_CRC_MODE_X8 = 3 ;
-static const uint8_t EXPLR_WDF_WECR_CFG_FORCE_DFI_CG_ALWAYS_ON = 4 ;
-static const uint8_t EXPLR_WDF_WECR_CFG_WDF_INTEGRITY_CHECK_DISABLE = 5 ;
-static const uint8_t EXPLR_WDF_WECR_CFG_WDF_CG_FORCE = 6 ;
-static const uint8_t EXPLR_WDF_WECR_CFG_WDF_SPARE7_11 = 7 ;
-static const uint8_t EXPLR_WDF_WECR_CFG_WDF_SPARE7_11_LEN = 5 ;
-static const uint8_t EXPLR_WDF_WECR_CFG_WDF_TRACE_SEL = 12 ;
-static const uint8_t EXPLR_WDF_WECR_CFG_WDF_TRACE_SEL_LEN = 4 ;
-static const uint8_t EXPLR_WDF_WECR_CFG_WDF_WAT_EN = 16 ;
-static const uint8_t EXPLR_WDF_WECR_CFG_WDF_WAT_EN_LEN = 4 ;
-
-static const uint8_t EXPLR_WDF_WERR_DQS0R_PE = 0 ;
-static const uint8_t EXPLR_WDF_WERR_DQS1R_PE = 1 ;
-static const uint8_t EXPLR_WDF_WERR_AACR_PE = 2 ;
-static const uint8_t EXPLR_WDF_WERR_AADR_PE = 3 ;
-static const uint8_t EXPLR_WDF_WERR_AAER_PE = 4 ;
-static const uint8_t EXPLR_WDF_WERR_WECR_PE = 5 ;
-static const uint8_t EXPLR_WDF_WERR_WSPAR_PE = 8 ;
-static const uint8_t EXPLR_WDF_WERR_WMSK_PE = 9 ;
-static const uint8_t EXPLR_WDF_WERR_RDF_BE_PE = 15 ;
-static const uint8_t EXPLR_WDF_WERR_TLXR_WR_PE = 16 ;
-static const uint8_t EXPLR_WDF_WERR_TLXR_BAD_PE = 17 ;
-static const uint8_t EXPLR_WDF_WERR_TLXR_BE_PE = 18 ;
-static const uint8_t EXPLR_WDF_WERR_SRQ_IF_PE = 19 ;
-static const uint8_t EXPLR_WDF_WERR_RDF_IF_PE = 20 ;
-static const uint8_t EXPLR_WDF_WERR_MMIO_IF_PE = 21 ;
-static const uint8_t EXPLR_WDF_WERR_CONTROL_PE = 22 ;
-static const uint8_t EXPLR_WDF_WERR_ECCGEN_ERR = 23 ;
-static const uint8_t EXPLR_WDF_WERR_WBUF_FUNC_UE = 24 ;
-static const uint8_t EXPLR_WDF_WERR_RMWBUF_FUNC_UE = 25 ;
-static const uint8_t EXPLR_WDF_WERR_BEBUF_FUNC_UE = 26 ;
-static const uint8_t EXPLR_WDF_WERR_BE_PE = 27 ;
-static const uint8_t EXPLR_WDF_WERR_INTEGRITY_ERR = 28 ;
-static const uint8_t EXPLR_WDF_WERR_WBUF_MMIO_UE = 29 ;
-static const uint8_t EXPLR_WDF_WERR_SCOM_FSM_PE = 32 ;
-static const uint8_t EXPLR_WDF_WERR_RMWBUF_SCOM_UE = 33 ;
-static const uint8_t EXPLR_WDF_WERR_BEBUF_SCOM_UE = 34 ;
-static const uint8_t EXPLR_WDF_WERR_WBUF_CE = 48 ;
-static const uint8_t EXPLR_WDF_WERR_RMWBUF_CE = 49 ;
-static const uint8_t EXPLR_WDF_WERR_BEBUF_CE = 50 ;
-
-static const uint8_t EXPLR_WDF_WESR_SYNDROME = 0 ;
-static const uint8_t EXPLR_WDF_WESR_SYNDROME_LEN = 8 ;
-static const uint8_t EXPLR_WDF_WESR_SEVERITY = 8 ;
-static const uint8_t EXPLR_WDF_WESR_PART = 9 ;
-static const uint8_t EXPLR_WDF_WESR_SOURCE = 10 ;
-static const uint8_t EXPLR_WDF_WESR_SOURCE_LEN = 3 ;
-
-static const uint8_t EXPLR_WDF_WMSK_DQS0R_PE = 0 ;
-static const uint8_t EXPLR_WDF_WMSK_DQS1R_PE = 1 ;
-static const uint8_t EXPLR_WDF_WMSK_AACR_PE = 2 ;
-static const uint8_t EXPLR_WDF_WMSK_AADR_PE = 3 ;
-static const uint8_t EXPLR_WDF_WMSK_AAER_PE = 4 ;
-static const uint8_t EXPLR_WDF_WMSK_WECR_PE = 5 ;
-static const uint8_t EXPLR_WDF_WMSK_WSPAR_PE = 8 ;
-static const uint8_t EXPLR_WDF_WMSK_WMSK_PE = 9 ;
-static const uint8_t EXPLR_WDF_WMSK_RDF_BE_PE = 15 ;
-static const uint8_t EXPLR_WDF_WMSK_TLXR_WR_PE = 16 ;
-static const uint8_t EXPLR_WDF_WMSK_TLXR_BAD_PE = 17 ;
-static const uint8_t EXPLR_WDF_WMSK_TLXR_BE_PE = 18 ;
-static const uint8_t EXPLR_WDF_WMSK_SRQ_IF_PE = 19 ;
-static const uint8_t EXPLR_WDF_WMSK_RDF_IF_PE = 20 ;
-static const uint8_t EXPLR_WDF_WMSK_MMIO_IF_PE = 21 ;
-static const uint8_t EXPLR_WDF_WMSK_CONTROL_PE = 22 ;
-static const uint8_t EXPLR_WDF_WMSK_ECCGEN_ERR = 23 ;
-static const uint8_t EXPLR_WDF_WMSK_WBUF_FUNC_UE = 24 ;
-static const uint8_t EXPLR_WDF_WMSK_RMWBUF_FUNC_UE = 25 ;
-static const uint8_t EXPLR_WDF_WMSK_BEBUF_FUNC_UE = 26 ;
-static const uint8_t EXPLR_WDF_WMSK_BE_PE = 27 ;
-static const uint8_t EXPLR_WDF_WMSK_INTEGRITY_ERR = 28 ;
-static const uint8_t EXPLR_WDF_WMSK_WBUF_MMIO_UE = 29 ;
-static const uint8_t EXPLR_WDF_WMSK_SCOM_FSM_PE = 32 ;
-static const uint8_t EXPLR_WDF_WMSK_RMWBUF_SCOM_UE = 33 ;
-static const uint8_t EXPLR_WDF_WMSK_BEBUF_SCOM_UE = 34 ;
-static const uint8_t EXPLR_WDF_WMSK_WBUF_CE = 48 ;
-static const uint8_t EXPLR_WDF_WMSK_RMWBUF_CE = 49 ;
-static const uint8_t EXPLR_WDF_WMSK_BEBUF_CE = 50 ;
-
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R0_LEFT = 0 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R0_LEFT_LEN = 5 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R0_RIGHT = 5 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R0_RIGHT_LEN = 5 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R1_LEFT = 10 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R1_LEFT_LEN = 5 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R1_RIGHT = 15 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R1_RIGHT_LEN = 5 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R2_LEFT = 20 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R2_LEFT_LEN = 5 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R2_RIGHT = 25 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R2_RIGHT_LEN = 5 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R3_LEFT = 30 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R3_LEFT_LEN = 5 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R3_RIGHT = 35 ;
-static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R3_RIGHT_LEN = 5 ;
-
-static const uint8_t EXPLR_EFUSE_IMAGE_OUT_0_ENTERPRISE_MODE_DIS = 10 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_WRITE_PROTECT_RINGS_REG_RINGS = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_WRITE_PROTECT_RINGS_REG_RINGS_LEN = 32 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN0 = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN1 = 1 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN2 = 2 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN3 = 3 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN4 = 4 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN5 = 5 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN6 = 6 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN7 = 7 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN8 = 8 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN9 = 9 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN10 = 10 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN11 = 11 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN12 = 12 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN13 = 13 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN14 = 14 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN14_LEN = 12 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XFIR_IN26 = 26 ;
+
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XTRA_TRACE_MODE_DATA = 0 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_XTRA_TRACE_MODE_DATA_LEN = 64 ;
+
+static const uint8_t EXPLR_WDF_AACR_BUFFER = 0 ;
+static const uint8_t EXPLR_WDF_AACR_ADDRESS = 1 ;
+static const uint8_t EXPLR_WDF_AACR_ADDRESS_LEN = 9 ;
+static const uint8_t EXPLR_WDF_AACR_AUTOINC = 10 ;
+static const uint8_t EXPLR_WDF_AACR_ECCGEN = 11 ;
+static const uint8_t EXPLR_WDF_AACR_PASSTHRU = 12 ;
+
+static const uint8_t EXPLR_WDF_AADR_DATA = 0 ;
+static const uint8_t EXPLR_WDF_AADR_DATA_LEN = 64 ;
+
+static const uint8_t EXPLR_WDF_AAER_META_ECC_SPARE = 0 ;
+static const uint8_t EXPLR_WDF_AAER_META_ECC_SPARE_LEN = 16 ;
+
+static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE0_SWIZZLE = 0 ;
+static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE0_SWIZZLE_LEN = 11 ;
+static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE1_SWIZZLE = 11 ;
+static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE1_SWIZZLE_LEN = 11 ;
+static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE2_SWIZZLE = 22 ;
+static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE2_SWIZZLE_LEN = 11 ;
+static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE3_SWIZZLE = 33 ;
+static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE3_SWIZZLE_LEN = 11 ;
+static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE4_SWIZZLE = 44 ;
+static const uint8_t EXPLR_WDF_DQS0R_CFG_BYTE4_SWIZZLE_LEN = 11 ;
+
+static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE5_SWIZZLE = 0 ;
+static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE5_SWIZZLE_LEN = 11 ;
+static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE6_SWIZZLE = 11 ;
+static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE6_SWIZZLE_LEN = 11 ;
+static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE7_SWIZZLE = 22 ;
+static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE7_SWIZZLE_LEN = 11 ;
+static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE8_SWIZZLE = 33 ;
+static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE8_SWIZZLE_LEN = 11 ;
+static const uint8_t EXPLR_WDF_DQS1R_CFG_ODD_RANK_SWIZZLE_EN = 44 ;
+static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE9_SWIZZLE = 45 ;
+static const uint8_t EXPLR_WDF_DQS1R_CFG_BYTE9_SWIZZLE_LEN = 11 ;
+
+static const uint8_t EXPLR_WDF_WECR_CFG_WDF_ECC_CHK_DISABLE = 0 ;
+static const uint8_t EXPLR_WDF_WECR_CFG_WDF_ECC_COR_DISABLE = 1 ;
+static const uint8_t EXPLR_WDF_WECR_CFG_CRC_MODE_EN = 2 ;
+static const uint8_t EXPLR_WDF_WECR_CFG_CRC_MODE_X8 = 3 ;
+static const uint8_t EXPLR_WDF_WECR_CFG_FORCE_DFI_CG_ALWAYS_ON = 4 ;
+static const uint8_t EXPLR_WDF_WECR_CFG_WDF_INTEGRITY_CHECK_DISABLE = 5 ;
+static const uint8_t EXPLR_WDF_WECR_CFG_WDF_CG_FORCE = 6 ;
+static const uint8_t EXPLR_WDF_WECR_CFG_WDF_SPARE7_11 = 7 ;
+static const uint8_t EXPLR_WDF_WECR_CFG_WDF_SPARE7_11_LEN = 5 ;
+static const uint8_t EXPLR_WDF_WECR_CFG_WDF_TRACE_SEL = 12 ;
+static const uint8_t EXPLR_WDF_WECR_CFG_WDF_TRACE_SEL_LEN = 4 ;
+static const uint8_t EXPLR_WDF_WECR_CFG_WDF_WAT_EN = 16 ;
+static const uint8_t EXPLR_WDF_WECR_CFG_WDF_WAT_EN_LEN = 4 ;
+
+static const uint8_t EXPLR_WDF_WERR_DQS0R_PE = 0 ;
+static const uint8_t EXPLR_WDF_WERR_DQS1R_PE = 1 ;
+static const uint8_t EXPLR_WDF_WERR_AACR_PE = 2 ;
+static const uint8_t EXPLR_WDF_WERR_AADR_PE = 3 ;
+static const uint8_t EXPLR_WDF_WERR_AAER_PE = 4 ;
+static const uint8_t EXPLR_WDF_WERR_WECR_PE = 5 ;
+static const uint8_t EXPLR_WDF_WERR_WSPAR_PE = 8 ;
+static const uint8_t EXPLR_WDF_WERR_WMSK_PE = 9 ;
+static const uint8_t EXPLR_WDF_WERR_RDF_BE_PE = 15 ;
+static const uint8_t EXPLR_WDF_WERR_TLXR_WR_PE = 16 ;
+static const uint8_t EXPLR_WDF_WERR_TLXR_BAD_PE = 17 ;
+static const uint8_t EXPLR_WDF_WERR_TLXR_BE_PE = 18 ;
+static const uint8_t EXPLR_WDF_WERR_SRQ_IF_PE = 19 ;
+static const uint8_t EXPLR_WDF_WERR_RDF_IF_PE = 20 ;
+static const uint8_t EXPLR_WDF_WERR_MMIO_IF_PE = 21 ;
+static const uint8_t EXPLR_WDF_WERR_CONTROL_PE = 22 ;
+static const uint8_t EXPLR_WDF_WERR_ECCGEN_ERR = 23 ;
+static const uint8_t EXPLR_WDF_WERR_WBUF_FUNC_UE = 24 ;
+static const uint8_t EXPLR_WDF_WERR_RMWBUF_FUNC_UE = 25 ;
+static const uint8_t EXPLR_WDF_WERR_BEBUF_FUNC_UE = 26 ;
+static const uint8_t EXPLR_WDF_WERR_BE_PE = 27 ;
+static const uint8_t EXPLR_WDF_WERR_INTEGRITY_ERR = 28 ;
+static const uint8_t EXPLR_WDF_WERR_WBUF_MMIO_UE = 29 ;
+static const uint8_t EXPLR_WDF_WERR_SCOM_FSM_PE = 32 ;
+static const uint8_t EXPLR_WDF_WERR_RMWBUF_SCOM_UE = 33 ;
+static const uint8_t EXPLR_WDF_WERR_BEBUF_SCOM_UE = 34 ;
+static const uint8_t EXPLR_WDF_WERR_WBUF_CE = 48 ;
+static const uint8_t EXPLR_WDF_WERR_RMWBUF_CE = 49 ;
+static const uint8_t EXPLR_WDF_WERR_BEBUF_CE = 50 ;
+
+static const uint8_t EXPLR_WDF_WESR_SYNDROME = 0 ;
+static const uint8_t EXPLR_WDF_WESR_SYNDROME_LEN = 8 ;
+static const uint8_t EXPLR_WDF_WESR_SEVERITY = 8 ;
+static const uint8_t EXPLR_WDF_WESR_PART = 9 ;
+static const uint8_t EXPLR_WDF_WESR_SOURCE = 10 ;
+static const uint8_t EXPLR_WDF_WESR_SOURCE_LEN = 3 ;
+
+static const uint8_t EXPLR_WDF_WMSK_DQS0R_PE = 0 ;
+static const uint8_t EXPLR_WDF_WMSK_DQS1R_PE = 1 ;
+static const uint8_t EXPLR_WDF_WMSK_AACR_PE = 2 ;
+static const uint8_t EXPLR_WDF_WMSK_AADR_PE = 3 ;
+static const uint8_t EXPLR_WDF_WMSK_AAER_PE = 4 ;
+static const uint8_t EXPLR_WDF_WMSK_WECR_PE = 5 ;
+static const uint8_t EXPLR_WDF_WMSK_WSPAR_PE = 8 ;
+static const uint8_t EXPLR_WDF_WMSK_WMSK_PE = 9 ;
+static const uint8_t EXPLR_WDF_WMSK_RDF_BE_PE = 15 ;
+static const uint8_t EXPLR_WDF_WMSK_TLXR_WR_PE = 16 ;
+static const uint8_t EXPLR_WDF_WMSK_TLXR_BAD_PE = 17 ;
+static const uint8_t EXPLR_WDF_WMSK_TLXR_BE_PE = 18 ;
+static const uint8_t EXPLR_WDF_WMSK_SRQ_IF_PE = 19 ;
+static const uint8_t EXPLR_WDF_WMSK_RDF_IF_PE = 20 ;
+static const uint8_t EXPLR_WDF_WMSK_MMIO_IF_PE = 21 ;
+static const uint8_t EXPLR_WDF_WMSK_CONTROL_PE = 22 ;
+static const uint8_t EXPLR_WDF_WMSK_ECCGEN_ERR = 23 ;
+static const uint8_t EXPLR_WDF_WMSK_WBUF_FUNC_UE = 24 ;
+static const uint8_t EXPLR_WDF_WMSK_RMWBUF_FUNC_UE = 25 ;
+static const uint8_t EXPLR_WDF_WMSK_BEBUF_FUNC_UE = 26 ;
+static const uint8_t EXPLR_WDF_WMSK_BE_PE = 27 ;
+static const uint8_t EXPLR_WDF_WMSK_INTEGRITY_ERR = 28 ;
+static const uint8_t EXPLR_WDF_WMSK_WBUF_MMIO_UE = 29 ;
+static const uint8_t EXPLR_WDF_WMSK_SCOM_FSM_PE = 32 ;
+static const uint8_t EXPLR_WDF_WMSK_RMWBUF_SCOM_UE = 33 ;
+static const uint8_t EXPLR_WDF_WMSK_BEBUF_SCOM_UE = 34 ;
+static const uint8_t EXPLR_WDF_WMSK_WBUF_CE = 48 ;
+static const uint8_t EXPLR_WDF_WMSK_RMWBUF_CE = 49 ;
+static const uint8_t EXPLR_WDF_WMSK_BEBUF_CE = 50 ;
+
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R0_LEFT = 0 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R0_LEFT_LEN = 5 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R0_RIGHT = 5 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R0_RIGHT_LEN = 5 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R1_LEFT = 10 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R1_LEFT_LEN = 5 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R1_RIGHT = 15 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R1_RIGHT_LEN = 5 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R2_LEFT = 20 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R2_LEFT_LEN = 5 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R2_RIGHT = 25 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R2_RIGHT_LEN = 5 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R3_LEFT = 30 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R3_LEFT_LEN = 5 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R3_RIGHT = 35 ;
+static const uint8_t EXPLR_WDF_WSPAR_CFG_STEERING_R3_RIGHT_LEN = 5 ;
#endif
diff --git a/src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fld_fixes.H b/src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fld_fixes.H
new file mode 100644
index 000000000..fc02d5360
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fld_fixes.H
@@ -0,0 +1,57 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/common/include/explorer_scom_addresses_fld_fixes.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __EXPLR_SCOM_ADDRESSES_FLD_FIXES_H
+#define __EXPLR_SCOM_ADDRESSES_FLD_FIXES_H
+
+static const uint64_t EXPLR_MIPS_TO_OCMB_INTERRUPT_REGISTER1_DOORBELL = 63;
+static const uint64_t EXPLR_EFUSE_IMAGE_OUT_0_ENTERPRISE_MODE_DIS = 53;
+static const uint64_t EXPLR_SRQ_MBA_PMU8Q_CFG_INIT_COMPLETE = 63;
+
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_72 = 0 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_72_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_73 = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_73_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_74 = 16 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_74_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_75 = 24 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_75_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_76 = 32 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_76_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_77 = 40 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_77_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_78 = 48 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_78_LEN = 8 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_79 = 56 ;
+static const uint8_t EXPLR_MCBIST_MBSSYMEC9Q_MODAL_SYMBOL_COUNTER_79_LEN = 8 ;
+static const uint8_t EXPLR_RDF_MCBCM2_MCBIST_HALF_COMPARE_MASK = 0 ;
+static const uint8_t EXPLR_RDF_MCBCM2_MCBIST_HALF_COMPARE_MASK_LEN = 40 ;
+static const uint8_t EXPLR_TP_MB_UNIT_TOP_TR1_TRACE_TRCTRL_CONFIG_TRA_MASTER_CLOCK_ENABLE = 22;
+static const uint8_t EXP_APBONLY0_MICROCONTMUXSEL_MICROCONTMUXSEL = 63 ;
+static const uint8_t EXP_DDR4_PHY_DDR_PHY_CONTROL_DFI_AC_SELECT = 63 - 8;
+static const uint8_t EXP_DDR4_PHY_DDR_PHY_CONTROL_DFI_CFGCMD_AC_MASK = 63 - 5;
+static const uint8_t EXP_DDR4_PHY_DDR_PHY_CONTROL_DFI_CFGCMD_AC_MASK_LEN = 2;
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.C
new file mode 100644
index 000000000..e451cc669
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.C
@@ -0,0 +1,58 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_background_scrub.C
+/// @brief Begin background scrub
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#include <lib/shared/exp_defaults.H>
+#include <exp_background_scrub.H>
+#include <lib/mcbist/exp_memdiags.H>
+
+extern "C"
+{
+
+ ///
+ /// @brief Begin background scrub
+ /// @param[in] i_target OCMB chip
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode exp_background_scrub(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+ {
+ FAPI_INF("Start exp background scrub for %s", mss::c_str(i_target));
+ FAPI_TRY(mss::memdiags::mss_background_scrub_helper(i_target));
+
+ fapi_try_exit:
+ FAPI_INF("End exp background scrub for %s", mss::c_str(i_target));
+ return fapi2::current_err;
+ }
+
+}
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.H
new file mode 100644
index 000000000..2e95cf6f9
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.H
@@ -0,0 +1,55 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_background_scrub.H
+/// @brief Procedure declaration to begin background scrub
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#ifndef __MSS_EXP_BACKGROUND_SCRUB__
+#define __MSS_EXP_BACKGROUND_SCRUB__
+
+#include <fapi2.H>
+
+// Required for Cronus
+typedef fapi2::ReturnCode (*exp_background_scrub_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&);
+
+extern "C"
+{
+
+ ///
+ /// @brief Begin background scrub
+ /// @param[in] i_target the controller
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode exp_background_scrub(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+
+}// extern C
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.mk
new file mode 100644
index 000000000..bf8e5f44a
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.mk
@@ -0,0 +1,31 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_background_scrub.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+# Include the macros and things for MSS EXP procedures
+-include 00exp_common.mk
+
+PROCEDURE=exp_background_scrub
+$(eval $(call ADD_EXP_MEMORY_INCDIRS,$(PROCEDURE)))
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.C
index 28aad7416..880004e23 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.C
@@ -22,3 +22,62 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_bulk_pwr_throttles.C
+/// @brief The explorer thermal/power config
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: Memory
+
+#include <lib/shared/exp_defaults.H>
+#include <vector>
+
+#include <fapi2.H>
+#include <exp_bulk_pwr_throttles.H>
+#include <lib/shared/exp_consts.H>
+#include <lib/power_thermal/exp_throttle.H>
+#include <mss_explorer_attribute_getters.H>
+#include <mss_explorer_attribute_setters.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+
+extern "C"
+{
+ ///
+ /// @brief Set ATTR_EXP_PORT_MAXPOWER, ATTR_EXP_MEM_THROTTLED_N_COMMANDS_PER_SLOT, ATTR_EXP_MEM_THROTTLED_N_COMMANDS_PER_PORT
+ /// @param[in] i_targets vector of OCMB chips
+ /// @param[in] i_throttle_type thermal boolean to determine whether to calculate throttles based on the power regulator or thermal limits
+ /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+ /// @note determines the throttle levels based off of the port's power curve,
+ /// sets the slot throttles to the same
+ /// @note Enums are POWER for power egulator throttles and THERMAL for thermal throttles
+ /// @note equalizes the throttles to the lowest of runtime and the lowest slot-throttle value
+ ///
+ fapi2::ReturnCode exp_bulk_pwr_throttles( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> >& i_targets,
+ const mss::throttle_type i_throttle_type)
+ {
+ FAPI_INF("Start exp_bulk_pwr_throttles for %s type throttling",
+ (( i_throttle_type == mss::throttle_type::THERMAL) ? "THERMAL" : "POWER"));
+
+ for ( const auto& l_ocmb : i_targets)
+ {
+ FAPI_TRY(mss::power_thermal::pwr_throttles(l_ocmb, i_throttle_type));
+ }
+
+ // Equalizes the throttles to the lowest of runtime and the lowest slot-throttle value
+ FAPI_TRY(mss::power_thermal::equalize_throttles(i_targets, i_throttle_type));
+
+ FAPI_INF("End exp_bulk_pwr_throttles");
+ return fapi2::current_err;
+
+ fapi_try_exit:
+ FAPI_ERR("Error calculating exp_bulk_pwr_throttles using %s throttling",
+ ((i_throttle_type == mss::throttle_type::POWER) ? "power" : "thermal"));
+ return fapi2::current_err;
+ }
+
+} //extern C
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.H
index 1112aefb8..79472932b 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.H
@@ -22,3 +22,42 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_bulk_pwr_throttles.H
+/// @brief The explorer thermal/power config
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: Memory
+#ifndef EXP_BULK_PWR_THROTTLES_H_
+#define EXP_BULK_PWR_THROTTLES_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
+typedef fapi2::ReturnCode (*exp_bulk_pwr_throttles_FP_t) ( const
+ std::vector< fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> >&,
+ const mss::throttle_type i_throttle_type);
+
+extern "C"
+{
+
+ ///
+ /// @brief Set ATTR_MSS_PORT_MAXPOWER, ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT
+ /// @param[in] i_targets vector of OCMB chip
+ /// @param[in] i_throttle_type thermal boolean to determine whether to calculate throttles based on the power regulator or thermal limits
+ /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+ /// @note Called in p9_mss_bulk_pwr_throttles
+ /// @note determines the throttle levels based off of the port's power curve,
+ /// sets the slot throttles to the same
+ /// @note Enums are POWER for power egulator throttles and THERMAL for thermal throttles
+ /// @note equalizes the throttles to the lowest of runtime and the lowest slot-throttle value
+ ///
+ fapi2::ReturnCode exp_bulk_pwr_throttles( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> >& i_targets,
+ const mss::throttle_type i_throttle_type);
+}
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.mk
index 6dfbc4fe6..c0ef17e69 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.mk
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_bulk_pwr_throttles.mk
@@ -22,3 +22,9 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+
+-include 00exp_common.mk
+
+PROCEDURE=exp_bulk_pwr_throttles
+$(eval $(call ADD_EXP_MEMORY_INCDIRS,$(PROCEDURE)))
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_check_for_ready.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_check_for_ready.C
index 6a7b0d894..d7f80d648 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_check_for_ready.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_check_for_ready.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,7 +37,9 @@
#include <lib/shared/exp_defaults.H>
#include <exp_check_for_ready.H>
#include <lib/i2c/exp_i2c.H>
-#include <generic/memory/lib/utils/poll.H>
+#include <generic/memory/mss_git_data_helper.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <mss_explorer_attribute_getters.H>
extern "C"
{
@@ -48,32 +50,13 @@ extern "C"
///
fapi2::ReturnCode exp_check_for_ready(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
{
- // Using default parameters
- mss::poll_parameters l_poll_params;
+ mss::display_git_commit_info("exp_check_for_ready");
- // From MSCC explorer firmware arch spec
- // 4.1.5: After power-up, the Explorer Chip will respond with NACK to all incoming I2C requests
- // from the HOST until the I2C slave interface is ready to receive commands.
- FAPI_ASSERT( mss::poll(i_target, l_poll_params, [i_target]()->bool
- {
- return mss::exp::i2c::is_ready(i_target) == fapi2::FAPI2_RC_SUCCESS;
- }),
- fapi2::MSS_EXP_I2C_POLLING_TIMEOUT().
- set_TARGET(i_target),
- "Failed to see an ACK from I2C -- polling timeout on %s",
- mss::c_str(i_target) );
+ fapi2::ATTR_MSS_CHECK_FOR_READY_TIMEOUT_Type l_poll_count = 0;
- // We send the EXP_FW_STATUS command as a sanity check to see if it returns SUCCESS
- FAPI_ASSERT( mss::poll(i_target, l_poll_params, [i_target]()->bool
- {
- return mss::exp::i2c::fw_status(i_target) == fapi2::FAPI2_RC_SUCCESS;
- }),
- fapi2::MSS_EXP_STATUS_POLLING_TIMEOUT().
- set_TARGET(i_target),
- "Failled to see a successful return code -- polling timeout on %s",
- mss::c_str(i_target) );
+ FAPI_TRY(mss::attr::get_check_for_ready_timeout(i_target, l_poll_count));
- return fapi2::FAPI2_RC_SUCCESS;
+ FAPI_TRY(mss::exp::i2c::exp_check_for_ready_helper(i_target, l_poll_count, mss::DELAY_1MS));
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C
index 78d941db2..bc9187fbe 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -34,12 +34,15 @@
// *HWP Consumed by: FSP:HB
#include <lib/shared/exp_consts.H>
-#include <exp_inband.H>
+#include <lib/inband/exp_inband.H>
#include <generic/memory/lib/utils/c_str.H>
#include <generic/memory/lib/utils/mss_bad_bits.H>
#include <lib/exp_draminit_utils.H>
#include <lib/phy/exp_train_display.H>
#include <lib/phy/exp_train_handler.H>
+#include <lib/shared/exp_consts.H>
+#include <generic/memory/mss_git_data_helper.H>
+#include <generic/memory/lib/utils/fir/gen_mss_unmask.H>
extern "C"
{
@@ -50,7 +53,10 @@ extern "C"
///
fapi2::ReturnCode exp_draminit(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
{
+ mss::display_git_commit_info("exp_draminit");
+
uint32_t l_crc = 0;
+ uint8_t l_phy_init_mode = 0;
user_input_msdg l_phy_params;
FAPI_TRY(mss::exp::setup_phy_params(i_target, l_phy_params),
@@ -60,47 +66,31 @@ extern "C"
FAPI_TRY( mss::exp::ib::putUserInputMsdg(i_target, l_phy_params, l_crc),
"Failed putUserInputMsdg() for %s", mss::c_str(i_target) );
- // Issue full boot mode cmd though EXP-FW REQ buffer
+ // Get phy init mode attribute
+ FAPI_TRY(mss::attr::get_exp_phy_init_mode(i_target, l_phy_init_mode));
+
+ // Make sure we're in range
+ FAPI_ASSERT((l_phy_init_mode <= fapi2::ENUM_ATTR_MSS_OCMB_PHY_INIT_MODE_WITH_EYE_CAPTURE),
+ fapi2::MSS_EXP_UNKNOWN_PHY_INIT_MODE()
+ .set_TARGET(i_target)
+ .set_VALUE(l_phy_init_mode),
+ "%s Value for phy init mode for exp_draminit is unknown: %u expected 0 (NORMAL), 1 (WITH_EYE_CAPTURE)",
+ mss::c_str(i_target), l_phy_init_mode);
+
+ // Call appropriate init function
+ if (l_phy_init_mode == fapi2::ENUM_ATTR_MSS_OCMB_PHY_INIT_MODE_NORMAL)
{
- host_fw_command_struct l_cmd;
- mss::exp::setup_cmd_params(l_crc, l_cmd);
- FAPI_TRY( mss::exp::ib::putCMD(i_target, l_cmd),
- "Failed putCMD() for %s", mss::c_str(i_target) );
+ FAPI_TRY(mss::exp::host_fw_phy_normal_init(i_target, l_crc));
}
-
- // Read the response message from EXP-FW RESP buffer
+ else
{
- host_fw_response_struct l_response;
- user_response_msdg l_train_response;
-
- std::vector<uint8_t> l_rsp_data;
- fapi2::ReturnCode l_rc(fapi2::FAPI2_RC_SUCCESS);
-
- FAPI_TRY( mss::exp::ib::getRSP(i_target, l_response, l_rsp_data),
- "Failed getRSP() for %s", mss::c_str(i_target) );
-
- // Proccesses the response data
- FAPI_TRY( mss::exp::read_training_response(i_target, l_rsp_data, l_train_response),
- "Failed read_training_response for %s", mss::c_str(i_target));
-
- // Displays the training response
- FAPI_TRY( mss::exp::train::display_info(i_target, l_train_response));
-
- // Check if cmd was successful
- l_rc = mss::exp::check::response(i_target, l_response);
-
- // If not, then we need to process the bad bitmap
- if(l_rc != fapi2::FAPI2_RC_SUCCESS)
- {
- mss::exp::bad_bit_interface l_interface(l_train_response);
+ FAPI_TRY(mss::exp::host_fw_phy_init_with_eye_capture(i_target, l_crc, l_phy_params));
+ }
- // Record bad bits should only fail if we have an attributes issue - that's a major issue
- FAPI_TRY(mss::record_bad_bits<mss::mc_type::EXPLORER>(i_target, l_interface));
+ // Unmask registers after draminit training
+ FAPI_TRY(mss::unmask::after_draminit_training(i_target), "%s Failed after_draminit_training", mss::c_str(i_target));
- // Now, go to our true error handling procedure
- FAPI_TRY(l_rc, "mss::exp::check::response failed for %s", mss::c_str(i_target));
- }
- }
+ return fapi2::FAPI2_RC_SUCCESS;
fapi_try_exit:
FAPI_INF("Draminit training - %s %s",
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.mk
index dd6f3e2a3..a9e488383 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.mk
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit_mc.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit_mc.C
index be2d4e36f..546299f57 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit_mc.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit_mc.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,6 +40,8 @@
#include <generic/memory/lib/utils/count_dimm.H>
#include <lib/mc/exp_port.H>
+#include <generic/memory/mss_git_data_helper.H>
+#include <generic/memory/lib/utils/fir/gen_mss_unmask.H>
extern "C"
{
@@ -50,6 +52,8 @@ extern "C"
///
fapi2::ReturnCode exp_draminit_mc( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target )
{
+ mss::display_git_commit_info("exp_draminit_mc");
+
FAPI_INF("%s Start exp_draminit MC", mss::c_str(i_target));
@@ -81,18 +85,21 @@ extern "C"
FAPI_TRY( mss::change_refresh_enable(i_target, mss::HIGH), "%s Failed change_refresh_enable",
mss::c_str(i_target) );
+ // Trigger the MC to take the DRAMs out of self refresh
+ FAPI_TRY( mss::change_force_str<mss::mc_type::EXPLORER>(i_target, mss::LOW), "%s Failed change_force_str",
+ mss::c_str(i_target) );
+
// Enable periodic short zq cal
FAPI_TRY( mss::enable_zq_cal(i_target), "%s Failed enable_zq_cal", mss::c_str(i_target) );
// Enable ecc checking
- FAPI_TRY( mss::enable_read_ecc(i_target), "%s Failed enable_read_ecc", mss::c_str(i_target) );
+ FAPI_TRY( mss::enable_read_ecc<mss::mc_type::EXPLORER>(i_target), "%s Failed enable_read_ecc", mss::c_str(i_target) );
// Apply marks from OCMB VPD
FAPI_TRY( mss::apply_mark_store(i_target), "%s Failed enable_read_ecc", mss::c_str(i_target) );
- // TODO: Move mss::unmask::after_draminit_mc to generic and call it
- // At this point the DDR interface must be monitored for memory errors. Memory related FIRs should be unmasked.
- //FAPI_TRY( mss::unmask::after_draminit_mc(i_target), "%s Failed after_draminit_mc", mss::c_str(i_target) );
+ // Unmask registers after draminit_mc
+ FAPI_TRY(mss::unmask::after_draminit_mc(i_target), "%s Failed after_draminit_mc", mss::c_str(i_target));
fapi_try_exit:
FAPI_INF("%s End exp_draminit MC", mss::c_str(i_target));
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_log_data.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_log_data.C
new file mode 100644
index 000000000..ad2c20a97
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_log_data.C
@@ -0,0 +1,109 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_log_data.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/// @file exp_fw_log_data.C
+///
+/// @brief Collects Explorer firmware log data
+// ----------------------------------------
+// *HWP HWP Owner: Matt Derksen <mderkse1@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB
+// ----------------------------------------
+#include <exp_fw_log_data.H>
+#include <fapi2.H>
+#include <lib/inband/exp_inband.H>
+#include <lib/inband/exp_fw_log.H>
+#include <lib/shared/exp_consts.H>
+#include <exp_data_structs.H>
+#include <generic/memory/lib/utils/c_str.H>
+
+
+extern "C"
+{
+ /// See header
+ fapi2::ReturnCode exp_active_log(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmbTarget,
+ std::vector<uint8_t>& o_data)
+ {
+ host_fw_command_struct l_active_errl_cmd;
+ host_fw_response_struct l_response;
+
+ // Set up the command packet
+ mss::exp::ib::build_log_cmd(i_ocmbTarget,
+ mss::exp::ib::SUB_CMD_READ_ACTIVE_LOG,
+ l_active_errl_cmd);
+
+ // Send the command packet
+ FAPI_TRY(mss::exp::ib::putCMD(i_ocmbTarget, l_active_errl_cmd),
+ "exp_active_error_log: Failed putCMD() for %s!",
+ mss::c_str(i_ocmbTarget));
+
+ // Get the response
+ FAPI_TRY(mss::exp::ib::getRSP(i_ocmbTarget, l_response, o_data),
+ "exp_active_error_log: Failed getRSP() cmd "
+ "for %s!", mss::c_str(i_ocmbTarget));
+
+ // Check if cmd was successful
+ FAPI_TRY(mss::exp::ib::check_log_cmd_response(i_ocmbTarget, l_response),
+ "exp_active_error_log: Failed check_log_cmd_response()"
+ " for %s!", mss::c_str(i_ocmbTarget));
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+
+ /// See header
+ fapi2::ReturnCode exp_saved_log(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmbTarget,
+ std::vector<uint8_t>& o_data)
+ {
+ host_fw_command_struct l_saved_log_cmd;
+ host_fw_response_struct l_response;
+
+ // Set up the command packet
+ mss::exp::ib::build_log_cmd(i_ocmbTarget,
+ mss::exp::ib::SUB_CMD_READ_SAVED_LOG,
+ l_saved_log_cmd);
+
+ // Send the command packet
+ FAPI_TRY(mss::exp::ib::putCMD(i_ocmbTarget, l_saved_log_cmd),
+ "exp_saved_log: Failed putCMD() for %s!",
+ mss::c_str(i_ocmbTarget));
+
+ // Get the response
+ FAPI_TRY(mss::exp::ib::getRSP(i_ocmbTarget, l_response, o_data),
+ "exp_saved_log: Failed getRSP() for %s!",
+ mss::c_str(i_ocmbTarget));
+
+ // Check if cmd was successful
+ FAPI_TRY(mss::exp::ib::check_log_cmd_response(i_ocmbTarget, l_response),
+ "exp_saved_log: Failed check_log_cmd_response()"
+ " for %s!", mss::c_str(i_ocmbTarget));
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+}
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_log_data.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_log_data.H
new file mode 100644
index 000000000..4cfe074a1
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_log_data.H
@@ -0,0 +1,77 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_log_data.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file exp_fw_log_data.H
+/// @brief Procedure declaration to get Explorer log data
+///
+// ----------------------------------------
+// *HWP HWP Owner: Matt Derksen <mderkse1@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB
+// ----------------------------------------
+#ifndef __EXP_FW_LOG_DATA__
+#define __EXP_FW_LOG_DATA__
+
+#include <fapi2.H>
+#include <vector>
+
+// Required for Cronus
+typedef fapi2::ReturnCode (*exp_active_log_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&,
+ std::vector<uint8_t>& );
+
+typedef fapi2::ReturnCode (*exp_saved_log_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&,
+ std::vector<uint8_t>& );
+
+extern "C"
+{
+
+ ///
+ /// @brief Grab active log entries from Explorer RAM
+ /// @param[in] i_target the controller
+ /// @param[out] o_data - where to put error log data
+ ///
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode exp_active_log(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmbTarget,
+ std::vector<uint8_t>& o_data );
+
+ ///
+ /// @brief Grab saved log entries from Explorer SPI flash
+ /// @param[in] i_target the controller
+ /// @param[out] o_data - where to put error log data
+ ///
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode exp_saved_log(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmbTarget,
+ std::vector<uint8_t>& o_data );
+
+}// extern C
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_update.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_update.C
new file mode 100644
index 000000000..8a4cb9978
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_update.C
@@ -0,0 +1,379 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_update.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_fw_update.C
+/// @brief Procedure definition to update explorer firmware
+///
+// *HWP HWP Owner: Glenn Miles <milesg@ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include <exp_fw_update.H>
+#include <lib/inband/exp_inband.H>
+#include <lib/shared/exp_consts.H>
+#include <exp_data_structs.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <lib/omi/crc32.H>
+#include <mmio_access.H>
+
+namespace mss
+{
+namespace exp
+{
+
+constexpr uint32_t FLASH_WRITE_BLOCK_SIZE = 256;
+
+namespace bupg
+{
+
+///
+/// @brief Checks explorer response argument for a successful command
+/// @param[in] i_target OCMB target
+/// @param[in] i_rsp response from command
+/// @param[in] i_cmd original command
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode check_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const host_fw_response_struct& i_rsp,
+ const host_fw_command_struct& i_cmd)
+{
+ std::vector<uint8_t> resp_arg;
+ uint8_t success_flag = 0;
+ uint16_t err_code = 0;
+ uint32_t index = 0;
+
+ //copy response_argument field into a vector that can be used by
+ //readCrctEndian()
+ resp_arg.assign(i_rsp.response_argument,
+ i_rsp.response_argument + ARGUMENT_SIZE);
+
+ //convert fields to native endianness
+ FAPI_TRY(mss::exp::ib::readCrctEndian(resp_arg, index, success_flag));
+ FAPI_TRY(mss::exp::ib::readCrctEndian(resp_arg, index, err_code));
+
+ // Check if cmd was successful
+ FAPI_ASSERT(success_flag == omi::response_arg::SUCCESS &&
+ i_rsp.request_identifier == i_cmd.request_identifier,
+ fapi2::EXP_UPDATE_CMD_FAILED().
+ set_TARGET(i_target).
+ set_RSP_ID(i_rsp.response_id).
+ set_REQ_ID(i_rsp.request_identifier).
+ set_ERROR_CODE(err_code).
+ set_RSP_DATA(i_rsp),
+ "Recieved failure response for firmware update command on %s",
+ mss::c_str(i_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}//bupg
+
+///
+/// @brief host_fw_command_struct structure setup for flash_write
+/// @param[in] i_binary_size the total size of the binary image
+/// @param[in] i_seq_number the sequence number of this command
+/// @param[in] i_cmd_data_crc the command data CRC
+/// @param[out] o_cmd the command packet to update
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode setup_flash_write_cmd(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint32_t i_binary_size,
+ const uint16_t i_seq_number,
+ const uint32_t i_cmd_data_crc,
+ host_fw_command_struct& o_cmd)
+{
+ std::vector<uint8_t> swapped32;
+ std::vector<uint8_t> cmd_args;
+ std::vector<uint8_t> test16_vec;
+ const uint16_t test16_value = 1;
+
+ memset(&o_cmd, 0, sizeof(host_fw_command_struct));
+
+ // Issue EXP_FW_BINARY_UPGRADE cmd though EXP-FW REQ buffer
+ o_cmd.cmd_id = mss::exp::omi::EXP_FW_BINARY_UPGRADE;
+ o_cmd.cmd_flags = mss::exp::omi::ADDITIONAL_DATA;
+
+ // Host generated id number (returned in response packet)
+ uint32_t l_counter = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_OCMB_COUNTER, i_target, l_counter));
+ o_cmd.request_identifier = l_counter;
+
+ //always send a block of data
+ o_cmd.cmd_length = FLASH_WRITE_BLOCK_SIZE;
+
+ o_cmd.cmd_crc = i_cmd_data_crc;
+ o_cmd.host_work_area = 0;
+ o_cmd.cmd_work_area = 0;
+ memset(o_cmd.padding, 0, sizeof(o_cmd.padding));
+
+ //populate command arguments using correct endian byte ordering
+ //NOTE: putCMD can not do the byte ordering of the command_arguments
+ // field for us.
+
+ //sub-command id is single byte. Never requires byte-swapping.
+ cmd_args.push_back(bupg::SUB_CMD_WRITE);
+
+ //forceCrctEndian can only handle 1, 2, 4, and 8 byte integers, so
+ //for the flash_binary_size field, which is a 3 byte integer, treat
+ //it as a 4 byte value and shift result right or left one byte
+ //depending on if it is little or big endian.
+ FAPI_TRY(mss::exp::ib::forceCrctEndian(i_binary_size, swapped32));
+
+ // Test for big or little endian value on a known value (0x1)
+ FAPI_TRY(mss::exp::ib::forceCrctEndian(test16_value, test16_vec));
+
+ //if the least significant byte ended up in byte 0, then the
+ //result is a little endian value.
+ if(test16_vec[0] == 1)
+ {
+ //use first 3 bytes of 4 byte value
+ cmd_args.insert(cmd_args.end(), swapped32.begin(), swapped32.end() - 1);
+ }
+ else //big endian
+ {
+ //use last 3 bytes of 4 byte value
+ cmd_args.insert(cmd_args.end(), swapped32.begin() + 1, swapped32.end());
+ }
+
+ //add the sequence number
+ FAPI_TRY(mss::exp::ib::forceCrctEndian(i_seq_number, cmd_args));
+
+ //copy cmd_args vector into command_args array
+ std::copy(cmd_args.begin(), cmd_args.end(), &o_cmd.command_argument[0]);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Sets the command_argument fields for flash_commit sub-command
+/// in the correct endianness.
+///
+/// @param[in] i_target OCMB target that will be acted upon with this command
+/// @param[out] o_cmd the command packet to update
+///
+fapi2::ReturnCode setup_flash_commit_cmd(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ host_fw_command_struct& o_cmd)
+{
+ memset(&o_cmd, 0, sizeof(host_fw_command_struct));
+
+ // Issue EXP_FW_BINARY_UPGRADE cmd though EXP-FW REQ buffer
+ o_cmd.cmd_id = mss::exp::omi::EXP_FW_BINARY_UPGRADE;
+ o_cmd.cmd_flags = 0;
+
+ // Retrieve a unique sequence id for this transaction
+ uint32_t l_counter = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_OCMB_COUNTER, i_target, l_counter));
+ o_cmd.request_identifier = l_counter;
+ o_cmd.cmd_length = 0;
+
+ o_cmd.cmd_crc = 0xffffffff;
+ o_cmd.host_work_area = 0;
+ o_cmd.cmd_work_area = 0;
+ memset(o_cmd.padding, 0, sizeof(o_cmd.padding));
+
+ // Set the sub-command ID in the command argument field to FLASH_COMMIT
+ o_cmd.command_argument[0] = bupg::SUB_CMD_COMMIT;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}//exp
+}//mss
+
+extern "C"
+{
+
+///
+/// @brief Updates explorer firmware
+/// @param[in] i_target the controller
+/// @param[in] i_image_ptr pointer to the binary image
+/// @param[in] i_image_sz size of the binary image
+/// @return FAPI2_RC_SUCCESS if ok
+///
+ fapi2::ReturnCode exp_fw_update(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint8_t* i_image_ptr, const size_t i_image_sz)
+ {
+ uint16_t seq_num = 0;
+ uint32_t block_crc = 0;
+ std::vector<uint8_t> buffer;
+ const uint8_t* end_ptr = i_image_ptr + i_image_sz;
+
+ FAPI_INF("Entering exp_fw_update(%s). imageSize[0x%08x]",
+ mss::c_str(i_target), i_image_sz);
+
+ //Check that i_image_sz value is not larger than 3 bytes, which
+ //is the actual field size for this value in the packet.
+ FAPI_ASSERT(((i_image_sz & 0xff000000) == 0),
+ fapi2::EXP_UPDATE_INVALID_IMAGE_SIZE()
+ .set_IMAGE_SIZE(i_image_sz),
+ "exp_fw_update: image size[0x%08x] must be less than 16MB!",
+ i_image_sz);
+
+ // Write successive blocks until the entire image is written
+ buffer.reserve(mss::exp::FLASH_WRITE_BLOCK_SIZE);
+
+ for(uint8_t* cur_ptr = const_cast<uint8_t*>(i_image_ptr);
+ cur_ptr < end_ptr;
+ cur_ptr += mss::exp::FLASH_WRITE_BLOCK_SIZE)
+ {
+ const uint32_t bytes_left = end_ptr - cur_ptr;
+ const uint32_t data_size = (bytes_left <
+ mss::exp::FLASH_WRITE_BLOCK_SIZE) ?
+ bytes_left :
+ mss::exp::FLASH_WRITE_BLOCK_SIZE;
+
+ // copy data into a vector (required by crc32_gen)
+ buffer.assign(cur_ptr, cur_ptr + data_size);
+
+ // pad end with FF's if smaller than block size
+ buffer.resize(mss::exp::FLASH_WRITE_BLOCK_SIZE, 0xFF);
+
+ // calculate the crc
+ block_crc = crc32_gen(buffer);
+
+ // endian swap
+ FAPI_TRY(mss::exp::ib::correctMMIOEndianForStruct(buffer));
+ FAPI_TRY(mss::exp::ib::correctMMIOword_order(buffer));
+
+ // write block to data buffer on explorer
+ FAPI_TRY(fapi2::putMMIO(i_target,
+ mss::exp::ib::EXPLR_IB_DATA_ADDR,
+ mss::exp::ib::BUFFER_TRANSACTION_SIZE,
+ buffer));
+
+ // Issue flash_write sub-command through EXP-FW request buffer
+ host_fw_command_struct flash_write_cmd;
+ {
+ // Set up the command packet
+ FAPI_TRY(mss::exp::setup_flash_write_cmd(
+ i_target,
+ i_image_sz,
+ seq_num,
+ block_crc,
+ flash_write_cmd),
+ "exp_fw_update: Failed setup_flash_write_cmd() "
+ "for %s! seq_num[%u]",
+ mss::c_str(i_target), seq_num);
+
+ // Send the command packet
+ FAPI_TRY(mss::exp::ib::putCMD(i_target, flash_write_cmd),
+ "exp_fw_update: Failed flash_write putCMD() "
+ "for %s! seq_num[%u]",
+ mss::c_str(i_target), seq_num);
+ }
+
+ // Read the response message from EXP-FW RESP buffer
+ {
+ host_fw_response_struct response;
+ std::vector<uint8_t> rsp_data;
+
+ // Normally we need to poll the outbound doorbell and read/check the
+ // fw_response_struct to make sure the command completed. In this case,
+ // we will only check the fw_response_struct for every 16th transfer to
+ // speed things up.
+ // We still have to poll the doorbell to make sure the command completed
+ if ((seq_num % 16) == 0)
+ {
+ // Read response from buffer
+ FAPI_TRY(mss::exp::ib::getRSP(i_target, response, rsp_data),
+ "exp_fw_update: getRSP() failed for flash_write "
+ "on %s! seq_num[%u]",
+ mss::c_str(i_target), seq_num);
+
+ // Check status in response packet
+ FAPI_TRY(mss::exp::bupg::check_response(i_target, response, flash_write_cmd),
+ "exp_fw_update: error response for flash_write "
+ "on %s! seq_num[%u]",
+ mss::c_str(i_target), seq_num);
+ }
+ else
+ {
+ // Poll response doorbell only
+ FAPI_TRY(mss::exp::ib::poll_for_response_ready(i_target),
+ "exp_fw_update: error polling response for flash_write "
+ "on %s! seq_num[%u]",
+ mss::c_str(i_target), seq_num);
+
+ // Clear response doorbell
+ FAPI_TRY(mss::exp::ib::clear_outbound_doorbell(i_target));
+ }
+ }
+
+ //increment sequence number after each 256 byte block is written
+ seq_num++;
+ }
+
+ host_fw_command_struct flash_commit_cmd;
+ // Issue the flash_commit sub-command through EXP-FW request buffer
+ {
+ FAPI_TRY(mss::exp::setup_flash_commit_cmd(i_target,
+ flash_commit_cmd));
+ FAPI_TRY(mss::exp::ib::putCMD(i_target, flash_commit_cmd),
+ "exp_fw_update: putCMD() failed for flash_commit on %s!",
+ mss::c_str(i_target));
+ }
+
+ // Read the response message from EXP-FW RESP buffer
+ {
+ host_fw_response_struct response;
+ std::vector<uint8_t> rsp_data;
+
+ // Wait a little while first (value based on MCHP estimations):
+ // 2 sec for image authentication
+ // 7 sec to erase 600K on flash part
+ // 1800 usec to program flash image
+ // = 10.8 sec, so wait 15 sec to be safe
+ FAPI_INF("Waiting for flash image commit to complete on %s...", mss::c_str(i_target));
+
+ for (uint64_t l_seconds = 0; l_seconds < 15; ++l_seconds)
+ {
+ FAPI_TRY(fapi2::delay(mss::DELAY_1S, 200));
+ }
+
+ FAPI_TRY(mss::exp::ib::getRSP(i_target, response, rsp_data),
+ "exp_fw_update: getRSP() failed for flash_commit on %s!",
+ mss::c_str(i_target) );
+
+ // Check if cmd was successful
+ FAPI_TRY(mss::exp::bupg::check_response(i_target, response, flash_commit_cmd),
+ "exp_fw_update: error response for flash_commit on %s!",
+ mss::c_str(i_target) );
+ }
+
+ fapi_try_exit:
+ FAPI_INF("Exiting exp_fw_update(%s) with return code : 0x%08x...",
+ mss::c_str(i_target), (uint64_t) fapi2::current_err);
+ return fapi2::current_err;
+ }
+
+} //extern "C"
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_update.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_update.H
new file mode 100644
index 000000000..b6c1fbd0f
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_update.H
@@ -0,0 +1,126 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_fw_update.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_fw_update.H
+/// @brief Procedure declaration to update explorer firmware
+///
+// *HWP HWP Owner: Glenn Miles <milesg@ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#ifndef __MSS_EXP_FW_UPDATE__
+#define __MSS_EXP_FW_UPDATE__
+
+#include <fapi2.H>
+#include <exp_data_structs.H>
+
+// Required for Cronus
+typedef fapi2::ReturnCode (*exp_fw_update_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&,
+ const uint8_t*, const size_t);
+
+extern "C"
+{
+
+///
+/// @brief Updates explorer firmware
+/// @param[in] i_target the controller
+/// @param[in] i_image_ptr pointer to the binary image
+/// @param[in] i_image_sz size of the binary image
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+ fapi2::ReturnCode exp_fw_update(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint8_t* i_image_ptr, const size_t i_image_sz);
+
+}// extern C
+
+namespace mss
+{
+namespace exp
+{
+namespace bupg
+{
+
+///
+/// @brief Defines the sub-commands available for the EXP_FW_BINARY_UPGRADE
+/// command
+///
+typedef enum sub_cmd_id
+{
+ SUB_CMD_NULL = 0x00,
+ SUB_CMD_WRITE = 0x01,
+ SUB_CMD_COMMIT = 0x02,
+ SUB_CMD_WRITE_ABORT = 0x03,
+ SUB_CMD_PART_INFO_GET = 0x04,
+ SUB_CMD_READ = 0x05,
+ SUB_CMD_PART_ERASE = 0x06,
+ SUB_CMD_MAX
+} sub_cmd_id_t;
+
+///
+/// @brief Checks explorer response argument for a successful command
+/// @param[in] i_target OCMB target
+/// @param[in] i_rsp response command
+/// @param[in] i_cmd original command
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode check_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const host_fw_response_struct& i_rsp,
+ const host_fw_command_struct& i_cmd);
+
+}// ns bupg
+
+///
+/// @brief host_fw_command_struct structure setup for flash_write
+/// @param[in] i_target OCMB target that will be acted upon with this command
+/// @param[in] i_binary_size the total size of the binary image
+/// @param[in] i_seq_number the sequence number of this command
+/// @param[in] i_cmd_data_crc the command data CRC
+/// @param[out] o_cmd the command packet to update
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode setup_flash_write_cmd(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint32_t i_binary_size,
+ const uint16_t i_seq_number,
+ const uint32_t i_cmd_data_crc,
+ host_fw_command_struct& o_cmd);
+
+///
+/// @brief Sets the command_argument fields for flash_commit sub-command
+/// in the correct endianness.
+///
+/// @param[in] i_target OCMB target that will be acted upon with this command
+/// @param[out] o_cmd the command packet to update
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode setup_flash_commit_cmd(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ host_fw_command_struct& o_cmd);
+
+}// ns exp
+}// ns mss
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getecid.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getecid.C
index ad20d2e0c..ac8d7e7cb 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getecid.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getecid.C
@@ -39,6 +39,8 @@
#include <explorer_scom_addresses.H>
#include <explorer_scom_addresses_fld.H>
#include <mss_explorer_attribute_setters.H>
+#include <generic/memory/mss_git_data_helper.H>
+#include <lib/plug_rules/exp_plug_rules.H>
extern "C"
{
@@ -50,24 +52,22 @@ extern "C"
///
fapi2::ReturnCode exp_getecid(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
{
- // Using FUSE enterprise_dis bit, determine whether enterprise is disabled, otherwise
- // we will enable it. Override to disable it is done in omi_setup. Half_dimm_mode we
- // will also disable by default, as it is not a feature of P systems
+ mss::display_git_commit_info("exp_getecid");
+
{
- uint8_t l_enterprise_mode = fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_MODE_NON_ENTERPRISE; // 0
- uint8_t l_half_dimm_mode = fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_FULL_DIMM; // 0
+ bool l_enterprise_fuse = false;
+ bool l_enterprise_final = false;
- FAPI_TRY(mss::exp::ecid::get_enterprise_and_half_dimm_from_fuse(
- i_target, l_enterprise_mode, l_half_dimm_mode),
- "exp_getecid: getting enterprise and half_dimm from fuse failed on %s",
+ FAPI_TRY(mss::exp::ecid::get_enterprise_from_fuse(i_target, l_enterprise_fuse),
+ "exp_getecid: getting enterprise from fuse failed on %s",
mss::c_str(i_target));
- // Set attributes
- FAPI_TRY(mss::attr::set_ocmb_enterprise_mode(i_target, l_enterprise_mode),
- "exp_getecid: Could not set ATTR_MSS_OCMB_ENTERPRISE_MODE");
+ // Calculate the global enterprise mode state while verifying plug rules with policy and override attributes
+ FAPI_TRY(mss::exp::plug_rule::enterprise_mode(i_target, l_enterprise_fuse, l_enterprise_final));
- FAPI_TRY(mss::attr::set_ocmb_half_dimm_mode(i_target, l_half_dimm_mode),
- "exp_getecid: Could not set ATTR_MSS_OCMB_HALF_DIMM_MODE");
+ // Set global enterprise mode attribute
+ FAPI_TRY(mss::attr::set_ocmb_enterprise_mode(i_target, l_enterprise_final),
+ "exp_getecid: Could not set ATTR_MSS_OCMB_ENTERPRISE_MODE");
}
//
@@ -87,6 +87,11 @@ extern "C"
FAPI_TRY(mss::exp::ecid::read_from_fuse(i_target, l_ecid),
"exp_getecid: Could not read ecid from FUSE on %s", mss::c_str(i_target));
+ for (uint8_t l_ecid_idx = 0; l_ecid_idx < mss::exp::ecid_consts::FUSE_ARRAY_SIZE; ++l_ecid_idx)
+ {
+ FAPI_INF("%s ECID[%u]: 0x%04X", mss::c_str(i_target), l_ecid_idx, l_ecid[l_ecid_idx]);
+ }
+
// TK - Remove once ATTR_ECID is made large enough
FAPI_TRY(mss::attr::set_ocmb_ecid(i_target, l_ecid),
"exp_getecid: Could not set ATTR_MSS_OCMB_ECID on %s", mss::c_str(i_target));
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getidec.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getidec.C
new file mode 100644
index 000000000..a5008d62f
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getidec.C
@@ -0,0 +1,130 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getidec.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_getidec.C
+/// @brief Contains function to lookup Chip ID and EC values of Explorer Chip
+///
+/// *HWP HWP Owner: Christian Geddes <crgeddes@us.ibm.com>
+/// *HWP HWP Backup: <none>
+/// *HWP Team: Hostboot
+/// *HWP Level: 2
+/// *HWP Consumed by: Hostboot / Cronus
+
+#include <fapi2.H>
+#include <exp_getidec.H>
+#include <lib/shared/exp_consts.H>
+#include <chips/ocmb/explorer/common/include/explorer_scom_addresses.H>
+#include <chips/ocmb/explorer/common/include/explorer_scom_addresses_fixes.H>
+#include <chips/ocmb/explorer/common/include/explorer_scom_addresses_fld.H>
+#include <chips/ocmb/explorer/common/include/explorer_scom_addresses_fld_fixes.H>
+#include <generic/memory/mss_git_data_helper.H>
+#include <generic/memory/lib/utils/c_str.H>
+
+extern "C"
+{
+
+ ///
+ /// @brief Lookup the Chip ID and EC level values for this explorer chip
+ /// @param[in] i_target Explorer OCMB chip
+ /// @param[out] o_chipId Explorer Chip ID
+ /// @param[out] o_chipEc Explorer Chip EC
+ /// @return fapi2:ReturnCode FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ fapi2::ReturnCode exp_getidec(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ uint16_t& o_chipId,
+ uint8_t& o_chipEc)
+ {
+ mss::display_git_commit_info("exp_getidec");
+ uint8_t l_revision = 0;
+ uint8_t l_location = 0;
+ uint8_t l_chipBaseId = 0;
+ fapi2::buffer<uint64_t> l_chip_info_buffer;
+ fapi2::buffer<uint64_t> l_efuse3_buffer;
+
+ // The chipid and location come from the CHIP_INFO register
+ FAPI_TRY(fapi2::getScom( i_target,
+ static_cast<uint64_t>(mss::exp::idec_consts::EXPLR_CHIP_INFO_REG),
+ l_chip_info_buffer ),
+ "exp_getidec: could not read explorer chip_info register register 0x%08x",
+ mss::exp::idec_consts::EXPLR_CHIP_INFO_REG);
+
+ l_chip_info_buffer.extractToRight<mss::exp::idec_consts::LOCATION_BIT_START,
+ mss::exp::idec_consts::LOCATION_BIT_LENGTH>(l_location);
+ l_chip_info_buffer.extractToRight<mss::exp::idec_consts::CHIPID_BIT_START,
+ mss::exp::idec_consts::CHIPID_BIT_LENGTH>(l_chipBaseId);
+
+ // Location 0:3
+ // Empty 4:7
+ // ChipId 8:15
+ o_chipId = (l_location << 12) | l_chipBaseId;
+
+
+ // The revision/DD/EC level comes from EFUSE_IMAGE_OUT_3
+ FAPI_TRY(fapi2::getScom( i_target, static_cast<uint64_t>(EXPLR_EFUSE_IMAGE_OUT_3), l_efuse3_buffer ),
+ "exp_getidec: could not read explorer efuse_out3 register 0x%08x", EXPLR_EFUSE_IMAGE_OUT_3);
+
+ l_efuse3_buffer.extractToRight<mss::exp::idec_consts::REVISION_BIT_START,
+ mss::exp::idec_consts::REVISION_BIT_LENGTH>(l_revision);
+
+ // Due to limitations in what logic could be updated between revisions
+ // there is no explicit Major+Minor value available in the hardware.
+ // Instead we have to explicitly convert a rolling number into the
+ // standard major.minor DD value we expect.
+ o_chipEc = 0;
+
+ switch( l_revision )
+ {
+ case(0):
+ o_chipEc = 0x10;
+ break; //A.0
+
+ case(1):
+ o_chipEc = 0x11;
+ break; //A.1
+
+ case(2):
+ o_chipEc = 0x20;
+ break; //B.0
+ }
+
+ // Ensure we found a known level
+ FAPI_ASSERT(o_chipEc != 0,
+ fapi2::EXP_UNKNOWN_REVISION().
+ set_TARGET(i_target).
+ set_REVISION(l_revision).
+ set_CHIP_INFO_REG(l_chip_info_buffer).
+ set_EFUSE_IMAGE_OUT_3(l_efuse3_buffer),
+ "The %s revision (%d) does not match a known DD level.",
+ mss::c_str(i_target), l_revision);
+
+
+ FAPI_DBG("EC found 0x%.02x chipId found 0x%.04x", o_chipEc, o_chipId);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+} // extern "C"
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getidec.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getidec.H
new file mode 100644
index 000000000..e319981a7
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getidec.H
@@ -0,0 +1,60 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_getidec.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_getidec.H
+/// @brief Contains function to lookup Chip ID and EC values of Explorer Chip
+///
+/// *HWP HWP Owner: Christian Geddes <crgeddes@us.ibm.com>
+/// *HWP HWP Backup: <none>
+/// *HWP Team: Hostboot
+/// *HWP Level: 2
+/// *HWP Consumed by: Hostboot / Cronus
+
+#ifndef __EXP_GETIDEC_H_
+#define __EXP_GETIDEC_H_
+
+#include <fapi2.H>
+
+typedef fapi2::ReturnCode (*exp_getidec_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&,
+ uint16_t&, uint8_t&);
+
+extern "C"
+{
+
+///
+/// @brief Lookup the Chip ID and EC level values for this explorer chip
+/// @param[in] i_target Explorer OCMB chip
+/// @param[out] o_chipId Explorer Chip ID
+/// @param[out] o_chipEc Explorer Chip EC
+/// @return fapi2:ReturnCode FAPI2_RC_SUCCESS if success, else error code.
+///
+ fapi2::ReturnCode exp_getidec(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ uint16_t& o_chipId,
+ uint8_t& o_chipEc);
+
+} // extern "C"
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.mk
deleted file mode 100644
index 3f998fd58..000000000
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
-#
-# $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.mk $
-#
-# OpenPOWER HostBoot Project
-#
-# Contributors Listed Below - COPYRIGHT 2018
-# [+] International Business Machines Corp.
-#
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# IBM_PROLOG_END_TAG
-PROCEDURE=exp_inband
-$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/p9/procedures/hwp/nest)
-$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/ocmb/explorer/common/include)
-# Explicitly calling the below to only pick up the generic constants
-# We don't want to clutter this procedure w/ too many includes
-$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH))
-$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/ocmb/explorer/procedures/hwp/memory)
-$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_eff_config_thermal.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_eff_config_thermal.C
new file mode 100644
index 000000000..71358528f
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_eff_config_thermal.C
@@ -0,0 +1,190 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_eff_config_thermal.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_mss_eff_config_thermal.C
+/// @brief The explorer thermal/power config
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: Memory
+
+#include <lib/shared/exp_defaults.H>
+#include <fapi2.H>
+#include <vector>
+#include <exp_bulk_pwr_throttles.H>
+#include <exp_mss_eff_config_thermal.H>
+#include <lib/power_thermal/exp_decoder.H>
+#include <lib/power_thermal/exp_throttle.H>
+#include <lib/shared/exp_consts.H>
+#include <mss_explorer_attribute_getters.H>
+#include <mss_explorer_attribute_setters.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/dimm/kind.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
+#include <generic/memory/lib/mss_generic_system_attribute_getters.H>
+
+extern "C"
+{
+ ///
+ /// @brief Perform thermal calculations
+ /// @param[in] i_targets vector of OCMB chip
+ /// @return FAPI2_RC_SUCCESS iff ok
+ fapi2::ReturnCode exp_mss_eff_config_thermal( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> >&
+ i_targets )
+ {
+ using TT = mss::power_thermal::throttle_traits<>;
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ FAPI_INF("Start exp_mss_eff_config_thermal");
+
+ // For regulaor power/current throttling or thermal throtling
+ // Do thermal throttling last so the attributes end up representing a total power value for later usage
+ // Need to have ATTR_EXP_TOTAL_PWR_SLOPE and ATTR_EXP_TOTAL_PWR_INTERCEPT with total DIMM power
+ // (not regulator current values) after exp_mss_eff_config_thermal is run, so when OCC calls
+ // exp_bulk_pwr_throttles at runtime the total DIMM power will be used for any memory bulk supply throttling
+ const std::vector<mss::throttle_type> throttle_types{ mss::throttle_type::POWER, mss::throttle_type::THERMAL};
+
+ // Return error if safemode throttle utilization is less than MIN_UTIL
+ const uint64_t l_min_util = TT::MIN_UTIL;
+ uint32_t l_safemode_util = 0;
+ FAPI_TRY( mss::attr::get_mrw_safemode_dram_databus_util(l_safemode_util), "Error in exp_mss_eff_config_thermal" );
+ FAPI_ASSERT( l_safemode_util >= TT::MIN_UTIL,
+ fapi2::MSS_MRW_SAFEMODE_UTIL_THROTTLE_NOT_SUPPORTED()
+ .set_MRW_SAFEMODE_UTIL(l_safemode_util)
+ .set_MIN_UTIL_VALUE(l_min_util),
+ "MRW safemode util (%d centi percent) has less util than the min util allowed (%d centi percent)",
+ l_safemode_util, l_min_util );
+
+ for ( const auto& l_ocmb : i_targets)
+ {
+ //Restore runtime_throttles
+ //Sets throttles to max_databus_util value
+ FAPI_INF("Restoring throttles for %s", mss::c_str(l_ocmb));
+ FAPI_TRY( mss::power_thermal::restore_runtime_throttles<>(l_ocmb), "Error in exp_mss_eff_config_thermal");
+ }
+
+ for (const auto& l_throttle_type : throttle_types )
+ {
+ for ( const auto& l_ocmb : i_targets)
+ {
+ //Not doing any work if there are no dimms installed
+ if (mss::count_dimm(l_ocmb) == 0)
+ {
+ FAPI_INF("Skipping eff_config thermal because no dimms for %s", mss::c_str(l_ocmb));
+ continue;
+ }
+
+ // Thermal power (OCMB+DRAM)
+ uint64_t l_thermal_power_limit[TT::SIZE_OF_THERMAL_LIMIT_ATTR] = {0};
+ uint64_t l_thermal_power_slope[TT::SIZE_OF_THERMAL_SLOPE_ATTR] = {0};
+ uint64_t l_thermal_power_intecept[TT::SIZE_OF_THERMAL_INTERCEPT_ATTR] = {0};
+ // Power (PMIC)
+ uint64_t l_current_curve_with_limit[TT::SIZE_OF_CURRENT_CURVE_WITH_LIMIT_ATTR] = {0};
+
+ // Get the data from MRW
+ FAPI_TRY( mss::attr::get_mrw_ocmb_thermal_memory_power_limit (l_thermal_power_limit),
+ "Error in exp_mss_eff_config_thermal");
+ FAPI_TRY( mss::attr::get_mrw_ocmb_pwr_slope (l_thermal_power_slope), "Error in exp_mss_eff_config_thermal");
+ FAPI_TRY( mss::attr::get_mrw_ocmb_pwr_intercept (l_thermal_power_intecept), "Error in exp_mss_eff_config_thermal");
+ FAPI_TRY( mss::attr::get_mrw_ocmb_current_curve_with_limit (l_current_curve_with_limit),
+ "Error in exp_mss_eff_config_thermal");
+
+ // Convert array to vector
+ std::vector<uint64_t> l_thermal_power_limit_v ( std::begin(l_thermal_power_limit),
+ std::end(l_thermal_power_limit) );
+ std::vector<uint64_t> l_thermal_power_slope_v ( std::begin(l_thermal_power_slope),
+ std::end(l_thermal_power_slope) );
+ std::vector<uint64_t> l_thermal_power_intecept_v ( std::begin(l_thermal_power_intecept),
+ std::end(l_thermal_power_intecept) );
+ std::vector<uint64_t> l_current_curve_with_limit_v( std::begin(l_current_curve_with_limit),
+ std::end(l_current_curve_with_limit) );
+
+
+ uint16_t l_slope [TT::DIMMS_PER_PORT] = {0};
+ uint16_t l_intercept[TT::DIMMS_PER_PORT] = {0};
+ uint32_t l_limit [TT::DIMMS_PER_PORT] = {0};
+
+ for (const auto& l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(l_ocmb))
+ {
+ //Don't run if there are no dimms on the port
+ if (mss::count_dimm(l_port) == 0)
+ {
+ continue;
+ }
+
+ // Set the thermal power throttle
+ //Set the PMIC current slope, intercept and limit
+ FAPI_TRY( mss::power_thermal::get_power_attrs (l_throttle_type,
+ l_port,
+ l_thermal_power_slope_v,
+ l_thermal_power_intecept_v,
+ l_thermal_power_limit_v,
+ l_current_curve_with_limit_v,
+ l_slope,
+ l_intercept,
+ l_limit) );
+
+ FAPI_TRY(mss::attr::set_total_pwr_slope(l_port, l_slope));
+ FAPI_TRY(mss::attr::set_total_pwr_intercept(l_port, l_intercept));
+ FAPI_TRY(mss::attr::set_dimm_thermal_limit(l_port, l_limit));
+ FAPI_TRY(mss::attr::set_mem_watt_target(l_port, l_limit));
+
+ for ( const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(l_port) )
+ {
+ const uint8_t l_dimm_pos = mss::index(l_dimm);
+ FAPI_INF( "DIMM (%d) slope is %d, intercept is %d, limit is %d for %s",
+ l_dimm_pos, l_slope[l_dimm_pos], l_intercept[l_dimm_pos],
+ l_limit[l_dimm_pos], mss::c_str(l_port));
+ }
+ }
+
+ FAPI_INF("Starting pwr_throttles(%s)", mss::throttle_type::POWER == l_throttle_type ? "POWER" : "THERMAL");
+ //get the power limits, done per dimm and set to worst case for the slot and port throttles
+ FAPI_TRY(mss::power_thermal::pwr_throttles(l_ocmb, l_throttle_type));
+ }
+
+ // Equalizes the throttles to the lowest of runtime and the lowest slot-throttle value
+ FAPI_TRY(mss::power_thermal::equalize_throttles(i_targets, l_throttle_type));
+
+ for ( const auto& l_ocmb : i_targets)
+ {
+ //Set runtime throttles to worst case between ATTR_EXP_MEM_THROTTLED_N_COMMANDS_PER_SLOT
+ //and ATTR_EXP_MEM_RUNTIME_THROTTLED_N_COMMANDS_PER_SLOT and the _PORT equivalents also
+ FAPI_TRY( mss::power_thermal::update_runtime_throttle(l_ocmb), "Error in exp_mss_eff_config_thermal for %d",
+ mss::c_str(l_ocmb));
+ }
+ }
+
+ //Done
+ FAPI_INF( "End exp_mss_eff_config_thermal");
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+} //extern C
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_eff_config_thermal.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_eff_config_thermal.H
new file mode 100644
index 000000000..bcc43f565
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_eff_config_thermal.H
@@ -0,0 +1,55 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_eff_config_thermal.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_mss_eff_config_thermal.H
+/// @brief The explorer thermal/power config
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: Memory
+#ifndef EXP_MSS_EFF_CONFIG_THERMAL_H_
+#define EXP_MSS_EFF_CONFIG_THERMAL_H_
+
+#include <fapi2.H>
+
+typedef fapi2::ReturnCode (*exp_mss_eff_config_thermal_FP_t) (const
+ std::vector< fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> >&);
+
+extern "C"
+{
+
+ ///
+ /// @brief Config the thermal/power throttle setting
+ /// @param[in] i_target vector of OCMB chip
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode exp_mss_eff_config_thermal( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> >&
+ i_targets);
+}
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_memdiag.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_memdiag.C
new file mode 100644
index 000000000..f2452efdd
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_memdiag.C
@@ -0,0 +1,71 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_memdiag.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_mss_memdiag.C
+/// @brief HW Procedure pattern testing
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include <exp_mss_memdiag.H>
+#include <lib/shared/exp_defaults.H>
+
+#include <lib/dimm/exp_rank.H>
+#include <lib/mc/exp_port.H>
+#include <lib/mcbist/exp_memdiags.H>
+#include <lib/mcbist/exp_mcbist_traits.H>
+
+extern "C"
+{
+ ///
+ /// @brief Initializes memory and sets firs
+ /// @param[in] i_target OCMB Chip
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode exp_mss_memdiag( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target )
+ {
+ uint8_t l_post_memdiags_subtest = 0;
+
+ FAPI_INF("Start exp_mss_memdiag on: %s", mss::c_str( i_target ));
+ FAPI_TRY(mss::memdiags::mss_initialize_memory(i_target));
+
+ FAPI_TRY(mss::attr::get_post_memdiags_read_subtest(i_target, l_post_memdiags_subtest));
+
+ // Perform subtest if attribute is set to
+ if (l_post_memdiags_subtest == fapi2::ENUM_ATTR_MSS_POST_MEMDIAGS_READ_SUBTEST_ENABLE)
+ {
+ FAPI_TRY(mss::exp::memdiags::perform_read_only_subtest(i_target));
+ }
+
+ fapi_try_exit:
+ FAPI_INF("End exp_mss_memdiag on %s", mss::c_str( i_target ));
+ return fapi2::current_err;
+ }
+}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_memdiag.H
index 5e8291a21..6650f2292 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_memdiag.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.H $ */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_memdiag.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -23,42 +23,30 @@
/* */
/* IBM_PROLOG_END_TAG */
+/// @file exp_mss_memdiag.H
+/// @brief Mainstore pattern testing
///
-/// @file mcbist/sim.H
-/// @brief MCBIST/memdiags functions for when we're in simulation mode
-///
-// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
-#ifndef _MSS_MCBIST_SIM_H_
-#define _MSS_MCBIST_SIM_H_
+#ifndef __EXP_MSS_MEMDIAG__
+#define __EXP_MSS_MEMDIAG__
#include <fapi2.H>
-namespace mss
-{
-
-namespace mcbist
-{
+typedef fapi2::ReturnCode (*exp_mss_memdiag_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&);
-namespace sim
+extern "C"
{
-
///
-/// @brief Perform a sim version of initializing memory
-/// @param T a fapi2::TargetType
-/// @param[in] i_target
-/// @param[in] i_pattern an index representing a pattern to use to initize memory (defaults to 0)
+/// @brief Pattern test the DRAM
+/// @param[in] i_target the memory controller of the dram you're training
/// @return FAPI2_RC_SUCCESS iff ok
///
-template< fapi2::TargetType T >
-fapi2::ReturnCode sf_init( const fapi2::Target<T>& i_target, const uint64_t i_pattern );
+ fapi2::ReturnCode exp_mss_memdiag( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target );
+}
-} // ns sim
-} // ns mcbist
-} // ns mss
#endif
-
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config_thermal.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_memdiag.mk
index 07adb9c70..32649e24e 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config_thermal.mk
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_memdiag.mk
@@ -1,11 +1,11 @@
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
-# $Source: src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config_thermal.mk $
+# $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_memdiag.mk $
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2015,2019
# [+] International Business Machines Corp.
#
#
@@ -24,8 +24,8 @@
# IBM_PROLOG_END_TAG
# Include the macros and things for MSS procedures
--include 00p9a_common.mk
+-include 00exp_common.mk
-PROCEDURE=p9a_mss_eff_config_thermal
-$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
+PROCEDURE=exp_mss_memdiag
+$(eval $(call ADD_EXP_MEMORY_INCDIRS,$(PROCEDURE)))
$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.C
new file mode 100644
index 000000000..d52ac1ba6
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.C
@@ -0,0 +1,90 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_mss_thermal_init.C
+/// @brief Procedure definition to initialize thermal sensor
+///
+// *HWP HWP Owner: Sharath Manjunath <shamanj4@in.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/find.H>
+#include <lib/exp_mss_thermal_init_utils.H>
+#include <lib/inband/exp_inband.H>
+#include <exp_mss_thermal_init.H>
+
+extern "C"
+{
+
+///
+/// @brief Initializes thermal sensor
+/// @param[in] i_target the controller target
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+ fapi2::ReturnCode exp_mss_thermal_init( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target )
+ {
+ FAPI_INF("%s Start thermal_init", mss::c_str(i_target));
+
+#if 0
+// Skip EXP_FW_TEMP_SENSOR_CONFIG_INTERVAL_READ until it's available in Explorer FW
+ // Declare variables
+ host_fw_command_struct l_cmd_sensor;
+ host_fw_response_struct l_response;
+ std::vector<uint8_t> l_rsp_data;
+
+ // Sets up EXP_FW_TEMP_SENSOR_CONFIG_INTERVAL_READ cmd params
+ mss::exp::setup_sensor_interval_read_cmd_params(l_cmd_sensor);
+
+ // Enable sensors
+ FAPI_TRY( mss::exp::ib::putCMD(i_target, l_cmd_sensor),
+ "Failed putCMD() for %s", mss::c_str(i_target) );
+
+ FAPI_TRY( mss::exp::ib::getRSP(i_target, l_response, l_rsp_data),
+ "Failed getRSP() for %s", mss::c_str(i_target) );
+
+ FAPI_TRY( mss::exp::check::sensor_response(i_target, l_response),
+ "Failed sensor_response() for %s", mss::c_str(i_target) );
+#endif
+
+#ifdef __HOSTBOOT_MODULE
+ // Prior to starting OCC, we go into "safemode" throttling
+ // After OCC is started, they can change throttles however they want
+ // We don't want to do this in Cronus mode
+ FAPI_TRY (mss::exp::mc::setup_emergency_throttles(i_target));
+#endif
+ // Clear the emergency mode throttle bit
+ FAPI_TRY (mss::exp::mc::disable_safe_mode_throttles(i_target));
+
+ FAPI_INF("%s End thermal_init", mss::c_str(i_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ fapi_try_exit:
+ FAPI_ERR("%s Error executing thermal_init", mss::c_str(i_target));
+ return fapi2::current_err;
+ }
+} //extern C
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.H
new file mode 100644
index 000000000..9ed3d1213
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.H
@@ -0,0 +1,53 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_mss_thermal_init.H
+/// @brief Procedure declaration to initialize thermal sensor
+///
+// *HWP HWP Owner: Sharath Manjunath <shamanj4@in.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#ifndef __MSS_EXP_THERMAL_INIT__
+#define __MSS_EXP_THERMAL_INIT__
+
+#include <fapi2.H>
+#include <lib/exp_mss_thermal_init_utils.H>
+
+typedef fapi2::ReturnCode (*exp_mss_thermal_init_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&);
+
+extern "C"
+{
+///
+/// @brief Initializes thermal sensor
+/// @param[in] i_target the controller target (MCS)
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+ fapi2::ReturnCode exp_mss_thermal_init( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target );
+}
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.mk
new file mode 100644
index 000000000..270920f4f
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.mk
@@ -0,0 +1,31 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_mss_thermal_init.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2018,2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+# Include the macros and things for MSS EXP procedures
+-include 00exp_common.mk
+
+PROCEDURE=exp_mss_thermal_init
+$(eval $(call ADD_EXP_MEMORY_INCDIRS,$(PROCEDURE)))
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.C
index 27b9f403a..40c253590 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -34,10 +34,13 @@
#include <exp_omi_init.H>
#include <exp_oc_regs.H>
-#include <exp_inband.H>
+#include <lib/inband/exp_inband.H>
#include <chips/common/utils/chipids.H>
#include <mss_explorer_attribute_getters.H>
#include <mss_p9a_attribute_getters.H>
+#include <generic/memory/mss_git_data_helper.H>
+#include <lib/workarounds/exp_omi_workarounds.H>
+#include <generic/memory/lib/utils/find.H>
///
/// @brief Verify we know how to talk to the connected device
@@ -55,6 +58,7 @@ fapi2::ReturnCode omiDeviceVerify(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CH
FAPI_ASSERT(l_data == ((POWER_OCID::EXPLORER << 16) | (POWER_OCID::VENDOR_IBM)),
fapi2::OCMB_IS_NOT_EXPLORER()
+ .set_OCMB_TARGET(i_target)
.set_TARGET(i_target)
.set_ID(l_data),
"Explorer ID was not found");
@@ -507,6 +511,42 @@ fapi2::ReturnCode omiSetACTagPASIDMetaData(const fapi2::Target<fapi2::TARGET_TYP
l_meta_data_ena,
"Metadata requested but not supported", l_meta_data_ena));
+ // If we plan on enabling metadata, make sure either upstream templates 5 or 9 are enabled
+ if (l_meta_data_ena)
+ {
+ uint8_t l_enable_template_5 = 0;
+ uint8_t l_enable_template_9 = 0;
+ uint8_t l_enable_template_4 = 0;
+
+ const auto& l_mcc = mss::find_target<fapi2::TARGET_TYPE_MCC>(i_target);
+
+ FAPI_TRY(mss::attr::get_explr_enable_us_tmpl_5(i_target, l_enable_template_5));
+ FAPI_TRY(mss::attr::get_explr_enable_us_tmpl_9(i_target, l_enable_template_9));
+
+ FAPI_ASSERT((l_enable_template_5 == fapi2::ENUM_ATTR_EXPLR_ENABLE_US_TMPL_5_ENABLED) ||
+ (l_enable_template_9 == fapi2::ENUM_ATTR_EXPLR_ENABLE_US_TMPL_9_ENABLED),
+ fapi2::METADATA_ENABLE_REQUIRES_TEMPLATE_5_OR_9()
+ .set_TARGET(i_target)
+ .set_TMPL_5(l_enable_template_5)
+ .set_TMPL_9(l_enable_template_9),
+ "%s METADATA_ENABLE requires upstream template either 5 or 9 to be set. "
+ "TMPL_5: %u TMPL_9: %u",
+ mss::c_str(i_target),
+ l_enable_template_5,
+ l_enable_template_9)
+
+ // Check for downstream template 4 as well. We won't bomb out here, just have an error printout if not enabled
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_ENABLE_DL_TMPL_4, l_mcc, l_enable_template_4),
+ "Error from FAPI_ATTR_GET (ATTR_PROC_ENABLE_DL_TMPL_4)");
+
+ if (l_enable_template_4 != fapi2::ENUM_ATTR_PROC_ENABLE_DL_TMPL_4_ENABLED)
+ {
+ FAPI_ERR("%s Expected MCC %s TMPL_4 to be enabled for metadata enabling. Was not enabled: may be incorrectly configured",
+ mss::c_str(i_target),
+ mss::c_str(l_mcc));
+ }
+ }
+
l_value.insertFromRight<EXPLR_OC_OCTRLPID_MSB_METADATA_ENABLED,
EXPLR_OC_OCTRLPID_MSB_METADATA_ENABLED_LEN>
(l_meta_data_ena);
@@ -602,7 +642,10 @@ fapi_try_exit:
///
fapi2::ReturnCode exp_omi_init(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
{
+ mss::display_git_commit_info("exp_omi_init");
+
FAPI_DBG("Start");
+ FAPI_TRY(mss::exp::workarounds::omi::gem_setup_config(i_target));
FAPI_TRY(omiDeviceVerify(i_target));
FAPI_TRY(omiSetUpstreamTemplates(i_target));
FAPI_TRY(omiValidateDownstream(i_target));
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.mk
index 7458548da..ff0e0a5ff 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.mk
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_init.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -25,8 +25,6 @@
# Makefile for exp_omi_init HWP
PROCEDURE=exp_omi_init
$(eval $(call ADD_EXP_MEMORY_INCDIRS,$(PROCEDURE)))
-lib$(PROCEDURE)_DEPLIBS+=mss_generic
-lib$(PROCEDURE)_DEPLIBS+=exp_inband
$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/ocmb/explorer/common/include)
$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/ocmb/explorer/common/inband)
$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/p9/procedures/hwp/nest)
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C
index e17271c93..ac783f35b 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C
@@ -34,9 +34,16 @@
// *HWP Consumed by: Memory
#include <fapi2.H>
+#include <exp_omi_setup.H>
#include <generic/memory/lib/utils/c_str.H>
#include <lib/exp_attribute_accessors_manual.H>
#include <lib/omi/exp_omi_utils.H>
+#include <lib/workarounds/exp_omi_workarounds.H>
+#include <lib/i2c/exp_i2c.H>
+#include <generic/memory/mss_git_data_helper.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
+#include <generic/memory/lib/mss_generic_system_attribute_getters.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
extern "C"
{
@@ -48,29 +55,79 @@ extern "C"
///
fapi2::ReturnCode exp_omi_setup( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
{
+ mss::display_git_commit_info("exp_omi_setup");
+ uint8_t l_gem_menterp_workaround = 0;
+
// Declares variables
- fapi2::buffer<uint64_t> l_data;
- bool l_is_enterprise = false;
- bool l_is_half_dimm = false;
+ std::vector<uint8_t> l_boot_config_data;
+
+ // BOOT CONFIG 0
+ uint8_t l_dl_layer_boot_mode = fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_DL_LAYER_BOOT_MODE_NON_DL_TRAINING;
+
+ // Gets the data setup
+ FAPI_TRY(mss::exp::omi::train::setup_fw_boot_config(i_target, l_boot_config_data));
+
+ // Sanity check: set dl_layer_boot_mode to NON DL TRAINING (0b00 == default)
+ FAPI_TRY(mss::exp::i2c::boot_cfg::set_dl_layer_boot_mode( i_target, l_boot_config_data, l_dl_layer_boot_mode ));
+
+ // Issues the command and checks for completion
+ // Note: This does not kick off OMI training
+ FAPI_TRY(mss::exp::i2c::boot_config(i_target, l_boot_config_data));
+
+ // Check FW status for success
+ FAPI_TRY(mss::exp::i2c::fw_status(i_target, mss::DELAY_1MS, 100));
+
+ FAPI_TRY(mss::exp::workarounds::omi::gem_menterp(i_target, l_gem_menterp_workaround));
+
+ // If no workaround (explorer), we can perform menterp reads/writes
+ // If workaround (gemini). we need to bypass menterp. Can also bypass dlx_config1 too since it's a noop
+ if (l_gem_menterp_workaround)
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Set up DLX_CONFIG1
+ {
+ fapi2::buffer<uint64_t> l_data;
+ fapi2::buffer<uint64_t> l_dlx_config1_data;
+
+ uint8_t l_edpl_disable = 0;
+ uint8_t l_enterprise_attr = 0;
+ bool l_is_half_dimm = false;
+ bool l_is_enterprise = false;
+
+ // Gets the configuration information from attributes
+ FAPI_TRY(mss::attr::get_ocmb_enterprise_mode(i_target, l_enterprise_attr));
+ l_is_enterprise = (l_enterprise_attr == fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_MODE_ENTERPRISE);
+
+ FAPI_TRY(mss::half_dimm_mode(i_target, l_is_enterprise, l_is_half_dimm));
+ FAPI_TRY(mss::attr::get_mss_omi_edpl_disable(l_edpl_disable));
+
+ // Prints out the data
+ FAPI_INF("%s is %s enterprise mode, and %s-DIMM mode", mss::c_str(i_target), l_is_enterprise ? "" : "non",
+ l_is_half_dimm ? "half" : "full");
- // Gets the configuration information from attributes
- FAPI_TRY(mss::enterprise_mode(i_target, l_is_enterprise));
- FAPI_TRY(mss::half_dimm_mode(i_target, l_is_half_dimm));
+ // Sets up the register
+ mss::exp::omi::set_enterprise_set_bit(l_data, l_is_enterprise);
+ mss::exp::omi::set_half_dimm_mode(l_data, l_is_half_dimm);
- // Prints out the data
- FAPI_INF("%s %s enterprise mode %s-DIMM mode", mss::c_str(i_target), l_is_enterprise ? "is" : "isn't",
- l_is_half_dimm ? "half" : "full");
+ // Writes the data to the register
+ FAPI_TRY(mss::exp::omi::write_enterprise_config(i_target, l_data));
- // Sets up the register
- mss::exp::omi::set_enterprise_set_bit(l_data, l_is_enterprise);
- mss::exp::omi::set_half_dimm_mode(l_data, l_is_half_dimm);
+ // Checks that the chip is configured correctly
+ FAPI_TRY(mss::exp::omi::read_enterprise_config(i_target, l_data));
+ FAPI_TRY(mss::exp::omi::check_enterprise_mode(i_target, l_is_enterprise, l_data));
- // Writes the data to the register
- FAPI_TRY(mss::exp::omi::write_enterprise_config(i_target, l_data));
+ // Set the EDPL according the attribute
+ FAPI_TRY(mss::exp::omi::read_dlx_config1(i_target, l_dlx_config1_data));
+ mss::exp::omi::set_edpl_enable_bit(l_dlx_config1_data, !l_edpl_disable);
+ FAPI_TRY(mss::exp::omi::write_dlx_config1(i_target, l_dlx_config1_data));
+ FAPI_INF("%s EDPL enable: %s", mss::c_str(i_target), l_edpl_disable ? "false" : "true");
+ }
- // Checks that the chip is configured correctly
- FAPI_TRY(mss::exp::omi::read_enterprise_config(i_target, l_data));
- FAPI_TRY(mss::exp::omi::check_enterprise_mode(i_target, l_is_enterprise, l_data));
+ // Perform p9a workaround
+ // Train mode 6 (state 3)
+ FAPI_TRY(mss::exp::workarounds::omi::pre_training_prbs(i_target));
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train.C
index 2865af091..0e21e87ef 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,7 +37,12 @@
#include <generic/memory/lib/utils/c_str.H>
#include <lib/omi/exp_omi_utils.H>
#include <lib/i2c/exp_i2c.H>
+#include <lib/exp_attribute_accessors_manual.H>
+#include <lib/workarounds/exp_omi_workarounds.H>
#include <exp_omi_train.H>
+#include <generic/memory/mss_git_data_helper.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
extern "C"
{
@@ -49,14 +54,43 @@ extern "C"
///
fapi2::ReturnCode exp_omi_train(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
{
- std::vector<uint8_t> l_data;
+ mss::display_git_commit_info("exp_omi_train");
- // Gets the data setup
- FAPI_TRY(mss::exp::omi::train::setup_fw_boot_config(i_target, l_data));
+ // Perform p9a workaround
+ // Train mode 1 (PATTERN_A)
+ FAPI_TRY(mss::exp::workarounds::omi::training_prbs(i_target));
- // Issues the command and checks for completion
- // Note: the status check also checks for the OMI training completion, so after we run this command, we're good to go
- FAPI_TRY(mss::exp::i2c::boot_config(i_target, l_data));
+ // BOOT CONFIG 1
+ {
+ bool l_ocmb_is_explorer = false;
+
+ std::vector<uint8_t> l_data;
+ uint8_t l_dl_layer_boot_mode = fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_DL_LAYER_BOOT_MODE_ONLY_DL_TRAINING;
+
+ // Gets the data setup
+ FAPI_TRY(mss::exp::omi::train::setup_fw_boot_config(i_target, l_data));
+
+ // Sets DL_TRAIN field
+ FAPI_TRY(mss::exp::i2c::boot_cfg::set_dl_layer_boot_mode( i_target, l_data, l_dl_layer_boot_mode ));
+
+ // Issues the command and checks for completion
+ FAPI_TRY(mss::exp::i2c::boot_config(i_target, l_data));
+
+ // Check for expected busy status (this won't work for gemini)
+ FAPI_TRY(mss::exp::workarounds::omi::ocmb_is_explorer(i_target, l_ocmb_is_explorer));
+
+ if (l_ocmb_is_explorer)
+ {
+ // Explorer & P9A environment should see a busy status until auto train is kicked off from both sides
+ FAPI_TRY(mss::exp::i2c::check_fw_status_busy(i_target));
+ }
+ else
+ {
+ // Gemini should return success code
+ FAPI_TRY(mss::exp::i2c::fw_status(i_target, mss::DELAY_1MS, 100));
+ }
+
+ }
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.C
new file mode 100644
index 000000000..08b4247bf
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.C
@@ -0,0 +1,141 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+/// @file exp_omi_train_check.C
+/// @brief Check that omi training was successful from explorer side
+///
+/// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+/// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+/// *HWP Team: Memory
+/// *HWP Level: 2
+/// *HWP Consumed by: HB
+
+#include <fapi2.H>
+#include <exp_omi_train_check.H>
+#include <lib/omi/exp_omi_utils.H>
+#include <generic/memory/mss_git_data_helper.H>
+#include <lib/shared/exp_consts.H>
+#include <generic/memory/lib/utils/find.H>
+#include <lib/i2c/exp_i2c.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
+///
+/// @brief Check that the OCMB's omi state machine is in its expected state after OMI training
+/// @param[in] i_target the OCMB target to check
+/// @return FAPI2_RC_SUCCESS iff ok
+/// @note the functionality of this procedure was made to match that of p9a_omi_train_check
+///
+fapi2::ReturnCode exp_omi_train_check(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ mss::display_git_commit_info("exp_omi_train_check");
+
+ FAPI_INF("%s Start exp_omi_train_check", mss::c_str(i_target));
+
+ // Const
+ constexpr uint8_t STATE_MACHINE_SUCCESS = 0b111; // This value is from Lonny Lambrecht
+ constexpr uint8_t MAX_LOOP_COUNT = 10; // Retry times
+ const auto& l_omi = mss::find_target<fapi2::TARGET_TYPE_OMI>(i_target);
+ const auto& l_proc = mss::find_target<fapi2::TARGET_TYPE_PROC_CHIP>(i_target);
+
+ // Declares variables
+ fapi2::buffer<uint64_t> l_omi_status;
+ fapi2::buffer<uint64_t> l_omi_training_status;
+ fapi2::buffer<uint64_t> l_dl0_error_hold;
+ fapi2::buffer<uint64_t> l_expected_dl0_error_hold;
+ fapi2::buffer<uint64_t> l_dl0_config1;
+ uint8_t l_state_machine_state = 0;
+ uint8_t l_tries = 0;
+ uint32_t l_omi_freq = 0;
+
+ do
+ {
+ // Delay
+ fapi2::delay(500 * mss::DELAY_1MS, 10 * mss::DELAY_1MS);
+
+ // Check OMI training status
+ FAPI_TRY(mss::exp::omi::train::omi_train_status(i_target, l_state_machine_state, l_omi_status));
+ l_tries++;
+
+ }
+ while (l_tries < MAX_LOOP_COUNT && l_state_machine_state != STATE_MACHINE_SUCCESS);
+
+ // Note: this is very useful debug information while trying to debug training during polling
+ FAPI_TRY(fapi2::getScom(i_target, EXPLR_DLX_DL0_TRAINING_STATUS, l_omi_training_status));
+ FAPI_TRY(fapi2::getScom(i_target, EXPLR_DLX_DL0_CONFIG1, l_dl0_config1));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FREQ_OMI_MHZ, l_proc, l_omi_freq));
+
+
+ FAPI_ASSERT(l_state_machine_state == STATE_MACHINE_SUCCESS,
+ fapi2::EXP_OMI_TRAIN_ERR()
+ .set_OCMB_TARGET(i_target)
+ .set_OMI_TARGET(l_omi)
+ .set_EXPECTED_SM_STATE(STATE_MACHINE_SUCCESS)
+ .set_ACTUAL_SM_STATE(l_state_machine_state)
+ .set_DL0_STATUS(l_omi_status)
+ .set_DL0_TRAINING_STATUS(l_omi_training_status)
+ .set_DL0_CONFIG1(l_dl0_config1)
+ .set_OMI_FREQ(l_omi_freq),
+ "%s EXP OMI Training Failure, expected state:%d/actual state:%d, DL0_STATUS:0x%016llx, DL0_TRAINING_STATUS:0x%016llx",
+ mss::c_str(i_target),
+ STATE_MACHINE_SUCCESS,
+ l_state_machine_state,
+ l_omi_status,
+ l_omi_training_status
+ );
+
+ // Finally, make sure fw_status is good
+ FAPI_TRY(mss::exp::i2c::fw_status(i_target, mss::common_timings::DELAY_1MS, 100));
+
+ // Check for errors in ERROR_HOLD until we get a proper FIR API setup
+ FAPI_TRY(fapi2::getScom(i_target, EXPLR_DLX_DL0_ERROR_HOLD, l_dl0_error_hold));
+
+ // Training done bit
+ l_expected_dl0_error_hold.setBit<EXPLR_DLX_DL0_ERROR_HOLD_CERR_39>();
+
+ if (l_dl0_error_hold != l_expected_dl0_error_hold)
+ {
+ // To get to this point, we had to have completed training, so these errors are not catastrophic
+ // We don't need to assert out, but let's make sure we print them out
+ FAPI_INF("%s EXPLR_DLX_DL0_ERROR_HOLD REG 0x%016llx "
+ "did not match expected value. REG contents: 0x%016llx Expected: 0x%016llx",
+ mss::c_str(i_target),
+ EXPLR_DLX_DL0_ERROR_HOLD,
+ l_dl0_error_hold,
+ l_expected_dl0_error_hold);
+ }
+
+ FAPI_DBG("%s End exp_omi_train_check, expected state:%d/actual state:%d, DL0_STATUS:0x%016llx, DL0_TRAINING_STATUS:0x%016llx",
+ mss::c_str(i_target),
+ STATE_MACHINE_SUCCESS,
+ l_state_machine_state,
+ l_omi_status,
+ l_omi_training_status);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}// exp_omi_train_check
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.H
new file mode 100644
index 000000000..0adb51ce9
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.H
@@ -0,0 +1,53 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+/// @file exp_omi_train_check.C
+/// @brief Check that omi training was successful from explorer side
+///
+/// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+/// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+/// *HWP Team: Memory
+/// *HWP Level: 2
+/// *HWP Consumed by: HB
+
+#ifndef _EXP_OMI_TRAIN_CHECK_H_
+#define _EXP_OMI_TRAIN_CHECK_H_
+
+#include <fapi2.H>
+
+typedef fapi2::ReturnCode (*exp_omi_train_check_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&);
+
+extern "C"
+{
+
+ ///
+ /// @brief Check that the OCMB's omi state machine is in its expected state after OMI training
+ /// @param[in] i_target the OCMB target to check
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode exp_omi_train_check(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+}
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_config_thermal.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.mk
index 22abeb618..93566fadd 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_config_thermal.mk
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.mk
@@ -1,7 +1,7 @@
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
-# $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_config_thermal.mk $
+# $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.mk $
#
# OpenPOWER HostBoot Project
#
@@ -22,3 +22,8 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+-include 00exp_common.mk
+
+PROCEDURE=exp_omi_train_check
+$(eval $(call ADD_EXP_MEMORY_INCDIRS,$(PROCEDURE)))
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scominit.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scominit.C
index 3c6767a94..e3e01d788 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scominit.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scominit.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,6 +38,7 @@
#include <generic/memory/lib/utils/count_dimm.H>
#include <generic/memory/lib/utils/find.H>
#include <explorer_scom.H>
+#include <generic/memory/mss_git_data_helper.H>
extern "C"
{
@@ -49,6 +50,8 @@ extern "C"
///
fapi2::ReturnCode exp_scominit( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
{
+ mss::display_git_commit_info("exp_scominit");
+
if (mss::count_dimm(i_target) == 0)
{
FAPI_INF("... skipping mss_scominit %s - no DIMM ...", mss::c_str(i_target));
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.C
index 6f6ee8caf..ca588d8d2 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,41 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_scrub.C
+/// @brief Begin background scrub
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#include <lib/shared/exp_defaults.H>
+#include <exp_scrub.H>
+#include <lib/utils/mss_exp_conversions.H>
+#include <lib/mcbist/exp_memdiags.H>
+
+extern "C"
+{
+
+ ///
+ /// @brief Begin background scrub
+ /// @param[in] i_target OCMB chip
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode exp_scrub(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+ {
+ FAPI_INF("Start exp scrub for %s", mss::c_str(i_target));
+ // Initialize memory and set firs accordingly
+ FAPI_TRY(mss::memdiags::mss_initialize_memory(i_target));
+ // Kickoff background scrub and unmask firs
+ FAPI_TRY(mss::memdiags::mss_background_scrub_helper(i_target));
+
+ fapi_try_exit:
+ FAPI_INF("End exp scrub for %s", mss::c_str(i_target));
+ return fapi2::current_err;
+ }
+
+}
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.H
index d3e650254..73affcb60 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.H
@@ -22,3 +22,34 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_scrub.H
+/// @brief Procedure declaration to begin background scrub
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#ifndef __MSS_EXP_SCRUB__
+#define __MSS_EXP_SCRUB__
+
+#include <fapi2.H>
+
+// Required for Cronus
+typedef fapi2::ReturnCode (*exp_scrub_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&);
+
+extern "C"
+{
+
+ ///
+ /// @brief Begin background scrub
+ /// @param[in] i_target the controller
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode exp_scrub(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+
+}// extern C
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.mk
index ef1c8a17d..9067611e3 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.mk
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_scrub.mk
@@ -22,3 +22,10 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+
+# Include the macros and things for MSS EXP procedures
+-include 00exp_common.mk
+
+PROCEDURE=exp_scrub
+$(eval $(call ADD_EXP_MEMORY_INCDIRS,$(PROCEDURE)))
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_explorer.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_explorer.C
new file mode 100644
index 000000000..26855282e
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_explorer.C
@@ -0,0 +1,166 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_explorer.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file ccs_explorer.C
+/// @brief Run and manage the CCS engine
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+
+#include <lib/shared/exp_defaults.H>
+#include <lib/ccs/ccs_traits_explorer.H>
+#include <generic/memory/lib/ccs/ccs.H>
+#include <lib/ccs/ccs_explorer.H>
+#include <lib/utils/mss_exp_conversions.H>
+
+// Generates linkage
+constexpr std::pair<uint64_t, uint64_t> ccsTraits<mss::mc_type::EXPLORER>::CS_N[];
+constexpr std::pair<uint64_t, uint64_t> ccsTraits<mss::mc_type::EXPLORER>::CS_ND[];
+
+namespace mss
+{
+namespace ccs
+{
+
+///
+/// @brief Cleans up from a CCS execution - multiple ports - EXPLORER specialization
+/// @param[in] i_program the vector of instructions
+/// @param[in] i_ports the vector of ports
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template<>
+fapi2::ReturnCode cleanup_from_execute<fapi2::TARGET_TYPE_MEM_PORT, mss::mc_type::EXPLORER>
+(const ccs::program& i_program,
+ const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> >& i_ports)
+{
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+///
+/// @brief Determine the CCS failure type
+/// @param[in] i_target OCMB target
+/// @param[in] i_type the failure type
+/// @param[in] i_port The port the CCS instruction is training
+/// @return ReturnCode associated with the fail.
+/// @note FFDC is handled here, caller doesn't need to do it
+///
+template<>
+fapi2::ReturnCode fail_type( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint64_t i_type,
+ const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_port )
+{
+ typedef ccsTraits<mss::mc_type::EXPLORER> TT;
+
+ // Including the PORT_TARGET here and below at CAL_TIMEOUT since these problems likely lie at the MCA level
+ // So we disable the PORT and hopefully that's it
+ // If the problem lies with the MCBIST, it'll just have to loop
+ FAPI_ASSERT(TT::STAT_READ_MISCOMPARE != i_type,
+ fapi2::MSS_EXP_CCS_READ_MISCOMPARE()
+ .set_MC_TARGET(i_target)
+ .set_FAIL_TYPE(i_type)
+ .set_PORT_TARGET(i_port),
+ "%s CCS FAIL Read Miscompare", mss::c_str(i_port));
+
+ // This error is likely due to a bad CCS engine/ MCBIST
+ FAPI_ASSERT(TT::STAT_UE_SUE != i_type,
+ fapi2::MSS_EXP_CCS_UE_SUE()
+ .set_FAIL_TYPE(i_type)
+ .set_MC_TARGET(i_target),
+ "%s CCS FAIL UE or SUE Error", mss::c_str(i_target));
+
+ // Problem with the CCS engine
+ FAPI_ASSERT(TT::STAT_HUNG != i_type,
+ fapi2::MSS_EXP_CCS_HUNG().set_MC_TARGET(i_target),
+ "%s CCS appears hung", mss::c_str(i_target));
+fapi_try_exit:
+ // Due to the PRD update, we need to check for FIR's
+ // If any FIR's have lit up, this CCS fail could have been caused by the FIR
+ // So, let PRD retrigger this step to see if we can resolve the issue
+ return mss::check::fir_or_pll_fail<mss::mc_type::EXPLORER>(i_target, fapi2::current_err);
+}
+
+///
+/// @brief EXP specialization for modeq_copy_cke_to_spare_cke
+/// @param[in] fapi2::Target<TARGET_TYPE_OCMB_CHIP>& the target to effect
+/// @param[in,out] the buffer representing the mode register
+/// @param[in] mss::states - mss::ON iff Copy CKE signals to CKE Spare on both ports
+/// @note no-op for p9n
+///
+template<>
+void copy_cke_to_spare_cke<fapi2::TARGET_TYPE_OCMB_CHIP>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&,
+ fapi2::buffer<uint64_t>&, states )
+{
+ return;
+}
+
+///
+/// @brief Updates the initial delays based upon the total delays passed in - EXP specialization
+/// @param[in] i_target the target type on which to operate
+/// @param[in] i_delay the calculated delays from CCS
+/// @param[in,out] io_program the program for which to update the delays
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template<>
+fapi2::ReturnCode update_initial_delays<fapi2::TARGET_TYPE_OCMB_CHIP, mss::mc_type::EXPLORER>
+( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint64_t i_delay,
+ ccs::program& io_program)
+{
+ // Check our program for any delays. If there isn't a iv_initial_delay configured, then
+ // we use the delay we just summed from the instructions.
+ if (io_program.iv_poll.iv_initial_delay == 0)
+ {
+ io_program.iv_poll.iv_initial_delay = cycles_to_ns(i_target, i_delay);
+ }
+
+ if (io_program.iv_poll.iv_initial_sim_delay == 0)
+ {
+ io_program.iv_poll.iv_initial_sim_delay = cycles_to_simcycles(i_delay);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+///
+/// @brief Select the port(s) to be used by the CCS - EXPLORER specialization
+/// @param[in] i_target the target to effect
+/// @param[in] i_ports the buffer representing the ports
+///
+template<>
+fapi2::ReturnCode select_ports<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ uint64_t i_ports)
+{
+ // No broadcast mode, only one port, so no port selection
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+} // namespace ccs
+} // namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/num.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_explorer.H
index 051aa214b..e02292508 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/num.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_explorer.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/utils/num.H $ */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_explorer.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -24,32 +24,30 @@
/* IBM_PROLOG_END_TAG */
///
-/// @file num.H
-/// @brief Miscellaneous number checking functions
+/// @file ccs_explorer.H
+/// @brief Run and manage the CCS engine
///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
-// *HWP Consumed by: HB:FSP
+// *HWP Consumed by: FSP:HB
-#ifndef _MSS_NUM_H_
-#define _MSS_NUM_H_
+#ifndef _MSS_CCS_EXPLORER_H_
+#define _MSS_CCS_EXPLORER_H_
+
+#include <fapi2.H>
+#include <lib/ccs/ccs_traits_explorer.H>
+#include <generic/memory/lib/ccs/ccs.H>
namespace mss
{
-
-///
-/// @brief Return whether or not a number is odd
-/// @param[in] i_number the number to check
-/// @return true if i_number is odd
-///
-template< typename T >
-constexpr bool is_odd(const T i_number)
+namespace ccs
{
- return (i_number & 0x1);
-}
+// This file ties the two needed header files together
+
+} // namespace ccs
+} // namespace mss
-}
#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_traits_explorer.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_traits_explorer.H
new file mode 100644
index 000000000..3411a677c
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_traits_explorer.H
@@ -0,0 +1,260 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ccs/ccs_traits_explorer.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file ccs_traits_nimbus.H
+/// @brief Run and manage the CCS engine
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_CCS_TRAITS_EXP_H_
+#define _MSS_CCS_TRAITS_EXP_H_
+
+#include <fapi2.H>
+#include <explorer_scom_addresses.H>
+#include <explorer_scom_addresses_fld.H>
+#include <lib/shared/exp_consts.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
+#include <generic/memory/lib/ccs/ccs_traits.H>
+
+///
+/// @class ccsTraits
+/// @brief Explorer CCS Engine traits
+///
+template<>
+class ccsTraits<mss::mc_type::EXPLORER>
+{
+ public:
+ static constexpr fapi2::TargetType PORT_TARGET_TYPE = fapi2::TARGET_TYPE_MEM_PORT;
+ static constexpr uint64_t MODEQ_REG = EXPLR_MCBIST_CCS_MODEQ;
+ static constexpr uint64_t MCB_CNTL_REG = EXPLR_MCBIST_MCB_CNTLQ;
+ static constexpr uint64_t CNTLQ_REG = EXPLR_MCBIST_CCS_CNTLQ;
+ static constexpr uint64_t STATQ_REG = EXPLR_MCBIST_CCS_STATQ;
+
+ static constexpr uint64_t PORTS_PER_MC_TARGET = mss::exp::MAX_PORT_PER_OCMB;
+ static constexpr uint64_t CCS_MAX_DIMM_PER_PORT = mss::exp::MAX_DIMM_PER_PORT;
+ static constexpr uint64_t CCS_MAX_MRANK_PER_PORT = mss::exp::MAX_MRANK_PER_PORT;
+ static constexpr uint64_t CCS_MAX_RANK_PER_DIMM = mss::exp::MAX_RANK_PER_DIMM;
+ static constexpr uint64_t CCS_MAX_RANKS_DIMM1 = mss::exp::MAX_RANKS_DIMM1;
+
+ static constexpr uint64_t NTTM_READ_DELAY = 0x40;
+ static constexpr uint64_t NTTM_MODE_FORCE_READ = 33;
+
+
+ // Command Pass Disable Delay Time for Explorer - really a JEDEC timing
+ static constexpr uint64_t TIMING_TCPDED = 4;
+
+ enum
+ {
+ // Non address values that are needed for helper functions
+
+ // ODT values used for beautification
+ // Attribute locations
+ ATTR_ODT_DIMM0_R0 = 0,
+ ATTR_ODT_DIMM0_R1 = 1,
+ ATTR_ODT_DIMM1_R0 = 4,
+ ATTR_ODT_DIMM1_R1 = 5,
+
+ // Right justified output - makes it so we can use insertFromRight
+ CCS_ODT_DIMM0_R0 = 4,
+ CCS_ODT_DIMM0_R1 = 5,
+ CCS_ODT_DIMM1_R0 = 6,
+ CCS_ODT_DIMM1_R1 = 7,
+
+ // Default ODT cycle length is 5 - one for the preamble and 4 for the data
+ DEFAULT_ODT_CYCLE_LEN = 5,
+
+ // CCS MODEQ
+ STOP_ON_ERR = EXPLR_MCBIST_CCS_MODEQ_STOP_ON_ERR,
+ UE_DISABLE = EXPLR_MCBIST_CCS_MODEQ_UE_DISABLE,
+ DATA_COMPARE_BURST_SEL = EXPLR_MCBIST_CCS_MODEQ_DATA_COMPARE_BURST_SEL,
+ DATA_COMPARE_BURST_SEL_LEN = EXPLR_MCBIST_CCS_MODEQ_DATA_COMPARE_BURST_SEL_LEN,
+ CFG_PARITY_AFTER_CMD = EXPLR_MCBIST_CCS_MODEQ_CFG_PARITY_AFTER_CMD,
+ COPY_CKE_TO_SPARE_CKE = EXPLR_MCBIST_CCS_MODEQ_COPY_CKE_TO_SPARE_CKE,
+ DISABLE_ECC_ARRAY_CHK = EXPLR_MCBIST_CCS_MODEQ_DISABLE_ECC_ARRAY_CHK,
+ DISABLE_ECC_ARRAY_CORRECTION = EXPLR_MCBIST_CCS_MODEQ_DISABLE_ECC_ARRAY_CORRECTION,
+ CFG_DGEN_FIXED_MODE = EXPLR_MCBIST_CCS_MODEQ_CFG_DGEN_FIXED_MODE,
+ IDLE_PAT_ADDRESS_0_13 = EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_0_13,
+ IDLE_PAT_ADDRESS_0_13_LEN = EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_0_13_LEN,
+ IDLE_PAT_ADDRESS_17 = EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_17,
+ IDLE_PAT_BANK_GROUP_1 = EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_GROUP_1,
+ IDLE_PAT_BANK_0_1 = EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_0_1,
+ IDLE_PAT_BANK_0_1_LEN = EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_0_1_LEN,
+ IDLE_PAT_BANK_GROUP_0 = EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_GROUP_0,
+ IDLE_PAT_ACTN = EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ACTN,
+ IDLE_PAT_ADDRESS_16 = EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_16,
+ IDLE_PAT_ADDRESS_15 = EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_15,
+ IDLE_PAT_ADDRESS_14 = EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_14,
+ NTTM_MODE = EXPLR_MCBIST_CCS_MODEQ_NTTM_MODE,
+ NTTM_RW_DATA_DLY = EXPLR_MCBIST_CCS_MODEQ_NTTM_RW_DATA_DLY,
+ NTTM_RW_DATA_DLY_LEN = EXPLR_MCBIST_CCS_MODEQ_NTTM_RW_DATA_DLY_LEN,
+ IDLE_PAT_BANK_2 = EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_BANK_2,
+ DDR_PARITY_ENABLE = EXPLR_MCBIST_CCS_MODEQ_DDR_PARITY_ENABLE,
+ IDLE_PAT_PARITY = EXPLR_MCBIST_CCS_MODEQ_IDLE_PAT_PARITY,
+
+ // CCS CNTL
+ CCS_START = EXPLR_MCBIST_CCS_CNTLQ_START,
+ CCS_STOP = EXPLR_MCBIST_CCS_CNTLQ_STOP,
+
+ // CCS STATQ
+ CCS_IN_PROGRESS = EXPLR_MCBIST_CCS_STATQ_IP,
+
+ // ARR0
+ ARR0_DDR_ADDRESS_0_13 = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13,
+ ARR0_DDR_ADDRESS_0_13_LEN = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13_LEN,
+ ARR0_DDR_ADDRESS_0_9 = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13, // Useful for rd/wr cmds
+ ARR0_DDR_ADDRESS_0_9_LEN = 10, // CA bits are 9:0, total length of 10
+ ARR0_DDR_ADDRESS_10 = 10, // ADR10 is the 10th bit from the left in Nimbus ARR0
+ ARR0_DDR_ADDRESS_17 = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_17,
+ ARR0_DDR_BANK_GROUP_1 = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_GROUP_1,
+ ARR0_DDR_RESETN = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_RESETN,
+ ARR0_DDR_BANK_0_1 = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_0_1,
+ ARR0_DDR_BANK_0_1_LEN = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_0_1_LEN,
+ ARR0_DDR_BANK_GROUP_0 = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_GROUP_0,
+ ARR0_DDR_ACTN = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ACTN,
+ ARR0_DDR_ADDRESS_16 = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_16,
+ ARR0_DDR_ADDRESS_15 = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_15,
+ ARR0_DDR_ADDRESS_14 = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_14,
+ ARR0_DDR_CKE = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CKE,
+ ARR0_DDR_CKE_LEN = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CKE_LEN,
+ ARR0_DDR_CSN_0_1 = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CSN_0_1,
+ ARR0_DDR_CSN_0_1_LEN = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CSN_0_1_LEN,
+ ARR0_DDR_CID_0_1 = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CID_0_1,
+ ARR0_DDR_CID_0_1_LEN = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CID_0_1_LEN,
+ ARR0_DDR_CSN_2_3 = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CSN_2_3,
+ ARR0_DDR_CSN_2_3_LEN = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CSN_2_3_LEN,
+ ARR0_DDR_CID_2 = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_CID_2,
+ ARR0_DDR_ODT = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ODT,
+ ARR0_DDR_ODT_LEN = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_ODT_LEN,
+ ARR0_DDR_PARITY = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_PARITY,
+ ARR0_DDR_BANK_2 = EXPLR_MCBIST_CCS_INST_ARR0_00_DDR_BANK_2,
+ ARR0_LOOP_BREAK_MODE = EXPLR_MCBIST_CCS_INST_ARR0_00_LOOP_BREAK_MODE,
+ ARR0_LOOP_BREAK_MODE_LEN = EXPLR_MCBIST_CCS_INST_ARR0_00_LOOP_BREAK_MODE_LEN,
+
+ // ARR1
+ ARR1_IDLES = EXPLR_MCBIST_CCS_INST_ARR1_00_IDLES,
+ ARR1_IDLES_LEN = EXPLR_MCBIST_CCS_INST_ARR1_00_IDLES_LEN,
+ ARR1_REPEAT_CMD_CNT = EXPLR_MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT,
+ ARR1_REPEAT_CMD_CNT_LEN = EXPLR_MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT_LEN,
+ ARR1_READ_OR_WRITE_DATA = EXPLR_MCBIST_CCS_INST_ARR1_00_READ_OR_WRITE_DATA,
+ ARR1_READ_OR_WRITE_DATA_LEN = EXPLR_MCBIST_CCS_INST_ARR1_00_READ_OR_WRITE_DATA_LEN,
+ ARR1_READ_COMPARE_REQUIRED = EXPLR_MCBIST_CCS_INST_ARR1_00_READ_COMPARE_REQUIRED,
+ ARR1_END = EXPLR_MCBIST_CCS_INST_ARR1_00_END,
+ ARR1_GOTO_CMD = EXPLR_MCBIST_CCS_INST_ARR1_00_GOTO_CMD,
+ ARR1_GOTO_CMD_LEN = EXPLR_MCBIST_CCS_INST_ARR1_00_GOTO_CMD_LEN,
+
+ // CCS array constants
+ CCS_ARRAY_LEN = 32,
+ CCS_ARR0_START = EXPLR_MCBIST_CCS_INST_ARR0_00,
+ CCS_ARR1_START = EXPLR_MCBIST_CCS_INST_ARR1_00,
+ };
+
+ ///
+ /// @brief Enums for CCS return codes
+ ///
+ enum
+ {
+ // Success is defined as done-bit set, no others.
+ STAT_QUERY_SUCCESS = 0x4000000000000000,
+
+ // Bit positions 3:5
+ STAT_ERR_MASK = 0x1800000000000000,
+ STAT_READ_MISCOMPARE = 0x1000000000000000,
+ STAT_UE_SUE = 0x0800000000000000,
+
+ // If the fail type isn't one of these, we're hung
+ STAT_HUNG = 0x0ull,
+ };
+
+
+ // CSN Regular Settings
+ static constexpr std::pair<uint64_t, uint64_t> CS_N[mss::MAX_RANK_PER_DIMM] =
+ {
+ // CS0 L, CS1 H, CID0-> L => Rank 0
+ { 0b01, 0b00 },
+
+ // CS0 L, CS1 H, CID0-> H => Rank 1
+ { 0b01, 0b11 },
+
+ // CS0 H, CS1 L, CID0-> L => Rank 2
+ { 0b10, 0b00 },
+
+ // CS0 H, CS1 L, CID0-> H => Rank 3
+ { 0b10, 0b11 },
+ };
+
+
+ // CSN Setup for Dual Direct Mode
+ // For DIMM0 .first is the CSN_0_1 setting, .second is the CSN_2_3 setting.
+ // For DIMM1 .first is the CSN_2_3 setting, .second is the CSN_0_1 setting.
+ static constexpr std::pair<uint64_t, uint64_t> CS_ND[mss::MAX_RANK_PER_DIMM] =
+ {
+ // CS0 L CS1 H => CS2 => H CS3 => H Rank 0
+ { 0b01, 0b11 },
+
+ // CS0 H CS1 L => CS2 => H CS3 => H Rank 1
+ { 0b10, 0b11 },
+
+ // CS0 H CS1 H => CS2 => L CS3 => H Rank 2
+ { 0b11, 0b01 },
+
+ // CS0 H CS1 H => CS2 => H CS3 => L Rank 3
+ { 0b11, 0b10 },
+ };
+
+ ///
+ /// @brief Gets the attribute for checking our rank configuration
+ /// @param[in] i_target the port target on which to operate
+ /// @param[out] o_ranks the rank data
+ /// @return SUCCESS iff the code executes successfully
+ ///
+ static fapi2::ReturnCode get_rank_config_attr(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+ {
+ return mss::attr::get_num_master_ranks_per_dimm(i_target, o_array);
+ }
+
+ ///
+ /// @brief Gets the attribute for checking our rank configuration
+ /// @param[in] i_target the port target on which to operate
+ /// @param[out] o_ranks the rank data
+ /// @return The fully setup nimbus error
+ ///
+ static fapi2::EXP_CCS_HUNG_TRYING_TO_STOP setup_trying_to_stop_err(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
+ i_target)
+ {
+ return fapi2::EXP_CCS_HUNG_TRYING_TO_STOP().set_MC_TARGET(i_target);
+ }
+
+ // Lab values
+ static constexpr uint64_t LAB_MRS_CMD = 0x000008F000000000;
+};
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/exp_rank.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/exp_rank.H
index 781389ae3..56dc34b4f 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/exp_rank.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/exp_rank.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,127 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file exp_rank.H
+/// @brief Explorer rank definitions
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_EXP_RANK_H_
+#define _MSS_EXP_RANK_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/mss_rank.H>
+
+namespace mss
+{
+namespace rank
+{
+
+///
+/// @brief Rank traits for explorer
+///
+template <>
+class rankTraits<mss::mc_type::EXPLORER>
+{
+ public:
+ static constexpr uint8_t MAX_DIMMS_PER_PORT = 2;
+ static constexpr uint8_t MAX_RANKS_PER_DIMM = 4;
+ static constexpr uint8_t RANK_INDEX_STEP = 4;
+
+ // Note! a configuration of 2 4-rank dimms is not possible.
+ // In this hypothetical scenario, the value for phy-rank would not
+ // be valid / does not apply, as there will be some rollover.
+ static constexpr uint8_t PHY_RANK_INDEX_STEP = 2;
+};
+
+///
+/// @brief Return a vector of rank numbers which represent the primary rank pairs for this port
+/// @param[in] i_target port target on which to operate
+/// @param[out] o_ranks a vector of ranks
+/// @return FAPI@_RC_SUCCESS iff all is ok
+inline fapi2::ReturnCode primary_ranks( const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ std::vector< uint64_t >& o_rps )
+{
+ o_rps.clear();
+ std::vector<mss::rank::info<mss::mc_type::EXPLORER>> l_rank_info_vect;
+ FAPI_TRY(mss::rank::ranks_on_port<mss::mc_type::EXPLORER>(i_target, l_rank_info_vect));
+
+ // Loop through and assemble the ranks
+ for(const auto& l_rank_info : l_rank_info_vect)
+ {
+ o_rps.push_back(l_rank_info.get_port_rank());
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Return a vector of rank numbers which represent the primary rank pairs for this dimm
+/// @param[in] i_target DIMM target on which to operate
+/// @param[out] o_ranks a vector of ranks
+/// @return FAPI@_RC_SUCCESS iff all is ok
+inline fapi2::ReturnCode primary_ranks( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ std::vector< uint64_t >& o_rps )
+{
+ o_rps.clear();
+ std::vector<mss::rank::info<mss::mc_type::EXPLORER>> l_rank_info_vect;
+ FAPI_TRY(mss::rank::ranks_on_dimm<mss::mc_type::EXPLORER>(i_target, l_rank_info_vect));
+
+ // Loop through and assemble the ranks
+ for(const auto& l_rank_info : l_rank_info_vect)
+ {
+ o_rps.push_back(l_rank_info.get_port_rank());
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Return the *port relative position* of the DIMM which posesses this rank
+/// @param[in] i_rank the rank number.
+/// @return the relative position of the DIMM which contains this rank.
+inline size_t get_dimm_from_rank(const uint64_t i_rank)
+{
+ using TT = rankTraits<mss::mc_type::EXPLORER>;
+ return i_rank / TT::MAX_RANKS_PER_DIMM;
+}
+
+///
+/// @brief Return a vector of rank numbers which represent the ranks for this dimm
+/// @param[in] i_dimm_target TARGET_TYPE_DIMM
+/// @param[out] o_ranks a vector of ranks for dimm (numbers)
+/// @return FAPI2_RC_SUCCESS iff all is ok
+///
+template<>
+inline fapi2::ReturnCode ranks_on_dimm_helper<mss::mc_type::EXPLORER>(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&
+ i_dimm_target,
+ std::vector<uint64_t>& o_ranks)
+{
+ std::vector<uint64_t> l_ranks;
+ std::vector<mss::rank::info<>> l_vect;
+
+ FAPI_TRY( mss::rank::ranks_on_dimm<mss::mc_type::EXPLORER>(i_dimm_target, l_vect) );
+
+ // Loop through and get ranks or each
+ for (const auto l_rank_info : l_vect)
+ {
+ l_ranks.push_back( l_rank_info.get_dimm_rank() );
+ }
+
+ o_ranks = l_ranks;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+} // namespace rank
+} // namespace mss
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/ecc_traits_explorer.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/ecc_traits_explorer.C
index f5bb7b342..15bb6a6cd 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/ecc_traits_explorer.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/ecc_traits_explorer.C
@@ -22,3 +22,50 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file ecc_traits_explorer.C
+/// @brief Traits class for the MC ECC syndrome registers
+///
+// *HWP HWP Owner: Matthew Hickman<Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include <explorer_scom_addresses.H>
+#include <explorer_scom_addresses_fld.H>
+#include <lib/ecc/ecc_traits_explorer.H>
+
+
+namespace mss
+{
+
+// we need these declarations here in order for the linker to see the definitions
+// in the eccTraits class
+constexpr const uint64_t eccTraits<mc_type::EXPLORER, fapi2::TARGET_TYPE_MEM_PORT>::MAINLINE_NCE_REGS[];
+constexpr const uint64_t eccTraits<mc_type::EXPLORER, fapi2::TARGET_TYPE_MEM_PORT>::MAINLINE_RCE_REGS[];
+constexpr const uint64_t eccTraits<mc_type::EXPLORER, fapi2::TARGET_TYPE_MEM_PORT>::MAINLINE_MPE_REGS[];
+constexpr const uint64_t eccTraits<mc_type::EXPLORER, fapi2::TARGET_TYPE_MEM_PORT>::MAINLINE_UE_REGS[];
+constexpr const uint64_t eccTraits<mc_type::EXPLORER, fapi2::TARGET_TYPE_MEM_PORT>::MAINLINE_AUE_REGS[];
+constexpr const uint64_t eccTraits<mc_type::EXPLORER, fapi2::TARGET_TYPE_MEM_PORT>::ERROR_VECTOR_REGS[];
+constexpr const uint8_t eccTraits<mc_type::EXPLORER, fapi2::TARGET_TYPE_MEM_PORT>::symbol2galois[];
+constexpr const uint8_t eccTraits<mc_type::EXPLORER, fapi2::TARGET_TYPE_MEM_PORT>::symbol2dq[];
+
+// Definition of the symbol error count registers for Explorer
+const std::vector< uint64_t > eccTraits<mc_type::EXPLORER, fapi2::TARGET_TYPE_OCMB_CHIP>::SYMBOL_COUNT_REG =
+{
+ EXPLR_MCBIST_MBSSYMEC0Q,
+ EXPLR_MCBIST_MBSSYMEC1Q,
+ EXPLR_MCBIST_MBSSYMEC2Q,
+ EXPLR_MCBIST_MBSSYMEC3Q,
+ EXPLR_MCBIST_MBSSYMEC4Q,
+ EXPLR_MCBIST_MBSSYMEC5Q,
+ EXPLR_MCBIST_MBSSYMEC6Q,
+ EXPLR_MCBIST_MBSSYMEC7Q,
+ EXPLR_MCBIST_MBSSYMEC8Q,
+ EXPLR_MCBIST_MBSSYMEC9Q,
+};
+
+} // close namespace mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/ecc_traits_explorer.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/ecc_traits_explorer.H
index 9eb24ec19..4ffd0f91b 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/ecc_traits_explorer.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/ecc_traits_explorer.H
@@ -22,3 +22,277 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file ecc_traits_explorer.H
+/// @brief Traits class for the MC ECC syndrome registers
+///
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_ECC_TRAITS_EXPLORER_H_
+#define _MSS_ECC_TRAITS_EXPLORER_H_
+
+#include <explorer_scom_addresses.H>
+#include <explorer_scom_addresses_fld.H>
+#include <explorer_scom_addresses_fixes.H>
+#include <explorer_scom_addresses_fld_fixes.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+#include <lib/shared/exp_consts.H>
+
+namespace mss
+{
+
+///
+/// @class eccTraits
+/// @brief a collection of traits associated with the Axone Mem Port ECC interface
+///
+template<>
+class eccTraits<mc_type::EXPLORER, fapi2::TARGET_TYPE_MEM_PORT>
+{
+ public:
+ // MCA ECC registers - must be 64 bits.
+ static constexpr uint64_t HARDWARE_MS0_REG = EXPLR_RDF_HWMS0;
+ static constexpr uint64_t HARDWARE_MS1_REG = EXPLR_RDF_HWMS1;
+ static constexpr uint64_t HARDWARE_MS2_REG = EXPLR_RDF_HWMS2;
+ static constexpr uint64_t HARDWARE_MS3_REG = EXPLR_RDF_HWMS3;
+ static constexpr uint64_t HARDWARE_MS4_REG = EXPLR_RDF_HWMS4;
+ static constexpr uint64_t HARDWARE_MS5_REG = EXPLR_RDF_HWMS5;
+ static constexpr uint64_t HARDWARE_MS6_REG = EXPLR_RDF_HWMS6;
+ static constexpr uint64_t HARDWARE_MS7_REG = EXPLR_RDF_HWMS7;
+ static constexpr uint64_t FIRMWARE_MS0_REG = EXPLR_RDF_FWMS0;
+ static constexpr uint64_t FIRMWARE_MS1_REG = EXPLR_RDF_FWMS1;
+ static constexpr uint64_t FIRMWARE_MS2_REG = EXPLR_RDF_FWMS2;
+ static constexpr uint64_t FIRMWARE_MS3_REG = EXPLR_RDF_FWMS3;
+ static constexpr uint64_t FIRMWARE_MS4_REG = EXPLR_RDF_FWMS4;
+ static constexpr uint64_t FIRMWARE_MS5_REG = EXPLR_RDF_FWMS5;
+ static constexpr uint64_t FIRMWARE_MS6_REG = EXPLR_RDF_FWMS6;
+ static constexpr uint64_t FIRMWARE_MS7_REG = EXPLR_RDF_FWMS7;
+ static constexpr uint64_t MARK_SHADOW_REG = EXPLR_RDF_MSR;
+ static constexpr uint64_t ECC_MAX_MRANK_PER_PORT = exp::MAX_MRANK_PER_PORT;
+ static constexpr uint64_t ECC_MAX_DQ_BITS = exp::MAX_DQ_BITS_PER_PORT;
+ static constexpr uint64_t ECC_MAX_SYMBOLS = exp::MAX_SYMBOLS_PER_PORT;
+
+
+ // MCBIST ECC registers - Register API uses an MEMPORT target instead
+ // of MCBIST since MEMPORT's relative position is needed to find
+ // correct reg+field
+ constexpr static const uint64_t MAINLINE_NCE_REGS[] =
+ {
+ EXPLR_MCBIST_MBNCER0Q,
+ };
+
+ constexpr static const uint64_t MAINLINE_RCE_REGS[] =
+ {
+ EXPLR_MCBIST_MBRCER0Q,
+ };
+
+ constexpr static const uint64_t MAINLINE_MPE_REGS[] =
+ {
+ EXPLR_MCBIST_MBMPER0Q,
+ };
+
+ constexpr static const uint64_t MAINLINE_UE_REGS[] =
+ {
+ EXPLR_MCBIST_MBUER0Q,
+ };
+
+ constexpr static const uint64_t MAINLINE_AUE_REGS[] =
+ {
+ EXPLR_MCBIST_MBAUER0Q,
+ };
+
+ constexpr static const uint64_t ERROR_VECTOR_REGS[] =
+ {
+ EXPLR_MCBIST_MBSEVR0Q,
+ };
+
+ // Fields, can be any size.
+ enum
+ {
+ HARDWARE_MS_CHIPMARK = EXPLR_RDF_HWMS0_CHIPMARK,
+ HARDWARE_MS_CHIPMARK_LEN = EXPLR_RDF_HWMS0_CHIPMARK_LEN,
+ HARDWARE_MS_CONFIRMED = EXPLR_RDF_HWMS0_CONFIRMED,
+ HARDWARE_MS_EXIT1 = EXPLR_RDF_HWMS0_EXIT_1,
+ FIRMWARE_MS_MARK = EXPLR_RDF_FWMS0_MARK,
+ FIRMWARE_MS_MARK_LEN = EXPLR_RDF_FWMS0_MARK_LEN,
+ FIRMWARE_MS_TYPE = EXPLR_RDF_FWMS0_TYPE,
+ FIRMWARE_MS_REGION = EXPLR_RDF_FWMS0_REGION,
+ FIRMWARE_MS_REGION_LEN = EXPLR_RDF_FWMS0_REGION_LEN,
+ FIRMWARE_MS_ADDRESS = EXPLR_RDF_FWMS0_ADDRESS,
+ FIRMWARE_MS_ADDRESS_LEN = EXPLR_RDF_FWMS0_ADDRESS_LEN,
+ FIRMWARE_MS_EXIT1 = EXPLR_RDF_FWMS0_EXIT_1,
+ NCE_ADDR_TRAP = EXPLR_MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ADDR_TRAP,
+ NCE_ADDR_TRAP_LEN = EXPLR_MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ADDR_TRAP_LEN,
+ NCE_ON_RCE = EXPLR_MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ON_RCE,
+ NCE_IS_TCE = EXPLR_MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_IS_TCE,
+ RCE_ADDR_TRAP = EXPLR_MCBIST_MBRCER0Q_PORT_0_MAINLINE_RCE_ADDR_TRAP,
+ RCE_ADDR_TRAP_LEN = EXPLR_MCBIST_MBRCER0Q_PORT_0_MAINLINE_RCE_ADDR_TRAP_LEN,
+ MPE_ADDR_TRAP = EXPLR_MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ADDR_TRAP,
+ MPE_ADDR_TRAP_LEN = EXPLR_MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ADDR_TRAP_LEN,
+ MPE_ON_RCE = EXPLR_MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ON_RCE,
+ UE_ADDR_TRAP = EXPLR_MCBIST_MBUER0Q_PORT_0_MAINLINE_UE_ADDR_TRAP,
+ UE_ADDR_TRAP_LEN = EXPLR_MCBIST_MBUER0Q_PORT_0_MAINLINE_UE_ADDR_TRAP_LEN,
+ AUE_ADDR_TRAP = EXPLR_MCBIST_MBAUER0Q_PORT_0_MAINLINE_AUE_ADDR_TRAP,
+ AUE_ADDR_TRAP_LEN = EXPLR_MCBIST_MBAUER0Q_PORT_0_MAINLINE_AUE_ADDR_TRAP_LEN,
+ P0_NCE_GALOIS = EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_GALOIS_FIELD,
+ P0_NCE_GALOIS_LEN = EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_GALOIS_FIELD_LEN,
+ P0_NCE_MAGNITUDE = EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_MAGNITUDE_FIELD,
+ P0_NCE_MAGNITUDE_LEN = EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_MAGNITUDE_FIELD_LEN,
+ P0_TCE_GALOIS = EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_GALOIS_FIELD,
+ P0_TCE_GALOIS_LEN = EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_GALOIS_FIELD_LEN,
+ P0_TCE_MAGNITUDE = EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_MAGNITUDE_FIELD,
+ P0_TCE_MAGNITUDE_LEN = EXPLR_MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_MAGNITUDE_FIELD_LEN,
+ CURRENT_ADDR_TRAP = EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_ADDR_TRAP,
+ CURRENT_ADDR_TRAP_LEN = EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_ADDR_TRAP_LEN,
+ CURRENT_PORT = EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_PORT_TRAP,
+ CURRENT_PORT_LEN = EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_PORT_TRAP_LEN,
+ CURRENT_DIMM = EXPLR_MCBIST_MCBMCATQ_CFG_CURRENT_DIMM_TRAP,
+ SHADOW_CHIPMARK = EXPLR_RDF_MSR_CHIPMARK,
+ SHADOW_CHIPMARK_LEN = EXPLR_RDF_MSR_CHIPMARK_LEN,
+ SHADOW_RANK = EXPLR_RDF_MSR_RANK,
+ SHADOW_RANK_LEN = EXPLR_RDF_MSR_RANK_LEN,
+
+ };
+
+ // Symbol to Galois code mapping table for Explorer
+ constexpr static const uint8_t symbol2galois[] =
+ {
+ 0x80, 0xa0, 0x90, 0xf0,
+ 0x08, 0x0a, 0x09, 0x0f,
+ 0x98, 0xda, 0xb9, 0x7f,
+ 0x91, 0xd7, 0xb2, 0x78,
+ 0x28, 0xea, 0x49, 0x9f,
+ 0x9a, 0xd4, 0xbd, 0x76,
+ 0x60, 0xb0, 0xc0, 0x20,
+ 0x06, 0x0b, 0x0c, 0x02,
+ 0xc6, 0xfb, 0x1c, 0x42,
+ 0xca, 0xf4, 0x1d, 0x46,
+ 0xd6, 0x8b, 0x3c, 0xc2,
+ 0xcb, 0xf3, 0x1f, 0x4e,
+ 0xe0, 0x10, 0x50, 0xd0,
+ 0x0e, 0x01, 0x05, 0x0d,
+ 0x5e, 0x21, 0xa5, 0x3d,
+ 0x5b, 0x23, 0xaf, 0x3e,
+ 0xfe, 0x61, 0x75, 0x5d,
+ 0x51, 0x27, 0xa2, 0x38
+ };
+
+ // Symbol to DQ index mapping table for Explorer
+ constexpr static const uint8_t symbol2dq[] =
+ {
+ 39, 38, 37, 36,
+ 35, 34, 33, 32,
+ 79, 78, 77, 76,
+ 71, 70, 69, 68,
+ 63, 62, 61, 60,
+ 55, 54, 53, 52,
+ 31, 30, 29, 28,
+ 23, 22, 21, 20,
+ 15, 14, 13, 12,
+ 7, 6, 5, 4,
+ 75, 74, 73, 72,
+ 67, 66, 65, 64,
+ 59, 58, 57, 56,
+ 51, 50, 49, 48,
+ 27, 26, 25, 24,
+ 19, 18, 17, 16,
+ 11, 10, 9, 8,
+ 3, 2, 1, 0
+ };
+
+};
+
+///
+/// @class eccTraits
+/// @brief a collection of traits associated with the Axone MC ECC interface
+///
+template<>
+class eccTraits<mc_type::EXPLORER, fapi2::TARGET_TYPE_OCMB_CHIP>
+{
+ public:
+ // MCBIST ECC registers - must be 64 bits.
+ static constexpr uint64_t READ_ERROR_COUNT_REG0 = EXPLR_MCBIST_MBSEC0Q;
+ static constexpr uint64_t READ_ERROR_COUNT_REG1 = EXPLR_MCBIST_MBSEC1Q;
+ static constexpr uint64_t MARK_SYMBOL_COUNT_REG = EXPLR_MCBIST_MBSMSECQ;
+ static constexpr uint64_t MODAL_SYM_COUNT0_REG = EXPLR_MCBIST_MBSSYMEC0Q;
+ static constexpr uint64_t MODAL_SYM_COUNT1_REG = EXPLR_MCBIST_MBSSYMEC1Q;
+ static constexpr uint64_t MODAL_SYM_COUNT2_REG = EXPLR_MCBIST_MBSSYMEC2Q;
+ static constexpr uint64_t MODAL_SYM_COUNT3_REG = EXPLR_MCBIST_MBSSYMEC3Q;
+ static constexpr uint64_t MODAL_SYM_COUNT4_REG = EXPLR_MCBIST_MBSSYMEC4Q;
+ static constexpr uint64_t MODAL_SYM_COUNT5_REG = EXPLR_MCBIST_MBSSYMEC5Q;
+ static constexpr uint64_t MODAL_SYM_COUNT6_REG = EXPLR_MCBIST_MBSSYMEC6Q;
+ static constexpr uint64_t MODAL_SYM_COUNT7_REG = EXPLR_MCBIST_MBSSYMEC7Q;
+ static constexpr uint64_t MODAL_SYM_COUNT8_REG = EXPLR_MCBIST_MBSSYMEC8Q;
+ static constexpr uint64_t MODAL_SYM_COUNT9_REG = EXPLR_MCBIST_MBSSYMEC9Q;
+ static constexpr uint64_t MPE_ADDR_TRAP_REG = EXPLR_MCBIST_MCBMCATQ;
+ static constexpr uint64_t ECC_MAX_MRANK_PER_PORT = exp::MAX_MRANK_PER_PORT;
+ static constexpr uint64_t ECC_MAX_DQ_BITS = exp::MAX_DQ_BITS_PER_PORT;
+ static constexpr uint64_t ECC_MAX_SYMBOLS = exp::MAX_SYMBOLS_PER_PORT;
+
+ // Stores the symbol counter registers in a vector for easier access for MCBIST
+ static constexpr uint64_t REQUIRED_NUMBER_OF_SYMBOL_REGS = 10;
+ static const std::vector<uint64_t> SYMBOL_COUNT_REG;
+
+ // Fields, can be any size.
+ enum
+ {
+ INTERMITTENT_CE_COUNT = EXPLR_MCBIST_MBSEC0Q_INTERMITTENT_CE_COUNT,
+ INTERMITTENT_CE_COUNT_LEN = EXPLR_MCBIST_MBSEC0Q_INTERMITTENT_CE_COUNT_LEN,
+ SOFT_CE_COUNT = EXPLR_MCBIST_MBSEC0Q_SOFT_CE_COUNT,
+ SOFT_CE_COUNT_LEN = EXPLR_MCBIST_MBSEC0Q_SOFT_CE_COUNT_LEN,
+ HARD_CE_COUNT = EXPLR_MCBIST_MBSEC0Q_HARD_CE_COUNT,
+ HARD_CE_COUNT_LEN = EXPLR_MCBIST_MBSEC0Q_HARD_CE_COUNT_LEN,
+ INTERMITTENT_MCE_COUNT = EXPLR_MCBIST_MBSEC0Q_INTERMITTENT_MCE_COUNT,
+ INTERMITTENT_MCE_COUNT_LEN = EXPLR_MCBIST_MBSEC0Q_INTERMITTENT_MCE_COUNT_LEN,
+ SOFT_MCE_COUNT = EXPLR_MCBIST_MBSEC0Q_SOFT_MCE_COUNT,
+ SOFT_MCE_COUNT_LEN = EXPLR_MCBIST_MBSEC0Q_SOFT_MCE_COUNT_LEN,
+ HARD_MCE_COUNT = EXPLR_MCBIST_MBSEC1Q_HARD_MCE_COUNT,
+ HARD_MCE_COUNT_LEN = EXPLR_MCBIST_MBSEC1Q_HARD_MCE_COUNT_LEN,
+ ICE_COUNT = EXPLR_MCBIST_MBSEC1Q_ICE_COUNT,
+ ICE_COUNT_LEN = EXPLR_MCBIST_MBSEC1Q_ICE_COUNT_LEN,
+ UE_COUNT = EXPLR_MCBIST_MBSEC1Q_UE_COUNT,
+ UE_COUNT_LEN = EXPLR_MCBIST_MBSEC1Q_UE_COUNT_LEN,
+ AUE_COUNT = EXPLR_MCBIST_MBSEC1Q_AUE,
+ AUE_COUNT_LEN = EXPLR_MCBIST_MBSEC1Q_AUE_LEN,
+ RCE_COUNT = EXPLR_MCBIST_MBSEC1Q_RCE_COUNT,
+ RCE_COUNT_LEN = EXPLR_MCBIST_MBSEC1Q_RCE_COUNT_LEN,
+ SYMBOL0_COUNT = EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL0_COUNT,
+ SYMBOL0_COUNT_LEN = EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL0_COUNT_LEN,
+ SYMBOL1_COUNT = EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL1_COUNT,
+ SYMBOL1_COUNT_LEN = EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL1_COUNT_LEN,
+ SYMBOL2_COUNT = EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL2_COUNT,
+ SYMBOL2_COUNT_LEN = EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL2_COUNT_LEN,
+ SYMBOL3_COUNT = EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL3_COUNT,
+ SYMBOL3_COUNT_LEN = EXPLR_MCBIST_MBSMSECQ_MCE_SYMBOL3_COUNT_LEN,
+ MODAL_SYMBOL_COUNTER_00 = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_00,
+ MODAL_SYMBOL_COUNTER_00_LEN = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_00_LEN,
+ MODAL_SYMBOL_COUNTER_01 = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_01,
+ MODAL_SYMBOL_COUNTER_01_LEN = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_01_LEN,
+ MODAL_SYMBOL_COUNTER_02 = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_02,
+ MODAL_SYMBOL_COUNTER_02_LEN = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_02_LEN,
+ MODAL_SYMBOL_COUNTER_03 = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_03,
+ MODAL_SYMBOL_COUNTER_03_LEN = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_03_LEN,
+ MODAL_SYMBOL_COUNTER_04 = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_04,
+ MODAL_SYMBOL_COUNTER_04_LEN = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_04_LEN,
+ MODAL_SYMBOL_COUNTER_05 = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_05,
+ MODAL_SYMBOL_COUNTER_05_LEN = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_05_LEN,
+ MODAL_SYMBOL_COUNTER_06 = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_06,
+ MODAL_SYMBOL_COUNTER_06_LEN = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_06_LEN,
+ MODAL_SYMBOL_COUNTER_07 = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_07,
+ MODAL_SYMBOL_COUNTER_07_LEN = EXPLR_MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_07_LEN,
+
+ // FROM NIMBUS, UNSURE IF STILL ACCURATE OR NEEDED
+ // and a couple constants
+ NUM_MBSSYM_REGS = 10,
+ MODAL_SYMBOL_COUNTERS_PER_REG = 8,
+ };
+
+};
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/exp_mbs_error_vector_trap.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/exp_mbs_error_vector_trap.H
new file mode 100644
index 000000000..cf0665d32
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/exp_mbs_error_vector_trap.H
@@ -0,0 +1,205 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/exp_mbs_error_vector_trap.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_mbs_error_vector_trap.H
+/// @brief Subroutines for the MC MBS error vector trap registers (MBSEVR*Q)
+///
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _EXP_MSS_MBS_ERROR_VECTOR_TRAP_H_
+#define _EXP_MSS_MBS_ERROR_VECTOR_TRAP_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/scom.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+#include <generic/memory/lib/ecc/mbs_error_vector_trap.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace mbs_error_vector_trap
+{
+
+///
+/// @brief set_nce_galois
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<mc_type::EXPLORER, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::EXPLORER, T> >
+inline void set_nce_galois( const fapi2::Target<T>& i_target,
+ fapi2::buffer<uint64_t>& io_data,
+ const uint64_t i_value)
+{
+ io_data.insertFromRight<TT::P0_NCE_GALOIS, TT::P0_NCE_GALOIS_LEN>(i_value);
+
+ FAPI_INF("%s set_nce_galois: 0x%016lx", mss::c_str(i_target), i_value);
+}
+
+///
+/// @brief get_nce_galois
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<mc_type::EXPLORER, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the register value
+/// @param[out] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::EXPLORER, T> >
+inline void get_nce_galois( const fapi2::Target<T>& i_target,
+ const fapi2::buffer<uint64_t>& i_data,
+ uint64_t& o_value)
+{
+ i_data.extractToRight<TT::P0_NCE_GALOIS, TT::P0_NCE_GALOIS_LEN>(o_value);
+
+ FAPI_INF("%s get_nce_galois: 0x%016lx", mss::c_str(i_target), o_value);
+}
+
+///
+/// @brief set_nce_magnitude
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<mc_type::EXPLORER, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::EXPLORER, T> >
+inline void set_nce_magnitude( const fapi2::Target<T>& i_target,
+ fapi2::buffer<uint64_t>& io_data,
+ const uint64_t i_value)
+{
+ io_data.insertFromRight<TT::P0_NCE_MAGNITUDE, TT::P0_NCE_MAGNITUDE_LEN>(i_value);
+
+ FAPI_INF("%s set_nce_magnitude: 0x%016lx", mss::c_str(i_target), i_value);
+}
+
+///
+/// @brief get_nce_magnitude
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<mc_type::EXPLORER, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the register value
+/// @param[out] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::EXPLORER, T> >
+inline void get_nce_magnitude( const fapi2::Target<T>& i_target,
+ const fapi2::buffer<uint64_t>& i_data,
+ uint64_t& o_value)
+{
+ i_data.extractToRight<TT::P0_NCE_MAGNITUDE, TT::P0_NCE_MAGNITUDE_LEN>(o_value);
+
+ FAPI_INF("%s get_nce_magnitude: 0x%016lx", mss::c_str(i_target), o_value);
+}
+
+///
+/// @brief set_tce_galois
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<mc_type::EXPLORER, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::EXPLORER, T> >
+inline void set_tce_galois( const fapi2::Target<T>& i_target,
+ fapi2::buffer<uint64_t>& io_data,
+ const uint64_t i_value)
+{
+ io_data.insertFromRight<TT::P0_TCE_GALOIS, TT::P0_TCE_GALOIS_LEN>(i_value);
+
+ FAPI_INF("%s set_tce_galois: 0x%016lx", mss::c_str(i_target), i_value);
+}
+
+///
+/// @brief get_tce_galois
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<mc_type::EXPLORER, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the register value
+/// @param[out] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::EXPLORER, T> >
+inline void get_tce_galois( const fapi2::Target<T>& i_target,
+ const fapi2::buffer<uint64_t>& i_data,
+ uint64_t& o_value)
+{
+ i_data.extractToRight<TT::P0_TCE_GALOIS, TT::P0_TCE_GALOIS_LEN>(o_value);
+
+ FAPI_INF("%s get_tce_galois: 0x%016lx", mss::c_str(i_target), o_value);
+}
+
+///
+/// @brief set_tce_magnitude
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<mc_type::EXPLORER, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::EXPLORER, T> >
+inline void set_tce_magnitude( const fapi2::Target<T>& i_target,
+ fapi2::buffer<uint64_t>& io_data,
+ const uint64_t i_value)
+{
+ io_data.insertFromRight<TT::P0_TCE_MAGNITUDE, TT::P0_TCE_MAGNITUDE_LEN>(i_value);
+
+ FAPI_INF("%s set_tce_magnitude: 0x%016lx", mss::c_str(i_target), i_value);
+}
+
+///
+/// @brief get_tce_magnitude
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<mc_type::EXPLORER, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the register value
+/// @param[out] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::EXPLORER, T> >
+inline void get_tce_magnitude( const fapi2::Target<T>& i_target,
+ const fapi2::buffer<uint64_t>& i_data,
+ uint64_t& o_value)
+{
+ i_data.extractToRight<TT::P0_TCE_MAGNITUDE, TT::P0_TCE_MAGNITUDE_LEN>(o_value);
+
+ FAPI_INF("%s get_tce_magnitude: 0x%016lx", mss::c_str(i_target), o_value);
+}
+
+} // close namespace mbs_error_vector_trap
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/exp_modal_symbol_count.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/exp_modal_symbol_count.H
new file mode 100644
index 000000000..dd9431a3d
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/exp_modal_symbol_count.H
@@ -0,0 +1,245 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/exp_modal_symbol_count.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_modal_symbol_count.H
+/// @brief Subroutines for the MC modal symbol count (MBSSYMEC*Q) registers
+///
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _EXP_MSS_MODAL_SYMBOL_COUNT_H_
+#define _EXP_MSS_MODAL_SYMBOL_COUNT_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/scom.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+#include <generic/memory/lib/ecc/modal_symbol_count.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace modal_symbol_count
+{
+
+///
+/// @brief Read modal symbol count (MBSSYMEC*Q) register
+/// @tparam N the register index (0-8)
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< uint64_t N, fapi2::TargetType T, typename TT = eccTraits<mc_type::EXPLORER, T> >
+inline fapi2::ReturnCode read_index( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ static_assert((N < TT::NUM_MBSSYM_REGS), "Modal symbol count reg index failed range check");
+ FAPI_TRY( mss::getScom(i_target, (TT::MODAL_SYM_COUNT0_REG + N), o_data) );
+ FAPI_INF("read_index<%d>: 0x%016lx", N, o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Read modal symbol count (MBSSYMEC*Q) 9 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_index9( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_index<9>(i_target, o_data) );
+}
+
+///
+/// @brief Read modal symbol count (MBSSYMEC*Q) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_index the register index
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TARGET_TYPE_OCMB_CHIP >
+inline fapi2::ReturnCode read( const fapi2::TARGET_TYPE_OCMB_CHIP i_target,
+ const uint64_t i_index,
+ fapi2::buffer<uint64_t>& o_data )
+{
+ switch (i_index)
+ {
+ case(0):
+ return ( read_index0(i_target, o_data) );
+
+ case(1):
+ return ( read_index1(i_target, o_data) );
+
+ case(2):
+ return ( read_index2(i_target, o_data) );
+
+ case(3):
+ return ( read_index3(i_target, o_data) );
+
+ case(4):
+ return ( read_index4(i_target, o_data) );
+
+ case(5):
+ return ( read_index5(i_target, o_data) );
+
+ case(6):
+ return ( read_index6(i_target, o_data) );
+
+ case(7):
+ return ( read_index7(i_target, o_data) );
+
+ case(8):
+ return ( read_index8(i_target, o_data) );
+
+ case(9):
+ return ( read_index9(i_target, o_data) );
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_INDEX_PASSED()
+ .set_INDEX(i_index)
+ .set_FUNCTION(SYMBOL_COUNT_READ),
+ "%s Invalid index passed to fwms::ecc::modal_symbol_count::read (%d)",
+ mss::c_str(i_target),
+ i_index);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write modal symbol count (MBSSYMEC*Q) register
+/// @tparam N the register index (0-8)
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<EXPLORER, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< uint64_t N, fapi2::TargetType T, typename TT = eccTraits<mc_type::EXPLORER, T> >
+inline fapi2::ReturnCode write_index( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ static_assert((N < TT::NUM_MBSSYM_REGS), "Modal symbol count reg index failed range check");
+ FAPI_TRY( mss::putScom(i_target, (TT::MODAL_SYM_COUNT0_REG + N), i_data) );
+ FAPI_INF("write_index<%d>: 0x%016lx", N, i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write modal symbol count (MBSSYMEC*Q) 9 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_index9( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_index<9>(i_target, i_data) );
+}
+
+///
+/// @brief Write Hardware Mark Store (HWMS) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_index the register index
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TARGET_TYPE_OCMB_CHIP >
+inline fapi2::ReturnCode write( const fapi2::TARGET_TYPE_OCMB_CHIP i_target,
+ const uint64_t i_index,
+ const fapi2::buffer<uint64_t>& i_data )
+{
+ switch (i_index)
+ {
+ case(0):
+ return ( write_index0(i_target, i_data) );
+
+ case(1):
+ return ( write_index1(i_target, i_data) );
+
+ case(2):
+ return ( write_index2(i_target, i_data) );
+
+ case(3):
+ return ( write_index3(i_target, i_data) );
+
+ case(4):
+ return ( write_index4(i_target, i_data) );
+
+ case(5):
+ return ( write_index5(i_target, i_data) );
+
+ case(6):
+ return ( write_index6(i_target, i_data) );
+
+ case(7):
+ return ( write_index7(i_target, i_data) );
+
+ case(8):
+ return ( write_index8(i_target, i_data) );
+
+ case(9):
+ return ( write_index9(i_target, i_data) );
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_INDEX_PASSED()
+ .set_INDEX(i_index)
+ .set_FUNCTION(SYMBOL_COUNT_WRITE),
+ "%s Invalid index passed to fwms::ecc::modal_symbol_count::write (%d)",
+ mss::c_str(i_target),
+ i_index);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+} // close namespace modal_symbol_count
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_attr_engine_traits.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_attr_engine_traits.H
index 3476d51e5..c21838b6a 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_attr_engine_traits.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_attr_engine_traits.H
@@ -42,19 +42,25 @@
#include <generic/memory/lib/data_engine/data_engine_traits_def.H>
#include <generic/memory/lib/data_engine/data_engine.H>
#include <generic/memory/lib/spd/spd_facade.H>
-#include <lib/mss_explorer_attribute_getters.H>
-#include <lib/mss_explorer_attribute_setters.H>
+#include <mss_explorer_attribute_getters.H>
+#include <mss_explorer_attribute_setters.H>
+#include <mss_generic_attribute_setters.H>
+#include <mss_generic_attribute_getters.H>
namespace mss
{
+////////////////////////////////////////////////////////
+// Explorer specific traits for setTimingTraits
+////////////////////////////////////////////////////////
+
///
/// @brief Forward declartion of traits for setTimingTraits
/// @class setTimingTraits
-/// @note attr_eff_engine_fields, SPD_TAA_MIN
+/// @note exp::attr_eff_engine_fields, SPD_TAA_MIN
///
template< >
-struct setTimingTraits< exp::attr_eff_engine_fields, exp::SPD_TAA_MIN >
+struct setTimingTraits< exp::attr_eff_engine_fields, exp::attr_eff_engine_fields::SPD_TAA_MIN >
{
static constexpr const char* TIMING_NAME = "tAAmin";
@@ -62,22 +68,80 @@ struct setTimingTraits< exp::attr_eff_engine_fields, exp::SPD_TAA_MIN >
static constexpr spd_facade_fptr get_timing_in_ftb = &spd::facade::fine_offset_min_taa;
};
+////////////////////////////////////////////////////////
+// Traits for explorer specific attr_eff_engine_fields
+////////////////////////////////////////////////////////
+
+
///
/// @brief Traits for attr_engine
/// @class attrEngineTraits
+/// @tparam P processor type
/// @note attr_eff_engine_fields, ATTR_EFF_BASE_CASE specialization
/// NOP for base case needed to trigger partial specialization of attr_engine
///
-template<>
-struct attrEngineTraits<exp::attr_eff_engine_fields, exp::ATTR_EFF_BASE_CASE> {};
+template< proc_type P >
+struct attrEngineTraits<P, exp::attr_eff_engine_fields, exp::attr_eff_engine_fields::ATTR_EFF_BASE_CASE> {};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @tparam P processor type
+/// @note attr_eff_engine_fields, ADDRESS_MIRROR specialization
+///
+template< proc_type P >
+struct attrEngineTraits<P, exp::attr_eff_engine_fields, exp::attr_eff_engine_fields::ADDRESS_MIRROR>
+{
+ using attr_type = fapi2::ATTR_MEM_EXP_DRAM_ADDRESS_MIRRORING_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EXP_DRAM_ADDRESS_MIRRORING_TargetType;
+ static constexpr exp::ffdc_codes FFDC_CODE = exp::SET_EXP_DRAM_ADDRESS_MIRRORING;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_exp_dram_address_mirroring(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_exp_dram_address_mirroring(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.address_mirroring(o_setting);
+ }
+};
///
/// @brief Traits for attr_engine
/// @class attrEngineTraits
+/// @tparam P processor type
/// @note attr_eff_engine_fields, BYTE_ENABLES specialization
///
-template<>
-struct attrEngineTraits<exp::attr_eff_engine_fields, exp::BYTE_ENABLES>
+template< proc_type P >
+struct attrEngineTraits<P, exp::attr_eff_engine_fields, exp::attr_eff_engine_fields::BYTE_ENABLES>
{
using attr_type = fapi2::ATTR_MEM_EFF_BYTE_ENABLES_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -93,7 +157,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::BYTE_ENABLES>
static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& o_setting)
{
- return attr::get_byte_enables(i_target, o_setting);
+ return mss::attr::get_byte_enables(i_target, o_setting);
}
///
@@ -105,7 +169,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::BYTE_ENABLES>
static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& i_setting)
{
- return attr::set_byte_enables(i_target, i_setting);
+ return mss::attr::set_byte_enables(i_target, i_setting);
}
///
@@ -124,10 +188,11 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::BYTE_ENABLES>
///
/// @brief Traits for attr_engine
/// @class attrEngineTraits
+/// @tparam P processor type
/// @note attr_eff_engine_fields, NIBBLE_ENABLES specialization
///
-template<>
-struct attrEngineTraits<exp::attr_eff_engine_fields, exp::NIBBLE_ENABLES>
+template< proc_type P >
+struct attrEngineTraits<P, exp::attr_eff_engine_fields, exp::attr_eff_engine_fields::NIBBLE_ENABLES>
{
using attr_type = fapi2::ATTR_MEM_EFF_NIBBLE_ENABLES_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -143,7 +208,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::NIBBLE_ENABLES>
static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& o_setting)
{
- return attr::get_nibble_enables(i_target, o_setting);
+ return mss::attr::get_nibble_enables(i_target, o_setting);
}
///
@@ -155,7 +220,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::NIBBLE_ENABLES>
static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& i_setting)
{
- return attr::set_nibble_enables(i_target, i_setting);
+ return mss::attr::set_nibble_enables(i_target, i_setting);
}
///
@@ -174,10 +239,11 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::NIBBLE_ENABLES>
///
/// @brief Traits for attr_engine
/// @class attrEngineTraits
+/// @tparam P processor type
/// @note attr_eff_engine_fields, SPD_TAA_MIN specialization
///
-template<>
-struct attrEngineTraits<exp::attr_eff_engine_fields, exp::SPD_TAA_MIN>
+template< proc_type P >
+struct attrEngineTraits<P, exp::attr_eff_engine_fields, exp::attr_eff_engine_fields::SPD_TAA_MIN>
{
using attr_type = fapi2::ATTR_MEM_EXP_SPD_TAA_MIN_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -193,7 +259,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::SPD_TAA_MIN>
static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& o_setting)
{
- return attr::get_exp_spd_taa_min(i_target, o_setting);
+ return mss::attr::get_exp_spd_taa_min(i_target, o_setting);
}
///
@@ -205,7 +271,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::SPD_TAA_MIN>
static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& i_setting)
{
- return attr::set_exp_spd_taa_min(i_target, i_setting);
+ return mss::attr::set_exp_spd_taa_min(i_target, i_setting);
}
///
@@ -217,17 +283,19 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::SPD_TAA_MIN>
static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
attr_integral_type& o_setting)
{
- return mss::calc_spd_time_in_ps<exp::attr_eff_engine_fields, exp::SPD_TAA_MIN>(i_spd_data, o_setting);
+ return mss::calc_spd_time_in_ps<exp::attr_eff_engine_fields, exp::attr_eff_engine_fields::SPD_TAA_MIN>(i_spd_data,
+ o_setting);
}
};
///
/// @brief Traits for attr_engine
/// @class attrEngineTraits
+/// @tparam P processor type
/// @note attr_eff_engine_fields, FOUR_RANK_MODE specialization
///
-template<>
-struct attrEngineTraits<exp::attr_eff_engine_fields, exp::FOUR_RANK_MODE>
+template< proc_type P >
+struct attrEngineTraits<P, exp::attr_eff_engine_fields, exp::attr_eff_engine_fields::FOUR_RANK_MODE>
{
using attr_type = fapi2::ATTR_MEM_EFF_FOUR_RANK_MODE_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -243,7 +311,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::FOUR_RANK_MODE>
static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& o_setting)
{
- return attr::get_four_rank_mode(i_target, o_setting);
+ return mss::attr::get_four_rank_mode(i_target, o_setting);
}
///
@@ -255,7 +323,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::FOUR_RANK_MODE>
static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& i_setting)
{
- return attr::set_four_rank_mode(i_target, i_setting);
+ return mss::attr::set_four_rank_mode(i_target, i_setting);
}
///
@@ -268,7 +336,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::FOUR_RANK_MODE>
attr_integral_type& o_setting)
{
constexpr auto FOUR_RANK_MODE_BIT = 7; // From SPEC
- uint8_t l_spd_four_rank_mode = 0;
+ attr_integral_type l_spd_four_rank_mode = 0;
FAPI_TRY(i_spd_data.compatabilty_modes(l_spd_four_rank_mode));
o_setting = fapi2::buffer<uint8_t>(l_spd_four_rank_mode).getBit<FOUR_RANK_MODE_BIT>();
@@ -281,10 +349,11 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::FOUR_RANK_MODE>
///
/// @brief Traits for attr_engine
/// @class attrEngineTraits
+/// @tparam P processor type
/// @note attr_eff_engine_fields, DDP_COMPATIBILITY specialization
///
-template<>
-struct attrEngineTraits<exp::attr_eff_engine_fields, exp::DDP_COMPATIBILITY>
+template< proc_type P >
+struct attrEngineTraits<P, exp::attr_eff_engine_fields, exp::attr_eff_engine_fields::DDP_COMPATIBILITY>
{
using attr_type = fapi2::ATTR_MEM_EFF_DDP_COMPATIBILITY_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -300,7 +369,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::DDP_COMPATIBILITY>
static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& o_setting)
{
- return attr::get_ddp_compatibility(i_target, o_setting);
+ return mss::attr::get_ddp_compatibility(i_target, o_setting);
}
///
@@ -312,7 +381,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::DDP_COMPATIBILITY>
static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& i_setting)
{
- return attr::set_ddp_compatibility(i_target, i_setting);
+ return mss::attr::set_ddp_compatibility(i_target, i_setting);
}
///
@@ -325,7 +394,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::DDP_COMPATIBILITY>
attr_integral_type& o_setting)
{
constexpr auto DDP_COMPATIBILITY_BIT = 6; // From SPEC
- uint8_t l_spd_ddp_compatibility = 0;
+ attr_integral_type l_spd_ddp_compatibility = 0;
FAPI_TRY(i_spd_data.compatabilty_modes(l_spd_ddp_compatibility));
o_setting = fapi2::buffer<uint8_t>(l_spd_ddp_compatibility).getBit<DDP_COMPATIBILITY_BIT>();
@@ -338,10 +407,11 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::DDP_COMPATIBILITY>
///
/// @brief Traits for attr_engine
/// @class attrEngineTraits
+/// @tparam P processor type
/// @note attr_eff_engine_fields, TSV_8H_SUPPORT specialization
///
-template<>
-struct attrEngineTraits<exp::attr_eff_engine_fields, exp::TSV_8H_SUPPORT>
+template< proc_type P >
+struct attrEngineTraits<P, exp::attr_eff_engine_fields, exp::attr_eff_engine_fields::TSV_8H_SUPPORT>
{
using attr_type = fapi2::ATTR_MEM_EFF_TSV_8H_SUPPORT_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -357,7 +427,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::TSV_8H_SUPPORT>
static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& o_setting)
{
- return attr::get_tsv_8h_support(i_target, o_setting);
+ return mss::attr::get_tsv_8h_support(i_target, o_setting);
}
///
@@ -369,7 +439,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::TSV_8H_SUPPORT>
static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& i_setting)
{
- return attr::set_tsv_8h_support(i_target, i_setting);
+ return mss::attr::set_tsv_8h_support(i_target, i_setting);
}
///
@@ -388,10 +458,11 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::TSV_8H_SUPPORT>
///
/// @brief Traits for attr_engine
/// @class attrEngineTraits
+/// @tparam P processor type
/// @note attr_eff_engine_fields, PSTATES specialization
///
-template<>
-struct attrEngineTraits<exp::attr_eff_engine_fields, exp::PSTATES>
+template< proc_type P >
+struct attrEngineTraits<P, exp::attr_eff_engine_fields, exp::attr_eff_engine_fields::PSTATES>
{
using attr_type = fapi2::ATTR_MEM_EFF_PSTATES_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -407,7 +478,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::PSTATES>
static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& o_setting)
{
- return attr::get_pstates(i_target, o_setting);
+ return mss::attr::get_pstates(i_target, o_setting);
}
///
@@ -419,7 +490,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::PSTATES>
static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& i_setting)
{
- return attr::set_pstates(i_target, i_setting);
+ return mss::attr::set_pstates(i_target, i_setting);
}
///
@@ -438,10 +509,11 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::PSTATES>
///
/// @brief Traits for attr_engine
/// @class attrEngineTraits
+/// @tparam P processor type
/// @note attr_eff_engine_fields, MRAM_SUPPORT specialization
///
-template<>
-struct attrEngineTraits<exp::attr_eff_engine_fields, exp::MRAM_SUPPORT>
+template< proc_type P >
+struct attrEngineTraits<P, exp::attr_eff_engine_fields, exp::attr_eff_engine_fields::MRAM_SUPPORT>
{
using attr_type = fapi2::ATTR_MEM_EFF_MRAM_SUPPORT_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -457,7 +529,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::MRAM_SUPPORT>
static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& o_setting)
{
- return attr::get_mram_support(i_target, o_setting);
+ return mss::attr::get_mram_support(i_target, o_setting);
}
///
@@ -469,7 +541,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::MRAM_SUPPORT>
static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& i_setting)
{
- return attr::set_mram_support(i_target, i_setting);
+ return mss::attr::set_mram_support(i_target, i_setting);
}
///
@@ -482,7 +554,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::MRAM_SUPPORT>
attr_integral_type& o_setting)
{
constexpr auto MRAM_SUPPORT_BIT = 4; // From SPEC
- uint8_t l_spd_ddp_compatibility = 0;
+ attr_integral_type l_spd_ddp_compatibility = 0;
FAPI_TRY(i_spd_data.compatabilty_modes(l_spd_ddp_compatibility));
o_setting = fapi2::buffer<uint8_t>(l_spd_ddp_compatibility).getBit<MRAM_SUPPORT_BIT>();
@@ -495,61 +567,11 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::MRAM_SUPPORT>
///
/// @brief Traits for attr_engine
/// @class attrEngineTraits
-/// @note attr_eff_engine_fields, HEIGHT_3DS specialization
-///
-template<>
-struct attrEngineTraits<exp::attr_eff_engine_fields, exp::HEIGHT_3DS>
-{
- using attr_type = fapi2::ATTR_MEM_EXP_3DS_HEIGHT_Type;
- using attr_integral_type = std::remove_all_extents<attr_type>::type;
- static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EXP_3DS_HEIGHT_TargetType;
- static constexpr exp::ffdc_codes FFDC_CODE = exp::SET_3DS_HEIGHT;
-
- ///
- /// @brief attribute getter
- /// @param[in] i_target the fapi2 target
- /// @param[out] o_setting array to populate
- /// @return FAPI2_RC_SUCCESS iff okay
- ///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
- {
- return attr::get_exp_3ds_height(i_target, o_setting);
- }
-
- ///
- /// @brief attribute setter
- /// @param[in] i_target the fapi2 target
- /// @param[in] i_setting array to set
- /// @return FAPI2_RC_SUCCESS iff okay
- ///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
- {
- return attr::set_exp_3ds_height(i_target, i_setting);
- }
-
- ///
- /// @brief Computes setting for attribute
- /// @param[in] i_spd_data EFD data
- /// @param[out] o_setting value we want to set attr with
- /// @return FAPI2_RC_SUCCESS iff okay
- ///
- static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
- attr_integral_type& o_setting)
- {
-
- return fapi2::FAPI2_RC_SUCCESS;
- }
-};
-
-///
-/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @tparam P processor type
/// @note attr_eff_engine_fields, SPD_CL_SUPPORTED specialization
///
-template<>
-struct attrEngineTraits<exp::attr_eff_engine_fields, exp::SPD_CL_SUPPORTED>
+template< proc_type P >
+struct attrEngineTraits<P, exp::attr_eff_engine_fields, exp::attr_eff_engine_fields::SPD_CL_SUPPORTED>
{
using attr_type = fapi2::ATTR_MEM_EXP_SPD_CL_SUPPORTED_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -565,7 +587,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::SPD_CL_SUPPORTED>
static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& o_setting)
{
- return attr::get_exp_spd_cl_supported(i_target, o_setting);
+ return mss::attr::get_exp_spd_cl_supported(i_target, o_setting);
}
///
@@ -577,7 +599,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::SPD_CL_SUPPORTED>
static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& i_setting)
{
- return attr::set_exp_spd_cl_supported(i_target, i_setting);
+ return mss::attr::set_exp_spd_cl_supported(i_target, i_setting);
}
///
@@ -591,6 +613,7 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::SPD_CL_SUPPORTED>
{
uint64_t l_val = 0;
FAPI_TRY(i_spd_data.supported_cas_latencies(l_val));
+
o_setting = static_cast<attr_integral_type>(l_val);
fapi_try_exit:
@@ -601,10 +624,11 @@ struct attrEngineTraits<exp::attr_eff_engine_fields, exp::SPD_CL_SUPPORTED>
///
/// @brief Traits for pre_data_engine
/// @class attrEngineTraits
+/// @tparam P processor type
/// @note AXONE, DIMM_TYPE_METADATA specialization
///
-template<>
-struct attrEngineTraits<generic_metadata_fields, DIMM_TYPE_METADATA>
+template< proc_type P >
+struct attrEngineTraits<P, generic_metadata_fields, generic_metadata_fields::DIMM_TYPE_METADATA>
{
using attr_type = fapi2::ATTR_MEM_DIMM_TYPE_METADATA_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -637,8 +661,8 @@ struct attrEngineTraits<generic_metadata_fields, DIMM_TYPE_METADATA>
///
/// @brief Computes setting for attribute
- /// @param[in] i_spd_data SPD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[in] i_target the DIMM target
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
static fapi2::ReturnCode get_value_to_set(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
@@ -685,10 +709,11 @@ class dimmPosTraits<mss::mc_type::EXPLORER>
///
/// @brief Traits for pre_data_engine
/// @class attrEngineTraits
+/// @tparam P processor type
/// @note generic_metadata_fields, DRAM_GEN_METADATA specialization
///
-template<>
-struct attrEngineTraits<generic_metadata_fields, DRAM_GEN_METADATA>
+template< proc_type P >
+struct attrEngineTraits<P, generic_metadata_fields, generic_metadata_fields::DRAM_GEN_METADATA>
{
using attr_type = fapi2::ATTR_MEM_DRAM_GEN_METADATA_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -721,8 +746,8 @@ struct attrEngineTraits<generic_metadata_fields, DRAM_GEN_METADATA>
///
/// @brief Computes setting for attribute
- /// @param[in] i_spd_data SPD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[in] i_target the DIMM target
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
static fapi2::ReturnCode get_value_to_set(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
@@ -735,10 +760,11 @@ struct attrEngineTraits<generic_metadata_fields, DRAM_GEN_METADATA>
///
/// @brief Traits for pre_data_engine
/// @class attrEngineTraits
+/// @tparam P processor type
/// @note generic_metadata_fields, DIMM_POS_METADATA specialization
///
-template<>
-struct attrEngineTraits<generic_metadata_fields, DIMM_POS_METADATA>
+template< proc_type P >
+struct attrEngineTraits<P, generic_metadata_fields, generic_metadata_fields::DIMM_POS_METADATA>
{
using attr_type = fapi2::ATTR_MEM_DIMM_POS_METADATA_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -771,8 +797,8 @@ struct attrEngineTraits<generic_metadata_fields, DIMM_POS_METADATA>
///
/// @brief Computes setting for attribute
- /// @param[in] i_spd_data SPD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[in] i_target the DIMM target
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
static fapi2::ReturnCode get_value_to_set(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
@@ -783,28 +809,6 @@ struct attrEngineTraits<generic_metadata_fields, DIMM_POS_METADATA>
}
};
-///
-/// @brief Value traits for attr_eff_engine_fields
-/// @class attrEngineTraits
-/// @note attr_eff_engine_fields
-///
-template < >
-struct attrEnumTraits<exp::attr_eff_engine_fields>
-{
- static constexpr size_t DISPATCHER = exp::ATTR_EFF_DISPATCHER;
-};
-
-///
-/// @brief Value traits for attr_eff_engine_fields
-/// @class attrEngineTraits
-/// @note attr_eff_engine_fields
-///
-template < >
-struct attrEnumTraits<generic_metadata_fields>
-{
- static constexpr size_t DISPATCHER = ATTR_METADATA_DISPATCHER;
-};
-
}//mss
#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_efd_processing.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_efd_processing.C
new file mode 100644
index 000000000..8aa963ab3
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_efd_processing.C
@@ -0,0 +1,276 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_efd_processing.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file explorer_efd_processing.C
+/// @brief Processing for EFD for eff config
+///
+
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP FW Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB:CI
+
+#include <fapi2.H>
+#include <lib/shared/exp_consts.H>
+#include <exp_data_structs.H>
+#include <generic/memory/lib/data_engine/data_engine_traits_def.H>
+#include <generic/memory/lib/data_engine/data_engine.H>
+#include <generic/memory/lib/spd/spd_facade.H>
+#include <mss_explorer_attribute_getters.H>
+#include <mss_explorer_attribute_setters.H>
+#include <lib/eff_config/explorer_efd_processing.H>
+#include <generic/memory/lib/mss_generic_attribute_setters.H>
+
+namespace mss
+{
+namespace exp
+{
+namespace efd
+{
+
+///
+/// @brief Processes the CAC delay A side
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode cac_delay_a(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ // Get the data
+ uint8_t l_addr_delay_a[DRAMINIT_NUM_ADDR_DELAYS] = {};
+ const auto& l_port = mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(i_target);
+
+ FAPI_TRY(mss::attr::get_exp_atxdly_a(l_port, l_addr_delay_a));
+
+ // Update the values
+ FAPI_TRY(i_efd_data->cac_delay_a_side_group_0(l_addr_delay_a[0]));
+ FAPI_TRY(i_efd_data->cac_delay_a_side_group_1(l_addr_delay_a[1]));
+ FAPI_TRY(i_efd_data->cac_delay_a_side_group_2(l_addr_delay_a[2]));
+ FAPI_TRY(i_efd_data->cac_delay_a_side_group_3(l_addr_delay_a[3]));
+ FAPI_TRY(i_efd_data->cac_delay_a_side_group_4(l_addr_delay_a[4]));
+ FAPI_TRY(i_efd_data->cac_delay_a_side_group_5(l_addr_delay_a[5]));
+ FAPI_TRY(i_efd_data->cac_delay_a_side_group_6(l_addr_delay_a[6]));
+ FAPI_TRY(i_efd_data->cac_delay_a_side_group_7(l_addr_delay_a[7]));
+
+ // Set the attribute
+ FAPI_TRY(mss::attr::set_exp_atxdly_a(l_port, l_addr_delay_a));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Processes the CAC delay B side
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode cac_delay_b(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ // Get the data
+ uint8_t l_addr_delay_b[DRAMINIT_NUM_ADDR_DELAYS] = {};
+ const auto& l_port = mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(i_target);
+
+ FAPI_TRY(mss::attr::get_exp_atxdly_b(l_port, l_addr_delay_b));
+
+ // Update the values
+ FAPI_TRY(i_efd_data->cac_delay_b_side_group_0(l_addr_delay_b[0]));
+ FAPI_TRY(i_efd_data->cac_delay_b_side_group_1(l_addr_delay_b[1]));
+ FAPI_TRY(i_efd_data->cac_delay_b_side_group_2(l_addr_delay_b[2]));
+ FAPI_TRY(i_efd_data->cac_delay_b_side_group_3(l_addr_delay_b[3]));
+ FAPI_TRY(i_efd_data->cac_delay_b_side_group_4(l_addr_delay_b[4]));
+ FAPI_TRY(i_efd_data->cac_delay_b_side_group_5(l_addr_delay_b[5]));
+ FAPI_TRY(i_efd_data->cac_delay_b_side_group_6(l_addr_delay_b[6]));
+ FAPI_TRY(i_efd_data->cac_delay_b_side_group_7(l_addr_delay_b[7]));
+
+ // Set the attribute
+ FAPI_TRY(mss::attr::set_exp_atxdly_b(l_port, l_addr_delay_b));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Processes the Host INIT RD VREF DQ
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+/// @note this is pulled in for exp_draminit. The individual fields are pulled into the SI engine
+///
+fapi2::ReturnCode init_vref_dq(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ // See Byte 44 of SPD Document (Bit 6 from right = Bit 1 from left)
+ static const uint8_t VREF_RANGE_BIT_LEFT_ALGINED = 1;
+
+ // Get the data
+ uint8_t l_vref_dq[mss::exp::sizes::MAX_RANK_PER_DIMM] = {0};
+
+ uint8_t l_range = 0;
+ uint8_t l_value = 0;
+ fapi2::buffer<uint8_t> l_combined_vref;
+
+ FAPI_TRY(mss::attr::get_exp_init_vref_dq(i_target, l_vref_dq));
+
+ // Piece together the field
+ FAPI_TRY(i_efd_data->wr_vref_dq_range(l_range));
+ FAPI_TRY(i_efd_data->wr_vref_dq_value(l_value));
+
+ l_combined_vref = l_value;
+ l_combined_vref.writeBit<VREF_RANGE_BIT_LEFT_ALGINED>(l_range);
+
+ // Insert
+ l_vref_dq[i_efd_data->get_rank()] = l_combined_vref;
+
+ // Set the attribute
+ FAPI_TRY(mss::attr::set_exp_init_vref_dq(i_target, l_vref_dq));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Processes the Host INIT PHY VREF
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode init_phy_vref(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ // Get the data
+ uint8_t l_phy_vref[mss::exp::sizes::MAX_RANK_PER_DIMM] = {0};
+
+ FAPI_TRY(mss::attr::get_exp_init_phy_vref(i_target, l_phy_vref));
+
+ // Update the values
+ FAPI_TRY(i_efd_data->init_phy_vref(l_phy_vref[i_efd_data->get_rank()]));
+
+ // Set the attribute
+ FAPI_TRY(mss::attr::set_exp_init_phy_vref(i_target, l_phy_vref));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Processes the CS command latency
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode cs_cmd_latency(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ // Get the data
+ uint8_t l_cmd_latency = 0;
+ FAPI_TRY(mss::attr::get_cs_cmd_latency(i_target, l_cmd_latency));
+
+ // Update the values
+ FAPI_TRY(i_efd_data->bist_ca_latency_mode(l_cmd_latency));
+
+ // Set the attribute
+ FAPI_TRY(mss::attr::set_cs_cmd_latency(i_target, l_cmd_latency));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Processes the CA parity latency
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode ca_parity_latency(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ // Get the data
+ uint8_t l_ca_parity_latency = 0;
+ FAPI_TRY(mss::attr::get_ca_parity_latency(i_target, l_ca_parity_latency));
+
+ // Update the values
+ FAPI_TRY(i_efd_data->bist_ca_pl_mode(l_ca_parity_latency));
+
+ // Set the attribute
+ FAPI_TRY(mss::attr::set_ca_parity_latency(i_target, l_ca_parity_latency));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Processes the DFIMRL_DDRCLK
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode dfimrl_ddrclk(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ // Get the data
+ uint8_t l_dfimrl_ddrclk = 0;
+ const auto& l_port = mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(i_target);
+
+ FAPI_TRY(mss::attr::get_exp_dfimrl_clk(l_port, l_dfimrl_ddrclk));
+
+ // Update the values
+ FAPI_TRY(i_efd_data->dfimrl_ddrclk(l_dfimrl_ddrclk));
+
+ // Set the attribute
+ FAPI_TRY(mss::attr::set_exp_dfimrl_clk(l_port, l_dfimrl_ddrclk));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Process the EFD data and set attributes
+/// @param[in] i_target DIMM target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode process(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data)
+{
+ FAPI_TRY(init_vref_dq(i_target, i_efd_data));
+ FAPI_TRY(init_phy_vref(i_target, i_efd_data));
+ FAPI_TRY(cs_cmd_latency(i_target, i_efd_data));
+ FAPI_TRY(ca_parity_latency(i_target, i_efd_data));
+ FAPI_TRY(dfimrl_ddrclk(i_target, i_efd_data));
+ FAPI_TRY(cac_delay_a(i_target, i_efd_data));
+ FAPI_TRY(cac_delay_b(i_target, i_efd_data));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // ns efd
+} // ns exp
+} // ns mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_efd_processing.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_efd_processing.H
new file mode 100644
index 000000000..2f7c5cc14
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_efd_processing.H
@@ -0,0 +1,130 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_efd_processing.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file explorer_efd_processing.H
+/// @brief Processing for EFD for eff config
+///
+
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP FW Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB:CI
+
+#ifndef _MSS_EXPLORER_EFD_PROCESSING_H_
+#define _MSS_EXPLORER_EFD_PROCESSING_H_
+
+#include <fapi2.H>
+#include <lib/shared/exp_consts.H>
+#include <generic/memory/lib/data_engine/data_engine_traits_def.H>
+#include <generic/memory/lib/data_engine/data_engine.H>
+#include <generic/memory/lib/spd/spd_facade.H>
+#include <mss_explorer_attribute_getters.H>
+#include <mss_explorer_attribute_setters.H>
+
+namespace mss
+{
+namespace exp
+{
+namespace efd
+{
+
+///
+/// @brief Processes the Host INIT RD VREF DQ
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+/// @note this is pulled in for exp_draminit. The individual fields are pulled into the SI engine
+///
+fapi2::ReturnCode init_vref_dq(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Processes the Host INIT PHY VREF
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode init_phy_vref(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Processes the CAC delay A side
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode cac_delay_a(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Processes the CAC delay A side
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode cac_delay_b(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Processes the CS command latency
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode cs_cmd_latency(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Processes the CA parity latency
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode ca_parity_latency(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Processes the DFIMRL_DDRCLK
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode dfimrl_ddrclk(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+
+///
+/// @brief Process the EFD data and set attributes
+/// @param[in] i_target DIMM target on which to operate
+/// @param[in] i_efd_data the EFD data to process
+/// @return fapi2::FAPI2_RC_SUCCESS iff function completes successfully
+///
+fapi2::ReturnCode process(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::shared_ptr<mss::efd::base_decoder>& i_efd_data);
+} // ns efd
+} // ns exp
+} // ns mss
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_attribute_accessors_manual.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_attribute_accessors_manual.H
index 04434c84c..eca4bc6ee 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_attribute_accessors_manual.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_attribute_accessors_manual.H
@@ -48,40 +48,72 @@ namespace mss
{
///
-/// @brief Gets whether the OCMB will be configred to enterprise mode
-/// @param[in] i_target OCMB target on which to operate
-/// @param[out] o_is_enterprise_mode true if the part is in enterprise mode
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @brief Unit-testable half dimm mode helper function. Calculates half dimm mode based on input params
+/// @param[in] i_target OCMB chip
+/// @param[in] i_is_enterprise enterprise mode is enabled
+/// @param[in] i_half_dimm_attr half dimm mode as obtained from attribute
+/// @param[in] i_half_dimm_override_attr half dimm mode override from attribute
+/// @param[out] o_is_half_dimm_mode resulting value for half dimm mode after calculations
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
///
-inline fapi2::ReturnCode enterprise_mode( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
- i_target,
- bool& o_is_enterprise_mode )
+inline fapi2::ReturnCode half_dimm_mode_helper(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const bool i_is_enterprise,
+ const uint8_t i_half_dimm_attr,
+ const uint8_t i_half_dimm_override_attr,
+ bool& o_is_half_dimm_mode )
{
- // Constexprs for beautification
- constexpr uint8_t ENTERPRISE = fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_MODE_ENTERPRISE;
- constexpr uint8_t NO_OVERRIDE = fapi2::ENUM_ATTR_MSS_OCMB_NONENTERPRISE_MODE_OVERRIDE_NO_OVERRIDE;
+ o_is_half_dimm_mode = false;
- // Variables
- o_is_enterprise_mode = false;
- uint8_t l_enterprise = 0;
- uint8_t l_override = 0;
+ bool l_is_half_dimm = 0;
+
+ // First let's assert that ocmb_half_dimm_mode isn't HALF_DIMM when ENTERPRISE is 0
+ // Even though this could theoretically be overridden back to FULL_DIMM, we should
+ // check that the initial value is also valid.
+ FAPI_ASSERT(!i_half_dimm_attr || i_is_enterprise,
+ fapi2::MSS_EXP_HALF_DIMM_MODE_NOT_SUPPORTED()
+ .set_ENTERPRISE_SETTING(i_is_enterprise)
+ .set_HALF_DIMM_SETTING(i_half_dimm_attr)
+ .set_OCMB_TARGET(i_target),
+ "%s Invalid configuration: ATTR_MSS_OCMB_HALF_DIMM_MODE set to HALF_DIMM while enterprise is disabled",
+ mss::c_str(i_target));
- FAPI_TRY( mss::attr::get_ocmb_enterprise_mode(i_target, l_enterprise) );
- FAPI_TRY( mss::attr::get_ocmb_nonenterprise_mode_override(i_target, l_override) );
+ // This might be overwritten below by overrides
+ l_is_half_dimm = (i_half_dimm_attr == fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_HALF_DIMM);
+ // Now let's apply the override
+ if (i_half_dimm_override_attr == fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_OVERRIDE_OVERRIDE_HALF_DIMM)
{
- const bool l_enterprise_mode = l_enterprise == ENTERPRISE;
- const bool l_no_override = l_override == NO_OVERRIDE;
- // We will be in enterprise mode (true) IF
- // 1) the chip is in enterprise mode (we can't run in enterprise mode if the part is non-enterprise capable) AND
- // 2) we do not have the override to non-enterprise mode
- o_is_enterprise_mode = l_enterprise_mode && l_no_override;
-
- FAPI_INF("%s is in %s mode chip is %s override is %s", mss::c_str(i_target),
- o_is_enterprise_mode ? "enterprise" : "non-enterprise", l_enterprise_mode ? "enterprise" : "non-enterprise",
- l_no_override ? "no override" : "override to non-enterprise");
+ l_is_half_dimm = true;
+
+ // Assert once more that this is valid
+ FAPI_ASSERT(!l_is_half_dimm || i_is_enterprise,
+ fapi2::MSS_EXP_HALF_DIMM_MODE_NOT_SUPPORTED()
+ .set_ENTERPRISE_SETTING(i_is_enterprise)
+ .set_HALF_DIMM_SETTING(l_is_half_dimm)
+ .set_OCMB_TARGET(i_target),
+ "%s Invalid configuration: HALF_DIMM_MODE overridden to HALF_DIMM while enterprise is disabled",
+ mss::c_str(i_target));
+
+ FAPI_DBG("%s overridden to HALF_DIMM_MODE", mss::c_str(i_target));
}
+ else if (i_half_dimm_override_attr == fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_OVERRIDE_OVERRIDE_FULL_DIMM)
+ {
+ l_is_half_dimm = false;
+ FAPI_DBG("%s overridden to FULL_DIMM_MODE", mss::c_str(i_target));
+ }
+
+ o_is_half_dimm_mode = l_is_half_dimm;
+
+ FAPI_INF("%s %s in enterprise mode, and %s override is present. The chip is in %s (attribute %u)",
+ mss::c_str(i_target),
+ i_is_enterprise ? "is" : "is not",
+ i_half_dimm_override_attr > 0 ? "an" : "no",
+ o_is_half_dimm_mode ? "half-DIMM mode" : "full-DIMM mode", l_is_half_dimm);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
fapi_try_exit:
return fapi2::current_err;
}
@@ -92,45 +124,22 @@ fapi_try_exit:
/// @param[out] o_is_half_dimm_mode true if the part is in half-DIMM mode
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
///
-inline fapi2::ReturnCode half_dimm_mode( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
- i_target,
- bool& o_is_half_dimm_mode )
+inline fapi2::ReturnCode half_dimm_mode(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const bool i_is_enterprise_mode,
+ bool& o_is_half_dimm_mode )
{
// Variables
o_is_half_dimm_mode = false;
- bool l_is_enterprise = false;
- uint8_t l_half_dimm = 0;
- uint8_t l_override = 0;
-
- FAPI_TRY( enterprise_mode(i_target, l_is_enterprise) );
-
- // We're in full DIMM mode if we're in non-enterprise mode
- if(!l_is_enterprise)
- {
- o_is_half_dimm_mode = false;
- FAPI_INF("%s is in full-DIMM as the chip is in non-enterprise mode", mss::c_str(i_target));
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
- // Now that we're not in enterprise mode, check for overrides
- FAPI_TRY( mss::attr::get_ocmb_half_dimm_mode_override(i_target, l_override) );
-
- // If we have an override, set based upon the override
- if(l_override != fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_OVERRIDE_NO_OVERRIDE)
- {
- o_is_half_dimm_mode = l_override == fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_OVERRIDE_OVERRIDE_HALF_DIMM;
- FAPI_INF("%s is in enterprise mode %s override is present. The chip is in %s (attribute %u)", mss::c_str(i_target),
- "an", o_is_half_dimm_mode ? "half-DIMM mode" : "full-DIMM mode", l_override);
- return fapi2::FAPI2_RC_SUCCESS;
- }
+ uint8_t l_half_dimm_attr = 0;
+ uint8_t l_override_attr = 0;
- // No override, so go with the attribute derived from the ECID
- FAPI_TRY( mss::attr::get_ocmb_half_dimm_mode(i_target, l_half_dimm) );
+ FAPI_TRY( mss::attr::get_ocmb_half_dimm_mode(i_target, l_half_dimm_attr) );
+ FAPI_TRY( mss::attr::get_ocmb_half_dimm_mode_override(i_target, l_override_attr) );
- // Set half DIMM mode based upon the the normal attribute
- o_is_half_dimm_mode = l_half_dimm == fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_HALF_DIMM;
- FAPI_INF("%s is in enterprise mode %s override is present. The chip is in %s (attribute %u)", mss::c_str(i_target),
- "no", o_is_half_dimm_mode ? "half-DIMM mode" : "full-DIMM mode", l_half_dimm);
+ // o_is_half_dimm_mode will be set by the helper function
+ FAPI_TRY( mss::half_dimm_mode_helper(i_target, i_is_enterprise_mode, l_half_dimm_attr, l_override_attr,
+ o_is_half_dimm_mode));
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_draminit_utils.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_draminit_utils.C
index 30683e5bb..25a23285a 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_draminit_utils.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_draminit_utils.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -34,6 +34,9 @@
#include <generic/memory/lib/utils/c_str.H>
#include <lib/exp_draminit_utils.H>
+#include <lib/phy/exp_train_display.H>
+#include <lib/phy/exp_train_handler.H>
+#include <exp_inband.H>
namespace mss
{
@@ -41,23 +44,367 @@ namespace exp
{
///
-/// @brief host_fw_command_struct structure setup
+/// @brief Check that the rsp_data size returned from the PHY_INIT command matches the expected size
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_actual_size size enum expected for the given phy init mode
+/// @param[in] i_mode phy init mode. Expected to be a valid enum value since we asserted as such in exp_draminit.C
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff matching, else MSS_EXP_INVALID_PHY_INIT_RSP_DATA_LENGTH
+///
+fapi2::ReturnCode check_rsp_data_size(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint16_t i_actual_size,
+ const phy_init_mode i_mode)
+{
+ uint16_t l_expected_size = 0;
+
+ switch (i_mode)
+ {
+ case phy_init_mode::NORMAL:
+ l_expected_size = sizeof(user_response_msdg_t);
+ break;
+
+ case phy_init_mode::EYE_CAPTURE_STEP_1:
+ l_expected_size = sizeof(user_2d_eye_response_1_msdg_t);
+ break;
+
+ case phy_init_mode::EYE_CAPTURE_STEP_2:
+ l_expected_size = sizeof(user_2d_eye_response_2_msdg_t);
+ break;
+
+ default:
+ // This really can't occur since we asserted phy_init_mode was valid in exp_draminit.C
+ // We have bigger problems if we get here, implying somehow this bad value was passed to explorer
+ FAPI_ASSERT(false,
+ fapi2::MSS_EXP_UNKNOWN_PHY_INIT_MODE()
+ .set_TARGET(i_target)
+ .set_VALUE(i_mode),
+ "%s Value for phy init mode for exp_draminit is unknown: %u expected 0 (NORMAL), 1 (EYE_CAPTURE_STEP_1), 2 (EYE_CAPTURE_STEP_2)",
+ mss::c_str(i_target), i_mode);
+ break;
+ }
+
+ FAPI_ASSERT(l_expected_size == i_actual_size,
+ fapi2::MSS_EXP_INVALID_PHY_INIT_RSP_DATA_LENGTH()
+ .set_OCMB_TARGET(i_target)
+ .set_PHY_INIT_MODE(i_mode)
+ .set_EXPECTED_LENGTH(l_expected_size)
+ .set_ACTUAL_LENGTH(i_actual_size),
+ "%s PHY INIT response data buffer size 0x%x did not match expected size 0x%x for phy_init_mode %u",
+ mss::c_str(i_target), i_actual_size, l_expected_size, i_mode);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Perform normal host FW phy init
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_crc CRC value
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode host_fw_phy_normal_init(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint32_t i_crc)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ host_fw_command_struct l_cmd;
+ std::vector<uint8_t> l_rsp_data;
+
+ // Issue full boot mode cmd though EXP-FW REQ buffer
+ FAPI_TRY(send_host_phy_init_cmd(i_target, i_crc, phy_init_mode::NORMAL, l_cmd));
+ FAPI_TRY(mss::exp::check_host_fw_response(i_target, l_cmd, l_rsp_data, l_rc));
+
+ FAPI_TRY(check_rsp_data_size(i_target, l_rsp_data.size(), phy_init_mode::NORMAL));
+ FAPI_TRY(mss::exp::read_and_display_normal_training_repsonse(i_target, l_rsp_data, l_rc));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Perform host FW phy init with eye capture
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_crc CRC value
+/// @param[in] i_phy_params PHY params struct
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+/// @note the goal here is to attempt to send both phy_inits even in the event of a bad return code from the read & display
+///
+fapi2::ReturnCode host_fw_phy_init_with_eye_capture(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint32_t i_crc,
+ const user_input_msdg& i_phy_params)
+{
+ fapi2::ReturnCode l_check_response_1_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::ReturnCode l_read_display_response_1_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::ReturnCode l_check_response_2_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::ReturnCode l_read_display_response_2_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ user_2d_eye_response_1_msdg l_response_1;
+ user_2d_eye_response_2_msdg l_response_2;
+
+ std::vector<uint8_t> l_rsp_data;
+
+ // First, step 1
+ {
+ host_fw_command_struct l_cmd;
+ FAPI_TRY(send_host_phy_init_cmd(i_target, i_crc, phy_init_mode::EYE_CAPTURE_STEP_1, l_cmd));
+
+ // Return code output param is that of check::response
+ // A fail of getRSP will go to fapi_try_exit
+ FAPI_TRY(mss::exp::check_host_fw_response(i_target, l_cmd, l_rsp_data, l_check_response_1_rc));
+
+ l_read_display_response_1_rc = check_rsp_data_size(i_target,
+ l_rsp_data.size(),
+ phy_init_mode::EYE_CAPTURE_STEP_1);
+
+ // If the data is the right size, we can read and display it. Otherwise, skip the reading and try step 2
+ // Check the return codes at the end
+ if (l_read_display_response_1_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ l_read_display_response_1_rc = mss::exp::read_and_display_user_2d_eye_response(i_target, l_rsp_data, l_response_1);
+ }
+ }
+ l_rsp_data.clear();
+
+ // Next, step 2
+ {
+ host_fw_command_struct l_cmd;
+ uint32_t l_crc = 0;
+
+ // Put user_input_msdg again for step 2 (overwritten by data buffer from step 1)
+ FAPI_TRY( mss::exp::ib::putUserInputMsdg(i_target, i_phy_params, l_crc),
+ "Failed putUserInputMsdg() for %s", mss::c_str(i_target) );
+
+ // Send cmd
+ FAPI_TRY(send_host_phy_init_cmd(i_target, l_crc, phy_init_mode::EYE_CAPTURE_STEP_2, l_cmd));
+
+ // Return code output param is that of check::response
+ // A fail of getRSP will go to fapi_try_exit
+ FAPI_TRY(mss::exp::check_host_fw_response(i_target, l_cmd, l_rsp_data, l_check_response_2_rc));
+
+ l_read_display_response_2_rc = check_rsp_data_size(i_target,
+ l_rsp_data.size(),
+ phy_init_mode::EYE_CAPTURE_STEP_2);
+
+ // If the data is the right size, we can read and display it. Otherwise, skip the reading.
+ // Next, we will check these return codes
+ if (l_read_display_response_2_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ l_read_display_response_2_rc = mss::exp::read_and_display_user_2d_eye_response(i_target, l_rsp_data, l_response_2);
+ }
+ }
+
+ // Check the return codes
+ FAPI_TRY(process_eye_capture_return_codes(i_target,
+ l_response_1,
+ l_response_2,
+ l_check_response_1_rc,
+ l_check_response_2_rc));
+
+ // Finally, check the display response return codes
+ FAPI_TRY(l_read_display_response_1_rc, "Error ocurred reading/displaying eye capture response 1 of %s",
+ mss::c_str(i_target));
+ FAPI_TRY(l_read_display_response_2_rc, "Error ocurred reading/displaying eye capture response 2 of %s",
+ mss::c_str(i_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Process return codes from PHY init with eye capture operations
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_response_1 response struct for EYE_CAPTURE_STEP_1
+/// @param[in] i_response_2 response struct for EYE_CAPTURE_STEP_2
+/// @param[in] i_response_1_rc response from check_host_fw_response from EYE_CAPTURE_STEP_1
+/// @param[in] i_response_2_rc response from check_host_fw_response from EYE_CAPTURE_STEP_2
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else an error from above as defined in the function algorithm
+/// @note return codes are passed by value, caller should not expect these to change
+///
+fapi2::ReturnCode process_eye_capture_return_codes(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const user_2d_eye_response_1_msdg& i_response_1,
+ const user_2d_eye_response_2_msdg& i_response_2,
+ fapi2::ReturnCode i_response_1_rc,
+ fapi2::ReturnCode i_response_2_rc)
+{
+ const bool l_response_1_failed = i_response_1_rc != fapi2::FAPI2_RC_SUCCESS;
+ const bool l_response_2_failed = i_response_2_rc != fapi2::FAPI2_RC_SUCCESS;
+
+ if (l_response_2_failed)
+ {
+ FAPI_ERR("%s check_fw_host_response() for %s returned error code 0x%016llu",
+ mss::c_str(i_target), "EYE_CAPTURE_STEP_2", uint64_t(i_response_2_rc));
+
+ mss::exp::bad_bit_interface<user_2d_eye_response_2_msdg> l_interface_2(i_response_2);
+ FAPI_TRY(mss::record_bad_bits<mss::mc_type::EXPLORER>(i_target, l_interface_2));
+
+ if (l_response_1_failed)
+ {
+ // Log response 2's error, and let's return response 1
+ fapi2::logError(i_response_2_rc, fapi2::FAPI2_ERRL_SEV_RECOVERED);
+
+ // logError sets the return code& to NULL. Set to FAPI2_RC_SUCCESS in case of use
+ i_response_2_rc = fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ FAPI_TRY(i_response_2_rc);
+ }
+
+ if (l_response_1_failed)
+ {
+ FAPI_ERR("%s check_fw_host_response() for %s returned error code 0x%016llu",
+ mss::c_str(i_target), "EYE_CAPTURE_STEP_1", uint64_t(i_response_1_rc));
+
+ mss::exp::bad_bit_interface<user_2d_eye_response_1_msdg> l_interface_1(i_response_1);
+ FAPI_TRY(mss::record_bad_bits<mss::mc_type::EXPLORER>(i_target, l_interface_1));
+
+ return i_response_1_rc;
+ }
+
+ // Else, we did not see errors!
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Send PHY init command given the provided phy mode and CRC
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_crc CRC field
+/// @param[in] i_phy_init_mode normal / eye capture step 1 or 2
+/// @param[out] host_fw_command_struct used for initialization
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode send_host_phy_init_cmd(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint32_t i_crc,
+ const uint8_t i_phy_init_mode,
+ host_fw_command_struct& o_cmd)
+{
+ host_fw_command_struct l_cmd;
+
+ // Issue full boot mode cmd though EXP-FW REQ buffer
+ FAPI_TRY(setup_cmd_params(i_target, i_crc, sizeof(user_input_msdg), i_phy_init_mode, l_cmd));
+ FAPI_TRY(mss::exp::ib::putCMD(i_target, l_cmd),
+ "Failed putCMD() for %s", mss::c_str(i_target));
+
+ // Wait a bit for the command (and training) to complete
+ // Value based on initial Explorer hardware in Cronus in i2c mode.
+ // Training takes ~10ms with no trace, ~450ms with Explorer UART debug
+ FAPI_TRY(fapi2::delay((mss::DELAY_1MS * 8), 200));
+
+ o_cmd = l_cmd;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get and check the host fw response from the explorer
+///
+/// @param[in] i_target OCMB chip
+/// @param[in] i_cmd host_fw_command_struct used to generate the response
+/// @param[out] o_rsp_data response data
+/// @param[out] o_rc return code from mss::exp::check::response()
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode check_host_fw_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ host_fw_command_struct& i_cmd,
+ std::vector<uint8_t>& o_rsp_data,
+ fapi2::ReturnCode& o_rc)
+{
+ host_fw_response_struct l_response;
+
+ FAPI_TRY(mss::exp::ib::getRSP(i_target, l_response, o_rsp_data),
+ "Failed getRSP() for %s", mss::c_str(i_target));
+
+ o_rc = mss::exp::check::response(i_target, l_response, i_cmd);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Reads and displays the normal draminit training response
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_resp_data RESP data
+/// @param[in] i_rc return code from checking response
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode read_and_display_normal_training_repsonse(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t> i_resp_data,
+ const fapi2::ReturnCode i_rc)
+{
+ user_response_msdg l_train_response;
+
+ // Proccesses the response data
+ FAPI_TRY( mss::exp::read_normal_training_response(i_target, i_resp_data, l_train_response),
+ "Failed read_normal_training_response for %s", mss::c_str(i_target));
+
+ // Displays the training response
+ FAPI_INF("%s displaying user response data version %u", mss::c_str(i_target), l_train_response.version_number)
+ FAPI_TRY( mss::exp::train::display_normal_info(i_target, l_train_response));
+
+ if(i_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ mss::exp::bad_bit_interface<user_response_msdg> l_interface(l_train_response);
+ FAPI_TRY(mss::record_bad_bits<mss::mc_type::EXPLORER>(i_target, l_interface));
+ FAPI_TRY(i_rc, "mss::exp::check::response failed for %s", mss::c_str(i_target));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief host_fw_phy_init_command_struct structure setup
+///
+/// @param[in] i_target OCMB target
/// @param[in] i_cmd_data_crc the command data CRC
+/// @param[in] i_cmd_length the length of the command present in the data buffer (if any)
+/// @param[in] i_phy_init_mode PHY init mode
/// @param[out] o_cmd the command parameters to set
///
-void setup_cmd_params(const uint32_t i_cmd_data_crc, host_fw_command_struct& o_cmd)
+fapi2::ReturnCode setup_cmd_params(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint32_t i_cmd_data_crc,
+ const uint32_t i_cmd_length,
+ const uint8_t i_phy_init_mode,
+ host_fw_command_struct& o_cmd)
{
+ memset(&o_cmd, 0, sizeof(host_fw_command_struct));
// Issue full boot mode cmd though EXP-FW REQ buffer
+ // Explicit with all of these (including 0 values) to avoid ambiguity
o_cmd.cmd_id = mss::exp::omi::EXP_FW_DDR_PHY_INIT;
- o_cmd.cmd_flags = 0;
- // TK - Fabricated value need to figure out if we'll be creating req_id tables
- o_cmd.request_identifier = 0xBB;
- o_cmd.cmd_length = 0;
+ // Retrieve a unique sequence id for this transaction
+ uint32_t l_counter = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_OCMB_COUNTER, i_target, l_counter));
+ o_cmd.request_identifier = l_counter;
+
+ // With cmd_length > 0, data exists in the extended data buffer. Must set cmd_flags to 1. However,
+ // eye capture step 2 needs cmd_flags to be set to zero as defined in MCHP spec section 5.4.3 Eye Capture
+ // despite having data in the extended data buffer
+ o_cmd.cmd_flags = ((i_cmd_length > 0) && (i_phy_init_mode != phy_init_mode::EYE_CAPTURE_STEP_2)) ? 1 : 0;
+
+ o_cmd.cmd_length = i_cmd_length;
o_cmd.cmd_crc = i_cmd_data_crc;
o_cmd.host_work_area = 0;
o_cmd.cmd_work_area = 0;
- memset(o_cmd.padding, 0, sizeof(o_cmd.padding));
+
+ // According to the spec Table 5-2, phy_init_mode takes the place of command_argument[0]
+ o_cmd.command_argument[0] = i_phy_init_mode;
+
+fapi_try_exit:
+ return fapi2::current_err;
}
///
@@ -77,6 +424,7 @@ fapi2::ReturnCode setup_phy_params(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_C
FAPI_TRY(l_rc, "Unable to instantiate phy_params for target %s", mss::c_str(i_target));
// Set the params by fetching them from the attributes
+ FAPI_TRY(l_set_phy_params.set_version_number(o_phy_params));
FAPI_TRY(l_set_phy_params.setup_DimmType(o_phy_params));
FAPI_TRY(l_set_phy_params.setup_CsPresent(o_phy_params));
FAPI_TRY(l_set_phy_params.setup_DramDataWidth(o_phy_params));
@@ -89,9 +437,11 @@ fapi2::ReturnCode setup_phy_params(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_C
FAPI_TRY(l_set_phy_params.set_SpdCLSupported(o_phy_params));
FAPI_TRY(l_set_phy_params.set_SpdtAAmin(o_phy_params));
FAPI_TRY(l_set_phy_params.set_Rank4Mode(o_phy_params));
+ FAPI_TRY(l_set_phy_params.set_EncodedQuadCs(o_phy_params));
FAPI_TRY(l_set_phy_params.set_DDPCompatible(o_phy_params));
FAPI_TRY(l_set_phy_params.set_TSV8HSupport(o_phy_params));
FAPI_TRY(l_set_phy_params.set_MRAMSupport(o_phy_params));
+ FAPI_TRY(l_set_phy_params.set_MDSSupport(o_phy_params));
FAPI_TRY(l_set_phy_params.set_NumPStates(o_phy_params));
FAPI_TRY(l_set_phy_params.set_Frequency(o_phy_params));
FAPI_TRY(l_set_phy_params.set_PhyOdtImpedance(o_phy_params));
@@ -133,7 +483,10 @@ fapi2::ReturnCode setup_phy_params(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_C
FAPI_TRY(l_set_phy_params.set_RcdDBDic(o_phy_params));
FAPI_TRY(l_set_phy_params.set_RcdSlewRate(o_phy_params));
- FAPI_TRY(l_set_phy_params.set_EmulationSupport(o_phy_params));
+
+ FAPI_TRY(l_set_phy_params.set_DFIMRL_DDRCLK(o_phy_params));
+ FAPI_TRY(l_set_phy_params.set_ATxDly_A(o_phy_params));
+ FAPI_TRY(l_set_phy_params.set_ATxDly_B(o_phy_params));
}
return fapi2::FAPI2_RC_SUCCESS;
@@ -152,15 +505,29 @@ namespace check
/// @return FAPI2_RC_SUCCESS iff okay
///
fapi2::ReturnCode response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
- const host_fw_response_struct& i_rsp)
+ const host_fw_response_struct& i_rsp,
+ const host_fw_command_struct& i_cmd)
{
+ fapi2::buffer<uint32_t> l_error_code;
+
+ l_error_code.insertFromRight<0, BITS_PER_BYTE>(i_rsp.response_argument[4]).
+ insertFromRight<BITS_PER_BYTE, BITS_PER_BYTE>(i_rsp.response_argument[3]).
+ insertFromRight<2 * BITS_PER_BYTE, BITS_PER_BYTE>(i_rsp.response_argument[2]).
+ insertFromRight<3 * BITS_PER_BYTE, BITS_PER_BYTE>(i_rsp.response_argument[1]);
+
// Check if cmd was successful
- FAPI_ASSERT(i_rsp.response_argument[0] == omi::response_arg::SUCCESS,
+ FAPI_ASSERT(i_rsp.response_argument[0] == omi::response_arg::SUCCESS &&
+ i_rsp.request_identifier == i_cmd.request_identifier,
fapi2::MSS_EXP_RSP_ARG_FAILED().
set_TARGET(i_target).
set_RSP_ID(i_rsp.response_id).
- set_ERROR_CODE(i_rsp.response_argument[1]),
- "Failed to initialize the PHY for %s", mss::c_str(i_target));
+ set_ERROR_CODE(l_error_code).
+ set_EXPECTED_REQID(i_cmd.request_identifier).
+ set_ACTUAL_REQID(i_rsp.request_identifier),
+ "Failed to initialize the PHY for %s, response=0x%X, error_code=0x%08X "
+ "RSP RQ ID: %u CMD RQ ID: %u",
+ mss::c_str(i_target), i_rsp.response_argument[0], l_error_code,
+ i_rsp.request_identifier, i_cmd.request_identifier);
return fapi2::FAPI2_RC_SUCCESS;
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_draminit_utils.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_draminit_utils.H
index 7ffe531ce..096cfcd60 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_draminit_utils.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_draminit_utils.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,6 +37,8 @@
#define __MSS_EXP_DRAMINIT_UTILS__
#include <fapi2.H>
+#include <lib/shared/exp_defaults.H>
+#include <lib/dimm/exp_rank.H>
#include <lib/shared/exp_consts.H>
#include <exp_data_structs.H>
#include <mss_generic_attribute_getters.H>
@@ -44,6 +46,10 @@
#include <generic/memory/lib/utils/c_str.H>
#include <generic/memory/lib/utils/find.H>
#include <generic/memory/lib/utils/mss_buffer_utils.H>
+#include <lib/phy/exp_train_display.H>
+#include <lib/phy/exp_train_handler.H>
+#include <exp_data_structs.H>
+#include <stdio.h>
namespace mss
{
@@ -51,13 +57,25 @@ namespace exp
{
///
+/// @brief Phy init mode for host_fw_command struct
+///
+enum phy_init_mode
+{
+ NORMAL = 0,
+ EYE_CAPTURE_STEP_1 = 1,
+ EYE_CAPTURE_STEP_2 = 2,
+};
+
+///
/// @brief defines the supported DIMM types in Explorer
///
enum msdg_dimm_types
{
- MSDG_UDIMM = 0x0000,
- MSDG_RDIMM = 0x0001,
- MSDG_LRDIMM = 0x0002,
+ MSDG_UDIMM = 0x0000,
+ MSDG_RDIMM = 0x0001,
+ MSDG_LRDIMM = 0x0002,
+ MSDG_MDS_LRDIMM = 0x0003,
+ MSDG_MDS = 0x0004
};
///
@@ -71,6 +89,15 @@ enum msdg_dram_data_width
};
///
+/// @brief Defines CS encoding mode
+///
+enum msdg_cs_encode_mode
+{
+ MSDG_QUAD_ENCODE_MODE = 1,
+ MSDG_DUAL_DIRECT_MODE = 0,
+};
+
+///
/// @brief defines the valid 3DS stack in Explorer
///
enum msdg_height_3DS
@@ -123,11 +150,154 @@ enum msdg_enable
};
///
+/// @brief defines fields for the ODT RD/WR params
+///
+enum odt_fields
+{
+ R2_FLD_LENGTH = 2, // R2 = 2 rank (normal / 2 rank mode: makes use of 2 bits)
+ R4_FLD_LENGTH = 4, // R4 = 4 rank (4 rank mode: makes use of 4 bits)
+ ODT_MIDPOINT = 4,
+ R4_SHIFT = 2,
+ RANK3 = 12,
+ RANK2 = 8,
+ RANK1 = 4,
+ RANK0 = 0,
+};
+
+///
+/// @brief Check that the rsp_data size returned from the PHY_INIT command matches the expected size
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_actual_size size enum expected for the given phy init mode
+/// @param[in] i_mode phy init mode. Expected to be a valid enum value since we asserted as such in exp_draminit.C
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff matching, else MSS_EXP_INVALID_PHY_INIT_RSP_DATA_LENGTH
+///
+fapi2::ReturnCode check_rsp_data_size(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint16_t i_actual_size,
+ const phy_init_mode i_mode);
+
+///
+/// @brief Perform normal host FW phy init
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_crc CRC value
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode host_fw_phy_normal_init(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint32_t i_crc);
+
+///
+/// @brief Perform host FW phy init with eye capture
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_crc CRC value
+/// @param[in] i_phy_params PHY params struct
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+/// @note the goal here is to attempt to send both phy_inits even in the event of a bad return code from the read & display
+///
+fapi2::ReturnCode host_fw_phy_init_with_eye_capture(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint32_t i_crc,
+ const user_input_msdg& i_phy_params);
+
+///
+/// @brief Process return codes from PHY init with eye capture operations
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_response_1 response struct for EYE_CAPTURE_STEP_1
+/// @param[in] i_response_2 response struct for EYE_CAPTURE_STEP_2
+/// @param[in] i_response_1_rc response from check_host_fw_response from EYE_CAPTURE_STEP_1
+/// @param[in] i_response_2_rc response from check_host_fw_response from EYE_CAPTURE_STEP_2
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else an error from above as defined in the function algorithm
+/// @note return codes are passed by value, caller should not expect these to change
+///
+fapi2::ReturnCode process_eye_capture_return_codes(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const user_2d_eye_response_1_msdg& i_response_1,
+ const user_2d_eye_response_2_msdg& i_response_2,
+ fapi2::ReturnCode i_response_1_rc,
+ fapi2::ReturnCode i_response_2_rc);
+
+///
+/// @brief Send PHY init command given the provided phy mode and CRC
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_crc CRC field
+/// @param[in] i_phy_init_mode normal / eye capture step 1 or 2
+/// @param[out] host_fw_command_struct used for initialization
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode send_host_phy_init_cmd(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint32_t i_crc,
+ const uint8_t i_phy_init_mode,
+ host_fw_command_struct& o_cmd);
+
+///
+/// @brief Get and check the host fw response from the explorer
+/// @param[in] i_target OCMB chip
+/// @param[in] i_cmd host_fw_command_struct used to generate the response
+/// @param[out] o_rsp_data response data
+/// @param[out] o_rc return code from mss::exp::check::response()
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode check_host_fw_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ host_fw_command_struct& i_cmd,
+ std::vector<uint8_t>& o_rsp_data,
+ fapi2::ReturnCode& o_rc);
+
+///
+/// @brief Reads and displays the normal draminit training response
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_resp_data RESP data
+/// @param[in] i_rc return code from checking response
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode read_and_display_normal_training_repsonse(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t> i_resp_data,
+ const fapi2::ReturnCode i_rc);
+
+///
+/// @brief Reads and displays the user 2d eye response 1
+///
+/// @tparam T response struct
+/// @param[in] i_target OCMB target
+/// @param[in] i_resp_data RESP data
+/// @param[out] o_rc return code from checking response
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff success
+///
+template <typename T>
+inline fapi2::ReturnCode read_and_display_user_2d_eye_response(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t> i_resp_data,
+ T& o_train_response)
+{
+ // Proccesses the response data
+ FAPI_TRY(mss::exp::read_user_2d_eye_response<T>(i_target, i_resp_data, o_train_response),
+ "Failed read_training_response for %s", mss::c_str(i_target));
+
+ // Displays the training response
+ FAPI_TRY(mss::exp::train::display_user_2d_eye_info<T>(i_target, o_train_response));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief host_fw_command_struct structure setup
+/// @param[in] i_target the OCMB being acted upon
/// @param[in] i_cmd_data_crc the command data CRC
+/// @param[in] i_cmd_length the length of the command present in the data buffer (if any)
+/// @param[in] i_phy_init_mode PHY init mode
/// @param[out] o_cmd the command parameters to set
+/// @return FAPI2_RC_SUCCESS iff okay
///
-void setup_cmd_params(const uint32_t i_cmd_data_crc, host_fw_command_struct& o_cmd);
+fapi2::ReturnCode setup_cmd_params(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint32_t i_cmd_data_crc,
+ const uint32_t i_cmd_length,
+ const uint8_t i_phy_init_mode,
+ host_fw_command_struct& o_cmd);
///
/// @brief user_input_msdg structure setup
@@ -148,10 +318,11 @@ struct phy_params_t
///
/// Declare variables to be used
///
+ uint32_t iv_version_number;
uint8_t iv_dimm_type[MAX_DIMM_PER_PORT];
- uint16_t iv_chip_select;
+ uint8_t iv_chip_select[MAX_DIMM_PER_PORT];
uint8_t iv_dram_data_width[MAX_DIMM_PER_PORT];
- uint16_t iv_height_3DS;
+ uint16_t iv_height_3DS[MAX_DIMM_PER_PORT];
uint16_t iv_dbyte_macro[MAX_DIMM_PER_PORT];
uint32_t iv_nibble[MAX_DIMM_PER_PORT];
uint8_t iv_addr_mirror[MAX_DIMM_PER_PORT];
@@ -160,14 +331,16 @@ struct phy_params_t
uint32_t iv_spdcl_support;
uint16_t iv_taa_min;
uint8_t iv_rank4_mode[MAX_DIMM_PER_PORT];
+ uint16_t iv_encoded_quadcs;
uint8_t iv_ddp_compatible[MAX_DIMM_PER_PORT];
uint8_t iv_tsv8h[MAX_DIMM_PER_PORT];
uint8_t iv_mram_support[MAX_DIMM_PER_PORT];
+ uint8_t iv_mdssupport;
uint8_t iv_num_pstate[MAX_DIMM_PER_PORT];
uint64_t iv_frequency;
uint8_t iv_odt_impedance[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
- uint8_t iv_drv_impedance_pu[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
- uint8_t iv_drv_impedance_pd[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
+ uint16_t iv_drv_impedance_pu[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
+ uint16_t iv_drv_impedance_pd[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
uint8_t iv_slew_rate[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
uint8_t iv_atx_impedance[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
uint8_t iv_atx_slew_rate[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
@@ -180,8 +353,8 @@ struct phy_params_t
uint8_t iv_dram_dic[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
uint8_t iv_dram_preamble[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
uint8_t iv_phy_equalization[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
- uint8_t iv_init_vref_dq;
- uint16_t iv_init_phy_vref;
+ uint8_t iv_init_vref_dq[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
+ uint8_t iv_init_phy_vref[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
uint8_t iv_odt_wr_map_cs[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
uint8_t iv_odt_rd_map_cs[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
uint8_t iv_geardown_mode[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM];
@@ -193,7 +366,9 @@ struct phy_params_t
uint8_t iv_f0rc7x[MAX_DIMM_PER_PORT];
uint8_t iv_f1rc00[MAX_DIMM_PER_PORT];
uint16_t iv_rcd_slew_rate;
- uint8_t iv_firmware_mode;
+ uint8_t iv_dfimrl_ddrclk;
+ uint8_t iv_atxdly_a[DRAMINIT_NUM_ADDR_DELAYS];
+ uint8_t iv_atxdly_b[DRAMINIT_NUM_ADDR_DELAYS];
};
///
@@ -208,6 +383,7 @@ class phy_params
fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> iv_target;
phy_params_t iv_params;
+ std::vector<mss::rank::info<>> iv_rank_info;
public:
@@ -219,17 +395,18 @@ class phy_params
///
/// @brief fetch the attributes and initialize it to the params
/// @param[in] i_target the fapi2 target
- /// @param[in,out] o_rc the fapi2 output
+ /// @param[out] o_rc the fapi2 output
///
phy_params(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
- fapi2::ReturnCode o_rc):
+ fapi2::ReturnCode& o_rc):
iv_target(i_target)
{
+ uint8_t l_master_ranks[MAX_DIMM_PER_PORT] = {};
// Fetch attributes and populate the member variables
FAPI_TRY(mss::attr::get_dimm_type(i_target, iv_params.iv_dimm_type));
- FAPI_TRY(mss::attr::get_exp_cs_present(i_target, iv_params.iv_chip_select));
+ FAPI_TRY(mss::attr::get_dimm_ranks_configed(i_target, iv_params.iv_chip_select));
FAPI_TRY(mss::attr::get_dram_width(i_target, iv_params.iv_dram_data_width));
- FAPI_TRY(mss::attr::get_exp_3ds_height(i_target, iv_params.iv_height_3DS));
+ FAPI_TRY(mss::attr::get_3ds_height(i_target, iv_params.iv_height_3DS));
FAPI_TRY(mss::attr::get_byte_enables(i_target, iv_params.iv_dbyte_macro));
FAPI_TRY(mss::attr::get_nibble_enables(i_target, iv_params.iv_nibble));
FAPI_TRY(mss::attr::get_exp_dram_address_mirroring(i_target, iv_params.iv_addr_mirror));
@@ -241,6 +418,7 @@ class phy_params
FAPI_TRY(mss::attr::get_ddp_compatibility(i_target, iv_params.iv_ddp_compatible));
FAPI_TRY(mss::attr::get_tsv_8h_support(i_target, iv_params.iv_tsv8h));
FAPI_TRY(mss::attr::get_mram_support(i_target, iv_params.iv_mram_support));
+ FAPI_TRY(mss::attr::get_dram_mds(i_target, iv_params.iv_mdssupport));
FAPI_TRY(mss::attr::get_pstates(i_target, iv_params.iv_num_pstate));
FAPI_TRY(mss::attr::get_freq(i_target, iv_params.iv_frequency));
FAPI_TRY(mss::attr::get_si_mc_rcv_imp_dq_dqs(i_target, iv_params.iv_odt_impedance));
@@ -271,7 +449,25 @@ class phy_params
FAPI_TRY(mss::attr::get_dimm_ddr4_f0rc7x(i_target, iv_params.iv_f0rc7x));
FAPI_TRY(mss::attr::get_dimm_ddr4_f1rc00(i_target, iv_params.iv_f1rc00));
FAPI_TRY(mss::attr::get_exp_rcd_slew_rate(i_target, iv_params.iv_rcd_slew_rate));
- FAPI_TRY(mss::attr::get_exp_firmware_emulation_mode(i_target, iv_params.iv_firmware_mode));
+ FAPI_TRY(mss::attr::get_exp_dfimrl_clk(i_target, iv_params.iv_dfimrl_ddrclk));
+ FAPI_TRY(mss::attr::get_exp_atxdly_a(i_target, iv_params.iv_atxdly_a));
+ FAPI_TRY(mss::attr::get_exp_atxdly_b(i_target, iv_params.iv_atxdly_b));
+
+ // TK update this if/when Microchip responds
+ iv_params.iv_version_number = DRAMINIT_STRUCTURE_VERSION;
+
+ // We're in quad encoded mode IF
+ // 1) 4R per DIMM
+ // 2) we have an RDIMM
+ FAPI_TRY(mss::attr::get_num_master_ranks_per_dimm(i_target, l_master_ranks));
+ {
+ const bool l_has_rcd = iv_params.iv_dimm_type[0] == fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_RDIMM ||
+ iv_params.iv_dimm_type[0] == fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_LRDIMM;
+ const bool l_4r = l_master_ranks[0] == fapi2::ENUM_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM_4R;
+ iv_params.iv_encoded_quadcs = (l_has_rcd && l_4r) ? MSDG_QUAD_ENCODE_MODE : MSDG_DUAL_DIRECT_MODE;
+ }
+
+ FAPI_TRY(mss::rank::ranks_on_port(i_target, iv_rank_info));
fapi_try_exit:
o_rc = fapi2::current_err;
@@ -283,11 +479,14 @@ class phy_params
/// @brief Set params as per the value initialized (useful for testing)
/// @param[in] i_target the fapi2 target
/// @param[in] i_phy_params explorer specific data structure
+ /// @param[out] o_rc Return code from rank API initialization
///
phy_params(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
- const phy_params_t& i_phy_params):
+ const phy_params_t& i_phy_params,
+ const std::vector<mss::rank::info<>> i_rank_info):
iv_target(i_target),
- iv_params(i_phy_params)
+ iv_params(i_phy_params),
+ iv_rank_info(i_rank_info)
{}
///
@@ -296,6 +495,129 @@ class phy_params
~phy_params() = default;
///
+ /// @brief Set the rank-based phy field from the attribute
+ ///
+ /// @param[in] i_phy_param_ranks array of pointers to the rank fields to be filled in
+ /// @param[in] i_phy_param_attr pointer to the iv array indexed by dimm & rank
+ /// @note this function assumes i_phy_param_ranks is properly populated with 4 fields (1 per phy rank)
+ ///
+ void set_phy_field_by_rank(const std::vector<uint16_t*>& i_phy_param_ranks,
+ const uint8_t (&i_phy_param_attr)[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM]) const
+ {
+ // First, zero everything out
+ for (uint8_t l_rank = 0; l_rank < i_phy_param_ranks.size(); ++l_rank)
+ {
+ *i_phy_param_ranks[l_rank] = 0;
+ }
+
+ // For each rank, the phy rank value (0-4) is what needs to be filled in for draminit
+ // This maps to the field corresponding to the ATTR index value
+ // indexed by the rank's dimm index and dimm rank
+ for (const auto& l_rank : iv_rank_info)
+ {
+ const uint8_t l_dimm_index = mss::index(l_rank.get_dimm_target());
+ const uint8_t l_dimm_rank = l_rank.get_dimm_rank();
+ *i_phy_param_ranks[l_rank.get_phy_rank()] = i_phy_param_attr[l_dimm_index][l_dimm_rank];
+ }
+ }
+
+ ///
+ /// @brief Maps the ODT RD/WR attributes to the form needed for exp_draminit
+ ///
+ /// @param[in] i_odt_rd_wr_attr iv array indexed by dimm & rank
+ /// @param[out] o_odt_buffer buffer to populate
+ ///
+ fapi2::ReturnCode populate_odt_buffer(const uint8_t (&i_odt_rd_wr_attr)[MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM],
+ fapi2::buffer<uint16_t>& o_odt_buffer) const
+ {
+ // TK - Update code for encoded quad CS, waiting on SPD
+ // static constexpr bool ENCODED_QUAD_CS_ENABLE = true;
+
+ // Const vector to map phy ranks to their buffer offset position
+ const std::vector<uint8_t> l_buffer_rank_offset =
+ {
+ odt_fields::RANK0,
+ odt_fields::RANK1,
+ odt_fields::RANK2,
+ odt_fields::RANK3,
+ };
+
+ for (const auto& l_rank : iv_rank_info)
+ {
+ if (iv_params.iv_rank4_mode[0] == fapi2::ENUM_ATTR_MEM_EFF_FOUR_RANK_MODE_ENABLE)
+ {
+ // A & B separate. We need to do a bit if shifting from our attribute
+ // our attribute is aligned XX00YY00 but we want XXYY0000
+ // The attr must be populated this way, as we only have 4 ODTs and they are aligned as such
+ // Otherwise, we have problems on the SPD/decoder side
+ // where XX is A0A1 (bits 0,1) and YY is B0B1 (bits 4,5)
+
+ // From MCHP spec:
+ // OdtRdMapCs BIT [1:0] ODT_A[1:0] value when reading to rank 0
+ // OdtRdMapCs BIT [3:2] ODT_B[1:0] value when reading to rank 0
+ // ...
+
+ const auto OFFSET = l_buffer_rank_offset[l_rank.get_phy_rank()];
+ const auto DIMM_RANK = l_rank.get_dimm_rank();
+ const auto DIMM_INDEX = mss::index(l_rank.get_dimm_target());
+
+ uint8_t l_data = 0;
+
+ // l_data populated as such:
+ // XX000000 || 0000YY00 << 2
+ l_data = i_odt_rd_wr_attr[DIMM_INDEX][DIMM_RANK];
+ l_data |= (i_odt_rd_wr_attr[DIMM_INDEX][DIMM_RANK] << odt_fields::R4_SHIFT);
+
+ // Sanity check: bitwise and the relevant bits
+ l_data &= 0b11110000;
+
+ // Now we have XXYY0000
+ // Insert into the buffer
+ FAPI_TRY(o_odt_buffer.insert(l_data, OFFSET, odt_fields::R4_FLD_LENGTH));
+ }
+ // TK: need more information for encoded_quadcs (4U only)
+ // else if (iv_params.iv_encoded_quadcs == ENCODED_QUAD_CS_ENABLE)
+ // {
+ // }
+ else
+ {
+ // For DDIMM:
+ // A & B together. B0 (ODT2) mirrors A0 (ODT0), B1 (ODT3) mirrors A1 (ODT1)
+ // ODTA/B [1:0] == [ODT3/1:ODT2/0]
+
+ // From MCHP spec:
+ // OdtRdMapCs BIT [1:0] ODTA/B[1:0] value when reading to rank 0
+ // So it already accounts for any mirroring, we just need to plop in the value
+
+ const auto OFFSET = l_buffer_rank_offset[l_rank.get_phy_rank()];
+ const auto DIMM_RANK = l_rank.get_dimm_rank();
+ const auto DIMM_INDEX = mss::index(l_rank.get_dimm_target());
+
+ uint8_t l_data = 0;
+ l_data = i_odt_rd_wr_attr[DIMM_INDEX][DIMM_RANK];
+
+ // Finally, put it back
+
+ // Insert l_data (attribute) from the corresponding dimm's position:
+ // DIMM0 (ODT0, ODT1) (bits 0,1) or DIMM1 ODT0, ODT1 (bits 4,5) (though DIMM1 probably wouldn't be applicable here)
+ // at the offset to match the draminit field.
+ //
+ FAPI_TRY(o_odt_buffer.insert(l_data, OFFSET, odt_fields::R2_FLD_LENGTH, DIMM_INDEX * odt_fields::ODT_MIDPOINT));
+ }
+ }
+
+ // Rest of the buffer should already be zeroed from declaration
+ // Our attribute values come in left aligned (LSB left), our buffers are left aligned, but MCHP wants things right aligned:
+ // (rank0 == [1:0], rank1 == [5:4])
+ // So we can set it up from the buffer perspective, but then flip the whole buffer, getting the values back to their
+ // correct form (MSB right aligned) in addition to flipping the rank positions to their expected locations
+ o_odt_buffer.reverse();
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
/// @brief user_input_msdg structure setup for parameter DimmType
/// @param[in,out] io_phy_params the phy params data struct
/// @return FAPI2_RC_SUCCESS iff okay
@@ -308,6 +630,9 @@ class phy_params
io_phy_params.DimmType = MSDG_RDIMM;
break;
+ // TK this will need to be updated for the 4U explorer card
+ // For 1U/2U (what we're working on now), the DDIMM means an unregistered MC to DRAM interface
+ case fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_DDIMM:
case fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_UDIMM:
io_phy_params.DimmType = MSDG_UDIMM;
break;
@@ -316,6 +641,14 @@ class phy_params
io_phy_params.DimmType = MSDG_LRDIMM;
break;
+ case fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_MDS_LRDIMM:
+ io_phy_params.DimmType = MSDG_MDS_LRDIMM;
+ break;
+
+ case fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_MDS:
+ io_phy_params.DimmType = MSDG_MDS;
+ break;
+
default:
const auto& l_ocmb = mss::find_target<fapi2::TARGET_TYPE_OCMB_CHIP>(iv_target);
FAPI_ASSERT(false,
@@ -341,7 +674,14 @@ class phy_params
///
fapi2::ReturnCode setup_CsPresent(user_input_msdg& io_phy_params) const
{
- io_phy_params.CsPresent = iv_params.iv_chip_select;
+ fapi2::buffer<uint8_t> l_cs_present(iv_params.iv_chip_select[0]);
+
+ // Flip buffer (Needs to be right aligned, currently 0bXXXX0000)
+ l_cs_present.reverse();
+
+ // Now extend to 16 bits for phy_params struct
+ io_phy_params.CsPresent = static_cast<uint16_t>(l_cs_present);
+
return fapi2::FAPI2_RC_SUCCESS;
}
@@ -391,21 +731,21 @@ class phy_params
///
fapi2::ReturnCode setup_Height3DS(user_input_msdg& io_phy_params) const
{
- switch (iv_params.iv_height_3DS)
+ switch (iv_params.iv_height_3DS[0])
{
- case fapi2::ENUM_ATTR_MEM_EXP_3DS_HEIGHT_PLANAR:
+ case fapi2::ENUM_ATTR_MEM_3DS_HEIGHT_PLANAR:
io_phy_params.Height3DS = MSDG_PLANAR;
break;
- case fapi2::ENUM_ATTR_MEM_EXP_3DS_HEIGHT_H2:
+ case fapi2::ENUM_ATTR_MEM_3DS_HEIGHT_H2:
io_phy_params.Height3DS = MSDG_H2;
break;
- case fapi2::ENUM_ATTR_MEM_EXP_3DS_HEIGHT_H4:
+ case fapi2::ENUM_ATTR_MEM_3DS_HEIGHT_H4:
io_phy_params.Height3DS = MSDG_H4;
break;
- case fapi2::ENUM_ATTR_MEM_EXP_3DS_HEIGHT_H8:
+ case fapi2::ENUM_ATTR_MEM_3DS_HEIGHT_H8:
io_phy_params.Height3DS = MSDG_H8;
break;
@@ -415,9 +755,9 @@ class phy_params
fapi2::MSS_EXP_DRAMINIT_UNSUPPORTED_3DS_HEIGHT().
set_OCMB_TARGET(l_ocmb).
set_PORT(iv_target).
- set_HEIGHT(iv_params.iv_height_3DS),
+ set_HEIGHT(iv_params.iv_height_3DS[0]),
"%s 3DS Height is not a supported (%d)",
- mss::c_str(iv_target), iv_params.iv_height_3DS);
+ mss::c_str(iv_target), iv_params.iv_height_3DS[0]);
break;
}
@@ -567,7 +907,8 @@ class phy_params
///
fapi2::ReturnCode set_Frequency(user_input_msdg& io_phy_params) const
{
- io_phy_params.Frequency[0] = static_cast<uint16_t>(iv_params.iv_frequency);
+ // Divide by 2 to convert from DRAM freq to MEMCLK freq
+ io_phy_params.Frequency[0] = static_cast<uint16_t>(iv_params.iv_frequency / 2);
return fapi2::FAPI2_RC_SUCCESS;
}
@@ -677,10 +1018,15 @@ class phy_params
///
fapi2::ReturnCode set_RttNom(user_input_msdg& io_phy_params) const
{
- io_phy_params.DramRttNomR0[0] = iv_params.iv_dram_rtt_nom[0][0];
- io_phy_params.DramRttNomR1[0] = iv_params.iv_dram_rtt_nom[0][1];
- io_phy_params.DramRttNomR2[0] = iv_params.iv_dram_rtt_nom[0][2];
- io_phy_params.DramRttNomR3[0] = iv_params.iv_dram_rtt_nom[0][3];
+ const std::vector<uint16_t*> l_rtt_noms =
+ {
+ &io_phy_params.DramRttNomR0[0],
+ &io_phy_params.DramRttNomR1[0],
+ &io_phy_params.DramRttNomR2[0],
+ &io_phy_params.DramRttNomR3[0],
+ };
+
+ set_phy_field_by_rank(l_rtt_noms, iv_params.iv_dram_rtt_nom);
return fapi2::FAPI2_RC_SUCCESS;
}
@@ -691,10 +1037,15 @@ class phy_params
///
fapi2::ReturnCode set_RttWr(user_input_msdg& io_phy_params) const
{
- io_phy_params.DramRttWrR0[0] = iv_params.iv_dram_rtt_wr[0][0];
- io_phy_params.DramRttWrR1[0] = iv_params.iv_dram_rtt_wr[0][1];
- io_phy_params.DramRttWrR2[0] = iv_params.iv_dram_rtt_wr[0][2];
- io_phy_params.DramRttWrR3[0] = iv_params.iv_dram_rtt_wr[0][3];
+ const std::vector<uint16_t*> l_rtt_wrs =
+ {
+ &io_phy_params.DramRttWrR0[0],
+ &io_phy_params.DramRttWrR1[0],
+ &io_phy_params.DramRttWrR2[0],
+ &io_phy_params.DramRttWrR3[0],
+ };
+
+ set_phy_field_by_rank(l_rtt_wrs, iv_params.iv_dram_rtt_wr);
return fapi2::FAPI2_RC_SUCCESS;
}
@@ -705,10 +1056,15 @@ class phy_params
///
fapi2::ReturnCode set_RttPark(user_input_msdg& io_phy_params) const
{
- io_phy_params.DramRttParkR0[0] = iv_params.iv_dram_rtt_park[0][0];
- io_phy_params.DramRttParkR1[0] = iv_params.iv_dram_rtt_park[0][1];
- io_phy_params.DramRttParkR2[0] = iv_params.iv_dram_rtt_park[0][2];
- io_phy_params.DramRttParkR3[0] = iv_params.iv_dram_rtt_park[0][3];
+ const std::vector<uint16_t*> l_rtt_parks =
+ {
+ &io_phy_params.DramRttParkR0[0],
+ &io_phy_params.DramRttParkR1[0],
+ &io_phy_params.DramRttParkR2[0],
+ &io_phy_params.DramRttParkR3[0],
+ };
+
+ set_phy_field_by_rank(l_rtt_parks, iv_params.iv_dram_rtt_park);
return fapi2::FAPI2_RC_SUCCESS;
}
@@ -756,7 +1112,7 @@ class phy_params
///
fapi2::ReturnCode set_PhyEqualization(user_input_msdg& io_phy_params) const
{
- io_phy_params.PhyEqualization = iv_params.iv_phy_equalization[0][0];
+ io_phy_params.PhyEqualization[0] = iv_params.iv_phy_equalization[0][0];
return fapi2::FAPI2_RC_SUCCESS;
}
@@ -767,7 +1123,7 @@ class phy_params
///
fapi2::ReturnCode set_InitVrefDQ(user_input_msdg& io_phy_params) const
{
- io_phy_params.InitVrefDQ[0] = iv_params.iv_init_vref_dq;
+ io_phy_params.InitVrefDQ[0] = iv_params.iv_init_vref_dq[0][0];
return fapi2::FAPI2_RC_SUCCESS;
}
@@ -778,9 +1134,7 @@ class phy_params
///
fapi2::ReturnCode set_InitPhyVref(user_input_msdg& io_phy_params) const
{
- // Attr Vref = percentage of VDDQ, Receiver Vref = VDDQ*PhyVref[6:0]/128
- // conversion is attr_value * 128 / 100
- io_phy_params.InitPhyVref[0] = iv_params.iv_init_phy_vref * 128 / 100;
+ io_phy_params.InitPhyVref[0] = iv_params.iv_init_phy_vref[0][0];
return fapi2::FAPI2_RC_SUCCESS;
}
@@ -791,8 +1145,13 @@ class phy_params
///
fapi2::ReturnCode set_OdtWrMapCs(user_input_msdg& io_phy_params) const
{
- io_phy_params.OdtWrMapCs[0] = iv_params.iv_odt_wr_map_cs[0][0];
- return fapi2::FAPI2_RC_SUCCESS;
+ fapi2::buffer<uint16_t> odt_wr_map_cs_buff;
+
+ FAPI_TRY(populate_odt_buffer(iv_params.iv_odt_wr_map_cs, odt_wr_map_cs_buff));
+ io_phy_params.OdtWrMapCs[0] = odt_wr_map_cs_buff;
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
///
@@ -802,8 +1161,13 @@ class phy_params
///
fapi2::ReturnCode set_OdtRdMapCs(user_input_msdg& io_phy_params) const
{
- io_phy_params.OdtRdMapCs[0] = iv_params.iv_odt_rd_map_cs[0][0];
- return fapi2::FAPI2_RC_SUCCESS;
+ fapi2::buffer<uint16_t> odt_rd_map_cs_buff;
+
+ FAPI_TRY(populate_odt_buffer(iv_params.iv_odt_rd_map_cs, odt_rd_map_cs_buff));
+ io_phy_params.OdtRdMapCs[0] = odt_rd_map_cs_buff;
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
///
@@ -881,7 +1245,7 @@ class phy_params
///
fapi2::ReturnCode set_RcdIBTCtrl(user_input_msdg& io_phy_params) const
{
- io_phy_params.RcdIBTCtrl = iv_params.iv_f0rc7x[0];
+ io_phy_params.RcdIBTCtrl[0] = iv_params.iv_f0rc7x[0];
return fapi2::FAPI2_RC_SUCCESS;
}
@@ -892,7 +1256,7 @@ class phy_params
///
fapi2::ReturnCode set_RcdDBDic(user_input_msdg& io_phy_params) const
{
- io_phy_params.RcdDBDic = iv_params.iv_f1rc00[0];
+ io_phy_params.RcdDBDic[0] = iv_params.iv_f1rc00[0];
return fapi2::FAPI2_RC_SUCCESS;
}
@@ -903,18 +1267,75 @@ class phy_params
///
fapi2::ReturnCode set_RcdSlewRate(user_input_msdg& io_phy_params) const
{
- io_phy_params.RcdSlewRate = iv_params.iv_rcd_slew_rate;
+ io_phy_params.RcdSlewRate[0] = iv_params.iv_rcd_slew_rate;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Version 2 updates
+
+ ///
+ /// @brief Get the value for parameter version_number
+ /// @param[in,out] io_phy_params the phy params data struct
+ /// @return FAPI2_RC_SUCCESS
+ ///
+ fapi2::ReturnCode set_version_number(user_input_msdg& io_phy_params) const
+ {
+ io_phy_params.version_number = iv_params.iv_version_number;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Get the value for parameter version_number
+ /// @param[in,out] io_phy_params the phy params data struct
+ /// @return FAPI2_RC_SUCCESS
+ ///
+ fapi2::ReturnCode set_EncodedQuadCs(user_input_msdg& io_phy_params) const
+ {
+ io_phy_params.EncodedQuadCs = iv_params.iv_encoded_quadcs;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Get the value for parameter MDSSupport
+ /// @param[in,out] io_phy_params the phy params data struct
+ /// @return FAPI2_RC_SUCCESS
+ ///
+ fapi2::ReturnCode set_MDSSupport(user_input_msdg& io_phy_params) const
+ {
+ io_phy_params.MDSSupport = iv_params.iv_mdssupport;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Get the value for parameter DFIMRL_DDRCLK
+ /// @param[in,out] io_phy_params the phy params data struct
+ /// @return FAPI2_RC_SUCCESS
+ ///
+ fapi2::ReturnCode set_DFIMRL_DDRCLK(user_input_msdg& io_phy_params) const
+ {
+ io_phy_params.DFIMRL_DDRCLK = iv_params.iv_dfimrl_ddrclk;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Get the value for parameter DFIMRL_DDRCLK
+ /// @param[in,out] io_phy_params the phy params data struct
+ /// @return FAPI2_RC_SUCCESS
+ ///
+ fapi2::ReturnCode set_ATxDly_A(user_input_msdg& io_phy_params) const
+ {
+ memcpy(&io_phy_params.ATxDly_A[0][0], &iv_params.iv_atxdly_a[0], DRAMINIT_NUM_ADDR_DELAYS);
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Get the value for parameter EmulationSupport
+ /// @brief Get the value for parameter DFIMRL_DDRCLK
/// @param[in,out] io_phy_params the phy params data struct
/// @return FAPI2_RC_SUCCESS
///
- fapi2::ReturnCode set_EmulationSupport(user_input_msdg& io_phy_params) const
+ fapi2::ReturnCode set_ATxDly_B(user_input_msdg& io_phy_params) const
{
- io_phy_params.EmulationSupport = iv_params.iv_firmware_mode;
+ memcpy(&io_phy_params.ATxDly_B[0][0], &iv_params.iv_atxdly_b[0], DRAMINIT_NUM_ADDR_DELAYS);
return fapi2::FAPI2_RC_SUCCESS;
}
};
@@ -925,11 +1346,13 @@ namespace check
///
/// @brief Checks explorer response argument for a successful command
/// @param[in] i_target OCMB target
-/// @param[in] i_rsp response command
+/// @param[in] i_rsp response from command
+/// @param[in] i_cmd original command
/// @return FAPI2_RC_SUCCESS iff okay
///
fapi2::ReturnCode response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
- const host_fw_response_struct& i_rsp);
+ const host_fw_response_struct& i_rsp,
+ const host_fw_command_struct& i_cmd);
}//check
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C
index dcef63ec8..8c0d62f4e 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C
@@ -36,7 +36,8 @@
#include <lib/i2c/exp_i2c.H>
#include <lib/shared/exp_consts.H>
#include <explorer_scom_addresses.H>
-#include <explorer_scom_addresses_fld.H>
+#include <explorer_scom_addresses_fixes.H>
+#include <explorer_scom_addresses_fld_fixes.H>
#include <mss_explorer_attribute_setters.H>
#include <generic/memory/lib/utils/mss_buffer_utils.H>
@@ -49,33 +50,21 @@ namespace ecid
{
///
-/// @brief Determines enterprise and half dimm states from explorer FUSE
+/// @brief Determines enterprise state from explorer FUSE
/// @param[in] i_target the controller
/// @param[out] o_enterprise_mode state
-/// @param[out] o_half_dimm_mode state
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode get_enterprise_and_half_dimm_from_fuse(
+fapi2::ReturnCode get_enterprise_from_fuse(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
- uint8_t& o_enterprise_mode,
- uint8_t& o_half_dimm_mode)
+ bool& o_enterprise_mode)
{
fapi2::buffer<uint64_t> l_reg_resp_buffer;
FAPI_TRY(fapi2::getScom( i_target, static_cast<uint64_t>(EXPLR_EFUSE_IMAGE_OUT_0), l_reg_resp_buffer ),
"exp_getecid: could not read explorer fuse register 0x%08x", EXPLR_EFUSE_IMAGE_OUT_0);
- // Default to disabled
- o_enterprise_mode = fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_MODE_NON_ENTERPRISE; // 0
-
- // If we support enterprise mode, enable it until otherwise overridden in OMI_SETUP
- if(!l_reg_resp_buffer.getBit < EXPLR_EFUSE_IMAGE_OUT_0_ENTERPRISE_MODE_DIS
- + mss::exp::ecid_consts::REG_BIT_OFFSET > ())
- {
- o_enterprise_mode = fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_MODE_ENTERPRISE; // 1, enabled
- }
-
- // half_dimm_mode will remain disabled for P systems
- o_half_dimm_mode = fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_FULL_DIMM; // 0, disabled
+ // Since the bit is a disable bit, take the opposite to get enable=true, disable=false
+ o_enterprise_mode = !(l_reg_resp_buffer.getBit<EXPLR_EFUSE_IMAGE_OUT_0_ENTERPRISE_MODE_DIS>());
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.H
index cb8600c04..7b8fdfac9 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.H
@@ -47,16 +47,14 @@ namespace ecid
{
///
-/// @brief Determines enterprise and half dimm states from explorer FUSE
+/// @brief Determines enterprise state from explorer FUSE
/// @param[in] i_target the controller
/// @param[out] o_enterprise_mode state
-/// @param[out] o_half_dimm_mode state
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode get_enterprise_and_half_dimm_from_fuse(
+fapi2::ReturnCode get_enterprise_from_fuse(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
- uint8_t& o_enterprise_mode,
- uint8_t& o_half_dimm_mode);
+ bool& o_enterprise_mode);
///
/// @brief Reads ECID into output array from fuse
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_mss_thermal_init_utils.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_mss_thermal_init_utils.C
new file mode 100644
index 000000000..6ddfd5bb7
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_mss_thermal_init_utils.C
@@ -0,0 +1,176 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_mss_thermal_init_utils.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_mss_thermal_init_utils.C
+/// @brief Thermal initialization utility functions
+///
+// *HWP HWP Owner: Sharath Manjunath <shamanj4@in.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include <lib/exp_mss_thermal_init_utils.H>
+#include <lib/inband/exp_inband.H>
+#include <lib/shared/exp_consts.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <explorer_scom_addresses.H>
+#include <explorer_scom_addresses_fld.H>
+
+namespace mss
+{
+namespace exp
+{
+
+///
+/// @brief host_fw_command_struct structure setup
+/// @param[out] o_cmd the command parameters to set
+///
+void setup_sensor_interval_read_cmd_params(host_fw_command_struct& o_cmd)
+{
+ // Sets up EXP_FW_TEMP_SENSOR_CONFIG_INTERVAL_READ cmd params
+ // Command is used to configure interval read options for temperature sensors
+ o_cmd.cmd_id = mss::exp::omi::EXP_FW_TEMP_SENSOR_CONFIG_INTERVAL_READ;
+ o_cmd.cmd_flags = 0;
+ o_cmd.request_identifier = 0;
+ o_cmd.cmd_length = 0;
+ o_cmd.cmd_crc = 0xFFFFFFFF;
+ o_cmd.host_work_area = 0;
+ o_cmd.cmd_work_area = 0;
+ memset(o_cmd.padding, 0, sizeof(o_cmd.padding));
+ memset(o_cmd.command_argument, 0, sizeof(o_cmd.command_argument));
+ o_cmd.command_argument[0] = 0x30; // i2c address of first sensor 0x30
+ o_cmd.command_argument[1] = 0x14; // i2c address register offset 0x05, and size b00 (1 byte)
+ o_cmd.command_argument[2] = 0x00; // 2 and 3 together defines the interval
+ o_cmd.command_argument[3] = 0x1E; // interval in ms 30ms for first sensor
+ o_cmd.command_argument[4] = 0x32; // i2c address of second sensor 0x32
+ o_cmd.command_argument[5] = 0x14; // i2c address register offset 0x05, and size b00 (1 byte)
+ o_cmd.command_argument[6] = 0x00; // 6 and 7 together defines the interval
+ o_cmd.command_argument[7] = 0x1E; // interval in ms 30ms for second sensor
+ o_cmd.command_argument[8] = 0x00; // 8 and 9 together defines the interval
+ o_cmd.command_argument[9] = 0x1E; // interval in ms 30ms for Onchip sensor
+}
+
+namespace mc
+{
+
+///
+/// @brief set the N/M throttle register to safemode values
+/// @param[in] i_target the ocmb target
+/// @return fapi2::fapi2_rc_success if ok
+/// @Will be overwritten by OCC/cronus later in IPL
+///
+fapi2::ReturnCode setup_emergency_throttles(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ fapi2::buffer<uint64_t> l_data;
+ uint32_t l_n_safemode_throttle_value = 0;
+ uint32_t l_m_throttle_value = 0;
+ uint16_t l_nslot_safe = 0;
+ uint16_t l_nport_safe = 0;
+
+ // Get the required values from the mrw attributes
+ FAPI_TRY(mss::attr::get_mrw_safemode_dram_databus_util(l_n_safemode_throttle_value),
+ "Error in setup_emergency_throttles" );
+ FAPI_TRY(mss::attr::get_mrw_mem_m_dram_clocks(l_m_throttle_value), "Error in setup_emergency_throttles" );
+
+ // Get the register to be programmed using getScom
+ FAPI_TRY(fapi2::getScom(i_target, EXPLR_SRQ_MBA_FARB3Q, l_data), "Error in setup_emergency_throttles" );
+
+ // Calculate Nslot and Nport throttles and set l_data
+ // TK to use throttled_cmds function from commit 72525
+ l_nslot_safe = (( l_n_safemode_throttle_value * l_m_throttle_value / 100 ) / 100 ) / 4;
+ l_nport_safe = l_nslot_safe;
+ l_data.insertFromRight<EXPLR_SRQ_MBA_FARB3Q_CFG_NM_N_PER_SLOT, EXPLR_SRQ_MBA_FARB3Q_CFG_NM_N_PER_SLOT_LEN>
+ (l_nslot_safe);
+ l_data.insertFromRight<EXPLR_SRQ_MBA_FARB3Q_CFG_NM_N_PER_PORT, EXPLR_SRQ_MBA_FARB3Q_CFG_NM_N_PER_PORT_LEN>
+ (l_nport_safe);
+
+ // Write it back using putScom
+ FAPI_TRY(fapi2::putScom(i_target, EXPLR_SRQ_MBA_FARB3Q, l_data), "Error in setup_emergency_throttles" );
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ FAPI_ERR("Error setting safemode throttles for target %s", mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief disable emergency mode throttle for thermal_init
+/// @param[in] i_target the ocmb target
+/// @return fapi2::fapi2_rc_success if ok
+/// @note clears MB_SIM.SRQ.MBA_FARB7Q bit
+///
+fapi2::ReturnCode disable_safe_mode_throttles (const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ fapi2::buffer<uint64_t> l_data;
+
+ // Get the register to be cleared
+ FAPI_TRY(fapi2::getScom(i_target, EXPLR_SRQ_MBA_FARB7Q, l_data));
+
+ // Clear the register and write it back to the address
+ l_data.clearBit<EXPLR_SRQ_MBA_FARB7Q_EMER_THROTTLE_IP>();
+ FAPI_TRY(fapi2::putScom(i_target, EXPLR_SRQ_MBA_FARB7Q, l_data));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // ns mc
+
+namespace check
+{
+
+///
+/// @brief Checks explorer response argument for a successful command
+/// @param[in] i_target OCMB target
+/// @param[in] i_rsp response command
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode sensor_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const host_fw_response_struct& i_rsp)
+{
+ // Check if cmd was successful
+ FAPI_ASSERT(i_rsp.response_argument[0] == mss::exp::omi::response_arg::SUCCESS,
+ fapi2::MSS_EXP_SENSOR_CACHE_ENABLE_FAILED().
+ set_TARGET(i_target).
+ set_RSP_ID(i_rsp.response_id).
+ set_ERROR_CODE(i_rsp.response_argument[1]),
+ "Failed to enable sensor cache for %s", mss::c_str(i_target));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // ns check
+
+} // ns exp
+
+} // ns mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_mss_thermal_init_utils.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_mss_thermal_init_utils.H
new file mode 100644
index 000000000..fa9a3cf7b
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_mss_thermal_init_utils.H
@@ -0,0 +1,95 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_mss_thermal_init_utils.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_mss_thermal_init_utils.H
+/// @brief Thermal initialization utility functions
+///
+// *HWP HWP Owner: Sharath Manjunath <shamanj4@in.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _EXP_MSS_THERMAL_INIT_UTILS_H_
+#define _EXP_MSS_THERMAL_INIT_UTILS_H_
+
+#include <fapi2.H>
+#include <mss_generic_attribute_getters.H>
+#include <mss_explorer_attribute_getters.H>
+#include <exp_data_structs.H>
+#include <mss_generic_system_attribute_getters.H>
+
+namespace mss
+{
+namespace exp
+{
+
+///
+/// @brief host_fw_command_struct structure setup
+/// @param[out] o_cmd the command parameters to set
+///
+void setup_sensor_interval_read_cmd_params(host_fw_command_struct& o_cmd);
+
+namespace mc
+{
+
+///
+/// @brief set the N/M throttle register to safemode values
+/// @param[in] i_target the ocmb target
+/// @return fapi2::fapi2_rc_success if ok
+/// @Will be overwritten by OCC/cronus later in IPL
+///
+fapi2::ReturnCode setup_emergency_throttles(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+
+///
+/// @brief disable emergency mode throttle for thermal_init
+/// @param[in] i_target the ocmb target
+/// @return fapi2::fapi2_rc_success if ok
+/// @note clears MB_SIM.SRQ.MBA_FARB7Q bit
+///
+fapi2::ReturnCode disable_safe_mode_throttles (const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+
+} // ns mc
+
+namespace check
+{
+
+///
+/// @brief Checks explorer response argument for a successful command
+/// @param[in] i_target OCMB target
+/// @param[in] i_rsp response command
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode sensor_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const host_fw_response_struct& i_rsp);
+
+} // ns check
+
+} // ns exp
+
+} // ns mss
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/port.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir.C
index 14054af10..55b5aea01 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/port.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir.C
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/port.H $ */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir.C $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir.H
index 182dad7e6..84937976a 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,27 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file exp_fir.H
+/// @brief Memory subsystem FIR support
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_EXP_FIR_H_
+#define _MSS_EXP_FIR_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/fir/gen_mss_fir.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
+namespace mss
+{
+
+// FIR Register Traits for Explorer will be here sooner or later.
+
+} // end mss ns
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir_traits.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir_traits.H
new file mode 100644
index 000000000..3fb3460dc
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir_traits.H
@@ -0,0 +1,99 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir_traits.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2020 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file exp_fir_traits.H
+/// @brief Memory subsystem FIR support
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_EXP_FIR_TRAITS_H_
+#define _MSS_EXP_FIR_TRAITS_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/fir/gen_mss_fir.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <explorer_scom_addresses.H>
+#include <explorer_scom_addresses_fld.H>
+
+namespace mss
+{
+
+///
+/// @brief FIR Register Traits for Explorer MCBIST FIR
+///
+template <>
+struct firTraits<EXPLR_MCBIST_MCBISTFIRQ>
+{
+ static constexpr uint64_t REG = EXPLR_MCBIST_MCBISTFIRQ;
+ static constexpr uint64_t ACT0 = EXPLR_MCBIST_MCBISTFIRACT0;
+ static constexpr uint64_t ACT1 = EXPLR_MCBIST_MCBISTFIRACT1;
+ static constexpr uint64_t MASK = EXPLR_MCBIST_MCBISTFIRMASK;
+ static constexpr uint64_t MASK_AND = EXPLR_MCBIST_MCBISTFIRMASK_AND;
+ static constexpr uint64_t MASK_OR = EXPLR_MCBIST_MCBISTFIRMASK_OR;
+
+ // Target type of this register
+ static constexpr fapi2::TargetType T = fapi2::TARGET_TYPE_OCMB_CHIP;
+};
+
+///
+/// @brief FIR Register Traits for Explorer SRQ FIR
+///
+template <>
+struct firTraits<EXPLR_SRQ_SRQFIRQ>
+{
+ static constexpr uint64_t REG = EXPLR_SRQ_SRQFIRQ;
+ static constexpr uint64_t ACT0 = EXPLR_SRQ_SRQFIR_ACTION0;
+ static constexpr uint64_t ACT1 = EXPLR_SRQ_SRQFIR_ACTION1;
+ static constexpr uint64_t MASK = EXPLR_SRQ_SRQFIR_MASK;
+ static constexpr uint64_t MASK_AND = EXPLR_SRQ_SRQFIR_MASK_AND;
+ static constexpr uint64_t MASK_OR = EXPLR_SRQ_SRQFIR_MASK_OR;
+
+ // Target type of this register
+ static constexpr fapi2::TargetType T = fapi2::TARGET_TYPE_OCMB_CHIP;
+};
+
+///
+/// @brief FIR Register Traits for Explorer RDF FIR
+///
+template <>
+struct firTraits<EXPLR_RDF_FIR>
+{
+ static constexpr uint64_t REG = EXPLR_RDF_FIR;
+ static constexpr uint64_t ACT0 = EXPLR_RDF_ACTION0;
+ static constexpr uint64_t ACT1 = EXPLR_RDF_ACTION1;
+ static constexpr uint64_t MASK = EXPLR_RDF_MASK;
+ static constexpr uint64_t MASK_AND = EXPLR_RDF_MASK_AND;
+ static constexpr uint64_t MASK_OR = EXPLR_RDF_MASK_OR;
+
+ // Target type of this register
+ static constexpr fapi2::TargetType T = fapi2::TARGET_TYPE_OCMB_CHIP;
+};
+
+} // end mss ns
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_unmask.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_unmask.C
index 701a0d87e..49137f3e2 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_unmask.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_unmask.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,178 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file exp_unmask.C
+/// @brief Subroutines for unmasking and setting up MSS FIR
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#include <lib/shared/exp_defaults.H>
+#include <fapi2.H>
+#include <explorer_scom_addresses.H>
+#include <explorer_scom_addresses_fld.H>
+#include <generic/memory/lib/utils/scom.H>
+#include <lib/fir/exp_fir.H>
+#include <lib/fir/exp_fir_traits.H>
+#include <generic/memory/lib/utils/fir/gen_mss_unmask.H>
+
+namespace mss
+{
+
+namespace unmask
+{
+
+///
+/// @brief Unmask and setup actions performed after draminit_mc
+/// @param[in] i_target the fapi2::Target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode after_draminit_mc<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
+ i_target )
+{
+ fapi2::ReturnCode l_rc1 = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::ReturnCode l_rc2 = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::ReturnCode l_rc3 = fapi2::FAPI2_RC_SUCCESS;
+
+ // Create registers and check success for MCBISTFIR and SRQFIR and RDFFIR
+ mss::fir::reg<EXPLR_MCBIST_MCBISTFIRQ> l_exp_mcbist_reg(i_target, l_rc1);
+ mss::fir::reg<EXPLR_SRQ_SRQFIRQ> l_exp_srq_reg(i_target, l_rc2);
+ mss::fir::reg<EXPLR_RDF_FIR> l_exp_rdf_reg(i_target, l_rc3);
+
+ FAPI_TRY(l_rc1, "unable to create fir::reg for %d", EXPLR_MCBIST_MCBISTFIRQ);
+ FAPI_TRY(l_rc2, "unable to create fir::reg for %d", EXPLR_SRQ_SRQFIRQ);
+ FAPI_TRY(l_rc3, "unable to create fir::reg for %d", EXPLR_RDF_FIR);
+
+ // Write MCBISTFIR register per Explorer unmask spec
+ FAPI_TRY(l_exp_mcbist_reg.attention<EXPLR_MCBIST_MCBISTFIRQ_MCBIST_PROGRAM_COMPLETE>()
+ .write());
+
+ // Write RDF FIR register per Explorer unmask spec
+ // TK Need to set EXPLR_RDF_FIR_MAINTENANCE_RCD to recoverable for planar/ISDIMM
+ FAPI_TRY(l_exp_rdf_reg.recoverable_error<EXPLR_RDF_FIR_MAINTENANCE_AUE>()
+ .recoverable_error<EXPLR_RDF_FIR_MAINTENANCE_IAUE>()
+ .recoverable_error<EXPLR_RDF_FIR_RDDATA_VALID_ERROR>()
+ .recoverable_error<EXPLR_RDF_FIR_SCOM_PARITY_CLASS_STATUS>()
+ .recoverable_error<EXPLR_RDF_FIR_SCOM_PARITY_CLASS_RECOVERABLE>()
+ .checkstop<EXPLR_RDF_FIR_SCOM_PARITY_CLASS_UNRECOVERABLE>()
+ .checkstop<EXPLR_RDF_FIR_ECC_CORRECTOR_INTERNAL_PARITY_ERROR>()
+ .recoverable_error<EXPLR_RDF_FIR_ECC_RBUF_CE_DW0>()
+ .recoverable_error<EXPLR_RDF_FIR_ECC_RBUF_CE_DW1>()
+ .checkstop<EXPLR_RDF_FIR_ECC_RBUF_UE_DW0>()
+ .checkstop<EXPLR_RDF_FIR_ECC_RBUF_UE_DW1>()
+ .write());
+
+ // Write SRQ FIR register per Explorer unmask spec
+ FAPI_TRY(l_exp_srq_reg.recoverable_error<EXPLR_SRQ_SRQFIRQ_REFRESH_OVERRUN>()
+ .write());
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err);
+ return fapi2::current_err;
+}
+
+///
+/// @brief Unmask and setup actions performed after draminit_training
+/// @param[in] i_target the fapi2::Target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode after_draminit_training<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
+ i_target )
+{
+ fapi2::ReturnCode l_rc1 = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::ReturnCode l_rc2 = fapi2::FAPI2_RC_SUCCESS;
+
+ // Create registers and check success for MCBISTFIR and SRQFIR
+ mss::fir::reg<EXPLR_MCBIST_MCBISTFIRQ> l_exp_mcbist_reg(i_target, l_rc1);
+ mss::fir::reg<EXPLR_SRQ_SRQFIRQ> l_exp_srq_reg(i_target, l_rc2);
+
+ FAPI_TRY(l_rc1, "unable to create fir::reg for %d", EXPLR_MCBIST_MCBISTFIRQ);
+ FAPI_TRY(l_rc2, "unable to create fir::reg for %d", EXPLR_SRQ_SRQFIRQ);
+
+ // Write MCBISTFIR register per Explorer unmask spec; omit bit 10 cmd_complete until draminit_mc
+ FAPI_TRY(l_exp_mcbist_reg.recoverable_error<EXPLR_MCBIST_MCBISTFIRQ_COMMAND_ADDRESS_TIMEOUT>()
+ .checkstop<EXPLR_MCBIST_MCBISTFIRQ_INTERNAL_FSM_ERROR>()
+ .checkstop<EXPLR_MCBIST_MCBISTFIRQ_CCS_ARRAY_UNCORRECT_CE_OR_UE>()
+ .recoverable_error<EXPLR_MCBIST_MCBISTFIRQ_SCOM_RECOVERABLE_REG_PE>()
+ .checkstop<EXPLR_MCBIST_MCBISTFIRQ_SCOM_FATAL_REG_PE>()
+ .write());
+
+ // Write SRQ FIR register per Explorer unmask spec
+ FAPI_TRY(l_exp_srq_reg.recoverable_error<EXPLR_SRQ_SRQFIRQ_NCF_MCB_LOGIC_ERROR>()
+ .checkstop<EXPLR_SRQ_SRQFIRQ_NCF_MCB_PARITY_ERROR>()
+ .recoverable_error<EXPLR_SRQ_SRQFIRQ_WRQ_RRQ_HANG_ERR>()
+ .checkstop<EXPLR_SRQ_SRQFIRQ_SM_1HOT_ERR>()
+ .checkstop<EXPLR_SRQ_SRQFIRQ_CMD_PARITY_ERROR>()
+ .checkstop<EXPLR_SRQ_SRQFIRQ_WDF_ERROR2>()
+ .checkstop<EXPLR_SRQ_SRQFIRQ_WDF_ERROR3>()
+ .recoverable_error<EXPLR_SRQ_SRQFIRQ_WDF_ERROR7>()
+ .checkstop<EXPLR_SRQ_SRQFIRQ_NCF_UE>()
+ .checkstop<EXPLR_SRQ_SRQFIRQ_NCF_LOGIC_ERROR>()
+ .checkstop<EXPLR_SRQ_SRQFIRQ_NCF_PARITY_ERROR>()
+ .recoverable_error<EXPLR_SRQ_SRQFIRQ_NCF_CORR_ERROR>()
+ .write());
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err);
+ return fapi2::current_err;
+}
+
+///
+/// @brief Unmask and setup actions performed after mss_scominit
+/// @param[in] i_target the fapi2::Target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+/// TODO: Need to implement this function
+template<>
+fapi2::ReturnCode after_scominit<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target )
+{
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+///
+/// @brief Unmask and setup actions performed after mss_ddr_phy_reset
+/// @param[in] i_target the fapi2::Target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+/// TODO: Need to implement this function
+template<>
+fapi2::ReturnCode after_phy_reset<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target )
+{
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+///
+/// @brief Unmask and setup actions for memdiags related FIR
+/// @param[in] i_target the fapi2::Target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+/// TODO: Need to implement this function
+template<>
+fapi2::ReturnCode after_memdiags<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target )
+{
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+///
+/// @brief Unmask and setup actions for scrub related FIR
+/// @param[in] i_target the fapi2::Target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+/// TODO: Need to implement this function
+template<>
+fapi2::ReturnCode after_background_scrub<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
+ i_target )
+{
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+} // end unmask ns
+} // end mss ns
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_unmask.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_unmask.H
deleted file mode 100644
index d147a4096..000000000
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_unmask.H
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_unmask.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/hwp_wrappers_exp.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/hwp_wrappers_exp.C
new file mode 100644
index 000000000..03ba1a1de
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/hwp_wrappers_exp.C
@@ -0,0 +1,169 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/hwp_wrappers_exp.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file hwp_wrappers_exp.C
+/// @brief Main wrapper file for PRD calling Explorer memory procedure code
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#include <fapi2.H>
+#include <lib/shared/exp_defaults.H>
+#include <lib/mcbist/exp_mcbist_traits.H>
+#include <lib/dimm/exp_rank.H>
+#include <lib/mc/exp_port.H>
+#include <lib/mcbist/exp_mcbist.H>
+#include <generic/memory/lib/utils/dimm/kind.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_memdiags.H>
+
+///
+/// @brief Memdiags stop command wrapper for Explorer
+/// @param[in] i_target the target
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode exp_stop( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target )
+{
+ return mss::memdiags::stop<mss::mc_type::EXPLORER>(i_target);
+}
+
+///
+/// @brief Memdiags Super Fast Init command wrapper for Nimbus
+/// @param[in] i_target the target behind which all memory should be initialized
+/// @param[in] i_pattern an index representing a pattern to use to init memory (defaults to 0)
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode exp_sf_init( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint64_t i_pattern )
+{
+ return mss::memdiags::sf_init<mss::mc_type::EXPLORER>(i_target, i_pattern);
+}
+
+///
+/// @brief Memdiags Super Fast Read command wrapper for Explorer
+/// @param[in] i_target the target behind which all memory should be read
+/// @param[in] i_stop stop conditions
+/// @param[in] i_address mcbist::address representing the address from which to start.
+// Defaults to the first address behind the target
+/// @param[in] i_end whether to end, and where
+/// Defaults to stop after slave rank
+/// @param[in] i_end_address mcbist::address representing the address to end.
+// Defaults to TT::LARGEST_ADDRESS
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode exp_sf_read( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const mss::mcbist::stop_conditions<mss::mc_type::EXPLORER>& i_stop,
+ const mss::mcbist::address& i_address,
+ const mss::mcbist::end_boundary i_end,
+ const mss::mcbist::address& i_end_address )
+{
+ return mss::memdiags::sf_read<mss::mc_type::EXPLORER>(i_target, i_stop, i_address, i_end, i_end_address);
+}
+
+///
+/// @brief Continuous background scrub command wrapper for Explorer
+/// @param[in] i_target the target behind which all memory should be scrubbed
+/// @param[in] i_stop stop conditions
+/// @param[in] i_speed the speed to scrub
+/// @param[in] i_address mcbist::address representing the address from which to start.
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode exp_background_scrub( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const mss::mcbist::stop_conditions<mss::mc_type::EXPLORER>& i_stop,
+ const mss::mcbist::speed i_speed,
+ const mss::mcbist::address& i_address )
+{
+ return mss::memdiags::background_scrub<mss::mc_type::EXPLORER>(i_target, i_stop, i_speed, i_address);
+}
+
+///
+/// @brief Targeted scrub command wrapper for Explorer
+/// @param[in] i_target the target behind which all memory should be scrubbed
+/// @param[in] i_stop stop conditions
+/// @param[in] i_speed the speed to scrub
+/// @param[in] i_start_address mcbist::address representing the address from which to start.
+/// @param[in] i_end_address mcbist::address representing the address at which to end.
+/// @param[in] i_end whether to end, and where
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode exp_targeted_scrub( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const mss::mcbist::stop_conditions<mss::mc_type::EXPLORER>& i_stop,
+ const mss::mcbist::address& i_start_address,
+ const mss::mcbist::address& i_end_address,
+ const mss::mcbist::end_boundary i_end )
+{
+ return mss::memdiags::targeted_scrub<mss::mc_type::EXPLORER>(i_target, i_stop, i_start_address, i_end_address, i_end);
+}
+
+///
+/// @brief Continue current command wrapper for Explorer
+/// @param[in] i_target the target
+/// @param[in] i_end whether to end, and where (default - don't stop at end of rank)
+/// @param[in] i_stop stop conditions (default - 0 meaning 'don't change conditions')
+/// @param[in] i_speed the speed to scrub (default - SAME_SPEED meaning leave speed untouched)
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode exp_continue_cmd( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const mss::mcbist::end_boundary i_end,
+ const mss::mcbist::stop_conditions<mss::mc_type::EXPLORER>& i_stop,
+ const mss::mcbist::speed i_speed )
+{
+ return mss::memdiags::continue_cmd<mss::mc_type::EXPLORER>(i_target, i_end, i_stop, i_speed);
+}
+
+///
+/// @brief Broadcast mode check wrapper for Explorer
+/// @param[in] i_target the target to effect
+/// @return o_capable - yes iff these vector of targets are broadcast capable
+///
+const mss::states exp_is_broadcast_capable(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ return mss::states::NO;
+}
+
+
+///
+/// @brief Broadcast mode check wrapper for Explorer
+/// @param[in] i_targets the vector of targets to analyze
+/// @return o_capable - yes iff these vector of targets are broadcast capable
+///
+const mss::states exp_is_broadcast_capable(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>>& i_targets)
+{
+ return mss::states::NO;
+}
+
+///
+/// @brief Broadcast mode check wrapper for Explorer
+/// @param[in] i_kinds the dimms to effect
+/// @return o_capable - yes iff these vector of targets are broadcast capable
+///
+const mss::states exp_is_broadcast_capable(const std::vector<mss::dimm::kind<mss::mc_type::EXPLORER>>& i_kinds)
+{
+ return mss::states::NO;
+}
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H
index d834b102a..c430c650e 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,11 +38,27 @@
#include <fapi2.H>
#include <i2c_access.H>
-
#include <vector>
-#include <lib/i2c/exp_i2c_fields.H>
-#include <generic/memory/lib/utils/pos.H>
-#include <generic/memory/lib/utils/endian_utils.H>
+
+#ifdef __PPE__
+ #include <exp_i2c_fields.H>
+ #include <endian_utils.H>
+#else
+ #include <generic/memory/lib/utils/poll.H>
+ #include <lib/i2c/exp_i2c_fields.H>
+ #include <generic/memory/lib/utils/pos.H>
+ #include <generic/memory/lib/utils/endian_utils.H>
+#endif
+
+
+//Macro
+#ifdef __PPE__
+ #define TARGIDFORMAT "0x%08X"
+ #define TARGID i_target.get()
+#else
+ #define TARGIDFORMAT "%s"
+ #define TARGID mss::c_str(i_target)
+#endif
namespace mss
{
@@ -58,24 +74,38 @@ namespace check
/// @param[in] i_target the OCMB target
/// @param[in] i_cmd_id the command ID
/// @param[in] i_data data to check from EXP_FW_STATUS
+/// @param[out] o_busy true if explorer returns FW_BUSY status, false otherwise
+/// @return FAPI2_RC_SUCCESS iff okay
///
inline fapi2::ReturnCode status_code( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const uint8_t i_cmd_id,
- const std::vector<uint8_t>& i_data )
+ const std::vector<uint8_t>& i_data,
+ bool& o_busy )
{
+ // Set o_busy to false just in case we don't make it to where we check it
+ o_busy = false;
+
// Set to a high number to make sure check for SUCCESS (== 0) isn't a fluke
uint8_t l_status = ~(0);
FAPI_TRY( status::get_status_code(i_target, i_data, l_status) );
+ // We need to try again if we get a FW_BUSY status, so set the flag
+ if (l_status == status_codes::FW_BUSY)
+ {
+ o_busy = true;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
// Technically many cmds have their own status code decoding..but SUCCESS is always 0.
// If it's anything else we can just look up the status code
+
FAPI_ASSERT( l_status == status_codes::SUCCESS,
fapi2::MSS_EXP_I2C_FW_STATUS_CODE_FAILED().
set_TARGET(i_target).
set_STATUS_CODE(l_status).
set_CMD_ID(i_cmd_id),
- "Status code did not return SUCCESS (%d), received (%d) for %s",
- status_codes::SUCCESS, l_status, mss::c_str(i_target) );
+ "Status code did not return SUCCESS (%d), received (%d) for " TARGIDFORMAT ,
+ status_codes::SUCCESS, l_status, TARGID );
return fapi2::FAPI2_RC_SUCCESS;
@@ -98,12 +128,26 @@ inline void fw_status_setup(size_t& o_size,
o_cmd_id.push_back(FW_STATUS);
}
+#ifndef __PPE__
///
-/// @brief EXP_FW_STATUS
+/// @brief EXP_FW_BYPASS_4SEC_TIMEOUT setup helper function
+/// @param[out] o_cmd_id the explorer command ID
+///
+inline void fw_bypass_download_window_setup(std::vector<uint8_t>& o_cmd_id)
+{
+ o_cmd_id.clear();
+ o_cmd_id.push_back(FW_BYPASS_4SEC_TIMEOUT);
+}
+#endif
+
+///
+/// @brief get EXP_FW_STATUS bytes
/// @param[in] i_target the OCMB target
+/// @param[out] o_data the return data from FW_STATUS command
/// @return FAPI2_RC_SUCCESS iff okay
///
-inline fapi2::ReturnCode fw_status(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+inline fapi2::ReturnCode get_fw_status(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ std::vector<uint8_t>& o_data)
{
// Retrieve setup data
size_t l_size = 0;
@@ -111,18 +155,102 @@ inline fapi2::ReturnCode fw_status(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_C
fw_status_setup(l_size, l_cmd_id);
// Get data and check for errors
+ FAPI_TRY(fapi2::getI2c(i_target, l_size, l_cmd_id, o_data));
+ FAPI_DBG( "status returned ( 5 bytes ) : 0x%.02X 0x%.02X 0x%.02X 0x%.02X 0x%.02X",
+ o_data[0], o_data[1] , o_data[2], o_data[3], o_data[4]);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to check FW_STATUS loop termination, for unit testing
+/// @param[in] i_target the OCMB target
+/// @param[in] i_busy busy flag from check::status_code
+/// @param[in] i_boot_stage boot_stage output from status::get_boot_stage
+/// @return true if we should break out of the loop, false otherwise
+///
+inline bool fw_status_loop_done(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const bool i_busy,
+ const uint8_t i_boot_stage)
+{
+ constexpr uint8_t EXPECTED_BOOT_STAGE = boot_stages::RUNTIME_FW;
+
+ if (i_busy)
+ {
+ FAPI_DBG( "%s reutrned FW_BUSY status. Retrying...", mss::c_str(i_target) );
+ return false;
+ }
+
+ if (i_boot_stage != EXPECTED_BOOT_STAGE)
+ {
+ FAPI_DBG( "%s reutrned non-RUNTIME boot stage (0x%02x). Retrying...",
+ mss::c_str(i_target), i_boot_stage );
+ return false;
+ }
+
+ return true;
+}
+
+///
+/// @brief EXP_FW_STATUS
+/// @param[in] i_target the OCMB target
+/// @param[in] i_delay delay between polls
+/// @param[in] i_loops number of polling loops to perform
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+inline fapi2::ReturnCode fw_status(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint64_t i_delay,
+ const uint64_t i_loops)
+{
+ constexpr uint8_t EXPECTED_BOOT_STAGE = boot_stages::RUNTIME_FW;
+
+ // So, why aren't we using the memory team's polling API?
+ // This is a base function that will be utilized by the platform code
+ // As such, we don't want to pull in more libraries than we need to: it would cause extra dependencies
+ // So, we're decomposing the polling library below
+ //fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ bool l_busy = true;
+ uint8_t l_boot_stage = 0;
+ uint64_t l_loop = 0;
+
+ // Loop until we max our our loop count or get a non-busy response
+ for(; l_loop < i_loops; ++l_loop)
{
std::vector<uint8_t> l_data;
- FAPI_TRY(fapi2::getI2c(i_target, l_size, l_cmd_id, l_data));
- FAPI_INF( "status returned ( 5 bytes ) : 0x%.02X 0x%.02X 0x%.02X 0x%.02X 0x%.02X",
- l_data[0], l_data[1] , l_data[2], l_data[3], l_data[4]);
- FAPI_TRY( check::status_code(i_target, l_cmd_id[0], l_data) );
+ FAPI_TRY( get_fw_status(i_target, l_data) );
+ FAPI_TRY( check::status_code(i_target, FW_STATUS, l_data, l_busy) );
+ FAPI_TRY( status::get_boot_stage(i_target, l_data, l_boot_stage) );
+
+ if (fw_status_loop_done(i_target, l_busy, l_boot_stage))
+ {
+ break;
+ }
+
+ FAPI_TRY( fapi2::delay( i_delay, 200) );
}
+ FAPI_DBG(TARGIDFORMAT " stopped on loop %u/%u", TARGID , l_loop, i_loops);
+ // Check that Explorer is not still in FW_BUSY state
+
+ FAPI_ASSERT( !l_busy,
+ fapi2::MSS_EXP_I2C_FW_STATUS_BUSY().
+ set_TARGET(i_target),
+ "Polling timeout on FW_STATUS command (still FW_BUSY) for " TARGIDFORMAT,
+ TARGID );
+ // Check that Explorer is in RUNTIME_FW boot stage
+ FAPI_ASSERT( (l_boot_stage == EXPECTED_BOOT_STAGE),
+ fapi2::MSS_EXP_I2C_WRONG_BOOT_STAGE().
+ set_TARGET(i_target).
+ set_BOOT_STAGE(l_boot_stage).
+ set_EXPECTED_BOOT_STAGE(EXPECTED_BOOT_STAGE),
+ "Polling timeout on FW_STATUS command (wrong boot stage: 0x%01x, expected 0x%01x) for " TARGIDFORMAT,
+ l_boot_stage, EXPECTED_BOOT_STAGE, TARGID );
+
fapi_try_exit:
return fapi2::current_err;
}
+#ifndef __PPE__
///
/// @brief EXP_FW_BOOT_CONFIG setup
/// @param[in,out] io_data the data to go to boot config
@@ -159,9 +287,47 @@ inline fapi2::ReturnCode boot_config(const fapi2::Target<fapi2::TARGET_TYPE_OCMB
std::vector<uint8_t> l_configured_data(i_data);
boot_config_setup(l_configured_data);
- // Get data and check for errors
+ // Send the command
FAPI_TRY(fapi2::putI2c(i_target, l_configured_data));
- FAPI_TRY(fw_status(i_target));
+
+ // Wait a bit for the command (DLL lock and OMI training) to complete
+ // Value based on initial Explorer hardware.
+ // The command takes ~300ms and we poll for around 100ms, so wait 250ms here
+ FAPI_TRY( fapi2::delay( (mss::DELAY_1MS * 250), 200) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Check that the FW status code returns a busy status (expected for exp_omi_train)
+///
+/// @param[in] i_target OCMB
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff busy and no error code, else, error code
+///
+inline fapi2::ReturnCode check_fw_status_busy(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ uint8_t l_status = ~(0);
+
+ std::vector<uint8_t> l_data;
+ FAPI_TRY(get_fw_status(i_target, l_data));
+
+ FAPI_TRY(status::get_status_code(i_target, l_data, l_status));
+
+ // Post bootconfig1, we should see a busy status until p9a_omi_train is kicked off (setting axone to AUTO_TRAIN)
+ // explorer will return busy status until then. if we have another status, then we may not have executed bootconfig1
+ // or some previous command correctly, so we should check it here
+ // After p9a_omi_train, exp_omi_train_check will check fw_status for success (in addition to checking training completion)
+ // to make sure things went smoothly
+ FAPI_ASSERT( l_status == status_codes::FW_BUSY,
+ fapi2::MSS_EXP_I2C_FW_BOOT_CONFIG_STATUS_CODE_INVALID().
+ set_TARGET(i_target).
+ set_STATUS_CODE(l_status).
+ set_CMD_ID(FW_STATUS),
+ "Status code did not return BUSY (%d) as expected post BOOT_CONFIG1, received (%d) for " TARGIDFORMAT ,
+ status_codes::FW_BUSY, l_status, TARGID );
+
+ return fapi2::FAPI2_RC_SUCCESS;
fapi_try_exit:
return fapi2::current_err;
@@ -180,13 +346,98 @@ inline fapi2::ReturnCode is_ready(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CH
std::vector<uint8_t> l_cmd_id;
fw_status_setup(l_size, l_cmd_id);
- // We just ignore the data. We'll see FAPI2_RC_SUCCESS if
- // the I2C returns an ACK.
+ // We'll see FAPI2_RC_SUCCESS if the I2C returns an ACK.
+ // We just ignore the data
std::vector<uint8_t> l_data;
return fapi2::getI2c(i_target, l_size, l_cmd_id, l_data);
}
///
+/// @brief EXP_FW_BYPASS_4SEC_TIMEOUT
+/// @param[in] i_target the OCMB target
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+inline fapi2::ReturnCode fw_bypass_download_window(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ std::vector<uint8_t> l_cmd_id;
+ fw_bypass_download_window_setup(l_cmd_id);
+
+ // We'll see FAPI2_RC_SUCCESS if the I2C returns an ACK.
+ return fapi2::putI2c(i_target, l_cmd_id);
+}
+
+///
+/// @brief Helper function for exp_check_for_ready
+/// @param[in] i_target the controller
+/// @param[in] i_poll_count the number of times to run the fw_status command (default = 200)
+/// @param[in] i_delay delay in ns between fw_status command attempts (default = 1ms)
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+inline fapi2::ReturnCode exp_check_for_ready_helper(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint64_t i_poll_count = 200,
+ const uint64_t i_delay = DELAY_1MS)
+{
+ std::vector<uint8_t> l_data;
+ uint8_t l_boot_stage = 0;
+
+ // Using using default parameters from class, with overrides for delay and poll_count
+ mss::poll_parameters l_poll_params(DELAY_10NS,
+ 200,
+ i_delay,
+ 200,
+ i_poll_count);
+
+ // From MSCC explorer firmware arch spec
+ // 4.1.5: After power-up, the Explorer Chip will respond with NACK to all incoming I2C requests
+ // from the HOST until the I2C slave interface is ready to receive commands.
+ FAPI_ASSERT( mss::poll(i_target, l_poll_params, [i_target]()->bool
+ {
+ return mss::exp::i2c::is_ready(i_target) == fapi2::FAPI2_RC_SUCCESS;
+ }),
+ fapi2::MSS_EXP_I2C_POLLING_TIMEOUT().
+ set_TARGET(i_target),
+ "Failed to see an ACK from I2C -- polling timeout on %s",
+ mss::c_str(i_target) );
+
+ // If we're already in RUNTIME_FW stage, due to fuse settings or running procedures manually,
+ // we can (and should) skip the bypass and polling here
+ FAPI_TRY( get_fw_status(i_target, l_data) );
+ FAPI_TRY( status::get_boot_stage(i_target, l_data, l_boot_stage) );
+
+ if (l_boot_stage == boot_stages::RUNTIME_FW)
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // MSCC explorer firmware arch spec 4.1.6.5
+ // Boot ROM will wait 4 secs and will proceed for normal boot operation. During this time,
+ // I2C channel will be disabled and Host will see NACK on the bus for subsequent EXP_FW_STATUS
+ // command.
+ // Sending FW_BYPASS_4SEC_TIMEOUT command will bypass the 4 secs
+ // and immediately load the runtime firmware.
+ FAPI_TRY(fw_bypass_download_window(i_target));
+
+ // Loop again until we get an ACK from i2c
+ FAPI_ASSERT( mss::poll(i_target, l_poll_params, [i_target]()->bool
+ {
+ return mss::exp::i2c::is_ready(i_target) == fapi2::FAPI2_RC_SUCCESS;
+ }),
+ fapi2::MSS_EXP_I2C_POLLING_TIMEOUT().
+ set_TARGET(i_target),
+ "Failed to see an ACK from I2C -- polling timeout on %s",
+ mss::c_str(i_target) );
+
+ // Now poll the EXP_FW_STATUS command until it returns SUCCESS and RUNTIME_FW
+ FAPI_TRY(fw_status(i_target, i_delay, i_poll_count));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+#endif
+///
/// @brief Perform a register write operation on the given OCMB chip
/// @param[in] i_target the OCMB target
/// @param[in] i_addr The translated address on the OCMB chip
@@ -199,7 +450,7 @@ inline fapi2::ReturnCode fw_reg_write(const fapi2::Target<fapi2::TARGET_TYPE_OC
{
// create byte vector that will hold command bytes in sequence that will do the scom
std::vector<uint8_t> l_cmd_vector;
- std::vector<uint8_t> l_be_vector;
+ std::vector<uint8_t> l_byte_vector;
uint32_t l_input_data = static_cast<uint32_t>(i_data_buffer);
@@ -211,14 +462,21 @@ inline fapi2::ReturnCode fw_reg_write(const fapi2::Target<fapi2::TARGET_TYPE_OC
// write them directly to the cmd_vector in the same order they
// currently are
// Byte 2:5 = Address
- forceBE(i_addr, l_be_vector);
- l_cmd_vector.insert(l_cmd_vector.end(), l_be_vector.begin(), l_be_vector.end());
+ forceBE(i_addr, l_byte_vector);
+
+ for(const auto l_byte : l_byte_vector)
+ {
+ l_cmd_vector.push_back(l_byte);
+ }
- l_be_vector.clear();
- forceBE(l_input_data, l_be_vector);
+ l_byte_vector.clear();
+ forceBE(l_input_data, l_byte_vector);
// Byte 6:9 = Data
- l_cmd_vector.insert(l_cmd_vector.end(), l_be_vector.begin(), l_be_vector.end());
+ for(const auto l_byte : l_byte_vector)
+ {
+ l_cmd_vector.push_back(l_byte);
+ }
// Use fapi2 putI2c interface to execute command
FAPI_TRY(fapi2::putI2c(i_target, l_cmd_vector),
@@ -226,7 +484,7 @@ inline fapi2::ReturnCode fw_reg_write(const fapi2::Target<fapi2::TARGET_TYPE_OC
i_addr, mss::fapi_pos(i_target));
// Check status of operation
- FAPI_TRY(fw_status(i_target),
+ FAPI_TRY(fw_status(i_target, DELAY_1MS, 100),
"Invalid Status after FW_REG_WRITE operation to 0x%.8X on OCMB w/ fapiPos = 0x%.8X",
i_addr, mss::fapi_pos(i_target));
@@ -248,13 +506,13 @@ inline fapi2::ReturnCode fw_reg_read(const fapi2::Target<fapi2::TARGET_TYPE_OCMB
{
// create byte vector that will hold command bytes in sequence that will do the scom
std::vector<uint8_t> l_cmd_vector;
- std::vector<uint8_t> l_tmp_vector;
+ std::vector<uint8_t> l_byte_vector;
// Flush o_data_buffer w/ all 0's to avoid stale data
o_data_buffer.flush<0>();
// Force the address to be BE
- forceBE(i_addr, l_tmp_vector);
+ forceBE(i_addr, l_byte_vector);
// Build the cmd vector for the Read
l_cmd_vector.push_back(FW_REG_ADDR_LATCH); // Byte 0 = 0x03 (FW_REG_ADDR_LATCH)
@@ -264,7 +522,11 @@ inline fapi2::ReturnCode fw_reg_read(const fapi2::Target<fapi2::TARGET_TYPE_OCMB
// directly to the cmd_vector in the same order it
// currently is in
// Byte 2:5 = Address
- l_cmd_vector.insert(l_cmd_vector.end(), l_tmp_vector.begin(), l_tmp_vector.end());
+
+ for(const auto l_byte : l_byte_vector)
+ {
+ l_cmd_vector.push_back(l_byte);
+ }
// Use fapi2 putI2c interface to execute command
FAPI_TRY(fapi2::putI2c(i_target, l_cmd_vector),
@@ -272,43 +534,51 @@ inline fapi2::ReturnCode fw_reg_read(const fapi2::Target<fapi2::TARGET_TYPE_OCMB
i_addr, mss::fapi_pos(i_target));
// Check i2c status after operation
- FAPI_TRY(fw_status(i_target),
+ FAPI_TRY(fw_status(i_target, DELAY_1MS, 100),
"Invalid Status after FW_REG_ADDR_LATCH operation to 0x%.8X on OCMB w/ fapiPos = 0x%.8X",
i_addr, mss::fapi_pos(i_target));
- // Clear out the tmp_vector because we will re-use as the read buffer
- l_tmp_vector.clear();
-
// Clear out cmd vector as i2c op is complete and we must prepare for next
l_cmd_vector.clear();
// Cmd vector is a single byte with FW_REG_READ code
l_cmd_vector.push_back(FW_REG_READ); // Byte 0 = 0x04 (FW_REG_READ)
- l_cmd_vector.push_back(0x4); // Remaining bytes dont matter to HB firmware
- l_cmd_vector.push_back(0x0); // but the hw is expecting something there so
- l_cmd_vector.push_back(0x0); // we should write something
- l_cmd_vector.push_back(0x0);
- l_cmd_vector.push_back(0x0);
+ l_cmd_vector.push_back(0x4); // length of read
+
+ // i_addr was converted to BE above so we can write it
+ // directly to the cmd_vector in the same order it
+ // currently is in
+ // Byte 2:5 = Address
+ // NOTE: Techinically Explorer says this is not needed but was found
+ // to be needed in Gemini and Explorer says they don't care why the
+ // next 4 bytes are so we will fill it in regardless
+ for(const auto l_byte : l_byte_vector)
+ {
+ l_cmd_vector.push_back(l_byte);
+ }
+
+ // Clear out the tmp_vector because we will re-use as the read buffer
+ l_byte_vector.clear();
// Use fapi2 getI2c interface to execute command
- FAPI_TRY(fapi2::getI2c(i_target, FW_I2C_SCOM_READ_SIZE, l_cmd_vector, l_tmp_vector),
+ FAPI_TRY(fapi2::getI2c(i_target, FW_I2C_SCOM_READ_SIZE, l_cmd_vector, l_byte_vector),
"getI2c returned error for FW_REG_READ operation to 0x%.8X on OCMB w/ fapiPos = 0x%.8X",
i_addr, mss::fapi_pos(i_target));
// The first byte returned should be the size of the remaining data
// We requested FW_REG_ADDR_LATCH_SIZE bytes so that is what we
// expect to see as the first byte.
- FAPI_ASSERT( (l_tmp_vector.front() == FW_REG_ADDR_LATCH_SIZE),
+ FAPI_ASSERT( (l_byte_vector.front() == FW_REG_ADDR_LATCH_SIZE),
fapi2::I2C_GET_SCOM_INVALID_READ_SIZE()
.set_TARGET(i_target)
.set_ADDRESS(i_addr)
- .set_SIZE_RETURNED(l_tmp_vector[0])
+ .set_SIZE_RETURNED(l_byte_vector[0])
.set_SIZE_REQUESTED(FW_REG_ADDR_LATCH_SIZE),
"First byte of read data was expected to be 0x%lx but byte read = 0x%x",
- FW_REG_ADDR_LATCH_SIZE, l_tmp_vector[0] );
+ FW_REG_ADDR_LATCH_SIZE, l_byte_vector[0] );
// Check i2c status after operation
- FAPI_TRY(fw_status(i_target),
+ FAPI_TRY(fw_status(i_target, DELAY_1MS, 100),
"Invalid Status after FW_REG_READ operation to 0x%.8X on OCMB w/ fapiPos = 0x%.8X",
i_addr, mss::fapi_pos(i_target));
@@ -316,10 +586,10 @@ inline fapi2::ReturnCode fw_reg_read(const fapi2::Target<fapi2::TARGET_TYPE_OCMB
// returned in BE so no translation neccesary. Faster to just access
// the 4 bytes and shift than to perform vector operations to pop off front
// entry and convert vector to uint32.
- o_data_buffer = ( l_tmp_vector[1] << 24 |
- l_tmp_vector[2] << 16 |
- l_tmp_vector[3] << 8 |
- l_tmp_vector[4]);
+ o_data_buffer = ( l_byte_vector[1] << 24 |
+ l_byte_vector[2] << 16 |
+ l_byte_vector[3] << 8 |
+ l_byte_vector[4]);
fapi_try_exit:
return fapi2::current_err;
}
@@ -350,6 +620,56 @@ inline uint32_t trans_micro_i2c_scom_addr(const uint32_t i_addr)
return (i_addr | OCMB_UNCACHED_OFFSET) ;
}
+#ifndef __PPE__
+
+///
+/// @brief Issue the DOWNLOAD command to the given OCMB chip
+/// @param[in] i_target the OCMB target
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+inline fapi2::ReturnCode fw_download(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ // create byte vector that will hold command bytes in sequence that will do the scom
+ std::vector<uint8_t> l_download_cmd;
+ std::vector<uint8_t> l_status_data;
+ uint8_t l_boot_stage = 0;
+
+ // Read status to get the current boot_stage
+ FAPI_TRY(get_fw_status(i_target, l_status_data));
+
+ // Extract the boot_stage value
+ FAPI_TRY(status::get_boot_stage(i_target, l_status_data, l_boot_stage));
+
+ // Check that we are in the BOOT_ROM or FW_UPGRADE stage of booting.
+ // The FW_DOWNLOAD command can only be sent in one of these modes
+ // (see table 13-1, pboot flowchart in FW arch doc for more info)
+ FAPI_ASSERT(((l_boot_stage == BOOT_ROM_STAGE) ||
+ (l_boot_stage == FW_UPGRADE_MODE)),
+ fapi2::MSS_EXP_I2C_FW_DOWNLOAD_INVALID_STATE().
+ set_TARGET(i_target).
+ set_BOOT_STAGE(l_boot_stage).
+ set_STATUS_DATA(l_status_data),
+ "Invalid boot stage[0x%02x] for FW_DOWNLOAD command on %s",
+ l_boot_stage, mss::c_str(i_target));
+
+ // Start building the cmd vector for the write operation
+ // Byte 0 = 0x06 (FW_DOWNLOAD)
+ l_download_cmd.push_back(FW_DOWNLOAD);
+
+ // Use fapi2 putI2c interface to execute command
+ FAPI_TRY(fapi2::putI2c(i_target, l_download_cmd),
+ "I2C FW_DOWNLOAD op failed to send FW_DOWNLOAD cmd to %s",
+ mss::c_str(i_target));
+
+ // NOTE: The EXP_FW_STATUS command will not work after sending the
+ // EXP_FW_DOWNLOAD because we will be in TWI mode from this point on.
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+#endif
+
}// i2c
}// exp
}// mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_fields.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_fields.C
index 822c518d3..c1c9c31a9 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_fields.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_fields.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -23,6 +23,7 @@
/* */
/* IBM_PROLOG_END_TAG */
#include <lib/i2c/exp_i2c_fields.H>
+#include <generic/memory/lib/utils/find.H>
namespace mss
{
@@ -33,7 +34,7 @@ namespace i2c
// If a constexpr static data member (since C++11) is odr-used,
// a definition at namespace scope is still required, but it cannot have an initializer.
-constexpr mss::field_t<mss::endian::BIG> fields::BOOT_MODE;
+constexpr mss::field_t<mss::endian::BIG> fields::DFE_DISABLE;
constexpr mss::field_t<mss::endian::BIG> fields::LANE_MODE;
constexpr mss::field_t<mss::endian::BIG> fields::SERDES_FREQ;
constexpr mss::field_t<mss::endian::BIG> fields::FW_MODE;
@@ -44,6 +45,49 @@ constexpr mss::field_t<mss::endian::BIG> fields::CMD_ID;
constexpr mss::field_t<mss::endian::BIG> fields::STATUS_CODE;
constexpr mss::field_t<mss::endian::BIG> fields::BOOT_STAGE;
+namespace boot_cfg
+{
+
+///
+/// @brief SERDES_FREQ setter
+/// @param[in] i_target the OCMB target
+/// @param[in,out] io_data the buffer as a reference to a vector
+/// @param[in] i_freq frequency to set
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode set_serdes_freq(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ std::vector<uint8_t>& io_data,
+ const uint32_t i_freq)
+{
+ static const std::vector< std::pair<uint32_t, uint8_t> > OMI_FREQ_MAP =
+ {
+ {fapi2::ENUM_ATTR_FREQ_OMI_MHZ_21330, 1},
+ {fapi2::ENUM_ATTR_FREQ_OMI_MHZ_23460, 2},
+ {fapi2::ENUM_ATTR_FREQ_OMI_MHZ_25600, 3},
+ // All others reserved or not supported
+ };
+
+ uint8_t l_setting = 0;
+ const bool l_is_val_found = mss::find_value_from_key(OMI_FREQ_MAP, i_freq, l_setting);
+
+ FAPI_ASSERT( l_is_val_found,
+ fapi2::MSS_LOOKUP_FAILED()
+ .set_KEY(i_freq)
+ .set_DATA(l_setting)
+ .set_FUNCTION(SET_SERDES_FREQ)
+ .set_TARGET(i_target),
+ "Failed to find a BOOT_CONFIG setting for OMI value %d on %s",
+ i_freq,
+ mss::c_str(i_target) );
+
+ return set_field<fields::SERDES_FREQ>(i_target, io_data, l_setting);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}// boot_cfg
+
}// i2c
}// exp
}// mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_fields.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_fields.H
index 3098e9e28..a11f0a03d 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_fields.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_fields.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,9 +36,14 @@
#ifndef _MSS_EXP_I2C_FIELDS_H_
#define _MSS_EXP_I2C_FIELDS_H_
-#include <generic/memory/lib/utils/mss_field.H>
-#include <lib/shared/exp_consts.H>
#include <functional>
+#ifdef __PPE__
+ #include <mss_field.H>
+ #include <exp_consts.H>
+#else
+ #include <generic/memory/lib/utils/mss_field.H>
+ #include <lib/shared/exp_consts.H>
+#endif
namespace mss
{
@@ -57,10 +62,11 @@ struct fields
// First value is byte index, then buffer extract start bit, and extract data length
// Part of EXP_FW_BOOT_CONFIG
- static constexpr mss::field_t<mss::endian::BIG> BOOT_MODE{0, 0, 1};
+ static constexpr mss::field_t<mss::endian::BIG> DFE_DISABLE{0, 0, 1};
static constexpr mss::field_t<mss::endian::BIG> LANE_MODE{0, 1, 3};
static constexpr mss::field_t<mss::endian::BIG> SERDES_FREQ{0, 4, 4};
- static constexpr mss::field_t<mss::endian::BIG> FW_MODE{1, 2, 1};
+ static constexpr mss::field_t<mss::endian::BIG> ADAPTATION_MODE{1, 0, 1};
+ static constexpr mss::field_t<mss::endian::BIG> FW_MODE{1, 1, 2};
static constexpr mss::field_t<mss::endian::BIG> LOOPBACK_TEST{1, 3, 1};
static constexpr mss::field_t<mss::endian::BIG> TRANSPORT_LAYER{1, 4, 2};
static constexpr mss::field_t<mss::endian::BIG> DL_LAYER_BOOT_MODE{1, 6, 2};
@@ -108,14 +114,14 @@ struct fieldTraits<fields::LANE_MODE>
};
///
-/// @class fieldTraits - BOOT_MODE specialization
+/// @class fieldTraits - DFE_DISABLE specialization
/// @brief Traits assoiated with the Explorer I2C commands
///
template <>
-struct fieldTraits<fields::BOOT_MODE>
+struct fieldTraits<fields::DFE_DISABLE>
{
static constexpr uint8_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "Boot mode";
+ static constexpr const char* FIELD_STR = "DFE Disable";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -170,7 +176,7 @@ struct fieldTraits<fields::LOOPBACK_TEST>
template <>
struct fieldTraits<fields::FW_MODE>
{
- static constexpr uint8_t COMPARISON_VAL = 0x01;
+ static constexpr uint8_t COMPARISON_VAL = 0x02;
static constexpr const char* FIELD_STR = "FW Mode";
template <typename T>
@@ -178,6 +184,20 @@ struct fieldTraits<fields::FW_MODE>
};
///
+/// @class fieldTraits - ADAPTATION_MODE specialization
+/// @brief Traits assoiated with the Explorer I2C commands
+///
+template <>
+struct fieldTraits<fields::ADAPTATION_MODE>
+{
+ static constexpr uint8_t COMPARISON_VAL = 0x01;
+ static constexpr const char* FIELD_STR = "Adaptation Mode";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
/// @class fieldTraits - CMD_ID specialization
/// @brief Traits assoiated with the Explorer I2C commands
///
@@ -241,6 +261,7 @@ inline fapi2::ReturnCode get_field(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_C
return mss::get_field<endian::BIG, F, TT>(i_target, i_data, EXP_I2C_GET_FIELD, o_value);
}
+#ifndef __PPE__
///
/// @brief Explorer I2C field setter
/// @tparam IT Input type
@@ -284,15 +305,12 @@ inline fapi2::ReturnCode get_serdes_freq(const fapi2::Target<fapi2::TARGET_TYPE_
/// @brief SERDES_FREQ setter
/// @param[in] i_target the OCMB target
/// @param[in,out] io_data the buffer as a reference to a vector
-/// @param[in] i_setting the value to set
+/// @param[in] i_freq frequency to set
/// @return FAPI2_RC_SUCCESS iff okay
///
-inline fapi2::ReturnCode set_serdes_freq(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
- std::vector<uint8_t>& io_data,
- const uint8_t i_setting)
-{
- return set_field<fields::SERDES_FREQ>(i_target, io_data, i_setting);
-}
+fapi2::ReturnCode set_serdes_freq(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ std::vector<uint8_t>& io_data,
+ const uint32_t i_freq);
///
/// @brief LANE_MODE getter
@@ -323,31 +341,31 @@ inline fapi2::ReturnCode set_lane_mode(const fapi2::Target<fapi2::TARGET_TYPE_OC
}
///
-/// @brief BOOT_MODE getter
+/// @brief DFE_DISABLE getter
/// @param[in] i_target the OCMB target
/// @param[in] i_data the buffer as a reference to a vector
/// @param[out] o_setting
/// @return FAPI2_RC_SUCCESS iff okay
///
-inline fapi2::ReturnCode get_boot_mode(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
- const std::vector<uint8_t>& i_data,
- uint8_t& o_setting)
+inline fapi2::ReturnCode get_dfe_disable(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t>& i_data,
+ uint8_t& o_setting)
{
- return get_field<fields::BOOT_MODE>(i_target, i_data, o_setting);
+ return get_field<fields::DFE_DISABLE>(i_target, i_data, o_setting);
}
///
-/// @brief BOOT_MODE setter
+/// @brief DFE_DISABLE setter
/// @param[in] i_target the OCMB target
/// @param[in,out] io_data the buffer as a reference to a vector
/// @param[in] i_setting the value to set
/// @return FAPI2_RC_SUCCESS iff okay
///
-inline fapi2::ReturnCode set_boot_mode(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
- std::vector<uint8_t>& io_data,
- const uint8_t i_setting)
+inline fapi2::ReturnCode set_dfe_disable(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ std::vector<uint8_t>& io_data,
+ const uint8_t i_setting)
{
- return set_field<fields::BOOT_MODE>(i_target, io_data, i_setting);
+ return set_field<fields::DFE_DISABLE>(i_target, io_data, i_setting);
}
/// @brief DL_LAYER_BOOT_MODE getter
@@ -377,6 +395,33 @@ inline fapi2::ReturnCode set_dl_layer_boot_mode(const fapi2::Target<fapi2::TARGE
return set_field<fields::DL_LAYER_BOOT_MODE>(i_target, io_data, i_setting);
}
+/// @brief ADAPTATION_MODE getter
+/// @param[in] i_target the OCMB target
+/// @param[in] i_data the buffer as a reference to a vector
+/// @param[out] o_setting
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+inline fapi2::ReturnCode get_adaptation_mode(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t>& i_data,
+ uint8_t& o_setting)
+{
+ return get_field<fields::ADAPTATION_MODE>(i_target, i_data, o_setting);
+}
+
+///
+/// @brief ADAPTATION_MODE setter
+/// @param[in] i_target the OCMB target
+/// @param[in,out] io_data the buffer as a reference to a vector
+/// @param[in] i_setting the value to set
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+inline fapi2::ReturnCode set_adaptation_mode(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ std::vector<uint8_t>& io_data,
+ const uint8_t i_setting)
+{
+ return set_field<fields::ADAPTATION_MODE>(i_target, io_data, i_setting);
+}
+
///
/// @brief DL_LAYER_BOOT_MODE getter
/// @param[in] i_target the OCMB target
@@ -464,6 +509,8 @@ inline fapi2::ReturnCode set_fw_mode(const fapi2::Target<fapi2::TARGET_TYPE_OCMB
}// boot_cfg
+#endif
+
namespace status
{
@@ -481,6 +528,7 @@ inline fapi2::ReturnCode get_boot_stage(const fapi2::Target<fapi2::TARGET_TYPE_O
return get_field<fields::BOOT_STAGE>(i_target, i_data, o_setting);
}
+
///
/// @brief STATUS_CODE getter
/// @param[in] i_target the OCMB target
@@ -495,6 +543,7 @@ inline fapi2::ReturnCode get_status_code(const fapi2::Target<fapi2::TARGET_TYPE_
return get_field<fields::STATUS_CODE>(i_target, i_data, o_setting);
}
+#ifndef __PPE__
///
/// @brief CMD_ID getter
/// @param[in] i_target the OCMB target
@@ -508,6 +557,7 @@ inline fapi2::ReturnCode get_cmd_id(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_
{
return get_field<fields::CMD_ID>(i_target, i_data, o_setting);
}
+#endif
}// status
}// i2c
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_pmic.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_pmic.H
deleted file mode 100644
index e546dda93..000000000
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_pmic.H
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_pmic.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_scom.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_scom.H
index f1d811245..b2813abec 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_scom.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c_scom.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,7 +36,11 @@
#ifndef _MSS_EXP_I2C_SCOM_H_
#define _MSS_EXP_I2C_SCOM_H_
-#include <lib/i2c/exp_i2c.H>
+#ifdef __PPE__
+ #include <exp_i2c.H>
+#else
+ #include <lib/i2c/exp_i2c.H>
+#endif
namespace mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_fw_log.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_fw_log.C
new file mode 100644
index 000000000..f9c17f564
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_fw_log.C
@@ -0,0 +1,139 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_fw_log.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/// @file exp_fw_log.C
+///
+/// @brief Helpers to access explorer firmware logs
+
+//
+// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
+// *HWP FW Owner: Matt Derksen <mderkse1@us.ibm.com>
+// *HWP Team:
+// *HWP Level: 2
+// *HWP Consumed by: HB
+
+#include <exp_fw_log.H>
+#include <fapi2.H>
+#include <exp_inband.H>
+#include <lib/shared/exp_consts.H>
+#include <exp_data_structs.H>
+#include <generic/memory/lib/utils/c_str.H>
+
+
+namespace mss
+{
+namespace exp
+{
+namespace ib
+{
+
+///
+/// @brief Response parameters of Explorer Log commands
+/// This is found in the response_argument field
+typedef struct
+{
+ uint8_t op; /**< Firmware error log sub-cmd operation */
+ uint8_t status; /**< Operation status */
+ uint32_t err_code; /**< Specific error code if operation failed */
+ uint32_t num_bytes_returned; /**< Number of bytes returned */
+} exp_fw_log_rsp_parms_struct_t;
+
+///
+/// @brief Operation status values
+///
+enum
+{
+ STATUS_OP_FAILED = 0x00,
+ STATUS_OP_SUCCESSFUL = 0x01,
+};
+
+/// See header
+void build_log_cmd( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const exp_log_sub_cmd_op i_sub_op,
+ host_fw_command_struct& o_cmd )
+{
+ // Issue EXP_FW_LOG cmd though EXP-FW REQ buffer
+ o_cmd.cmd_id = mss::exp::omi::EXP_FW_LOG;
+ o_cmd.cmd_flags = 0;
+
+ // Host generated id number (returned in response packet)
+ // @todo RTC 210371
+ //uint32_t l_counter = 0;
+ //FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_OCMB_COUNTER, i_target, l_counter));
+ o_cmd.request_identifier = 0xabcd;
+
+ if (i_sub_op == SUB_CMD_READ_SAVED_LOG)
+ {
+ o_cmd.request_identifier = 0xabce;
+ }
+
+ o_cmd.cmd_length = 0;
+
+ o_cmd.cmd_crc = 0xffffffff;
+ o_cmd.host_work_area = 0;
+ o_cmd.cmd_work_area = 0;
+ memset(o_cmd.padding, 0, sizeof(o_cmd.padding));
+
+ // Set the sub-command ID in the command argument field
+ o_cmd.command_argument[0] = i_sub_op;
+}
+
+/// See header
+fapi2::ReturnCode check_log_cmd_response(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const host_fw_response_struct& i_rsp )
+{
+ std::vector<uint8_t> resp_arg;
+ uint32_t index = 0;
+ exp_fw_log_rsp_parms_struct_t l_rsp_args;
+
+ //copy response_argument field into a vector that can be
+ //used by readCrctEndian()
+ resp_arg.assign(i_rsp.response_argument,
+ i_rsp.response_argument + ARGUMENT_SIZE);
+
+ //convert fields to native endianness
+ FAPI_TRY(mss::exp::ib::readCrctEndian(resp_arg, index, l_rsp_args.op));
+ FAPI_TRY(mss::exp::ib::readCrctEndian(resp_arg, index, l_rsp_args.status));
+ FAPI_TRY(mss::exp::ib::readCrctEndian(resp_arg, index, l_rsp_args.err_code));
+ FAPI_TRY(mss::exp::ib::readCrctEndian(resp_arg, index, l_rsp_args.num_bytes_returned));
+
+ // check if command was successful
+ FAPI_ASSERT(l_rsp_args.status == STATUS_OP_SUCCESSFUL,
+ fapi2::MSS_EXP_RSP_ARG_FAILED().
+ set_TARGET(i_target).
+ set_RSP_ID(i_rsp.response_id).
+ set_ERROR_CODE(l_rsp_args.err_code),
+ "EXP_FW_LOG command 0x%02X failed for %s. "
+ "Status: 0x%02X, err_code 0x%04X, num_bytes_returned 0x%04X",
+ l_rsp_args.op, mss::c_str(i_target), l_rsp_args.status,
+ l_rsp_args.err_code, l_rsp_args.num_bytes_returned);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}//ib namespace
+}//exp namespace
+}//mss namespace
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_fw_log.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_fw_log.H
new file mode 100644
index 000000000..3817640be
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_fw_log.H
@@ -0,0 +1,104 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_fw_log.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file exp_fw_log.H
+/// @brief Helpers to access explorer firmware logs
+/// The Explorer firmware modules log pertinent data regarding
+/// operations and errors, and the Host manages and accesses this
+/// information by using the EXP_FW_LOG API command. The firmware
+/// maintains the log in a circular buffer in RAM and in the event
+/// of a processor exception, firmware assert, or other critical
+/// condition the firmware saves the data in RAM to SPI flash.
+/// Having the log stored in non-volatile memory allows post-analysis
+/// of the log even if it requires a power-cycle to recover the system.
+///
+// *HWP HWP Owner: Matt Derksen <mderkse1@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#ifndef __MSS_EXP_FW_LOG__
+#define __MSS_EXP_FW_LOG__
+
+#include <fapi2.H>
+#include <vector>
+#include <exp_data_structs.H>
+
+namespace mss
+{
+namespace exp
+{
+namespace ib
+{
+///
+/// @brief Defines the sub-commands available for the
+/// EXP_FW_LOG command
+///
+enum exp_log_sub_cmd_op
+{
+ // This is used to read log entries from the active
+ // firmware logfile stored in Explorer RAM
+ SUB_CMD_READ_ACTIVE_LOG = 0x01,
+
+ // This is used to read log entries from the saved
+ // firmware logfile stored in Explorer SPI flash
+ SUB_CMD_READ_SAVED_LOG = 0x02,
+
+ // This is used to clear the active logfile in Explorer RAM
+ SUB_CMD_CLEAR_ACTIVE_LOG = 0x03,
+
+ // This is used to erase the saved logfile in Explorer SPI flash
+ SUB_CMD_ERASE_SAVED_LOG = 0x04,
+};
+
+///
+/// @brief Sets the command_argument fields for EXP_FW_LOG command
+///
+/// @param[in] i_target - OCMB target
+/// @param[in] i_sub_op - what sub-command of EXP_FW_LOG to use
+/// @param[out] o_cmd - command packet to update
+///
+void build_log_cmd(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const exp_log_sub_cmd_op i_sub_op,
+ host_fw_command_struct& o_cmd );
+
+
+///
+/// @brief Checks the response of the EXP_FW_LOG command
+///
+/// @param[in] i_target - OCMB target
+/// @param[in] i_rsp - response portion of EXP_FW_ERROR_LOG (from getRsp())
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode check_log_cmd_response(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const host_fw_response_struct& i_rsp );
+
+}//exp
+}//mss
+}//ib
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.C
index ff24bc76c..b871c9682 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.C
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.C $ */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.C $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -32,7 +32,7 @@
// *HWP Level: 2
// *HWP Consumed by: HB
-#include <exp_inband.H>
+#include <lib/inband/exp_inband.H>
#include <lib/omi/crc32.H>
#include <lib/shared/exp_consts.H>
@@ -63,7 +63,7 @@ namespace ib
fapi2::ReturnCode putMMIO64(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const uint64_t i_addr,
- const fapi2::buffer<uint64_t>& i_data )
+ const fapi2::buffer<uint64_t>& i_data)
{
uint64_t l_v = static_cast<uint64_t>(i_data);
std::vector<uint8_t> l_wd;
@@ -71,9 +71,6 @@ fapi2::ReturnCode putMMIO64(
return fapi2::putMMIO(i_target, EXPLR_IB_MMIO_OFFSET | i_addr, 8, l_wd);
}
-
-
-
/// @brief Writes 32 bits of data to MMIO space to the selected Explorer
///
/// @param[in] i_target The Explorer chip to write
@@ -84,7 +81,7 @@ fapi2::ReturnCode putMMIO64(
fapi2::ReturnCode putMMIO32(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const uint64_t i_addr,
- const fapi2::buffer<uint32_t>& i_data )
+ const fapi2::buffer<uint32_t>& i_data)
{
uint32_t l_v = static_cast<uint32_t>(i_data);
std::vector<uint8_t> l_wd;
@@ -92,9 +89,6 @@ fapi2::ReturnCode putMMIO32(
return fapi2::putMMIO(i_target, EXPLR_IB_MMIO_OFFSET | i_addr, 4, l_wd);
}
-
-
-
/// @brief Writes 64 bits of data to SCOM MMIO space
///
/// @param[in] i_target The Explorer chip to write
@@ -112,9 +106,6 @@ fapi2::ReturnCode putScom(
return putMMIO64(i_target, l_scomAddr, i_data);
}
-
-
-
/// @brief Writes 32 bits of data to OpenCAPI config space
///
/// @param[in] i_target The Explorer chip to write
@@ -127,18 +118,35 @@ fapi2::ReturnCode putOCCfg(
const uint64_t i_cfgAddr,
const fapi2::buffer<uint32_t>& i_data)
{
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
uint32_t l_v = static_cast<uint32_t>(i_data);
std::vector<uint8_t> l_wd;
- forceLE(l_v, l_wd);
- return fapi2::putMMIO(i_target, i_cfgAddr, 4, l_wd);
-}
+ fapi2::ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL_Type l_endian;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL,
+ FAPI_SYSTEM, l_endian));
+ if (l_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL_LITTLE_ENDIAN)
+ {
+ forceLE(l_v, l_wd);
+ }
+ else
+ {
+ forceBE(l_v, l_wd);
+ }
+
+ FAPI_TRY(fapi2::putMMIO(i_target, i_cfgAddr, 4, l_wd));
+fapi_try_exit:
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
+ return fapi2::current_err;
+}
fapi2::ReturnCode user_input_msdg_to_little_endian(const user_input_msdg& i_input, std::vector<uint8_t>& o_data,
uint32_t& o_crc)
{
+ o_data.clear();
+ FAPI_TRY(forceCrctEndian(i_input.version_number, o_data));
FAPI_TRY(forceCrctEndian(i_input.DimmType, o_data));
FAPI_TRY(forceCrctEndian(i_input.CsPresent, o_data));
FAPI_TRY(forceCrctEndian(i_input.DramDataWidth, o_data));
@@ -151,9 +159,11 @@ fapi2::ReturnCode user_input_msdg_to_little_endian(const user_input_msdg& i_inpu
FAPI_TRY(forceCrctEndian(i_input.SpdCLSupported, o_data));
FAPI_TRY(forceCrctEndian(i_input.SpdtAAmin, o_data));
FAPI_TRY(forceCrctEndian(i_input.Rank4Mode, o_data));
+ FAPI_TRY(forceCrctEndian(i_input.EncodedQuadCs, o_data));
FAPI_TRY(forceCrctEndian(i_input.DDPCompatible, o_data));
FAPI_TRY(forceCrctEndian(i_input.TSV8HSupport, o_data));
FAPI_TRY(forceCrctEndian(i_input.MRAMSupport, o_data));
+ FAPI_TRY(forceCrctEndian(i_input.MDSSupport, o_data));
FAPI_TRY(forceCrctEndian(i_input.NumPStates, o_data));
FAPI_TRY(forceCrctEndianArray(i_input.Frequency, MSDG_MAX_PSTATE, o_data));
FAPI_TRY(forceCrctEndianArray(i_input.PhyOdtImpedance, MSDG_MAX_PSTATE, o_data));
@@ -180,7 +190,7 @@ fapi2::ReturnCode user_input_msdg_to_little_endian(const user_input_msdg& i_inpu
FAPI_TRY(forceCrctEndianArray(i_input.DramDic, MSDG_MAX_PSTATE, o_data));
FAPI_TRY(forceCrctEndianArray(i_input.DramWritePreamble, MSDG_MAX_PSTATE, o_data));
FAPI_TRY(forceCrctEndianArray(i_input.DramReadPreamble, MSDG_MAX_PSTATE, o_data));
- FAPI_TRY(forceCrctEndian(i_input.PhyEqualization, o_data));
+ FAPI_TRY(forceCrctEndianArray(i_input.PhyEqualization, MSDG_MAX_PSTATE, o_data));
FAPI_TRY(forceCrctEndianArray(i_input.InitVrefDQ, MSDG_MAX_PSTATE, o_data));
FAPI_TRY(forceCrctEndianArray(i_input.InitPhyVref, MSDG_MAX_PSTATE, o_data));
FAPI_TRY(forceCrctEndianArray(i_input.OdtWrMapCs, MSDG_MAX_PSTATE, o_data));
@@ -191,17 +201,29 @@ fapi2::ReturnCode user_input_msdg_to_little_endian(const user_input_msdg& i_inpu
FAPI_TRY(forceCrctEndianArray(i_input.BistCAParityLatency, MSDG_MAX_PSTATE, o_data));
FAPI_TRY(forceCrctEndianArray(i_input.RcdDic, MSDG_MAX_PSTATE, o_data));
FAPI_TRY(forceCrctEndianArray(i_input.RcdVoltageCtrl, MSDG_MAX_PSTATE, o_data));
- FAPI_TRY(forceCrctEndian(i_input.RcdIBTCtrl, o_data));
- FAPI_TRY(forceCrctEndian(i_input.RcdDBDic, o_data));
- FAPI_TRY(forceCrctEndian(i_input.RcdSlewRate, o_data));
- FAPI_TRY(forceCrctEndian(i_input.EmulationSupport, o_data));
+ FAPI_TRY(forceCrctEndianArray(i_input.RcdIBTCtrl, MSDG_MAX_PSTATE, o_data));
+ FAPI_TRY(forceCrctEndianArray(i_input.RcdDBDic, MSDG_MAX_PSTATE, o_data));
+ FAPI_TRY(forceCrctEndianArray(i_input.RcdSlewRate, MSDG_MAX_PSTATE, o_data));
+ FAPI_TRY(forceCrctEndian(i_input.DFIMRL_DDRCLK, o_data));
+
+ for (uint8_t l_pstate = 0; l_pstate < MSDG_MAX_PSTATE; ++l_pstate)
+ {
+ FAPI_TRY(forceCrctEndianArray(i_input.ATxDly_A[l_pstate], DRAMINIT_NUM_ADDR_DELAYS, o_data));
+ }
+
+ for (uint8_t l_pstate = 0; l_pstate < MSDG_MAX_PSTATE; ++l_pstate)
+ {
+ FAPI_TRY(forceCrctEndianArray(i_input.ATxDly_B[l_pstate], DRAMINIT_NUM_ADDR_DELAYS, o_data));
+ }
o_crc = crc32_gen(o_data);
+ padCommData(o_data);
FAPI_TRY(correctMMIOEndianForStruct(o_data));
+ FAPI_TRY(correctMMIOword_order(o_data));
fapi_try_exit:
- FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err);
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
return fapi2::current_err;
}
@@ -224,12 +246,10 @@ fapi2::ReturnCode putUserInputMsdg(
FAPI_TRY(fapi2::putMMIO(i_target, EXPLR_IB_DATA_ADDR, BUFFER_TRANSACTION_SIZE, l_data));
fapi_try_exit:
- FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err);
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
return fapi2::current_err;
}
-
-
fapi2::ReturnCode host_fw_command_struct_to_little_endian(const host_fw_command_struct& i_input,
std::vector<uint8_t>& o_data)
{
@@ -248,10 +268,12 @@ fapi2::ReturnCode host_fw_command_struct_to_little_endian(const host_fw_command_
l_cmd_header_crc = crc32_gen(o_data);
FAPI_DBG("Command header crc: %xl", l_cmd_header_crc);
FAPI_TRY(forceCrctEndian(l_cmd_header_crc, o_data));
+ padCommData(o_data);
FAPI_TRY(correctMMIOEndianForStruct(o_data));
+ FAPI_TRY(correctMMIOword_order(o_data));
fapi_try_exit:
- FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err);
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
return fapi2::current_err;
}
@@ -272,23 +294,28 @@ fapi2::ReturnCode putCMD(
// Clear the doorbell
l_scom.setBit<EXPLR_MMIO_MDBELLC_MDBELL_MDBELL>();
- FAPI_TRY(mss::exp::ib::putScom(i_target, EXPLR_MMIO_MDBELLC, l_scom));
+ FAPI_DBG("Clearing the inbound doorbell...");
+ FAPI_TRY(fapi2::putScom(i_target, EXPLR_MMIO_MDBELLC, l_scom), "Failed to clear inbound doorbell register");
+
+ // Clear the response doorbell, just in case the last response didn't get cleared
+ FAPI_TRY(clear_outbound_doorbell(i_target));
// Set the command
- FAPI_TRY(fapi2::putMMIO(i_target, EXPLR_IB_CMD_ADDR, BUFFER_TRANSACTION_SIZE, l_data))
+ FAPI_DBG("Writing the command...");
+ FAPI_TRY(fapi2::putMMIO(i_target, EXPLR_IB_CMD_ADDR, BUFFER_TRANSACTION_SIZE, l_data),
+ "Failed to write to the command buffer");
// Ring the doorbell - aka the bit that interrupts the microchip FW and tells it to do the thing
l_scom.flush<0>();
l_scom.setBit<EXPLR_MMIO_MDBELL_MDBELL>();
- FAPI_TRY(mss::exp::ib::putScom(i_target, EXPLR_MMIO_MDBELL, l_scom));
+ FAPI_DBG("Setting the inbound doorbell...");
+ FAPI_TRY(fapi2::putScom(i_target, EXPLR_MMIO_MDBELL, l_scom), "Failed to set inbound doorbell bit");
fapi_try_exit:
- FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err);
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
return fapi2::current_err;
}
-
-
//--------------------------------------------------------------------------------
// Read operations
//--------------------------------------------------------------------------------
@@ -312,13 +339,10 @@ fapi2::ReturnCode getMMIO64(
readLE(l_data, l_idx, l_rd);
o_data = l_rd;
fapi_try_exit:
- FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err);
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
return fapi2::current_err;
}
-
-
-
/// @brief Reads 32 bits of data from MMIO space on the selected Explorer
///
/// @param[in] i_target The Explorer chip to read data from
@@ -338,13 +362,10 @@ fapi2::ReturnCode getMMIO32(
readLE(l_data, l_idx, l_rd);
o_data = l_rd;
fapi_try_exit:
- FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err);
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
return fapi2::current_err;
}
-
-
-
/// @brief Reads 64 bits of data from SCOM MMIO space on the selected Explorer
///
/// @param[in] i_target The Explorer chip to read data from
@@ -362,9 +383,6 @@ fapi2::ReturnCode getScom(
return getMMIO64(i_target, l_scomAddr, o_data);
}
-
-
-
/// @brief Reads 32 bits of data from OpenCAPI config space on the selected Explorer
///
/// @param[in] i_target The Explorer chip to read data from
@@ -377,18 +395,32 @@ fapi2::ReturnCode getOCCfg(
const uint64_t i_cfgAddr,
fapi2::buffer<uint32_t>& o_data)
{
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
uint32_t l_rd = 0;
std::vector<uint8_t> l_data(4);
uint32_t l_idx = 0;
+ fapi2::ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL_Type l_endian;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL,
+ FAPI_SYSTEM, l_endian));
+
FAPI_TRY(fapi2::getMMIO(i_target, i_cfgAddr, 4, l_data));
- readLE(l_data, l_idx, l_rd);
+
+ if (l_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL_LITTLE_ENDIAN)
+ {
+ readLE(l_data, l_idx, l_rd);
+ }
+ else
+ {
+ readBE(l_data, l_idx, l_rd);
+ }
+
o_data = l_rd;
fapi_try_exit:
- FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err);
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
return fapi2::current_err;
}
-
///
/// @brief Converts a little endian data array to a host_fw_response_struct
/// @param[in] i_data little endian data to process
@@ -401,19 +433,37 @@ fapi2::ReturnCode host_fw_response_struct_from_little_endian(std::vector<uint8_t
host_fw_response_struct& o_response)
{
uint32_t l_idx = 0;
+
+ uint8_t l_response_id = 0;
+ uint8_t l_response_flags = 0;
+ uint16_t l_request_identifier = 0;
+ uint32_t l_response_length = 0;
+ uint32_t l_response_crc = 0;
+ uint32_t l_host_work_area = 0;
+ uint32_t l_response_header_crc = 0;
+
FAPI_TRY(correctMMIOEndianForStruct(i_data));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_response.response_id));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_response.response_flags));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_response.request_identifier));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_response.response_length));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_response.response_crc));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_response.host_work_area));
+ FAPI_TRY(correctMMIOword_order(i_data));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_id));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_flags));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_request_identifier));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_length));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_crc));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_host_work_area));
FAPI_TRY(readCrctEndianArray(i_data, RSP_PADDING_SIZE, l_idx, o_response.padding));
FAPI_TRY(readCrctEndianArray(i_data, ARGUMENT_SIZE, l_idx, o_response.response_argument));
+ o_response.response_id = l_response_id;
+ o_response.response_flags = l_response_flags;
+ o_response.request_identifier = l_request_identifier;
+ o_response.response_length = l_response_length;
+ o_response.response_crc = l_response_crc;
+ o_response.host_work_area = l_host_work_area;
+
o_crc = crc32_gen(i_data, l_idx);
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_response.response_header_crc));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_response_header_crc));
+ o_response.response_header_crc = l_response_header_crc;
fapi_try_exit:
return fapi2::current_err;
@@ -434,15 +484,17 @@ fapi2::ReturnCode host_fw_response_struct_from_little_endian(const fapi2::Target
{
uint32_t l_crc = 0;
fapi2::current_err = host_fw_response_struct_from_little_endian(i_data, l_crc, o_response);
- FAPI_ASSERT( fapi2::current_err == fapi2::FAPI2_RC_SUCCESS,
- fapi2::EXP_INBAND_LE_DATA_RANGE()
- .set_TARGET(i_target)
- .set_FUNCTION(mss::exp::READ_HOST_FW_RESPONSE_STRUCT)
- .set_DATA_SIZE(i_data.size())
- .set_MAX_INDEX(sizeof(host_fw_response_struct)),
- "%s Failed to convert from data to host_fw_response_struct data size %u expected size %u",
- mss::c_str(i_target), i_data.size(), sizeof(host_fw_response_struct));
-
+ FAPI_ASSERT(fapi2::current_err == fapi2::FAPI2_RC_SUCCESS,
+ fapi2::EXP_INBAND_LE_DATA_RANGE()
+ .set_TARGET(i_target)
+ .set_FUNCTION(mss::exp::READ_HOST_FW_RESPONSE_STRUCT)
+ .set_DATA_SIZE(i_data.size())
+ .set_MAX_INDEX(sizeof(host_fw_response_struct)),
+ "%s Failed to convert from data to host_fw_response_struct data size %u expected size %u",
+ mss::c_str(i_target), i_data.size(), sizeof(host_fw_response_struct));
+
+//TODO CQ: SW461052 Correct MMIO CRC responses
+#ifndef CONFIG_AXONE_BRING_UP
FAPI_ASSERT(l_crc == o_response.response_header_crc,
fapi2::EXP_INBAND_RSP_CRC_ERR()
.set_COMPUTED(l_crc)
@@ -450,6 +502,73 @@ fapi2::ReturnCode host_fw_response_struct_from_little_endian(const fapi2::Target
.set_OCMB_TARGET(i_target),
"%s Response CRC failed to validate computed: 0x%08x got: 0x%08x",
mss::c_str(i_target), l_crc, o_response.response_header_crc);
+#endif
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Polls for response ready door bell bit
+/// @param[in] i_target the OCMB target on which to operate
+/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode poll_for_response_ready(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ // NUM_LOOPS is based on EXP_FW_DDR_PHY_INIT command, which completes in ~370ms in HW.
+ // We initially delay 8ms, so we should only need to poll for ~360ms here.
+ // We're waiting 20ms between polls, so we should only need about 18 loops here,
+ // but we make it 200 to be safe. Max timeout is (200 x 20ms) = 4 seconds
+ constexpr uint64_t NUM_LOOPS = 200;
+
+ // So, why aren't we using the memory team's polling API?
+ // This is a base function that will be utilized by the platform code
+ // As such, we don't want to pull in more libraries than we need to: it would cause extra dependencies
+ // So, we're decomposing the polling library below
+ bool l_doorbell_response = false;
+ uint64_t l_loop = 0;
+ fapi2::buffer<uint64_t> l_data;
+
+ // Loop until we max our our loop count or get a doorbell response
+ for (; l_loop < NUM_LOOPS && !l_doorbell_response; ++l_loop)
+ {
+ FAPI_TRY(fapi2::getScom(i_target, EXPLR_MIPS_TO_OCMB_INTERRUPT_REGISTER1, l_data));
+ l_doorbell_response = l_data.getBit<EXPLR_MIPS_TO_OCMB_INTERRUPT_REGISTER1_DOORBELL>();
+ FAPI_TRY(fapi2::delay(20 * DELAY_1MS, 200));
+ }
+
+ FAPI_DBG("%s stopped on loop%u/%u data:0x%016lx %u",
+ mss::c_str(i_target), l_loop, NUM_LOOPS, l_data, l_doorbell_response);
+
+ // Error check - doorbell response should be true
+ FAPI_ASSERT(l_doorbell_response,
+ fapi2::EXP_INBAND_RSP_NO_DOORBELL()
+ .set_OCMB_TARGET(i_target)
+ .set_DATA(l_data)
+ .set_NUM_LOOPS(l_loop),
+ "%s doorbell timed out after %u loops: data 0x%016lx",
+ mss::c_str(i_target), l_loop, l_data);
+
+ // Ding-dong! the doorbell is rung and the response is ready
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Clears outbound (response ready) door bell bit
+/// @param[in] i_target the OCMB target on which to operate
+/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode clear_outbound_doorbell(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ fapi2::buffer<uint64_t> l_data;
+
+ // Doorbell is cleared by writing a '1' to the doorbell bit
+ l_data.setBit<EXPLR_MIPS_TO_OCMB_INTERRUPT_REGISTER1_DOORBELL>();
+
+ FAPI_DBG("%s Clearing outbound doorbell...", mss::c_str(i_target));
+ FAPI_TRY(fapi2::putScom(i_target, EXPLR_MIPS_TO_OCMB_INTERRUPT_REGISTER1, l_data));
fapi_try_exit:
return fapi2::current_err;
@@ -464,36 +583,46 @@ fapi_try_exit:
/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
fapi2::ReturnCode getRSP(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
- host_fw_response_struct& o_rsp, std::vector<uint8_t>& o_data)
+ host_fw_response_struct& o_rsp,
+ std::vector<uint8_t>& o_data)
{
std::vector<uint8_t> l_data(static_cast<int>(sizeof(o_rsp)));
- FAPI_TRY(fapi2::getMMIO(i_target, EXPLR_IB_RSP_ADDR, BUFFER_TRANSACTION_SIZE, l_data));
+ // Polls for the response to be ready first
+ FAPI_TRY(poll_for_response_ready(i_target));
+
+ FAPI_DBG("Reading the response buffer...");
+ FAPI_TRY(fapi2::getMMIO(i_target, EXPLR_IB_RSP_ADDR, BUFFER_TRANSACTION_SIZE, l_data));
FAPI_TRY(host_fw_response_struct_from_little_endian(i_target, l_data, o_rsp));
+ FAPI_DBG("Checking if we have response data...");
+
// If response data in buffer portion, return that too
if (o_rsp.response_length > 0)
{
// make sure expected size is a multiple of 8
- o_data.resize( o_rsp.response_length +
- (8 - (o_rsp.response_length % 8)) );
+ const uint32_t l_padding = ((o_rsp.response_length % 8) > 0) ? (8 - (o_rsp.response_length % 8)) : 0;
+ o_data.resize(o_rsp.response_length + l_padding);
+ FAPI_DBG("Reading response data...");
- FAPI_TRY( fapi2::getMMIO(i_target, EXPLR_IB_DATA_ADDR, BUFFER_TRANSACTION_SIZE, o_data) );
+ FAPI_TRY(fapi2::getMMIO(i_target, EXPLR_IB_DATA_ADDR, BUFFER_TRANSACTION_SIZE, o_data));
+ FAPI_TRY(correctMMIOEndianForStruct(o_data));
+ FAPI_TRY(correctMMIOword_order(o_data));
}
else
{
+ FAPI_DBG("No response data returned...");
// make sure no buffer data is returned
o_data.clear();
}
+ FAPI_TRY(clear_outbound_doorbell(i_target));
+
fapi_try_exit:
- FAPI_DBG("%s Exiting with return code : 0x%08X...", mss::c_str(i_target), (uint64_t) fapi2::current_err);
+ FAPI_DBG("%s Exiting with return code : 0x%08X...", mss::c_str(i_target), (uint64_t)fapi2::current_err);
return fapi2::current_err;
}
-
-
-
///
/// @brief Converts a little endian data array to a sensor_cache_struct
/// @param[in] i_data little endian data to process
@@ -504,25 +633,59 @@ fapi_try_exit:
fapi2::ReturnCode sensor_cache_struct_from_little_endian(std::vector<uint8_t>& i_data,
sensor_cache_struct& o_data)
{
+ // Local variables to avoid error in passing packed struct fields by reference
uint32_t l_idx = 0;
+ uint16_t l_status = 0;
+ uint16_t l_ocmb_dts = 0;
+ uint16_t l_mem_dts0 = 0;
+ uint16_t l_mem_dts1 = 0;
+ uint32_t l_mba_reads = 0;
+ uint32_t l_mba_writes = 0;
+ uint32_t l_mba_activations = 0;
+ uint32_t l_mba_powerups = 0;
+ uint8_t l_self_timed_refresh = 0;
+ uint32_t l_frame_count = 0;
+ uint32_t l_mba_arrival_histo_base = 0;
+ uint32_t l_mba_arrival_histo_low = 0;
+ uint32_t l_mba_arrival_histo_med = 0;
+ uint32_t l_mba_arrival_histo_high = 0;
+ uint8_t l_initial_packet1 = 0;
FAPI_TRY(correctMMIOEndianForStruct(i_data));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.status));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.ocmb_dts));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.mem_dts0));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.mem_dts1));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.mba_reads));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.mba_writes));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.mba_activations));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.mba_powerups));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.self_timed_refresh));
+ FAPI_TRY(correctMMIOword_order(i_data));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_status));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_ocmb_dts));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_mem_dts0));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_mem_dts1));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_reads));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_writes));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_activations));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_powerups));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_self_timed_refresh));
FAPI_TRY(readCrctEndianArray(i_data, SENSOR_CACHE_PADDING_SIZE_0, l_idx, o_data.reserved0));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.frame_count));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.mba_arrival_histo_base));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.mba_arrival_histo_low));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.mba_arrival_histo_med));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.mba_arrival_histo_high));
- FAPI_TRY(readCrctEndian(i_data, l_idx, o_data.initial_packet1));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_frame_count));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_arrival_histo_base));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_arrival_histo_low));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_arrival_histo_med));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_mba_arrival_histo_high));
+ FAPI_TRY(readCrctEndian(i_data, l_idx, l_initial_packet1));
+
+ o_data.frame_count = l_frame_count;
+ o_data.mba_arrival_histo_base = l_mba_arrival_histo_base;
+ o_data.mba_arrival_histo_low = l_mba_arrival_histo_low;
+ o_data.mba_arrival_histo_med = l_mba_arrival_histo_med;
+ o_data.mba_arrival_histo_high = l_mba_arrival_histo_high;
+ o_data.initial_packet1 = l_initial_packet1;
+ o_data.status = l_status;
+ o_data.ocmb_dts = l_ocmb_dts;
+ o_data.mem_dts0 = l_mem_dts0;
+ o_data.mem_dts1 = l_mem_dts1;
+ o_data.mba_reads = l_mba_reads;
+ o_data.mba_writes = l_mba_writes;
+ o_data.mba_activations = l_mba_activations;
+ o_data.mba_powerups = l_mba_powerups;
+ o_data.self_timed_refresh = l_self_timed_refresh;
+
FAPI_TRY(readCrctEndianArray(i_data, SENSOR_CACHE_PADDING_SIZE_1, l_idx, o_data.reserved1));
fapi_try_exit:
@@ -569,62 +732,106 @@ fapi2::ReturnCode getSensorCache(
FAPI_TRY(sensor_cache_struct_from_little_endian(i_target, l_data, o_data));
fapi_try_exit:
- FAPI_DBG("%s Exiting with return code : 0x%08X...", mss::c_str(i_target), (uint64_t) fapi2::current_err);
+ FAPI_DBG("%s Exiting with return code : 0x%08X...", mss::c_str(i_target), (uint64_t)fapi2::current_err);
return fapi2::current_err;
}
+///
+/// @brief UT helper for correctMMIOEndianForStruct
+///
+/// @param[in] i_endian_ctrl value of ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL
+/// @param[in,out] io_data value to swizzle
+///
+void correctMMIOEndianForStruct_helper(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL_Type i_endian_ctrl,
+ std::vector<uint8_t>& io_data)
+{
+ size_t l_loops = 0;
+ if (i_endian_ctrl == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL_SWAP)
+ {
+ l_loops = io_data.size() / BUFFER_TRANSACTION_SIZE;
+ for (size_t l_idx = 0; l_idx < l_loops; l_idx++)
+ {
+ for (int l_bidx = BUFFER_TRANSACTION_SIZE - 1; l_bidx >= 0; l_bidx--)
+ {
+ io_data.push_back(io_data.at(l_bidx));
+ }
+ io_data.erase(io_data.begin(), io_data.begin() + BUFFER_TRANSACTION_SIZE);
+ }
+ }
+}
+///
/// @brief We will use 4 or 8 byte reads via fapi2::put/getMMIO for buffer
/// data structures. The byte order of the 4 or 8 byte reads should be little
/// endian. In order to represent the data structure in its proper layout
/// the endianness of each 4 or 8 byte read must be corrected.
-///
/// @param[in,out] io_data Either data structure in proper byte order that we
/// want to swizzle prior to writing to the buffer, or the data returned
/// from reading the buffer that we want to unsizzle.
-///
/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
fapi2::ReturnCode correctMMIOEndianForStruct(std::vector<uint8_t>& io_data)
{
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL_Type l_endian_ctrl;
- size_t l_loops = 0;
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL,
- FAPI_SYSTEM, l_endian_ctrl));
- if (l_endian_ctrl == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL_NO_SWAP)
- {
- goto fapi_try_exit;
- }
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL,
+ FAPI_SYSTEM, l_endian_ctrl));
+ correctMMIOEndianForStruct_helper(l_endian_ctrl, io_data);
- while ((io_data.size() % BUFFER_TRANSACTION_SIZE) != 0)
- {
- io_data.push_back(0);
- }
-
- l_loops = io_data.size() / BUFFER_TRANSACTION_SIZE;
+fapi_try_exit:
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
+ return fapi2::current_err;
+}
- for (size_t l_idx = 0; l_idx < l_loops; l_idx++)
+///
+/// @brief UT helper for correctMMIOword_order
+/// @param[in] i_word_swap value of ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP
+/// @param[in,out] io_data value to swizzle
+///
+void correctMMIOword_order_helper(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP_Type i_word_swap,
+ std::vector<uint8_t>& io_data)
+{
+ if (i_word_swap == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP_SWAP)
{
- for (int l_bidx = BUFFER_TRANSACTION_SIZE - 1; l_bidx >= 0; l_bidx--)
+ for (size_t l_idx = 0; l_idx < io_data.size(); l_idx += BUFFER_TRANSACTION_SIZE)
{
- io_data.push_back(io_data.at(l_bidx));
+ for (size_t l_bidx = l_idx; l_bidx < l_idx + BUFFER_TRANSACTION_SIZE / 2; l_bidx++)
+ {
+ uint8_t l_temp_first_word = io_data.at(l_bidx);
+ uint8_t l_temp_second_word = io_data.at(l_bidx + BUFFER_TRANSACTION_SIZE / 2);
+ io_data[l_bidx] = l_temp_second_word;
+ io_data[l_bidx + BUFFER_TRANSACTION_SIZE / 2] = l_temp_first_word;
+ }
}
-
- io_data.erase(io_data.begin(), io_data.begin() + BUFFER_TRANSACTION_SIZE);
}
+}
+
+///
+/// @brief Because of how the AXI bridge in Explorer breaks up the transaction,
+/// we might need to swap 32-bit word order
+/// @param[in,out] io_data Either data structure in proper byte order that we
+/// want to swizzle prior to writing to the buffer, or the data returned
+/// from reading the buffer that we want to unsizzle.
+/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode correctMMIOword_order(std::vector<uint8_t>& io_data)
+{
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
+ fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP_Type l_word_swap;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP,
+ FAPI_SYSTEM, l_word_swap));
+ correctMMIOword_order_helper(l_word_swap, io_data);
fapi_try_exit:
- FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err);
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
return fapi2::current_err;
}
-
-
///
/// @brief Forces native data into the correct endianness necessary for Explorer
/// buffer data structures.
@@ -632,14 +839,14 @@ fapi_try_exit:
/// @param[in] i_input inputted data to process
/// @param[in,out] io_data vector to append data to
///
-template < typename T >
+template <typename T>
fapi2::ReturnCode forceCrctEndian(const T& i_input, std::vector<uint8_t>& io_data)
{
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_Type l_struct_endian;
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN,
- FAPI_SYSTEM, l_struct_endian));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN,
+ FAPI_SYSTEM, l_struct_endian));
if (l_struct_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_LITTLE_ENDIAN)
{
@@ -651,12 +858,10 @@ fapi2::ReturnCode forceCrctEndian(const T& i_input, std::vector<uint8_t>& io_dat
}
fapi_try_exit:
- FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err);
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
return fapi2::current_err;
}
-
-
///
/// @brief Forces native data into the correct endianness for an array buffer
/// data structures.
@@ -665,14 +870,14 @@ fapi_try_exit:
/// @param[in] i_size size of the array
/// @param[in,out] io_data vector to append data to
///
-template < typename T >
+template <typename T>
fapi2::ReturnCode forceCrctEndianArray(const T* i_input, const uint64_t i_size, std::vector<uint8_t>& io_data)
{
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_Type l_struct_endian;
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN,
- FAPI_SYSTEM, l_struct_endian));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN,
+ FAPI_SYSTEM, l_struct_endian));
if (l_struct_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_LITTLE_ENDIAN)
{
@@ -684,12 +889,10 @@ fapi2::ReturnCode forceCrctEndianArray(const T* i_input, const uint64_t i_size,
}
fapi_try_exit:
- FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err);
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
return fapi2::current_err;
}
-
-
///
/// @brief Converts endianness of data read from Explorer buffer data structures
// into native order.
@@ -699,14 +902,14 @@ fapi_try_exit:
/// @param[out] o_data data that has been converted into native endianness
/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
///
-template < typename T >
+template <typename T>
fapi2::ReturnCode readCrctEndian(const std::vector<uint8_t>& i_input, uint32_t& io_idx, T& o_data)
{
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_Type l_struct_endian;
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN,
- FAPI_SYSTEM, l_struct_endian));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN,
+ FAPI_SYSTEM, l_struct_endian));
if (l_struct_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_LITTLE_ENDIAN)
{
@@ -732,21 +935,19 @@ fapi2::ReturnCode readCrctEndian(const std::vector<uint8_t>& i_input, uint32_t&
}
fapi_try_exit:
- FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err);
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
return fapi2::current_err;
}
-
-
-template < typename T >
+template <typename T>
fapi2::ReturnCode readCrctEndianArray(const std::vector<uint8_t>& i_input, const uint32_t i_size, uint32_t& io_idx,
T* o_data)
{
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_Type l_struct_endian;
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN,
- FAPI_SYSTEM, l_struct_endian));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN,
+ FAPI_SYSTEM, l_struct_endian));
if (l_struct_endian == fapi2::ENUM_ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN_LITTLE_ENDIAN)
{
@@ -772,13 +973,12 @@ fapi2::ReturnCode readCrctEndianArray(const std::vector<uint8_t>& i_input, const
}
fapi_try_exit:
- FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t) fapi2::current_err);
+ FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
return fapi2::current_err;
}
+} // namespace ib
-} // ns ib
-
-} // ns exp
+} // namespace exp
-} // ns mss
+} // namespace mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.H
index 7c88ff45b..9b562ed0b 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_inband.H $ */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/exp_inband.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -87,6 +87,8 @@
#include <exp_data_structs.H>
#include <explorer_scom_addresses.H>
#include <explorer_scom_addresses_fld.H>
+#include <explorer_scom_addresses_fixes.H>
+#include <explorer_scom_addresses_fld_fixes.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
namespace mss
@@ -101,9 +103,9 @@ namespace ib
static const size_t BUFFER_TRANSACTION_SIZE = 8;
static const uint64_t EXPLR_IB_CONFIG_OFFSET = 0x0000000000000000ull;
-static const uint64_t EXPLR_IB_MMIO_OFFSET = 0x0000000100000000ull; // 4GB
-static const uint64_t EXPLR_IB_BAR_SIZE = 0b01111111; // 4GB Depends on EXPLR_IB_MMIO_OFFSET
-static const uint64_t EXPLR_IB_BAR_B_BIT = EXPLR_IB_MMIO_OFFSET >> 1; // 2GB AND with A == 0, AND with B != 0
+static const uint64_t EXPLR_IB_MMIO_OFFSET = 0x0000000100000000ull; // 4GB
+static const uint64_t EXPLR_IB_BAR_SIZE = 0b01111111; // 4GB Depends on EXPLR_IB_MMIO_OFFSET
+static const uint64_t EXPLR_IB_BAR_B_BIT = EXPLR_IB_MMIO_OFFSET >> 1; // 2GB AND with A == 0, AND with B != 0
static const uint64_t EXPLR_IB_BAR_MASK_ZERO = (EXPLR_IB_BAR_B_BIT - 1); // AND with BAR must == 0
//--------------------------------------------------------------------------------
@@ -117,13 +119,13 @@ static const uint64_t EXPLR_IB_BAR_MASK_ZERO = (EXPLR_IB_BAR_B_BIT - 1); // AND
/// Response Buffer 0xA103 FF00 BAR + 0x0103 FF00 0xA103 FF00
/// Data Buffer 0xA102 FF00 BAR + 0x0102 FF00 0xA102 FF00
///
-static const uint64_t EXPLR_IB_SRAM_BASE = 0x01000000; // MSCCRNGE 01000000 020FFFFF
-static const uint64_t EXPLR_IB_CMD_SRAM_ADDR = EXPLR_IB_SRAM_BASE | 0x03FF40;
-static const uint64_t EXPLR_IB_RSP_SRAM_ADDR = EXPLR_IB_SRAM_BASE | 0x03FF00;
+static const uint64_t EXPLR_IB_SRAM_BASE = 0x01000000; // MSCCRNGE 01000000 020FFFFF
+static const uint64_t EXPLR_IB_CMD_SRAM_ADDR = EXPLR_IB_SRAM_BASE | 0x03FF40;
+static const uint64_t EXPLR_IB_RSP_SRAM_ADDR = EXPLR_IB_SRAM_BASE | 0x03FF00;
static const uint64_t EXPLR_IB_DATA_SRAM_ADDR = EXPLR_IB_SRAM_BASE | 0x02FF00;
-static const uint64_t EXPLR_IB_CMD_ADDR = EXPLR_IB_MMIO_OFFSET | EXPLR_IB_CMD_SRAM_ADDR;
-static const uint64_t EXPLR_IB_RSP_ADDR = EXPLR_IB_MMIO_OFFSET | EXPLR_IB_RSP_SRAM_ADDR;
+static const uint64_t EXPLR_IB_CMD_ADDR = EXPLR_IB_MMIO_OFFSET | EXPLR_IB_CMD_SRAM_ADDR;
+static const uint64_t EXPLR_IB_RSP_ADDR = EXPLR_IB_MMIO_OFFSET | EXPLR_IB_RSP_SRAM_ADDR;
static const uint64_t EXPLR_IB_DATA_ADDR = EXPLR_IB_MMIO_OFFSET | EXPLR_IB_DATA_SRAM_ADDR;
static const uint64_t EXPLR_IB_SENSOR_CACHE_ADDR = EXPLR_IB_MMIO_OFFSET | 0x40084200;
@@ -212,10 +214,7 @@ fapi2::ReturnCode sensor_cache_struct_from_little_endian(const fapi2::Target<fap
fapi2::ReturnCode putMMIO64(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const uint64_t i_addr,
- const fapi2::buffer<uint64_t>& i_data ) ;
-
-
-
+ const fapi2::buffer<uint64_t>& i_data);
/// @brief Writes 32 bits of data to MMIO space to the selected Explorer
///
@@ -227,10 +226,7 @@ fapi2::ReturnCode putMMIO64(
fapi2::ReturnCode putMMIO32(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const uint64_t i_addr,
- const fapi2::buffer<uint32_t>& i_data ) ;
-
-
-
+ const fapi2::buffer<uint32_t>& i_data);
/// @brief Writes 64 bits of data to SCOM MMIO space
///
@@ -242,10 +238,7 @@ fapi2::ReturnCode putMMIO32(
fapi2::ReturnCode putScom(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const uint64_t i_scomAddr,
- const fapi2::buffer<uint64_t>& i_data) ;
-
-
-
+ const fapi2::buffer<uint64_t>& i_data);
/// @brief Writes 32 bits of data to OpenCAPI config space
///
@@ -257,10 +250,7 @@ fapi2::ReturnCode putScom(
fapi2::ReturnCode putOCCfg(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const uint64_t i_cfgAddr,
- const fapi2::buffer<uint32_t>& i_data) ;
-
-
-
+ const fapi2::buffer<uint32_t>& i_data);
/// @brief Writes user_input_msdg to the data buffer
///
@@ -274,9 +264,6 @@ fapi2::ReturnCode putUserInputMsdg(
const user_input_msdg& i_data,
uint32_t& o_crc);
-
-
-
/// @brief Writes a command to the command buffer and issues interrupt
///
/// @param[in] i_target The Explorer chip to issue the command to
@@ -285,9 +272,7 @@ fapi2::ReturnCode putUserInputMsdg(
/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
fapi2::ReturnCode putCMD(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
- const host_fw_command_struct& i_cmd) ;
-
-
+ const host_fw_command_struct& i_cmd);
//--------------------------------------------------------------------------------
// Read operations
@@ -303,10 +288,7 @@ fapi2::ReturnCode putCMD(
fapi2::ReturnCode getMMIO64(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const uint64_t i_addr,
- fapi2::buffer<uint64_t>& o_data) ;
-
-
-
+ fapi2::buffer<uint64_t>& o_data);
/// @brief Reads 32 bits of data from MMIO space on the selected Explorer
///
@@ -318,10 +300,7 @@ fapi2::ReturnCode getMMIO64(
fapi2::ReturnCode getMMIO32(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const uint64_t i_addr,
- fapi2::buffer<uint32_t>& o_data) ;
-
-
-
+ fapi2::buffer<uint32_t>& o_data);
/// @brief Reads 64 bits of data from SCOM MMIO space on the selected Explorer
///
@@ -333,10 +312,7 @@ fapi2::ReturnCode getMMIO32(
fapi2::ReturnCode getScom(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const uint64_t i_scomAddr,
- fapi2::buffer<uint64_t>& o_data) ;
-
-
-
+ fapi2::buffer<uint64_t>& o_data);
/// @brief Reads 32 bits of data from OpenCAPI config space on the selected Explorer
///
@@ -348,10 +324,21 @@ fapi2::ReturnCode getScom(
fapi2::ReturnCode getOCCfg(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const uint64_t i_cfgAddr,
- fapi2::buffer<uint32_t>& o_data) ;
-
+ fapi2::buffer<uint32_t>& o_data);
+///
+/// @brief Polls for response ready door bell bit
+/// @param[in] i_target the OCMB target on which to operate
+/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode poll_for_response_ready(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+///
+/// @brief Clears outbound (response ready) door bell bit
+/// @param[in] i_target the OCMB target on which to operate
+/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode clear_outbound_doorbell(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
/// @brief Reads a response from the response buffer
///
@@ -363,10 +350,8 @@ fapi2::ReturnCode getOCCfg(
/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
fapi2::ReturnCode getRSP(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
- host_fw_response_struct& o_rsp, std::vector<uint8_t>& o_data) ;
-
-
-
+ host_fw_response_struct& o_rsp,
+ std::vector<uint8_t>& o_data);
/// @brief Reads the complete 64 byte sensor cache on the selected Explorer
///
@@ -376,12 +361,51 @@ fapi2::ReturnCode getRSP(
/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
fapi2::ReturnCode getSensorCache(
const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
- sensor_cache_struct& o_data) ;
+ sensor_cache_struct& o_data);
//--------------------------------------------------------------------------------
// Command/Response/Data structure Endian handling
//--------------------------------------------------------------------------------
+///
+/// @brief UT helper for correctMMIOEndianForStruct
+///
+/// @param[in] i_endian_ctrl value of ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL
+/// @param[in,out] io_data value to swizzle
+///
+void correctMMIOEndianForStruct_helper(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL_Type i_endian_ctrl,
+ std::vector<uint8_t>& io_data);
+
+///
+/// @brief We will use 4 or 8 byte reads via fapi2::put/getMMIO for buffer
+/// data structures. The byte order of the 4 or 8 byte reads should be little
+/// endian. In order to represent the data structure in its proper layout
+/// the endianness of each 4 or 8 byte read must be corrected.
+/// @param[in,out] io_data Either data structure in proper byte order that we
+/// want to swizzle prior to writing to the buffer, or the data returned
+/// from reading the buffer that we want to unsizzle.
+/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode correctMMIOEndianForStruct(std::vector<uint8_t>& io_data);
+
+///
+/// @brief UT helper for correctMMIOword_order
+/// @param[in] i_word_swap value of ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP
+/// @param[in,out] io_data value to swizzle
+///
+void correctMMIOword_order_helper(fapi2::ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP_Type i_word_swap,
+ std::vector<uint8_t>& io_data);
+
+///
+/// @brief Because of how the AXI bridge in Explorer breaks up the transaction,
+/// we might need to swap 32-bit word order
+/// @param[in,out] io_data Either data structure in proper byte order that we
+/// want to swizzle prior to writing to the buffer, or the data returned
+/// from reading the buffer that we want to unsizzle.
+/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode correctMMIOword_order(std::vector<uint8_t>& io_data);
+
/// @brief We will use 4 or 8 byte reads via fapi2::put/getMMIO for buffer
/// data structures. The byte order of the 4 or 8 byte reads should be little
/// endian. In order to represent the data structure in its proper layout
@@ -394,6 +418,30 @@ fapi2::ReturnCode getSensorCache(
/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
fapi2::ReturnCode correctMMIOEndianForStruct(std::vector<uint8_t>& io_data);
+/// @brief Because of how the AXI bridge in Explorer breaks up the transaction,
+/// we might need to swap 32-bit word order
+/// @param[in,out] io_data Either data structure in proper byte order that we
+/// want to swizzle prior to writing to the buffer, or the data returned
+/// from reading the buffer that we want to unsizzle.
+///
+/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode correctMMIOword_order(std::vector<uint8_t>& io_data);
+
+/// @brief Ensure data is an even multiple of 8 (BUFFER_TRANSACTION_SIZE).
+/// If (sizeof(buffer) % BUFFER_TRANSACTION_SIZE != 0) ; then pad
+/// buffer with zeros until statement is true.
+///
+/// @param[in,out] io_data Communication data , either CMD or RSP buffer
+///
+/// @return void
+inline void padCommData(std::vector<uint8_t>& io_data)
+{
+ while ((io_data.size() % BUFFER_TRANSACTION_SIZE) != 0)
+ {
+ io_data.push_back(0);
+ }
+}
+
///
/// @brief Forces native data into the correct endianness necessary for Explorer
/// buffer data structures.
@@ -402,7 +450,7 @@ fapi2::ReturnCode correctMMIOEndianForStruct(std::vector<uint8_t>& io_data);
/// @param[in,out] io_data vector to append data to
/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
///
-template < typename T >
+template <typename T>
fapi2::ReturnCode forceCrctEndian(const T& i_input, std::vector<uint8_t>& io_data);
///
@@ -414,7 +462,7 @@ fapi2::ReturnCode forceCrctEndian(const T& i_input, std::vector<uint8_t>& io_dat
/// @param[in,out] io_data vector to append data to
/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
///
-template < typename T >
+template <typename T>
fapi2::ReturnCode forceCrctEndianArray(const T* i_input, const uint64_t i_size, std::vector<uint8_t>& io_data);
///
@@ -426,7 +474,7 @@ fapi2::ReturnCode forceCrctEndianArray(const T* i_input, const uint64_t i_size,
/// @param[out] o_data data that has been converted into native endianness
/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
///
-template < typename T >
+template <typename T>
fapi2::ReturnCode readCrctEndian(const std::vector<uint8_t>& i_input, uint32_t& io_idx, T& o_data);
///
@@ -439,16 +487,16 @@ fapi2::ReturnCode readCrctEndian(const std::vector<uint8_t>& i_input, uint32_t&
/// @param[out] o_data data that has been converted into native endianness
/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
///
-template < typename T >
+template <typename T>
fapi2::ReturnCode readCrctEndianArray(const std::vector<uint8_t>& i_input, const uint32_t i_size, uint32_t& io_idx,
T* o_data);
//--------------------------------------------------------------------------------
-} // ns ib
+} // namespace ib
-} // ns exp
+} // namespace exp
-} // ns mss
+} // namespace mss
#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/exp_port.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/exp_port.C
new file mode 100644
index 000000000..e4d733180
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/exp_port.C
@@ -0,0 +1,81 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/exp_port.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2020 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_port.C
+/// @brief Code to support ports
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#include <fapi2.H>
+#include <lib/shared/exp_defaults.H>
+#include <exp_port.H>
+
+namespace mss
+{
+
+///
+/// @brief Set up memory controller specific settings for ECC registers (at the end of draminit_mc)
+/// @param[in] i_target the target
+/// @param[in,out] io_data contents of RECR register
+/// @return FAPI2_RC_SUCCESS if and only if ok
+/// @note mc_type::EXPLORER specialization
+///
+template< >
+fapi2::ReturnCode ecc_reg_settings_draminit_mc<mss::mc_type::EXPLORER>(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ fapi2::buffer<uint64_t>& io_data )
+{
+ using TT = portTraits<mss::mc_type::EXPLORER>;
+ fapi2::buffer<uint64_t> l_ctcr_data;
+
+ // Explorer specific settings for RECR
+ io_data.setBit<TT::RECR_ENABLE_MPE_NOISE_WINDOW>();
+ io_data.setBit<TT::RECR_RETRY_UNMARKED_ERRORS>();
+ io_data.clearBit<TT::RECR_CFG_MAINT_USE_TIMERS>();
+
+ // Set up CTCR timers to 20x4^3 (1280 clock cycles; typical read latency is 120ish, so this is about 10x)
+ // This is a preliminary guess from the design team. Also enable UE lockout window
+ // CTCR -> 51A8E00000000000
+ FAPI_TRY( mss::getScom(i_target, TT::CTCR_REG, l_ctcr_data) );
+
+ l_ctcr_data.insertFromRight<TT::CTCR_MPE_TIMER, TT::CTCR_MPE_TIMER_LEN>(0b010100);
+ l_ctcr_data.insertFromRight<TT::CTCR_MPE_TIMEBASE, TT::CTCR_MPE_TIMEBASE_LEN>(0b011);
+ l_ctcr_data.insertFromRight<TT::CTCR_UE_TIMER, TT::CTCR_UE_TIMER_LEN>(0b010100);
+ l_ctcr_data.insertFromRight<TT::CTCR_UE_TIMEBASE, TT::CTCR_UE_TIMEBASE_LEN>(0b011);
+ l_ctcr_data.setBit<TT::CTCR_UE_LOCKOUT_ENABLE>();
+
+ FAPI_TRY( mss::putScom(i_target, TT::CTCR_REG, l_ctcr_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+}// mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/exp_port.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/exp_port.H
index a65375672..57646e97a 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/exp_port.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/exp_port.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,31 +39,22 @@
#include <fapi2.H>
#include <explorer_scom_addresses.H>
#include <explorer_scom_addresses_fld.H>
+#include <explorer_scom_addresses_fld_fixes.H>
#include <lib/exp_attribute_accessors_manual.H>
+#include <lib/utils/mss_exp_conversions.H>
+#include <mss_explorer_attribute_getters.H>
#include <lib/shared/exp_consts.H>
+#include <lib/dimm/exp_rank.H>
#include <generic/memory/lib/utils/mc/gen_mss_port.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
-#include <mss_explorer_attribute_getters.H>
+#include <mss_generic_attribute_getters.H>
namespace mss
{
-///
-/// @brief ATTR_MSS_MEM_MVPD_FWMS getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
-/// @param[out] uint32_t* memory to store the value
-/// @note Generated by gen_accessors.pl generateParameters (G)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Mark store records from MPVD Lx
-/// keyword
-///
-template<>
-inline fapi2::ReturnCode mvpd_fwms(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
- uint32_t (&o_array)[mss::MARK_STORE_COUNT])
-{
- return mss::attr::get_mvpd_fwms(i_target, o_array);
-}
-
+//////////////////////////////////////////////////////////////
+// Traits values for EXPLORER
+//////////////////////////////////////////////////////////////
///
/// @class Traits and policy class for port code - specialization for Explorer. The target of registers is TARGET_TYPE_OCMB_CHIP
///
@@ -71,6 +62,9 @@ template<>
class portTraits< mss::mc_type::EXPLORER >
{
public:
+ // PORT_TYPE
+ static constexpr fapi2::TargetType PORT_TYPE = fapi2::TARGET_TYPE_MEM_PORT;
+
// scom register definition
static constexpr uint64_t MBARPC0Q_REG = EXPLR_SRQ_MBARPC0Q;
@@ -78,8 +72,11 @@ class portTraits< mss::mc_type::EXPLORER >
static constexpr uint64_t FARB5Q_REG = EXPLR_SRQ_MBA_FARB5Q;
static constexpr uint64_t FARB6Q_REG = EXPLR_SRQ_MBA_FARB6Q;
static constexpr uint64_t FARB9Q_REG = EXPLR_SRQ_MBA_FARB9Q;
+ static constexpr uint64_t PMU8Q_REG = EXPLR_SRQ_MBA_PMU8Q;
static constexpr uint64_t REFRESH_REG = EXPLR_SRQ_MBAREF0Q;
+ static constexpr uint64_t STR0Q_REG = EXPLR_SRQ_MBASTR0Q;
static constexpr uint64_t ECC_REG = EXPLR_RDF_RECR;
+ static constexpr uint64_t CTCR_REG = EXPLR_RDF_CTCR;
static constexpr uint64_t DSM0Q_REG = EXPLR_SRQ_MBA_DSM0Q;
static constexpr uint64_t FWMS_REG = EXPLR_RDF_FWMS0;
@@ -96,23 +93,45 @@ class portTraits< mss::mc_type::EXPLORER >
CFG_CCS_INST_RESET_ENABLE = EXPLR_SRQ_MBA_FARB5Q_CFG_CCS_INST_RESET_ENABLE,
CFG_DDR_RESETN = EXPLR_SRQ_MBA_FARB5Q_CFG_DDR_RESETN,
CFG_CCS_ADDR_MUX_SEL = EXPLR_SRQ_MBA_FARB5Q_CFG_CCS_ADDR_MUX_SEL,
- //TODO: It's not defined in scom register header file. Change this once it's available in scom address header file
- CFG_INIT_COMPLETE = 32, //EXPLR_SRQ_MBA_FARB6Q_CFG_INIT_COMPLETE,
+ CFG_INIT_COMPLETE = EXPLR_SRQ_MBA_PMU8Q_CFG_INIT_COMPLETE,
CFG_ZQ_PER_CAL_ENABLE = EXPLR_SRQ_MBA_FARB9Q_CFG_ZQ_PER_CAL_ENABLE,
REFRESH_ENABLE = EXPLR_SRQ_MBAREF0Q_CFG_REFRESH_ENABLE,
+ CFG_FORCE_STR = EXPLR_SRQ_MBASTR0Q_CFG_FORCE_STR,
+
ECC_CHECK_DISABLE = EXPLR_RDF_RECR_MBSECCQ_DISABLE_MEMORY_ECC_CHECK_CORRECT,
ECC_CORRECT_DISABLE = EXPLR_RDF_RECR_MBSECCQ_DISABLE_MEMORY_ECC_CORRECT,
ECC_USE_ADDR_HASH = EXPLR_RDF_RECR_MBSECCQ_USE_ADDRESS_HASH,
PORT_FAIL_DISABLE = EXPLR_SRQ_MBA_FARB0Q_CFG_PORT_FAIL_DISABLE,
- DFI_INIT_START = EXPLR_SRQ_MBA_FARB0Q_CFG_MISR_FEEDBACK_ENABLE,
+ DFI_INIT_START = EXPLR_SRQ_MBA_FARB0Q_CFG_INIT_START,
RCD_RECOVERY_DISABLE = EXPLR_SRQ_MBA_FARB0Q_CFG_DISABLE_RCD_RECOVERY,
+ BW_WINDOW_SIZE = EXPLR_SRQ_MBA_FARB0Q_CFG_BW_WINDOW_SIZE,
+ BW_WINDOW_SIZE_LEN = EXPLR_SRQ_MBA_FARB0Q_CFG_BW_WINDOW_SIZE_LEN,
+ BW_SNAPSHOT = EXPLR_SRQ_MBA_FARB6Q_CFG_BW_SNAPSHOT,
+ BW_SNAPSHOT_LEN = EXPLR_SRQ_MBA_FARB6Q_CFG_BW_SNAPSHOT_LEN,
+ RECR_ENABLE_MPE_NOISE_WINDOW = EXPLR_RDF_RECR_MBSECCQ_ENABLE_MPE_NOISE_WINDOW,
+ RECR_ENABLE_UE_NOISE_WINDOW = EXPLR_RDF_RECR_MBSECCQ_ENABLE_UE_NOISE_WINDOW,
RECR_TCE_CORRECTION = EXPLR_RDF_RECR_MBSECCQ_ENABLE_TCE_CORRECTION,
RECR_MBSECCQ_DATA_INVERSION = EXPLR_RDF_RECR_MBSECCQ_DATA_INVERSION,
RECR_MBSECCQ_DATA_INVERSION_LEN = EXPLR_RDF_RECR_MBSECCQ_DATA_INVERSION_LEN,
+ RECR_RETRY_UNMARKED_ERRORS = EXPLR_RDF_RECR_RETRY_UNMARKED_ERRORS,
+ RECR_CFG_MAINT_USE_TIMERS = EXPLR_RDF_RECR_CFG_MAINT_USE_TIMERS,
+ RECR_MBSECCQ_MAINT_NO_RETRY_UE = EXPLR_RDF_RECR_MBSECCQ_MAINT_NO_RETRY_UE,
+ RECR_MBSECCQ_MAINT_NO_RETRY_MPE = EXPLR_RDF_RECR_MBSECCQ_MAINT_NO_RETRY_MPE,
+
+ CTCR_MPE_TIMER = EXPLR_RDF_CTCR_MPE_TIMER,
+ CTCR_MPE_TIMER_LEN = EXPLR_RDF_CTCR_MPE_TIMER_LEN,
+ CTCR_MPE_TIMEBASE = EXPLR_RDF_CTCR_MPE_TIMEBASE,
+ CTCR_MPE_TIMEBASE_LEN = EXPLR_RDF_CTCR_MPE_TIMEBASE_LEN,
+ CTCR_UE_TIMER = EXPLR_RDF_CTCR_UE_TIMER,
+ CTCR_UE_TIMER_LEN = EXPLR_RDF_CTCR_UE_TIMER_LEN,
+ CTCR_UE_TIMEBASE = EXPLR_RDF_CTCR_UE_TIMEBASE,
+ CTCR_UE_TIMEBASE_LEN = EXPLR_RDF_CTCR_UE_TIMEBASE_LEN,
+ CTCR_UE_LOCKOUT_ENABLE = EXPLR_RDF_CTCR_UE_LOCKOUT_ENABLE,
+
DSM0Q_RDTAG_DLY = EXPLR_SRQ_MBA_DSM0Q_CFG_RDTAG_DLY,
DSM0Q_RDTAG_DLY_LEN = EXPLR_SRQ_MBA_DSM0Q_CFG_RDTAG_DLY_LEN,
DSM0Q_WRDONE_DLY = EXPLR_SRQ_MBA_DSM0Q_CFG_WRDONE_DLY,
@@ -129,6 +148,60 @@ class portTraits< mss::mc_type::EXPLORER >
};
};
+///
+/// @brief ATTR_MSS_MEM_MVPD_FWMS getter
+/// @param[in] const ref to the TARGET_TYPE_OCMB_CHIP
+/// @param[out] uint32_t&[] array reference to store the value
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Mark store records from OCMB VPD. The array dimension is [port][mark]. Explorer
+/// only has one port so only [0][mark] is used in explorer.
+///
+template<>
+inline fapi2::ReturnCode mvpd_fwms< mss::mc_type::EXPLORER >(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ uint32_t (&o_array)[mss::MARK_STORE_COUNT])
+{
+ return mss::attr::get_mvpd_fwms(i_target, o_array);
+}
+
+/// @brief Get the attributes for the reorder queue setting
+/// @param[in] const ref to the mc target
+/// @param[out] uint8_t& reference to store the value
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Contains the settings for write/read reorder
+/// queue
+///
+template< >
+inline fapi2::ReturnCode reorder_queue_setting<mss::mc_type::EXPLORER>(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ uint8_t& o_value)
+{
+ return mss::attr::get_reorder_queue_setting(i_target, o_value);
+}
+
+///
+/// @brief Change the state of the force_str bit - mc_type::EXPLORER specialization
+/// @tparam MC the memory controller type
+/// @param[in] i_target the target
+/// @param[in] i_state the state
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template< >
+inline fapi2::ReturnCode change_force_str<DEFAULT_MC_TYPE>(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const states i_state )
+{
+ using TT = portTraits<mss::mc_type::EXPLORER>;
+ fapi2::buffer<uint64_t> l_data;
+
+ FAPI_DBG("Change force_str to %s %s", (i_state == HIGH ? "high" : "low"), mss::c_str(i_target));
+ FAPI_TRY( mss::getScom(i_target, TT::STR0Q_REG, l_data) );
+ l_data.writeBit<TT::CFG_FORCE_STR>(i_state);
+ FAPI_TRY( mss::putScom(i_target, TT::STR0Q_REG, l_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
}// mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_config_thermal.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/exp_port_traits.H
index c552c0454..e76d5b70d 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_config_thermal.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/exp_port_traits.H
@@ -1,7 +1,7 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_config_thermal.C $ */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mc/exp_port_traits.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/address.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/address.H
deleted file mode 100644
index 6f300a2ce..000000000
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/address.H
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/address.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_address.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_address.H
index af8933ce4..6cf1c5a71 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_address.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_address.H
@@ -22,3 +22,28 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_address.H
+/// @brief Class for mcbist related addresses (addresses below the hash translation)
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_MCBIST_EXP_ADDRESS_H_
+#define _MSS_MCBIST_EXP_ADDRESS_H_
+
+#include <fapi2.H>
+#include <utility>
+#include <lib/shared/exp_consts.H>
+#include <lib/ecc/ecc_traits_explorer.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_ecc_trap_address.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_fwms_address.H>
+
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist.C
index 47d9da4af..02da32e8f 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist.C
@@ -22,3 +22,202 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_mcbist.C
+/// @brief Run and manage the MCBIST engine
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include <lib/shared/exp_defaults.H>
+#include <lib/shared/exp_consts.H>
+#include <lib/mcbist/exp_mcbist.H>
+#include <mss_explorer_attribute_getters.H>
+#include <mss_explorer_attribute_setters.H>
+#include <mss_generic_attribute_getters.H>
+
+namespace mss
+{
+
+///
+/// @brief Gets the attribute for freq
+/// @param[in] const ref to the target
+/// @param[out] uint64_t& reference to store the value
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Frequency of this memory channel in MT/s (Mega Transfers per second)
+///
+template<>
+fapi2::ReturnCode freq<mss::mc_type::EXPLORER, fapi2::TARGET_TYPE_OCMB_CHIP>(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ uint64_t& o_value)
+{
+ // Each OCMB only has one MEM_PORT
+ for (const auto l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
+ {
+ return attr::get_freq(l_port, o_value);
+ }
+
+ o_value = 0;
+ return ~fapi2::FAPI2_RC_SUCCESS;
+}
+
+const std::pair<uint64_t, uint64_t> mcbistTraits<mss::mc_type::EXPLORER>::address_pairs[] =
+{
+ { START_ADDRESS_0, END_ADDRESS_0 },
+ { START_ADDRESS_1, END_ADDRESS_1 },
+ { START_ADDRESS_2, END_ADDRESS_2 },
+ { START_ADDRESS_3, END_ADDRESS_3 },
+};
+
+const std::vector< mss::mcbist::op_type > mcbistTraits<mss::mc_type::EXPLORER>::FIFO_MODE_REQUIRED_OP_TYPES =
+{
+ mss::mcbist::op_type::WRITE ,
+ mss::mcbist::op_type::READ ,
+ mss::mcbist::op_type::READ_WRITE ,
+ mss::mcbist::op_type::WRITE_READ ,
+ mss::mcbist::op_type::READ_WRITE_READ ,
+ mss::mcbist::op_type::READ_WRITE_WRITE ,
+ mss::mcbist::op_type::RAND_SEQ ,
+ mss::mcbist::op_type::READ_READ_WRITE ,
+};
+
+// These valus are pulled out of the MCBIST specification - page 41 10-DEC-19
+// The index is the fixed width - the value is the LFSR_MASK value to be used
+const std::vector< uint64_t > mcbistTraits<mss::mc_type::EXPLORER, fapi2::TARGET_TYPE_OCMB_CHIP>::LFSR_MASK_VALUES =
+{
+ 0x000000031,
+ 0x00000001F,
+ 0x001000000,
+ 0x100000000,
+ 0x004000003,
+ 0x000080000,
+ 0x040000018,
+ 0x008000000,
+ 0x010006000,
+ 0x004000000,
+ 0x001000000,
+ 0x003200000,
+ 0x001880000,
+ 0x000200000,
+ 0x000610000,
+ 0x000100000,
+ 0x000040000,
+ 0x000010000,
+ 0x000023000,
+ 0x000002000,
+ 0x000000400,
+ 0x000002000,
+ 0x000005008,
+ 0x000002000,
+ 0x000001088,
+ 0x000000B00,
+ 0x0000004A0,
+ 0x000000100,
+ 0x000000040,
+ 0x000000010,
+ 0x000000038,
+ 0x000000008,
+ 0x000000010,
+ 0x000000004,
+ 0x000000004,
+ 0x000000002,
+ 0x000000001,
+};
+
+namespace mcbist
+{
+///
+/// @brief Get a list of ports involved in the program
+/// Specialization for program<>
+/// @param[in] i_target the target for this program
+/// @return vector of port targets
+///
+template<>
+std::vector<fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>>
+ program<>::get_port_list( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target ) const
+{
+
+ return mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target);
+}
+///
+/// @brief Configures broadcast mode, if it is needed
+/// @param[in] i_target the target to effect
+/// @param[in,out] io_program the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template<>
+fapi2::ReturnCode configure_broadcast_mode(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ mcbist::program<mss::mc_type::EXPLORER>& io_program)
+{
+ // No broadcast mode for explorer
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+///
+/// @brief Read entries from MCBIST Read Buffer (RB) array
+/// Specialization for fapi2::TARGET_TYPE_MEM_PORT
+/// @param[in] i_target the target to effect
+/// @param[in] i_start_addr the array address to read first
+/// @param[in] i_num_entries the number of array entries to read
+/// @param[out] o_data vector of output data
+/// @param[out] o_ecc_data vector of ecc data
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template<>
+fapi2::ReturnCode read_rb_array(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_start_addr,
+ const uint64_t i_num_entries,
+ std::vector< fapi2::buffer<uint64_t> >& o_data,
+ std::vector< fapi2::buffer<uint64_t> >& o_ecc_data)
+{
+ using TT = mcbistTraits<DEFAULT_MC_TYPE, fapi2::TARGET_TYPE_OCMB_CHIP>;
+
+ fapi2::buffer<uint64_t> l_data;
+ uint64_t l_array_addr = i_start_addr;
+
+ const auto& l_ocmb = mss::find_target<fapi2::TARGET_TYPE_OCMB_CHIP>(i_target);
+
+ // Clear out any stale values from output vectors
+ o_data.clear();
+ o_ecc_data.clear();
+
+ for (uint8_t l_index = 0; l_index < i_num_entries; ++l_index)
+ {
+ fapi2::buffer<uint64_t> l_control_value;
+
+ // set start address
+ l_control_value.insertFromRight<TT::RB_ADDRESS, TT::RB_ADDRESS_LEN>(l_array_addr);
+
+ FAPI_INF("Setting the RB array access control register.");
+ FAPI_TRY( mss::putScom(l_ocmb, TT::RD_BUF_CTL_REG, l_control_value) );
+
+
+ // We setup the address to what we need it to be, so let's continue
+ FAPI_TRY( mss::getScom(i_target, TT::RD_BUF_DATA_REG, l_data) );
+ FAPI_INF("RB data index %d is: 0x%016lx", l_array_addr, l_data);
+ o_data.push_back(l_data);
+
+ // Need to read ecc register to increment array index
+ FAPI_TRY( mss::getScom(i_target, TT::RD_BUF_ECC_REG, l_data) );
+ o_ecc_data.push_back(l_data);
+ ++l_array_addr;
+
+ // Array address automatically rolls over if we go beyond NUM_COMPARE_LOG_ENTRIES
+ if (l_array_addr >= TT::NUM_COMPARE_LOG_ENTRIES)
+ {
+ l_array_addr = 0;
+ }
+
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // namespace mcbist
+} // namespace mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist.H
index f4d8a8bb1..13dd0ba6d 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,66 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_mcbist.H
+/// @brief Run and manage the MCBIST engine
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_EXP_MCBIST_H_
+#define _MSS_EXP_MCBIST_H_
+
+#include <fapi2.H>
+
+#include <explorer_scom_addresses.H>
+#include <explorer_scom_addresses_fld.H>
+
+#include <lib/shared/exp_consts.H>
+#include <lib/ecc/ecc_traits_explorer.H>
+#include <lib/mcbist/exp_mcbist_traits.H>
+#include <lib/mc/exp_port.H>
+#include <lib/utils/mss_exp_conversions.H>
+#include <generic/memory/lib/utils/poll.H>
+#include <generic/memory/lib/utils/memory_size.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist.H>
+
+namespace mss
+{
+
+namespace mcbist
+{
+
+///
+/// @brief Load MCBIST ECC (and?) spare data pattern given a pattern - explorer specialization
+/// @param[in] i_target the target to effect
+/// @param[in] i_pattern an mcbist::patterns
+/// @param[in] i_invert whether to invert the pattern or not
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< >
+inline fapi2::ReturnCode load_eccspare_pattern<mss::mc_type::EXPLORER>(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const pattern& i_pattern,
+ const bool i_invert )
+{
+ // First up assemble the pattern
+ const auto l_pattern = generate_eccspare_pattern(i_pattern, i_invert);
+
+ FAPI_TRY(fapi2::putScom(i_target, EXPLR_MCBIST_MCBFDQ, l_pattern));
+ FAPI_TRY(fapi2::putScom(i_target, EXPLR_MCBIST_MCBFDSPQ, l_pattern));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // ns mss
+
+} // ns mcbist
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist_traits.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist_traits.H
index 3c848de59..72f06be05 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist_traits.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist_traits.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,627 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_mcbist_traits.H
+/// @brief Run and manage the MCBIST engine
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_EXP_MCBIST_TRAITS_H_
+#define _MSS_EXP_MCBIST_TRAITS_H_
+
+#include <fapi2.H>
+
+#include <explorer_scom_addresses.H>
+#include <explorer_scom_addresses_fld.H>
+
+#include <lib/shared/exp_consts.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist.H>
+
+namespace mss
+{
+
+///
+/// @class mcbistMCTraits
+/// @brief A MC to MC_TARGET_TYPE mapping specialization for EXPLORER
+///
+template<>
+class mcbistMCTraits< mss::mc_type::EXPLORER>
+{
+ public:
+ static constexpr fapi2::TargetType MC_TARGET_TYPE = fapi2::TARGET_TYPE_OCMB_CHIP;
+ static constexpr fapi2::TargetType FWMS_ADDR_TARGET_TYPE = fapi2::TARGET_TYPE_MEM_PORT;
+
+ ///
+ /// @brief Returns an error for memdiags compare error in last pattern
+ /// @return memdiags error
+ ///
+ static fapi2::EXP_MEMDIAGS_COMPARE_ERROR_IN_LAST_PATTERN memdiags_compare_error_in_last_pattern()
+ {
+ return fapi2::EXP_MEMDIAGS_COMPARE_ERROR_IN_LAST_PATTERN();
+ }
+
+ ///
+ /// @brief Returns an error for memdiags error in last pattern
+ /// @return memdiags error
+ ///
+ static fapi2::EXP_MEMDIAGS_ERROR_IN_LAST_PATTERN memdiags_error_in_last_pattern()
+ {
+ return fapi2::EXP_MEMDIAGS_ERROR_IN_LAST_PATTERN();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags failed to start
+ /// @return memdiags error
+ ///
+ static fapi2::EXP_MEMDIAGS_MCBIST_FAILED_TO_START memdiags_failed_to_start()
+ {
+ return fapi2::EXP_MEMDIAGS_MCBIST_FAILED_TO_START();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags failed to stop
+ /// @return memdiags error
+ ///
+ static fapi2::EXP_MEMDIAGS_MCBIST_FAILED_TO_STOP memdiags_failed_to_stop()
+ {
+ return fapi2::EXP_MEMDIAGS_MCBIST_FAILED_TO_STOP();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags has a non-functional port
+ /// @return memdiags error
+ ///
+ static fapi2::EXP_MEMDIAGS_PORT_NOT_FUNCTIONAL memdiags_port_not_functional()
+ {
+ return fapi2::EXP_MEMDIAGS_PORT_NOT_FUNCTIONAL();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags super fast init failed to init
+ /// @return memdiags error
+ ///
+ static fapi2::EXP_MEMDIAGS_SUPERFAST_INIT_FAILED_TO_INIT memdiags_sf_init_failed_init()
+ {
+ return fapi2::EXP_MEMDIAGS_SUPERFAST_INIT_FAILED_TO_INIT();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags super fast read failed to init
+ /// @return memdiags error
+ ///
+ static fapi2::EXP_MEMDIAGS_SUPERFAST_READ_FAILED_TO_INIT memdiags_sf_read_failed_init()
+ {
+ return fapi2::EXP_MEMDIAGS_SUPERFAST_READ_FAILED_TO_INIT();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags super fast read failed to init
+ /// @return memdiags error
+ ///
+ static fapi2::EXP_MEMDIAGS_CONTINUOUS_SCRUB_FAILED_TO_INIT memdiags_continuous_scrub_failed_init()
+ {
+ return fapi2::EXP_MEMDIAGS_CONTINUOUS_SCRUB_FAILED_TO_INIT();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags targeted scrub failed to init
+ /// @return memdiags error
+ ///
+ static fapi2::EXP_MEMDIAGS_TARGETED_SCRUB_FAILED_TO_INIT memdiags_targeted_scrub_failed_init()
+ {
+ return fapi2::EXP_MEMDIAGS_TARGETED_SCRUB_FAILED_TO_INIT();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags is already at a boundary
+ /// @return memdiags error
+ ///
+ static fapi2::EXP_MEMDIAGS_ALREADY_AT_BOUNDARY memdiags_already_at_boundary()
+ {
+ return fapi2::EXP_MEMDIAGS_ALREADY_AT_BOUNDARY();
+ }
+
+ ///
+ /// @brief Returns an error if MCBIST timesout
+ /// @return MCBIST error
+ ///
+ static fapi2::EXP_MCBIST_TIMEOUT mcbist_timeout()
+ {
+ return fapi2::EXP_MCBIST_TIMEOUT();
+ }
+
+ ///
+ /// @brief Returns an error if MCBIST has an unknown failure
+ /// @return MCBIST error
+ ///
+ static fapi2::EXP_MCBIST_UNKNOWN_FAILURE mcbist_unknown_failure()
+ {
+ return fapi2::EXP_MCBIST_UNKNOWN_FAILURE();
+ }
+
+ ///
+ /// @brief Returns an error if MCBIST has a data miscompare
+ /// @return MCBIST error
+ ///
+ static fapi2::EXP_MCBIST_DATA_FAIL mcbist_data_fail()
+ {
+ return fapi2::EXP_MCBIST_DATA_FAIL();
+ }
+};
+
+///
+/// @class mcbistTraits
+/// @brief a collection of traits associated with the Explorer MCBIST engine or hardware
+///
+template<>
+class mcbistTraits< mss::mc_type::EXPLORER, fapi2::TARGET_TYPE_OCMB_CHIP>
+{
+ public:
+
+ // PORT_TYPE used in continuous_scrub_operation
+ static constexpr fapi2::TargetType PORT_TYPE = fapi2::TARGET_TYPE_MEM_PORT;
+
+ // ATTN support
+ static constexpr mss::states CFG_ENABLE_ATTN_SUPPORT = mss::states::NO;
+ static constexpr mss::states BROADCAST_CAPABLE = mss::states::NO;
+
+ // Multi-ports, dimms
+ static constexpr mss::states MULTI_PORTS = mss::states::NO;
+
+ // Subtest
+ static constexpr size_t SUBTEST_PER_REG = 4;
+ static constexpr size_t SUBTEST_PER_PROGRAM = 32;
+ static constexpr size_t BITS_IN_SUBTEST = 16; // 2 Bytes
+ static constexpr size_t LEFT_SHIFT = (sizeof(uint64_t) * 8) - BITS_IN_SUBTEST;
+
+ // LARGEST_ADDRESS. port select (bit0~1) are always 0 so shift 2 more bits.
+ static constexpr uint64_t LARGEST_ADDRESS = ~0 >> (mss::mcbist::address::MAGIC_PAD + 2);
+
+ // Length of expected patterns
+ static constexpr uint64_t EXPECTED_PATTERN_SIZE = 4;
+
+ // Size
+ static constexpr size_t PORTS_PER_MCBIST = mss::exp::MAX_PORT_PER_OCMB;
+ static constexpr size_t MAX_DIMM_PER_PORT = mss::exp::MAX_DIMM_PER_PORT;
+ // Closest we've got to primary rank
+ static constexpr size_t MAX_PRIMARY_RANKS_PER_PORT = mss::exp::MAX_RANK_PER_DIMM;
+ static constexpr size_t MAX_DQ_BITS = 80;
+ static constexpr size_t MAX_DQ_NIBBLES = MAX_DQ_BITS / BITS_PER_NIBBLE;
+ static constexpr size_t MAX_DRAMS_X8 = MAX_DQ_BITS / BITS_PER_BYTE;
+ static constexpr size_t MAX_DRAMS_X4 = MAX_DQ_BITS / BITS_PER_NIBBLE;
+
+ /// MCBIST "memory registers" - config for subtests.
+ static constexpr uint64_t MCBMR0_REG = EXPLR_MCBIST_MCBMR0Q;
+ static constexpr uint64_t MCBMR1_REG = EXPLR_MCBIST_MCBMR1Q;
+ static constexpr uint64_t MCBMR2_REG = EXPLR_MCBIST_MCBMR2Q;
+ static constexpr uint64_t MCBMR3_REG = EXPLR_MCBIST_MCBMR3Q;
+ static constexpr uint64_t MCBMR4_REG = EXPLR_MCBIST_MCBMR4Q;
+ static constexpr uint64_t MCBMR5_REG = EXPLR_MCBIST_MCBMR5Q;
+ static constexpr uint64_t MCBMR6_REG = EXPLR_MCBIST_MCBMR6Q;
+ static constexpr uint64_t MCBMR7_REG = EXPLR_MCBIST_MCBMR7Q;
+ static constexpr uint64_t CFGQ_REG = EXPLR_MCBIST_MCBCFGQ;
+ static constexpr uint64_t CNTLQ_REG = EXPLR_MCBIST_MCB_CNTLQ;
+ static constexpr uint64_t STATQ_REG = EXPLR_MCBIST_MCB_CNTLSTATQ;
+ static constexpr uint64_t MCBSTATQ_REG = EXPLR_MCBIST_MCBSTATQ;
+ static constexpr uint64_t MCBPARMQ_REG = EXPLR_MCBIST_MCBPARMQ;
+ static constexpr uint64_t MCBAGRAQ_REG = EXPLR_MCBIST_MCBAGRAQ;
+ static constexpr uint64_t SRERR0_REG = EXPLR_MCBIST_MBSEC0Q;
+ static constexpr uint64_t SRERR1_REG = EXPLR_MCBIST_MBSEC1Q;
+ static constexpr uint64_t THRESHOLD_REG = EXPLR_MCBIST_MBSTRQ;
+ static constexpr uint64_t FIRQ_REG = EXPLR_MCBIST_MCBISTFIRQ;
+ static constexpr uint64_t LAST_ADDR_REG = EXPLR_MCBIST_MCBMCATQ;
+
+ static constexpr uint64_t MCBAMR0A0Q_REG = EXPLR_MCBIST_MCBAMR0A0Q;
+ static constexpr uint64_t MCBAMR1A0Q_REG = EXPLR_MCBIST_MCBAMR1A0Q;
+ static constexpr uint64_t MCBAMR2A0Q_REG = EXPLR_MCBIST_MCBAMR2A0Q;
+ static constexpr uint64_t MCBAMR3A0Q_REG = EXPLR_MCBIST_MCBAMR3A0Q;
+ static constexpr uint64_t LFSR_REG = EXPLR_MCBIST_MCBLFSRA0Q;
+ static const std::vector<uint64_t> LFSR_MASK_VALUES;
+
+ // All of the pattern registers are calculated off of this base
+ static constexpr uint64_t PATTERN0_REG = EXPLR_MCBIST_MCBFD0Q;
+ static constexpr uint64_t PATTERN1_REG = EXPLR_MCBIST_MCBFD1Q;
+ static constexpr uint64_t PATTERN2_REG = EXPLR_MCBIST_MCBFD2Q;
+ static constexpr uint64_t PATTERN3_REG = EXPLR_MCBIST_MCBFD3Q;
+ static constexpr uint64_t PATTERN4_REG = EXPLR_MCBIST_MCBFD4Q;
+ static constexpr uint64_t PATTERN5_REG = EXPLR_MCBIST_MCBFD5Q;
+ static constexpr uint64_t PATTERN6_REG = EXPLR_MCBIST_MCBFD6Q;
+ static constexpr uint64_t PATTERN7_REG = EXPLR_MCBIST_MCBFD7Q;
+
+ static constexpr uint64_t DATA_ROTATE_CNFG_REG = EXPLR_MCBIST_MCBDRCRQ;
+ static constexpr uint64_t DATA_ROTATE_SEED_REG = EXPLR_MCBIST_MCBDRSRQ;
+
+ static constexpr uint16_t MAX_ADDRESS_START_END_REGISTERS = 4;
+ static constexpr uint64_t START_ADDRESS_0 = EXPLR_MCBIST_MCBSA0Q;
+ static constexpr uint64_t START_ADDRESS_1 = EXPLR_MCBIST_MCBSA1Q;
+ static constexpr uint64_t START_ADDRESS_2 = EXPLR_MCBIST_MCBSA2Q;
+ static constexpr uint64_t START_ADDRESS_3 = EXPLR_MCBIST_MCBSA3Q;
+
+ static constexpr uint64_t END_ADDRESS_0 = EXPLR_MCBIST_MCBEA0Q;
+ static constexpr uint64_t END_ADDRESS_1 = EXPLR_MCBIST_MCBEA1Q;
+ static constexpr uint64_t END_ADDRESS_2 = EXPLR_MCBIST_MCBEA2Q;
+ static constexpr uint64_t END_ADDRESS_3 = EXPLR_MCBIST_MCBEA3Q;
+
+ static constexpr uint64_t RANDOM_DATA_SEED0 = EXPLR_MCBIST_MCBRDS0Q;
+ static constexpr uint64_t RANDOM_DATA_SEED1 = EXPLR_MCBIST_MCBRDS1Q;
+
+ static constexpr uint64_t MBSTRQ_CFG_PAUSE_ON_MPE = EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_MPE;
+
+ // MCBIST Compare Masks, used to setup the ECC traps
+ static constexpr uint64_t COMPARE_MASK = EXPLR_RDF_MCBCM;
+
+ static constexpr uint64_t PATTERN_COUNT = 4;
+
+ // Sometimes we want to access the start/end address registers based off
+ // of an index, like master rank. This allows us to do that.
+ static const std::pair<uint64_t, uint64_t> address_pairs[];
+ static constexpr uint64_t ADDRESS_PAIRS = 4;
+
+ // Subtest types that need to be run in FIFO mode
+ static const std::vector< mss::mcbist::op_type > FIFO_MODE_REQUIRED_OP_TYPES;
+
+ // Which bit in the end boundary which siginifies this is a slave rank detect situation
+ static constexpr uint64_t SLAVE_RANK_INDICATED_BIT = 61;
+
+ enum
+ {
+ // The start/end address config registers have common lengths and bits, just including 1 below
+ MCB_ADDR_CONFIG = EXPLR_MCBIST_MCBEA0Q_CFG_END_ADDR_0,
+ MCB_ADDR_CONFIG_LEN = EXPLR_MCBIST_MCBEA0Q_CFG_END_ADDR_0_LEN,
+
+ // Subtest control bits. These are the same in all '16 bit subtest' field
+ COMPL_1ST_CMD = EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_1ST_CMD,
+ COMPL_2ND_CMD = EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_2ND_CMD,
+ COMPL_3RD_CMD = EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_3RD_CMD,
+ ADDR_REV_MODE = EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_REV_MODE,
+ ADDR_RAND_MODE = EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_RAND_MODE,
+
+ // Goto subtests use the compl_1st - rand_mode to define the subtest to jump to
+ GOTO_SUBTEST = EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_1ST_CMD,
+ GOTO_SUBTEST_LEN = 5,
+
+ ECC_MODE = EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ECC_MODE,
+ DATA_MODE = EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DATA_MODE,
+ DATA_MODE_LEN = EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DATA_MODE_LEN,
+ ADDR_SEL = EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_SEL,
+ ADDR_SEL_LEN = EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_SEL_LEN,
+ OP_TYPE = EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_OP_TYPE,
+ OP_TYPE_LEN = EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_OP_TYPE_LEN,
+ DONE = EXPLR_MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DONE,
+
+ // No broadcast in explorer due to only one port per MCBIST
+ // SYNC_EN
+ // SYNC_WAIT
+ // SYNC_WAIT_LEN
+
+ // No port sel in explorer due to only one port per MCBIST
+ PORT_SEL = 0,
+ PORT_SEL_LEN = 1,
+
+ MCBIST_START = EXPLR_MCBIST_MCB_CNTLQ_START,
+ MCBIST_STOP = EXPLR_MCBIST_MCB_CNTLQ_STOP,
+ MCBIST_RESUME = EXPLR_MCBIST_MCB_CNTLQ_RESUME_FROM_PAUSE,
+ MCBIST_RESET_ERRORS = EXPLR_MCBIST_MCB_CNTLQ_RESET_ERROR_LOGS,
+
+ MCBIST_IN_PROGRESS = EXPLR_MCBIST_MCB_CNTLSTATQ_IP,
+ MCBIST_DONE = EXPLR_MCBIST_MCB_CNTLSTATQ_DONE,
+ MCBIST_FAIL = EXPLR_MCBIST_MCB_CNTLSTATQ_FAIL,
+
+ MIN_CMD_GAP = EXPLR_MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP,
+ MIN_CMD_GAP_LEN = EXPLR_MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_LEN,
+ MIN_GAP_TIMEBASE = EXPLR_MCBIST_MCBPARMQ_CFG_MIN_GAP_TIMEBASE,
+ MIN_CMD_GAP_BLIND_STEER = EXPLR_MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_BLIND_STEER,
+ MIN_CMD_GAP_BLIND_STEER_LEN = EXPLR_MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_BLIND_STEER_LEN,
+ MIN_GAP_TIMEBASE_BLIND_STEER = EXPLR_MCBIST_MCBPARMQ_CFG_MIN_GAP_TIMEBASE_BLIND_STEER,
+ RANDCMD_WGT = EXPLR_MCBIST_MCBPARMQ_CFG_RANDCMD_WGT,
+ RANDCMD_WGT_LEN = EXPLR_MCBIST_MCBPARMQ_CFG_RANDCMD_WGT_LEN,
+ // No clock monitor for explorer
+ // CLOCK_MONITOR_EN
+ EN_RANDCMD_GAP = EXPLR_MCBIST_MCBPARMQ_CFG_EN_RANDCMD_GAP,
+ RANDGAP_WGT = EXPLR_MCBIST_MCBPARMQ_CFG_RANDGAP_WGT,
+ RANDGAP_WGT_LEN = EXPLR_MCBIST_MCBPARMQ_CFG_RANDGAP_WGT_LEN,
+ BC4_EN = EXPLR_MCBIST_MCBPARMQ_CFG_BC4_EN,
+
+ FIXED_WIDTH = EXPLR_MCBIST_MCBAGRAQ_CFG_FIXED_WIDTH,
+ FIXED_WIDTH_LEN = EXPLR_MCBIST_MCBAGRAQ_CFG_FIXED_WIDTH_LEN,
+ ADDR_COUNTER_MODE = EXPLR_MCBIST_MCBAGRAQ_CFG_ADDR_COUNTER_MODE,
+ ADDR_COUNTER_MODE_LEN = EXPLR_MCBIST_MCBAGRAQ_CFG_ADDR_COUNTER_MODE_LEN,
+ MAINT_ADDR_MODE_EN = EXPLR_MCBIST_MCBAGRAQ_CFG_MAINT_ADDR_MODE_EN,
+
+ // No broadcast in explorer due to only one port per MCBIST
+ //MAINT_BROADCAST_MODE_EN
+ MAINT_DETECT_SRANK_BOUNDARIES = EXPLR_MCBIST_MCBAGRAQ_CFG_MAINT_DETECT_SRANK_BOUNDARIES,
+
+ CFG_CMD_TIMEOUT_MODE = EXPLR_MCBIST_MCBCFGQ_CFG_CMD_TIMEOUT_MODE,
+ CFG_CMD_TIMEOUT_MODE_LEN = EXPLR_MCBIST_MCBCFGQ_CFG_CMD_TIMEOUT_MODE_LEN,
+ RESET_KEEPER = EXPLR_MCBIST_MCBCFGQ_RESET_KEEPER,
+ CFG_CURRENT_ADDR_TRAP_UPDATE_DIS = EXPLR_MCBIST_MCBCFGQ_CFG_CURRENT_ADDR_TRAP_UPDATE_DIS,
+ CFG_CCS_RETRY_DIS = EXPLR_MCBIST_MCBCFGQ_CFG_CCS_RETRY_DIS,
+ CFG_RESET_CNTS_START_OF_RANK = EXPLR_MCBIST_MCBCFGQ_CFG_RESET_CNTS_START_OF_RANK,
+ CFG_LOG_COUNTS_IN_TRACE = EXPLR_MCBIST_MCBCFGQ_CFG_LOG_COUNTS_IN_TRACE,
+ SKIP_INVALID_ADDR_DIMM_DIS = EXPLR_MCBIST_MCBCFGQ_SKIP_INVALID_ADDR_DIMM_DIS,
+ REFRESH_ONLY_SUBTEST_EN = EXPLR_MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_EN,
+ REFRESH_ONLY_SUBTEST_TIMEBASE_SEL = EXPLR_MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_TIMEBASE_SEL,
+ REFRESH_ONLY_SUBTEST_TIMEBASE_SEL_LEN = EXPLR_MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_TIMEBASE_SEL_LEN,
+ RAND_ADDR_ALL_ADDR_MODE_EN = EXPLR_MCBIST_MCBCFGQ_RAND_ADDR_ALL_ADDR_MODE_EN,
+ MCBIST_CFG_REF_WAIT_TIME = EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_REF_WAIT_TIME,
+ MCBIST_CFG_REF_WAIT_TIME_LEN = EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_REF_WAIT_TIME_LEN,
+ CFG_MCB_LEN64 = EXPLR_MCBIST_MCBCFGQ_CFG_MCB_LEN64,
+ CFG_PAUSE_ON_ERROR_MODE = EXPLR_MCBIST_MCBCFGQ_CFG_PAUSE_ON_ERROR_MODE,
+ CFG_PAUSE_ON_ERROR_MODE_LEN = EXPLR_MCBIST_MCBCFGQ_CFG_PAUSE_ON_ERROR_MODE_LEN,
+ MCBIST_CFG_PAUSE_AFTER_CCS_SUBTEST = EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_PAUSE_AFTER_CCS_SUBTEST,
+ MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR = EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR,
+ MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST = EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST,
+
+ // No ATTN in explorer
+ CFG_ENABLE_SPEC_ATTN = 0,
+ CFG_ENABLE_HOST_ATTN = 0,
+ MCBIST_CFG_PAUSE_AFTER_RANK = EXPLR_MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_RANK,
+
+ LOGGED_ERROR_ON_PORT_INDICATOR = EXPLR_MCBIST_MCBSTATQ_MCBIST_LOGGED_ERROR_ON_PORT_INDICATOR,
+ LOGGED_ERROR_ON_PORT_INDICATOR_LEN = 1,
+ SUBTEST_NUM_INDICATOR = EXPLR_MCBIST_MCBSTATQ_MCBIST_SUBTEST_NUM_INDICATOR,
+ SUBTEST_NUM_INDICATOR_LEN = EXPLR_MCBIST_MCBSTATQ_MCBIST_SUBTEST_NUM_INDICATOR_LEN,
+
+ UE_COUNT = EXPLR_MCBIST_MBSEC1Q_UE_COUNT,
+ UE_COUNT_LEN = EXPLR_MCBIST_MBSEC1Q_UE_COUNT_LEN,
+
+ MBSTRQ_CFG_MAINT_RCE_WITH_CE = EXPLR_MCBIST_MBSTRQ_CFG_MAINT_RCE_WITH_CE,
+
+ CFG_AMAP_DIMM_SELECT = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_DIMM_SELECT,
+ CFG_AMAP_DIMM_SELECT_LEN = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_DIMM_SELECT_LEN,
+ CFG_AMAP_MRANK0 = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK0,
+ CFG_AMAP_MRANK0_LEN = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK0_LEN,
+ CFG_AMAP_MRANK1 = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK1,
+ CFG_AMAP_MRANK1_LEN = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK1_LEN,
+ CFG_AMAP_SRANK0 = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK0,
+ CFG_AMAP_SRANK0_LEN = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK0_LEN,
+ CFG_AMAP_SRANK1 = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK1,
+ CFG_AMAP_SRANK1_LEN = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK1_LEN,
+ CFG_AMAP_SRANK2 = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK2,
+ CFG_AMAP_SRANK2_LEN = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK2_LEN,
+ CFG_AMAP_BANK2 = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK2,
+ CFG_AMAP_BANK2_LEN = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK2_LEN ,
+ CFG_AMAP_BANK1 = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK1,
+ CFG_AMAP_BANK1_LEN = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK1_LEN ,
+ CFG_AMAP_BANK0 = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK0,
+ CFG_AMAP_BANK0_LEN = EXPLR_MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK0_LEN ,
+
+ CFG_AMAP_BANK_GROUP1 = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP1,
+ CFG_AMAP_BANK_GROUP1_LEN = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP1_LEN ,
+ CFG_AMAP_BANK_GROUP0 = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP0,
+ CFG_AMAP_BANK_GROUP0_LEN = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP0_LEN ,
+ CFG_AMAP_ROW17 = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW17,
+ CFG_AMAP_ROW17_LEN = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW17_LEN,
+ CFG_AMAP_ROW16 = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW16,
+ CFG_AMAP_ROW16_LEN = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW16_LEN,
+ CFG_AMAP_ROW15 = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW15,
+ CFG_AMAP_ROW15_LEN = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW15_LEN,
+ CFG_AMAP_ROW14 = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW14,
+ CFG_AMAP_ROW14_LEN = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW14_LEN,
+ CFG_AMAP_ROW13 = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW13,
+ CFG_AMAP_ROW13_LEN = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW13_LEN,
+ CFG_AMAP_ROW12 = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12,
+ CFG_AMAP_ROW12_LEN = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12_LEN,
+ CFG_AMAP_ROW11 = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW11,
+ CFG_AMAP_ROW11_LEN = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW11_LEN,
+ CFG_AMAP_ROW10 = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW10,
+ CFG_AMAP_ROW10_LEN = EXPLR_MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW10_LEN,
+
+ CFG_AMAP_ROW9 = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW9,
+ CFG_AMAP_ROW9_LEN = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW9_LEN,
+ CFG_AMAP_ROW8 = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW8,
+ CFG_AMAP_ROW8_LEN = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW8_LEN,
+ CFG_AMAP_ROW7 = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW7,
+ CFG_AMAP_ROW7_LEN = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW7_LEN,
+ CFG_AMAP_ROW6 = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW6,
+ CFG_AMAP_ROW6_LEN = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW6_LEN,
+ CFG_AMAP_ROW5 = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW5,
+ CFG_AMAP_ROW5_LEN = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW5_LEN,
+ CFG_AMAP_ROW4 = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW4,
+ CFG_AMAP_ROW4_LEN = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW4_LEN,
+ CFG_AMAP_ROW3 = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW3,
+ CFG_AMAP_ROW3_LEN = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW3_LEN,
+ CFG_AMAP_ROW2 = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW2,
+ CFG_AMAP_ROW2_LEN = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW2_LEN,
+ CFG_AMAP_ROW1 = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW1,
+ CFG_AMAP_ROW1_LEN = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW1_LEN,
+ CFG_AMAP_ROW0 = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW0,
+ CFG_AMAP_ROW0_LEN = EXPLR_MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW0_LEN,
+
+ CFG_AMAP_COL9 = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL9,
+ CFG_AMAP_COL9_LEN = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL9_LEN,
+ CFG_AMAP_COL8 = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL8,
+ CFG_AMAP_COL8_LEN = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL8_LEN,
+ CFG_AMAP_COL7 = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL7,
+ CFG_AMAP_COL7_LEN = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL7_LEN,
+ CFG_AMAP_COL6 = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL6,
+ CFG_AMAP_COL6_LEN = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL6_LEN,
+ CFG_AMAP_COL5 = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL5,
+ CFG_AMAP_COL5_LEN = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL5_LEN,
+ CFG_AMAP_COL4 = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL4,
+ CFG_AMAP_COL4_LEN = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL4_LEN,
+ CFG_AMAP_COL3 = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL3,
+ CFG_AMAP_COL3_LEN = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL3_LEN,
+ CFG_AMAP_COL2 = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL2,
+ CFG_AMAP_COL2_LEN = EXPLR_MCBIST_MCBAMR3A0Q_CFG_AMAP_COL2_LEN,
+
+ LFSR_MASK = EXPLR_MCBIST_MCBLFSRA0Q_CFG_LFSR_MASK_A0,
+ LFSR_MASK_LEN = EXPLR_MCBIST_MCBLFSRA0Q_CFG_LFSR_MASK_A0_LEN,
+
+ CFG_DATA_ROT_SEED1 = EXPLR_MCBIST_MCBDRSRQ_CFG_DATA_ROT_SEED,
+ CFG_DATA_ROT_SEED1_LEN = EXPLR_MCBIST_MCBDRSRQ_CFG_DATA_ROT_SEED_LEN,
+ CFG_DATA_ROT = EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_ROT,
+ CFG_DATA_ROT_LEN = EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_ROT_LEN,
+ CFG_DATA_ROT_SEED2 = EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_ROT_SEED,
+ CFG_DATA_ROT_SEED2_LEN = EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_ROT_SEED_LEN,
+ CFG_DATA_SEED_MODE = EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_SEED_MODE,
+ CFG_DATA_SEED_MODE_LEN = EXPLR_MCBIST_MCBDRCRQ_CFG_DATA_SEED_MODE_LEN,
+
+ CFG_TRAP_CE_ENABLE = EXPLR_RDF_MCBCM_MCBIST_TRAP_CE_ENABLE,
+ CFG_TRAP_UE_ENABLE = EXPLR_RDF_MCBCM_MCBIST_TRAP_UE_ENABLE,
+ CFG_TRAP_MPE_ENABLE = EXPLR_RDF_MCBCM_MCBIST_TRAP_MPE_ENABLE,
+
+ CFG_DGEN_RNDD_SEED0 = EXPLR_MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0,
+ CFG_DGEN_RNDD_SEED0_LEN = EXPLR_MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0_LEN,
+ CFG_DGEN_RNDD_SEED1 = EXPLR_MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1,
+ CFG_DGEN_RNDD_SEED1_LEN = EXPLR_MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1_LEN,
+ CFG_DGEN_RNDD_SEED2 = EXPLR_MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2,
+ CFG_DGEN_RNDD_SEED2_LEN = EXPLR_MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2_LEN,
+ CFG_DGEN_RNDD_DATA_MAPPING = EXPLR_MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING,
+ CFG_DGEN_RNDD_DATA_MAPPING_LEN = EXPLR_MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING_LEN,
+
+ // THRESHOLD control bits
+ MBSTRQ_CFG_THRESH_MAG_NCE_INT = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT,
+ MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN,
+ MBSTRQ_CFG_THRESH_MAG_NCE_SOFT = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT,
+ MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN,
+ MBSTRQ_CFG_THRESH_MAG_NCE_HARD = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD,
+ MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN,
+ MBSTRQ_CFG_THRESH_MAG_RCE = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE,
+ MBSTRQ_CFG_THRESH_MAG_RCE_LEN = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE_LEN,
+ MBSTRQ_CFG_THRESH_MAG_ICE = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE,
+ MBSTRQ_CFG_THRESH_MAG_ICE_LEN = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE_LEN,
+ MBSTRQ_CFG_THRESH_MAG_MCE_INT = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT,
+ MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN,
+ MBSTRQ_CFG_THRESH_MAG_MCE_SOFT = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT,
+ MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN,
+ MBSTRQ_CFG_THRESH_MAG_MCE_HARD = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD,
+ MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN = EXPLR_MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN,
+ MBSTRQ_CFG_PAUSE_ON_SCE = EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_SCE,
+ // NO MBSTRQ_CFG_PAUSE_ON_MCE
+ // MBSTRQ_CFG_PAUSE_ON_MCE
+ MBSTRQ_CFG_PAUSE_ON_UE = EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_UE,
+ MBSTRQ_CFG_PAUSE_ON_SUE = EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_SUE,
+ MBSTRQ_CFG_PAUSE_ON_AUE = EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_AUE,
+ MBSTRQ_CFG_PAUSE_ON_RCD = EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_ON_RCD,
+ MBSTRQ_CFG_SYMBOL_COUNTER_MODE = EXPLR_MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE,
+ MBSTRQ_CFG_SYMBOL_COUNTER_MODE_LEN = EXPLR_MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE_LEN,
+ MBSTRQ_CFG_NCE_SOFT_SYMBOL_COUNT_ENABLE = EXPLR_MCBIST_MBSTRQ_CFG_NCE_SOFT_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_NCE_INTER_SYMBOL_COUNT_ENABLE = EXPLR_MCBIST_MBSTRQ_CFG_NCE_INTER_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_NCE_HARD_SYMBOL_COUNT_ENABLE = EXPLR_MCBIST_MBSTRQ_CFG_NCE_HARD_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_PAUSE_MCB_ERROR = EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_MCB_ERROR,
+ MBSTRQ_CFG_PAUSE_MCB_LOG_FULL = EXPLR_MCBIST_MBSTRQ_CFG_PAUSE_MCB_LOG_FULL,
+ MBSTRQ_CFG_MCE_SOFT_SYMBOL_COUNT_ENABLE = EXPLR_MCBIST_MBSTRQ_CFG_MCE_SOFT_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_MCE_INTER_SYMBOL_COUNT_ENABLE = EXPLR_MCBIST_MBSTRQ_CFG_MCE_INTER_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_MCE_HARD_SYMBOL_COUNT_ENABLE = EXPLR_MCBIST_MBSTRQ_CFG_MCE_HARD_SYMBOL_COUNT_ENABLE,
+
+ // Bit mapping for MCBIST error log control data
+ ERROR_LOG_SUBTEST = 0,
+ ERROR_LOG_SUBTEST_LEN = 5,
+ ERROR_LOG_SUBCMD = 5,
+ ERROR_LOG_SUBCMD_LEN = 2,
+ ERROR_LOG_ADDR_DIMM = 7,
+ ERROR_LOG_ADDR_MRANK = 8,
+ ERROR_LOG_ADDR_MRANK_LEN = 2,
+ ERROR_LOG_ADDR_SRANK = 10,
+ ERROR_LOG_ADDR_SRANK_LEN = 3,
+ ERROR_LOG_ADDR_BANK_GROUP = 13,
+ ERROR_LOG_ADDR_BANK_GROUP_LEN = 2,
+ ERROR_LOG_ADDR_BANK = 15,
+ ERROR_LOG_ADDR_BANK_LEN = 3,
+ ERROR_LOG_ADDR_ROW = 18,
+ ERROR_LOG_ADDR_ROW_LEN = 18,
+ ERROR_LOG_ADDR_COLUMN = 36,
+ ERROR_LOG_ADDR_COLUMN_LEN = 8,
+ ERROR_LOG_BEAT = 44,
+ ERROR_LOG_BEAT_LEN = 2,
+ ERROR_LOG_TYPE = 46,
+ ERROR_LOG_TYPE_LEN = 2,
+
+ //MCBIST FIR mask
+ MCB_PROGRAM_COMPLETE = EXPLR_MCBIST_MCBISTFIRQ_MCBIST_PROGRAM_COMPLETE,
+ MCB_WAT_DEBUG_ATTN = EXPLR_MCBIST_MCBISTFIRQ_WAT_DEBUG_ATTN,
+ MCB_DATA_ERROR = EXPLR_MCBIST_MCBISTFIRQ_MCBIST_DATA_ERROR,
+
+ //XLT address valid offset
+ XLT0_SLOT1_D_VALID = EXPLR_MCBIST_MBXLT0Q_SLOT1_VALID,
+ XLT0_SLOT0_M1_VALID = EXPLR_MCBIST_MBXLT0Q_SLOT0_M1_VALID,
+ XLT0_SLOT0_M0_VALID = EXPLR_MCBIST_MBXLT0Q_SLOT0_M0_VALID,
+ XLT0_SLOT0_S2_VALID = EXPLR_MCBIST_MBXLT0Q_SLOT0_S2_VALID,
+ XLT0_SLOT0_S1_VALID = EXPLR_MCBIST_MBXLT0Q_SLOT0_S1_VALID,
+ XLT0_SLOT0_S0_VALID = EXPLR_MCBIST_MBXLT0Q_SLOT0_S0_VALID,
+ XLT0_SLOT0_ROW17_VALID = EXPLR_MCBIST_MBXLT0Q_SLOT0_ROW17_VALID,
+ XLT0_SLOT0_ROW16_VALID = EXPLR_MCBIST_MBXLT0Q_SLOT0_ROW16_VALID,
+ XLT0_SLOT0_ROW15_VALID = EXPLR_MCBIST_MBXLT0Q_SLOT0_ROW15_VALID,
+
+ };
+
+ // MCBIST error log related registers
+ static constexpr uint64_t RD_BUF_CTL_REG = EXPLR_RDF_AACR;
+ static constexpr uint64_t RD_BUF_DATA_REG = EXPLR_RDF_AADR;
+ static constexpr uint64_t RD_BUF_ECC_REG = EXPLR_RDF_AAER;
+
+ enum
+ {
+ // Register field constants
+ RB_ADDRESS = EXPLR_RDF_AACR_ADDRESS,
+ RB_ADDRESS_LEN = EXPLR_RDF_AACR_ADDRESS_LEN,
+ RB_AUTOINC = EXPLR_RDF_AACR_AUTOINC,
+
+ // Other constants
+ NUM_COMPARE_LOG_ENTRIES = 64,
+ };
+};
+
+
+///
+/// @class mcbistTraits
+/// @brief a collection of traits associated with the Explorer MEM_PORT
+///
+template<>
+class mcbistTraits< mss::mc_type::EXPLORER, fapi2::TARGET_TYPE_MEM_PORT>
+{
+ public:
+ // MCBIST error log related registers
+ static constexpr uint64_t ERROR_LOG_PTR_REG = EXPLR_RDF_ELPR;
+ static constexpr uint64_t RMW_WRT_BUF_CTL_REG = EXPLR_WDF_AACR;
+ static constexpr uint64_t RMW_WRT_BUF_DATA_REG = EXPLR_WDF_AADR;
+ static constexpr uint64_t RMW_WRT_BUF_ECC_REG = EXPLR_WDF_AAER;
+
+ static constexpr uint64_t XLTATE0 = EXPLR_MCBIST_MBXLT0Q;
+ static constexpr uint64_t XLTATE1 = EXPLR_MCBIST_MBXLT1;
+ static constexpr uint64_t XLTATE2 = EXPLR_MCBIST_MBXLT2;
+
+ // Maintenance data location within the array
+ static constexpr uint64_t MAINT_DATA_INDEX_START = 0b000000000;
+ static constexpr uint64_t MAINT_DATA_INDEX_END = 0b000001000;
+
+ enum
+ {
+ // Register field constants
+ ERROR_LOG_PTR = EXPLR_RDF_ELPR_LOG_POINTER,
+ ERROR_LOG_PTR_LEN = EXPLR_RDF_ELPR_LOG_POINTER_LEN,
+ ERROR_LOG_FULL = EXPLR_RDF_ELPR_LOG_FULL,
+ RMW_WRT_BUFFER_SEL = EXPLR_WDF_AACR_BUFFER,
+ RMW_WRT_ADDRESS = EXPLR_WDF_AACR_ADDRESS,
+ RMW_WRT_ADDRESS_LEN = EXPLR_WDF_AACR_ADDRESS_LEN,
+ RMW_WRT_AUTOINC = EXPLR_WDF_AACR_AUTOINC,
+ RMW_WRT_ECCGEN = EXPLR_WDF_AACR_ECCGEN,
+
+ XLTATE_SLOT0_VALID = EXPLR_MCBIST_MBXLT0Q_SLOT0_VALID,
+ XLTATE_SLOT1_VALID = EXPLR_MCBIST_MBXLT0Q_SLOT1_VALID,
+
+ // Constants used for field settings
+ SELECT_RMW_BUFFER = 0,
+ SELECT_WRT_BUFFER = 1,
+
+ // Other constants
+ NUM_COMPARE_LOG_ENTRIES = 64,
+ // In compare mode, there is one "info" entry per 4 data (log) entries
+ // so compare mode only uses 16 info entries total in the rmw array
+ NUM_COMPARE_DATA_PER_INFO_LOG = 4,
+ NUM_COMPARE_INFO_ENTRIES = 16,
+ };
+};
+
+}// mss
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_memdiags.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_memdiags.C
index 540de3b0f..0c879abe9 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_memdiags.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_memdiags.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,168 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_memdiags.C
+/// @brief Run and manage the MEMDIAGS engine
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Marc Gollub <gollub@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+
+#include <lib/shared/exp_defaults.H>
+#include <p9_mc_scom_addresses.H>
+#include <p9_mc_scom_addresses_fld.H>
+
+#include <lib/dimm/exp_rank.H>
+#include <lib/mcbist/exp_memdiags.H>
+#include <lib/mcbist/exp_mcbist.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+#include <generic/memory/lib/utils/poll.H>
+
+
+namespace mss
+{
+
+namespace memdiags
+{
+
+///
+/// @brief memdiags multi-port init internal.
+/// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
+/// in subclassed constructors more easily.
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+template<>
+fapi2::ReturnCode operation<mss::mc_type::EXPLORER>::multi_port_init_internal()
+{
+ return single_port_init();
+}
+
+///
+/// @brief Set up memory controller specific settings for pre-maint mode read
+/// @param[in] i_target the memory controller target
+/// @return FAPI2_RC_SUCCESS iff ok
+/// @note mc_type::EXPLORER specialization
+///
+template<>
+fapi2::ReturnCode pre_maint_read_settings<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
+ i_target )
+{
+ using TT = mss::portTraits<mss::mc_type::EXPLORER>;
+ fapi2::buffer<uint64_t> l_data;
+
+ // Set up Explorer specific settings
+ FAPI_TRY( mss::getScom(i_target, TT::ECC_REG, l_data) );
+
+ l_data.setBit<TT::RECR_MBSECCQ_MAINT_NO_RETRY_UE>();
+ l_data.setBit<TT::RECR_MBSECCQ_MAINT_NO_RETRY_MPE>();
+
+ FAPI_TRY( mss::putScom(i_target, TT::ECC_REG, l_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Set up memory controller specific settings for pre-scrub
+/// @param[in] i_target the memory controller target
+/// @return FAPI2_RC_SUCCESS iff ok
+/// @note mc_type::EXPLORER specialization
+///
+template<>
+fapi2::ReturnCode pre_scrub_settings<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
+ i_target )
+{
+ using TT = mss::portTraits<mss::mc_type::EXPLORER>;
+ fapi2::buffer<uint64_t> l_data;
+
+ // Set up Explorer specific settings
+ FAPI_TRY( mss::getScom(i_target, TT::ECC_REG, l_data) );
+
+ l_data.clearBit<TT::RECR_MBSECCQ_MAINT_NO_RETRY_UE>();
+ l_data.clearBit<TT::RECR_MBSECCQ_MAINT_NO_RETRY_MPE>();
+
+ FAPI_TRY( mss::putScom(i_target, TT::ECC_REG, l_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // namespace memdiags
+
+namespace exp
+{
+
+namespace memdiags
+{
+
+///
+/// @brief Process the result from the mcbist sf_read subtest after memdiags
+///
+/// @param[in] i_target OCMB target for traces
+/// @param[in] l_fail_behavior_attr
+/// @param[in,out] io_rc ReturnCode from sf_read
+/// @return fapi2::ReturnCode
+///
+fapi2::ReturnCode process_subtest_result(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint8_t l_fail_behavior_attr,
+ fapi2::ReturnCode& io_rc)
+{
+ // Check RC
+ if ((l_fail_behavior_attr == fapi2::ENUM_ATTR_MSS_POST_MEMDIAGS_READ_SUBTEST_FAIL_BEHAVIOR_TRACE)
+ && (io_rc != fapi2::FAPI2_RC_SUCCESS))
+ {
+ // Trace + Bad RC: Log as recovered, return success, set io_rc back to success
+ FAPI_ERR("%s Error code 0x%08lx from post-memdiags mcbist read subtest", mss::c_str(i_target), uint32_t(io_rc));
+ fapi2::logError(io_rc, fapi2::FAPI2_ERRL_SEV_RECOVERED);
+
+ io_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Else, we will just try the RC as-is
+ FAPI_TRY(io_rc, "%s Error from post-memdiags mcbist read subtest", mss::c_str(i_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Perform a read only mcbist subtest at the end of memdiags
+///
+/// @param[in] i_target OCMB Chip
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error
+///
+fapi2::ReturnCode perform_read_only_subtest(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ uint8_t l_fail_behavior = 0;
+
+ auto l_stop_conditions = mss::mcbist::stop_conditions<mss::mc_type::EXPLORER>();
+
+ // Pause on unrecoverable error
+ l_stop_conditions.set_pause_on_ue(mss::ON);
+
+ // sf_read will run, poll for completion and return result ReturnCode
+ l_rc = mss::memdiags::sf_read<mss::mc_type::EXPLORER>(i_target, l_stop_conditions);
+
+ // Get fail behavior attr and process the result
+ FAPI_TRY(mss::attr::get_post_memdiags_read_subtest(i_target, l_fail_behavior));
+ FAPI_TRY(process_subtest_result(i_target, l_fail_behavior, l_rc));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // memdiags
+} // exp
+
+} // namespace mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_memdiags.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_memdiags.H
index 496b97f80..a53b7c312 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_memdiags.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_memdiags.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,58 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_memdiags.H
+/// @brief API for memory diagnostics
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Marc Gollub <gollub@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+//
+
+#ifndef _MSS_EXP_MEMDIAGS_H_
+#define _MSS_EXP_MEMDIAGS_H_
+
+#include <fapi2.H>
+
+#include <lib/shared/exp_consts.H>
+#include <lib/mcbist/exp_mcbist.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_memdiags.H>
+
+// This file is still necessary to put traits and generic code together
+
+namespace mss
+{
+namespace exp
+{
+namespace memdiags
+{
+
+///
+/// @brief Process the result from the mcbist sf_read subtest after memdiags
+///
+/// @param[in] i_target OCMB target for traces
+/// @param[in] l_fail_behavior_attr
+/// @param[in, out] i_rc ReturnCode from sf_read
+/// @return fapi2::ReturnCode
+///
+fapi2::ReturnCode process_subtest_result(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint8_t l_fail_behavior_attr,
+ fapi2::ReturnCode& io_rc);
+
+///
+/// @brief Perform a read only mcbist subtest at the end of memdiags
+///
+/// @param[in] i_target OCMB Chip
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error
+///
+fapi2::ReturnCode perform_read_only_subtest(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+
+} // memdiags
+} // exp
+} // mss
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_settings.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_settings.H
index ed1703ecb..dc1c42c4b 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_settings.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_settings.H
@@ -22,3 +22,26 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file exp_settings.H
+/// @brief MCBIST settings, like stop conditions, thresholds, etc
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Marc Gollub <gollub@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_MCBIST_EXP_SETTINGS_H_
+#define _MSS_MCBIST_EXP_SETTINGS_H_
+
+#include <fapi2.H>
+
+#include <lib/shared/exp_consts.H>
+#include <lib/ecc/ecc_traits_explorer.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H>
+
+// This file is still necessary to put traits and generic code together
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist.C
deleted file mode 100644
index e6284b618..000000000
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist.C
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist.H
deleted file mode 100644
index 87c62e802..000000000
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist.H
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist_traits.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist_traits.H
deleted file mode 100644
index 446ab46e9..000000000
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist_traits.H
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/mcbist_traits.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/memdiags.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/memdiags.C
deleted file mode 100644
index b85c12fc4..000000000
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/memdiags.C
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/memdiags.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/memdiags.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/memdiags.H
deleted file mode 100644
index 999a83ced..000000000
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/memdiags.H
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/memdiags.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/settings.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/settings.H
deleted file mode 100644
index 1bdb23803..000000000
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/settings.H
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/settings.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/crc32.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/crc32.H
index c6a6793aa..8d34537e4 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/crc32.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/crc32.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,73 +38,42 @@
#include <stdint.h>
#include <vector>
-// CRC32 lookup table can be found online via multiple websites
+// CRC32 lookup table to match the table used in Microchip firmware
+// Note that this table is known as CRC32_BZIP2 in some texts
static const uint32_t crc32_lookup_table[] =
{
- 0x00000000ul, 0x77073096ul, 0xEE0E612Cul, 0x990951BAul,
- 0x076DC419ul, 0x706AF48Ful, 0xE963A535ul, 0x9E6495A3ul,
- 0x0EDB8832ul, 0x79DCB8A4ul, 0xE0D5E91Eul, 0x97D2D988ul,
- 0x09B64C2Bul, 0x7EB17CBDul, 0xE7B82D07ul, 0x90BF1D91ul,
- 0x1DB71064ul, 0x6AB020F2ul, 0xF3B97148ul, 0x84BE41DEul,
- 0x1ADAD47Dul, 0x6DDDE4EBul, 0xF4D4B551ul, 0x83D385C7ul,
- 0x136C9856ul, 0x646BA8C0ul, 0xFD62F97Aul, 0x8A65C9ECul,
- 0x14015C4Ful, 0x63066CD9ul, 0xFA0F3D63ul, 0x8D080DF5ul,
- 0x3B6E20C8ul, 0x4C69105Eul, 0xD56041E4ul, 0xA2677172ul,
- 0x3C03E4D1ul, 0x4B04D447ul, 0xD20D85FDul, 0xA50AB56Bul,
- 0x35B5A8FAul, 0x42B2986Cul, 0xDBBBC9D6ul, 0xACBCF940ul,
- 0x32D86CE3ul, 0x45DF5C75ul, 0xDCD60DCFul, 0xABD13D59ul,
- 0x26D930ACul, 0x51DE003Aul, 0xC8D75180ul, 0xBFD06116ul,
- 0x21B4F4B5ul, 0x56B3C423ul, 0xCFBA9599ul, 0xB8BDA50Ful,
- 0x2802B89Eul, 0x5F058808ul, 0xC60CD9B2ul, 0xB10BE924ul,
- 0x2F6F7C87ul, 0x58684C11ul, 0xC1611DABul, 0xB6662D3Dul,
- 0x76DC4190ul, 0x01DB7106ul, 0x98D220BCul, 0xEFD5102Aul,
- 0x71B18589ul, 0x06B6B51Ful, 0x9FBFE4A5ul, 0xE8B8D433ul,
- 0x7807C9A2ul, 0x0F00F934ul, 0x9609A88Eul, 0xE10E9818ul,
- 0x7F6A0DBBul, 0x086D3D2Dul, 0x91646C97ul, 0xE6635C01ul,
- 0x6B6B51F4ul, 0x1C6C6162ul, 0x856530D8ul, 0xF262004Eul,
- 0x6C0695EDul, 0x1B01A57Bul, 0x8208F4C1ul, 0xF50FC457ul,
- 0x65B0D9C6ul, 0x12B7E950ul, 0x8BBEB8EAul, 0xFCB9887Cul,
- 0x62DD1DDFul, 0x15DA2D49ul, 0x8CD37CF3ul, 0xFBD44C65ul,
- 0x4DB26158ul, 0x3AB551CEul, 0xA3BC0074ul, 0xD4BB30E2ul,
- 0x4ADFA541ul, 0x3DD895D7ul, 0xA4D1C46Dul, 0xD3D6F4FBul,
- 0x4369E96Aul, 0x346ED9FCul, 0xAD678846ul, 0xDA60B8D0ul,
- 0x44042D73ul, 0x33031DE5ul, 0xAA0A4C5Ful, 0xDD0D7CC9ul,
- 0x5005713Cul, 0x270241AAul, 0xBE0B1010ul, 0xC90C2086ul,
- 0x5768B525ul, 0x206F85B3ul, 0xB966D409ul, 0xCE61E49Ful,
- 0x5EDEF90Eul, 0x29D9C998ul, 0xB0D09822ul, 0xC7D7A8B4ul,
- 0x59B33D17ul, 0x2EB40D81ul, 0xB7BD5C3Bul, 0xC0BA6CADul,
- 0xEDB88320ul, 0x9ABFB3B6ul, 0x03B6E20Cul, 0x74B1D29Aul,
- 0xEAD54739ul, 0x9DD277AFul, 0x04DB2615ul, 0x73DC1683ul,
- 0xE3630B12ul, 0x94643B84ul, 0x0D6D6A3Eul, 0x7A6A5AA8ul,
- 0xE40ECF0Bul, 0x9309FF9Dul, 0x0A00AE27ul, 0x7D079EB1ul,
- 0xF00F9344ul, 0x8708A3D2ul, 0x1E01F268ul, 0x6906C2FEul,
- 0xF762575Dul, 0x806567CBul, 0x196C3671ul, 0x6E6B06E7ul,
- 0xFED41B76ul, 0x89D32BE0ul, 0x10DA7A5Aul, 0x67DD4ACCul,
- 0xF9B9DF6Ful, 0x8EBEEFF9ul, 0x17B7BE43ul, 0x60B08ED5ul,
- 0xD6D6A3E8ul, 0xA1D1937Eul, 0x38D8C2C4ul, 0x4FDFF252ul,
- 0xD1BB67F1ul, 0xA6BC5767ul, 0x3FB506DDul, 0x48B2364Bul,
- 0xD80D2BDAul, 0xAF0A1B4Cul, 0x36034AF6ul, 0x41047A60ul,
- 0xDF60EFC3ul, 0xA867DF55ul, 0x316E8EEFul, 0x4669BE79ul,
- 0xCB61B38Cul, 0xBC66831Aul, 0x256FD2A0ul, 0x5268E236ul,
- 0xCC0C7795ul, 0xBB0B4703ul, 0x220216B9ul, 0x5505262Ful,
- 0xC5BA3BBEul, 0xB2BD0B28ul, 0x2BB45A92ul, 0x5CB36A04ul,
- 0xC2D7FFA7ul, 0xB5D0CF31ul, 0x2CD99E8Bul, 0x5BDEAE1Dul,
- 0x9B64C2B0ul, 0xEC63F226ul, 0x756AA39Cul, 0x026D930Aul,
- 0x9C0906A9ul, 0xEB0E363Ful, 0x72076785ul, 0x05005713ul,
- 0x95BF4A82ul, 0xE2B87A14ul, 0x7BB12BAEul, 0x0CB61B38ul,
- 0x92D28E9Bul, 0xE5D5BE0Dul, 0x7CDCEFB7ul, 0x0BDBDF21ul,
- 0x86D3D2D4ul, 0xF1D4E242ul, 0x68DDB3F8ul, 0x1FDA836Eul,
- 0x81BE16CDul, 0xF6B9265Bul, 0x6FB077E1ul, 0x18B74777ul,
- 0x88085AE6ul, 0xFF0F6A70ul, 0x66063BCAul, 0x11010B5Cul,
- 0x8F659EFFul, 0xF862AE69ul, 0x616BFFD3ul, 0x166CCF45ul,
- 0xA00AE278ul, 0xD70DD2EEul, 0x4E048354ul, 0x3903B3C2ul,
- 0xA7672661ul, 0xD06016F7ul, 0x4969474Dul, 0x3E6E77DBul,
- 0xAED16A4Aul, 0xD9D65ADCul, 0x40DF0B66ul, 0x37D83BF0ul,
- 0xA9BCAE53ul, 0xDEBB9EC5ul, 0x47B2CF7Ful, 0x30B5FFE9ul,
- 0xBDBDF21Cul, 0xCABAC28Aul, 0x53B39330ul, 0x24B4A3A6ul,
- 0xBAD03605ul, 0xCDD70693ul, 0x54DE5729ul, 0x23D967BFul,
- 0xB3667A2Eul, 0xC4614AB8ul, 0x5D681B02ul, 0x2A6F2B94ul,
- 0xB40BBE37ul, 0xC30C8EA1ul, 0x5A05DF1Bul, 0x2D02EF8Dul
+ 0x0, 0x4c11db7, 0x9823b6e, 0xd4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
+ 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
+ 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
+ 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
+ 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
+ 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
+ 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
+ 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
+ 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
+ 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x18aeb13, 0x54bf6a4, 0x808d07d, 0xcc9cdca,
+ 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
+ 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+ 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
+ 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
+ 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
+ 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
+ 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
+ 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
+ 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
+ 0x315d626, 0x7d4cb91, 0xa97ed48, 0xe56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
+ 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
+ 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
+ 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
+ 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
+ 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
+ 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
+ 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x29f3d35, 0x65e2082, 0xb1d065b, 0xfdc1bec,
+ 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
+ 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
+ 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
+ 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
+ 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4,
};
///
@@ -123,8 +92,8 @@ inline uint32_t crc32_gen(const std::vector<uint8_t>& i_data, const uint64_t i_l
for (uint64_t i = 0; i < i_data.size() && i < i_len; ++i)
{
const uint8_t l_data = i_data[i];
- const uint32_t l_tmp = l_crc ^ static_cast<uint32_t>(l_data);
- l_crc = (l_crc >> 8) ^ crc32_lookup_table[ l_tmp & 0xFF ];
+ const uint32_t l_tmp = (l_crc >> 24) ^ static_cast<uint32_t>(l_data);
+ l_crc = (l_crc << 8) ^ crc32_lookup_table[ l_tmp & 0xFF ];
}
return l_crc ^ 0xFFFFFFFFul;
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.C
index e58f134cb..f8133bafb 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,10 +33,14 @@
// *HWP Level: 3
// *HWP Consumed by: Memory
+#include <generic/memory/lib/utils/find.H>
#include <lib/omi/exp_omi_utils.H>
#include <lib/shared/exp_consts.H>
#include <lib/i2c/exp_i2c_fields.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
#include <mss_explorer_attribute_getters.H>
+#include <generic/memory/lib/mss_generic_system_attribute_getters.H>
+#include <lib/shared/exp_consts.H>
namespace mss
{
@@ -44,6 +48,47 @@ namespace exp
{
namespace omi
{
+
+///
+/// @brief Set the OMI_DL0 configuration register for a given mode
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_train_mode mode to use
+/// @param[in] i_dl_x4_backoff_en backoff enable bit
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+/// @note Algorithm from p9a_omi_train.C
+///
+fapi2::ReturnCode setup_omi_dl0_config0(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint8_t i_train_mode,
+ const uint8_t i_dl_x4_backoff_en)
+{
+ fapi2::buffer<uint64_t> l_config0;
+
+ // Get the "reset" values so we can just overwrite with the changes
+ FAPI_TRY(fapi2::getScom(i_target, EXPLR_DLX_DL0_CONFIG0, l_config0),
+ "Error reading EXPLR_DLX_DL0_CONFIG0 on %s", mss::c_str(i_target));
+
+ // CFG_DL0_HALF_WIDTH_BACKOFF_ENABLE: dl0 x4 backoff enabled
+ l_config0.writeBit<EXPLR_DLX_DL0_CONFIG0_CFG_HALF_WIDTH_BACKOFF_ENABLE>(i_dl_x4_backoff_en);
+
+ // CFG_DL0_TRAIN_MODE: dl0 train mode
+ l_config0.insertFromRight<EXPLR_DLX_DL0_CONFIG0_CFG_TRAIN_MODE,
+ EXPLR_DLX_DL0_CONFIG0_CFG_TRAIN_MODE_LEN>(i_train_mode);
+
+ l_config0.writeBit<EXPLR_DLX_DL0_CONFIG0_CFG_PWRMGT_ENABLE>(0);
+
+ FAPI_DBG("Writing 0x%16llx to EXPLR_DLX_DL0_CONFIG0 (0x%16llx) of %s",
+ l_config0, EXPLR_DLX_DL0_CONFIG0, mss::c_str(i_target));
+
+ // All other bits will be left at their default values
+ FAPI_TRY( fapi2::putScom(i_target, EXPLR_DLX_DL0_CONFIG0, l_config0),
+ "Error writing EXPLR_DLX_DL0_CONFIG0 on %s", mss::c_str(i_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
namespace train
{
@@ -61,11 +106,16 @@ fapi2::ReturnCode setup_fw_boot_config( const fapi2::Target<fapi2::TARGET_TYPE_O
uint8_t l_loopback_test = 0;
uint8_t l_transport_layer = 0;
uint8_t l_dl_layer_boot_mode = 0;
- uint8_t l_boot_mode = 0;
+ uint8_t l_dfe_disable = 0;
uint8_t l_lane_mode = 0;
- uint8_t l_serdes_freq = 0;
+ uint8_t l_adaptation_mode = 0;
+ uint32_t l_omi_freq = 0;
+
+ const auto& l_proc = mss::find_target<fapi2::TARGET_TYPE_PROC_CHIP>(i_target);
// Read the EXP_FW_BOOT_CONFIG from the attributes
+ FAPI_TRY(mss::attr::get_ocmb_exp_boot_config_adaptation_mode(i_target, l_adaptation_mode));
+
FAPI_TRY(mss::attr::get_ocmb_exp_boot_config_fw_mode(i_target, l_fw_mode));
FAPI_TRY(mss::attr::get_ocmb_exp_boot_config_opencapi_loopback_test(i_target, l_loopback_test));
@@ -74,24 +124,51 @@ fapi2::ReturnCode setup_fw_boot_config( const fapi2::Target<fapi2::TARGET_TYPE_O
FAPI_TRY(mss::attr::get_ocmb_exp_boot_config_dl_layer_boot_mode(i_target, l_dl_layer_boot_mode));
- FAPI_TRY(mss::attr::get_ocmb_exp_boot_config_boot_mode(i_target, l_boot_mode));
+ FAPI_TRY(mss::attr::get_ocmb_exp_boot_config_dfe_disable(i_target, l_dfe_disable));
FAPI_TRY(mss::attr::get_ocmb_exp_boot_config_lane_mode(i_target, l_lane_mode));
- FAPI_TRY(mss::attr::get_ocmb_exp_boot_config_serdes_frequency(i_target, l_serdes_freq));
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_FREQ_OMI_MHZ, l_proc, l_omi_freq) );
// Clears o_data, just in case
o_data.clear();
o_data.assign(mss::exp::i2c::FW_BOOT_CONFIG_BYTE_LEN, 0);
- FAPI_TRY(mss::exp::i2c::boot_cfg::set_serdes_freq( i_target, o_data, l_serdes_freq ));
+ FAPI_TRY(mss::exp::i2c::boot_cfg::set_serdes_freq( i_target, o_data, l_omi_freq ));
FAPI_TRY(mss::exp::i2c::boot_cfg::set_lane_mode( i_target, o_data, l_lane_mode ));
- FAPI_TRY(mss::exp::i2c::boot_cfg::set_boot_mode( i_target, o_data, l_boot_mode ));
+ FAPI_TRY(mss::exp::i2c::boot_cfg::set_dfe_disable( i_target, o_data, l_dfe_disable ));
FAPI_TRY(mss::exp::i2c::boot_cfg::set_dl_layer_boot_mode( i_target, o_data, l_dl_layer_boot_mode ));
FAPI_TRY(mss::exp::i2c::boot_cfg::set_transport_layer( i_target, o_data, l_transport_layer ));
FAPI_TRY(mss::exp::i2c::boot_cfg::set_loopback_test( i_target, o_data, l_loopback_test ));
FAPI_TRY(mss::exp::i2c::boot_cfg::set_fw_mode( i_target, o_data, l_fw_mode ));
+ FAPI_TRY(mss::exp::i2c::boot_cfg::set_adaptation_mode( i_target, o_data, l_adaptation_mode ));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Check the OMI train status on the OCMB chip
+///
+/// @param[in] i_target OCMB chil
+/// @param[out] o_state_machine_state training state mahcine
+/// @param[out] o_omi_training_status training status
+/// @return fapi2::ReturnCode
+///
+fapi2::ReturnCode omi_train_status(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ uint8_t& o_state_machine_state,
+ fapi2::buffer<uint64_t>& o_omi_training_status)
+{
+ fapi2::buffer<uint64_t> l_omi_status;
+
+ // Check OMI training status
+ FAPI_TRY(fapi2::getScom(i_target, EXPLR_DLX_DL0_STATUS, l_omi_status));
+
+ o_omi_training_status = l_omi_status;
+ o_state_machine_state = 0;
+ l_omi_status.extractToRight<EXPLR_DLX_DL0_STATUS_STS_TRAINING_STATE_MACHINE,
+ EXPLR_DLX_DL0_STATUS_STS_TRAINING_STATE_MACHINE_LEN>(o_state_machine_state);
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.H
index 1faf02014..5022271ee 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.H
@@ -103,6 +103,27 @@ inline bool get_enterprise_config( const fapi2::buffer<uint64_t>& i_data )
return i_data.getBit<EXPLR_MMIO_MENTERP_CFG_ENTERPRISE_MODE>();
}
+
+///
+/// @brief Get edpl enable bit
+/// @param[in] i_data the register data
+/// @return The register's EDPL_ENA bit
+///
+inline bool get_edpl_enable_bit( const fapi2::buffer<uint64_t>& i_data )
+{
+ return i_data.getBit<EXPLR_DLX_DL0_CONFIG1_CFG_EDPL_ENA>();
+}
+
+///
+/// @brief Set edpl enable bit
+/// @param[in,out] io_data the register data
+/// @param[in] i_enable The register's EDPL_ENA bit
+///
+inline void set_edpl_enable_bit( fapi2::buffer<uint64_t>& io_data, const bool i_enable )
+{
+ io_data.writeBit<EXPLR_DLX_DL0_CONFIG1_CFG_EDPL_ENA>(i_enable);
+}
+
///
/// @brief Checks if the enterprise config bit is in the correct mode
/// @param[in] i_target target on which we are operating - for logging
@@ -115,6 +136,7 @@ inline fapi2::ReturnCode check_enterprise_mode( const fapi2::Target<fapi2::TARGE
fapi2::buffer<uint64_t>& i_data )
{
const bool l_actual = mss::exp::omi::get_enterprise_config(i_data);
+
FAPI_ASSERT(l_actual == i_is_enterprise,
fapi2::MSS_EXP_ENTERPRISE_SETUP_ERROR()
.set_EXPECTED(i_is_enterprise)
@@ -124,6 +146,8 @@ inline fapi2::ReturnCode check_enterprise_mode( const fapi2::Target<fapi2::TARGE
"%s failed to setup enterprise mode properly expected: %u actual: %u register data 0x%016lx",
mss::c_str(i_target), i_is_enterprise, l_actual, i_data);
+ return fapi2::FAPI2_RC_SUCCESS;
+
fapi_try_exit:
return fapi2::current_err;
}
@@ -157,6 +181,44 @@ inline fapi2::ReturnCode write_enterprise_config( const fapi2::Target<fapi2::TAR
return fapi2::putScom(i_target, EXPLR_MMIO_MENTERP, i_data);
}
+///
+/// @brief Reads the EXPLR_DLX_DL0_CONFIG1 register using I2C
+/// @param[in] i_target the OCMB target on which to operate
+/// @param[out] o_data the register contents
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+///
+inline fapi2::ReturnCode read_dlx_config1( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ fapi2::buffer<uint64_t>& o_data )
+{
+ return fapi2::getScom(i_target, EXPLR_DLX_DL0_CONFIG1, o_data);
+}
+
+///
+/// @brief Writes the EXPLR_DLX_DL0_CONFIG1 register using I2C
+/// @param[in] i_target the OCMB target on which to operate
+/// @param[in] i_data the register contents
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+///
+inline fapi2::ReturnCode write_dlx_config1( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const fapi2::buffer<uint64_t>& i_data )
+{
+ return fapi2::putScom(i_target, EXPLR_DLX_DL0_CONFIG1, i_data);
+}
+
+///
+/// @brief Set the OMI_DL0 configuration register for a given mode
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_train_mode mode to use
+/// @param[in] i_dl_x4_backoff_en backoff enable bit
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+/// @note Algorithm from p9a_omi_train.C
+///
+fapi2::ReturnCode setup_omi_dl0_config0(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint8_t i_train_mode,
+ const uint8_t i_dl_x4_backoff_en);
+
namespace train
{
@@ -169,6 +231,18 @@ namespace train
fapi2::ReturnCode setup_fw_boot_config( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
std::vector<uint8_t>& o_data );
+///
+/// @brief Check the OMI train status on the OCMB chip
+///
+/// @param[in] i_target OCMB chil
+/// @param[out] o_state_machine_state training state mahcine
+/// @param[out] o_omi_training_status training status
+/// @return fapi2::ReturnCode
+///
+fapi2::ReturnCode omi_train_status(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ uint8_t& o_state_machine_state,
+ fapi2::buffer<uint64_t>& o_omi_training_status);
+
} // ns train
} // ns omi
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_display.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_display.C
new file mode 100644
index 000000000..f7fbad41a
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_display.C
@@ -0,0 +1,239 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_display.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_train_display.C
+/// @brief Procedures used to display the training response information
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include <lib/shared/exp_consts.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/index.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <exp_data_structs.H>
+#include <lib/phy/exp_train_display.H>
+
+namespace mss
+{
+namespace exp
+{
+namespace train
+{
+///
+/// @brief Displays training information
+/// @param[in] i_target the OCMB target
+/// @param[in] i_lane the lane for the training information
+/// @param[in] i_data the training data for this lane
+///
+void display_lane_results(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint64_t i_lane,
+ const uint16_t i_data)
+{
+ // Extracts the per-rank information
+ fapi2::buffer<uint16_t> l_data(i_data);
+ uint8_t l_rank0 = 0;
+ uint8_t l_rank1 = 0;
+ uint8_t l_rank2 = 0;
+ uint8_t l_rank3 = 0;
+
+ l_data.extractToRight<0, BITS_PER_NIBBLE>(l_rank3)
+ .extractToRight<BITS_PER_NIBBLE, BITS_PER_NIBBLE>(l_rank2)
+ .extractToRight<BITS_PER_NIBBLE * 2, BITS_PER_NIBBLE>(l_rank1)
+ .extractToRight<BITS_PER_NIBBLE * 3, BITS_PER_NIBBLE>(l_rank0);
+
+ constexpr uint16_t CLEAN = 0;
+
+ // If we passed, display the information as only as MFG - we don't want to clutter the screen with too much information
+ if(CLEAN == i_data)
+ {
+ FAPI_MFG("%s lane: %u PASSING R0:%u R1:%u R2:%u R3:%u",
+ mss::c_str(i_target), i_lane,
+ l_rank0, l_rank1, l_rank2, l_rank3);
+ }
+
+ // If we failed, display the information as INF
+ else
+ {
+ FAPI_INF("%s lane: %u FAILING R0:%u R1:%u R2:%u R3:%u",
+ mss::c_str(i_target), i_lane,
+ l_rank0, l_rank1, l_rank2, l_rank3);
+ }
+}
+
+///
+/// @brief Display train_2d_read_eye_msdg_t response struct
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_training_info training info struct
+///
+void display_train_2d_read_eye(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const user_2d_eye_response_1_msdg_t& i_training_info)
+{
+ FAPI_MFG("%s %s (EYE MIN/MAX):", mss::c_str(i_target), "VrefDAC0");
+
+ for (uint8_t l_rank = 0; l_rank < TRAINING_RESPONSE_NUM_RANKS; ++l_rank)
+ {
+ for (uint8_t l_dbyte = 0; l_dbyte < DBYTE_N_SIZE; ++l_dbyte)
+ {
+ for (uint8_t l_bit = 0; l_bit < BIT_N_SIZE; ++l_bit)
+ {
+ for (uint8_t l_eye_index = 0; l_eye_index < EYE_MIN_MAX_SIZE; ++l_eye_index)
+ {
+ const auto l_eye_min = i_training_info.read_2d_eye_resp.VrefDAC0[l_rank][l_dbyte][l_bit].eye_min[l_eye_index];
+ const auto l_eye_max = i_training_info.read_2d_eye_resp.VrefDAC0[l_rank][l_dbyte][l_bit].eye_max[l_eye_index];
+
+ FAPI_MFG("%s %s RANK %u, DBYTE %u BIT %u EYE INDEX %u -- MIN: %u MAX: %u",
+ mss::c_str(i_target), "VrefDAC0", l_rank, l_dbyte, l_bit, l_eye_index, l_eye_min, l_eye_max);
+ }
+ }
+ }
+ }
+
+ FAPI_MFG("%s %s_Center:", mss::c_str(i_target), "VrefDAC0");
+
+ for (uint8_t l_dbyte = 0; l_dbyte < DBYTE_N_SIZE; ++l_dbyte)
+ {
+ for (uint8_t l_bit = 0; l_bit < BIT_N_SIZE; ++l_bit)
+ {
+ const auto l_vref_dac0_center = i_training_info.read_2d_eye_resp.VrefDAC0_Center[l_dbyte][l_bit];
+ FAPI_MFG("%s %s DBYTE %u, BIT %u: %u", mss::c_str(i_target), "VrefDAC0_Center", l_dbyte, l_bit, l_vref_dac0_center);
+ }
+ }
+
+ FAPI_MFG("%s %s_Center:", mss::c_str(i_target), "RxClkDly");
+
+ for (uint8_t l_rank = 0; l_rank < TRAINING_RESPONSE_NUM_RANKS; ++l_rank)
+ {
+ for (uint8_t l_nibble = 0; l_nibble < NIBBLE_N_SIZE; ++l_nibble)
+ {
+ const auto l_rxclkdly_center = i_training_info.read_2d_eye_resp.RxClkDly_Center[l_rank][l_nibble];
+ FAPI_MFG("%s %s RANK %u, NIBBLE %u: %u", mss::c_str(i_target), "RxClkDly_Center", l_rank, l_nibble, l_rxclkdly_center);
+ }
+ }
+}
+
+///
+/// @brief Display train_2d_write_eye_msdg_t response struct
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_training_info training info struct
+///
+void display_train_2d_write_eye(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const user_2d_eye_response_2_msdg_t& i_training_info)
+{
+ FAPI_MFG("%s %s (EYE MIN/MAX):", mss::c_str(i_target), "VrefDQ");
+
+ for (uint8_t l_rank = 0; l_rank < TRAINING_RESPONSE_NUM_RANKS; ++l_rank)
+ {
+ for (uint8_t l_dbyte = 0; l_dbyte < DBYTE_N_SIZE; ++l_dbyte)
+ {
+ for (uint8_t l_bit = 0; l_bit < BIT_N_SIZE; ++l_bit)
+ {
+ for (uint8_t l_eye_index = 0; l_eye_index < EYE_MIN_MAX_SIZE; ++l_eye_index)
+ {
+ const auto l_eye_min = i_training_info.write_2d_eye_resp.VrefDQ[l_rank][l_dbyte][l_bit].eye_min[l_eye_index];
+ const auto l_eye_max = i_training_info.write_2d_eye_resp.VrefDQ[l_rank][l_dbyte][l_bit].eye_max[l_eye_index];
+
+ FAPI_MFG("%s %s RANK %u, DBYTE %u BIT %u EYE INDEX %u -- MIN: %u MAX: %u",
+ mss::c_str(i_target), "VrefDQ", l_rank, l_dbyte, l_bit, l_eye_index, l_eye_min, l_eye_max);
+ }
+ }
+ }
+ }
+
+ FAPI_MFG("%s %s_Center:", mss::c_str(i_target), "VrefDQ");
+
+ for (uint8_t l_rank = 0; l_rank < TRAINING_RESPONSE_NUM_RANKS; ++l_rank)
+ {
+ for (uint8_t l_nibble = 0; l_nibble < NIBBLE_N_SIZE; ++l_nibble)
+ {
+ const auto l_vrefdq_center = i_training_info.write_2d_eye_resp.VrefDQ_Center[l_rank][l_nibble];
+ FAPI_MFG("%s %s RANK %u, NIBBLE %u: %u", mss::c_str(i_target), "VrefDQ_Center", l_rank, l_nibble, l_vrefdq_center);
+ }
+ }
+
+ FAPI_MFG("%s %s_Center:", mss::c_str(i_target), "TxDqDly");
+
+ for (uint8_t l_rank = 0; l_rank < TRAINING_RESPONSE_NUM_RANKS; ++l_rank)
+ {
+ for (uint8_t l_dbyte = 0; l_dbyte < DBYTE_N_SIZE; ++l_dbyte)
+ {
+ for (uint8_t l_bit = 0; l_bit < BIT_N_SIZE; ++l_bit)
+ {
+ const auto l_txdqdly_center = i_training_info.write_2d_eye_resp.TxDqDly_Center[l_rank][l_dbyte][l_bit];
+ FAPI_MFG("%s %s RANK %u, DBYTE %u BIT %u: %u", mss::c_str(i_target), "TxDqDly_Center", l_rank, l_dbyte, l_bit,
+ l_txdqdly_center);
+ }
+ }
+ }
+}
+
+///
+/// @brief Displays all training information
+/// @param[in] i_target the OCMB target
+/// @param[in] i_training_info the training information to display
+/// @return fapi2::FAPI2_RC_SUCCESS iff success
+///
+template <>
+fapi2::ReturnCode display_user_2d_eye_info<user_2d_eye_response_1_msdg_t>(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const user_2d_eye_response_1_msdg_t& i_training_info)
+{
+ FAPI_INF("%s displaying user 2d eye response 1 data version %u", mss::c_str(i_target), i_training_info.version_number)
+ display_train_2d_read_eye(i_target, i_training_info);
+ FAPI_TRY(display_normal_info(i_target, i_training_info));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Displays all training information
+/// @param[in] i_target the OCMB target
+/// @param[in] i_training_info the training information to display
+/// @return fapi2::FAPI2_RC_SUCCESS iff success
+///
+template <>
+fapi2::ReturnCode display_user_2d_eye_info<user_2d_eye_response_2_msdg_t>(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const user_2d_eye_response_2_msdg_t& i_training_info)
+{
+ FAPI_INF("%s displaying user 2d eye response 2 data version %u", mss::c_str(i_target), i_training_info.version_number)
+ display_train_2d_write_eye(i_target, i_training_info);
+ FAPI_TRY(display_normal_info(i_target, i_training_info));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // ns train
+} // ns exp
+} // ns mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_display.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_display.H
index f4afb90f7..abd131559 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_display.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_display.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,10 +37,16 @@
#define _EXP_TRAIN_DISPLAY_H_
#include <fapi2.H>
+#include <lib/shared/exp_consts.H>
+#include <lib/shared/exp_defaults.H>
+#include <lib/dimm/exp_rank.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <generic/memory/lib/utils/index.H>
#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/utils/find.H>
#include <exp_data_structs.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
+
namespace mss
{
@@ -49,18 +55,346 @@ namespace exp
namespace train
{
///
-/// @brief Displays all training information
+/// @brief Displays training information
+/// @param[in] i_target the OCMB target
+/// @param[in] i_lane the lane for the training information
+/// @param[in] i_data the training data for this lane
+///
+void display_lane_results(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint64_t i_lane,
+ const uint16_t i_data);
+
+///
+/// @brief Displays RCW information for a single 8-bit RCW
+/// @param[in] i_target the OCMB target
+/// @param[in] i_dimm the dimm number associated w/ the RCW
+/// @param[in] i_func_space the function space for the RCW
+/// @param[in] i_rcw_number RCW number
+/// @param[in] i_data data associated with the RCW
+///
+inline void display_rcw_8bit(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint64_t i_dimm,
+ const uint64_t i_func_space,
+ const uint64_t i_rcw_number,
+ const uint8_t i_data)
+{
+ const uint64_t l_rcw_print_number = i_rcw_number - exp_struct_sizes::RCW_8BIT_CUTOFF;
+ FAPI_MFG("%s DIMM%u F%uRC%xX: 0x%02x", mss::c_str(i_target), i_dimm, i_func_space, l_rcw_print_number, i_data);
+}
+
+///
+/// @brief Displays RCW information for a single 4-bit RCW
+/// @param[in] i_target the OCMB target
+/// @param[in] i_dimm the dimm number associated w/ the RCW
+/// @param[in] i_func_space the function space for the RCW
+/// @param[in] i_rcw_number RCW number
+/// @param[in] i_data data associated with the RCW
+///
+inline void display_rcw_4bit(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint64_t i_dimm,
+ const uint64_t i_func_space,
+ const uint64_t i_rcw_number,
+ const uint8_t i_data)
+{
+ FAPI_MFG("%s DIMM%u F%uRC%02x: 0x%02x", mss::c_str(i_target), i_dimm, i_func_space, i_rcw_number, i_data);
+}
+
+
+///
+/// @brief Displays lane failure information after training
+/// @tparam T response struct
+/// @param[in] i_target the OCMB target
+/// @param[in] i_training_info the training information to display
+///
+template <typename T>
+void display_lane_info(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const T& i_training_info)
+{
+ for(uint8_t l_lane = 0; l_lane < exp_struct_sizes::TRAINING_RESPONSE_NUM_LANES; ++l_lane)
+ {
+ display_lane_results( i_target, l_lane, i_training_info.err_resp.Failure_Lane[l_lane]);
+ }
+}
+
+///
+/// @brief Displays MR information
+/// @tparam T response struct
+/// @param[in] i_target the OCMB target
+/// @param[in] i_training_info the training information to display
+///
+template <typename T>
+fapi2::ReturnCode display_mrs_info(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const T& i_training_info)
+{
+ // Loop through all ports
+ for (const auto& l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
+ {
+ // Rank info object for
+ std::vector<mss::rank::info<>> l_rank_info_vect;
+ uint8_t l_dram_width[mss::exp::sizes::MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY(mss::rank::ranks_on_port<>(l_port, l_rank_info_vect));
+ FAPI_TRY(mss::attr::get_dram_width(l_port, l_dram_width));
+
+ // Loops through all of the ranks
+ for (const auto& l_rank_info : l_rank_info_vect)
+ {
+ const uint8_t l_phy_rank = l_rank_info.get_phy_rank();
+ const uint8_t l_port_rank = l_rank_info.get_port_rank();
+ const uint8_t l_dram_width_for_dimm = l_dram_width[mss::index(l_rank_info.get_dimm_target())];
+ // MR0->5 are easy, just display the value
+ FAPI_MFG("%s rank%u MR%u 0x%04x", mss::c_str(i_target), l_port_rank, 0, i_training_info.mrs_resp.MR0);
+ FAPI_MFG("%s rank%u MR%u 0x%04x", mss::c_str(i_target), l_port_rank, 1, i_training_info.mrs_resp.MR1[l_phy_rank]);
+ FAPI_MFG("%s rank%u MR%u 0x%04x", mss::c_str(i_target), l_port_rank, 2, i_training_info.mrs_resp.MR2[l_phy_rank]);
+ FAPI_MFG("%s rank%u MR%u 0x%04x", mss::c_str(i_target), l_port_rank, 3, i_training_info.mrs_resp.MR3);
+ FAPI_MFG("%s rank%u MR%u 0x%04x", mss::c_str(i_target), l_port_rank, 4, i_training_info.mrs_resp.MR4);
+ FAPI_MFG("%s rank%u MR%u 0x%04x", mss::c_str(i_target), l_port_rank, 5, i_training_info.mrs_resp.MR5[l_phy_rank]);
+
+ // The number of the DRAM's and the position to access each DRAM changes based upon x4 vs x8
+ const auto l_num_dram = l_dram_width_for_dimm == fapi2::ENUM_ATTR_MEM_EFF_DRAM_WIDTH_X4 ?
+ mss::exp::generic_consts::EXP_NUM_DRAM_X4 : mss::exp::generic_consts::EXP_NUM_DRAM_X8;
+ // The correction factor is used to determine the correct DRAM position, as x8 DRAM's take up two entries
+ const auto l_correction_factor = l_dram_width_for_dimm == fapi2::ENUM_ATTR_MEM_EFF_DRAM_WIDTH_X4 ? 1 : 2;
+
+ for (uint64_t l_dram = 0; l_dram < l_num_dram; ++l_dram)
+ {
+ const auto l_dram_pos = l_correction_factor * l_dram;
+ FAPI_MFG("%s rank%u MR6 dram%u 0x%04x", mss::c_str(i_target), l_port_rank, l_dram,
+ i_training_info.mrs_resp.MR6[l_phy_rank][l_dram_pos]);
+ }
+ }
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Displays all RCW information
+/// @tparam T response struct
+/// @param[in] i_target the OCMB target
+/// @param[in] i_training_info the training information to display
+///
+template <typename T>
+void display_rcw_info(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const T& i_training_info)
+{
+ constexpr uint64_t FUNC_SPACE0 = 0;
+ constexpr uint64_t FUNC_SPACE1 = 1;
+
+ // Only display the DIMM's that exist
+ const auto& l_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target);
+
+ // Display DIMM0
+ if(l_dimms.size() >= 1)
+ {
+ // Display all of function space 0
+ // Display all 4-bit numbers
+ for(uint8_t l_rcw = 0; l_rcw < exp_struct_sizes::RCW_8BIT_CUTOFF; ++l_rcw)
+ {
+ display_rcw_4bit( i_target, 0, FUNC_SPACE0, l_rcw, i_training_info.rc_resp.F0RC_D0[l_rcw]);
+ }
+
+ // Display all 8-bit numbers
+ for(uint8_t l_rcw = exp_struct_sizes::RCW_8BIT_CUTOFF; l_rcw < exp_struct_sizes::TRAINING_RESPONSE_NUM_RC; ++l_rcw)
+ {
+ display_rcw_8bit( i_target, 0, FUNC_SPACE0, l_rcw, i_training_info.rc_resp.F0RC_D0[l_rcw]);
+ }
+
+ // Display all of function space 1
+ // Display all 4-bit numbers
+ for(uint8_t l_rcw = 0; l_rcw < exp_struct_sizes::RCW_8BIT_CUTOFF; ++l_rcw)
+ {
+ display_rcw_4bit( i_target, 0, FUNC_SPACE1, l_rcw, i_training_info.rc_resp.F1RC_D0[l_rcw]);
+ }
+
+ // Display all 8-bit numbers
+ for(uint8_t l_rcw = exp_struct_sizes::RCW_8BIT_CUTOFF; l_rcw < exp_struct_sizes::TRAINING_RESPONSE_NUM_RC; ++l_rcw)
+ {
+ display_rcw_8bit( i_target, 0, FUNC_SPACE1, l_rcw, i_training_info.rc_resp.F1RC_D0[l_rcw]);
+ }
+ }
+
+ // Display DIMM1
+ if(l_dimms.size() == 2)
+ {
+ // Display all of function space 0
+ // Display all 4-bit numbers
+ for(uint8_t l_rcw = 0; l_rcw < exp_struct_sizes::RCW_8BIT_CUTOFF; ++l_rcw)
+ {
+ display_rcw_4bit( i_target, 1, FUNC_SPACE0, l_rcw, i_training_info.rc_resp.F0RC_D1[l_rcw]);
+ }
+
+ // Display all 8-bit numbers
+ for(uint8_t l_rcw = exp_struct_sizes::RCW_8BIT_CUTOFF; l_rcw < exp_struct_sizes::TRAINING_RESPONSE_NUM_RC; ++l_rcw)
+ {
+ display_rcw_8bit( i_target, 1, FUNC_SPACE0, l_rcw, i_training_info.rc_resp.F0RC_D1[l_rcw]);
+ }
+
+ // Display all of function space 1
+ // Display all 4-bit numbers
+ for(uint8_t l_rcw = 0; l_rcw < exp_struct_sizes::RCW_8BIT_CUTOFF; ++l_rcw)
+ {
+ display_rcw_4bit( i_target, 1, FUNC_SPACE1, l_rcw, i_training_info.rc_resp.F1RC_D1[l_rcw]);
+ }
+
+ // Display all 8-bit numbers
+ for(uint8_t l_rcw = exp_struct_sizes::RCW_8BIT_CUTOFF; l_rcw < exp_struct_sizes::TRAINING_RESPONSE_NUM_RC; ++l_rcw)
+ {
+ display_rcw_8bit( i_target, 1, FUNC_SPACE1, l_rcw, i_training_info.rc_resp.F1RC_D1[l_rcw]);
+ }
+ }
+}
+
+///
+/// @brief Displays command to command response timing
+/// @tparam T response struct
/// @param[in] i_target the OCMB target
/// @param[in] i_training_info the training information to display
/// @return returns FAPI2_RC_SUCCESS iff the procedure executes successfully
-/// @note This is a place holder to help avoid merge conflicts
///
-inline fapi2::ReturnCode display_info(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
- const user_response_msdg_t& i_training_info)
+template <typename T>
+inline fapi2::ReturnCode display_response_timing(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const T& i_training_info)
{
+ // Loop through all ports
+ for (const auto& l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
+ {
+ // Rank info object for
+ std::vector<mss::rank::info<>> l_rank_info_vect;
+ FAPI_TRY(mss::rank::ranks_on_port<>(l_port, l_rank_info_vect));
+
+ // DFIMRL_DDRCLK_trained training result
+ FAPI_MFG("%s DFIMRL_DDRCLK_trained: %u", mss::c_str(i_target), i_training_info.tm_resp.DFIMRL_DDRCLK_trained);
+
+ // RD to RD
+ FAPI_MFG("%s RD-to-RD : 0 1 2 3", mss::c_str(i_target));
+
+ for(const auto& l_rank : l_rank_info_vect)
+ {
+ const auto l_phy_rank = l_rank.get_phy_rank();
+ const auto l_port_rank = l_rank.get_port_rank();
+ FAPI_MFG("%s RD-to-RD rank%u: %2i %2i %2i %2i", mss::c_str(i_target), l_port_rank,
+ i_training_info.tm_resp.CDD_RR[l_phy_rank][0], i_training_info.tm_resp.CDD_RR[l_phy_rank][1],
+ i_training_info.tm_resp.CDD_RR[l_phy_rank][2], i_training_info.tm_resp.CDD_RR[l_phy_rank][3]);
+ }
+
+ // WR to WR
+ FAPI_MFG("%s WR-to-WR : 0 1 2 3", mss::c_str(i_target));
+
+ for(const auto& l_rank : l_rank_info_vect)
+ {
+ const auto l_phy_rank = l_rank.get_phy_rank();
+ const auto l_port_rank = l_rank.get_port_rank();
+ FAPI_MFG("%s WR-to-WR rank%u: %2i %2i %2i %2i", mss::c_str(i_target), l_port_rank,
+ i_training_info.tm_resp.CDD_WW[l_phy_rank][0], i_training_info.tm_resp.CDD_WW[l_phy_rank][1],
+ i_training_info.tm_resp.CDD_WW[l_phy_rank][2], i_training_info.tm_resp.CDD_WW[l_phy_rank][3]);
+ }
+
+ // WR to RD
+ FAPI_MFG("%s WR-to-RD : 0 1 2 3", mss::c_str(i_target));
+
+ for(const auto& l_rank : l_rank_info_vect)
+ {
+ const auto l_phy_rank = l_rank.get_phy_rank();
+ const auto l_port_rank = l_rank.get_port_rank();
+ FAPI_MFG("%s WR-to-RD rank%u: %2i %2i %2i %2i", mss::c_str(i_target), l_port_rank,
+ i_training_info.tm_resp.CDD_WR[l_phy_rank][0], i_training_info.tm_resp.CDD_WR[l_phy_rank][1],
+ i_training_info.tm_resp.CDD_WR[l_phy_rank][2], i_training_info.tm_resp.CDD_WR[l_phy_rank][3]);
+ }
+
+ // RD to WR
+ FAPI_MFG("%s RD-to-WR : 0 1 2 3", mss::c_str(i_target));
+
+ for(const auto& l_rank : l_rank_info_vect)
+ {
+ const auto l_phy_rank = l_rank.get_phy_rank();
+ const auto l_port_rank = l_rank.get_port_rank();
+ FAPI_MFG("%s RD-to-WR rank%u: %2i %2i %2i %2i", mss::c_str(i_target), l_port_rank,
+ i_training_info.tm_resp.CDD_RW[l_phy_rank][0], i_training_info.tm_resp.CDD_RW[l_phy_rank][1],
+ i_training_info.tm_resp.CDD_RW[l_phy_rank][2], i_training_info.tm_resp.CDD_RW[l_phy_rank][3]);
+ }
+ }
+
return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Display train_2d_read_eye_msdg_t response struct
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_training_info training info struct
+///
+void display_train_2d_read_eye(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const user_2d_eye_response_1_msdg_t& i_training_info);
+
+///
+/// @brief Display train_2d_write_eye_msdg_t response struct
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_training_info training info struct
+///
+void display_train_2d_write_eye(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const user_2d_eye_response_2_msdg_t& i_training_info);
+
+///
+/// @brief Displays all training information common to all response structs
+/// @tparam T response struct
+/// @param[in] i_target the OCMB target
+/// @param[in] i_training_info the training information to display
+/// @return returns FAPI2_RC_SUCCESS iff the procedure executes successfully
+///
+template <typename T>
+inline fapi2::ReturnCode display_normal_info(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const T& i_training_info)
+{
+ // Target trace & FAPI_INF moved to the caller(s) such that we can call this from the eye capture functions
+ display_rcw_info(i_target, i_training_info);
+ FAPI_TRY(display_mrs_info(i_target, i_training_info));
+ display_lane_info(i_target, i_training_info);
+ FAPI_TRY(display_response_timing(i_target, i_training_info));
+
+fapi_try_exit:
+ return fapi2::current_err;
}
+///
+/// @brief Displays all training information
+/// @tparam T response struct
+/// @param[in] i_target the OCMB target
+/// @param[in] i_training_info the training information to display
+/// @return fapi2::FAPI2_RC_SUCCESS iff success
+///
+template <typename T>
+fapi2::ReturnCode display_user_2d_eye_info(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const T& i_training_info);
+
+///
+/// @brief Displays all training information for eye response 1
+/// @param[in] i_target the OCMB target
+/// @param[in] i_training_info the training information to display
+/// @return fapi2::FAPI2_RC_SUCCESS iff success
+///
+template <>
+fapi2::ReturnCode display_user_2d_eye_info<user_2d_eye_response_1_msdg_t>(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const user_2d_eye_response_1_msdg_t& i_training_info);
+
+///
+/// @brief Displays all training information for eye response 2
+/// @param[in] i_target the OCMB target
+/// @param[in] i_training_info the training information to display
+/// @return fapi2::FAPI2_RC_SUCCESS iff success
+///
+template <>
+fapi2::ReturnCode display_user_2d_eye_info<user_2d_eye_response_2_msdg_t>(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const user_2d_eye_response_2_msdg_t& i_training_info);
} // ns train
} // ns exp
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.C
index 0418b59d1..82a538c32 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -46,17 +46,40 @@ namespace mss
{
///
-/// @brief A generic bad bits setter
-/// @tparam MC type memory controller type
+/// @brief Bad bit getter - Explorer specialization
/// @param[in] i_target the fapi2 target oon which training was conducted
-/// @param[in] i_array the bad bits to set
+/// @param[out] o_array the bad bits
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+template <>
+fapi2::ReturnCode get_bad_dq_bitmap<mss::mc_type::EXPLORER>(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT])
+{
+ return mss::attr::get_bad_dq_bitmap(i_target, o_array);
+}
+
+///
+/// @brief Bad bit setter - Explorer specialization
+/// @param[in] i_target the fapi2 target oon which training was conducted
+/// @param[in] i_array the bad bits to append
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if bad bits can be repaired
///
template <>
fapi2::ReturnCode set_bad_dq_bitmap<mss::mc_type::EXPLORER>(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
uint8_t (&i_array)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT])
{
- return mss::attr::set_bad_dq_bitmap(i_target, i_array);
+ uint8_t l_current_data[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT] = {};
+
+ // Get existing bad bits data
+ FAPI_TRY(mss::attr::get_bad_dq_bitmap(i_target, l_current_data));
+
+ // Now, or the new bits and any existing bits together
+ mss::combine_bad_bits(l_current_data, i_array);
+
+ FAPI_TRY(mss::attr::set_bad_dq_bitmap(i_target, i_array));
+
+fapi_try_exit:
+ return fapi2::current_err;
}
namespace check
@@ -72,12 +95,11 @@ namespace check
// TK update this when FIR's are fully reviewed
template<>
fapi2::ReturnCode bad_fir_bits<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
-
fapi2::ReturnCode& io_rc,
bool& o_fir_error )
{
- io_rc = fapi2::FAPI2_RC_SUCCESS;
+ FAPI_ERR("%s Checking for FIR's is currently unimplemented. Passing back the discovered RC", mss::c_str(i_target));
o_fir_error = false;
return fapi2::FAPI2_RC_SUCCESS;
}
@@ -94,52 +116,17 @@ namespace exp
/// @param[out] o_resp the processed training response class
/// @return FAPI2_RC_SUCCESS if ok
///
-fapi2::ReturnCode read_training_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+fapi2::ReturnCode read_normal_training_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const std::vector<uint8_t>& i_data,
user_response_msdg& o_resp)
{
-
- // True if we pass
// We assert at the end to avoid LOTS of fapi asserts
uint32_t l_idx = 0;
- bool l_pass = readLE(i_data, l_idx, o_resp.version_number);
-
- // Reads in the timing portion of the training response
- l_pass &= readLE(i_data, l_idx, o_resp.tm_resp.DFIMRL_DDRCLK_trained);
- l_pass &= readLEArray(i_data, TIMING_RESPONSE_2D_ARRAY_SIZE, l_idx, &o_resp.tm_resp.CDD_RR[0][0]);
- l_pass &= readLEArray(i_data, TIMING_RESPONSE_2D_ARRAY_SIZE, l_idx, &o_resp.tm_resp.CDD_WW[0][0]);
- l_pass &= readLEArray(i_data, TIMING_RESPONSE_2D_ARRAY_SIZE, l_idx, &o_resp.tm_resp.CDD_RW[0][0]);
- l_pass &= readLEArray(i_data, TIMING_RESPONSE_2D_ARRAY_SIZE, l_idx, &o_resp.tm_resp.CDD_WR[0][0]);
-
- // Error response
- l_pass &= readLEArray(i_data, 80, l_idx, o_resp.err_resp.Failure_Lane);
-
- // MRS response
- l_pass &= readLE(i_data, l_idx, o_resp.mrs_resp.MR0);
- l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RANKS, l_idx, o_resp.mrs_resp.MR1);
- l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RANKS, l_idx, o_resp.mrs_resp.MR2);
- l_pass &= readLE(i_data, l_idx, o_resp.mrs_resp.MR3);
- l_pass &= readLE(i_data, l_idx, o_resp.mrs_resp.MR4);
- l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RANKS, l_idx, o_resp.mrs_resp.MR5);
- l_pass &= readLEArray(i_data, TRAINING_RESPONSE_MR6_SIZE, l_idx, &o_resp.mrs_resp.MR6[0][0]);
-
- // Register Control Word (RCW) response
- l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RC, l_idx, o_resp.rc_resp.F0RC_D0);
- l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RC, l_idx, o_resp.rc_resp.F1RC_D0);
- l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RC, l_idx, o_resp.rc_resp.F0RC_D1);
- l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RC, l_idx, o_resp.rc_resp.F1RC_D1);
-
- // Check if we have errors
- FAPI_ASSERT( l_pass,
- fapi2::EXP_INBAND_LE_DATA_RANGE()
- .set_TARGET(i_target)
- .set_FUNCTION(mss::exp::READ_TRAINING_RESPONSE_STRUCT)
- .set_DATA_SIZE(i_data.size())
- .set_MAX_INDEX(sizeof(user_response_msdg)),
- "%s Failed to convert from data to host_fw_response_struct data size %u expected size %u",
- mss::c_str(i_target), i_data.size(), sizeof(user_response_msdg));
+ uint32_t l_version_number = 0;
+ bool l_pass = readLE(i_data, l_idx, l_version_number);
+ o_resp.version_number = l_version_number;
- return fapi2::FAPI2_RC_SUCCESS;
+ FAPI_TRY(read_tm_err_mrs_rc_response<user_response_msdg>(i_target, i_data, l_idx, l_pass, o_resp));
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.H
index 41c868946..dc599616c 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.H
@@ -38,7 +38,10 @@
#include <fapi2.H>
#include <lib/shared/exp_consts.H>
+#include <lib/shared/exp_defaults.H>
+#include <lib/dimm/exp_rank.H>
#include <exp_data_structs.H>
+#include <generic/memory/lib/utils/endian_utils.H>
#include <generic/memory/lib/utils/mss_bad_bits.H>
#include <generic/memory/lib/mss_generic_attribute_setters.H>
#include <generic/memory/lib/mss_generic_attribute_getters.H>
@@ -49,20 +52,204 @@ namespace exp
{
///
-/// @brief Reads the training response structure
-/// @param[in] i_target the target associated with the response data
-/// @param[in] i_data the response data to read
-/// @param[out] o_resp the processed training response class
-/// @return FAPI2_RC_SUCCESS if ok
+/// @brief Read eye capture response data from explorer data buffer
+///
+/// @tparam T Response struct type
+/// @param[in] i_target OCMB target
+/// @param[in] i_data Raw data bytes
+/// @param[in,out] io_current_idx Current parsing index
+/// @param[in,out] io_pass any errors occurred during reading/endian-swapping
+/// @param[in,out] io_resp response struct
+/// @note this function expects io_current_index to be set correctly to the start of eye capture data
+///
+template <typename T>
+void read_eye_capture_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t>& i_data,
+ uint32_t& io_current_idx,
+ bool& io_pass,
+ T& io_resp);
+
+///
+/// @brief Read eye capture response data from explorer data buffer (eye capture step 1)
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_data Raw data bytes
+/// @param[in,out] io_current_idx Current parsing index
+/// @param[in,out] io_pass any errors occurred during reading/endian-swapping
+/// @param[in,out] io_resp train_2d_read_eye_msdg
+/// @note this function expects io_current_index to be set correctly to the start of eye capture data
///
-fapi2::ReturnCode read_training_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+template<>
+inline void read_eye_capture_response<user_2d_eye_response_1_msdg>(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
+ i_target,
const std::vector<uint8_t>& i_data,
- user_response_msdg& o_resp);
+ uint32_t& io_current_idx,
+ bool& io_pass,
+ user_2d_eye_response_1_msdg& io_resp)
+{
+ // Eye capture step 1 struct
+ uint32_t l_idx = io_current_idx;
+ bool l_pass = io_pass;
+
+ // VrefDAC0: 3D array of 2 1D arrays
+ for (uint8_t l_num_ranks = 0; l_num_ranks < TRAINING_RESPONSE_NUM_RANKS; ++l_num_ranks)
+ {
+ for (uint8_t l_dbyte_n_size = 0; l_dbyte_n_size < DBYTE_N_SIZE; ++ l_dbyte_n_size)
+ {
+ for (uint8_t l_bit_n_sze = 0; l_bit_n_sze < BIT_N_SIZE; ++ l_bit_n_sze)
+ {
+ l_pass &= readLEArray(i_data, EYE_MIN_MAX_SIZE, l_idx,
+ &io_resp.read_2d_eye_resp.VrefDAC0[l_num_ranks][l_dbyte_n_size][l_bit_n_sze].eye_min[0]);
+ l_pass &= readLEArray(i_data, EYE_MIN_MAX_SIZE, l_idx,
+ &io_resp.read_2d_eye_resp.VrefDAC0[l_num_ranks][l_dbyte_n_size][l_bit_n_sze].eye_max[0]);
+ }
+ }
+ }
+
+ // 2D array VrefDAC0_Center [DBYTE_N_SIZE][BIT_N_SIZE]
+ l_pass &= readLEArray(i_data, (DBYTE_N_SIZE * BIT_N_SIZE), l_idx,
+ &io_resp.read_2d_eye_resp.VrefDAC0_Center[0][0]);
+
+ // 2D array RxClkDly_Center [TRAINING_RESPONSE_NUM_RANKS][NIBBLE_N_SIZE]
+ l_pass &= readLEArray(i_data, (TRAINING_RESPONSE_NUM_RANKS * NIBBLE_N_SIZE), l_idx,
+ &io_resp.read_2d_eye_resp.RxClkDly_Center[0][0]);
+
+ io_pass = l_pass;
+ io_current_idx = l_idx;
+}
+
+///
+/// @brief Read eye capture response data from explorer data buffer (eye capture step 2)
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_data Raw data bytes
+/// @param[in,out] io_current_idx Current parsing index
+/// @param[in,out] io_pass any errors occurred during reading/endian-swapping
+/// @param[in,out] io_resp user_2d_eye_response_2_msdg
+/// @note this function expects io_current_index to be set correctly to the start of eye capture data
+///
+template<>
+inline void read_eye_capture_response<user_2d_eye_response_2_msdg>(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
+ i_target,
+ const std::vector<uint8_t>& i_data,
+ uint32_t& io_current_idx,
+ bool& io_pass,
+ user_2d_eye_response_2_msdg& io_resp)
+{
+
+ // Eye capture step 1 struct
+ uint32_t l_idx = io_current_idx;
+ bool l_pass = io_pass;
+
+ // VrefDQ: 3D array of 2 1D arrays
+ for (uint8_t l_num_ranks = 0; l_num_ranks < TRAINING_RESPONSE_NUM_RANKS; ++l_num_ranks)
+ {
+ for (uint8_t l_dbyte_n_size = 0; l_dbyte_n_size < DBYTE_N_SIZE; ++ l_dbyte_n_size)
+ {
+ for (uint8_t l_bit_n_sze = 0; l_bit_n_sze < BIT_N_SIZE; ++ l_bit_n_sze)
+ {
+ l_pass &= readLEArray(i_data, EYE_MIN_MAX_SIZE, l_idx,
+ &io_resp.write_2d_eye_resp.VrefDQ[l_num_ranks][l_dbyte_n_size][l_bit_n_sze].eye_min[0]);
+ l_pass &= readLEArray(i_data, EYE_MIN_MAX_SIZE, l_idx,
+ &io_resp.write_2d_eye_resp.VrefDQ[l_num_ranks][l_dbyte_n_size][l_bit_n_sze].eye_max[0]);
+ }
+ }
+ }
+
+ // 2D array VrefDQ_Center [TRAINING_RESPONSE_NUM_RANKS][NIBBLE_N_SIZE]
+ l_pass &= readLEArray(i_data, (TRAINING_RESPONSE_NUM_RANKS * NIBBLE_N_SIZE), l_idx,
+ &io_resp.write_2d_eye_resp.VrefDQ_Center[0][0]);
+
+ // 3D array TxDqDly_Center [TRAINING_RESPONSE_NUM_RANKS][DBYTE_N_SIZE][DBYTE_N_SIZE]
+ l_pass &= readLEArray(i_data, (TRAINING_RESPONSE_NUM_RANKS * DBYTE_N_SIZE * BIT_N_SIZE), l_idx,
+ &io_resp.write_2d_eye_resp.TxDqDly_Center[0][0][0]);
+
+ io_pass = l_pass;
+ io_current_idx = l_idx;
+
+ return;
+}
+
+///
+/// @brief Read the common block of fields from the training response structs
+///
+/// @tparam T training repsonse struct type
+/// @param[in] i_target OCMB chip
+/// @param[in] i_data response data
+/// @param[in] i_current_idx last index left off
+/// @param[in] i_pass response parsing success thus far
+/// @param[in,out] io_resp response struct
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+template <typename T>
+fapi2::ReturnCode read_tm_err_mrs_rc_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t>& i_data,
+ const uint32_t i_current_idx,
+ const bool i_pass,
+ T& io_resp)
+{
+ uint32_t l_idx = i_current_idx;
+ bool l_pass = i_pass;
+
+ uint16_t l_DFIMRL_DDRCLK_trained = 0;
+
+ // Reads in the timing portion of the training response
+ l_pass &= readLE(i_data, l_idx, l_DFIMRL_DDRCLK_trained);
+ l_pass &= readLEArray(i_data, TIMING_RESPONSE_2D_ARRAY_SIZE, l_idx, &io_resp.tm_resp.CDD_RR[0][0]);
+ l_pass &= readLEArray(i_data, TIMING_RESPONSE_2D_ARRAY_SIZE, l_idx, &io_resp.tm_resp.CDD_WW[0][0]);
+ l_pass &= readLEArray(i_data, TIMING_RESPONSE_2D_ARRAY_SIZE, l_idx, &io_resp.tm_resp.CDD_RW[0][0]);
+ l_pass &= readLEArray(i_data, TIMING_RESPONSE_2D_ARRAY_SIZE, l_idx, &io_resp.tm_resp.CDD_WR[0][0]);
+
+ // Write to user_response_msdg
+ io_resp.tm_resp.DFIMRL_DDRCLK_trained = l_DFIMRL_DDRCLK_trained;
+
+ // Error response
+ l_pass &= readLEArray(i_data, 80, l_idx, io_resp.err_resp.Failure_Lane);
+
+ uint16_t l_MR0 = 0;
+ uint16_t l_MR3 = 0;
+ uint16_t l_MR4 = 0;
+
+ // MRS response
+ l_pass &= readLE(i_data, l_idx, l_MR0);
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RANKS, l_idx, io_resp.mrs_resp.MR1);
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RANKS, l_idx, io_resp.mrs_resp.MR2);
+ l_pass &= readLE(i_data, l_idx, l_MR3);
+ l_pass &= readLE(i_data, l_idx, l_MR4);
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RANKS, l_idx, io_resp.mrs_resp.MR5);
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_MR6_SIZE, l_idx, &io_resp.mrs_resp.MR6[0][0]);
+
+ io_resp.mrs_resp.MR0 = l_MR0;
+ io_resp.mrs_resp.MR3 = l_MR3;
+ io_resp.mrs_resp.MR4 = l_MR4;
+
+ // Register Control Word (RCW) response
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RC, l_idx, io_resp.rc_resp.F0RC_D0);
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RC, l_idx, io_resp.rc_resp.F1RC_D0);
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RC, l_idx, io_resp.rc_resp.F0RC_D1);
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RC, l_idx, io_resp.rc_resp.F1RC_D1);
+
+ // Check if we have errors
+ FAPI_ASSERT( l_pass,
+ fapi2::EXP_INBAND_LE_DATA_RANGE()
+ .set_TARGET(i_target)
+ .set_FUNCTION(mss::exp::READ_TRAINING_RESPONSE_STRUCT)
+ .set_DATA_SIZE(i_data.size())
+ .set_MAX_INDEX(sizeof(T)),
+ "%s Failed to convert from data to host_fw_response_struct data size %u expected size %u",
+ mss::c_str(i_target), i_data.size(), sizeof(T));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
///
/// @brief Explorer's bad bit interface class
-/// @brief Explorer's bad bit interface class
+/// @tparam T user response struct type
///
+template <typename T>
class bad_bit_interface
{
public:
@@ -83,7 +270,7 @@ class bad_bit_interface
/// @brief Constructor
/// @param[in] i_response response data from training
///
- bad_bit_interface(const user_response_msdg_t& i_response )
+ bad_bit_interface(const T& i_response )
{
// First, clear everything
std::fill(&iv_bad_bits[0][0], &iv_bad_bits[0][0] + sizeof(iv_bad_bits), 0);
@@ -154,28 +341,12 @@ class bad_bit_interface
fapi2::ReturnCode record_bad_bits_interface( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
uint8_t (&o_bad_dq)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT]) const
{
- // Gets the rank offset for this DIMM
- const uint64_t DIMM_OFFSET = mss::index(i_target) == 0 ? 0 : 2;
-
- // Loops through all of the ranks on this DIMM
- uint8_t l_num_ranks = 0;
- FAPI_TRY(mss::attr::get_num_master_ranks_per_dimm(i_target, l_num_ranks));
+ std::vector<mss::rank::info<>> l_ranks;
+ FAPI_TRY(mss::rank::ranks_on_dimm(i_target, l_ranks));
- // TK Add in num ranks check here
- // TK update for the ranks API
-
- for(uint64_t l_rank = 0; l_rank < l_num_ranks; ++l_rank)
+ for(const auto& l_rank : l_ranks)
{
- const uint64_t RANK = DIMM_OFFSET + l_rank;
- FAPI_ASSERT(RANK < mss::exp::MAX_RANK_PER_DIMM,
- fapi2::MSS_EXP_DRAMINIT_BAD_NUM_RANKS()
- .set_NUM_RANKS(RANK)
- .set_MAX_RANKS(mss::exp::MAX_RANK_PER_DIMM)
- .set_TARGET(i_target),
- "%s bad number of ranks passed num:%u, max:%u",
- mss::c_str(i_target), RANK, mss::exp::MAX_RANK_PER_DIMM);
-
- memcpy(&o_bad_dq[RANK], &iv_bad_bits[RANK], sizeof(uint8_t[BAD_DQ_BYTE_COUNT]));
+ memcpy(&o_bad_dq[l_rank.get_phy_rank()], &iv_bad_bits[l_rank.get_phy_rank()], sizeof(uint8_t[BAD_DQ_BYTE_COUNT]));
}
return fapi2::FAPI2_RC_SUCCESS;
@@ -185,6 +356,48 @@ class bad_bit_interface
}
};
+
+///
+/// @brief Reads the training response structure
+/// @param[in] i_target the target associated with the response data
+/// @param[in] i_data the response data to read
+/// @param[out] o_resp the processed training response class
+/// @return FAPI2_RC_SUCCESS if ok
+///
+fapi2::ReturnCode read_normal_training_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t>& i_data,
+ user_response_msdg& o_resp);
+
+///
+/// @brief Reads user 2d eye response 1
+/// @tparam T response struct
+/// @param[in] i_target the target associated with the response data
+/// @param[in] i_data the response data to read
+/// @param[out] o_resp the processed training response class
+/// @return FAPI2_RC_SUCCESS if ok
+///
+template <typename T>
+inline fapi2::ReturnCode read_user_2d_eye_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t>& i_data,
+ T& o_resp)
+{
+ // First let's erase the struct
+ memset(&o_resp, 0, sizeof(T));
+ // We assert at the end to avoid LOTS of fapi asserts
+ uint32_t l_idx = 0;
+ uint32_t l_version_number = 0;
+ bool l_pass = readLE(i_data, l_idx, l_version_number);
+ o_resp.version_number = l_version_number;
+
+ read_eye_capture_response<T>(i_target, i_data, l_idx, l_pass, o_resp);
+
+ FAPI_TRY(read_tm_err_mrs_rc_response<T>(i_target, i_data, l_idx, l_pass, o_resp));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
} // ns exp
} // ns mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.C
new file mode 100644
index 000000000..7d833b2ff
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.C
@@ -0,0 +1,155 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_plug_rules.C
+/// @brief Plug rules enforcement for explorer
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include <lib/plug_rules/exp_plug_rules.H>
+#include <mss_explorer_attribute_getters.H>
+
+namespace mss
+{
+namespace exp
+{
+namespace plug_rule
+{
+
+///
+/// @brief Determine enterprise mode from given attribute/fuse values
+///
+/// @param[in] i_target OCMB chip target
+/// @param[in] i_enterprise_fuse enterprise as determined from fuse
+/// @param[in] i_enterprise_policy enterprise policy system attribute value
+/// @param[in] i_non_enterprise_override override attribute value
+/// @param[out] o_is_enterprise_mode resulting state for enterprise mode
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+/// @note this helper function exists for unit testing purposes
+///
+fapi2::ReturnCode enterprise_mode_helper(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const bool i_enterprise_fuse,
+ const uint8_t i_enterprise_policy,
+ const uint8_t i_non_enterprise_override,
+ bool& o_is_enterprise_mode)
+{
+ o_is_enterprise_mode = false;
+
+ // Constexprs to make things easier on the eyes
+ constexpr uint8_t REQUIRE_ENTERPRISE = fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_POLICY_REQUIRE_ENTERPRISE;
+ constexpr uint8_t FORCE_NONENTERPRISE = fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_POLICY_FORCE_NONENTERPRISE;
+
+ // Truth table:
+ // Enterprise (fuse): 0=Disabled 1=Enabled (inverted from fuse logic)
+ // Policy: 0=ALLOW_ENTERPRISE (allow any) 1=REQUIRE_ENTERPRISE 2=FORCE_NONENTERPRISE
+ // Override OFF: 0=NO_OVERRIDE 1=OVERRIDE_TO_NONENTERPRISE
+ //
+ // Enterprise (fuse) Policy Override OFF Result Description
+ // 0 0 0 0
+ // 0 0 1 0
+ // 1 0 0 1
+ // 1 0 1 0
+ // 0 1 0 Error: We don't support enterprise
+ // 0 1 1 Error: We don't support enterprise
+ // 1 1 0 1
+ // 1 1 1 0 Override beats policy
+ // 0 2 0 0
+ // 0 2 1 0
+ // 1 2 0 Error: Policy does not allow for enterprise dimm plugged in
+ // 1 2 1 Error: Policy does not allow for enterprise dimm plugged in
+
+ // Check if we have one of the error configurations
+ const bool l_invalid_config = ((!i_enterprise_fuse) && (i_enterprise_policy == REQUIRE_ENTERPRISE)) ||
+ ((i_enterprise_fuse) && (i_enterprise_policy == FORCE_NONENTERPRISE));
+
+ // For the below assert, i_enterprise_policy must be 1 or 2 to assert out,
+ // so we can use the ternary operator to generate a string description from these two cases
+ FAPI_ASSERT(!l_invalid_config,
+ fapi2::MSS_EXP_ENTERPRISE_INVALID_CONFIGURATION()
+ .set_OCMB_TARGET(i_target)
+ .set_ENTERPRISE_SUPPORTED(i_enterprise_fuse)
+ .set_POLICY(i_enterprise_policy),
+ "%s The enterprise supported bit from the Explorer efuse: %u conflicts with the enterprise "
+ "policy attribute setting: %s",
+ mss::c_str(i_target),
+ i_enterprise_fuse,
+ (i_enterprise_policy == FORCE_NONENTERPRISE ? "FORCE_NONENTERPRISE" : "REQUIRE_ENTERPRISE"));
+
+ // Now generate the resulting value from the remaining truth table entries
+ // We are non-enterprise whenever i_enterprise_policy is 2, or i_non_enterprise_override.
+ // Otherwise, we use the value of i_enterprise_fuse
+ o_is_enterprise_mode = i_enterprise_fuse && !((i_enterprise_policy == FORCE_NONENTERPRISE)
+ || (i_non_enterprise_override));
+
+ FAPI_INF("%s is in %s mode. (OCMB chip is %s, with %s)",
+ mss::c_str(i_target),
+ o_is_enterprise_mode ? "enterprise" : "non-enterprise",
+ i_enterprise_fuse ? "enterprise" : "non-enterprise",
+ i_non_enterprise_override ? "override to non-enterprise" : "no override");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Gets whether the OCMB will be configred to enterprise mode, will assert out if policy/override do not agree
+/// @param[in] i_target OCMB target on which to operate
+/// @param[in] i_enterprise_fuse enterprise as determined from fuse
+/// @param[out] o_is_enterprise_mode true if the part is in enterprise mode
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+///
+fapi2::ReturnCode enterprise_mode(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const bool i_enterprise_fuse,
+ bool& o_is_enterprise_mode )
+{
+ o_is_enterprise_mode = false;
+
+ // Variables
+ uint8_t l_enterprise_policy = 0;
+ uint8_t l_override_attr = 0;
+
+ FAPI_TRY( mss::attr::get_ocmb_enterprise_policy(l_enterprise_policy) );
+ FAPI_TRY( mss::attr::get_ocmb_nonenterprise_mode_override(i_target, l_override_attr) );
+
+ // This function will populate o_is_enterprise_mode accordingly
+ FAPI_TRY(enterprise_mode_helper(i_target, i_enterprise_fuse, l_enterprise_policy, l_override_attr,
+ o_is_enterprise_mode));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+} // plug_rule
+} // exp
+} // mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.H
new file mode 100644
index 000000000..2fbc0d7df
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.H
@@ -0,0 +1,82 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_plug_rules.H
+/// @brief Plug rules enforcement for explorer
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#ifndef _EXP_PLUG_RULES_H_
+#define _EXP_PLUG_RULES_H_
+
+#include <fapi2.H>
+
+namespace mss
+{
+namespace exp
+{
+namespace plug_rule
+{
+
+///
+/// @brief Determine enterprise mode from given attribute/fuse values
+///
+/// @param[in] i_target OCMB chip target
+/// @param[in] i_enterprise_fuse enterprise as determined from fuse
+/// @param[in] i_enterprise_policy enterprise policy system attribute value
+/// @param[in] i_non_enterprise_override override attribute value
+/// @param[out] o_is_enterprise_mode resulting state for enterprise mode
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+/// @note this helper function exists for unit testing purposes
+///
+fapi2::ReturnCode enterprise_mode_helper(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const bool i_enterprise_fuse,
+ const uint8_t i_enterprise_policy,
+ const uint8_t i_non_enterprise_override,
+ bool& o_is_enterprise_mode);
+
+///
+/// @brief Gets whether the OCMB will be configred to enterprise mode, will assert out if policy/override do not agree
+/// @param[in] i_target OCMB target on which to operate
+/// @param[in] i_enterprise_fuse enterprise as determined from fuse
+/// @param[out] o_is_enterprise_mode true if the part is in enterprise mode
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+///
+fapi2::ReturnCode enterprise_mode(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const bool i_enterprise_fuse,
+ bool& o_is_enterprise_mode );
+
+} // plug_rule
+} // exp
+} // mss
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/pmic/exp_pmic_consts.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/pmic/exp_pmic_consts.H
deleted file mode 100644
index 497dd52ff..000000000
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/pmic/exp_pmic_consts.H
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/pmic/exp_pmic_consts.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_decoder.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_decoder.C
index eedfafe84..ea703b9e7 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_decoder.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_decoder.C
@@ -22,3 +22,285 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_decoder.C
+/// @brief Decode MRW attributes for DIMM power curves and power limits
+///
+// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#include <lib/shared/exp_defaults.H>
+// fapi2
+#include <fapi2.H>
+#include <vector>
+#include <utility>
+
+#include <lib/shared/exp_consts.H>
+#include <lib/power_thermal/exp_decoder.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/utils/dimm/kind.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+#include <generic/memory/lib/utils/power_thermal/gen_decoder.H>
+
+namespace mss
+{
+namespace power_thermal
+{
+
+const std::vector< std::pair<uint8_t , uint8_t> > throttle_traits<mss::mc_type::EXPLORER>::DIMM_TYPE_MAP =
+{
+ {fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_RDIMM, 0b00},
+ {fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_UDIMM, 0b01},
+ {fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_LRDIMM, 0b10},
+ {fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_DDIMM, 0b11},
+ {ANY_TYPE, 0b111}
+};
+
+///
+/// @brief Finds a value for the power curve slope attributes by matching the generated hashes
+/// @param[in] i_slope vector of generated key-values from MRW power curve attriutes
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+/// @note populates iv_vddr_slope, iv_total_slope
+///
+template<>
+fapi2::ReturnCode decoder<mss::mc_type::EXPLORER>::find_slope (
+ const std::vector< const std::vector<uint64_t>* >& i_slope)
+{
+ using TT = throttle_traits<mss::mc_type::EXPLORER>;
+
+ // For explorer, two attribute are used to get slope (i_slope[0], i_slope[1])
+ // ATTR_MSS_MRW_OCMB_PWR_SLOPE is for thermal power slope
+ // ATTR_MSS_MRW_OCMB_CURRENT_CURVE_WITH_LIMIT is for power slope
+ FAPI_ASSERT(i_slope.size() == 2,
+ fapi2::MSS_POWER_THERMAL_ATTR_VECTORS_INCORRECT()
+ .set_FUNCTION(SLOPE)
+ .set_INPUT_SIZE(i_slope.size())
+ .set_EXPECTED_SIZE(2),
+ "The attributes vectors size is incorrect for find_slope input:%d, expected:%d",
+ i_slope.size(),
+ 2);
+
+ // To get thermal power slope
+ FAPI_TRY( (get_power_thermal_value<TT::THERMAL_START, TT::THERMAL_LENGTH, SLOPE>(
+ *i_slope[0],
+ "ATTR_MSS_MRW_OCMB_PWR_SLOPE",
+ iv_total_slope)) );
+
+ // To get power slope
+ FAPI_TRY( (get_power_thermal_value<TT::POWER_SLOPE_START, TT::POWER_SLOPE_LENGTH, SLOPE>(
+ *i_slope[1],
+ "ATTR_MSS_MRW_OCMB_CURRENT_CURVE_WITH_LIMIT",
+ iv_vddr_slope)) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Finds a value for power curve intercept attributes by matching the generated hashes
+/// @param[in] i_intercept vector of generated key-values from MRW power curve attributes
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+/// @note populates iv_vddr_intercept, iv_total_intercept
+///
+template<>
+fapi2::ReturnCode decoder<mss::mc_type::EXPLORER>::find_intercept (
+ const std::vector< const std::vector<uint64_t>* >& i_intercept)
+{
+ using TT = throttle_traits<mss::mc_type::EXPLORER>;
+
+ // For explorer, two attribute are used to get slope (i_slope[0], i_slope[1])
+ // ATTR_MSS_MRW_OCMB_PWR_INTERCEPT is for thermal power intercept
+ // ATTR_MSS_MRW_OCMB_CURRENT_CURVE_WITH_LIMIT is for power intercept
+ FAPI_ASSERT(i_intercept.size() == 2,
+ fapi2::MSS_POWER_THERMAL_ATTR_VECTORS_INCORRECT()
+ .set_FUNCTION(INTERCEPT)
+ .set_INPUT_SIZE(i_intercept.size())
+ .set_EXPECTED_SIZE(2),
+ "The attributes vectors size is incorrect for find_intercept input:%d, expected:%d",
+ i_intercept.size(),
+ 2);
+
+ // To get thermal power intercept
+ FAPI_TRY( (get_power_thermal_value<TT::THERMAL_START, TT::THERMAL_LENGTH, INTERCEPT>(
+ *i_intercept[0],
+ "ATTR_MSS_MRW_OCMB_PWR_INTERCEPT",
+ iv_total_intercept)) );
+
+ // To get power intercept
+ FAPI_TRY( (get_power_thermal_value<TT::POWER_INTERCEPT_START, TT::POWER_INTERCEPT_LENGTH, INTERCEPT>(
+ *i_intercept[1],
+ "ATTR_MSS_MRW_OCMB_CURRENT_CURVE_WITH_LIMIT",
+ iv_vddr_intercept)) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Finds a value for the power limit attributes by matching the generated hashes
+/// @param[in] i_thermal_limits is a vector of the generated values from MRW power limit attributes
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+/// @note populates iv_thermal_power_limit, iv_power_limit
+///
+template<>
+fapi2::ReturnCode decoder<mss::mc_type::EXPLORER>::find_thermal_power_limit (
+ const std::vector< const std::vector<uint64_t>* >& i_thermal_limits)
+{
+ using TT = throttle_traits<mss::mc_type::EXPLORER>;
+
+ // For explorer, two attribute are used to get slope (i_slope[0], i_slope[1])
+ // ATTR_MSS_MRW_OCMB_THERMAL_MEMORY_POWER_LIMIT is for thermal power limit
+ // ATTR_MSS_MRW_OCMB_CURRENT_CURVE_WITH_LIMIT is for power limit
+ FAPI_ASSERT(i_thermal_limits.size() == 2,
+ fapi2::MSS_POWER_THERMAL_ATTR_VECTORS_INCORRECT()
+ .set_FUNCTION(INTERCEPT)
+ .set_INPUT_SIZE(i_thermal_limits.size())
+ .set_EXPECTED_SIZE(2),
+ "The attributes vectors size is incorrect for find_thermal_power_limit input:%d, expected:%d",
+ i_thermal_limits.size(),
+ 2);
+
+ // To get thermal power limit
+ FAPI_TRY( (get_power_thermal_value<TT::THERMAL_START, TT::THERMAL_LENGTH, POWER_LIMIT>(
+ *i_thermal_limits[0],
+ "ATTR_MSS_MRW_OCMB_THERMAL_MEMORY_POWER_LIMIT",
+ iv_thermal_power_limit)) );
+
+ // To get regulator power or current limit
+ FAPI_TRY( (get_power_thermal_value<TT::POWER_LIMIT_START, TT::POWER_LIMIT_LENGTH, POWER_LIMIT>(
+ *i_thermal_limits[1],
+ "ATTR_MSS_MRW_OCMB_CURRENT_CURVE_WITH_LIMIT",
+ iv_power_limit)) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief find the power curve attributes for each dimm on an MEM_PORT target
+/// @param[in] i_throttle_type specifies whether this is for power or thermal throttling
+/// @param[in] i_port vector of MEM_PORT targets on which dimm attrs will be set
+/// @param[in] i_slope vector of generated hashes for encoding the values for memory power curve slopes
+/// @param[in] i_intercept vector of generated hashes for encoding the values for memory power curve intercepts
+/// @param[in] i_thermal_power_limit vector of generated hashes for encoding the values for memory power limits
+/// @param[in] i_current_curve_with_limit vector of generated hashes for encoding the values for regulator power curves and limits
+/// @param[out] o_slope the power curve slope for each dimm
+/// @param[out] o_intercept the power curve intercept for each dimm
+/// @param[out] o_limit the power limit for the dimm
+/// @return FAPI2_RC_SUCCESS iff ok
+/// @note used to set power curve attributes in calling function
+/// @note decodes the attribute "encoding" to get the power curves and power limits for a dimm
+///
+fapi2::ReturnCode get_power_attrs (const mss::throttle_type i_throttle_type,
+ const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_port,
+ const std::vector< uint64_t >& i_slope,
+ const std::vector< uint64_t >& i_intercept,
+ const std::vector< uint64_t >& i_thermal_power_limit,
+ const std::vector< uint64_t >& i_current_curve_with_limit,
+ uint16_t o_slope [throttle_traits<>::DIMMS_PER_PORT],
+ uint16_t o_intercept [throttle_traits<>::DIMMS_PER_PORT],
+ uint32_t o_limit [throttle_traits<>::DIMMS_PER_PORT])
+{
+ using TT = throttle_traits<mss::mc_type::EXPLORER>;
+
+ for (const auto& l_dimm : find_targets <fapi2::TARGET_TYPE_DIMM> (i_port))
+ {
+ const auto l_dimm_pos = mss::index (l_dimm);
+ mss::dimm::kind<> l_kind (l_dimm);
+ mss::power_thermal::decoder<> l_decoder(l_kind);
+ fapi2::buffer<uint64_t> l_attr_value;
+
+ // DDIMMs mrw slope/intercept/limit attribute values are for whole DDIMM, so divide these by total number of virtual DIMMs
+ // to get it to a DIMM level. This will get the DIMM count to use in later calculations.
+ // ISDIMMs use a value of 1 since mrw attribute values are at the DIMM level
+ uint8_t l_number_dimm_for_attr_value = (l_kind.iv_dimm_type == fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_DDIMM) ?
+ mss::count_dimm(mss::find_target<fapi2::TARGET_TYPE_OCMB_CHIP>(l_dimm)) :
+ 1;
+
+ FAPI_TRY( l_decoder.generate_encoding(), "%s Error in get_power_attrs", mss::c_str(l_dimm) );
+
+ // The first entry into these arrays must be valid
+ // If we don't find any values, the attributes aren't found so go with some defaults
+ l_attr_value = i_slope[0];
+
+ if (i_slope.empty() || !l_attr_value.getBit<TT::POWER_LIMIT_START, TT::POWER_LENGTH>())
+ {
+ FAPI_INF("%s ATTR_MSS_MRW_OCMB_PWR_SLOPE not found or has zero values", mss::c_str(l_dimm));
+
+ o_slope[l_dimm_pos] =
+ ((i_throttle_type == mss::throttle_type::POWER) ? TT::POWER_SLOPE : TT::TOTAL_SLOPE) /
+ l_number_dimm_for_attr_value;
+ }
+ else
+ {
+ const std::vector< const std::vector<uint64_t>* > l_slope {&i_slope, &i_current_curve_with_limit};
+
+ FAPI_TRY( l_decoder.find_slope(l_slope), "%s Error in get_power_attrs", mss::c_str(l_dimm) );
+
+ o_slope[l_dimm_pos] =
+ ((i_throttle_type == mss::throttle_type::POWER) ? l_decoder.iv_vddr_slope : l_decoder.iv_total_slope) /
+ l_number_dimm_for_attr_value;
+ }
+
+ l_attr_value = i_intercept[0];
+
+ if (i_intercept.empty() || !l_attr_value.getBit<TT::POWER_LIMIT_START, TT::POWER_LENGTH>())
+ {
+ FAPI_INF("%s ATTR_MSS_MRW_OCMB_PWR_INTERCEPT not found or has zero values", mss::c_str(l_dimm));
+
+ o_intercept[l_dimm_pos] =
+ ((i_throttle_type == mss::throttle_type::POWER) ? TT::POWER_INT : TT::TOTAL_INT) /
+ l_number_dimm_for_attr_value;
+ }
+ else
+ {
+ const std::vector< const std::vector<uint64_t>* > l_intercept {&i_intercept, &i_current_curve_with_limit};
+
+ FAPI_TRY( l_decoder.find_intercept(l_intercept), "%s Error in get_power_attrs", mss::c_str(l_dimm) );
+
+ o_intercept[l_dimm_pos] =
+ ((i_throttle_type == mss::throttle_type::POWER) ? l_decoder.iv_vddr_intercept : l_decoder.iv_total_intercept) /
+ l_number_dimm_for_attr_value;
+ }
+
+ l_attr_value = i_thermal_power_limit[0];
+
+ if (i_thermal_power_limit.empty() || !l_attr_value.getBit<TT::THERMAL_START, TT::THERMAL_LENGTH>())
+ {
+ FAPI_INF("%s ATTR_MSS_MRW_OCMB_THERMAL_MEMORY_POWER_LIMIT not found or has zero values", mss::c_str(l_dimm));
+
+ // The unit of limit and intercept is cA but limit is dA in mss::throttle_type::POWER
+ // So we need to transfer them to the same unit
+ o_limit[l_dimm_pos] =
+ ((i_throttle_type == mss::throttle_type::POWER) ? TT::POWER_LIMIT* DECI_TO_CENTI : TT::THERMAL_LIMIT) /
+ l_number_dimm_for_attr_value;
+ }
+ else
+ {
+ std::vector< const std::vector<uint64_t>* > l_thermal_power_limit {&i_thermal_power_limit, &i_current_curve_with_limit};
+
+ FAPI_TRY( l_decoder.find_thermal_power_limit(l_thermal_power_limit),
+ "%s Error in get_power_attrs", mss::c_str(l_dimm) );
+ // The unit of limit and intercept is cA but limit is dA in mss::throttle_type::POWER
+ // So we need to transfer them to the same unit
+ o_limit[l_dimm_pos] =
+ ((i_throttle_type == mss::throttle_type::POWER) ?
+ l_decoder.iv_power_limit* DECI_TO_CENTI : l_decoder.iv_thermal_power_limit
+ ) /
+ l_number_dimm_for_attr_value;
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} //ns power_thermal
+} // ns mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_decoder.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_decoder.H
index 3ce2f3ed3..9f49ee70f 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_decoder.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_decoder.H
@@ -22,3 +22,61 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_decoder.H
+/// @brief Decoder for ATTR_MSS_MRW_PWR_CURVE_SLOPE and _INTERCEPT and THERMAL_POWER_LIMIT
+///
+// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_POWER_EXP_DECODER__
+#define _MSS_POWER_EXP_DECODER__
+
+#include <fapi2.H>
+
+#include <lib/shared/exp_consts.H>
+#include <generic/memory/lib/utils/dimm/kind.H>
+#include <lib/power_thermal/exp_throttle.H>
+#include <generic/memory/lib/utils/power_thermal/gen_decoder.H>
+
+
+namespace mss
+{
+
+namespace power_thermal
+{
+
+
+///
+/// @brief find the power curve attributes for each dimm on an MCS target
+/// @param[in] i_targets vector of MCS targets on which dimm attrs will be set
+/// @param[in] i_slope vector of generated hashes for encoding and values for MSS_MRW_POWER_SLOPE
+/// @param[in] i_intercept vector of generated hashes for encoding and values for MSS_MRW_POWER_INTERCEPT
+/// @param[in] i_thermal_power_limit vector of generated hashes for encoding and values for MSS_MRW_THERMAL_MEMORY_POWER_LIMIT
+/// @param[out] o_vddr_slope the VDDR power curve slope for each dimm
+/// @param[out] o_vddr_int the VDDR power curve intercept for each dimm
+/// @param[out] o_total_slope the VDDR+VPP power curve slope for each dimm
+/// @param[out] o_total_int the VDDR+VPP power curve intercept for each dimm
+/// @param[out] o_thermal_power the thermal power limit for the dimm
+/// @return FAPI2_RC_SUCCESS iff ok
+/// @note used to set power curve attributes in calling function
+/// @note decodes the attribute "encoding" to get the vddr and vddr/vpp power curves for a dimm
+///
+fapi2::ReturnCode get_power_attrs (const mss::throttle_type i_throttle_type,
+ const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_port,
+ const std::vector< uint64_t >& i_slope,
+ const std::vector< uint64_t >& i_intercept,
+ const std::vector< uint64_t >& i_thermal_power_limit,
+ const std::vector< uint64_t >& i_current_curve_with_limit,
+ uint16_t o_slope [throttle_traits<>::DIMMS_PER_PORT],
+ uint16_t o_intercept [throttle_traits<>::DIMMS_PER_PORT],
+ uint32_t o_limit [throttle_traits<>::DIMMS_PER_PORT]);
+
+
+} // power_thermal
+} // mss
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle.C
index b3114480e..9c3a484f4 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,129 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_throttle.C
+/// @brief Determine throttle settings for memory
+///
+// *HWP HWP Owner: Andre A. Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#include <lib/shared/exp_defaults.H>
+// fapi2
+#include <fapi2.H>
+
+#include <lib/shared/exp_consts.H>
+#include <lib/power_thermal/exp_throttle.H>
+#include <mss_explorer_attribute_getters.H>
+#include <mss_explorer_attribute_setters.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+
+namespace mss
+{
+namespace power_thermal
+{
+///
+/// @brief Calcuate the throttle values based on throttle type
+/// @param[in] i_target
+/// @param[in] i_throttle_type thermal boolean to determine whether to calculate throttles based on the power regulator or thermal limits
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Called in p9_mss_bulk_pwr_throttles
+/// @note determines the throttle levels based off of the port's power curve,
+/// sets the slot throttles to the same
+/// @note Enums are POWER for power egulator throttles and THERMAL for thermal throttles
+/// @note equalizes the throttles to the lowest of runtime and the lowest slot-throttle value
+///
+fapi2::ReturnCode pwr_throttles( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const mss::throttle_type i_throttle_type)
+{
+ if (mss::count_dimm (i_target) == 0)
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ uint16_t l_slot = 0;
+ uint16_t l_port = 0;
+ uint32_t l_power = 0;
+
+ for (const auto& l_port_target : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
+ {
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ //Don't run if there are no dimms on the port
+ if (mss::count_dimm(l_port_target) == 0)
+ {
+ continue;
+ }
+
+ mss::power_thermal::throttle<> l_pwr_struct(l_port_target, l_rc);
+ FAPI_TRY(l_rc, "Error constructing mss:power_thermal::throttle object for target %s",
+ mss::c_str(l_port_target));
+
+ //Let's do the actual work now
+ if ( i_throttle_type == mss::throttle_type::THERMAL)
+ {
+ FAPI_TRY (l_pwr_struct.thermal_throttles());
+ }
+ else
+ {
+ FAPI_TRY (l_pwr_struct.power_regulator_throttles());
+ }
+
+ l_slot = l_pwr_struct.iv_n_slot;
+ l_port = l_pwr_struct.iv_n_port;
+ l_power = l_pwr_struct.iv_calc_port_maxpower;
+
+ FAPI_INF("For target %s Calculated power is %d, throttle per slot is %d, throttle per port is %d",
+ mss::c_str(l_port_target), l_power, l_slot, l_port);
+
+ FAPI_TRY(mss::attr::set_port_maxpower( l_port_target, l_power));
+ FAPI_TRY(mss::attr::set_mem_throttled_n_commands_per_slot( l_port_target, l_slot));
+ FAPI_TRY(mss::attr::set_mem_throttled_n_commands_per_port( l_port_target, l_port));
+ }
+
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("Error calculating pwr_throttles using %s throttling",
+ ((i_throttle_type == mss::throttle_type::POWER) ? "power" : "thermal"));
+ return fapi2::current_err;
+}
+
+///
+/// @brief Equalize the throttles among OCMB chips
+/// @param[in] i_targets vector of OCMB chips
+/// @param[in] i_throttle_type thermal boolean to determine whether to calculate throttles based on the power regulator or thermal limits
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note equalizes the throttles to the lowest of runtime and the lowest slot-throttle value
+///
+fapi2::ReturnCode equalize_throttles( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> >& i_targets,
+ const mss::throttle_type i_throttle_type)
+{
+ std::vector< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> > l_exceeded_power;
+
+ // Set all of the throttles to the lowest value per port for performance reasons
+ FAPI_TRY(mss::power_thermal::equalize_throttles(i_targets, i_throttle_type, l_exceeded_power));
+
+ // Report any port that exceeded the max power limit, and return a failing RC if we have any
+ for (const auto& l_port : l_exceeded_power)
+ {
+ FAPI_ERR(" MEM_PORT %s estimated power exceeded the maximum allowed", mss::c_str(l_port) );
+ fapi2::current_err = fapi2::FAPI2_RC_FALSE;
+ }
+
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("Error calculating equalize_throttles using %s throttling",
+ ((i_throttle_type == mss::throttle_type::POWER) ? "power" : "thermal"));
+ return fapi2::current_err;
+}
+
+
+
+}//namespace power_thermal
+}//namespace mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle.H
index 83559db83..17f8a7dbc 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle.H
@@ -22,3 +22,61 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_throttle.H
+/// @brief throttle API
+///
+
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_EXP_THROTTLE_
+#define _MSS_EXP_THROTTLE_
+
+#include <fapi2.H>
+#include <lib/shared/exp_consts.H>
+#include <lib/power_thermal/exp_throttle.H>
+#include <mss_explorer_attribute_setters.H>
+#include <mss_explorer_attribute_getters.H>
+#include <lib/power_thermal/exp_throttle_traits.H>
+#include <generic/memory/lib/utils/dimm/kind.H>
+#include <generic/memory/lib/utils/power_thermal/gen_throttle.H>
+
+namespace mss
+{
+namespace power_thermal
+{
+
+///
+/// @brief Set ATTR_EXP_PORT_MAXPOWER, ATTR_OCMB_EXP_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
+/// ATTR_EXP_MEM_THROTTLED_N_COMMANDS_PER_PORT
+/// @param[in] i_target
+/// @param[in] i_throttle_type thermal boolean to determine whether to calculate throttles based on the power regulator or thermal limits
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Called in p9_mss_bulk_pwr_throttles
+/// @note determines the throttle levels based off of the port's power curve,
+/// sets the slot throttles to the same
+/// @note Enums are POWER for power egulator throttles and THERMAL for thermal throttles
+/// @note equalizes the throttles to the lowest of runtime and the lowest slot-throttle value
+///
+fapi2::ReturnCode pwr_throttles( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const mss::throttle_type i_throttle_type);
+
+///
+/// @brief Equalize the throttles among OCMB chips
+/// @param[in] i_targets vector of OCMB chips
+/// @param[in] i_throttle_type thermal boolean to determine whether to calculate throttles based on the power regulator or thermal limits
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note equalizes the throttles to the lowest of runtime and the lowest slot-throttle value
+///
+fapi2::ReturnCode equalize_throttles( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> >& i_targets,
+ const mss::throttle_type i_throttle_type);
+
+}//power_thermal
+}// mss
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle_traits.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle_traits.H
index 1c8945f89..0b0d06572 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle_traits.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/power_thermal/exp_throttle_traits.H
@@ -22,3 +22,147 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_throttle_traits.H
+/// @brief throttle API
+///
+
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_EXP_THROTTLE_TRAITS_
+#define _MSS_EXP_THROTTLE_TRAITS_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/power_thermal/gen_throttle_traits.H>
+
+namespace mss
+{
+namespace power_thermal
+{
+
+///
+/// @class Traits and policy class for throttle code - specialization for the Explorer mc type
+///
+template<>
+class throttle_traits<mss::mc_type::EXPLORER>
+{
+ public:
+ //////////////////////////////////////////////////////////////
+ // Target types
+ //////////////////////////////////////////////////////////////
+ static constexpr fapi2::TargetType MC_TARGET_TYPE = fapi2::TARGET_TYPE_OCMB_CHIP;
+ static constexpr fapi2::TargetType PORT_TARGET_TYPE = fapi2::TARGET_TYPE_MEM_PORT;
+
+ //////////////////////////////////////////////////////////////
+ // Traits values
+ //////////////////////////////////////////////////////////////
+ // MIN_UTIL is in c%
+ static const uint64_t MIN_UTIL = 2500;
+ // IDLE_UTIL is in c%
+ static const uint64_t IDLE_UTIL = 0;
+ // Minimum throttle allowed for the port and or slot. If we set to 0, we brick the port
+ static const uint64_t MIN_THROTTLE = 1;
+
+ enum size_of_attrs : size_t
+ {
+ // Thermal power (OCMB+DRAM)
+ SIZE_OF_THERMAL_LIMIT_ATTR = 25,
+ SIZE_OF_THERMAL_SLOPE_ATTR = 50,
+ SIZE_OF_THERMAL_INTERCEPT_ATTR = 50,
+
+ // Power (PMIC)
+ SIZE_OF_CURRENT_CURVE_WITH_LIMIT_ATTR = 25,
+ };
+
+ enum default_power
+ {
+ //Values are the worst case defaults for power curves
+ //They are the default/ catch-all values from the power curve attributes
+ //Shouldn't be used if system is set up correctly and attributes are available
+ //This will throttle the DIMMs to ~76% dram data bus utilization
+ //(using the mrw regulator current limit of 100 dA cW and thermal power limit here of 2175 cW).
+ // Thermal power (OCMB+DRAM)
+ TOTAL_SLOPE = 0x462,
+ TOTAL_INT = 0x526,
+ THERMAL_LIMIT = 0x87F,
+
+ // Power (PMIC)
+ POWER_SLOPE = 0x152,
+ POWER_INT = 0x94,
+ POWER_LIMIT = 0x64,
+
+ };
+
+ enum
+ {
+ PORTS_PER_MC = 1,
+ DIMMS_PER_PORT = 2,
+ };
+
+ //Bit positions for different section of the attribute
+ //first 32 bits are the encoding, second are for values
+ enum DECODE_BUFFER_POS
+ {
+ ENCODING_START = 0,
+ ENCODING_LENGTH = 32,
+
+ // Thermal total power (OCMB+DRAM)
+ THERMAL_START = 32,
+ THERMAL_LENGTH = 16,
+
+ // Current power (PMIC)
+ POWER_LIMIT_START = 32,
+ POWER_LIMIT_LENGTH = 8,
+ POWER_SLOPE_START = 40,
+ POWER_SLOPE_LENGTH = 12,
+ POWER_INTERCEPT_START = 52,
+ POWER_INTERCEPT_LENGTH = 12,
+ POWER_LENGTH = 32,
+ };
+
+ //Positions and lengths of the encodings
+ enum ATTR_DECODE_INFO
+ {
+ DIMM_SIZE_START = 0,
+ DIMM_SIZE_LEN = 4,
+
+ DRAM_GEN_START = 4,
+ DRAM_GEN_LEN = 2,
+
+ DIMM_TYPE_START = 6,
+ DIMM_TYPE_LEN = 3,
+
+ DRAM_WIDTH_START = 9,
+ DRAM_WIDTH_LEN = 3,
+
+ DRAM_DENSITY_START = 12,
+ DRAM_DENSITY_LEN = 3,
+
+ DRAM_STACK_TYPE_START = 15,
+ DRAM_STACK_TYPE_LEN = 2,
+
+ DRAM_MFGID_START = 17,
+ DRAM_MFGID_LEN = 3,
+
+ DIMM_MODULE_HEIGHT_START = 20,
+ DIMM_MODULE_HEIGHT_LEN = 2,
+
+ // Invalid for Explorer but compile will fail without them
+ DIMMS_PER_PORT_START = 0,
+ DIMMS_PER_PORT_LEN = 1,
+ };
+
+ // Definition is in chip folder
+ static const std::vector< std::pair<uint8_t , uint8_t> > DIMM_TYPE_MAP;
+
+};
+}//power_thermal
+}// mss
+
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_consts.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_consts.H
index c55d2d4d5..9051c946a 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_consts.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_consts.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,7 +36,9 @@
#ifndef MSS_EXP_CONSTS_H
#define MSS_EXP_CONSTS_H
-#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#ifndef __PPE__
+ #include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#endif
namespace mss
{
@@ -46,10 +48,54 @@ namespace exp
constexpr uint32_t OCMB_ADDR_SHIFT = 3;
+#ifndef __PPE__
+///
+/// @brief enum list for the indexes for the address delays
+/// @note Taken from 07-MAY-19 firwmare document
+///
+enum attr_delay_index
+{
+ ODT1 = 0,
+ ODT0 = 0,
+ CS_N0 = 0,
+ CS_N1 = 0,
+ ADDR13 = 1,
+ ADDR5 = 1,
+ BG0 = 1,
+ CKE1 = 1,
+ ADDR17 = 2,
+ ADDR7 = 2,
+ BA0 = 2,
+ ADDR16 = 2,
+ ADDR8 = 3,
+ BG1 = 3,
+ CID1 = 3,
+ CID0 = 3,
+ ADDR1 = 4,
+ ADDR9 = 4,
+ ADDR2 = 4,
+ CAPARITY = 4,
+ ADDR12 = 5,
+ ADDR3 = 5,
+ ADDR4 = 5,
+ ADDR0 = 5,
+ CKE0 = 6,
+ ADDR15 = 6,
+ ACT_N = 6,
+ ADDR10 = 6,
+ ADDR11 = 7,
+ ADDR6 = 7,
+ BA1 = 7,
+ ADDR14 = 7,
+};
+
///
-/// @brief enum list of explorer eff attributes to set
+/// @brief enum list of explorer SPD derived attributes to set
+/// @note these attrs are strictly derived from SPD
+/// @warning wrapped in exp namesapce to be distinguished from
+/// the exp::attr_eff_engine_fields
///
-enum attr_eff_engine_fields
+enum class attr_eff_engine_fields
{
// Template recursive base case
ATTR_EFF_BASE_CASE = 0,
@@ -63,11 +109,11 @@ enum attr_eff_engine_fields
TSV_8H_SUPPORT = 6,
PSTATES = 7,
MRAM_SUPPORT = 8,
- HEIGHT_3DS = 9,
- SPD_CL_SUPPORTED = 10,
+ SPD_CL_SUPPORTED = 9,
+ ADDRESS_MIRROR = 10,
// Dispatcher set to last enum value
- ATTR_EFF_DISPATCHER = SPD_CL_SUPPORTED,
+ DISPATCHER = ADDRESS_MIRROR,
};
///
@@ -75,11 +121,19 @@ enum attr_eff_engine_fields
///
enum sizes
{
+ MAX_PORT_PER_OCMB = 1,
MAX_DIMM_PER_PORT = 2,
MAX_RANK_PER_DIMM = 4,
- MAX_BITS_PER_PORT = 80,
+ MAX_DQ_BITS_PER_PORT = 80,
+ MAX_SYMBOLS_PER_PORT = 72,
+ MAX_RANKS_DIMM1 = 2,
+ MAX_MRANK_PER_PORT = MAX_DIMM_PER_PORT * MAX_RANK_PER_DIMM,
+ MAX_BYTES_PER_PORT = MAX_DQ_BITS_PER_PORT / BITS_PER_BYTE,
+ MAX_NIBBLES_PER_PORT = MAX_DQ_BITS_PER_PORT / BITS_PER_NIBBLE,
};
+#endif
+
///
/// @brief explorer ffdc codes
///
@@ -92,6 +146,7 @@ enum ffdc_codes
READ_CRCT_ENDIAN = 0x0005,
READ_TRAINING_RESPONSE_STRUCT = 0x0006,
+ SET_EXP_DRAM_ADDRESS_MIRRORING = 0x1040,
SET_BYTE_ENABLES = 0x1041,
SET_NIBBLE_ENABLES = 0x1042,
SET_TAA_MIN = 0x1043,
@@ -101,8 +156,8 @@ enum ffdc_codes
SET_VREF_DQ_TRAIN_RANGE = 0x1047,
SET_PSTATES = 0x1048,
SET_MRAM_SUPPORT = 0x1049,
- SET_3DS_HEIGHT = 0x1050,
- SET_SPD_CL_SUPPORTED = 0x1051,
+ SET_SPD_CL_SUPPORTED = 0x1050,
+ SET_SERDES_FREQ = 0x1051,
};
///
@@ -114,25 +169,70 @@ enum ecid_consts
DATA_IN_SIZE = 16,
// TK - Will need to be changed once ATTR_ECID is made larger
ATTR_ECID_SIZE = 2,
- // 32 bit registers with getScom/putScom use the right-most 32 bits
- REG_BIT_OFFSET = 32,
+};
+
+///
+/// @brief constants for getidec procedure
+///
+enum idec_consts
+{
+ EXPLR_CHIP_INFO_REG = 0x2134,
+ LOCATION_BIT_START = 44,
+ LOCATION_BIT_LENGTH = 4,
+ CHIPID_BIT_START = 56,
+ CHIPID_BIT_LENGTH = 8,
+
+ REVISION_BIT_START = 50,
+ REVISION_BIT_LENGTH = 4,
+};
+
+
+
+///
+/// @brief generic explorer constants
+///
+enum generic_consts
+{
+ // Number of DRAM for x4 vs x8
+ EXP_NUM_DRAM_X4 = 20,
+ EXP_NUM_DRAM_X8 = 10,
};
namespace i2c
{
+///
/// @brief List of explorer I2C commands
///
enum cmd_id : uint8_t
{
- FW_BOOT_CONFIG = 0x01,
- FW_STATUS = 0x02,
- FW_REG_ADDR_LATCH = 0x03,
- FW_REG_READ = 0x04,
- FW_REG_WRITE = 0x05,
- FW_DOWNLOAD = 0x06,
- FW_CONT_REG_READ = 0x07,
- FW_CONT_REG_WRITE = 0x08,
+ FW_BOOT_CONFIG = 0x01,
+ FW_STATUS = 0x02,
+ FW_REG_ADDR_LATCH = 0x03,
+ FW_REG_READ = 0x04,
+ FW_REG_WRITE = 0x05,
+ FW_DOWNLOAD = 0x06,
+ FW_CONT_REG_READ = 0x07,
+ FW_CONT_REG_WRITE = 0x08,
+ FW_BYPASS_4SEC_TIMEOUT = 0x09,
+ FW_PQM_LANE_SET = 0x0A,
+ FW_PQM_LANE_GET = 0x0B,
+ FW_PQM_FREQ_SET = 0x0C,
+ FW_PQM_FREQ_GET = 0x0D,
+ FW_PQM_LANE_TRAINING = 0x0E,
+ FW_PQM_TRAINING_RESET = 0x0F,
+ FW_PQM_RX_ADAPTATION_OBJ_READ = 0x10,
+ FW_PQM_RX_CALIBRATION_VALUE_READ = 0x11,
+ FW_PQM_CSU_CALIBRATION_VALUE_STATUS_READ = 0x12,
+ FW_PQM_PRBS_PATTERN_MODE_SET = 0x13,
+ FW_PQM_PRBS_USER_DEFINED_PATTERN_SET = 0x14,
+ FW_PQM_PRBS_MONITOR_CONTROL = 0x15,
+ FW_PQM_PRBS_GENERATOR_CONTROL = 0x16,
+ FW_PQM_PRBS_ERR_COUNT_READ = 0x17,
+ FW_PQM_HORIZONTAL_BATHTUB_GET = 0x18,
+ FW_PQM_VERTICAL_BATHTUB_GET = 0x19,
+ FW_PQM_2D_BATHTUB_GET = 0x1A,
+ EXP_FW_PQM_FORCE_DELAY_LINE_UPDATE = 0x22,
};
///
@@ -163,8 +263,10 @@ enum status_codes
SUCCESS = 0x00,
ADDRESS_OUT_OF_RANGE = 0x01,
ADDRESS_PROHIBITED = 0x02,
+ FW_BUSY = 0xFE,
};
+#ifndef __PPE__
///
/// @brief status codes for FW_BOOT_CONFIG
///
@@ -182,6 +284,7 @@ enum fw_boot_cfg_status
FW_BOOT_CFG_UNSUPPORTED_SERDES_FREQ = 0x04,
};
+#endif
///
/// @brief I2C boot stage options
/// @note certain cmds work in certain boot stages
@@ -229,9 +332,9 @@ enum addrSide
RHS = 0x01
};
-
}// i2c
+#ifndef __PPE__
namespace omi
{
@@ -249,10 +352,10 @@ enum cmd_and_response_id
EXP_FW_DDR_PHY_INIT = 0x02,
// read temperature sensor
- EXP_FW_FW_TEMP_SENSOR_PASS_THROUGH_READ = 0x03,
+ EXP_FW_TEMP_SENSOR_PASS_THROUGH_READ = 0x03,
// configure temperature sensor
- EXP_FW_FW_TEMP_SENSOR_PASS_THROUGH_WRITE = 0x04,
+ EXP_FW_TEMP_SENSOR_PASS_THROUGH_WRITE = 0x04,
// configure interval read mechanism
EXP_FW_TEMP_SENSOR_CONFIG_INTERVAL_READ = 0x05,
@@ -272,8 +375,17 @@ enum cmd_and_response_id
// find the flash loader version information
EXP_FW_FLASH_LOADER_VERSION_INFO = 0x09,
- // read the error logs from various modules of Explorer block
- EXP_FW_ERROR_LOG_GET = 0x0A,
+ // read the FW logs from various modules of Explorer block
+ EXP_FW_LOG = 0x0A,
+};
+
+///
+/// @brief Command flag definitions
+///
+enum cmd_flags
+{
+ NO_FLAGS = 0,
+ ADDITIONAL_DATA = 1,
};
///
@@ -286,6 +398,7 @@ enum response_arg
};
}// omi
+#endif
}// exp
}// mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_defaults.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_defaults.H
index 999e93425..d4bfd3387 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_defaults.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_defaults.H
@@ -25,7 +25,7 @@
///
/// @file exp_defaults.H
-/// @brief default types associated with Nimbus system
+/// @brief default types associated with Explorer system
///
// *HWP HWP Owner: Andre A. Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
@@ -33,15 +33,18 @@
// *HWP Level: 2
// *HWP Consumed by: CI
-#ifndef _MSS_NIMBUS_DEFAULTS_H_
-#define _MSS_NIMBUS_DEFAULTS_H_
+#ifndef _MSS_EXPLORER_DEFAULTS_H_
+#define _MSS_EXPLORER_DEFAULTS_H_
+#include <fapi2.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
namespace mss
{
constexpr mss::mc_type DEFAULT_MC_TYPE = mss::mc_type::EXPLORER;
+constexpr fapi2::TargetType DEFAULT_MC_TARGET = fapi2::TARGET_TYPE_OCMB_CHIP;
+constexpr fapi2::TargetType DEFAULT_MEM_PORT_TARGET = fapi2::TARGET_TYPE_MEM_PORT;
} // ns mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/explorer_pos.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/explorer_pos.C
index 9d1393cb4..9803640c0 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/explorer_pos.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/explorer_pos.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,7 +39,6 @@ namespace mss
{
///
-///
/// @brief Return a DIMM's relative position from a port
/// @param[in] i_target a target representing the target in question
/// @return The position relative to chiplet R
@@ -90,4 +89,18 @@ relative_pos<fapi2::TARGET_TYPE_MEM_PORT>(const fapi2::Target<fapi2::TARGET_TYPE
return 0;
}
+///
+/// @brief Return a mem_port's relative position from a proc_chip
+/// @param[in] i_target a target representing the target in question
+/// @return The position relative to chiplet R
+///
+template<>
+posTraits<fapi2::TARGET_TYPE_MEM_PORT>::pos_type
+relative_pos<fapi2::TARGET_TYPE_PROC_CHIP>(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target)
+{
+ typedef mcTypeTraits<mc_type::EXPLORER> TT;
+ return fapi_pos(i_target) % (TT::PORTS_PER_OCMB * TT::OCMB_PER_OMI * TT::OMI_PER_MCC * TT::MCC_PER_MI * TT::MI_PER_MC *
+ TT::MC_PER_PROC);
+}
+
}// mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/mss_exp_conversions.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/mss_exp_conversions.H
index 85347c950..44df49cde 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/mss_exp_conversions.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/mss_exp_conversions.H
@@ -22,3 +22,192 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file mss_exp_conversions.H
+/// @brief Functions to convert units
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_EXPLORER_CONVERSIONS_H_
+#define _MSS_EXPLORER_CONVERSIONS_H_
+
+#include <mss_generic_attribute_getters.H>
+#include <generic/memory/lib/utils/conversions.H>
+#include <generic/memory/lib/utils/find.H>
+
+namespace mss
+{
+
+///
+/// @brief Return the number of cycles contained in a count of picoseconds
+/// @tparam T the target type from which to get the mt/s
+/// @tparam OT the output type, derrived from the parameters
+/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_ps the number of picoseconds to convert
+/// @return uint64_t, the number of cycles
+///
+template< fapi2::TargetType T, typename OT >
+inline OT ps_to_cycles(const fapi2::Target<T>& i_target, const OT i_ps)
+{
+ // The frequency in MT/s
+ uint64_t l_freq = 0;
+ uint64_t l_clock_period = 0;
+
+ // Each OCMB only has one MEM_PORT
+ for (const auto l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
+ {
+ FAPI_TRY(attr::get_freq(l_port, l_freq));
+ }
+
+ // No time if MT/s is 0 (well, infinite really but shut up)
+ if (l_freq == 0)
+ {
+ return 0;
+ }
+
+ // Hoping the compiler figures out how to do these together.
+ FAPI_TRY( freq_to_ps(l_freq, l_clock_period) );
+
+ return ps_to_cycles( l_clock_period, i_ps );
+
+fapi_try_exit:
+ // We simply can't work if we can't get the frequency or
+ // if we get an unsupported value that can't be converted to a valid tCK (clock period)
+ // ...so this should be ok
+ FAPI_ERR("Can't get MSS_FREQ or obtained an invalid MSS_FREQ (%d) - stopping", l_freq);
+ fapi2::Assert(false);
+
+ // Keeps compiler happy
+ return 0;
+}
+
+///
+/// @brief Return the number of ps contained in a count of cycles
+/// @tparam T the target type from which to get the mt/s
+/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_cycles the number of cycles to convert
+/// @return uint64_t, the number of picoseconds
+///
+template< fapi2::TargetType T >
+inline uint64_t cycles_to_ps(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
+{
+ // The frequency in MHZ
+ uint64_t l_freq = 0;
+ uint64_t l_clock_period = 0;
+
+ // Each OCMB only has one MEM_PORT
+ for (const auto l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
+ {
+ FAPI_TRY(attr::get_freq(l_port, l_freq));
+ }
+
+ FAPI_TRY( freq_to_ps(l_freq, l_clock_period) );
+ return cycles_to_ps(l_clock_period, i_cycles);
+
+fapi_try_exit:
+
+ // We simply can't work if we can't get the frequency or
+ // if we get an unsupported value that can't be converted to a valid tCK (clock period)
+ // ...so this should be ok
+ FAPI_ERR("Can't get MSS_FREQ or obtained an invalid MSS_FREQ (%d) - stopping", l_freq);
+ fapi2::Assert(false);
+
+ // Keeps compiler happy
+ return 0;
+}
+
+///
+/// @brief Return the number of cycles contained in a count of microseconds
+/// @tparam T the target type from which to get the mt/s
+/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_us the number of microseconds to convert
+/// @return uint64_t, the number of cycles
+///
+template< fapi2::TargetType T >
+inline uint64_t us_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_us)
+{
+ return ps_to_cycles(i_target, i_us * CONVERT_PS_IN_A_US);
+}
+
+///
+/// @brief Return the number of cycles contained in a count of nanoseconds
+/// @tparam T the target type from which to get the mt/s
+/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_ps the number of nanoseconds to convert
+/// @return uint64_t, the number of cycles
+///
+template< fapi2::TargetType T >
+inline uint64_t ns_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_ns)
+{
+ return ps_to_cycles(i_target, i_ns * CONVERT_PS_IN_A_NS);
+}
+
+///
+/// @brief Return the amount of unit time contained in a count of cycles
+/// @tparam T the target type from which to get the mt/s
+/// @tparam D the time conversion (NS_IN_PS, etc)
+/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_cycles the number of cycles to convert
+/// @return uint64_t, the number of microseconds
+///
+template< uint64_t D, fapi2::TargetType T >
+inline uint64_t cycles_to_time(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
+{
+ // Hoping the compiler figures out how to do these together.
+ uint64_t l_dividend = cycles_to_ps(i_target, i_cycles);
+ uint64_t l_quotient = l_dividend / ((D == 0) ? 1 : D);
+ uint64_t l_remainder = l_dividend % ((D == 0) ? 1 : D);
+
+ // Make sure we add time if there wasn't an even number of cycles
+ return l_quotient + (l_remainder == 0 ? 0 : 1);
+}
+
+///
+/// @brief Return the number of nanoseconds contained in a count of cycles
+/// @tparam T the target type from which to get the mt/s
+/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_cycles the number of cycles to convert
+/// @return uint64_t, the number of nanoseconds
+///
+template< fapi2::TargetType T >
+inline uint64_t cycles_to_ns(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
+{
+ uint64_t l_ns = cycles_to_time<CONVERT_PS_IN_A_NS>(i_target, i_cycles);
+ return l_ns;
+}
+
+///
+/// @brief Return the number of microseconds contained in a count of cycles
+/// @tparam T the target type from which to get the mt/s
+/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_cycles the number of cycles to convert
+/// @return uint64_t, the number of microseconds
+///
+template< fapi2::TargetType T >
+inline uint64_t cycles_to_us(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
+{
+ uint64_t l_us = cycles_to_time<CONVERT_PS_IN_A_US>(i_target, i_cycles);
+ return l_us;
+}
+
+///
+/// @brief Return the maximum of two values *in clocks*, the first in clocks the second in ns
+/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
+/// @param[in] i_target
+/// @param[in] i_clocks a value in clocks
+/// @param[in] i_time a value in nanoseconds
+/// @return max( iclocks nCK, i_time ) in clocks
+///
+template< fapi2::TargetType T >
+inline uint64_t max_ck_ns(const fapi2::Target<T>& i_target, const uint64_t i_clocks, const uint64_t i_time)
+{
+ return std::max( i_clocks, ns_to_cycles(i_target, i_time) );
+}
+
+} // ns mss
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.C
new file mode 100644
index 000000000..eae18dd1f
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.C
@@ -0,0 +1,201 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_omi_workarounds.C
+/// @brief Workarounds for exp_omi_* procedures
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: Memory
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/find.H>
+#include <lib/workarounds/exp_omi_workarounds.H>
+#include <lib/shared/exp_consts.H>
+#include <lib/omi/exp_omi_utils.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
+#include <generic/memory/lib/mss_generic_system_attribute_getters.H>
+#include <lib/inband/exp_inband.H>
+#include <exp_oc_regs.H>
+
+namespace mss
+{
+namespace exp
+{
+namespace workarounds
+{
+namespace omi
+{
+
+///
+/// @brief Determine if the OCMB is an explorer
+///
+/// @param[in] i_ocmb_chip OCMB chip
+/// @param[out] o_explorer true/false is explorer
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+/// @note Used for exp_omi_train procedure to differentiate fw_status behavior with gemini
+///
+fapi2::ReturnCode ocmb_is_explorer(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_chip, bool& o_explorer)
+{
+ uint8_t l_name = 0;
+ FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, i_ocmb_chip, l_name));
+
+ o_explorer = (l_name == fapi2::ENUM_ATTR_NAME_EXPLORER);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+///
+/// @brief Set configurable delay based on the PRBS ATTR and SIM mode
+///
+/// @param[in] i_ocmb_chip OCMB target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode prbs_delay(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_chip)
+{
+ uint8_t l_sim = 0;
+ uint32_t l_prbs_time = 0;
+ uint64_t l_prbs_time_scaled = 0;
+
+ FAPI_TRY( mss::attr::get_is_simulation( l_sim) );
+
+ FAPI_TRY(mss::attr::get_omi_dl_preipl_prbs_time(mss::find_target<fapi2::TARGET_TYPE_OMI>(i_ocmb_chip), l_prbs_time),
+ "Error from FAPI_ATTR_GET (ATTR_OMI_DL_PREIPL_PRBS_TIME)");
+ l_prbs_time_scaled = l_prbs_time * mss::common_timings::DELAY_1MS;
+
+ FAPI_TRY(fapi2::delay(l_prbs_time_scaled, mss::common_timings::DELAY_1US));
+ FAPI_DBG("OMI Training Pre-ipl PRBS Time = %dns",
+ (l_sim ? mss::common_timings::DELAY_1US : l_prbs_time_scaled));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determine if we need to bypass MENTERP register reads/writes
+///
+/// @param[in] i_target OCMB chip
+/// @param[out] o_workaround true (1) for gemini, else false (0)
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode gem_menterp(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> i_target,
+ uint8_t& o_workaround)
+{
+ o_workaround = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_GEMINI_MENTERP_WORKAROUND, i_target, o_workaround),
+ "Error getting ATTR_CHIP_EC_FEATURE_GEMINI_MENTERP_WORKAROUND");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/// @brief Determine if / perform the gemini workaround to setup the OMI config registers
+///
+/// @param[in] i_target OCMB (gemini)
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error
+/// @note Gemini workaround to setup METADATA and TEMPLATE bits before doing reads
+///
+fapi2::ReturnCode gem_setup_config(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ uint8_t l_gemini_config_workaround = 0;
+
+ // Check if gemini workaround should be performed
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_GEMINI_OMI_SETUP_CONFIG_WORKAROUND, i_target,
+ l_gemini_config_workaround),
+ "Error getting ATTR_CHIP_EC_FEATURE_GEMINI_OMI_SETUP_CONFIG_WORKAROUND");
+
+ if (l_gemini_config_workaround)
+ {
+ // Set metadata bits
+ fapi2::buffer<uint32_t> l_value;
+ l_value.setBit<EXPLR_OC_OCTRLPID_MSB_METADATA_SUPPORTED>();
+ l_value.setBit<EXPLR_OC_OCTRLPID_MSB_METADATA_ENABLED>();
+ FAPI_TRY(mss::exp::ib::putOCCfg(i_target, EXPLR_OC_OCTRLPID_MSB, l_value));
+
+ // Set template bits
+ l_value.flush<0>();
+ l_value.setBit<EXPLR_OC_OTTCFG_MSB_TEMPLATE_0>();
+ l_value.setBit<EXPLR_OC_OTTCFG_MSB_TEMPLATE_5>();
+ FAPI_TRY(mss::exp::ib::putOCCfg(i_target, EXPLR_OC_OTTCFG_MSB, l_value));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Workaround for exp_omi_train to perform dlx_config0 setup
+///
+/// @param[in] i_target OCMB chip
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode training_prbs(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ uint8_t l_dl_x4_backoff_en = 0;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, i_target, l_dl_x4_backoff_en),
+ "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE");
+
+ // Train mode 1 (PATTERN_A)
+ FAPI_TRY(mss::exp::omi::setup_omi_dl0_config0(i_target,
+ mss::omi::train_mode::TX_PATTERN_A,
+ l_dl_x4_backoff_en));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Workaround for exp_omi_setup to perform dlx_config0 setup
+///
+/// @param[in] i_target OCMB chip
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode pre_training_prbs(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ uint8_t l_dl_x4_backoff_en = 0;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, i_target, l_dl_x4_backoff_en),
+ "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE");
+
+ // State 6
+ FAPI_TRY(mss::exp::omi::setup_omi_dl0_config0(i_target,
+ mss::omi::train_mode::TX_TRAINING_STATE3,
+ l_dl_x4_backoff_en));
+
+ // Set configurable delay based on the PRBS ATTR and SIM mode
+ FAPI_TRY(prbs_delay(i_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // omi
+} // workarounds
+} // exp
+} // mss
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.H
new file mode 100644
index 000000000..f99eceda5
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.H
@@ -0,0 +1,106 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file exp_omi_workarounds.H
+/// @brief Workarounds for exp_omi_* procedures
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: Memory
+
+#ifndef _EXP_OMI_WORKAROUNDS_H_
+#define _EXP_OMI_WORKAROUNDS_H_
+
+#include <fapi2.H>
+
+namespace mss
+{
+namespace exp
+{
+namespace workarounds
+{
+namespace omi
+{
+
+///
+/// @brief Determine if the OCMB is an explorer
+///
+/// @param[in] i_ocmb_chip OCMB chip
+/// @param[out] o_explorer true/false is explorer
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+/// @note Used for exp_omi_train procedure to differentiate fw_status behavior with gemini
+///
+fapi2::ReturnCode ocmb_is_explorer(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_chip, bool& o_explorer);
+
+///
+/// @brief Set configurable delay based on the PRBS ATTR and SIM mode
+///
+/// @param[in] i_ocmb_chip OCMB target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode prbs_delay(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_chip);
+
+///
+/// @brief Determine if we need to bypass MENTERP register reads/writes
+///
+/// @param[in] i_target OCMB chip
+/// @param[out] o_workaround true (1) for gemini, else false (0)
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode gem_menterp(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> i_target,
+ uint8_t& o_workaround);
+
+/// @brief Determine if / perform the gemini workaround to setup the OMI config registers
+///
+/// @param[in] i_target OCMB (gemini)
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error
+///
+fapi2::ReturnCode gem_setup_config(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+
+///
+/// @brief Workaround for exp_omi_train to perform dlx_config0 setup
+///
+/// @param[in] i_target OCMB chip
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode training_prbs(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+
+///
+/// @brief Workaround for exp_omi_setup to perform dlx_config0 setup
+///
+/// @param[in] i_target OCMB chip
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode pre_training_prbs(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+
+} // omi
+} // workarounds
+} // exp
+} // mss
+
+#endif
diff --git a/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_attributes.xml b/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_attributes.xml
index e19cfe5be..61ff45e98 100644
--- a/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_attributes.xml
+++ b/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2018,2019 -->
+<!-- Contributors Listed Below - COPYRIGHT 2018,2020 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -29,7 +29,6 @@
<!-- -->
<!-- *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> -->
<!-- *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> -->
-<!-- *HWP FW Owner: Bill Hoffa <wghoffa@us.ibm.com> -->
<!-- *HWP Team: Memory -->
<!-- *HWP Level: 2 -->
<!-- *HWP Consumed by: FSP:HB -->
@@ -56,6 +55,31 @@
</attribute>
<attribute>
+ <id>ATTR_MSS_OCMB_ENTERPRISE_POLICY</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ Indicates whether the OCMB is allowed to run in enterprise
+ mode, commodity mode, or either.
+
+ ALLOW_ENTERPRISE = Most permissive, uses whatever is installed in
+ the way it is intended to be used.
+ REQUIRE_ENTERPRISE = Throws an error for any commodity dimms that
+ are installed.
+ FORCE_NONENTERPRISE = Throws an error for any enterprise dimms that
+ are installed.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>
+ ALLOW_ENTERPRISE = 0,
+ REQUIRE_ENTERPRISE = 1,
+ FORCE_NONENTERPRISE = 2
+ </enum>
+ <platInit/>
+ <default>ALLOW_ENTERPRISE</default>
+ <mssAccessorName>ocmb_enterprise_policy</mssAccessorName>
+ </attribute>
+
+ <attribute>
<id>ATTR_MSS_OCMB_NONENTERPRISE_MODE_OVERRIDE</id>
<targetType>TARGET_TYPE_OCMB_CHIP</targetType>
<description>
@@ -77,7 +101,6 @@
<targetType>TARGET_TYPE_OCMB_CHIP</targetType>
<description>
Indicates whether the OCMB should be run in half DIMM mode or not
- Note: needs to be setup by the get ECID functionality
</description>
<initToZero></initToZero>
<valueType>uint8</valueType>
@@ -85,7 +108,7 @@
FULL_DIMM = 0,
HALF_DIMM = 1
</enum>
- <writeable/>
+ <platInit/>
<mssAccessorName>ocmb_half_dimm_mode</mssAccessorName>
</attribute>
@@ -122,18 +145,6 @@
<!-- user_input_msdg attribute overrides start -->
<attribute>
- <id>ATTR_MEM_EXP_CS_PRESENT</id>
- <targetType>TARGET_TYPE_MEM_PORT</targetType>
- <description>
- Indicate presence of DRAM at each Chip Select for PHY
- </description>
- <initToZero></initToZero>
- <valueType>uint16</valueType>
- <writeable/>
- <mssAccessorName>exp_cs_present</mssAccessorName>
- </attribute>
-
- <attribute>
<id>ATTR_MEM_EXP_INIT_VREF_DQ</id>
<targetType>TARGET_TYPE_MEM_PORT</targetType>
<description>
@@ -142,6 +153,7 @@
<valueType>uint8</valueType>
<initToZero></initToZero>
<writeable/>
+ <array>2 4</array>
<mssAccessorName>exp_init_vref_dq</mssAccessorName>
</attribute>
@@ -151,9 +163,10 @@
<description>
Initial DQ Vref setting of PHY before training
</description>
- <valueType>uint16</valueType>
+ <valueType>uint8</valueType>
<initToZero></initToZero>
<writeable/>
+ <array>2 4</array>
<mssAccessorName>exp_init_phy_vref</mssAccessorName>
</attribute>
@@ -209,19 +222,6 @@
</attribute>
<attribute>
- <id>ATTR_MEM_EXP_3DS_HEIGHT</id>
- <targetType>TARGET_TYPE_MEM_PORT</targetType>
- <description>
- Explorer setting for 3DS stack
- </description>
- <initToZero></initToZero>
- <valueType>uint16</valueType>
- <enum>PLANAR = 0, H2 = 2, H4 = 4, H8 = 8</enum>
- <writeable/>
- <mssAccessorName>exp_3ds_height</mssAccessorName>
- </attribute>
-
- <attribute>
<id>ATTR_MEM_EXP_SPD_CL_SUPPORTED</id>
<targetType>TARGET_TYPE_MEM_PORT</targetType>
<description>
@@ -246,6 +246,21 @@
<mssAccessorName>exp_spd_taa_min</mssAccessorName>
</attribute>
+ <attribute>
+ <id>ATTR_MSS_EXP_REORDER_QUEUE_SETTING</id>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ <description>
+ Contains the settings for write/read reorder queue
+ </description>
+ <default>REORDER</default>
+ <initToZero></initToZero>
+ <writeable/>
+ <enum>REORDER = 0, FIFO = 1</enum>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <mssAccessorName>exp_reorder_queue_setting</mssAccessorName>
+ </attribute>
+
<attribute>
<id>ATTR_MEM_EXP_FIRMWARE_EMULATION_MODE</id>
<targetType>TARGET_TYPE_MEM_PORT</targetType>
@@ -274,7 +289,7 @@
SWAP = 0,
NO_SWAP = 1
</enum>
- <writeable/>
+ <platInit/>
</attribute>
<attribute>
@@ -291,7 +306,40 @@
BIG_ENDIAN = 0,
LITTLE_ENDIAN = 1
</enum>
- <writeable/>
+ <platInit/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ Controls whether or not the first and second half of MMIO
+ transactions are swapped before and after mmio accesses to
+ the buffer.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>
+ SWAP = 0,
+ NO_SWAP = 1
+ </enum>
+ <platInit/>
+ <default>NO_SWAP</default>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ Controls whether OMI CFG reg accesses
+ are considered big or little endian.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>
+ LITTLE_ENDIAN = 0,
+ BIG_ENDIAN = 1
+ </enum>
+ <platInit/>
+ <default>LITTLE_ENDIAN</default>
</attribute>
<attribute>
@@ -307,4 +355,172 @@
<mssAccessorName>ocmb_ecid</mssAccessorName>
</attribute>
+ <attribute>
+ <id>ATTR_MEM_EXP_DFIMRL_CLK</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ timing parameter for the DFIMRL clock
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <mssAccessorName>exp_dfimrl_clk</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_ATXDLY_A</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ ARRAY[ADDRESS INDEX]
+ ATxDly_A/B[0]: ODT[1],ODT[0],CS_N[0],CS_N[1]
+ ATxDly_A/B[1]: ADDR[13],ADDR[5],BG[0],CKE[1]
+ ATxDly_A/B[2]: ADDR[17],ADDR[7],BA[0],ADDR[16]
+ ATxDly_A/B[3]: ADDR[8],BG[1],CID[1],CID[0]
+ ATxDly_A/B[4]: ADDR[1],ADDR[9],ADDR[2],CAPARITY
+ ATxDly_A/B[5]: ADDR[12],ADDR[3],ADDR[4],ADDR[0]
+ ATxDly_A/B[6]: CKE[0],ADDR[15],ACT_N,ADDR[10]
+ ATxDly_A/B[7]: ADDR[11],ADDR[6],BA[1],ADDR[14]
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>8</array>
+ <mssAccessorName>exp_atxdly_a</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_EFF_ATXDLY_B</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ ARRAY[ADDRESS INDEX]
+ ATxDly_A/B[0]: ODT[1],ODT[0],CS_N[0],CS_N[1]
+ ATxDly_A/B[1]: ADDR[13],ADDR[5],BG[0],CKE[1]
+ ATxDly_A/B[2]: ADDR[17],ADDR[7],BA[0],ADDR[16]
+ ATxDly_A/B[3]: ADDR[8],BG[1],CID[1],CID[0]
+ ATxDly_A/B[4]: ADDR[1],ADDR[9],ADDR[2],CAPARITY
+ ATxDly_A/B[5]: ADDR[12],ADDR[3],ADDR[4],ADDR[0]
+ ATxDly_A/B[6]: CKE[0],ADDR[15],ACT_N,ADDR[10]
+ ATxDly_A/B[7]: ADDR[11],ADDR[6],BA[1],ADDR[14]
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>8</array>
+ <mssAccessorName>exp_atxdly_b</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MSS_OCMB_PHY_INIT_MODE</id>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ <description>
+ Mode for PHY initialization.
+ </description>
+ <valueType>uint8</valueType>
+ <initToZero></initToZero>
+ <enum>
+ NORMAL = 0,
+ WITH_EYE_CAPTURE = 1
+ </enum>
+ <writeable/>
+ <mssAccessorName>exp_phy_init_mode</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MSS_OCMB_CHECKSTOP_OBJ_HANDLE</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ The obj_handle value to send on ocmb checkstop
+ </description>
+ <valueType>uint64</valueType>
+ <default>0x0</default>
+ <platInit/>
+ <mrwHide/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MSS_OCMB_RECOV_OBJ_HANDLE</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ The obj_handle value to send on ocmb recoverable errors
+ </description>
+ <valueType>uint64</valueType>
+ <default>0x1</default>
+ <platInit/>
+ <mrwHide/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MSS_OCMB_SPECATTN_OBJ_HANDLE</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ The obj_handle value to send on ocmb special attention
+ </description>
+ <valueType>uint64</valueType>
+ <default>0x2</default>
+ <platInit/>
+ <mrwHide/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MSS_OCMB_APPINTR_OBJ_HANDLE</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ The obj_handle value to send on ocmb application interrupt
+ </description>
+ <valueType>uint64</valueType>
+ <default>0x3</default>
+ <platInit/>
+ <mrwHide/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MSS_CHECK_FOR_READY_TIMEOUT</id>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ <description>
+ Timeout (in msec) for polling for FW_STATUS reply during
+ exp_check_for_ready. Default is 400msec, from lab experimentation
+ </description>
+ <valueType>uint16</valueType>
+ <default>400</default>
+ <platInit/>
+ <mrwHide/>
+ <mssAccessorName>check_for_ready_timeout</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MSS_POST_MEMDIAGS_READ_SUBTEST</id>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ <description>
+ Whether to run post-memdiags read-only subtest
+ </description>
+ <valueType>uint8</valueType>
+ <enum>
+ DISABLE = 0,
+ ENABLE = 1
+ </enum>
+ <default>ENABLE</default>
+ <platInit/>
+ <overrideOnly/>
+ <mssAccessorName>post_memdiags_read_subtest</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MSS_POST_MEMDIAGS_READ_SUBTEST_FAIL_BEHAVIOR</id>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ <description>
+ Behvaior to perform if read subtest post-memdiags does not get a good result.
+ EXIT = fapi_try_exit out with error code
+ TRACE = FAPI_ERR that test failed, return success code
+ </description>
+ <valueType>uint8</valueType>
+ <enum>
+ EXIT = 0,
+ TRACE = 1
+ </enum>
+ <default>EXIT</default>
+ <platInit/>
+ <overrideOnly/>
+ <mssAccessorName>post_memdiags_read_subtest_fail_behavior</mssAccessorName>
+ </attribute>
+
</attributes>
diff --git a/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_omi_train.xml b/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_omi_train.xml
index e8880095e..75b9f968b 100644
--- a/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_omi_train.xml
+++ b/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_omi_train.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2018,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -44,10 +44,12 @@
<valueType>uint8</valueType>
<enum>
NORMAL_MODE = 0,
- MANUFACTURING_MODE = 1
+ MANUFACTURING_MODE = 1,
+ PRODUCT_QUALIFICATION_MODE = 2
</enum>
<initToZero/>
- <writeable/>
+ <platInit/>
+ <overrideOnly/>
<mssAccessorName>ocmb_exp_boot_config_fw_mode</mssAccessorName>
</attribute>
@@ -63,7 +65,8 @@
PERFORM_LOOPBACK_TESTING = 1
</enum>
<initToZero/>
- <writeable/>
+ <platInit/>
+ <overrideOnly/>
<mssAccessorName>ocmb_exp_boot_config_opencapi_loopback_test</mssAccessorName>
</attribute>
@@ -80,7 +83,8 @@
JTAG = 2
</enum>
<initToZero/>
- <writeable/>
+ <platInit/>
+ <overrideOnly/>
<mssAccessorName>ocmb_exp_boot_config_transport_layer</mssAccessorName>
</attribute>
@@ -93,28 +97,30 @@
</description>
<valueType>uint8</valueType>
<enum>
- BOOT_RIGHT_AFTER_CONFIG = 0,
- WAIT_FOR_HOST_CMD = 1
+ NON_DL_TRAINING = 0,
+ ONLY_DL_TRAINING = 1
</enum>
+ <platInit/>
<initToZero/>
- <writeable/>
+ <overrideOnly/>
<mssAccessorName>ocmb_exp_boot_config_dl_layer_boot_mode</mssAccessorName>
</attribute>
<attribute>
- <id>ATTR_MSS_OCMB_EXP_BOOT_CONFIG_BOOT_MODE</id>
+ <id>ATTR_MSS_OCMB_EXP_BOOT_CONFIG_DFE_DISABLE</id>
<targetType>TARGET_TYPE_OCMB_CHIP</targetType>
<description>
- Indicates the full boot or step-by-step boot
+ Set to enable or disable DFE
</description>
<valueType>uint8</valueType>
<enum>
- FULL_BOOT = 0,
- STEP_BY_STEP_BOOT = 1
+ DISABLE = 0,
+ ENABLE = 1
</enum>
- <initToZero/>
- <writeable/>
- <mssAccessorName>ocmb_exp_boot_config_boot_mode</mssAccessorName>
+ <default>ENABLE</default>
+ <platInit/>
+ <overrideOnly/>
+ <mssAccessorName>ocmb_exp_boot_config_dfe_disable</mssAccessorName>
</attribute>
<attribute>
@@ -130,7 +136,6 @@
</enum>
<default>1</default>
<platInit/>
- <writeable/>
<mssAccessorName>ocmb_exp_boot_config_lane_mode</mssAccessorName>
</attribute>
@@ -148,8 +153,22 @@
</enum>
<default>3</default>
<platInit/>
- <writeable/>
<mssAccessorName>ocmb_exp_boot_config_serdes_frequency</mssAccessorName>
</attribute>
+ <attribute>
+ <id>ATTR_MSS_OCMB_EXP_BOOT_CONFIG_ADAPTATION_MODE</id>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ <description>
+ Indicates whether to enable adaptation
+ </description>
+ <valueType>uint8</valueType>
+ <enum>
+ DISABLE = 0,
+ ENABLE = 1
+ </enum>
+ <default>ENABLE</default>
+ <platInit/>
+ <mssAccessorName>ocmb_exp_boot_config_adaptation_mode</mssAccessorName>
+ </attribute>
</attributes>
diff --git a/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_power_thermal.xml b/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_power_thermal.xml
index eaa83be48..8b50d2594 100644
--- a/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_power_thermal.xml
+++ b/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/exp_power_thermal.xml
@@ -23,4 +23,168 @@
<!-- -->
<!-- IBM_PROLOG_END_TAG -->
<attributes>
+ <attribute>
+ <id>ATTR_EXP_MEM_THROTTLED_N_COMMANDS_PER_PORT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ This is the throttled N commands per window
+ of M DRAM clocks setting for cfg_nm_n_per_port.
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint16</valueType>
+ <writeable/>
+ <mssAccessorName>mem_throttled_n_commands_per_port</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_EXP_MEM_THROTTLED_N_COMMANDS_PER_SLOT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>This is the throttle numerator setting for cfg_nm_n_per_slot</description>
+ <initToZero></initToZero>
+ <valueType>uint16</valueType>
+ <writeable/>
+ <mssAccessorName>mem_throttled_n_commands_per_slot</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_EXP_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Runtime throttled N commands per
+ M DRAM clocks setting for cfg_nm_n_per_port.
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint16</valueType>
+ <writeable/>
+ <mssAccessorName>runtime_mem_throttled_n_commands_per_port</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_EXP_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>Runtime throttle numerator setting for cfg_nm_n_per_slot</description>
+ <initToZero></initToZero>
+ <valueType>uint16</valueType>
+ <writeable/>
+ <mssAccessorName>runtime_mem_throttled_n_commands_per_slot</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_EXP_SAFEMODE_MEM_THROTTLED_N_COMMANDS_PER_PORT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Safe mode throttle value for numerator cfg_nm_n_per_port
+ Set to below optimum value/ rate.
+ On a per port basis
+ Also used for emergency mode throttle MBA_FARB4Q_EMERGENCY_N
+ Used to thermally protect the system in all supported environmental conditions when OCC is not functional
+ </description>
+ <valueType>uint16</valueType>
+ <default>32</default>
+ <platInit/>
+ <initToZero/>
+ <mssAccessorName>safemode_mem_throttled_n_commands_per_port</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_EXP_RUNTIME_MEM_M_DRAM_CLOCKS</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>Runtime for M DRAM clocks setting for cfg_nm_m</description>
+ <initToZero></initToZero>
+ <valueType>uint32</valueType>
+ <writeable/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_EXP_MEM_PORT_POS_OF_FAIL_THROTTLE</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ This is the fapi position of the port that failed to calculate
+ memory throttles given the passed in watt target and or utilization
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint64</valueType>
+ <writeable/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_EXP_MEM_WATT_TARGET</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Total memory power used to throttle for each dimm
+ Used to compute the throttles on the channel and/or dimms for OCC
+ OCC sets after IPL
+ </description>
+ <initToZero></initToZero>
+ <mssUnit>cW</mssUnit>
+ <valueType>uint32</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>mem_watt_target</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_EXP_TOTAL_PWR_SLOPE</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ VDDR+VPP Power slope value for dimm
+ creator: mss_eff_config
+ consumer: mss_bulk_pwr_throttles
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint16</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>total_pwr_slope</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_EXP_TOTAL_PWR_INTERCEPT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ VDDR+VPP Power intercept value for dimm
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint16</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>total_pwr_intercept</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_EXP_DATABUS_UTIL</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Databus utilization per port limit used to calculate memory throttles and power limit
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint32</valueType>
+ <writeable/>
+ <mssAccessorName>databus_util</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_EXP_PORT_MAXPOWER</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>Channel Pair Max Power output from thermal procedures</description>
+ <initToZero></initToZero>
+ <valueType>uint32</valueType>
+ <writeable/>
+ <mssAccessorName>port_maxpower</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_EXP_DIMM_THERMAL_LIMIT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ DIMM Max Power based on a thermal limit
+ Decoded from ATTR_MSS_MRW_THERMAL_POWER_LIMIT
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint32</valueType>
+ <writeable/>
+ <mssUnit>cW</mssUnit>
+ <array>2</array>
+ <mssAccessorName>dimm_thermal_limit</mssAccessorName>
+ </attribute>
</attributes>
diff --git a/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_collect_explorer_errors.xml b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_collect_explorer_errors.xml
new file mode 100644
index 000000000..d605771eb
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_collect_explorer_errors.xml
@@ -0,0 +1,49 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_collect_explorer_errors.xml $ -->
+<!-- -->
+<!-- OpenPOWER HostBoot Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2019 -->
+<!-- [+] International Business Machines Corp. -->
+<!-- -->
+<!-- -->
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); -->
+<!-- you may not use this file except in compliance with the License. -->
+<!-- You may obtain a copy of the License at -->
+<!-- -->
+<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
+<!-- -->
+<!-- Unless required by applicable law or agreed to in writing, software -->
+<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
+<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -->
+<!-- implied. See the License for the specific language governing -->
+<!-- permissions and limitations under the License. -->
+<!-- -->
+<!-- IBM_PROLOG_END_TAG -->
+<hwpErrors>
+ <!-- ******************************************************************** -->
+ <hwpError>
+ <rc>RC_COLLECT_EXPLORER_ERROR</rc>
+ <description>Collects error log data from Explorer chip</description>
+ <collectFfdc>exp_collect_explorer_active_log, OCMB_CHIP_TARGET, EXP_ACTIVE_LOG_SIZE</collectFfdc>
+ <collectFfdc>exp_collect_explorer_saved_log, OCMB_CHIP_TARGET, EXP_SAVED_LOG_SIZE</collectFfdc>
+ <ffdc>OCMB_CHIP_TARGET</ffdc>
+ <ffdc>EXP_ACTIVE_LOG_SIZE</ffdc>
+ <ffdc>EXP_SAVED_LOG_SIZE</ffdc>
+ </hwpError>
+ <!-- ******************************************************************** -->
+ <hwpError>
+ <rc>RC_EXPLORER_ACTIVE_ERROR_LOG</rc>
+ <description>Collect active explorer errors during exp_collect_explorer_active_log</description>
+ <ffdc>UNIT_FFDC_EXP_ERROR</ffdc>
+ </hwpError>
+ <!-- ******************************************************************** -->
+ <hwpError>
+ <rc>RC_EXPLORER_SAVED_ERROR_LOG</rc>
+ <description>Collect saved explorer errors during exp_collect_explorer_saved_log</description>
+ <ffdc>UNIT_FFDC_EXP_ERROR</ffdc>
+ </hwpError>
+ <!-- ******************************************************************** -->
+</hwpErrors>
diff --git a/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_fw_update_errors.xml b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_fw_update_errors.xml
new file mode 100644
index 000000000..dffdca189
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_fw_update_errors.xml
@@ -0,0 +1,154 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_fw_update_errors.xml $ -->
+<!-- -->
+<!-- OpenPOWER HostBoot Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2019 -->
+<!-- [+] International Business Machines Corp. -->
+<!-- -->
+<!-- -->
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); -->
+<!-- you may not use this file except in compliance with the License. -->
+<!-- You may obtain a copy of the License at -->
+<!-- -->
+<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
+<!-- -->
+<!-- Unless required by applicable law or agreed to in writing, software -->
+<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
+<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -->
+<!-- implied. See the License for the specific language governing -->
+<!-- permissions and limitations under the License. -->
+<!-- -->
+<!-- IBM_PROLOG_END_TAG -->
+<hwpErrors>
+
+ <hwpError>
+ <rc>RC_EXP_UPDATE_INVALID_IMAGE_SIZE</rc>
+ <description>
+ Explorer firmware image must be less than 16MB
+ </description>
+ <ffdc>IMAGE_SIZE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_UPDATE_CMD_FAILED</rc>
+ <description>
+ The response_argument field of the host_fw_response_struct returned a FAILURE
+ </description>
+ <ffdc>RSP_ID</ffdc>
+ <ffdc>REQ_ID</ffdc>
+ <ffdc>ERROR_CODE</ffdc>
+ <ffdc>RSP_DATA</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_TWI_INVALID_STATUS_ID</rc>
+ <description>
+ The status_id field of the TWI status was invalid
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>STATUS_ID</ffdc>
+ <ffdc>STATUS_WORD32</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_TWI_UNEXPECTED_STATUS</rc>
+ <description>
+ Received unexpected TWI status
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>EXPECTED_STATUS</ffdc>
+ <ffdc>STATUS</ffdc>
+ <ffdc>STATUS_WORD32</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_TWI_UNEXPECTED_WRITE_OFFSET</rc>
+ <description>
+ Received unexpected TWI write offset
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>EXPECTED_OFFSET</ffdc>
+ <ffdc>WRITE_OFFSET</ffdc>
+ <ffdc>STATUS_WORD32</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_TWI_INVALID_IMAGE_SIZE</rc>
+ <description>
+ Explorer TWI firmware image must be less than 256KB
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>MAX_SIZE</ffdc>
+ <ffdc>ACTUAL_SIZE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_EXP_I2C_FW_DOWNLOAD_INVALID_STATE</rc>
+ <description>
+ Must be in BOOT_ROM or FW_UPGRADE boot stage to issue FW_DOWNLOAD command
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>BOOT_STAGE</ffdc>
+ <ffdc>STATUS_DATA</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+
+</hwpErrors>
diff --git a/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_pmic_errors.xml b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_getidec.xml
index 8e1ede29e..f5060138c 100644
--- a/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_pmic_errors.xml
+++ b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_getidec.xml
@@ -1,11 +1,11 @@
<!-- IBM_PROLOG_BEGIN_TAG -->
<!-- This is an automatically generated prolog. -->
<!-- -->
-<!-- $Source: src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_pmic_errors.xml $ -->
+<!-- $Source: src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_getidec.xml $ -->
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2019 -->
+<!-- Contributors Listed Below - COPYRIGHT 2020 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -22,5 +22,29 @@
<!-- permissions and limitations under the License. -->
<!-- -->
<!-- IBM_PROLOG_END_TAG -->
+
<hwpErrors>
+
+ <hwpError>
+ <rc>RC_EXP_UNKNOWN_REVISION</rc>
+ <description>
+ The Explorer revision does not match a known DD level.
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>REVISION</ffdc>
+ <ffdc>CHIP_INFO_REG</ffdc>
+ <ffdc>EFUSE_IMAGE_OUT_3</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
</hwpErrors>
diff --git a/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_inband_errors.xml b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_inband_errors.xml
index f69b3dd8e..1a337a57f 100644
--- a/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_inband_errors.xml
+++ b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_inband_errors.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2018,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -70,4 +70,18 @@
</callout>
</hwpError>
+ <hwpError>
+ <rc>RC_EXP_INBAND_RSP_NO_DOORBELL</rc>
+ <description>
+ Doorbell is low when expecting a response
+ </description>
+ <ffdc>DATA</ffdc>
+ <ffdc>NUM_LOOPS</ffdc>
+ <ffdc>OCMB_TARGET</ffdc>
+ <callout>
+ <target>OCMB_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
</hwpErrors>
diff --git a/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_init_errors.xml b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_init_errors.xml
index 7654fe832..eba974e3b 100644
--- a/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_init_errors.xml
+++ b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_init_errors.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2018,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -83,4 +83,16 @@
<ffdc>A</ffdc>
</hwpError>
<!-- ******************************************************************** -->
+ <hwpError>
+ <rc>RC_METADATA_ENABLE_REQUIRES_TEMPLATE_5_OR_9</rc>
+ <description>
+ Procedure: exp_omi_init.C
+ Upstream template 5 or 9 need to be enabled for
+ metadata enable.
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>TMPL_5</ffdc>
+ <ffdc>TMPL_9</ffdc>
+ </hwpError>
+ <!-- ******************************************************************** -->
</hwpErrors>
diff --git a/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_train_errors.xml b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_train_errors.xml
new file mode 100644
index 000000000..9b735dd02
--- /dev/null
+++ b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_train_errors.xml
@@ -0,0 +1,55 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_train_errors.xml $ -->
+<!-- -->
+<!-- OpenPOWER HostBoot Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2019 -->
+<!-- [+] International Business Machines Corp. -->
+<!-- -->
+<!-- -->
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); -->
+<!-- you may not use this file except in compliance with the License. -->
+<!-- You may obtain a copy of the License at -->
+<!-- -->
+<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
+<!-- -->
+<!-- Unless required by applicable law or agreed to in writing, software -->
+<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
+<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -->
+<!-- implied. See the License for the specific language governing -->
+<!-- permissions and limitations under the License. -->
+<!-- -->
+<!-- IBM_PROLOG_END_TAG -->
+<hwpErrors>
+ <!-- ******************************************************************** -->
+ <hwpError>
+ <rc>RC_EXP_OMI_TRAIN_ERR</rc>
+ <description>
+ exp_omi_train_check did not see expected trained status from OCMB DL0 status register
+ </description>
+ <ffdc>OCMB_TARGET</ffdc>
+ <ffdc>EXPECTED_SM_STATE</ffdc>
+ <ffdc>ACTUAL_SM_STATE</ffdc>
+ <ffdc>DL0_STATUS</ffdc>
+ <ffdc>DL0_TRAINING_STATUS</ffdc>
+ <ffdc>DL0_CONFIG1</ffdc>
+ <ffdc>OMI_FREQ</ffdc>
+ <callout>
+ <target>OCMB_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <bus>OMI_TARGET, OCMB_TARGET</bus>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>OCMB_TARGET</target>
+ </deconfigure>
+ <gard>
+ <target>OCMB_TARGET</target>
+ </gard>
+ </hwpError>
+ <!-- ******************************************************************** -->
+</hwpErrors>
diff --git a/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml b/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml
index d2b864abf..702c0aef1 100644
--- a/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml
+++ b/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml
@@ -24,6 +24,260 @@
<!-- IBM_PROLOG_END_TAG -->
<hwpErrors>
+ <registerFfdc>
+ <id>REG_FFDC_EXP_MEMDIAGS_FAILURE</id>
+ <scomRegister>EXPLR_MCBIST_MCBMR0Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBCFGQ</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCB_CNTLQ</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCB_CNTLSTATQ</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBSTATQ</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBMCATQ</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBPARMQ</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBAGRAQ</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MBSEC1Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MBSTRQ</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBISTFIRQ</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBAMR0A0Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBAMR1A0Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBAMR2A0Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBAMR3A0Q</scomRegister>
+
+ <scomRegister>EXPLR_MCBIST_MCBFD0Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBFD1Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBFD2Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBFD3Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBFD4Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBFD5Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBFD6Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBFD7Q</scomRegister>
+
+ <scomRegister>EXPLR_MCBIST_MCBSA0Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBSA1Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBSA2Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBSA3Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBEA0Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBEA1Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBEA2Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBEA3Q</scomRegister>
+ </registerFfdc>
+
+ <hwpError>
+ <rc>RC_EXP_MEMDIAGS_COMPARE_ERROR_IN_LAST_PATTERN</rc>
+ <description>A miscompare error was caused by the last MCBIST pattern</description>
+ <ffdc>PORT</ffdc>
+ <ffdc>SUBTEST</ffdc>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_MEMDIAGS_ERROR_IN_LAST_PATTERN</rc>
+ <description>An error was caused by the last MCBIST pattern</description>
+ <ffdc>STATUS0</ffdc>
+ <ffdc>STATUS1</ffdc>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_MEMDIAGS_MCBIST_FAILED_TO_START</rc>
+ <description>The MCBIST engine failed to start its program</description>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_MEMDIAGS_PORT_NOT_FUNCTIONAL</rc>
+ <description>The port used in an MCBIST program is not functional</description>
+ <ffdc>RELATIVE_PORT_POSITION</ffdc>
+ <ffdc>ADDRESS</ffdc>
+ <ffdc>MC_TARGET</ffdc>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_MEMDIAGS_SUPERFAST_INIT_FAILED_TO_INIT</rc>
+ <description>A superfast init operation failed initialization</description>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_MEMDIAGS_SUPERFAST_READ_FAILED_TO_INIT</rc>
+ <description>A superfast read operation failed initialization</description>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_MEMDIAGS_MCBIST_FAILED_TO_STOP</rc>
+ <description>The MCBIST engine failed to stop its program</description>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <ffdc>POLL_COUNT</ffdc>
+ <callout>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_MEMDIAGS_CONTINUOUS_SCRUB_FAILED_TO_INIT</rc>
+ <description>A continuous scrub operation failed initialization</description>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_MEMDIAGS_TARGETED_SCRUB_FAILED_TO_INIT</rc>
+ <description>A continuous scrub operation failed initialization</description>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_MEMDIAGS_ALREADY_AT_BOUNDARY</rc>
+ <description>A continue request asked to stop at a boundary, but we are there already</description>
+ <ffdc>MC_TARGET</ffdc>
+ <ffdc>BOUNDARY</ffdc>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_MCBIST_TIMEOUT</rc>
+ <description>
+ MCBIST program failed to return in the time allowed
+ Software timer, MCBIST has not finished in the time allowed
+ </description>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>MC_TARGET</target>
+ </deconfigure>
+ <gard>
+ <target>MC_TARGET</target>
+ </gard>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_MCBIST_DATA_FAIL</rc>
+ <description>
+ MCBIST program appeared to have failed, but set conflicting bits in the status register
+ </description>
+ <ffdc>STATUS_REGISTER</ffdc>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>MC_TARGET</target>
+ </deconfigure>
+ <gard>
+ <target>MC_TARGET</target>
+ </gard>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_MCBIST_UNKNOWN_FAILURE</rc>
+ <description>MCBIST program reported a failure but no error status was found</description>
+ <ffdc>STATUS_REGISTER</ffdc>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>MC_TARGET</target>
+ </deconfigure>
+ <gard>
+ <target>MC_TARGET</target>
+ </gard>
+ </hwpError>
+
<hwpError>
<rc>RC_MSS_EXP_DRAMINIT_BAD_NUM_RANKS</rc>
<description>Bad number of ranks were passed in the bad bits functionality</description>
@@ -82,6 +336,39 @@
</hwpError>
<hwpError>
+ <rc>RC_MSS_EXP_HALF_DIMM_MODE_NOT_SUPPORTED</rc>
+ <description>
+ The enterprise settings do not support half dimm mode.
+ </description>
+ <ffdc>ENTERPRISE_SETTING</ffdc>
+ <ffdc>HALF_DIMM_SETTING</ffdc>
+ <callout>
+ <target>OCMB_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>OCMB_TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_EXP_ENTERPRISE_INVALID_CONFIGURATION</rc>
+ <description>
+ The enterprise supported bit from explorer fuse
+ conflicts with the enterprise policy setting.
+ </description>
+ <ffdc>ENTERPRISE_SUPPORTED</ffdc>
+ <ffdc>POLICY</ffdc>
+ <callout>
+ <target>OCMB_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>OCMB_TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
<rc>RC_MSS_EXP_ENTERPRISE_SETUP_ERROR</rc>
<description>The enterprise mode bit is in the incorrect state</description>
<ffdc>EXPECTED</ffdc>
@@ -102,6 +389,29 @@
Explorer status code for command ID EXP_FW_STATUS
did not return SUCCESS
</description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>STATUS_CODE</ffdc>
+ <ffdc>CMD_ID</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_EXP_I2C_FW_BOOT_CONFIG_STATUS_CODE_INVALID</rc>
+ <description>
+ Unexpected Explorer status code returned during OMI link training pattern handshake.
+ Expected FW_BUSY, but received STATUS_CODE in FFDC data
+ </description>
+ <ffdc>TARGET</ffdc>
<ffdc>STATUS_CODE</ffdc>
<ffdc>CMD_ID</ffdc>
<callout>
@@ -118,6 +428,49 @@
</hwpError>
<hwpError>
+ <rc>RC_MSS_EXP_I2C_FW_STATUS_BUSY</rc>
+ <description>
+ Received FW_BUSY status after polling timeout for
+ command ID EXP_FW_STATUS
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>STATUS_CODE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_EXP_I2C_WRONG_BOOT_STAGE</rc>
+ <description>
+ Received incorrect boot stage from
+ command ID EXP_FW_STATUS
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>BOOT_STAGE</ffdc>
+ <ffdc>EXPECTED_BOOT_STAGE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
<rc>RC_MSS_EXP_I2C_POLLING_TIMEOUT</rc>
<description>
Polling the explorer I2C slave interface for an ACK
@@ -162,6 +515,8 @@
</description>
<ffdc>RSP_ID</ffdc>
<ffdc>ERROR_CODE</ffdc>
+ <ffdc>EXPECTED_REQID</ffdc>
+ <ffdc>ACTUAL_REQID</ffdc>
<callout>
<procedure>CODE</procedure>
<priority>MEDIUM</priority>
@@ -175,4 +530,242 @@
</deconfigure>
</hwpError>
+ <hwpError>
+ <rc>RC_MSS_EXP_SENSOR_CACHE_ENABLE_FAILED</rc>
+ <description>
+ The response_argument field of the host_fw_response_struct returned
+ a FAILURE for enabling sensor cache
+ </description>
+ <ffdc>RSP_ID</ffdc>
+ <ffdc>ERROR_CODE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <registerFfdc>
+ <id>REG_FFDC_EXP_CCS_FAILURE</id>
+ <scomRegister>EXPLR_MCBIST_CCS_MODEQ</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_STATQ</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_CNTLQ</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MCBMCATQ</scomRegister>
+
+ <!-- Instructions -->
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_00</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_01</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_02</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_03</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_04</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_05</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_06</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_07</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_08</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_09</scomRegister>
+
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_10</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_11</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_12</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_13</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_14</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_15</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_16</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_17</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_18</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_19</scomRegister>
+
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_20</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_21</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_22</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_23</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_24</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_25</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_26</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_27</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_28</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_29</scomRegister>
+
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_30</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR0_31</scomRegister>
+
+ <!-- Control array -->
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_00</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_01</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_02</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_03</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_04</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_05</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_06</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_07</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_08</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_09</scomRegister>
+
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_10</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_11</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_12</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_13</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_14</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_15</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_16</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_17</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_18</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_19</scomRegister>
+
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_20</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_21</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_22</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_23</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_24</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_25</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_26</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_27</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_28</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_29</scomRegister>
+
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_30</scomRegister>
+ <scomRegister>EXPLR_MCBIST_CCS_INST_ARR1_31</scomRegister>
+
+ <!-- to get the CCS state machine hung state -->
+ <scomRegister>EXPLR_MCBIST_MBA_MCBERRPT0Q</scomRegister>
+ <scomRegister>EXPLR_MCBIST_MBA_MCBERRPT1Q</scomRegister>
+ </registerFfdc>
+
+ <hwpError>
+ <rc>RC_MSS_EXP_CCS_READ_MISCOMPARE</rc>
+ <description>
+ CCS reports a read miscompare.
+ </description>
+ <ffdc>FAIL_TYPE</ffdc>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_CCS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <target>PORT_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>PORT_TARGET</target>
+ </deconfigure>
+ <gard>
+ <target>PORT_TARGET</target>
+ </gard>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_EXP_CCS_UE_SUE</rc>
+ <description>
+ CCS reports a UE or SUE in the CCS program array
+ Chould be an indicator of corruption in the CCS program
+ </description>
+ <ffdc>FAIL_TYPE</ffdc>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_CCS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>MC_TARGET</target>
+ </deconfigure>
+ <gard>
+ <target>MC_TARGET</target>
+ </gard>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_EXP_CCS_HUNG</rc>
+ <description>
+ Software reported that the machine is not seeing the CCS finish in the alloted time
+ </description>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_CCS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>MC_TARGET</target>
+ </deconfigure>
+ <gard>
+ <target>MC_TARGET</target>
+ </gard>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_EXP_CCS_HUNG_TRYING_TO_STOP</rc>
+ <description>
+ CCS failed to return from in-progress status while trying to stop a previous program
+ Software reported that CCS did not finish in alloted time after manually triggering stop
+ </description>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_EXP_CCS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ </collectRegisterFfdc>
+ <callout>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>MC_TARGET</target>
+ </deconfigure>
+ <gard>
+ <target>MC_TARGET</target>
+ </gard>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_EXP_UNKNOWN_PHY_INIT_MODE</rc>
+ <description>
+ The PHY init mode value was an unknown value.
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>VALUE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_EXP_INVALID_PHY_INIT_RSP_DATA_LENGTH</rc>
+ <description>
+ The data buffer vector retrieved from the EXP_FW_DDR_PHY_INIT response did not match the expected length
+ </description>
+ <ffdc>OCMB_TARGET</ffdc>
+ <ffdc>PHY_INIT_MODE</ffdc>
+ <ffdc>EXPECTED_LENGTH</ffdc>
+ <ffdc>ACTUAL_LENGTH</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>OCMB_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>OCMB_TARGET</target>
+ </deconfigure>
+ </hwpError>
+
</hwpErrors>
diff --git a/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.C b/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.C
index 548ee2de6..275ae67c6 100644
--- a/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.C
+++ b/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.C
@@ -22,3 +22,39 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gem_draminit.C
+/// @brief Procedure definition to initialize DRAM
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include <lib/gem_draminit_utils.H>
+#include <generic/memory/mss_git_data_helper.H>
+
+extern "C"
+{
+ ///
+ /// @brief Initializes DRAM
+ /// @param[in] i_target the OCMB chip (Gemini)
+ /// @return FAPI2_RC_SUCCESS iff ok, else fapi2::current_err
+ ///
+ fapi2::ReturnCode gem_draminit(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+ {
+ mss::display_git_commit_info("gem_draminit");
+
+ FAPI_TRY(mss::gem::poll_check_calibration(i_target));
+ FAPI_TRY(mss::gem::init_memory(i_target));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+} // extern "C"
diff --git a/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.H b/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.H
index 61da5bde8..bfe86b631 100644
--- a/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.H
+++ b/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.H
@@ -22,3 +22,34 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gem_draminit.H
+/// @brief Procedure definition to initialize DRAM
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#ifndef __MSS_GEM_DRAMINIT__
+#define __MSS_GEM_DRAMINIT__
+
+#include <fapi2.H>
+
+// Required for Cronus
+typedef fapi2::ReturnCode (*gem_draminit_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&);
+
+extern "C"
+{
+
+///
+/// @brief Initializes DRAM
+/// @param[in] i_target the controller
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+ fapi2::ReturnCode gem_draminit(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+
+}// extern C
+#endif
diff --git a/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.mk b/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.mk
index 84a97f3ab..ea64e2617 100644
--- a/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.mk
+++ b/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_draminit.mk
@@ -22,3 +22,10 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+
+# Include the macros and things for MSS GEMINI procedures
+-include 00gem_common.mk
+
+PROCEDURE=gem_draminit
+$(eval $(call ADD_GEM_MEMORY_INCDIRS,$(PROCEDURE)))
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.C b/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.C
index 8deac2c76..dc92bb1ab 100644
--- a/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.C
+++ b/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.C
@@ -22,3 +22,44 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+#include <fapi2.H>
+#include <gem_getecid.H>
+#include <mss_explorer_attribute_setters.H>
+#include <generic/memory/mss_git_data_helper.H>
+
+extern "C"
+{
+
+ ///
+ /// @brief Gets gemini ECID
+ /// @param[in] i_target the controller
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode gem_getecid(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+ {
+ mss::display_git_commit_info("gem_getecid");
+
+ // Address defined here as gemini SCOM address library does not exist
+ static constexpr uint64_t GEMINI_ECID_REGISTER = 0x0801240E;
+ fapi2::buffer<uint64_t> l_data_buffer;
+
+ FAPI_TRY(fapi2::getScom(i_target, GEMINI_ECID_REGISTER, l_data_buffer),
+ "Failed getScom() for %s", mss::spd::c_str(i_target));
+
+ {
+ // Set ATTR_ECID
+ // TK - Update once ATTR_ECID array size is updated to be larger than 2
+ static constexpr uint32_t ECID_ARRAY_SIZE = 2;
+ uint64_t l_attr_ecid[ECID_ARRAY_SIZE] = {l_data_buffer, 0};
+
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_ECID, i_target, l_attr_ecid),
+ "exp_getecid: Could not set ATTR_ECID on %s", mss::c_str(i_target) );
+ }
+
+ // omi_setup not used by GEMINI, so not setting ocmb enterprise mode and half-dimm mode attributes
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+} // extern "C"
diff --git a/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.H b/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.H
index 20b8d4bb6..3ee0d7403 100644
--- a/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.H
+++ b/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.H
@@ -22,3 +22,24 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+#ifndef __MSS_GEM_GETECID__
+#define __MSS_GEM_GETECID__
+
+#include <fapi2.H>
+
+// Required for Cronus
+typedef fapi2::ReturnCode (*gem_getecid_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&);
+
+extern "C"
+{
+
+///
+/// @brief Gets gemini ECID
+/// @param[in] i_target the controller
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+ fapi2::ReturnCode gem_getecid(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+
+}// extern C
+#endif
diff --git a/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.mk b/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.mk
index 339fd149e..efd3e49a3 100644
--- a/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.mk
+++ b/src/import/chips/ocmb/gemini/procedures/hwp/memory/gem_getecid.mk
@@ -22,3 +22,8 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+-include 00gemini_common.mk
+
+PROCEDURE=gem_getecid
+$(eval $(call ADD_GEM_MEMORY_INCDIRS,$(PROCEDURE)))
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/ocmb/gemini/procedures/hwp/memory/lib/gem_draminit_utils.C b/src/import/chips/ocmb/gemini/procedures/hwp/memory/lib/gem_draminit_utils.C
index c9f1a9b63..771ecfbc2 100644
--- a/src/import/chips/ocmb/gemini/procedures/hwp/memory/lib/gem_draminit_utils.C
+++ b/src/import/chips/ocmb/gemini/procedures/hwp/memory/lib/gem_draminit_utils.C
@@ -22,3 +22,126 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file gem_draminit_utils.C
+/// @brief Procedure definition to initialize DRAM
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/utils/poll.H>
+#include <mss_generic_attribute_getters.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+#include <mss_generic_attribute_setters.H>
+#include <lib/gem_draminit_utils.H>
+
+namespace mss
+{
+namespace gem
+{
+
+///
+/// @brief Polls DRAM calibration register to check for complete
+/// @param[in] i_target the controller
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode poll_check_calibration(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ // Address defined here as gemini SCOM address library does not exist
+
+ // Using default parameters
+ mss::poll_parameters l_poll_params;
+
+ fapi2::buffer<uint64_t> l_data_buffer;
+
+ bool l_poll_success =
+ mss::poll(i_target, GEMINI_ICETRAP4, l_poll_params,
+ [&l_data_buffer](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
+ {
+ FAPI_DBG("Polling: Gemini calibration status 0x%llx, remaining: %d", stat_reg, poll_remaining);
+ l_data_buffer = stat_reg;
+
+ return l_data_buffer.getBit<FLD_ICETRAP4_CALIBRATION_STATUS_BIT_1>()
+ && l_data_buffer.getBit<FLD_ICETRAP4_CALIBRATION_STATUS_BIT_2>();
+ });
+
+ FAPI_ASSERT(l_poll_success == true,
+ fapi2::MSS_GEM_DRAMINIT_CALIBRATION_DID_NOT_COMPLETE()
+ .set_TARGET(i_target)
+ .set_REGISTER(GEMINI_ICETRAP4)
+ .set_CONTENTS(l_data_buffer),
+ "Calibration check timed out for target %s", mss::spd::c_str(i_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Write bit to initialize memory and then poll for completion
+///
+/// @param[in] i_target gemini target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode init_memory(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
+{
+ // Polling needs to occur for at least 5 seconds. Doing 7 seconds with delay of 0.25 seconds
+ static constexpr uint32_t QUARTER_SECOND_POLL_DELAY = 250000000; // NS
+ static constexpr uint32_t SEVEN_SECOND_POLL_COUNT = 28;
+
+ fapi2::buffer<uint64_t> l_reg_contents;
+ mss::poll_parameters l_poll_params;
+
+ l_poll_params.iv_delay = QUARTER_SECOND_POLL_DELAY;
+ l_poll_params.iv_poll_count = SEVEN_SECOND_POLL_COUNT;
+
+ // Init memory to address as data
+ FAPI_TRY(fapi2::getScom(i_target, GEMINI_ICECFG1, l_reg_contents));
+
+ if (l_reg_contents.getBit<FLD_ICECFG1_MEMORY_INIT_START>())
+ {
+ // Init bit is stuck. We need to clear it before we can set the bit again
+ FAPI_INF("gem_draminit(): Memory appears to be already initialized for %s , Clearing bit before continuing",
+ mss::c_str(i_target));
+ l_reg_contents.clearBit<FLD_ICECFG1_MEMORY_INIT_START>();
+ FAPI_TRY(fapi2::putScom(i_target, GEMINI_ICECFG1, l_reg_contents));
+ }
+
+ l_reg_contents.setBit<FLD_ICECFG1_INIT_ZERO>();
+ FAPI_TRY(fapi2::putScom(i_target, GEMINI_ICECFG1, l_reg_contents));
+
+ l_reg_contents.setBit<FLD_ICECFG1_MEMORY_INIT_START>();
+ FAPI_TRY(fapi2::putScom(i_target, GEMINI_ICECFG1, l_reg_contents));
+
+ l_reg_contents.flush<0>();
+ {
+ bool l_poll_success = mss::poll(i_target, GEMINI_ICETRAP4, l_poll_params,
+ [&l_reg_contents](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
+ {
+ FAPI_DBG("Polling: Gemini calibration status 0x%016x for memory init, remaining: %d",
+ stat_reg, poll_remaining);
+ l_reg_contents = stat_reg;
+
+ return l_reg_contents.getBit<FLD_ICETRAP4_MEMORY_INIT_COMPELTE>();
+ });
+
+ FAPI_ASSERT(l_poll_success,
+ fapi2::MSS_GEM_DRAMINIT_MEM_INIT_DID_NOT_COMPLETE()
+ .set_TARGET(i_target)
+ .set_REGISTER(GEMINI_ICETRAP4)
+ .set_CONTENTS(l_reg_contents),
+ "Calibration check timed out for target %s", mss::spd::c_str(i_target));
+ }
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}// exp
+}// mss
diff --git a/src/import/chips/ocmb/gemini/procedures/hwp/memory/lib/gem_draminit_utils.H b/src/import/chips/ocmb/gemini/procedures/hwp/memory/lib/gem_draminit_utils.H
index 346eabb40..9a3c4f1b6 100644
--- a/src/import/chips/ocmb/gemini/procedures/hwp/memory/lib/gem_draminit_utils.H
+++ b/src/import/chips/ocmb/gemini/procedures/hwp/memory/lib/gem_draminit_utils.H
@@ -22,3 +22,51 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gem_draminit_utils.H
+/// @brief Procedure definition to initialize DRAM
+///
+// *HWP HWP Owner: Mark Pizzutillo <aamarin@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#ifndef __MSS_GEM_DRAMINIT_UTILS__
+#define __MSS_GEM_DRAMINIT_UTILS__
+
+#include <fapi2.H>
+
+namespace mss
+{
+namespace gem
+{
+
+static constexpr uint64_t GEMINI_ICETRAP4 = 0x08012428;
+static constexpr uint64_t GEMINI_ICECFG1 = 0x0801240D;
+static constexpr uint64_t FLD_ICETRAP4_CALIBRATION_STATUS_BIT_1 = 0x0;
+static constexpr uint64_t FLD_ICETRAP4_CALIBRATION_STATUS_BIT_2 = 0x1;
+static constexpr uint64_t FLD_ICETRAP4_MEMORY_INIT_COMPELTE = 32;
+static constexpr uint64_t FLD_ICECFG1_INIT_ZERO = 8;
+static constexpr uint64_t FLD_ICECFG1_MEMORY_INIT_START = 7;
+
+///
+/// @brief Polls DRAM calibration register to check for complete
+/// @param[in] i_target gemini target
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode poll_check_calibration(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+
+///
+/// @brief Write bit to initialize memory and then poll for completion
+///
+/// @param[in] i_target gemini target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode init_memory(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+
+}// exp
+}// mss
+
+#endif
diff --git a/src/import/chips/ocmb/gemini/procedures/xml/error_info/gem_draminit_errors.xml b/src/import/chips/ocmb/gemini/procedures/xml/error_info/gem_draminit_errors.xml
index a8cdc5e7d..d47d3b3af 100644
--- a/src/import/chips/ocmb/gemini/procedures/xml/error_info/gem_draminit_errors.xml
+++ b/src/import/chips/ocmb/gemini/procedures/xml/error_info/gem_draminit_errors.xml
@@ -23,4 +23,35 @@
<!-- -->
<!-- IBM_PROLOG_END_TAG -->
<hwpErrors>
+
+ <hwpError>
+ <rc>RC_MSS_GEM_DRAMINIT_CALIBRATION_DID_NOT_COMPLETE</rc>
+ <description>
+ During gemini dram initialization, the calibration process
+ did not complete as reported by the Gemini calibration status register.
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>REGISTER</ffdc>
+ <ffdc>CONTENTS</ffdc>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_GEM_DRAMINIT_MEM_INIT_DID_NOT_COMPLETE</rc>
+ <description>
+ During gemini dram initialization, the memory initialization process
+ did not complete as reported by the Gemini calibration status register.
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>REGISTER</ffdc>
+ <ffdc>CONTENTS</ffdc>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
</hwpErrors>
diff --git a/src/import/chips/ocmb/procedures/hwp/initfiles/explorer_scom.C b/src/import/chips/ocmb/procedures/hwp/initfiles/explorer_scom.C
index 764f38274..964485726 100644
--- a/src/import/chips/ocmb/procedures/hwp/initfiles/explorer_scom.C
+++ b/src/import/chips/ocmb/procedures/hwp/initfiles/explorer_scom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -32,8 +32,9 @@ using namespace fapi2;
constexpr uint64_t literal_1 = 1;
constexpr uint64_t literal_3 = 3;
constexpr uint64_t literal_0 = 0;
-constexpr uint64_t literal_9 = 9;
+constexpr uint64_t literal_11 = 11;
constexpr uint64_t literal_4 = 4;
+constexpr uint64_t literal_9 = 9;
constexpr uint64_t literal_14 = 14;
constexpr uint64_t literal_7 = 7;
constexpr uint64_t literal_2 = 2;
@@ -42,7 +43,6 @@ constexpr uint64_t literal_5 = 5;
constexpr uint64_t literal_266 = 266;
constexpr uint64_t literal_1866 = 1866;
constexpr uint64_t literal_2668 = 2668;
-constexpr uint64_t literal_11 = 11;
constexpr uint64_t literal_2934 = 2934;
constexpr uint64_t literal_12 = 12;
constexpr uint64_t literal_13 = 13;
@@ -96,6 +96,7 @@ constexpr uint64_t literal_0b01010 = 0b01010;
constexpr uint64_t literal_0b00000 = 0b00000;
constexpr uint64_t literal_0b00010 = 0b00010;
constexpr uint64_t literal_0b00011 = 0b00011;
+constexpr uint64_t literal_0b0001 = 0b0001;
fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& TGT0,
const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& TGT1, const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT2,
@@ -105,6 +106,8 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
fapi2::ATTR_IS_SIMULATION_Type l_TGT2_ATTR_IS_SIMULATION;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, TGT2, l_TGT2_ATTR_IS_SIMULATION));
uint64_t l_def_IS_MICROSEMI_SIM = (l_TGT2_ATTR_IS_SIMULATION == literal_1);
+ fapi2::ATTR_MEM_EXP_DFIMRL_CLK_Type l_TGT1_ATTR_MEM_EXP_DFIMRL_CLK;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEM_EXP_DFIMRL_CLK, TGT1, l_TGT1_ATTR_MEM_EXP_DFIMRL_CLK));
fapi2::ATTR_MEM_RDIMM_BUFFER_DELAY_Type l_TGT1_ATTR_MEM_RDIMM_BUFFER_DELAY;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEM_RDIMM_BUFFER_DELAY, TGT1, l_TGT1_ATTR_MEM_RDIMM_BUFFER_DELAY));
fapi2::ATTR_MEM_EFF_DIMM_TYPE_Type l_TGT1_ATTR_MEM_EFF_DIMM_TYPE;
@@ -115,6 +118,7 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
fapi2::ATTR_MEM_EFF_DRAM_CL_Type l_TGT1_ATTR_MEM_EFF_DRAM_CL;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_CL, TGT1, l_TGT1_ATTR_MEM_EFF_DRAM_CL));
uint64_t l_def_IS_IBM_SIM = literal_0;
+ uint64_t l_def_IS_HW = (l_TGT2_ATTR_IS_SIMULATION == literal_0);
fapi2::ATTR_MEM_DRAM_CWL_Type l_TGT1_ATTR_MEM_DRAM_CWL;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEM_DRAM_CWL, TGT1, l_TGT1_ATTR_MEM_DRAM_CWL));
fapi2::ATTR_MEM_EFF_FREQ_Type l_TGT1_ATTR_MEM_EFF_FREQ;
@@ -172,10 +176,10 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
l_TGT1_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM[literal_1]);
uint64_t l_def_NUM_MRANKS_0 = ((l_TGT1_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM[literal_0] == literal_0x0) |
l_TGT1_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM[literal_0]);
- fapi2::ATTR_MEM_EFF_NUM_RANKS_PER_DIMM_Type l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM;
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_NUM_RANKS_PER_DIMM, TGT1, l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM));
- uint64_t l_def_NUM_SRANKS_1 = (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] / l_def_NUM_MRANKS_1);
- uint64_t l_def_NUM_SRANKS_0 = (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] / l_def_NUM_MRANKS_0);
+ fapi2::ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM_Type l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM, TGT1, l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM));
+ uint64_t l_def_NUM_SRANKS_1 = (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] / l_def_NUM_MRANKS_1);
+ uint64_t l_def_NUM_SRANKS_0 = (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] / l_def_NUM_MRANKS_0);
uint64_t l_def_disable_fast_act = ((((l_def_NUM_SRANKS_0 > literal_1) || (l_def_NUM_SRANKS_1 > literal_1))
&& ((l_def_NUM_MRANKS_0 == literal_4) || (l_def_NUM_MRANKS_1 == literal_4))) || l_def_half_dimm_mode);
fapi2::ATTR_MSS_MRW_DRAM_2N_MODE_Type l_TGT2_ATTR_MSS_MRW_DRAM_2N_MODE;
@@ -186,16 +190,24 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEM_MRW_IS_PLANAR, TGT0, l_TGT0_ATTR_MEM_MRW_IS_PLANAR));
uint64_t l_def_SLOT0_DENOMINATOR = ((l_TGT1_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM[literal_0] == literal_0x0) |
l_TGT1_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM[literal_0]);
- uint64_t l_def_SLOT0_DRAM_STACK_HEIGHT = (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] / l_def_SLOT0_DENOMINATOR);
+ uint64_t l_def_SLOT0_DRAM_STACK_HEIGHT = (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] /
+ l_def_SLOT0_DENOMINATOR);
uint64_t l_def_SLOT1_DENOMINATOR = ((l_TGT1_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM[literal_1] == literal_0x0) |
l_TGT1_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM[literal_1]);
- uint64_t l_def_SLOT1_DRAM_STACK_HEIGHT = (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] / l_def_SLOT1_DENOMINATOR);
+ uint64_t l_def_SLOT1_DRAM_STACK_HEIGHT = (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] /
+ l_def_SLOT1_DENOMINATOR);
fapi2::ATTR_MEM_SI_ODT_RD_Type l_TGT1_ATTR_MEM_SI_ODT_RD;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_ODT_RD, TGT1, l_TGT1_ATTR_MEM_SI_ODT_RD));
+ uint64_t l_def_dual_drop = ((l_TGT1_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM[literal_0] > literal_0)
+ && (l_TGT1_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM[literal_1] > literal_0));
+ fapi2::ATTR_MEM_EFF_FOUR_RANK_MODE_Type l_TGT1_ATTR_MEM_EFF_FOUR_RANK_MODE;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_FOUR_RANK_MODE, TGT1, l_TGT1_ATTR_MEM_EFF_FOUR_RANK_MODE));
+ uint64_t l_def_four_rank_mode = (l_TGT1_ATTR_MEM_EFF_FOUR_RANK_MODE[literal_0] == literal_1);
+ uint64_t l_def_cs_tied = ((l_def_four_rank_mode == literal_0) && (l_def_dual_drop == literal_0));
fapi2::ATTR_MEM_SI_ODT_WR_Type l_TGT1_ATTR_MEM_SI_ODT_WR;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_ODT_WR, TGT1, l_TGT1_ATTR_MEM_SI_ODT_WR));
- uint64_t l_def_NUM_RANKS = (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] +
- l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1]);
+ uint64_t l_def_NUM_RANKS = (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] +
+ l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1]);
uint64_t l_def_NUM_RANKS_DENOMINATOR = ((l_def_NUM_RANKS == literal_0x0) | l_def_NUM_RANKS);
fapi2::ATTR_MEM_EFF_DRAM_TREFI_Type l_TGT1_ATTR_MEM_EFF_DRAM_TREFI;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TREFI, TGT1, l_TGT1_ATTR_MEM_EFF_DRAM_TREFI));
@@ -219,8 +231,8 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
uint64_t l_def_row_bit16_val_1 = (l_TGT1_ATTR_MEM_EFF_DRAM_ROW_BITS[literal_1] >= literal_17);
uint64_t l_def_row_bit17_val_0 = (l_TGT1_ATTR_MEM_EFF_DRAM_ROW_BITS[literal_0] >= literal_18);
uint64_t l_def_row_bit17_val_1 = (l_TGT1_ATTR_MEM_EFF_DRAM_ROW_BITS[literal_1] >= literal_18);
- uint64_t l_def_slot_val_0 = (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] > literal_0);
- uint64_t l_def_slot_val_1 = (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] > literal_0);
+ uint64_t l_def_slot_val_0 = (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] > literal_0);
+ uint64_t l_def_slot_val_1 = (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] > literal_0);
uint64_t l_def_m0_val_0 = (l_def_NUM_MRANKS_0 > literal_2);
uint64_t l_def_m1_val_0 = (l_def_NUM_MRANKS_0 >= literal_2);
uint64_t l_def_m0_val_1 = (l_def_NUM_MRANKS_1 > literal_2);
@@ -229,18 +241,32 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
l_def_m0_val_0) + l_def_m1_val_0) + l_def_s0_val_0) + l_def_s1_val_0) + l_def_s2_val_0);
uint64_t l_def_num_of_bitvals_1 = (((((((l_def_row_bit17_val_1 + l_def_row_bit16_val_1) + l_def_row_bit15_val_1) +
l_def_m0_val_1) + l_def_m1_val_1) + l_def_s0_val_1) + l_def_s1_val_1) + l_def_s2_val_1);
+ fapi2::ATTR_MSS_OCMB_CHECKSTOP_OBJ_HANDLE_Type l_TGT2_ATTR_MSS_OCMB_CHECKSTOP_OBJ_HANDLE;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_CHECKSTOP_OBJ_HANDLE, TGT2, l_TGT2_ATTR_MSS_OCMB_CHECKSTOP_OBJ_HANDLE));
+ fapi2::ATTR_MSS_OCMB_RECOV_OBJ_HANDLE_Type l_TGT2_ATTR_MSS_OCMB_RECOV_OBJ_HANDLE;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_RECOV_OBJ_HANDLE, TGT2, l_TGT2_ATTR_MSS_OCMB_RECOV_OBJ_HANDLE));
+ fapi2::ATTR_MSS_OCMB_SPECATTN_OBJ_HANDLE_Type l_TGT2_ATTR_MSS_OCMB_SPECATTN_OBJ_HANDLE;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_SPECATTN_OBJ_HANDLE, TGT2, l_TGT2_ATTR_MSS_OCMB_SPECATTN_OBJ_HANDLE));
+ fapi2::ATTR_MSS_OCMB_APPINTR_OBJ_HANDLE_Type l_TGT2_ATTR_MSS_OCMB_APPINTR_OBJ_HANDLE;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_APPINTR_OBJ_HANDLE, TGT2, l_TGT2_ATTR_MSS_OCMB_APPINTR_OBJ_HANDLE));
fapi2::buffer<uint64_t> l_scom_buffer;
{
FAPI_TRY(fapi2::getScom( TGT0, 0x801140cull, l_scom_buffer ));
if (l_def_IS_MICROSEMI_SIM)
{
- l_scom_buffer.insert<36, 6, 58, uint64_t>(((l_TGT1_ATTR_MEM_EFF_DRAM_CL - literal_9) + l_def_RDIMM_Add_latency) );
+ l_scom_buffer.insert<36, 6, 58, uint64_t>((((l_TGT1_ATTR_MEM_EFF_DRAM_CL - literal_11) + l_def_RDIMM_Add_latency) +
+ l_TGT1_ATTR_MEM_EXP_DFIMRL_CLK) );
}
else if (l_def_IS_IBM_SIM)
{
l_scom_buffer.insert<36, 6, 58, uint64_t>(((l_TGT1_ATTR_MEM_EFF_DRAM_CL - literal_4) + l_def_RDIMM_Add_latency) );
}
+ else if (l_def_IS_HW)
+ {
+ l_scom_buffer.insert<36, 6, 58, uint64_t>((((l_TGT1_ATTR_MEM_EFF_DRAM_CL - literal_11) + l_def_RDIMM_Add_latency) +
+ l_TGT1_ATTR_MEM_EXP_DFIMRL_CLK) );
+ }
if (l_def_IS_MICROSEMI_SIM)
{
@@ -250,6 +276,10 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
{
l_scom_buffer.insert<47, 5, 59, uint64_t>(((l_TGT1_ATTR_MEM_EFF_DRAM_CL - literal_4) + l_def_RDIMM_Add_latency) );
}
+ else if (l_def_IS_HW)
+ {
+ l_scom_buffer.insert<47, 5, 59, uint64_t>(((l_TGT1_ATTR_MEM_EFF_DRAM_CL - literal_9) + l_def_RDIMM_Add_latency) );
+ }
if (l_def_IS_MICROSEMI_SIM)
{
@@ -259,6 +289,10 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
{
l_scom_buffer.insert<42, 5, 59, uint64_t>(((l_TGT1_ATTR_MEM_EFF_DRAM_CL - literal_4) + l_def_RDIMM_Add_latency) );
}
+ else if (l_def_IS_HW)
+ {
+ l_scom_buffer.insert<42, 5, 59, uint64_t>(((l_TGT1_ATTR_MEM_EFF_DRAM_CL - literal_9) + l_def_RDIMM_Add_latency) );
+ }
if (l_def_IS_MICROSEMI_SIM)
{
@@ -268,6 +302,10 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
{
l_scom_buffer.insert<30, 6, 58, uint64_t>(((l_TGT1_ATTR_MEM_DRAM_CWL - literal_9) + l_def_RDIMM_Add_latency) );
}
+ else if (l_def_IS_HW)
+ {
+ l_scom_buffer.insert<30, 6, 58, uint64_t>(((l_TGT1_ATTR_MEM_DRAM_CWL - literal_14) + l_def_RDIMM_Add_latency) );
+ }
if (l_def_IS_MICROSEMI_SIM)
{
@@ -277,6 +315,10 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
{
l_scom_buffer.insert<57, 5, 59, uint64_t>(((l_TGT1_ATTR_MEM_DRAM_CWL - literal_2) + l_def_RDIMM_Add_latency) );
}
+ else if (l_def_IS_HW)
+ {
+ l_scom_buffer.insert<57, 5, 59, uint64_t>(((l_TGT1_ATTR_MEM_DRAM_CWL - literal_7) + l_def_RDIMM_Add_latency) );
+ }
if (l_def_IS_MICROSEMI_SIM)
{
@@ -286,6 +328,10 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
{
l_scom_buffer.insert<52, 5, 59, uint64_t>(((l_TGT1_ATTR_MEM_DRAM_CWL - literal_2) + l_def_RDIMM_Add_latency) );
}
+ else if (l_def_IS_HW)
+ {
+ l_scom_buffer.insert<52, 5, 59, uint64_t>(((l_TGT1_ATTR_MEM_DRAM_CWL - literal_7) + l_def_RDIMM_Add_latency) );
+ }
l_scom_buffer.insert<24, 6, 58, uint64_t>(literal_24 );
l_scom_buffer.insert<0, 6, 58, uint64_t>(((l_TGT1_ATTR_MEM_EFF_DRAM_CL - l_TGT1_ATTR_MEM_DRAM_CWL) +
@@ -589,12 +635,20 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
l_scom_buffer.insert<0, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_0] >> literal_7) );
l_scom_buffer.insert<1, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_0] >> literal_6) );
- l_scom_buffer.insert<2, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_0] >> literal_3) );
- l_scom_buffer.insert<3, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_0] >> literal_2) );
+ l_scom_buffer.insert<2, 1, 63, uint64_t>(((((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_0] >> literal_3) &
+ literal_0b1) && (l_def_cs_tied == literal_0))
+ || (((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_0] >> literal_7) & literal_0b1) && (l_def_cs_tied == literal_1))) );
+ l_scom_buffer.insert<3, 1, 63, uint64_t>(((((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_0] >> literal_2) &
+ literal_0b1) && (l_def_cs_tied == literal_0))
+ || (((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_0] >> literal_6) & literal_0b1) && (l_def_cs_tied == literal_1))) );
l_scom_buffer.insert<4, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_1] >> literal_7) );
l_scom_buffer.insert<5, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_1] >> literal_6) );
- l_scom_buffer.insert<6, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_1] >> literal_3) );
- l_scom_buffer.insert<7, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_1] >> literal_2) );
+ l_scom_buffer.insert<6, 1, 63, uint64_t>(((((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_1] >> literal_3) &
+ literal_0b1) && (l_def_cs_tied == literal_0))
+ || (((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_1] >> literal_7) & literal_0b1) && (l_def_cs_tied == literal_1))) );
+ l_scom_buffer.insert<7, 1, 63, uint64_t>(((((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_1] >> literal_2) &
+ literal_0b1) && (l_def_cs_tied == literal_0))
+ || (((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_1] >> literal_6) & literal_0b1) && (l_def_cs_tied == literal_1))) );
l_scom_buffer.insert<8, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_2] >> literal_7) );
l_scom_buffer.insert<9, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_2] >> literal_6) );
l_scom_buffer.insert<10, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_0][literal_2] >> literal_3) );
@@ -621,12 +675,20 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
l_scom_buffer.insert<31, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_RD[literal_1][literal_3] >> literal_2) );
l_scom_buffer.insert<32, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_0] >> literal_7) );
l_scom_buffer.insert<33, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_0] >> literal_6) );
- l_scom_buffer.insert<34, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_0] >> literal_3) );
- l_scom_buffer.insert<35, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_0] >> literal_2) );
+ l_scom_buffer.insert<34, 1, 63, uint64_t>(((((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_0] >> literal_3) &
+ literal_0b1) && (l_def_cs_tied == literal_0))
+ || (((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_0] >> literal_7) & literal_0b1) && (l_def_cs_tied == literal_1))) );
+ l_scom_buffer.insert<35, 1, 63, uint64_t>(((((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_0] >> literal_2) &
+ literal_0b1) && (l_def_cs_tied == literal_0))
+ || (((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_0] >> literal_6) & literal_0b1) && (l_def_cs_tied == literal_1))) );
l_scom_buffer.insert<36, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_1] >> literal_7) );
l_scom_buffer.insert<37, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_1] >> literal_6) );
- l_scom_buffer.insert<38, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_1] >> literal_3) );
- l_scom_buffer.insert<39, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_1] >> literal_2) );
+ l_scom_buffer.insert<38, 1, 63, uint64_t>(((((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_1] >> literal_3) &
+ literal_0b1) && (l_def_cs_tied == literal_0))
+ || (((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_1] >> literal_7) & literal_0b1) && (l_def_cs_tied == literal_1))) );
+ l_scom_buffer.insert<39, 1, 63, uint64_t>(((((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_1] >> literal_2) &
+ literal_0b1) && (l_def_cs_tied == literal_0))
+ || (((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_1] >> literal_6) & literal_0b1) && (l_def_cs_tied == literal_1))) );
l_scom_buffer.insert<40, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_2] >> literal_7) );
l_scom_buffer.insert<41, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_2] >> literal_6) );
l_scom_buffer.insert<42, 1, 63, uint64_t>((l_TGT1_ATTR_MEM_SI_ODT_WR[literal_0][literal_2] >> literal_3) );
@@ -775,70 +837,71 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
}
l_scom_buffer.insert<46, 11, 53, uint64_t>(l_def_REFRESH_INTERVAL );
+ l_scom_buffer.insert<62, 1, 63, uint64_t>(literal_1 );
FAPI_TRY(fapi2::putScom(TGT0, 0x8011437ull, l_scom_buffer));
}
{
FAPI_TRY(fapi2::getScom( TGT0, 0x801186full, l_scom_buffer ));
- if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<59, 5, 59, uint64_t>(literal_0b01011 );
}
- else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<59, 5, 59, uint64_t>(literal_0b01100 );
}
- else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<59, 5, 59, uint64_t>(literal_0b01100 );
}
- else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<59, 5, 59, uint64_t>(literal_0b01101 );
}
- if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<54, 5, 59, uint64_t>(literal_0b01100 );
}
- else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<54, 5, 59, uint64_t>(literal_0b01101 );
}
- else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<54, 5, 59, uint64_t>(literal_0b01101 );
}
- else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<54, 5, 59, uint64_t>(literal_0b01110 );
}
- if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<49, 5, 59, uint64_t>(literal_0b01101 );
}
- else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<49, 5, 59, uint64_t>(literal_0b01110 );
}
- else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<49, 5, 59, uint64_t>(literal_0b01110 );
}
- else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<49, 5, 59, uint64_t>(literal_0b01111 );
}
@@ -1298,92 +1361,92 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
l_scom_buffer.insert<38, 5, 59, uint64_t>(literal_0b10011 );
}
- if (((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] < literal_2)
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] < literal_2)))
+ if (((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] < literal_2)
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] < literal_2)))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b00110 );
}
else if (((l_def_half_dimm_mode == literal_1) && ((l_def_num_of_bitvals_0 == literal_1)
- && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] >= literal_2)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] >= literal_2)))))
+ && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] >= literal_2)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] >= literal_2)))))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b01100 );
}
else if (((l_def_half_dimm_mode == literal_1) && ((l_def_num_of_bitvals_0 == literal_2)
- && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] >= literal_2)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] >= literal_2)))))
+ && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] >= literal_2)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] >= literal_2)))))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b01101 );
}
else if (((l_def_half_dimm_mode == literal_1) && ((l_def_num_of_bitvals_0 == literal_3)
- && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] >= literal_2)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] >= literal_2)))))
+ && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] >= literal_2)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] >= literal_2)))))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b01110 );
}
else if (((l_def_half_dimm_mode == literal_1) && ((l_def_num_of_bitvals_0 == literal_4)
- && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] >= literal_2)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] >= literal_2)))))
+ && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] >= literal_2)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] >= literal_2)))))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b01111 );
}
else if (((l_def_half_dimm_mode == literal_1) && ((l_def_num_of_bitvals_0 == literal_5)
- && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] >= literal_2)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] >= literal_2)))))
+ && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] >= literal_2)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] >= literal_2)))))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b10000 );
}
else if (((l_def_half_dimm_mode == literal_1) && ((l_def_num_of_bitvals_0 == literal_6)
- && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] >= literal_2)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] >= literal_2)))))
+ && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] >= literal_2)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] >= literal_2)))))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b10001 );
}
else if (((l_def_half_dimm_mode == literal_1) && ((l_def_num_of_bitvals_0 == literal_7)
- && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] >= literal_2)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] >= literal_2)))))
+ && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] >= literal_2)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] >= literal_2)))))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b10010 );
}
else if (((l_def_half_dimm_mode == literal_0) && ((l_def_num_of_bitvals_0 == literal_1)
- && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] >= literal_2)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] >= literal_2)))))
+ && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] >= literal_2)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] >= literal_2)))))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b01101 );
}
else if (((l_def_half_dimm_mode == literal_0) && ((l_def_num_of_bitvals_0 == literal_2)
- && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] >= literal_2)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] >= literal_2)))))
+ && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] >= literal_2)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] >= literal_2)))))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b01110 );
}
else if (((l_def_half_dimm_mode == literal_0) && ((l_def_num_of_bitvals_0 == literal_3)
- && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] >= literal_2)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] >= literal_2)))))
+ && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] >= literal_2)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] >= literal_2)))))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b01111 );
}
else if (((l_def_half_dimm_mode == literal_0) && ((l_def_num_of_bitvals_0 == literal_4)
- && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] >= literal_2)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] >= literal_2)))))
+ && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] >= literal_2)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] >= literal_2)))))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b10000 );
}
else if (((l_def_half_dimm_mode == literal_0) && ((l_def_num_of_bitvals_0 == literal_5)
- && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] >= literal_2)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] >= literal_2)))))
+ && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] >= literal_2)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] >= literal_2)))))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b10001 );
}
else if (((l_def_half_dimm_mode == literal_0) && ((l_def_num_of_bitvals_0 == literal_6)
- && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] >= literal_2)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] >= literal_2)))))
+ && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] >= literal_2)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] >= literal_2)))))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b10010 );
}
else if (((l_def_half_dimm_mode == literal_0) && ((l_def_num_of_bitvals_0 == literal_7)
- && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] >= literal_2)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] >= literal_2)))))
+ && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] >= literal_2)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] >= literal_2)))))
{
l_scom_buffer.insert<33, 5, 59, uint64_t>(literal_0b10011 );
}
@@ -1429,76 +1492,76 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
{
l_scom_buffer.insert<35, 5, 59, uint64_t>(literal_0b00101 );
}
- else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<35, 5, 59, uint64_t>(literal_0b00110 );
}
- else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<35, 5, 59, uint64_t>(literal_0b00111 );
}
- if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<43, 5, 59, uint64_t>(literal_0b00110 );
}
- else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<43, 5, 59, uint64_t>(literal_0b00111 );
}
- else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<43, 5, 59, uint64_t>(literal_0b00111 );
}
- else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<43, 5, 59, uint64_t>(literal_0b01000 );
}
- if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<51, 5, 59, uint64_t>(literal_0b00111 );
}
- else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<51, 5, 59, uint64_t>(literal_0b01000 );
}
- else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<51, 5, 59, uint64_t>(literal_0b01000 );
}
- else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<51, 5, 59, uint64_t>(literal_0b01001 );
}
- if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<59, 5, 59, uint64_t>(literal_0b01000 );
}
- else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<59, 5, 59, uint64_t>(literal_0b01001 );
}
- else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<59, 5, 59, uint64_t>(literal_0b01001 );
}
- else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<59, 5, 59, uint64_t>(literal_0b01010 );
}
@@ -1646,50 +1709,83 @@ fapi2::ReturnCode explorer_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP
l_scom_buffer.insert<19, 5, 59, uint64_t>(literal_0b00101 );
}
- if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<3, 5, 59, uint64_t>(literal_0b01001 );
}
- else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<3, 5, 59, uint64_t>(literal_0b01010 );
}
- else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<3, 5, 59, uint64_t>(literal_0b01010 );
}
- else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<3, 5, 59, uint64_t>(literal_0b01011 );
}
- if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ if (((l_def_half_dimm_mode == literal_1) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<11, 5, 59, uint64_t>(literal_0b01010 );
}
- else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_1) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<11, 5, 59, uint64_t>(literal_0b01011 );
}
- else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] == literal_1)
- || (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] == literal_1))))
+ else if (((l_def_half_dimm_mode == literal_0) && ((l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] == literal_1)
+ || (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] == literal_1))))
{
l_scom_buffer.insert<11, 5, 59, uint64_t>(literal_0b01011 );
}
- else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_0] != literal_1))
- && (l_TGT1_ATTR_MEM_EFF_NUM_RANKS_PER_DIMM[literal_1] != literal_1)))
+ else if ((((l_def_half_dimm_mode == literal_0) && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_0] != literal_1))
+ && (l_TGT1_ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM[literal_1] != literal_1)))
{
l_scom_buffer.insert<11, 5, 59, uint64_t>(literal_0b01100 );
}
FAPI_TRY(fapi2::putScom(TGT0, 0x8011871ull, l_scom_buffer));
}
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x801240dull, l_scom_buffer ));
+
+ l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b0001 );
+ l_scom_buffer.insert<52, 4, 60, uint64_t>(literal_0b0001 );
+ l_scom_buffer.insert<56, 4, 60, uint64_t>(literal_0b0001 );
+ l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0001 );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x801240dull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8012410ull, l_scom_buffer ));
+
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(l_TGT2_ATTR_MSS_OCMB_CHECKSTOP_OBJ_HANDLE );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8012410ull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8012411ull, l_scom_buffer ));
+
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(l_TGT2_ATTR_MSS_OCMB_RECOV_OBJ_HANDLE );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8012411ull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8012412ull, l_scom_buffer ));
+
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(l_TGT2_ATTR_MSS_OCMB_SPECATTN_OBJ_HANDLE );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8012412ull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8012413ull, l_scom_buffer ));
+
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(l_TGT2_ATTR_MSS_OCMB_APPINTR_OBJ_HANDLE );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8012413ull, l_scom_buffer));
+ }
};
fapi_try_exit:
diff --git a/src/import/chips/p9/common/include/p9_frequency_buckets.H b/src/import/chips/p9/common/include/p9_frequency_buckets.H
index ab6af1b5d..2ac8574d5 100644
--- a/src/import/chips/p9/common/include/p9_frequency_buckets.H
+++ b/src/import/chips/p9/common/include/p9_frequency_buckets.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -65,6 +65,30 @@ const uint32_t MEM_PLL_FREQ_LIST[MEM_PLL_FREQ_BUCKETS] =
2666
};
+// OMI bucket descriptor
+struct OmiBucketDescriptor_t
+{
+ uint32_t omifreq; // OMI Frequency in MHz
+ uint32_t vco; // VCO selector
+
+ uint32_t mcafreq; // MCA Frequency in MHz
+};
+
+//MC PLL frequency in MHz for Axone
+// index is bucket number
+// OMI -> ATTR_FREQ_OMI_MHZ
+// VCO -> ATTR_OMI_PLL_VCO
+// MCA -> ATTR_FREQ_MCA_MHZ
+const OmiBucketDescriptor_t OMI_PLL_FREQ_LIST[MEM_PLL_FREQ_BUCKETS] =
+{
+ // OMI VCO MCA Data rate
+ { 19200, 0, 1200 }, // ->DDR4-2400
+ { 21330, 0, 1333 }, // ->DDR4-2667
+ { 23460, 0, 1466 }, // ->DDR4-2933
+ { 23460, 1, 1466 }, // ->DDR4-2933
+ { 25600, 1, 1600 } // ->DDR4-3200
+};
+
// constant definining number of OBUS PLL frequency options ('buckets')
// to be built into unsigned HW image
const uint8_t OBUS_PLL_FREQ_BUCKETS = 3;
diff --git a/src/import/chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h b/src/import/chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h
index b8d4c030e..0a51fbca3 100644
--- a/src/import/chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h
+++ b/src/import/chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h
@@ -41,7 +41,8 @@
extern "C" {
#endif
-#define HCODE_OCC_SHARED_MAGIC_NUMBER 0x4F505330 //OPS0
+#define HCODE_OCC_SHARED_MAGIC_NUMBER_OPS0 0x4F505330 //OPS0
+#define HCODE_OCC_SHARED_MAGIC_NUMBER_OPS1 0x4F505331 //OPS1
//---------------
// IPC from 405
@@ -409,17 +410,9 @@ typedef struct
// -----------------------------------------------------------------------------
// Start Error Log Table
-/// Maximum number of error log entries available
-#define MAX_HCODE_ELOG_ENTRIES 4
-
-/// Index into the array of error log entries
-enum elog_entry_index
-{
- ELOG_PGPE_CRITICAL = 0,
- ELOG_PGPE_INFO = 1,
- ELOG_SGPE_CRITICAL = 2,
- ELOG_SGPE_INFO = 3,
-};
+/// Maximum number of error log entries available, 1 UE per SPGE & PGPE
+#define MAX_HCODE_ELOG_ENTRIES 2
+#define HCODE_ELOG_TABLE_MAGIC_WORD 0x454C5443 // "ELTC"
/// Structure of an individual error log entry
typedef struct
@@ -461,7 +454,7 @@ typedef struct hcode_error_table
} fields;
} dw0;
- /// Array of error log entries (index with enum elog_entry_index)
+ /// Array of error log entries
hcode_elog_entry_t elog[MAX_HCODE_ELOG_ENTRIES];
} hcode_error_table_t;
@@ -491,9 +484,6 @@ typedef struct
//PGPE WOF Values
pgpe_wof_values_t pgpe_wof_values;
- //Reserved
- uint64_t reserved1;
-
/// Hcode Error Log Index
hcode_error_table_t errlog_idx;
diff --git a/src/import/chips/p9/common/scominfo/p9_cu.H b/src/import/chips/p9/common/scominfo/p9_cu.H
index 620e072a9..180828620 100644
--- a/src/import/chips/p9/common/scominfo/p9_cu.H
+++ b/src/import/chips/p9/common/scominfo/p9_cu.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -68,7 +68,8 @@ extern "C"
PU_PPE_CHIPUNIT, ///< PPE
PU_SBE_CHIPUNIT, ///< SBE
PU_CAPP_CHIPUNIT, ///< CAPP
- PU_MC_CHIPUNIT, ///< mc
+ PU_MC_CHIPUNIT, ///< mc
+ PU_NPU_CHIPUNIT, ///< NPU
NONE, ///< None/Invalid
} p9ChipUnits_t;
diff --git a/src/import/chips/p9/common/scominfo/p9_scom_addr.H b/src/import/chips/p9/common/scominfo/p9_scom_addr.H
index 513cf0db6..b3d1186c0 100644
--- a/src/import/chips/p9/common/scominfo/p9_scom_addr.H
+++ b/src/import/chips/p9/common/scominfo/p9_scom_addr.H
@@ -452,6 +452,13 @@ extern "C"
P9A_MC_OMI2_FRST_LANE = 0x10, ///< First lane of OMI % 3 = 2
} p9a_mc_lane_t;
+ typedef enum
+ {
+ P9A_NPU_2_RING_ID = 0x7,
+ P9A_NPU_2_FIR_RING_ID = 0x8,
+ P9A_NPU_0_FIR_RING_ID = 0xF,
+ } p9a_npu_ring_id_t;
+
// 8 7 6 5 4 3 2 1
//
// |0 1 2 3| |4 5 6 7| |8 9 10 11| |12 13 14 15| |16 17 18 19| |20 21 22 23| |24 25 26 27| |28 29 30 31|
diff --git a/src/import/chips/p9/common/scominfo/p9_scominfo.C b/src/import/chips/p9/common/scominfo/p9_scominfo.C
index 0039625ca..ff80a3161 100644
--- a/src/import/chips/p9/common/scominfo/p9_scominfo.C
+++ b/src/import/chips/p9/common/scominfo/p9_scominfo.C
@@ -646,6 +646,66 @@ extern "C"
break;
+ case PU_NPU_CHIPUNIT:
+
+ // NPU0 and NPU1 exist on the N3 chiplet, NPU2 exists on the N1 chiplet instead
+ l_chiplet_id = ( 2 == i_chipUnitNum ) ? N1_CHIPLET_ID : N3_CHIPLET_ID ;
+ l_scom.set_chiplet_id( l_chiplet_id );
+
+ // Covers the following addresses:
+ // NPU0: 05011000 to 050113FF
+ // NPU1: 05011400 to 050117FF
+ // NPU2: 03011C00 to 03011FFF
+ if ( N3_NPU_0_RING_ID == l_ring ||
+ N3_NPU_1_RING_ID == l_ring ||
+ P9A_NPU_2_RING_ID == l_ring )
+ {
+ // NPU0/NPU1
+ if ( N3_CHIPLET_ID == l_chiplet_id )
+ {
+ l_scom.set_ring( N3_NPU_0_RING_ID + i_chipUnitNum );
+ }
+ // NPU2
+ else if ( N1_CHIPLET_ID == l_chiplet_id )
+ {
+ l_scom.set_ring( P9A_NPU_2_RING_ID );
+ }
+ else
+ {
+ l_scom.set_addr( FAILED_TRANSLATION );
+ }
+ }
+ // Covers the following addresses:
+ // NPU0: 05013C00 to 05013C8F
+ // NPU1: 05013CC0 to 05013D4F
+ // NPU2: 03012000 to 0301208F
+ else if ( P9A_NPU_0_FIR_RING_ID == l_ring ||
+ P9A_NPU_2_FIR_RING_ID == l_ring )
+ {
+ // NPU0/NPU1
+ if ( N3_CHIPLET_ID == l_chiplet_id )
+ {
+ l_scom.set_ring( P9A_NPU_0_FIR_RING_ID );
+ l_scom.set_sat_id( (l_sat_id % 3) + (3 * i_chipUnitNum) );
+ }
+ // NPU2
+ else if ( N1_CHIPLET_ID == l_chiplet_id )
+ {
+ l_scom.set_ring( P9A_NPU_2_FIR_RING_ID );
+ l_scom.set_sat_id( l_sat_id % 3 );
+ }
+ else
+ {
+ l_scom.set_addr( FAILED_TRANSLATION );
+ }
+ }
+ else
+ {
+ l_scom.set_addr( FAILED_TRANSLATION );
+ }
+
+ break;
+
default:
l_scom.set_addr(FAILED_TRANSLATION);
break;
@@ -1179,7 +1239,7 @@ extern "C"
}
}
- if (P9A_MC_OMIC0_PPE_RING_ID <= l_ring && l_ring < P9A_MC_OMIC2_PPE_RING_ID && l_port == UNIT_PORT_ID)
+ if (P9A_MC_OMIC0_PPE_RING_ID <= l_ring && l_ring <= P9A_MC_OMIC2_PPE_RING_ID && l_port == UNIT_PORT_ID)
{
o_chipUnitRelated = true;
o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_OMIC_CHIPUNIT,
@@ -1498,6 +1558,37 @@ extern "C"
o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_PPE_CHIPUNIT,
(l_chiplet_id - OB0_CHIPLET_ID) + PPE_IO_OB0_CHIPUNIT_NUM));
}
+
+ // PU_NPU_CHIPUNIT
+ // npu: 0..1
+ if ( (l_port == UNIT_PORT_ID) &&
+ (l_chiplet_id == N3_CHIPLET_ID) &&
+ (N3_NPU_0_RING_ID <= l_ring && l_ring <= N3_NPU_1_RING_ID) )
+ {
+ o_chipUnitRelated = true;
+ o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_NPU_CHIPUNIT,
+ (l_ring - N3_NPU_0_RING_ID)));
+ }
+
+ if ( (l_port == UNIT_PORT_ID) &&
+ (l_chiplet_id == N3_CHIPLET_ID) &&
+ (l_ring == P9A_NPU_0_FIR_RING_ID) )
+ {
+ o_chipUnitRelated = true;
+ o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_NPU_CHIPUNIT,
+ (l_sat_id / 3)));
+ }
+
+ // PU_NPU_CHIPUNIT
+ // npu: 2
+ if ( (l_port == UNIT_PORT_ID) &&
+ (l_chiplet_id == N1_CHIPLET_ID) &&
+ (l_ring == P9A_NPU_2_RING_ID || l_ring == P9A_NPU_2_FIR_RING_ID) )
+ {
+ o_chipUnitRelated = true;
+ o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_NPU_CHIPUNIT, 2));
+ }
+
}
return (!l_scom.is_valid());
diff --git a/src/import/chips/p9/initfiles/p9a.int.scan.initfile b/src/import/chips/p9/initfiles/p9a.int.scan.initfile
new file mode 100644
index 000000000..745c936d3
--- /dev/null
+++ b/src/import/chips/p9/initfiles/p9a.int.scan.initfile
@@ -0,0 +1,47 @@
+#-- *!***************************************************************************
+#-- *!
+#-- *! OWNER NAME : David Kauer (dmkauer@us.ibm.com)
+#-- *!
+#-- *!***************************************************************************
+
+
+SyntaxVersion = 3
+
+target_type 0 TARGET_TYPE_PROC_CHIP;
+
+# Enabled for DD1 only
+ispy INT.INT_PC_LBS1_CMD_MMIO_LDST_CS [when=L && ATTR_CHIP_EC_FEATURE_P9N_INT_DD10] {
+ bits, spyv;
+ 5, 0b1;
+ 6, 0b1;
+}
+
+# Defect HW378025 / Nimbus DD1 only
+ispy INT.INT_PC_LBS1_REGS_CLOCKGATE_DIS_CS [when=L && ATTR_CHIP_EC_FEATURE_HW378025] {
+ spyv;
+ 0b1;
+}
+
+# Defect HW930007 / Nimbus DD1 only
+ispy INT.INT_PC.LBS2.VPC.P1.LCBCNTL_BLK.CLOCKGATE_DISABLE [when=L && ATTR_CHIP_EC_FEATURE_HW930007] {
+ spyv;
+ 0b1;
+}
+
+# Defect HW408972 / Nimbus DD1 & DD2
+ispy INT.INT_PC_LBS1_CRESP_MAC_CS [when=L && ATTR_CHIP_EC_FEATURE_HW408972] {
+ bits, spyv, expr;
+ 3, 0b1, ((ATTR_CHIP_EC_FEATURE_P9N_INT_DD10 == 1) || (ATTR_CHIP_EC_FEATURE_P9N_INT_DD20 == 1));
+ 4, 0b1, (ATTR_CHIP_EC_FEATURE_P9N_INT_DD21 == 1);
+}
+
+# Defect HW388874
+espy BRIDGE.PSIHB.ESB_OR_LSI_INTERRUPTS [when=L] {
+ spyv, expr;
+ ON, (ATTR_CHIP_EC_FEATURE_HW388874 == 0);
+}
+# HW441771 - Axone init to return to P9 behavior
+ispy INT.INT_VC_LBS6_ARX_CS_AXONE_DISABLE_CILOAD_ORDERINGS [when=L && ATTR_CHIP_EC_FEATURE_AXONE_HW441771] {
+ spyv;
+ 0b1;
+}
diff --git a/src/import/chips/p9/initfiles/p9a.int.scom.initfile b/src/import/chips/p9/initfiles/p9a.int.scom.initfile
new file mode 100644
index 000000000..5b0ff1886
--- /dev/null
+++ b/src/import/chips/p9/initfiles/p9a.int.scom.initfile
@@ -0,0 +1,178 @@
+#- *!***************************************************************************
+#-- *!
+#-- *! OWNER NAME : David Kauer (dmkauer@us.ibm.com)
+#-- *!
+#-- *!***************************************************************************
+
+SyntaxVersion = 3
+
+target_type 0 TARGET_TYPE_PROC_CHIP;
+target_type 1 TARGET_TYPE_SYSTEM;
+
+ispy INT.INT_PC.INT_PC_AIB_TX_CRD_RSD_CRD_VPC_LD_RMT [when=S && ATTR_CHIP_EC_FEATURE_P9N_INT_DD10] {
+ spyv;
+ 0b00;
+}
+
+ispy INT.INT_VC.INT_VC_EQC_CONFIG_PAGE_OFFSET_CFG [when=S] {
+ spyv;
+ 0x5BBF;
+}
+
+ispy INT.INT_VC.INT_VC_IRQ_TO_EQC_CREDITS [when=S] {
+ spyv;
+ 0x6262220242160000;
+}
+
+# SW437676 / SW445631
+ispy INT.INT_VC.INT_VC_AIB_TIMEOUT [when=S] {
+ spyv;
+ 0x18;
+}
+
+ispy INT.INT_PC.INT_PC_DBG_TMOT_ARX_TIMEOUT [when=S] {
+ spyv;
+ 0x18;
+}
+
+ispy INT.INT_PC.INT_PC_DBG_TMOT_MMIO_LDST_TIMEOUT [when=S] {
+ spyv;
+ 0x18;
+}
+
+# Defect HW372116 / Nimbus DD1 only
+ispy INT.INT_CQ.INT_CQ_AIB_CTL [when=S && ATTR_CHIP_EC_FEATURE_HW372116] {
+ spyv;
+ 0x0070000072040140;
+}
+
+# Defect HW395947 / Nimbus DD1 only
+espy INT.INT_VC.INT_VC_AIB_TX_ORDERING_TAG_2_RELAXED_WR_ORDERING_DMA [when=S && ATTR_CHIP_EC_FEATURE_HW395947] {
+ spyv;
+ OFF;
+}
+
+espy INT.INT_PC.INT_PC_AIB_TX_ORDER_RELAXED_WR_ORDERING [when=S && ATTR_CHIP_EC_FEATURE_HW395947] {
+ spyv;
+ OFF;
+}
+
+# Error Configuration
+ispy INT.INT_PC.INT_PC_ERR0_CFG0_ERROR_CONFIG0 [when=S] {
+ spyv, expr;
+ 0x010003FF00100020, (ATTR_CHIP_EC_FEATURE_HW426891 == 0);
+ 0x050043EF00100020, (ATTR_CHIP_EC_FEATURE_HW426891 == 1);
+}
+
+ispy INT.INT_PC.INT_PC_ERR0_CFG1_ERROR_CONFIG0 [when=S] {
+ spyv, expr;
+ 0xD8DFB200DFAFFFD7, (ATTR_CHIP_EC_FEATURE_HW426891 == 0);
+ 0xFADFBB8CFFAFFFD7, (ATTR_CHIP_EC_FEATURE_HW426891 == 1);
+}
+
+ispy INT.INT_PC.INT_PC_ERR1_CFG0_ERROR_CONFIG0 [when=S && ATTR_CHIP_EC_FEATURE_P9N_INT_DD10] {
+ spyv;
+ 0x0008002000002002;
+}
+
+ispy INT.INT_PC.INT_PC_ERR1_CFG1_ERROR_CONFIG0 [when=S && ATTR_CHIP_EC_FEATURE_P9N_INT_DD10] {
+ spyv;
+ 0xEF6417D2DE7DD3FD;
+}
+
+ispy INT.INT_PC.LBS2.INT_PC_VPC_ERR_CFG0_ERROR_CONFIG [when=S] {
+ spyv, expr;
+ 0x0002000410000000, (ATTR_CHIP_EC_FEATURE_HW426891 == 0);
+ 0x0002000610000000, (ATTR_CHIP_EC_FEATURE_HW426891 == 1);
+}
+
+ispy INT.INT_PC.LBS2.INT_PC_VPC_ERR_CFG1_ERROR_CONFIG [when=S && ATTR_CHIP_EC_FEATURE_P9N_INT_DD10] {
+ spyv;
+ 0x7710CCC3E0000701;
+}
+
+ispy INT.INT_VC.INT_VC_ERR_CFG_G0R0_ERROR_CONFIG [when=S && ATTR_CHIP_EC_FEATURE_P9N_INT_DD10] {
+ spyv;
+ 0x00001003000002;
+}
+
+ispy INT.INT_VC.INT_VC_ERR_CFG_G0R1_ERROR_CONFIG [when=S && ATTR_CHIP_EC_FEATURE_P9N_INT_DD10] {
+ spyv;
+ 0xFFFFEFFCFFFFFC;
+}
+
+ispy INT.INT_VC.INT_VC_ERR_CFG_G1R0_ERROR_CONFIG [when=S && ATTR_CHIP_EC_FEATURE_HW411637] {
+ spyv;
+ 0x0002C018006;
+}
+
+ispy INT.INT_VC.INT_VC_ERR_CFG_G1R1_ERROR_CONFIG [when=S && ATTR_CHIP_EC_FEATURE_HW411637] {
+ spyv;
+ 0xFFFCFFEFFFA;
+}
+
+
+# FIR Registers
+ispy INT.INT_CQ.INT_CQ_FIRMASK_FIR_MASK [when=S] {
+ spyv, expr;
+ 0x2000005C04028000, (ATTR_CHIP_EC_FEATURE_HW411637 == 1 && ATTR_CHIP_EC_FEATURE_HW426891 == 0);
+ 0x2000005C040281C3, (ATTR_CHIP_EC_FEATURE_HW411637 == 1 && ATTR_CHIP_EC_FEATURE_HW426891 == 1);
+ 0x0000005C040081C3, (ATTR_CHIP_EC_FEATURE_HW411637 == 0 && ATTR_CHIP_EC_FEATURE_HW426891 == 1);
+}
+
+ispy INT.INT_CQ.INT_CQ_ACTION0_ACTION0 [when=S] {
+ spyv;
+ 0x0000000000000000;
+}
+
+ispy INT.INT_CQ.INT_CQ_ACTION1_ACTION1 [when=S] {
+ spyv, expr;
+ 0x9554021F80110FCF, (ATTR_CHIP_EC_FEATURE_P9N_INT_DD10 == 1);
+ 0x9554021F80110E0C, (ATTR_CHIP_EC_FEATURE_P9N_INT_DD10 == 0);
+}
+
+
+# Dependent Dials
+ispy INT.INT_CQ.INT_CQ_CFG_PB_GEN_ADDR_BAR_MODE [when=S] {
+ spyv;
+ 0;
+}
+
+ispy INT.INT_CQ.INT_CQ_PBO_CTL_SKIP_G [when=S] {
+ spyv, expr;
+ 1 , (TGT1.ATTR_PROC_FABRIC_PUMP_MODE == ATTR_PROC_FABRIC_PUMP_MODE::CHIP_IS_GROUP);
+ 0 , (TGT1.ATTR_PROC_FABRIC_PUMP_MODE == ATTR_PROC_FABRIC_PUMP_MODE::CHIP_IS_NODE);
+}
+
+ispy INT.INT_CQ.INT_CQ_CFG_PB_GEN_PUMP_MODE [when=S] {
+ spyv, expr;
+ 1 , (TGT1.ATTR_PROC_FABRIC_PUMP_MODE == ATTR_PROC_FABRIC_PUMP_MODE::CHIP_IS_GROUP);
+ 0 , (TGT1.ATTR_PROC_FABRIC_PUMP_MODE == ATTR_PROC_FABRIC_PUMP_MODE::CHIP_IS_NODE);
+}
+
+ispy INT.INT_CQ.INT_CQ_CFG_PB_GEN_ADDR_EXT_MASK_EN_15_21 [when=S && ATTR_CHIP_EC_FEATURE_EXTENDED_ADDRESSING_MODE] {
+ bits, spyv;
+ 0:3, (TGT1.ATTR_FABRIC_ADDR_EXTENSION_GROUP_ID);
+ 4:6, (TGT1.ATTR_FABRIC_ADDR_EXTENSION_CHIP_ID);
+}
+
+ispy INT.INT_CQ.INT_CQ_CFG_PB_GEN_SMF_CONFIG_0_1 [when=S && ATTR_CHIP_EC_FEATURE_SMF_SUPPORTED] {
+ spyv, expr;
+ 0b10, (TGT1.ATTR_SMF_CONFIG == TGT1.ATTR_SMF_CONFIG::ENABLED);
+}
+
+# disable MCD for HW423589
+espy INT.INT_CQ.INT_CQ_PBO_CTL_DISABLE_G [when=S && ATTR_CHIP_EC_FEATURE_HW423589_OPTION1] {
+ spyv;
+ ON;
+}
+
+espy INT.INT_CQ.INT_CQ_PBO_CTL_DISABLE_VG_NOT_SYS [when=S && ATTR_CHIP_EC_FEATURE_HW423589_OPTION1] {
+ spyv;
+ ON;
+}
+# HW441771 - Axone init to return to P9 behavior
+ispy INT.INT_CQ.INT_CQ_PBI_CTL_RESERVED_25_31 [when=S && ATTR_CHIP_EC_FEATURE_AXONE_HW441771] {
+ spyv;
+ 0b1000000;
+}
diff --git a/src/import/chips/p9/procedures/hwp/accessors/ddimm_get_efd.C b/src/import/chips/p9/procedures/hwp/accessors/ddimm_get_efd.C
index 058067490..9480b341f 100644..100755
--- a/src/import/chips/p9/procedures/hwp/accessors/ddimm_get_efd.C
+++ b/src/import/chips/p9/procedures/hwp/accessors/ddimm_get_efd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -82,6 +82,8 @@ const uint16_t SPD_EFD_COUNT_MASK = 0x003F;
// Offset to the EFD meta data within the SPD.
// size is 128 bytes; address 288 to 415; 32 EFD meta data's sized 4 bytes each
const size_t SPD_EFD_META_DATA_ADDR = 288;
+// Offset to Host Interface Speed Supported within the SPD.
+const size_t SPD_SUPPORTED_HOST_SPEEDS_ADDR = 205;
/// SPD - EFD meta data constants
// Size of the EFD meta data's within the SPD
@@ -151,11 +153,15 @@ const size_t SPD_DDR4_SIZE = 512;
// This value is extrapolated from the JEDEC document
// 0x29 is for for Microsemi
// size is 2 bytes
-const uint16_t SPD_DDR4_EXPECTED_DMB_MFG_ID = 0x2980;
+const uint16_t SPD_DDR4_DMB_MFG_ID_MICROCHIP = 0x2980;
+const uint16_t SPD_DDR4_DMB_MFG_ID_IBM = 0xA480;
// SPD - DDR4 expected value for the DMB revision.
// Currently at initial revision - revision 0
// size is 1 byte
-const uint8_t SPD_DDR4_EXPECTED_DMB_REVISION = 0x00;
+const uint8_t SPD_DDR4_EXPECTED_DMB_REVISION_0_MICROCHIP = 0x00;
+const uint8_t SPD_DDR4_EXPECTED_DMB_REVISION_A0_MICROCHIP = 0xA0;
+const uint8_t SPD_DDR4_EXPECTED_DMB_REVISION_A1_MICROCHIP = 0xA1;
+const uint8_t SPD_DDR4_EXPECTED_DMB_REVISION_IBM = 0x00;
// Maximum number of FFDC elements we will save off
// (should stay in sync with error xml)
@@ -196,6 +202,50 @@ enum DDR_MASTER_RANK : uint8_t
DDR_MR_BIT_MASK_3 = 0x08,
};
+///
+/// @brief Check that MFG ID matches possible values
+///
+/// @param[in] i_mfg_id MFG ID
+/// @return boolean valid/invalid
+/// @note Can be expanded for future MFG IDs
+///
+bool check_valid_mfg_id(const uint16_t i_mfg_id)
+{
+ return (SPD_DDR4_DMB_MFG_ID_MICROCHIP == i_mfg_id ||
+ SPD_DDR4_DMB_MFG_ID_IBM == i_mfg_id);
+}
+
+///
+/// @brief Gets the expected DMB revision of a particular MFG ID
+///
+/// @param[in] i_mfg_id MFG ID
+/// @param[in] i_dmb_revision DMB revision
+/// @return expected DMB revision for ID
+///
+bool check_valid_dmb_revision(const uint16_t i_mfg_id, const uint8_t i_dmb_revision)
+{
+ if (i_mfg_id == SPD_DDR4_DMB_MFG_ID_IBM)
+ {
+ FAPI_DBG("ddr4_get_efd: SPD DMB revision = 0x%.2X, expected DMB revision = 0x%.2X",
+ i_dmb_revision, SPD_DDR4_EXPECTED_DMB_REVISION_IBM);
+
+ return (i_dmb_revision == SPD_DDR4_EXPECTED_DMB_REVISION_IBM);
+ }
+ else // == SPD_DDR4_EXPECTED_DMB_REVISION_MICROCHIP
+ {
+ // We asserted earlier that we are either MCHP or IBM mfg ID
+ FAPI_DBG("ddr4_get_efd: SPD DMB revision = 0x%.2X, expected DMB revision = 0x%.2X or 0x%.2X or 0x%.2X",
+ i_dmb_revision,
+ SPD_DDR4_EXPECTED_DMB_REVISION_0_MICROCHIP,
+ SPD_DDR4_EXPECTED_DMB_REVISION_A0_MICROCHIP,
+ SPD_DDR4_EXPECTED_DMB_REVISION_A1_MICROCHIP);
+
+ return ((i_dmb_revision == SPD_DDR4_EXPECTED_DMB_REVISION_0_MICROCHIP) ||
+ (i_dmb_revision == SPD_DDR4_EXPECTED_DMB_REVISION_A0_MICROCHIP) ||
+ (i_dmb_revision == SPD_DDR4_EXPECTED_DMB_REVISION_A1_MICROCHIP));
+ }
+}
+
/// Local utilities
// @brief Maps the frequency numeric value to it's bit mask equivalent
// Uses the enums in DDR_FREQUENCY above
@@ -409,6 +459,7 @@ extern "C"
uint16_t l_efdCount{0}; // The number of EFDs
size_t l_efdSize{0}; // The size of an EFD, not EFD meta data
uint16_t l_dmbMfgId{0}; // The DMB manufacture ID
+ uint8_t l_dmb_revision{0};
uint16_t l_freqMask{0}; // The frequency mask as found in EFD
uint8_t l_rankMask{0}; // The rank mask as found in EFD
size_t ii{0}; // A loop index
@@ -420,6 +471,8 @@ extern "C"
const uint8_t* l_efdMetaDataNptr(nullptr);
// Pointer to an individual EFD
const uint8_t* l_efdDataNptr(nullptr);
+ // Host Interface Supported Speeds field
+ uint16_t l_supportedSpeeds(0);
// Fill in a data buffer for FFDC purposes that contains
// the first 8 bytes from the SPD (freq,rank,channel,dimms)
@@ -597,25 +650,19 @@ extern "C"
// Swap endianess to host format.
l_dmbMfgId = le16toh(l_dmbMfgId);
- FAPI_DBG ( "ddr4_get_efd: SPD DMB manufacturer ID = 0x%.4X, "
- "expected DMB manufacturer ID = 0x%.4X",
- l_dmbMfgId,
- SPD_DDR4_EXPECTED_DMB_MFG_ID );
+ FAPI_DBG ( "ddr4_get_efd: SPD DMB manufacturer ID = 0x%.4X", l_dmbMfgId);
// Confirm the DMB manufacturer ID value is what is expected
- FAPI_ASSERT( (SPD_DDR4_EXPECTED_DMB_MFG_ID == l_dmbMfgId),
- fapi2::DDIMM_GET_EFD_UNSUPPORTED_DMB_MFG_ID().
- set_DMB_MFG_ID(static_cast<uint32_t>(l_dmbMfgId)).
- set_EXPECTED(static_cast<uint32_t>
- (SPD_DDR4_EXPECTED_DMB_MFG_ID)).
- set_OCMB_CHIP_TARGET(i_ocmbFapi2Target).
- set_VPD_TYPE(io_vpdInfo.iv_vpd_type).
- set_DDR_TYPE(static_cast<uint32_t>
- (i_spdBuffer[SPD_MEM_TYPE_ADDR])),
- "ddr4_get_efd: SPD DMB manufacturer ID 0x%.4X is not the "
- "expected DMB manufacturer ID 0x%.4X ",
- l_dmbMfgId,
- SPD_DDR4_EXPECTED_DMB_MFG_ID);
+ FAPI_ASSERT(check_valid_mfg_id(l_dmbMfgId),
+ fapi2::DDIMM_GET_EFD_UNSUPPORTED_DMB_MFG_ID().
+ set_DMB_MFG_ID(static_cast<uint32_t>(l_dmbMfgId)).
+ set_OCMB_CHIP_TARGET(i_ocmbFapi2Target).
+ set_VPD_TYPE(io_vpdInfo.iv_vpd_type).
+ set_DDR_TYPE(static_cast<uint32_t>
+ (i_spdBuffer[SPD_MEM_TYPE_ADDR])),
+ "ddr4_get_efd: SPD DMB manufacturer ID 0x%.4X is not of "
+ "expected DMB manufacturer IDs MCHP: 0x%.4X or IBM: 0x%.4X",
+ l_dmbMfgId, SPD_DDR4_DMB_MFG_ID_MICROCHIP, SPD_DDR4_DMB_MFG_ID_IBM);
// Set the outgoing DMB manufacturer ID
io_vpdInfo.iv_dmb_mfg_id = l_dmbMfgId;
@@ -623,29 +670,28 @@ extern "C"
FAPI_DBG ( "ddr4_get_efd: SPD DMB manufacturer ID = 0x%.4X",
io_vpdInfo.iv_dmb_mfg_id);
- FAPI_DBG ( "ddr4_get_efd: SPD DMB revision = 0x%.2X, "
- "expected DMB revision = 0x%.2X",
- i_spdBuffer[SPD_DMB_REVISION_ADDR],
- SPD_DDR4_EXPECTED_DMB_REVISION );
+ l_dmb_revision = *reinterpret_cast<const uint8_t*>(&i_spdBuffer[SPD_DMB_REVISION_ADDR]);
// Confirm that the DMB revision is what is expected
- FAPI_ASSERT( (SPD_DDR4_EXPECTED_DMB_REVISION ==
- i_spdBuffer[SPD_DMB_REVISION_ADDR]),
+ FAPI_ASSERT( check_valid_dmb_revision(l_dmbMfgId, l_dmb_revision),
fapi2::DDIMM_GET_EFD_UNSUPPORTED_DMB_REVISION().
set_DMB_REVISION(static_cast<uint32_t>
- (SPD_DDR4_EXPECTED_DMB_REVISION)).
- set_EXPECTED(static_cast<uint32_t>(SPD_DMB_REVISION_ADDR)).
+ (l_dmb_revision)).
set_OCMB_CHIP_TARGET(i_ocmbFapi2Target).
set_VPD_TYPE(io_vpdInfo.iv_vpd_type).
set_DDR_TYPE(static_cast<uint32_t>
(i_spdBuffer[SPD_MEM_TYPE_ADDR])),
- "ddr4_get_efd: SPD DMB revision 0x%.2X is not the expected "
- "revision 0x%.2X",
- i_spdBuffer[SPD_DMB_REVISION_ADDR],
- SPD_DDR4_EXPECTED_DMB_REVISION);
+ "ddr4_get_efd: SPD DMB revision 0x%.2X is not an expected revision: "
+ "IBM expected: 0x%.2X "
+ "MCHP expected: 0x%.2X or 0x%.2X or 0x%.2X",
+ l_dmb_revision,
+ SPD_DDR4_EXPECTED_DMB_REVISION_IBM,
+ SPD_DDR4_EXPECTED_DMB_REVISION_0_MICROCHIP,
+ SPD_DDR4_EXPECTED_DMB_REVISION_A0_MICROCHIP,
+ SPD_DDR4_EXPECTED_DMB_REVISION_A1_MICROCHIP);
// Set the outgoing DMB revision
- io_vpdInfo.iv_dmb_revision = SPD_DDR4_EXPECTED_DMB_REVISION;
+ io_vpdInfo.iv_dmb_revision = l_dmb_revision;
FAPI_DBG ( "ddr4_get_efd: SPD DMB revision = 0x%.2X",
io_vpdInfo.iv_dmb_revision);
@@ -659,7 +705,7 @@ extern "C"
// No need to swap endian, already in host format
l_freqMask = ddrFrequencyToBitMask(io_vpdInfo.iv_omi_freq_mhz);
- FAPI_DBG ( "ddr4_get_efd: Caller supplied frquency = %d",
+ FAPI_DBG ( "ddr4_get_efd: Caller supplied frequency = %d",
io_vpdInfo.iv_omi_freq_mhz );
// Confirm that mapping the frequency succeeded
@@ -667,6 +713,8 @@ extern "C"
{
// If no value for freq, then mapping of frequency was unsuccessful
+ // Note we don't want to produce FFDC if the ffdc_enabled flag is not set
+ // i.e. if we're just probing the EFD for its supported frequencies
FAPI_ASSERT( ( !io_vpdInfo.iv_is_config_ffdc_enabled ),
fapi2::DDIMM_GET_EFD_UNSUPPORTED_FREQUENCY().
set_UNSUPPORTED_FREQ(static_cast<uint32_t>
@@ -695,7 +743,7 @@ extern "C"
FAPI_TRY(fapi2::FAPI2_RC_FALSE);
}
- FAPI_DBG ("ddr4_get_efd: Caller supplied frquency = %d, "
+ FAPI_DBG ("ddr4_get_efd: Caller supplied frequency = %d, "
"converted to frequency bit value mask = 0x%.4X",
io_vpdInfo.iv_omi_freq_mhz, l_freqMask);
@@ -707,6 +755,8 @@ extern "C"
if ( !l_rankMask)
{
// If no value for MR, then mapping of MR was unsuccessful
+ // Note we don't want to produce FFDC if the ffdc_enabled flag is not set
+ // i.e. if we're just probing the EFD for its supported frequencies
FAPI_ASSERT( ( !io_vpdInfo.iv_is_config_ffdc_enabled ),
fapi2::DDIMM_GET_EFD_UNSUPPORTED_RANK().
set_UNSUPPORTED_RANK(static_cast<uint32_t>
@@ -743,6 +793,36 @@ extern "C"
//// Fourthly, find the EFD that matches the given frequency
//// and master rank
+ // Check the master list of supported frequencies before walking
+ // through the EFDs
+ l_supportedSpeeds = *reinterpret_cast<const uint16_t*>
+ (i_spdBuffer + SPD_SUPPORTED_HOST_SPEEDS_ADDR);
+ l_supportedSpeeds = le16toh(l_supportedSpeeds);
+
+ if (!(l_freqMask & l_supportedSpeeds))
+ {
+ // Note we don't want to produce FFDC if the ffdc_enabled flag is not set
+ // i.e. if we're just probing the EFD for its supported frequencies
+ FAPI_ASSERT( !io_vpdInfo.iv_is_config_ffdc_enabled,
+ fapi2::DDIMM_UNSUPPORTED_FREQUENCY().
+ set_UNSUPPORTED_FREQ(static_cast<uint32_t>
+ (io_vpdInfo.iv_omi_freq_mhz)).
+ set_SUPPORTED_FREQS(l_supportedSpeeds).
+ set_OCMB_CHIP_TARGET(i_ocmbFapi2Target).
+ set_VPD_TYPE(io_vpdInfo.iv_vpd_type).
+ set_DDR_TYPE(static_cast<uint32_t>
+ (i_spdBuffer[SPD_MEM_TYPE_ADDR])),
+ "Invalid frequency for this DIMM - request=%d, supported mask=%.4X",
+ io_vpdInfo.iv_omi_freq_mhz, l_supportedSpeeds );
+
+ // If unable to collect FFDC and assert, at least trace out and exit with false
+ FAPI_INF ("ddr4_get_efd: Unsupported frequency %d (frequency bit mask = 0x%.4X, "
+ "supported mask = 0x%.4X)",
+ io_vpdInfo.iv_omi_freq_mhz, l_freqMask, l_supportedSpeeds);
+
+ FAPI_TRY(fapi2::FAPI2_RC_FALSE);
+ }
+
// Point to the beginning of the EFD meta data, AKA EFD[0] meta data.
l_efdMetaDataPtr = i_spdBuffer + SPD_EFD_META_DATA_ADDR;
@@ -810,12 +890,12 @@ extern "C"
// If the 'is implemented flag' is true for the EFD, AND if the EFD
// frequency mask contains the frequency mask we are looking for AND
- // the EFD master rank matches the master rank we are looking for
+ // the EFD master rank bitmap includes the master rank we are looking for
// then copy the EFD block for the caller.
if ( (l_efdMetaDataNptr[SPD_EFD_META_DATA_EFD_BYTE_3_OFFSET] &
SPD_EFD_META_DATA_EFD_IS_IMPLEMENTED_MASK) &&
(l_efdFreqMask & l_freqMask) &&
- (l_efdDataNptr[EFD_DDR4_MASTER_RANK_ADDR] == l_rankMask) )
+ (l_efdDataNptr[EFD_DDR4_MASTER_RANK_ADDR] & l_rankMask) )
{
// io_vpdInfo.iv_size and EFD block size compatibility
// have been verified above
@@ -863,6 +943,8 @@ extern "C"
{
// Did not find an EFD to match frequency and master rank criteria
// Collect FFDC and assert if iv_is_config_ffdc_enabled is true
+ // Note we don't want to produce FFDC if the ffdc_enabled flag is not set
+ // i.e. if we're just probing the EFD for its supported frequencies
FAPI_ASSERT( ( !io_vpdInfo.iv_is_config_ffdc_enabled ),
fapi2::DDIMM_GET_EFD_EFD_NOT_FOUND().
set_FREQUENCY(io_vpdInfo.iv_omi_freq_mhz).
diff --git a/src/import/chips/p9/procedures/hwp/customize/p9_xip_customize.C b/src/import/chips/p9/procedures/hwp/customize/p9_xip_customize.C
index 27b1877ba..b6412b206 100644
--- a/src/import/chips/p9/procedures/hwp/customize/p9_xip_customize.C
+++ b/src/import/chips/p9/procedures/hwp/customize/p9_xip_customize.C
@@ -305,6 +305,7 @@ fapi2::ReturnCode writeMboxRegs (
MBOX_ATTR_WRITE (ATTR_PROC_EPS_WRITE_CYCLES_T2, FAPI_SYSTEM, i_image);
MBOX_ATTR_WRITE (ATTR_LPC_CONSOLE_CNFG, i_procTarget, i_image);
MBOX_ATTR_WRITE (ATTR_SBE_NVDIMM_IN_PORT, i_procTarget, i_image);
+ MBOX_ATTR_WRITE (ATTR_SMF_CONFIG, FAPI_SYSTEM, i_image);
// for backwards compatiblity with images that don't contain
// the OB/MC PLL bucket attributes, ensure that the item exists
@@ -2614,8 +2615,9 @@ ReturnCode p9_xip_customize (
if ((uint32_t)l_fapiRc == RC_XIPC_IMAGE_WOULD_OVERFLOW)
{
- FAPI_INF("p9_xip_customize(): Image is full. Ran out of space appending VPD rings"
- " to the .rings section");
+ FAPI_INF("p9_xip_customize(): Image is full. Ran out of space appending VPD"
+ " rings to the .rings section. Now checking if min required cores"
+ " is satisfied.");
// Check the bootCoreMask to determine if enough cores have been configured.
uint8_t attrMinReqdEcs = 0;
@@ -2655,11 +2657,14 @@ ReturnCode p9_xip_customize (
"Image buffer would overflow before reaching the minimum required"
" number of EC boot cores" );
+ fapi2::current_err = FAPI2_RC_SUCCESS;
+ }
+ else
+ {
+ fapi2::current_err = l_fapiRc;
}
- fapi2::current_err = l_fapiRc;
goto fapi_try_exit;
-
}
// More size code sanity checks of section and image sizes.
diff --git a/src/import/chips/p9/procedures/hwp/ffdc/exp_collect_explorer_log.C b/src/import/chips/p9/procedures/hwp/ffdc/exp_collect_explorer_log.C
new file mode 100644
index 000000000..843da913f
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/ffdc/exp_collect_explorer_log.C
@@ -0,0 +1,253 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/ffdc/exp_collect_explorer_log.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file exp_collect_explorer_log.C
+///
+/// @brief Collects and adds Explorer logs to rc
+//------------------------------------------------------------------------------
+// *HWP HW Owner : Matt Derksen
+// *HWP HW Backup Owner : <>
+// *HWP FW Owner : <>
+// *HWP Level : 2
+// *HWP Consumed by : SE:HB
+//------------------------------------------------------------------------------
+
+#include <fapi2.H>
+#include "exp_collect_explorer_log.H"
+#include <exp_fw_log_data.H>
+
+struct explog_section_header_t
+{
+ uint16_t packet_num; // ordering byte (0 = first packet)
+ uint32_t offset_exp_log; // offset where data portion started in full explorer log
+ uint16_t error_data_size; // size of data portion following header
+
+ explog_section_header_t()
+ : packet_num(0),
+ offset_exp_log(0),
+ error_data_size(0)
+ {}
+} __attribute__((__packed__));
+
+// 1st entry is most relevant traces so make it a small size so
+// it won't be truncated from HWP error log
+const size_t FIRST_PACKET_SIZE = 0x100;
+
+// Use a larger packet size for the rest of the remaining error data
+// These aren't as important since they are older trace logs
+const size_t FOLLOWING_PACKET_SIZE = 0x200;
+
+/**
+ * @brief Explorer Log type?
+ *
+ * The firmware maintains the log in a circular buffer in RAM (ACTIVE_LOG) and
+ * in the event of a processor exception, firmware assert, or other critical
+ * condition the firmware saves the data in RAM to SPI flash (SAVED_LOG).
+ * Having the log stored in non-volatile memory allows post-analysis
+ * of the log even if it requires a power-cycle to recover the system.
+ */
+enum exp_log_type : uint8_t
+{
+ ACTIVE_LOG = 1, // RAM error section
+ SAVED_LOG = 2 // SPI flash error section
+};
+
+/**
+ * @brief Main procedure to grab log traces from Explorer chip
+ * and append the trace data to HWP error (o_rc)
+ *
+ * @param[in] i_ocmb_chip - OCMB chip target
+ * @param[in] i_size - allowable total size (add entries upto this size)
+ * @param[in] i_log_type - what kind of explorer log to grab
+ * @param[out] o_rc - return code to add FFDC data to.
+ *
+ * @return FAPI2_RC_SUCCESS iff ok
+ */
+fapi2::ReturnCode exp_collect_explorer_logs(const fapi2::ffdc_t& i_ocmb_chip,
+ const fapi2::ffdc_t& i_size,
+ const exp_log_type i_log_type,
+ fapi2::ReturnCode& o_rc)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ // This variable is reused multiple times to build up a unique section
+ // identifier to split the log data read from the OCMB before we add
+ // each section to the HWP error
+ explog_section_header_t l_header_meta;
+
+ // target from which to grab the error log data
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_target_ocmb =
+ *(reinterpret_cast<const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> *>
+ (i_ocmb_chip.ptr()));
+
+ // How much explorer log data are we allowed to add to the HWP error?
+ uint32_t l_allowable_size = *(reinterpret_cast<const uint32_t*>(i_size.ptr()));
+
+ std::vector<uint8_t>l_explorer_log_data; // full Explorer log data
+ fapi2::ffdc_t UNIT_FFDC_EXP_ERROR; // filled in for RC_EXPLORER_ERROR_LOG
+
+ FAPI_INF( "exp_collect_explorer_logs: Entering ... "
+ "(log type: %s, max data size: 0x%04X)",
+ i_log_type == ACTIVE_LOG ? "Active" : "Saved", l_allowable_size );
+
+ if ( ACTIVE_LOG == i_log_type )
+ {
+ FAPI_EXEC_HWP(l_rc, exp_active_log, l_target_ocmb, l_explorer_log_data);
+ }
+ else
+ {
+ FAPI_EXEC_HWP(l_rc, exp_saved_log, l_target_ocmb, l_explorer_log_data);
+ }
+
+ if (l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ FAPI_ERR("exp_collect_explorer_logs: error 0x%04X from exp_%s_log",
+ (uint32_t)l_rc, i_log_type == ACTIVE_LOG ? "active" : "saved");
+ }
+ else
+ {
+ // Variable to store how much Explorer data we have remaining
+ uint32_t l_explorer_bytes_left = l_explorer_log_data.size();
+
+ // Add this much explorer log data (as maximum amount, could be less)
+ l_header_meta.error_data_size = FIRST_PACKET_SIZE;
+
+ // We read from the end since the most recent logs are the last
+ // entries returned in the full Explorer log data
+ auto l_end_ptr = l_explorer_log_data.end();
+
+ // This is where we start iterating through the Explorer log data
+ // and break it into sections that are added to the HWP error
+ while ( l_explorer_bytes_left )
+ {
+ // ----------------------------------------------------------------
+ // Calculate how much explorer data to add for this section entry
+ // ----------------------------------------------------------------
+ // Verify there is enough space left in the allowable HWP error
+ // so we can add another full data section
+ if ( l_allowable_size > l_header_meta.error_data_size)
+ {
+ // We can add at least a packet of data, if we have that
+ // much to add
+ if (l_explorer_bytes_left < l_header_meta.error_data_size)
+ {
+ FAPI_INF("exp_collect_explorer_logs: %d) reduce packet size to include the last explorer log bytes"
+ "(l_explorer_bytes_left %d, Initial packet size %d)", l_header_meta.packet_num,
+ l_explorer_bytes_left, l_header_meta.error_data_size);
+
+ // reduce the packet size to include the last explorer log bytes
+ l_header_meta.error_data_size = l_explorer_bytes_left;
+ }
+
+ // else, have enough data and space, so add full data size
+ }
+ else if ( l_allowable_size ) // Any space left?
+ {
+ // Note: if here, we cannot add a full section size of data
+
+ // Is allowable size remaining less than the explorer bytes available?
+ if ( l_allowable_size < l_explorer_bytes_left )
+ {
+ // use up the rest of the allowable space available
+ FAPI_INF("exp_collect_explorer_logs: %d) use up rest of space available"
+ "(l_explorer_bytes_left %d, l_allowable_size %d)", l_header_meta.packet_num,
+ l_explorer_bytes_left, l_allowable_size);
+ l_header_meta.error_data_size = l_allowable_size;
+ }
+ else
+ {
+ // reduce the packet size to include the last explorer log bytes
+ l_header_meta.error_data_size = l_explorer_bytes_left;
+ }
+ }
+ else
+ {
+ // reached allowable size
+ break;
+ }
+
+ // ----------------------------------------------------------------
+
+ // offset where the data is starting from out of the whole Explorer log data
+ l_header_meta.offset_exp_log = l_explorer_bytes_left - l_header_meta.error_data_size;
+
+ FAPI_INF("exp_collect_explorer_logs: %d) starting offset 0x%08X "
+ "(data size: %d)", l_header_meta.packet_num,
+ l_header_meta.offset_exp_log, l_header_meta.error_data_size);
+
+ // Adding header with meta data
+ auto const ptr = reinterpret_cast<uint8_t*>(&l_header_meta);
+ std::vector<uint8_t>l_error_log_entry ( ptr, ptr + sizeof(l_header_meta));
+
+ // Now append the explorer error section to the section entry
+ // Note: working backwards from the end of the Explorer log data
+ l_error_log_entry.insert( l_error_log_entry.end(),
+ l_end_ptr - l_header_meta.error_data_size,
+ l_end_ptr );
+
+ // Add the section entry to the HWP error log
+ UNIT_FFDC_EXP_ERROR.ptr() = l_error_log_entry.data();
+ UNIT_FFDC_EXP_ERROR.size() = l_error_log_entry.size();
+
+ if (ACTIVE_LOG == i_log_type)
+ {
+ FAPI_ADD_INFO_TO_HWP_ERROR(o_rc, RC_EXPLORER_ACTIVE_ERROR_LOG);
+ }
+ else
+ {
+ FAPI_ADD_INFO_TO_HWP_ERROR(o_rc, RC_EXPLORER_SAVED_ERROR_LOG);
+ }
+
+ // Update to next packet of Explorer error log data
+ l_header_meta.packet_num++;
+ l_explorer_bytes_left -= l_header_meta.error_data_size;
+ l_end_ptr -= l_header_meta.error_data_size; // point to beginning of last data inserted
+ l_allowable_size -= l_header_meta.error_data_size;
+ l_header_meta.error_data_size = FOLLOWING_PACKET_SIZE;
+ }
+ }
+
+ FAPI_INF("exp_collect_explorer_logs: Exiting ...");
+
+ return l_rc;
+}
+
+/// See header
+fapi2::ReturnCode exp_collect_explorer_active_log(
+ const fapi2::ffdc_t& i_ocmb_chip,
+ const fapi2::ffdc_t& i_size,
+ fapi2::ReturnCode& o_rc )
+{
+ return exp_collect_explorer_logs(i_ocmb_chip, i_size, ACTIVE_LOG, o_rc);
+}
+
+/// See header
+fapi2::ReturnCode exp_collect_explorer_saved_log(
+ const fapi2::ffdc_t& i_ocmb_chip,
+ const fapi2::ffdc_t& i_size,
+ fapi2::ReturnCode& o_rc )
+{
+ return exp_collect_explorer_logs(i_ocmb_chip, i_size, SAVED_LOG, o_rc);
+}
diff --git a/src/import/chips/p9/procedures/hwp/ffdc/exp_collect_explorer_log.H b/src/import/chips/p9/procedures/hwp/ffdc/exp_collect_explorer_log.H
new file mode 100644
index 000000000..adba2eee2
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/ffdc/exp_collect_explorer_log.H
@@ -0,0 +1,109 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/ffdc/exp_collect_explorer_log.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/// @file exp_collect_explorer_log.H
+///
+/// @brief Collects and adds Explorer debug logs to rc
+// ----------------------------------------
+// *HWP HWP Owner: Matt Derksen <mderkse1@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB
+// ----------------------------------------
+#ifndef _COLLECT_EXPLORER_LOG_H_
+#define _COLLECT_EXPLORER_LOG_H_
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <return_code.H>
+#include <error_info_defs.H>
+
+//------------------------------------------------------------------------------
+// Structure definitions
+//------------------------------------------------------------------------------
+
+// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*exp_collect_explorer_active_log_FP_t)(
+ const fapi2::ffdc_t&,
+ const fapi2::ffdc_t&,
+ fapi2::ReturnCode& );
+
+typedef fapi2::ReturnCode (*exp_collect_explorer_saved_log_FP_t)(
+ const fapi2::ffdc_t&,
+ const fapi2::ffdc_t&,
+ fapi2::ReturnCode& );
+
+//------------------------------------------------------------------------------
+// Constant definitions
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+// Function prototypes
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+///
+/// @brief Procedure to grab active (RAM) log traces from Explorer chip
+/// and add those traces to the HWP error
+/// @param[in] i_ocmb_chip - OCMB chip target
+/// @param[in] i_size - allowable total size (add entries upto this size)
+/// @param[out] o_rc - return code to add FFDC data to.
+///
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+/// NOTE: All input parameters must be of type fapi2::ffdc_t and converted
+/// to the correct type inside the function.
+///
+ fapi2::ReturnCode exp_collect_explorer_active_log(
+ const fapi2::ffdc_t& i_ocmb_chip,
+ const fapi2::ffdc_t& i_size,
+ fapi2::ReturnCode& o_rc );
+
+
+///
+/// @brief Procedure to grab saved (SPI flash) log traces from Explorer chip
+/// and add those traces to the HWP error
+/// @param[in] i_ocmb_chip - OCMB chip target
+/// @param[in] i_size - allowable total size (add entries upto this size)
+/// @param[out] o_rc - return code to add FFDC data to.
+///
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+/// NOTE: All input parameters must be of type fapi2::ffdc_t and converted
+/// to the correct type inside the function.
+///
+ fapi2::ReturnCode exp_collect_explorer_saved_log(
+ const fapi2::ffdc_t& i_ocmb_chip,
+ const fapi2::ffdc_t& i_size,
+ fapi2::ReturnCode& o_rc );
+
+
+} // extern "C"
+
+
+#endif // _COLLECT_EXPLORER_LOG_H_
diff --git a/src/import/chips/p9/procedures/hwp/ffdc/ffdc_includes.H b/src/import/chips/p9/procedures/hwp/ffdc/ffdc_includes.H
index c84739fb4..2336e59bf 100644
--- a/src/import/chips/p9/procedures/hwp/ffdc/ffdc_includes.H
+++ b/src/import/chips/p9/procedures/hwp/ffdc/ffdc_includes.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -35,4 +35,8 @@
#include <p9_collect_ppe_state.H>
#include <p9_eq_clear_atomic_lock.H>
#include <p9_collect_lpc_regs.H>
+
+// needed for collectFfdc to work for adding Explorer log data
+#include <exp_collect_explorer_log.H>
+
#endif
diff --git a/src/import/chips/p9/procedures/hwp/ffdc/p9_collect_lpc_regs.C b/src/import/chips/p9/procedures/hwp/ffdc/p9_collect_lpc_regs.C
index 4e8ee34b2..f17dcffcb 100644
--- a/src/import/chips/p9/procedures/hwp/ffdc/p9_collect_lpc_regs.C
+++ b/src/import/chips/p9/procedures/hwp/ffdc/p9_collect_lpc_regs.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -32,7 +32,7 @@
#include "p9_misc_scom_addresses.H"
#include "p9_misc_scom_addresses_fld.H"
-#include "../perv/p9_lpc_utils.H"
+#include <p9_lpc_utils.H>
static void lpc_dump(
const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target_chip,
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp1_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp1_scom.C
index 6f65f5fe5..896614802 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp1_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp1_scom.C
@@ -149,6 +149,10 @@ fapi2::ReturnCode p9_fbc_cd_hp1_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_CORE_CEILING_RATIO, TGT1, l_TGT1_ATTR_PROC_FABRIC_CORE_CEILING_RATIO));
uint64_t l_def_CORE_CEILING_RATIO_8_8 = (l_TGT1_ATTR_PROC_FABRIC_CORE_CEILING_RATIO ==
ENUM_ATTR_PROC_FABRIC_CORE_CEILING_RATIO_RATIO_8_8);
+ fapi2::ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS_Type l_TGT0_ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS, TGT0,
+ l_TGT0_ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS));
+ uint64_t l_def_IS_AXONE = (l_TGT0_ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS != literal_0);
fapi2::buffer<uint64_t> l_scom_buffer;
{
if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
@@ -1200,11 +1204,21 @@ fapi2::ReturnCode p9_fbc_cd_hp1_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC
l_scom_buffer.insert<34, 8, 56, uint64_t>(literal_0b11111110 );
}
- if (literal_1)
+ if (l_def_IS_AXONE)
+ {
+ l_scom_buffer.insert<42, 2, 62, uint64_t>(literal_0b10 );
+ }
+
+ if (( ! l_def_IS_AXONE))
{
l_scom_buffer.insert<42, 8, 56, uint64_t>(literal_0b11111110 );
}
+ if (l_def_IS_AXONE)
+ {
+ l_scom_buffer.insert<44, 6, 58, uint64_t>(literal_0b000000 );
+ }
+
if (literal_1)
{
l_scom_buffer.insert<50, 2, 62, uint64_t>(literal_0b01 );
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp2_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp2_scom.C
index 42e21b5f9..456de5563 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp2_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp2_scom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,9 +40,11 @@ constexpr uint64_t literal_0b1111 = 0b1111;
constexpr uint64_t literal_0b011 = 0b011;
constexpr uint64_t literal_0b010 = 0b010;
constexpr uint64_t literal_0b11111110 = 0b11111110;
+constexpr uint64_t literal_0 = 0;
+constexpr uint64_t literal_0b10 = 0b10;
+constexpr uint64_t literal_0b000000 = 0b000000;
constexpr uint64_t literal_0b01 = 0b01;
constexpr uint64_t literal_0b00 = 0b00;
-constexpr uint64_t literal_0b10 = 0b10;
fapi2::ReturnCode p9_fbc_cd_hp2_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT0,
const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT1)
@@ -59,6 +61,10 @@ fapi2::ReturnCode p9_fbc_cd_hp2_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC
fapi2::ATTR_PROC_FABRIC_X_LINKS_CNFG_Type l_TGT0_ATTR_PROC_FABRIC_X_LINKS_CNFG;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_X_LINKS_CNFG, TGT0, l_TGT0_ATTR_PROC_FABRIC_X_LINKS_CNFG));
uint64_t l_def_NUM_X_LINKS_CFG = l_TGT0_ATTR_PROC_FABRIC_X_LINKS_CNFG;
+ fapi2::ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS_Type l_TGT0_ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS, TGT0,
+ l_TGT0_ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS));
+ uint64_t l_def_IS_AXONE = (l_TGT0_ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS != literal_0);
fapi2::buffer<uint64_t> l_scom_buffer;
{
if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
@@ -184,11 +190,21 @@ fapi2::ReturnCode p9_fbc_cd_hp2_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC
l_scom_buffer.insert<34, 8, 56, uint64_t>(literal_0b11111110 );
}
- if (literal_1)
+ if (l_def_IS_AXONE)
+ {
+ l_scom_buffer.insert<42, 2, 62, uint64_t>(literal_0b10 );
+ }
+
+ if (( ! l_def_IS_AXONE))
{
l_scom_buffer.insert<42, 8, 56, uint64_t>(literal_0b11111110 );
}
+ if (l_def_IS_AXONE)
+ {
+ l_scom_buffer.insert<44, 6, 58, uint64_t>(literal_0b000000 );
+ }
+
if (literal_1)
{
l_scom_buffer.insert<50, 2, 62, uint64_t>(literal_0b01 );
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp3_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp3_scom.C
index 9790095c3..3488465f2 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp3_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp3_scom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,9 +40,11 @@ constexpr uint64_t literal_0b1 = 0b1;
constexpr uint64_t literal_0b011 = 0b011;
constexpr uint64_t literal_0b010 = 0b010;
constexpr uint64_t literal_0b11111110 = 0b11111110;
+constexpr uint64_t literal_0 = 0;
+constexpr uint64_t literal_0b10 = 0b10;
+constexpr uint64_t literal_0b000000 = 0b000000;
constexpr uint64_t literal_0b01 = 0b01;
constexpr uint64_t literal_0b00 = 0b00;
-constexpr uint64_t literal_0b10 = 0b10;
fapi2::ReturnCode p9_fbc_cd_hp3_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT0,
const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT1)
@@ -59,6 +61,10 @@ fapi2::ReturnCode p9_fbc_cd_hp3_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC
fapi2::ATTR_PROC_FABRIC_X_LINKS_CNFG_Type l_TGT0_ATTR_PROC_FABRIC_X_LINKS_CNFG;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_X_LINKS_CNFG, TGT0, l_TGT0_ATTR_PROC_FABRIC_X_LINKS_CNFG));
uint64_t l_def_NUM_X_LINKS_CFG = l_TGT0_ATTR_PROC_FABRIC_X_LINKS_CNFG;
+ fapi2::ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS_Type l_TGT0_ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS, TGT0,
+ l_TGT0_ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS));
+ uint64_t l_def_IS_AXONE = (l_TGT0_ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS != literal_0);
fapi2::buffer<uint64_t> l_scom_buffer;
{
if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
@@ -184,11 +190,21 @@ fapi2::ReturnCode p9_fbc_cd_hp3_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC
l_scom_buffer.insert<34, 8, 56, uint64_t>(literal_0b11111110 );
}
- if (literal_1)
+ if (l_def_IS_AXONE)
+ {
+ l_scom_buffer.insert<42, 2, 62, uint64_t>(literal_0b10 );
+ }
+
+ if (( ! l_def_IS_AXONE))
{
l_scom_buffer.insert<42, 8, 56, uint64_t>(literal_0b11111110 );
}
+ if (l_def_IS_AXONE)
+ {
+ l_scom_buffer.insert<44, 6, 58, uint64_t>(literal_0b000000 );
+ }
+
if (literal_1)
{
l_scom_buffer.insert<50, 2, 62, uint64_t>(literal_0b01 );
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_npu_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_npu_scom.C
new file mode 100644
index 000000000..da89cd6ef
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_npu_scom.C
@@ -0,0 +1,84 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_npu_scom.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include "p9_fbc_ioo_dl_npu_scom.H"
+#include <stdint.h>
+#include <stddef.h>
+#include <fapi2.H>
+
+using namespace fapi2;
+
+
+fapi2::ReturnCode p9_fbc_ioo_dl_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_OBUS>& TGT0,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT1, const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT2)
+{
+ {
+ fapi2::ATTR_EC_Type l_chip_ec;
+ fapi2::ATTR_NAME_Type l_chip_id;
+ FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, TGT1, l_chip_id));
+ FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_EC, TGT1, l_chip_ec));
+ fapi2::ATTR_PROC_NPU_REGION_ENABLED_Type l_TGT1_ATTR_PROC_NPU_REGION_ENABLED;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU_REGION_ENABLED, TGT1, l_TGT1_ATTR_PROC_NPU_REGION_ENABLED));
+ fapi2::ATTR_OPTICS_CONFIG_MODE_Type l_TGT0_ATTR_OPTICS_CONFIG_MODE;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_OPTICS_CONFIG_MODE, TGT0, l_TGT0_ATTR_OPTICS_CONFIG_MODE));
+ uint64_t l_def_OBUS_NV_ENABLED = ((l_TGT0_ATTR_OPTICS_CONFIG_MODE == fapi2::ENUM_ATTR_OPTICS_CONFIG_MODE_NV)
+ && l_TGT1_ATTR_PROC_NPU_REGION_ENABLED);
+ fapi2::buffer<uint64_t> l_scom_buffer;
+ {
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x901080cull, l_scom_buffer ));
+
+ if (l_def_OBUS_NV_ENABLED)
+ {
+ constexpr auto l_PB_IOO_LL0_CONFIG_NV0_NPU_ENABLED_ON = 0x1;
+ l_scom_buffer.insert<60, 1, 63, uint64_t>(l_PB_IOO_LL0_CONFIG_NV0_NPU_ENABLED_ON );
+ }
+
+ if (l_def_OBUS_NV_ENABLED)
+ {
+ constexpr auto l_PB_IOO_LL0_CONFIG_NV1_NPU_ENABLED_ON = 0x1;
+ l_scom_buffer.insert<61, 1, 63, uint64_t>(l_PB_IOO_LL0_CONFIG_NV1_NPU_ENABLED_ON );
+ }
+
+ if (l_def_OBUS_NV_ENABLED)
+ {
+ constexpr auto l_PB_IOO_LL0_CONFIG_NV2_NPU_ENABLED_ON = 0x1;
+ l_scom_buffer.insert<62, 1, 63, uint64_t>(l_PB_IOO_LL0_CONFIG_NV2_NPU_ENABLED_ON );
+ }
+
+ if (l_def_OBUS_NV_ENABLED)
+ {
+ constexpr auto l_PB_IOO_LL0_CONFIG_NV3_NPU_ENABLED_ON = 0x1;
+ l_scom_buffer.insert<63, 1, 63, uint64_t>(l_PB_IOO_LL0_CONFIG_NV3_NPU_ENABLED_ON );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x901080cull, l_scom_buffer));
+ }
+ }
+
+ };
+fapi_try_exit:
+ return fapi2::current_err;
+}
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_npu_scom.H b/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_npu_scom.H
new file mode 100644
index 000000000..144dc1165
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_npu_scom.H
@@ -0,0 +1,45 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_npu_scom.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef _INIT_P9_FBC_IOO_DL_NPU_SCOM_PROCEDURE_H_
+#define _INIT_P9_FBC_IOO_DL_NPU_SCOM_PROCEDURE_H_
+
+
+#include <stddef.h>
+#include <stdint.h>
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_fbc_ioo_dl_npu_scom_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_OBUS>&,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&, const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>&);
+
+extern "C"
+{
+
+ fapi2::ReturnCode p9_fbc_ioo_dl_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_OBUS>& TGT0,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT1, const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT2);
+
+}
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_scom.C
index f724cdb5a..384d9070f 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_ioo_dl_scom.C
@@ -116,33 +116,6 @@ fapi2::ReturnCode p9_fbc_ioo_dl_scom(const fapi2::Target<fapi2::TARGET_TYPE_OBUS
{
FAPI_TRY(fapi2::getScom( TGT0, 0x901080cull, l_scom_buffer ));
- if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
- {
- if (l_def_OBUS_NV_ENABLED)
- {
- constexpr auto l_PB_IOO_LL0_CONFIG_NV0_NPU_ENABLED_ON = 0x1;
- l_scom_buffer.insert<60, 1, 63, uint64_t>(l_PB_IOO_LL0_CONFIG_NV0_NPU_ENABLED_ON );
- }
- }
-
- if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
- {
- if (l_def_OBUS_NV_ENABLED)
- {
- constexpr auto l_PB_IOO_LL0_CONFIG_NV1_NPU_ENABLED_ON = 0x1;
- l_scom_buffer.insert<61, 1, 63, uint64_t>(l_PB_IOO_LL0_CONFIG_NV1_NPU_ENABLED_ON );
- }
- }
-
- if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
- {
- if (l_def_OBUS_NV_ENABLED)
- {
- constexpr auto l_PB_IOO_LL0_CONFIG_NV2_NPU_ENABLED_ON = 0x1;
- l_scom_buffer.insert<62, 1, 63, uint64_t>(l_PB_IOO_LL0_CONFIG_NV2_NPU_ENABLED_ON );
- }
- }
-
if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
&& (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
|| ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
@@ -179,15 +152,6 @@ fapi2::ReturnCode p9_fbc_ioo_dl_scom(const fapi2::Target<fapi2::TARGET_TYPE_OBUS
}
}
- if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
- {
- if (l_def_OBUS_NV_ENABLED)
- {
- constexpr auto l_PB_IOO_LL0_CONFIG_NV3_NPU_ENABLED_ON = 0x1;
- l_scom_buffer.insert<63, 1, 63, uint64_t>(l_PB_IOO_LL0_CONFIG_NV3_NPU_ENABLED_ON );
- }
- }
-
if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
&& (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
|| ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_no_hp_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_no_hp_scom.C
index d368c5b07..44bc30c3f 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_no_hp_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9_fbc_no_hp_scom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -128,6 +128,13 @@ fapi2::ReturnCode p9_fbc_no_hp_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_
constexpr auto l_PB_COM_PB_CFG_LCL_HW_MARK_CNT_42 = 0x2aaaa;
l_scom_buffer.insert<30, 6, 46, uint64_t>(l_PB_COM_PB_CFG_LCL_HW_MARK_CNT_42 );
+
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ constexpr auto l_PB_COM_PB_CFG_NP2_EN_ON = 0x7;
+ l_scom_buffer.insert<49, 1, 61, uint64_t>(l_PB_COM_PB_CFG_NP2_EN_ON );
+ }
+
FAPI_TRY(fapi2::putScom(TGT0, 0x501180aull, l_scom_buffer));
}
{
@@ -168,6 +175,13 @@ fapi2::ReturnCode p9_fbc_no_hp_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_
constexpr auto l_PB_COM_PB_CFG_LCL_HW_MARK_CNT_42 = 0x2aaaa;
l_scom_buffer.insert<30, 6, 52, uint64_t>(l_PB_COM_PB_CFG_LCL_HW_MARK_CNT_42 );
+
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ constexpr auto l_PB_COM_PB_CFG_NP2_EN_ON = 0x7;
+ l_scom_buffer.insert<49, 1, 62, uint64_t>(l_PB_COM_PB_CFG_NP2_EN_ON );
+ }
+
FAPI_TRY(fapi2::putScom(TGT0, 0x5011c0aull, l_scom_buffer));
}
{
@@ -1710,6 +1724,13 @@ fapi2::ReturnCode p9_fbc_no_hp_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_
constexpr auto l_PB_COM_PB_CFG_LCL_HW_MARK_CNT_42 = 0x2aaaa;
l_scom_buffer.insert<30, 6, 58, uint64_t>(l_PB_COM_PB_CFG_LCL_HW_MARK_CNT_42 );
+
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ constexpr auto l_PB_COM_PB_CFG_NP2_EN_ON = 0x7;
+ l_scom_buffer.insert<49, 1, 63, uint64_t>(l_PB_COM_PB_CFG_NP2_EN_ON );
+ }
+
FAPI_TRY(fapi2::putScom(TGT0, 0x501200aull, l_scom_buffer));
}
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9_npu_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9_npu_scom.C
index e36053acd..f81fb7abd 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9_npu_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9_npu_scom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -44,12 +44,14 @@ constexpr uint64_t literal_0x200 = 0x200;
constexpr uint64_t literal_0x300 = 0x300;
constexpr uint64_t literal_0xFFF = 0xFFF;
constexpr uint64_t literal_0x8 = 0x8;
+constexpr uint64_t literal_0x7E = 0x7E;
constexpr uint64_t literal_0x0 = 0x0;
constexpr uint64_t literal_0xE000000000000000 = 0xE000000000000000;
constexpr uint64_t literal_0x0000740000000000 = 0x0000740000000000;
constexpr uint64_t literal_0x7F60B04500AC0000 = 0x7F60B04500AC0000;
constexpr uint64_t literal_0xAAA70A55F0000000 = 0xAAA70A55F0000000;
constexpr uint64_t literal_0x5550740000000000 = 0x5550740000000000;
+constexpr uint64_t literal_0x0FFE6FC00FF1B000 = 0x0FFE6FC00FF1B000;
constexpr uint64_t literal_0x009A48180F01FFFF = 0x009A48180F01FFFF;
constexpr uint64_t literal_0xFFFFFFFFFFFFFFFF = 0xFFFFFFFFFFFFFFFF;
constexpr uint64_t literal_0x0000000000000000 = 0x0000000000000000;
@@ -61,8 +63,8 @@ constexpr uint64_t literal_0x0000F4000FFFFFFF = 0x0000F4000FFFFFFF;
constexpr uint64_t literal_0xFFF70A5DF0000000 = 0xFFF70A5DF0000000;
constexpr uint64_t literal_0x000801A200000000 = 0x000801A200000000;
constexpr uint64_t literal_0xFFFF0BFFF0000000 = 0xFFFF0BFFF0000000;
-constexpr uint64_t literal_0xF000003FF00C0FFF = 0xF000003FF00C0FFF;
-constexpr uint64_t literal_0x0000100000024000 = 0x0000100000024000;
+constexpr uint64_t literal_0xF001803FF00C0FFF = 0xF001803FF00C0FFF;
+constexpr uint64_t literal_0x0FFE7FC00FF3F000 = 0x0FFE7FC00FF3F000;
constexpr uint64_t literal_0xF = 0xF;
constexpr uint64_t literal_0b001000 = 0b001000;
constexpr uint64_t literal_0b000001 = 0b000001;
@@ -70,7 +72,6 @@ constexpr uint64_t literal_0x66 = 0x66;
constexpr uint64_t literal_0b01 = 0b01;
constexpr uint64_t literal_0x67 = 0x67;
constexpr uint64_t literal_0x4B = 0x4B;
-constexpr uint64_t literal_0x7E = 0x7E;
constexpr uint64_t literal_0x009A48180F63FFFF = 0x009A48180F63FFFF;
constexpr uint64_t literal_0x009A48180F03FFFF = 0x009A48180F03FFFF;
constexpr uint64_t literal_0x8005000200100000 = 0x8005000200100000;
@@ -133,6 +134,16 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
if ((l_def_NVLINK_ACTIVE == literal_1))
{
+ l_scom_buffer.insert<26, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if (literal_1)
+ {
+ l_scom_buffer.insert<6, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
l_scom_buffer.insert<32, 1, 63, uint64_t>(literal_0x1 );
}
@@ -218,6 +229,16 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
if ((l_def_NVLINK_ACTIVE == literal_1))
{
+ l_scom_buffer.insert<26, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if (literal_1)
+ {
+ l_scom_buffer.insert<6, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
l_scom_buffer.insert<32, 1, 63, uint64_t>(literal_0x1 );
}
@@ -303,6 +324,16 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
if ((l_def_NVLINK_ACTIVE == literal_1))
{
+ l_scom_buffer.insert<26, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if (literal_1)
+ {
+ l_scom_buffer.insert<6, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
l_scom_buffer.insert<32, 1, 63, uint64_t>(literal_0x1 );
}
@@ -388,6 +419,16 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
if ((l_def_NVLINK_ACTIVE == literal_1))
{
+ l_scom_buffer.insert<26, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if (literal_1)
+ {
+ l_scom_buffer.insert<6, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
l_scom_buffer.insert<32, 1, 63, uint64_t>(literal_0x1 );
}
@@ -558,6 +599,32 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
{
+ FAPI_TRY(fapi2::getScom( TGT0, 0x3011e2aull, l_scom_buffer ));
+
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
+ l_scom_buffer.insert<32, 8, 56, uint64_t>(literal_0x7E );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x3011e2aull, l_scom_buffer));
+ }
+ }
+ {
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x3011e5aull, l_scom_buffer ));
+
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
+ l_scom_buffer.insert<32, 8, 56, uint64_t>(literal_0x7E );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x3011e5aull, l_scom_buffer));
+ }
+ }
+ {
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
FAPI_TRY(fapi2::getScom( TGT0, 0x3011ef5ull, l_scom_buffer ));
if ((l_def_NVLINK_ACTIVE == literal_1))
@@ -641,6 +708,19 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
{
+ FAPI_TRY(fapi2::getScom( TGT0, 0x3011fb0ull, l_scom_buffer ));
+
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0FFE6FC00FF1B000 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x3011fb0ull, l_scom_buffer));
+ }
+ }
+ {
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
FAPI_TRY(fapi2::getScom( TGT0, 0x3012003ull, l_scom_buffer ));
if ((l_def_NVLINK_ACTIVE == literal_1))
@@ -751,7 +831,7 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0xF000003FF00C0FFF );
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0xF001803FF00C0FFF );
}
else if ((l_def_NVLINK_ACTIVE == literal_0))
{
@@ -781,7 +861,7 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0000100000024000 );
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0FFE7FC00FF3F000 );
}
FAPI_TRY(fapi2::putScom(TGT0, 0x3012087ull, l_scom_buffer));
@@ -878,6 +958,19 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
+ l_scom_buffer.insert<26, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if (literal_1)
+ {
+ l_scom_buffer.insert<6, 1, 63, uint64_t>(literal_0x1 );
+ }
+ }
+
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
l_scom_buffer.insert<32, 1, 63, uint64_t>(literal_0x1 );
}
}
@@ -1862,6 +1955,19 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
+ l_scom_buffer.insert<26, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if (literal_1)
+ {
+ l_scom_buffer.insert<6, 1, 63, uint64_t>(literal_0x1 );
+ }
+ }
+
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
l_scom_buffer.insert<32, 1, 63, uint64_t>(literal_0x1 );
}
}
@@ -2590,6 +2696,19 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
+ l_scom_buffer.insert<26, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if (literal_1)
+ {
+ l_scom_buffer.insert<6, 1, 63, uint64_t>(literal_0x1 );
+ }
+ }
+
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
l_scom_buffer.insert<32, 1, 63, uint64_t>(literal_0x1 );
}
}
@@ -2955,6 +3074,19 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
+ l_scom_buffer.insert<26, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if (literal_1)
+ {
+ l_scom_buffer.insert<6, 1, 63, uint64_t>(literal_0x1 );
+ }
+ }
+
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
l_scom_buffer.insert<32, 1, 63, uint64_t>(literal_0x1 );
}
}
@@ -5526,22 +5658,22 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
FAPI_TRY(fapi2::getScom( TGT0, 0x501138aull, l_scom_buffer ));
- if (((l_chip_id == 0x5) && (l_chip_ec == 0x10)) )
+ if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
+ && (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
+ || ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
+ && (l_chip_ec == 0x13)) )
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x7F60B04500AC0000 );
+ l_scom_buffer.insert<32, 8, 56, uint64_t>(literal_0x7E );
}
}
- if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
- && (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
- || ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
- && (l_chip_ec == 0x13)) )
+ if (((l_chip_id == 0x5) && (l_chip_ec == 0x10)) )
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<32, 8, 56, uint64_t>(literal_0x7E );
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x7F60B04500AC0000 );
}
}
@@ -5575,6 +5707,19 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
}
}
{
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x50113b0ull, l_scom_buffer ));
+
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0FFE6FC00FF1B000 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x50113b0ull, l_scom_buffer));
+ }
+ }
+ {
if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
&& (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
|| ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
@@ -5670,6 +5815,19 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
+ l_scom_buffer.insert<26, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if (literal_1)
+ {
+ l_scom_buffer.insert<6, 1, 63, uint64_t>(literal_0x1 );
+ }
+ }
+
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
l_scom_buffer.insert<32, 1, 63, uint64_t>(literal_0x1 );
}
}
@@ -6378,6 +6536,19 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
+ l_scom_buffer.insert<26, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if (literal_1)
+ {
+ l_scom_buffer.insert<6, 1, 63, uint64_t>(literal_0x1 );
+ }
+ }
+
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
l_scom_buffer.insert<32, 1, 63, uint64_t>(literal_0x1 );
}
}
@@ -6970,6 +7141,19 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
+ l_scom_buffer.insert<26, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if (literal_1)
+ {
+ l_scom_buffer.insert<6, 1, 63, uint64_t>(literal_0x1 );
+ }
+ }
+
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
l_scom_buffer.insert<32, 1, 63, uint64_t>(literal_0x1 );
}
}
@@ -7090,6 +7274,16 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
if ((l_def_NVLINK_ACTIVE == literal_1))
{
+ l_scom_buffer.insert<26, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if (literal_1)
+ {
+ l_scom_buffer.insert<6, 1, 63, uint64_t>(literal_0x1 );
+ }
+
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
l_scom_buffer.insert<32, 1, 63, uint64_t>(literal_0x1 );
}
@@ -7230,11 +7424,14 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
FAPI_TRY(fapi2::getScom( TGT0, 0x501158aull, l_scom_buffer ));
- if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
+ && (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
+ || ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
+ && (l_chip_ec == 0x13)) )
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<1, 3, 61, uint64_t>(literal_0x4 );
+ l_scom_buffer.insert<32, 8, 56, uint64_t>(literal_0x7E );
}
}
@@ -7242,7 +7439,7 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<4, 10, 54, uint64_t>(literal_0x100 );
+ l_scom_buffer.insert<1, 3, 61, uint64_t>(literal_0x4 );
}
}
@@ -7250,7 +7447,7 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<14, 10, 54, uint64_t>(literal_0x200 );
+ l_scom_buffer.insert<4, 10, 54, uint64_t>(literal_0x100 );
}
}
@@ -7258,18 +7455,15 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<24, 10, 54, uint64_t>(literal_0x300 );
+ l_scom_buffer.insert<14, 10, 54, uint64_t>(literal_0x200 );
}
}
- if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
- && (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
- || ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
- && (l_chip_ec == 0x13)) )
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<32, 8, 56, uint64_t>(literal_0x7E );
+ l_scom_buffer.insert<24, 10, 54, uint64_t>(literal_0x300 );
}
}
@@ -7300,6 +7494,19 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
}
}
{
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x501162aull, l_scom_buffer ));
+
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
+ l_scom_buffer.insert<32, 8, 56, uint64_t>(literal_0x7E );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x501162aull, l_scom_buffer));
+ }
+ }
+ {
if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
&& (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
|| ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
@@ -7321,6 +7528,19 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
}
}
{
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x501165aull, l_scom_buffer ));
+
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
+ l_scom_buffer.insert<32, 8, 56, uint64_t>(literal_0x7E );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x501165aull, l_scom_buffer));
+ }
+ }
+ {
if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
&& (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
|| ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
@@ -7449,6 +7669,22 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
}
}
{
+ if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
+ && (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
+ || ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
+ && (l_chip_ec == 0x13)) )
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x5011700ull, l_scom_buffer ));
+
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0FFE6FC00FF1B000 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x5011700ull, l_scom_buffer));
+ }
+ }
+ {
if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
{
FAPI_TRY(fapi2::getScom( TGT0, 0x5011733ull, l_scom_buffer ));
@@ -7514,6 +7750,19 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
}
}
{
+ if (((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x50117b0ull, l_scom_buffer ));
+
+ if ((l_def_NVLINK_ACTIVE == literal_1))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0FFE6FC00FF1B000 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x50117b0ull, l_scom_buffer));
+ }
+ }
+ {
if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
&& (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
|| ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
@@ -7794,7 +8043,7 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0xF000003FF00C0FFF );
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0xF001803FF00C0FFF );
}
else if ((l_def_NVLINK_ACTIVE == literal_0))
{
@@ -7806,7 +8055,7 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0xF000003FF00C0FFF );
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0xF001803FF00C0FFF );
}
else if ((l_def_NVLINK_ACTIVE == literal_0))
{
@@ -7862,7 +8111,7 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0000100000024000 );
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0FFE7FC00FF3F000 );
}
}
@@ -7870,7 +8119,7 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
{
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0000100000024000 );
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0FFE7FC00FF3F000 );
}
}
@@ -8003,7 +8252,7 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0xF000003FF00C0FFF );
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0xF001803FF00C0FFF );
}
else if ((l_def_NVLINK_ACTIVE == literal_0))
{
@@ -8033,7 +8282,7 @@ fapi2::ReturnCode p9_npu_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
if ((l_def_NVLINK_ACTIVE == literal_1))
{
- l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0000100000024000 );
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0FFE7FC00FF3F000 );
}
FAPI_TRY(fapi2::putScom(TGT0, 0x5013d47ull, l_scom_buffer));
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9_xbus_g0_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9_xbus_g0_scom.C
index 1442041f7..fc00dc42a 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9_xbus_g0_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9_xbus_g0_scom.C
@@ -43,10 +43,13 @@ constexpr uint64_t literal_0b0000011 = 0b0000011;
constexpr uint64_t literal_0b000000 = 0b000000;
constexpr uint64_t literal_0b100111 = 0b100111;
constexpr uint64_t literal_0b1010 = 0b1010;
+constexpr uint64_t literal_0b00 = 0b00;
constexpr uint64_t literal_0b01 = 0b01;
constexpr uint64_t literal_0b11 = 0b11;
+constexpr uint64_t literal_0b01010000 = 0b01010000;
constexpr uint64_t literal_0b01011100 = 0b01011100;
constexpr uint64_t literal_0b01100110 = 0b01100110;
+constexpr uint64_t literal_0b00110111 = 0b00110111;
constexpr uint64_t literal_0b00111101 = 0b00111101;
constexpr uint64_t literal_0b01000100 = 0b01000100;
constexpr uint64_t literal_0b0010000 = 0b0010000;
@@ -61,7 +64,6 @@ constexpr uint64_t literal_0b0000000000000000 = 0b0000000000000000;
constexpr uint64_t literal_0b01111111 = 0b01111111;
constexpr uint64_t literal_0b10 = 0b10;
constexpr uint64_t literal_0b1100 = 0b1100;
-constexpr uint64_t literal_0b00 = 0b00;
constexpr uint64_t literal_0b01110 = 0b01110;
fapi2::ReturnCode p9_xbus_g0_scom(const fapi2::Target<fapi2::TARGET_TYPE_XBUS>& TGT0,
@@ -80,6 +82,9 @@ fapi2::ReturnCode p9_xbus_g0_scom(const fapi2::Target<fapi2::TARGET_TYPE_XBUS>&
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IO_XBUS_CHAN_EQ, TGT0, l_TGT0_ATTR_IO_XBUS_CHAN_EQ));
fapi2::ATTR_CHIP_EC_FEATURE_HW393297_Type l_TGT2_ATTR_CHIP_EC_FEATURE_HW393297;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_HW393297, TGT2, l_TGT2_ATTR_CHIP_EC_FEATURE_HW393297));
+ fapi2::ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND_Type l_TGT2_ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND, TGT2,
+ l_TGT2_ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND));
fapi2::ATTR_IO_XBUS_MASTER_MODE_Type l_TGT0_ATTR_IO_XBUS_MASTER_MODE;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IO_XBUS_MASTER_MODE, TGT0, l_TGT0_ATTR_IO_XBUS_MASTER_MODE));
uint64_t l_def_is_master = (l_TGT0_ATTR_IO_XBUS_MASTER_MODE == literal_1);
@@ -3213,7 +3218,15 @@ fapi2::ReturnCode p9_xbus_g0_scom(const fapi2::Target<fapi2::TARGET_TYPE_XBUS>&
{
FAPI_TRY(fapi2::getScom( TGT0, 0x8008c00006010c3full, l_scom_buffer ));
- l_scom_buffer.insert<48, 2, 62, uint64_t>(literal_0b01 );
+ if (l_TGT2_ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND)
+ {
+ l_scom_buffer.insert<48, 2, 62, uint64_t>(literal_0b00 );
+ }
+ else if (( true ))
+ {
+ l_scom_buffer.insert<48, 2, 62, uint64_t>(literal_0b01 );
+ }
+
constexpr auto l_IOF1_RX_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_PEAK_TUNE_OFF = 0x0;
l_scom_buffer.insert<55, 1, 63, uint64_t>(l_IOF1_RX_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_PEAK_TUNE_OFF );
l_scom_buffer.insert<57, 2, 62, uint64_t>(literal_0b11 );
@@ -3238,7 +3251,11 @@ fapi2::ReturnCode p9_xbus_g0_scom(const fapi2::Target<fapi2::TARGET_TYPE_XBUS>&
{
FAPI_TRY(fapi2::getScom( TGT0, 0x8008d00006010c3full, l_scom_buffer ));
- if ((l_TGT0_ATTR_IO_XBUS_CHAN_EQ & ENUM_ATTR_IO_XBUS_CHAN_EQ_LOWER_VGA_GAIN_TARGET))
+ if (l_TGT2_ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND)
+ {
+ l_scom_buffer.insert<48, 8, 56, uint64_t>(literal_0b01010000 );
+ }
+ else if ((l_TGT0_ATTR_IO_XBUS_CHAN_EQ & ENUM_ATTR_IO_XBUS_CHAN_EQ_LOWER_VGA_GAIN_TARGET))
{
l_scom_buffer.insert<48, 8, 56, uint64_t>(literal_0b01011100 );
}
@@ -3247,7 +3264,11 @@ fapi2::ReturnCode p9_xbus_g0_scom(const fapi2::Target<fapi2::TARGET_TYPE_XBUS>&
l_scom_buffer.insert<48, 8, 56, uint64_t>(literal_0b01100110 );
}
- if ((l_TGT0_ATTR_IO_XBUS_CHAN_EQ & ENUM_ATTR_IO_XBUS_CHAN_EQ_LOWER_VGA_GAIN_TARGET))
+ if (l_TGT2_ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND)
+ {
+ l_scom_buffer.insert<56, 8, 56, uint64_t>(literal_0b00110111 );
+ }
+ else if ((l_TGT0_ATTR_IO_XBUS_CHAN_EQ & ENUM_ATTR_IO_XBUS_CHAN_EQ_LOWER_VGA_GAIN_TARGET))
{
l_scom_buffer.insert<56, 8, 56, uint64_t>(literal_0b00111101 );
}
@@ -3377,6 +3398,12 @@ fapi2::ReturnCode p9_xbus_g0_scom(const fapi2::Target<fapi2::TARGET_TYPE_XBUS>&
constexpr auto l_IOF1_RX_RX0_RXCTL_DATASM_DATASM_REGS_RX_CTL_DATASM_CLKDIST_PDWN_OFF = 0x0;
l_scom_buffer.insert<60, 1, 63, uint64_t>(l_IOF1_RX_RX0_RXCTL_DATASM_DATASM_REGS_RX_CTL_DATASM_CLKDIST_PDWN_OFF );
+
+ if (l_TGT2_ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND)
+ {
+ l_scom_buffer.insert<56, 4, 60, uint64_t>(literal_0b0010 );
+ }
+
FAPI_TRY(fapi2::putScom(TGT0, 0x800b800006010c3full, l_scom_buffer));
}
{
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9_xbus_g1_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9_xbus_g1_scom.C
index c8052a2ca..ef24c37e6 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9_xbus_g1_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9_xbus_g1_scom.C
@@ -44,10 +44,13 @@ constexpr uint64_t literal_0b000000 = 0b000000;
constexpr uint64_t literal_0b100111 = 0b100111;
constexpr uint64_t literal_0b000001 = 0b000001;
constexpr uint64_t literal_0b1010 = 0b1010;
+constexpr uint64_t literal_0b00 = 0b00;
constexpr uint64_t literal_0b01 = 0b01;
constexpr uint64_t literal_0b11 = 0b11;
+constexpr uint64_t literal_0b01010000 = 0b01010000;
constexpr uint64_t literal_0b01011100 = 0b01011100;
constexpr uint64_t literal_0b01100110 = 0b01100110;
+constexpr uint64_t literal_0b00110111 = 0b00110111;
constexpr uint64_t literal_0b00111101 = 0b00111101;
constexpr uint64_t literal_0b01000100 = 0b01000100;
constexpr uint64_t literal_0b0010000 = 0b0010000;
@@ -62,7 +65,6 @@ constexpr uint64_t literal_0b0000000000000000 = 0b0000000000000000;
constexpr uint64_t literal_0b01111111 = 0b01111111;
constexpr uint64_t literal_0b10 = 0b10;
constexpr uint64_t literal_0b1100 = 0b1100;
-constexpr uint64_t literal_0b00 = 0b00;
constexpr uint64_t literal_0b01110 = 0b01110;
fapi2::ReturnCode p9_xbus_g1_scom(const fapi2::Target<fapi2::TARGET_TYPE_XBUS>& TGT0,
@@ -81,6 +83,9 @@ fapi2::ReturnCode p9_xbus_g1_scom(const fapi2::Target<fapi2::TARGET_TYPE_XBUS>&
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IO_XBUS_CHAN_EQ, TGT0, l_TGT0_ATTR_IO_XBUS_CHAN_EQ));
fapi2::ATTR_CHIP_EC_FEATURE_HW393297_Type l_TGT2_ATTR_CHIP_EC_FEATURE_HW393297;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_HW393297, TGT2, l_TGT2_ATTR_CHIP_EC_FEATURE_HW393297));
+ fapi2::ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND_Type l_TGT2_ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND, TGT2,
+ l_TGT2_ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND));
fapi2::ATTR_IO_XBUS_MASTER_MODE_Type l_TGT0_ATTR_IO_XBUS_MASTER_MODE;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IO_XBUS_MASTER_MODE, TGT0, l_TGT0_ATTR_IO_XBUS_MASTER_MODE));
uint64_t l_def_is_master = (l_TGT0_ATTR_IO_XBUS_MASTER_MODE == literal_1);
@@ -3212,9 +3217,22 @@ fapi2::ReturnCode p9_xbus_g1_scom(const fapi2::Target<fapi2::TARGET_TYPE_XBUS>&
FAPI_TRY(fapi2::putScom(TGT0, 0x8008402006010c3full, l_scom_buffer));
}
{
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8008c00006010c3full, l_scom_buffer ));
+
+ if (l_TGT2_ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND)
+ {
+ l_scom_buffer.insert<48, 2, 62, uint64_t>(literal_0b00 );
+ }
+ else if (( true ))
+ {
+ l_scom_buffer.insert<48, 2, 62, uint64_t>(literal_0b01 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8008c00006010c3full, l_scom_buffer));
+ }
+ {
FAPI_TRY(fapi2::getScom( TGT0, 0x8008c02006010c3full, l_scom_buffer ));
- l_scom_buffer.insert<48, 2, 62, uint64_t>(literal_0b01 );
constexpr auto l_IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_PEAK_TUNE_OFF = 0x0;
l_scom_buffer.insert<55, 1, 63, uint64_t>(l_IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_PEAK_TUNE_OFF );
l_scom_buffer.insert<57, 2, 62, uint64_t>(literal_0b11 );
@@ -3239,7 +3257,11 @@ fapi2::ReturnCode p9_xbus_g1_scom(const fapi2::Target<fapi2::TARGET_TYPE_XBUS>&
{
FAPI_TRY(fapi2::getScom( TGT0, 0x8008d02006010c3full, l_scom_buffer ));
- if ((l_TGT0_ATTR_IO_XBUS_CHAN_EQ & ENUM_ATTR_IO_XBUS_CHAN_EQ_LOWER_VGA_GAIN_TARGET))
+ if (l_TGT2_ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND)
+ {
+ l_scom_buffer.insert<48, 8, 56, uint64_t>(literal_0b01010000 );
+ }
+ else if ((l_TGT0_ATTR_IO_XBUS_CHAN_EQ & ENUM_ATTR_IO_XBUS_CHAN_EQ_LOWER_VGA_GAIN_TARGET))
{
l_scom_buffer.insert<48, 8, 56, uint64_t>(literal_0b01011100 );
}
@@ -3248,7 +3270,11 @@ fapi2::ReturnCode p9_xbus_g1_scom(const fapi2::Target<fapi2::TARGET_TYPE_XBUS>&
l_scom_buffer.insert<48, 8, 56, uint64_t>(literal_0b01100110 );
}
- if ((l_TGT0_ATTR_IO_XBUS_CHAN_EQ & ENUM_ATTR_IO_XBUS_CHAN_EQ_LOWER_VGA_GAIN_TARGET))
+ if (l_TGT2_ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND)
+ {
+ l_scom_buffer.insert<56, 8, 56, uint64_t>(literal_0b00110111 );
+ }
+ else if ((l_TGT0_ATTR_IO_XBUS_CHAN_EQ & ENUM_ATTR_IO_XBUS_CHAN_EQ_LOWER_VGA_GAIN_TARGET))
{
l_scom_buffer.insert<56, 8, 56, uint64_t>(literal_0b00111101 );
}
@@ -3378,6 +3404,12 @@ fapi2::ReturnCode p9_xbus_g1_scom(const fapi2::Target<fapi2::TARGET_TYPE_XBUS>&
constexpr auto l_IOF1_RX_RX1_RXCTL_DATASM_DATASM_REGS_RX_CTL_DATASM_CLKDIST_PDWN_OFF = 0x0;
l_scom_buffer.insert<60, 1, 63, uint64_t>(l_IOF1_RX_RX1_RXCTL_DATASM_DATASM_REGS_RX_CTL_DATASM_CLKDIST_PDWN_OFF );
+
+ if (l_TGT2_ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND)
+ {
+ l_scom_buffer.insert<56, 4, 60, uint64_t>(literal_0b0010 );
+ }
+
FAPI_TRY(fapi2::putScom(TGT0, 0x800b802006010c3full, l_scom_buffer));
}
{
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.C b/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.C
new file mode 100644
index 000000000..f35a145d7
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.C
@@ -0,0 +1,72 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include "p9a_int_scan.H"
+#include <stdint.h>
+#include <stddef.h>
+#include <fapi2.H>
+
+using namespace fapi2;
+
+constexpr uint64_t literal_0 = 0;
+constexpr uint64_t literal_0b1 = 0b1;
+
+fapi2::ReturnCode p9a_int_scan(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT0)
+{
+ {
+ fapi2::ATTR_EC_Type l_chip_ec;
+ fapi2::ATTR_NAME_Type l_chip_id;
+ FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, TGT0, l_chip_id));
+ FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_EC, TGT0, l_chip_ec));
+ fapi2::ATTR_CHIP_EC_FEATURE_HW388874_Type l_TGT0_ATTR_CHIP_EC_FEATURE_HW388874;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_HW388874, TGT0, l_TGT0_ATTR_CHIP_EC_FEATURE_HW388874));
+ bool l_BRIDGE_PSIHB_ESB_OR_LSI_INTERRUPTS_update = false;
+ fapi2::variable_buffer l_BRIDGE_PSIHB_ESB_OR_LSI_INTERRUPTS(1);
+ fapi2::variable_buffer l_BRIDGE_PSIHB_ESB_OR_LSI_INTERRUPTS_CARE(1);
+
+ if ((l_TGT0_ATTR_CHIP_EC_FEATURE_HW388874 == literal_0))
+ {
+ constexpr auto l_BRIDGE_PSIHB_ESB_OR_LSI_INTERRUPTS_ON = 0x1;
+ l_BRIDGE_PSIHB_ESB_OR_LSI_INTERRUPTS.insertFromRight<uint64_t>(l_BRIDGE_PSIHB_ESB_OR_LSI_INTERRUPTS_ON, 0, 1);
+ l_BRIDGE_PSIHB_ESB_OR_LSI_INTERRUPTS_CARE.insertFromRight<uint64_t>(0x1, 0, 1);
+ l_BRIDGE_PSIHB_ESB_OR_LSI_INTERRUPTS_update = true;
+ }
+
+ if ( l_BRIDGE_PSIHB_ESB_OR_LSI_INTERRUPTS_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "BRIDGE.PSIHB.ESB_OR_LSI_INTERRUPTS", l_BRIDGE_PSIHB_ESB_OR_LSI_INTERRUPTS,
+ l_BRIDGE_PSIHB_ESB_OR_LSI_INTERRUPTS_CARE));
+ }
+
+ fapi2::variable_buffer l_INT_INT_VC_LBS6_ARX_CS_AXONE_DISABLE_CILOAD_ORDERINGS(1);
+ fapi2::variable_buffer l_INT_INT_VC_LBS6_ARX_CS_AXONE_DISABLE_CILOAD_ORDERINGS_CARE(1);
+ l_INT_INT_VC_LBS6_ARX_CS_AXONE_DISABLE_CILOAD_ORDERINGS.insertFromRight<uint64_t>(literal_0b1, 0, 1);
+ l_INT_INT_VC_LBS6_ARX_CS_AXONE_DISABLE_CILOAD_ORDERINGS_CARE.insertFromRight<uint64_t>(0x1, 0, 1);
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "INT.INT_VC_LBS6_ARX_CS_AXONE_DISABLE_CILOAD_ORDERINGS",
+ l_INT_INT_VC_LBS6_ARX_CS_AXONE_DISABLE_CILOAD_ORDERINGS, l_INT_INT_VC_LBS6_ARX_CS_AXONE_DISABLE_CILOAD_ORDERINGS_CARE));
+
+ };
+fapi_try_exit:
+ return fapi2::current_err;
+}
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.H b/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.H
new file mode 100644
index 000000000..470e17d7d
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.H
@@ -0,0 +1,47 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef _INIT_P9A_INT_SCAN_PROCEDURE_H_
+#define _INIT_P9A_INT_SCAN_PROCEDURE_H_
+
+
+#include <stddef.h>
+#include <stdint.h>
+#include <fapi2.H>
+
+#ifdef IFCOMPILER_PLAT
+#define INITFILE_PROCEDURE \
+ p9a_int_scan(TGT0);
+#endif
+
+typedef fapi2::ReturnCode (*p9a_int_scan_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);
+
+extern "C"
+{
+
+ fapi2::ReturnCode p9a_int_scan(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT0);
+
+}
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.mk b/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.mk
new file mode 100644
index 000000000..6fcb57af4
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.mk
@@ -0,0 +1,36 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scan.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+PROCEDURE=p9a_int_scan
+lib$(PROCEDURE)_COMMONFLAGS+=-DFAPI_SUPPORT_SPY_AS_STRING=1
+$(call BUILD_PROCEDURE)
+
+PROCEDURE=p9a_int_scan_ifCompiler
+lib$(PROCEDURE)_COMMONFLAGS+=-DFAPI_SUPPORT_SPY_AS_STRING=1
+lib$(PROCEDURE)_COMMONFLAGS+=-DIFCOMPILER_PLAT=1
+FAPI=2_IFCOMPILER
+OBJS+=p9a_int_scan.o
+lib$(PROCEDURE)_LIBPATH=$(LIBPATH)/ifCompiler
+lib$(PROCEDURE)_COMMONFLAGS+=-fno-var-tracking-assignments
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.C
new file mode 100644
index 000000000..aa6143eb6
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.C
@@ -0,0 +1,228 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include "p9a_int_scom.H"
+#include <stdint.h>
+#include <stddef.h>
+#include <fapi2.H>
+
+using namespace fapi2;
+
+constexpr uint64_t literal_0 = 0;
+constexpr uint64_t literal_1 = 1;
+constexpr uint64_t literal_0b10 = 0b10;
+constexpr uint64_t literal_0b1000000 = 0b1000000;
+constexpr uint64_t literal_0x2000005C04028000 = 0x2000005C04028000;
+constexpr uint64_t literal_0x2000005C040281C3 = 0x2000005C040281C3;
+constexpr uint64_t literal_0x0000005C040081C3 = 0x0000005C040081C3;
+constexpr uint64_t literal_0x0000000000000000 = 0x0000000000000000;
+constexpr uint64_t literal_0x9554021F80110FCF = 0x9554021F80110FCF;
+constexpr uint64_t literal_0x9554021F80110E0C = 0x9554021F80110E0C;
+constexpr uint64_t literal_0x18 = 0x18;
+constexpr uint64_t literal_0x010003FF00100020 = 0x010003FF00100020;
+constexpr uint64_t literal_0x050043EF00100020 = 0x050043EF00100020;
+constexpr uint64_t literal_0xD8DFB200DFAFFFD7 = 0xD8DFB200DFAFFFD7;
+constexpr uint64_t literal_0xFADFBB8CFFAFFFD7 = 0xFADFBB8CFFAFFFD7;
+constexpr uint64_t literal_0x0002000410000000 = 0x0002000410000000;
+constexpr uint64_t literal_0x0002000610000000 = 0x0002000610000000;
+constexpr uint64_t literal_0x6262220242160000 = 0x6262220242160000;
+constexpr uint64_t literal_0x5BBF = 0x5BBF;
+
+fapi2::ReturnCode p9a_int_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT0,
+ const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT1)
+{
+ {
+ fapi2::ATTR_EC_Type l_chip_ec;
+ fapi2::ATTR_NAME_Type l_chip_id;
+ FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, TGT0, l_chip_id));
+ FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_EC, TGT0, l_chip_ec));
+ fapi2::ATTR_PROC_FABRIC_PUMP_MODE_Type l_TGT1_ATTR_PROC_FABRIC_PUMP_MODE;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_PUMP_MODE, TGT1, l_TGT1_ATTR_PROC_FABRIC_PUMP_MODE));
+ fapi2::ATTR_FABRIC_ADDR_EXTENSION_GROUP_ID_Type l_TGT1_ATTR_FABRIC_ADDR_EXTENSION_GROUP_ID;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FABRIC_ADDR_EXTENSION_GROUP_ID, TGT1, l_TGT1_ATTR_FABRIC_ADDR_EXTENSION_GROUP_ID));
+ fapi2::ATTR_FABRIC_ADDR_EXTENSION_CHIP_ID_Type l_TGT1_ATTR_FABRIC_ADDR_EXTENSION_CHIP_ID;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FABRIC_ADDR_EXTENSION_CHIP_ID, TGT1, l_TGT1_ATTR_FABRIC_ADDR_EXTENSION_CHIP_ID));
+ fapi2::ATTR_SMF_CONFIG_Type l_TGT1_ATTR_SMF_CONFIG;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SMF_CONFIG, TGT1, l_TGT1_ATTR_SMF_CONFIG));
+ fapi2::ATTR_CHIP_EC_FEATURE_HW426891_Type l_TGT0_ATTR_CHIP_EC_FEATURE_HW426891;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_HW426891, TGT0, l_TGT0_ATTR_CHIP_EC_FEATURE_HW426891));
+ fapi2::ATTR_CHIP_EC_FEATURE_HW411637_Type l_TGT0_ATTR_CHIP_EC_FEATURE_HW411637;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_HW411637, TGT0, l_TGT0_ATTR_CHIP_EC_FEATURE_HW411637));
+ fapi2::ATTR_CHIP_EC_FEATURE_P9N_INT_DD10_Type l_TGT0_ATTR_CHIP_EC_FEATURE_P9N_INT_DD10;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_P9N_INT_DD10, TGT0, l_TGT0_ATTR_CHIP_EC_FEATURE_P9N_INT_DD10));
+ fapi2::buffer<uint64_t> l_scom_buffer;
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x501300aull, l_scom_buffer ));
+
+ l_scom_buffer.insert<0, 1, 63, uint64_t>(literal_0 );
+
+ if ((l_TGT1_ATTR_PROC_FABRIC_PUMP_MODE == fapi2::ENUM_ATTR_PROC_FABRIC_PUMP_MODE_CHIP_IS_GROUP))
+ {
+ l_scom_buffer.insert<1, 1, 63, uint64_t>(literal_1 );
+ }
+ else if ((l_TGT1_ATTR_PROC_FABRIC_PUMP_MODE == fapi2::ENUM_ATTR_PROC_FABRIC_PUMP_MODE_CHIP_IS_NODE))
+ {
+ l_scom_buffer.insert<1, 1, 63, uint64_t>(literal_0 );
+ }
+
+ l_scom_buffer.insert<5, 4, 60, uint64_t>(l_TGT1_ATTR_FABRIC_ADDR_EXTENSION_GROUP_ID );
+ l_scom_buffer.insert<9, 3, 61, uint64_t>(l_TGT1_ATTR_FABRIC_ADDR_EXTENSION_CHIP_ID );
+
+ if ((l_TGT1_ATTR_SMF_CONFIG == fapi2::ENUM_ATTR_SMF_CONFIG_ENABLED))
+ {
+ l_scom_buffer.insert<12, 2, 62, uint64_t>(literal_0b10 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x501300aull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x5013020ull, l_scom_buffer ));
+
+ l_scom_buffer.insert<25, 7, 57, uint64_t>(literal_0b1000000 );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x5013020ull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x5013021ull, l_scom_buffer ));
+
+ if ((l_TGT1_ATTR_PROC_FABRIC_PUMP_MODE == fapi2::ENUM_ATTR_PROC_FABRIC_PUMP_MODE_CHIP_IS_GROUP))
+ {
+ l_scom_buffer.insert<49, 1, 63, uint64_t>(literal_1 );
+ }
+ else if ((l_TGT1_ATTR_PROC_FABRIC_PUMP_MODE == fapi2::ENUM_ATTR_PROC_FABRIC_PUMP_MODE_CHIP_IS_NODE))
+ {
+ l_scom_buffer.insert<49, 1, 63, uint64_t>(literal_0 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x5013021ull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x5013033ull, l_scom_buffer ));
+
+ if (((l_TGT0_ATTR_CHIP_EC_FEATURE_HW411637 == literal_1) && (l_TGT0_ATTR_CHIP_EC_FEATURE_HW426891 == literal_0)))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x2000005C04028000 );
+ }
+ else if (((l_TGT0_ATTR_CHIP_EC_FEATURE_HW411637 == literal_1) && (l_TGT0_ATTR_CHIP_EC_FEATURE_HW426891 == literal_1)))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x2000005C040281C3 );
+ }
+ else if (((l_TGT0_ATTR_CHIP_EC_FEATURE_HW411637 == literal_0) && (l_TGT0_ATTR_CHIP_EC_FEATURE_HW426891 == literal_1)))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0000005C040081C3 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x5013033ull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x5013036ull, l_scom_buffer ));
+
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0000000000000000 );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x5013036ull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x5013037ull, l_scom_buffer ));
+
+ if ((l_TGT0_ATTR_CHIP_EC_FEATURE_P9N_INT_DD10 == literal_1))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x9554021F80110FCF );
+ }
+ else if ((l_TGT0_ATTR_CHIP_EC_FEATURE_P9N_INT_DD10 == literal_0))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x9554021F80110E0C );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x5013037ull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x5013130ull, l_scom_buffer ));
+
+ l_scom_buffer.insert<2, 6, 58, uint64_t>(literal_0x18 );
+ l_scom_buffer.insert<10, 6, 58, uint64_t>(literal_0x18 );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x5013130ull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x5013140ull, l_scom_buffer ));
+
+ if ((l_TGT0_ATTR_CHIP_EC_FEATURE_HW426891 == literal_0))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x010003FF00100020 );
+ }
+ else if ((l_TGT0_ATTR_CHIP_EC_FEATURE_HW426891 == literal_1))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x050043EF00100020 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x5013140ull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x5013141ull, l_scom_buffer ));
+
+ if ((l_TGT0_ATTR_CHIP_EC_FEATURE_HW426891 == literal_0))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0xD8DFB200DFAFFFD7 );
+ }
+ else if ((l_TGT0_ATTR_CHIP_EC_FEATURE_HW426891 == literal_1))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0xFADFBB8CFFAFFFD7 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x5013141ull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x5013178ull, l_scom_buffer ));
+
+ if ((l_TGT0_ATTR_CHIP_EC_FEATURE_HW426891 == literal_0))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0002000410000000 );
+ }
+ else if ((l_TGT0_ATTR_CHIP_EC_FEATURE_HW426891 == literal_1))
+ {
+ l_scom_buffer.insert<0, 64, 0, uint64_t>(literal_0x0002000610000000 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x5013178ull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x501320eull, l_scom_buffer ));
+
+ l_scom_buffer.insert<0, 48, 0, uint64_t>(literal_0x6262220242160000 );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x501320eull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x5013214ull, l_scom_buffer ));
+
+ l_scom_buffer.insert<16, 16, 48, uint64_t>(literal_0x5BBF );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x5013214ull, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x501322bull, l_scom_buffer ));
+
+ l_scom_buffer.insert<58, 6, 58, uint64_t>(literal_0x18 );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x501322bull, l_scom_buffer));
+ }
+
+ };
+fapi_try_exit:
+ return fapi2::current_err;
+}
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.H b/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.H
new file mode 100644
index 000000000..50fb3b02e
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.H
@@ -0,0 +1,45 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef _INIT_P9A_INT_SCOM_PROCEDURE_H_
+#define _INIT_P9A_INT_SCOM_PROCEDURE_H_
+
+
+#include <stddef.h>
+#include <stdint.h>
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9a_int_scom_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&,
+ const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>&);
+
+extern "C"
+{
+
+ fapi2::ReturnCode p9a_int_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT0,
+ const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT1);
+
+}
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.mk b/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.mk
new file mode 100644
index 000000000..8242855ad
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.mk
@@ -0,0 +1,27 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/import/chips/p9/procedures/hwp/initfiles/p9a_int_scom.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+PROCEDURE=p9a_int_scom
+lib$(PROCEDURE)_COMMONFLAGS+=-fno-var-tracking-assignments
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scan.C b/src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scan.C
index 974ffb124..887cafdca 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scan.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scan.C
@@ -30,8 +30,25 @@
using namespace fapi2;
constexpr uint64_t literal_8 = 8;
+constexpr uint64_t literal_1 = 1;
+constexpr uint64_t literal_12 = 12;
+constexpr uint64_t literal_0 = 0;
+constexpr uint64_t literal_0b0100 = 0b0100;
+constexpr uint64_t literal_28 = 28;
+constexpr uint64_t literal_0x1 = 0x1;
+constexpr uint64_t literal_4 = 4;
+constexpr uint64_t literal_6 = 6;
+constexpr uint64_t literal_0b1100111111111111111111111 = 0b1100111111111111111111111;
+constexpr uint64_t literal_24 = 24;
+constexpr uint64_t literal_0x3 = 0x3;
+constexpr uint64_t literal_0x5 = 0x5;
+constexpr uint64_t literal_0x7 = 0x7;
+constexpr uint64_t literal_0x26 = 0x26;
+constexpr uint64_t literal_0x33 = 0x33;
+constexpr uint64_t literal_0x40 = 0x40;
-fapi2::ReturnCode p9a_mcc_omi_scan(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT0)
+fapi2::ReturnCode p9a_mcc_omi_scan(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT0,
+ const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT1)
{
{
fapi2::ATTR_EC_Type l_chip_ec;
@@ -70,6 +87,773 @@ fapi2::ReturnCode p9a_mcc_omi_scan(const fapi2::Target<fapi2::TARGET_TYPE_PROC_C
FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC23.CHAN3.ATCL.CL.CLSCOM.MCPERF0_WR_RSVD_LOWER_OR_STATIC_LIMIT",
l_MC23_CHAN0_ATCL_CL_CLSCOM_MCPERF0_WR_RSVD_LOWER_OR_STATIC_LIMIT,
l_MC23_CHAN0_ATCL_CL_CLSCOM_MCPERF0_WR_RSVD_LOWER_OR_STATIC_LIMIT_CARE));
+ uint64_t l_def_ENABLE_AMO_CLEAN_LINES = literal_1;
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN(1);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_CARE(1);
+
+ if ((l_def_ENABLE_AMO_CLEAN_LINES == literal_1))
+ {
+ constexpr auto l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_ON = 0x1;
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN.insertFromRight<uint64_t>
+ (l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_ON, 0, 1);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_CARE.insertFromRight<uint64_t>(0x1, 0, 1);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCAMOC_ENABLE_CLEAN",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCAMOC_ENABLE_CLEAN",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCAMOC_ENABLE_CLEAN",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCAMOC_ENABLE_CLEAN",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_CARE));
+ }
+
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN(6);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN_CARE(6);
+
+ if ((l_def_ENABLE_AMO_CLEAN_LINES == literal_1))
+ {
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN.insertFromRight<uint64_t>(literal_12, 0, 6);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN_CARE.insertFromRight<uint64_t>(0x3f, 0, 6);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCPERF2_NUM_CLEAN",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCPERF2_NUM_CLEAN",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCPERF2_NUM_CLEAN",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCPERF2_NUM_CLEAN",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_CLEAN_CARE));
+ }
+
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_ALT_M(4);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_ALT_M_CARE(4);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_ALT_M.insertFromRight<uint64_t>(literal_0, 0, 4);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_ALT_M_CARE.insertFromRight<uint64_t>(0xf, 0, 4);
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCPERF2_ALT_M",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_ALT_M, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_ALT_M_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCPERF2_ALT_M",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_ALT_M, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_ALT_M_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCPERF2_ALT_M",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_ALT_M, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_ALT_M_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCPERF2_ALT_M",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_ALT_M, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_ALT_M_CARE));
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_SQ_LFSR_CNTL(4);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_SQ_LFSR_CNTL_CARE(4);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_SQ_LFSR_CNTL.insertFromRight<uint64_t>(literal_0b0100, 0, 4);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_SQ_LFSR_CNTL_CARE.insertFromRight<uint64_t>(0xf, 0, 4);
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCPERF2_SQ_LFSR_CNTL",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_SQ_LFSR_CNTL, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_SQ_LFSR_CNTL_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCPERF2_SQ_LFSR_CNTL",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_SQ_LFSR_CNTL, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_SQ_LFSR_CNTL_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCPERF2_SQ_LFSR_CNTL",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_SQ_LFSR_CNTL, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_SQ_LFSR_CNTL_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCPERF2_SQ_LFSR_CNTL",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_SQ_LFSR_CNTL, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_SQ_LFSR_CNTL_CARE));
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_RMW_BUF(5);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_RMW_BUF_CARE(5);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_RMW_BUF.insertFromRight<uint64_t>(literal_28, 0, 5);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_RMW_BUF_CARE.insertFromRight<uint64_t>(0x1f, 0, 5);
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCPERF2_NUM_RMW_BUF",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_RMW_BUF, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_RMW_BUF_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCPERF2_NUM_RMW_BUF",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_RMW_BUF, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_RMW_BUF_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCPERF2_NUM_RMW_BUF",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_RMW_BUF, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_RMW_BUF_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCPERF2_NUM_RMW_BUF",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_RMW_BUF, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_NUM_RMW_BUF_CARE));
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_JITTER_EPSILON(8);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_JITTER_EPSILON_CARE(8);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_JITTER_EPSILON.insertFromRight<uint64_t>(literal_0x1, 0, 8);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_JITTER_EPSILON_CARE.insertFromRight<uint64_t>(0xff, 0, 8);
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCEPSQ_JITTER_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_JITTER_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_JITTER_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCEPSQ_JITTER_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_JITTER_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_JITTER_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCEPSQ_JITTER_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_JITTER_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_JITTER_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCEPSQ_JITTER_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_JITTER_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_JITTER_EPSILON_CARE));
+ fapi2::ATTR_PROC_EPS_READ_CYCLES_T0_Type l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_EPS_READ_CYCLES_T0, TGT1, l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T0));
+ uint64_t l_def_MC_EPSILON_CFG_T0 = ((l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T0 + literal_6) / literal_4);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_LOCAL_NODE_EPSILON(8);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_LOCAL_NODE_EPSILON_CARE(8);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_LOCAL_NODE_EPSILON.insertFromRight<uint64_t>(l_def_MC_EPSILON_CFG_T0, 0, 8);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_LOCAL_NODE_EPSILON_CARE.insertFromRight<uint64_t>(0xff, 0, 8);
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCEPSQ_LOCAL_NODE_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_LOCAL_NODE_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_LOCAL_NODE_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCEPSQ_LOCAL_NODE_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_LOCAL_NODE_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_LOCAL_NODE_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCEPSQ_LOCAL_NODE_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_LOCAL_NODE_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_LOCAL_NODE_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCEPSQ_LOCAL_NODE_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_LOCAL_NODE_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_LOCAL_NODE_EPSILON_CARE));
+ fapi2::ATTR_PROC_EPS_READ_CYCLES_T1_Type l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T1;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_EPS_READ_CYCLES_T1, TGT1, l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T1));
+ uint64_t l_def_MC_EPSILON_CFG_T1 = ((l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T1 + literal_6) / literal_4);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_NEAR_NODAL_EPSILON(8);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_NEAR_NODAL_EPSILON_CARE(8);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_NEAR_NODAL_EPSILON.insertFromRight<uint64_t>(l_def_MC_EPSILON_CFG_T1, 0, 8);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_NEAR_NODAL_EPSILON_CARE.insertFromRight<uint64_t>(0xff, 0, 8);
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCEPSQ_NEAR_NODAL_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_NEAR_NODAL_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_NEAR_NODAL_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCEPSQ_NEAR_NODAL_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_NEAR_NODAL_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_NEAR_NODAL_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCEPSQ_NEAR_NODAL_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_NEAR_NODAL_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_NEAR_NODAL_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCEPSQ_NEAR_NODAL_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_NEAR_NODAL_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_NEAR_NODAL_EPSILON_CARE));
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_GROUP_EPSILON(8);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_GROUP_EPSILON_CARE(8);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_GROUP_EPSILON.insertFromRight<uint64_t>(l_def_MC_EPSILON_CFG_T1, 0, 8);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_GROUP_EPSILON_CARE.insertFromRight<uint64_t>(0xff, 0, 8);
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCEPSQ_GROUP_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_GROUP_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_GROUP_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCEPSQ_GROUP_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_GROUP_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_GROUP_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCEPSQ_GROUP_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_GROUP_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_GROUP_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCEPSQ_GROUP_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_GROUP_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_GROUP_EPSILON_CARE));
+ fapi2::ATTR_PROC_EPS_READ_CYCLES_T2_Type l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T2;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_EPS_READ_CYCLES_T2, TGT1, l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T2));
+ uint64_t l_def_MC_EPSILON_CFG_T2 = ((l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T2 + literal_6) / literal_4);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_REMOTE_NODAL_EPSILON(8);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_REMOTE_NODAL_EPSILON_CARE(8);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_REMOTE_NODAL_EPSILON.insertFromRight<uint64_t>(l_def_MC_EPSILON_CFG_T2, 0, 8);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_REMOTE_NODAL_EPSILON_CARE.insertFromRight<uint64_t>(0xff, 0, 8);
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCEPSQ_REMOTE_NODAL_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_REMOTE_NODAL_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_REMOTE_NODAL_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCEPSQ_REMOTE_NODAL_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_REMOTE_NODAL_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_REMOTE_NODAL_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCEPSQ_REMOTE_NODAL_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_REMOTE_NODAL_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_REMOTE_NODAL_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCEPSQ_REMOTE_NODAL_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_REMOTE_NODAL_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_REMOTE_NODAL_EPSILON_CARE));
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_VECTOR_GROUP_EPSILON(8);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_VECTOR_GROUP_EPSILON_CARE(8);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_VECTOR_GROUP_EPSILON.insertFromRight<uint64_t>(l_def_MC_EPSILON_CFG_T2, 0, 8);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_VECTOR_GROUP_EPSILON_CARE.insertFromRight<uint64_t>(0xff, 0, 8);
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCEPSQ_VECTOR_GROUP_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_VECTOR_GROUP_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_VECTOR_GROUP_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCEPSQ_VECTOR_GROUP_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_VECTOR_GROUP_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_VECTOR_GROUP_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCEPSQ_VECTOR_GROUP_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_VECTOR_GROUP_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_VECTOR_GROUP_EPSILON_CARE));
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCEPSQ_VECTOR_GROUP_EPSILON",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_VECTOR_GROUP_EPSILON, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCEPSQ_VECTOR_GROUP_EPSILON_CARE));
+ uint64_t l_def_ENABLE_AMO_CACHING = literal_1;
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES(25);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES_CARE(25);
+
+ if (l_def_ENABLE_AMO_CACHING)
+ {
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES.insertFromRight<uint64_t>
+ (literal_0b1100111111111111111111111, 0, 25);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES_CARE.insertFromRight<uint64_t>(0x1ffffff, 0, 25);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCAMOC_WRTO_AMO_COLLISION_RULES",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCAMOC_WRTO_AMO_COLLISION_RULES",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCAMOC_WRTO_AMO_COLLISION_RULES",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCAMOC_WRTO_AMO_COLLISION_RULES",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_WRTO_AMO_COLLISION_RULES_CARE));
+ }
+
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT(3);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_CARE(3);
+
+ if (l_def_ENABLE_AMO_CACHING)
+ {
+ constexpr auto l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_128B_RW_64B_DATA = 0x1;
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT.insertFromRight<uint64_t>
+ (l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_128B_RW_64B_DATA, 0, 3);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_CARE.insertFromRight<uint64_t>(0x7, 0, 3);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCAMOC_AMO_SIZE_SELECT",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCAMOC_AMO_SIZE_SELECT",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCAMOC_AMO_SIZE_SELECT",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCAMOC_AMO_SIZE_SELECT",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_CARE));
+ }
+
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT(6);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT_CARE(6);
+
+ if (l_def_ENABLE_AMO_CACHING)
+ {
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT.insertFromRight<uint64_t>(literal_24, 0, 6);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT_CARE.insertFromRight<uint64_t>(0x3f, 0, 6);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCPERF0_AMO_LIMIT",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCPERF0_AMO_LIMIT",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCPERF0_AMO_LIMIT",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCPERF0_AMO_LIMIT",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF0_AMO_LIMIT_CARE));
+ }
+
+ bool l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_update = false;
+ fapi2::variable_buffer l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE(1);
+ fapi2::variable_buffer l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_CARE(1);
+
+ if (l_def_ENABLE_AMO_CACHING)
+ {
+ constexpr auto l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_ON = 0x1;
+ l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE.insertFromRight<uint64_t>(l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_ON, 0, 1);
+ l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_CARE.insertFromRight<uint64_t>(0x1, 0, 1);
+ l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_update = true;
+ }
+
+ if ( l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MCP.CHAN0.WRITE.NEW_WRITE_64B_MODE", l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE,
+ l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_CARE));
+ }
+
+ if ( l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MCP.CHAN1.WRITE.NEW_WRITE_64B_MODE", l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE,
+ l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_CARE));
+ }
+
+ if ( l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MCP.CHAN2.WRITE.NEW_WRITE_64B_MODE", l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE,
+ l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_CARE));
+ }
+
+ if ( l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MCP.CHAN3.WRITE.NEW_WRITE_64B_MODE", l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE,
+ l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_CARE));
+ }
+
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL(1);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_CARE(1);
+
+ if (l_def_ENABLE_AMO_CACHING)
+ {
+ constexpr auto l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_ON = 0x1;
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL.insertFromRight<uint64_t>
+ (l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_ON, 0, 1);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_CARE.insertFromRight<uint64_t>(0x1, 0, 1);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCPERF3_AMO_LIMIT_SEL",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCPERF3_AMO_LIMIT_SEL",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCPERF3_AMO_LIMIT_SEL",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCPERF3_AMO_LIMIT_SEL",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_CARE));
+ }
+
+ uint64_t l_def_ENABLE_PREFETCH_DROP_PROMOTE_BASIC = literal_1;
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0(3);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0_CARE(3);
+
+ if (l_def_ENABLE_PREFETCH_DROP_PROMOTE_BASIC)
+ {
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0.insertFromRight<uint64_t>(literal_0x1, 0, 3);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0_CARE.insertFromRight<uint64_t>(0x7, 0, 3);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE0",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE0",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE0",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE0",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE0_CARE));
+ }
+
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1(3);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1_CARE(3);
+
+ if (l_def_ENABLE_PREFETCH_DROP_PROMOTE_BASIC)
+ {
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1.insertFromRight<uint64_t>(literal_0x3, 0, 3);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1_CARE.insertFromRight<uint64_t>(0x7, 0, 3);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE1",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE1",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE1",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE1",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE1_CARE));
+ }
+
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2(3);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2_CARE(3);
+
+ if (l_def_ENABLE_PREFETCH_DROP_PROMOTE_BASIC)
+ {
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2.insertFromRight<uint64_t>(literal_0x5, 0, 3);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2_CARE.insertFromRight<uint64_t>(0x7, 0, 3);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE2",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE2",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE2",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE2",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE2_CARE));
+ }
+
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3(3);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3_CARE(3);
+
+ if (l_def_ENABLE_PREFETCH_DROP_PROMOTE_BASIC)
+ {
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3.insertFromRight<uint64_t>(literal_0x7, 0, 3);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3_CARE.insertFromRight<uint64_t>(0x7, 0, 3);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE3",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE3",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE3",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCPERF2_PF_DROP_VALUE3",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3, l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF2_PF_DROP_VALUE3_CARE));
+ }
+
+ uint64_t l_def_ENABLE_MCBUSY = literal_1;
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS(1);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_CARE(1);
+
+ if (l_def_ENABLE_MCBUSY)
+ {
+ constexpr auto l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_ON = 0x1;
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS.insertFromRight<uint64_t>
+ (l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_ON, 0, 1);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_CARE.insertFromRight<uint64_t>(0x1, 0, 1);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCBUSYQ_ENABLE_BUSY_COUNTERS",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCBUSYQ_ENABLE_BUSY_COUNTERS",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCBUSYQ_ENABLE_BUSY_COUNTERS",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCBUSYQ_ENABLE_BUSY_COUNTERS",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_CARE));
+ }
+
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT(3);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_CARE(3);
+
+ if (l_def_ENABLE_MCBUSY)
+ {
+ constexpr auto l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_1024_CYCLES = 0x1;
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT.insertFromRight<uint64_t>
+ (l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_1024_CYCLES, 0, 3);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_CARE.insertFromRight<uint64_t>(0x7, 0, 3);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_CARE));
+ }
+
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0(10);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0_CARE(10);
+
+ if (l_def_ENABLE_MCBUSY)
+ {
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0.insertFromRight<uint64_t>(literal_0x26, 0, 10);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0_CARE.insertFromRight<uint64_t>(0x3ff, 0, 10);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_THRESHOLD0",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_THRESHOLD0",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_THRESHOLD0",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_THRESHOLD0",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD0_CARE));
+ }
+
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1(10);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1_CARE(10);
+
+ if (l_def_ENABLE_MCBUSY)
+ {
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1.insertFromRight<uint64_t>(literal_0x33, 0, 10);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1_CARE.insertFromRight<uint64_t>(0x3ff, 0, 10);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_THRESHOLD1",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_THRESHOLD1",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_THRESHOLD1",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_THRESHOLD1",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD1_CARE));
+ }
+
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2(10);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2_CARE(10);
+
+ if (l_def_ENABLE_MCBUSY)
+ {
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2.insertFromRight<uint64_t>(literal_0x40, 0, 10);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2_CARE.insertFromRight<uint64_t>(0x3ff, 0, 10);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_THRESHOLD2",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_THRESHOLD2",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_THRESHOLD2",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCBUSYQ_BUSY_COUNTER_THRESHOLD2",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_THRESHOLD2_CARE));
+ }
+
+ fapi2::ATTR_ENABLE_MEM_EARLY_DATA_SCOM_Type l_TGT1_ATTR_ENABLE_MEM_EARLY_DATA_SCOM;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_ENABLE_MEM_EARLY_DATA_SCOM, TGT1, l_TGT1_ATTR_ENABLE_MEM_EARLY_DATA_SCOM));
+ bool l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_update = false;
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY(1);
+ fapi2::variable_buffer l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_CARE(1);
+
+ if ((l_TGT1_ATTR_ENABLE_MEM_EARLY_DATA_SCOM == fapi2::ENUM_ATTR_ENABLE_MEM_EARLY_DATA_SCOM_OFF))
+ {
+ constexpr auto l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_ON = 0x1;
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY.insertFromRight<uint64_t>
+ (l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_ON, 0, 1);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_CARE.insertFromRight<uint64_t>(0x1, 0, 1);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_update = true;
+ }
+ else if ((l_TGT1_ATTR_ENABLE_MEM_EARLY_DATA_SCOM == fapi2::ENUM_ATTR_ENABLE_MEM_EARLY_DATA_SCOM_ON))
+ {
+ constexpr auto l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_OFF = 0x0;
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY.insertFromRight<uint64_t>
+ (l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_OFF, 0, 1);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_CARE.insertFromRight<uint64_t>(0x1, 0, 1);
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_update = true;
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN0.ATCL.CL.CLSCOM.MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN1.ATCL.CL.CLSCOM.MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN2.ATCL.CL.CLSCOM.MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_CARE));
+ }
+
+ if ( l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_update)
+ {
+ FAPI_TRY(fapi2::putSpyWithCare(TGT0, "MC01.CHAN3.ATCL.CL.CLSCOM.MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY",
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY,
+ l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_CARE));
+ }
};
fapi_try_exit:
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scan.H b/src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scan.H
index 7ba8bd967..cd0857ff7 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scan.H
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scan.H
@@ -32,15 +32,17 @@
#ifdef IFCOMPILER_PLAT
#define INITFILE_PROCEDURE \
- p9a_mcc_omi_scan(TGT0);
+ p9a_mcc_omi_scan(TGT0, TGT1);
#endif
-typedef fapi2::ReturnCode (*p9a_mcc_omi_scan_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);
+typedef fapi2::ReturnCode (*p9a_mcc_omi_scan_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&,
+ const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>&);
extern "C"
{
- fapi2::ReturnCode p9a_mcc_omi_scan(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT0);
+ fapi2::ReturnCode p9a_mcc_omi_scan(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT0,
+ const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT1);
}
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scom.C
index 7f8143749..aee57fe52 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_mcc_omi_scom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -29,28 +29,14 @@
using namespace fapi2;
-constexpr uint64_t literal_1 = 1;
-constexpr uint64_t literal_24 = 24;
-constexpr uint64_t literal_12 = 12;
-constexpr uint64_t literal_0 = 0;
-constexpr uint64_t literal_0b0100 = 0b0100;
-constexpr uint64_t literal_28 = 28;
-constexpr uint64_t literal_0x1 = 0x1;
-constexpr uint64_t literal_0x3 = 0x3;
-constexpr uint64_t literal_0x5 = 0x5;
-constexpr uint64_t literal_0x7 = 0x7;
-constexpr uint64_t literal_0b1100111111111111111111111 = 0b1100111111111111111111111;
-constexpr uint64_t literal_4 = 4;
-constexpr uint64_t literal_6 = 6;
-constexpr uint64_t literal_0x26 = 0x26;
-constexpr uint64_t literal_0x33 = 0x33;
-constexpr uint64_t literal_0x40 = 0x40;
constexpr uint64_t literal_0b100000 = 0b100000;
constexpr uint64_t literal_0b0001 = 0b0001;
constexpr uint64_t literal_0b1000000 = 0b1000000;
constexpr uint64_t literal_0b011000 = 0b011000;
+constexpr uint64_t literal_1 = 1;
constexpr uint64_t literal_7 = 7;
constexpr uint64_t literal_0b1 = 0b1;
+constexpr uint64_t literal_4 = 4;
constexpr uint64_t literal_6363 = 6363;
constexpr uint64_t literal_10000 = 10000;
constexpr uint64_t literal_4500 = 4500;
@@ -59,8 +45,10 @@ constexpr uint64_t literal_5800 = 5800;
constexpr uint64_t literal_5 = 5;
constexpr uint64_t literal_8181 = 8181;
constexpr uint64_t literal_7000 = 7000;
+constexpr uint64_t literal_6 = 6;
constexpr uint64_t literal_9090 = 9090;
constexpr uint64_t literal_8000 = 8000;
+constexpr uint64_t literal_0 = 0;
constexpr uint64_t literal_0b0000110000 = 0b0000110000;
fapi2::ReturnCode p9a_mcc_omi_scom(const fapi2::Target<fapi2::TARGET_TYPE_MCC>& TGT0,
@@ -71,21 +59,6 @@ fapi2::ReturnCode p9a_mcc_omi_scom(const fapi2::Target<fapi2::TARGET_TYPE_MCC>&
fapi2::ATTR_NAME_Type l_chip_id;
FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, TGT3, l_chip_id));
FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_EC, TGT3, l_chip_ec));
- uint64_t l_def_ENABLE_AMO_CACHING = literal_1;
- uint64_t l_def_ENABLE_AMO_CLEAN_LINES = literal_1;
- uint64_t l_def_ENABLE_PREFETCH_DROP_PROMOTE_BASIC = literal_1;
- fapi2::ATTR_PROC_EPS_READ_CYCLES_T0_Type l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T0;
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_EPS_READ_CYCLES_T0, TGT1, l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T0));
- uint64_t l_def_MC_EPSILON_CFG_T0 = ((l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T0 + literal_6) / literal_4);
- fapi2::ATTR_PROC_EPS_READ_CYCLES_T1_Type l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T1;
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_EPS_READ_CYCLES_T1, TGT1, l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T1));
- uint64_t l_def_MC_EPSILON_CFG_T1 = ((l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T1 + literal_6) / literal_4);
- fapi2::ATTR_PROC_EPS_READ_CYCLES_T2_Type l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T2;
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_EPS_READ_CYCLES_T2, TGT1, l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T2));
- uint64_t l_def_MC_EPSILON_CFG_T2 = ((l_TGT1_ATTR_PROC_EPS_READ_CYCLES_T2 + literal_6) / literal_4);
- uint64_t l_def_ENABLE_MCBUSY = literal_1;
- fapi2::ATTR_ENABLE_MEM_EARLY_DATA_SCOM_Type l_TGT1_ATTR_ENABLE_MEM_EARLY_DATA_SCOM;
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_ENABLE_MEM_EARLY_DATA_SCOM, TGT1, l_TGT1_ATTR_ENABLE_MEM_EARLY_DATA_SCOM));
uint64_t l_def_ENABLE_MCU_TIMEOUTS = literal_1;
fapi2::ATTR_IS_SIMULATION_Type l_TGT1_ATTR_IS_SIMULATION;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, TGT1, l_TGT1_ATTR_IS_SIMULATION));
@@ -99,137 +72,6 @@ fapi2::ReturnCode p9a_mcc_omi_scom(const fapi2::Target<fapi2::TARGET_TYPE_MCC>&
uint64_t l_def_ENABLE_HWFM = literal_1;
fapi2::buffer<uint64_t> l_scom_buffer;
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x5010823ull, l_scom_buffer ));
-
- if (l_def_ENABLE_AMO_CACHING)
- {
- l_scom_buffer.insert<22, 6, 58, uint64_t>(literal_24 );
- }
-
- FAPI_TRY(fapi2::putScom(TGT0, 0x5010823ull, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x5010824ull, l_scom_buffer ));
-
- if ((l_def_ENABLE_AMO_CLEAN_LINES == literal_1))
- {
- l_scom_buffer.insert<44, 6, 58, uint64_t>(literal_12 );
- }
-
- l_scom_buffer.insert<40, 4, 60, uint64_t>(literal_0 );
- l_scom_buffer.insert<28, 4, 60, uint64_t>(literal_0b0100 );
- l_scom_buffer.insert<50, 5, 59, uint64_t>(literal_28 );
-
- if (l_def_ENABLE_PREFETCH_DROP_PROMOTE_BASIC)
- {
- l_scom_buffer.insert<0, 3, 61, uint64_t>(literal_0x1 );
- }
-
- if (l_def_ENABLE_PREFETCH_DROP_PROMOTE_BASIC)
- {
- l_scom_buffer.insert<3, 3, 61, uint64_t>(literal_0x3 );
- }
-
- if (l_def_ENABLE_PREFETCH_DROP_PROMOTE_BASIC)
- {
- l_scom_buffer.insert<6, 3, 61, uint64_t>(literal_0x5 );
- }
-
- if (l_def_ENABLE_PREFETCH_DROP_PROMOTE_BASIC)
- {
- l_scom_buffer.insert<9, 3, 61, uint64_t>(literal_0x7 );
- }
-
- FAPI_TRY(fapi2::putScom(TGT0, 0x5010824ull, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x5010825ull, l_scom_buffer ));
-
- if ((l_def_ENABLE_AMO_CLEAN_LINES == literal_1))
- {
- constexpr auto l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_ON = 0x1;
- l_scom_buffer.insert<0, 1, 63, uint64_t>(l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_ENABLE_CLEAN_ON );
- }
-
- if (l_def_ENABLE_AMO_CACHING)
- {
- l_scom_buffer.insert<4, 25, 39, uint64_t>(literal_0b1100111111111111111111111 );
- }
-
- if (l_def_ENABLE_AMO_CACHING)
- {
- constexpr auto l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_128B_RW_64B_DATA = 0x1;
- l_scom_buffer.insert<29, 3, 61, uint64_t>(l_MC01_CHAN0_ATCL_CL_CLSCOM_MCAMOC_AMO_SIZE_SELECT_128B_RW_64B_DATA );
- }
-
- FAPI_TRY(fapi2::putScom(TGT0, 0x5010825ull, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x5010826ull, l_scom_buffer ));
-
- l_scom_buffer.insert<0, 8, 56, uint64_t>(literal_0x1 );
- l_scom_buffer.insert<8, 8, 56, uint64_t>(l_def_MC_EPSILON_CFG_T0 );
- l_scom_buffer.insert<16, 8, 56, uint64_t>(l_def_MC_EPSILON_CFG_T1 );
- l_scom_buffer.insert<24, 8, 56, uint64_t>(l_def_MC_EPSILON_CFG_T1 );
- l_scom_buffer.insert<32, 8, 56, uint64_t>(l_def_MC_EPSILON_CFG_T2 );
- l_scom_buffer.insert<40, 8, 56, uint64_t>(l_def_MC_EPSILON_CFG_T2 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x5010826ull, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x5010827ull, l_scom_buffer ));
-
- if (l_def_ENABLE_MCBUSY)
- {
- constexpr auto l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_ON = 0x1;
- l_scom_buffer.insert<0, 1, 63, uint64_t>(l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_ENABLE_BUSY_COUNTERS_ON );
- }
-
- if (l_def_ENABLE_MCBUSY)
- {
- constexpr auto l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_1024_CYCLES = 0x1;
- l_scom_buffer.insert<1, 3, 61, uint64_t>(l_MC01_CHAN0_ATCL_CL_CLSCOM_MCBUSYQ_BUSY_COUNTER_WINDOW_SELECT_1024_CYCLES );
- }
-
- if (l_def_ENABLE_MCBUSY)
- {
- l_scom_buffer.insert<4, 10, 54, uint64_t>(literal_0x26 );
- }
-
- if (l_def_ENABLE_MCBUSY)
- {
- l_scom_buffer.insert<14, 10, 54, uint64_t>(literal_0x33 );
- }
-
- if (l_def_ENABLE_MCBUSY)
- {
- l_scom_buffer.insert<24, 10, 54, uint64_t>(literal_0x40 );
- }
-
- FAPI_TRY(fapi2::putScom(TGT0, 0x5010827ull, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x501082bull, l_scom_buffer ));
-
- if (l_def_ENABLE_AMO_CACHING)
- {
- constexpr auto l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_ON = 0x1;
- l_scom_buffer.insert<45, 1, 63, uint64_t>(l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_AMO_LIMIT_SEL_ON );
- }
-
- if ((l_TGT1_ATTR_ENABLE_MEM_EARLY_DATA_SCOM == fapi2::ENUM_ATTR_ENABLE_MEM_EARLY_DATA_SCOM_OFF))
- {
- constexpr auto l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_ON = 0x1;
- l_scom_buffer.insert<43, 1, 63, uint64_t>(l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_ON );
- }
- else if ((l_TGT1_ATTR_ENABLE_MEM_EARLY_DATA_SCOM == fapi2::ENUM_ATTR_ENABLE_MEM_EARLY_DATA_SCOM_ON))
- {
- constexpr auto l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_OFF = 0x0;
- l_scom_buffer.insert<43, 1, 63, uint64_t>(l_MC01_CHAN0_ATCL_CL_CLSCOM_MCPERF3_ENABLE_CP_M_MDI0_LOCAL_ONLY_OFF );
- }
-
- FAPI_TRY(fapi2::putScom(TGT0, 0x501082bull, l_scom_buffer));
- }
- {
FAPI_TRY(fapi2::getScom( TGT0, 0x701090aull, l_scom_buffer ));
l_scom_buffer.insert<2, 6, 58, uint64_t>(literal_0b100000 );
@@ -307,17 +149,6 @@ fapi2::ReturnCode p9a_mcc_omi_scom(const fapi2::Target<fapi2::TARGET_TYPE_MCC>&
l_scom_buffer.insert<48, 10, 54, uint64_t>(literal_0b0000110000 );
FAPI_TRY(fapi2::putScom(TGT0, 0x7010a13ull, l_scom_buffer));
}
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x7012348ull, l_scom_buffer ));
-
- if (l_def_ENABLE_AMO_CACHING)
- {
- constexpr auto l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_ON = 0x1;
- l_scom_buffer.insert<9, 1, 63, uint64_t>(l_MCP_CHAN0_WRITE_NEW_WRITE_64B_MODE_ON );
- }
-
- FAPI_TRY(fapi2::putScom(TGT0, 0x7012348ull, l_scom_buffer));
- }
};
fapi_try_exit:
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_mi_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9a_mi_scom.C
index 20b65bd74..fafc20414 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9a_mi_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_mi_scom.C
@@ -32,6 +32,8 @@ using namespace fapi2;
constexpr uint64_t literal_7 = 7;
constexpr uint64_t literal_1 = 1;
constexpr uint64_t literal_0x19 = 0x19;
+constexpr uint64_t literal_0b1111000000 = 0b1111000000;
+constexpr uint64_t literal_0b0111111 = 0b0111111;
constexpr uint64_t literal_0b0000000000001000 = 0b0000000000001000;
constexpr uint64_t literal_0b011 = 0b011;
constexpr uint64_t literal_0b01 = 0b01;
@@ -43,6 +45,8 @@ fapi2::ReturnCode p9a_mi_scom(const fapi2::Target<fapi2::TARGET_TYPE_MI>& TGT0,
uint64_t l_def_ENABLE_PREFETCH_DROP_PROMOTE_BASIC = literal_1;
fapi2::ATTR_ENABLE_MEM_EARLY_DATA_SCOM_Type l_TGT1_ATTR_ENABLE_MEM_EARLY_DATA_SCOM;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_ENABLE_MEM_EARLY_DATA_SCOM, TGT1, l_TGT1_ATTR_ENABLE_MEM_EARLY_DATA_SCOM));
+ fapi2::ATTR_MEM_MIRROR_PLACEMENT_POLICY_Type l_TGT1_ATTR_MEM_MIRROR_PLACEMENT_POLICY;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEM_MIRROR_PLACEMENT_POLICY, TGT1, l_TGT1_ATTR_MEM_MIRROR_PLACEMENT_POLICY));
uint64_t l_def_ENABLE_AMO_CACHING = literal_1;
uint64_t l_def_ENABLE_MCU_TIMEOUTS = literal_1;
fapi2::buffer<uint64_t> l_scom_buffer;
@@ -91,6 +95,22 @@ fapi2::ReturnCode p9a_mi_scom(const fapi2::Target<fapi2::TARGET_TYPE_MI>& TGT0,
l_scom_buffer.insert<4, 1, 63, uint64_t>(l_MC01_PBI01_SCOMFIR_MCMODE0_ENABLE_ECRESP_ON );
}
+ l_scom_buffer.insert<15, 10, 54, uint64_t>(literal_0b1111000000 );
+ l_scom_buffer.insert<25, 7, 57, uint64_t>(literal_0b0111111 );
+ constexpr auto l_MC01_PBI01_SCOMFIR_MCMODE0_FORCE_COMMANDLIST_VALID_ON = 0x1;
+ l_scom_buffer.insert<5, 1, 63, uint64_t>(l_MC01_PBI01_SCOMFIR_MCMODE0_FORCE_COMMANDLIST_VALID_ON );
+
+ if ((l_TGT1_ATTR_MEM_MIRROR_PLACEMENT_POLICY == fapi2::ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_FLIPPED))
+ {
+ constexpr auto l_MC01_PBI01_SCOMFIR_MCMODE0_MEM_MAP_MODE_ON = 0x1;
+ l_scom_buffer.insert<36, 1, 63, uint64_t>(l_MC01_PBI01_SCOMFIR_MCMODE0_MEM_MAP_MODE_ON );
+ }
+ else if ((l_TGT1_ATTR_MEM_MIRROR_PLACEMENT_POLICY == fapi2::ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL))
+ {
+ constexpr auto l_MC01_PBI01_SCOMFIR_MCMODE0_MEM_MAP_MODE_OFF = 0x0;
+ l_scom_buffer.insert<36, 1, 63, uint64_t>(l_MC01_PBI01_SCOMFIR_MCMODE0_MEM_MAP_MODE_OFF );
+ }
+
FAPI_TRY(fapi2::putScom(TGT0, 0x5010811ull, l_scom_buffer));
}
{
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_init_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_init_scom.C
index 3801b25b9..68c8df463 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_init_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_init_scom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,6 +40,8 @@ fapi2::ReturnCode p9a_omi_init_scom(const fapi2::Target<fapi2::TARGET_TYPE_MCC>&
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_ENABLE_DL_TMPL_7, TGT0, l_TGT0_ATTR_PROC_ENABLE_DL_TMPL_7));
fapi2::ATTR_PROC_ENABLE_DL_TMPL_4_Type l_TGT0_ATTR_PROC_ENABLE_DL_TMPL_4;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_ENABLE_DL_TMPL_4, TGT0, l_TGT0_ATTR_PROC_ENABLE_DL_TMPL_4));
+ fapi2::ATTR_PROC_ENABLE_DL_TMPL_1_Type l_TGT0_ATTR_PROC_ENABLE_DL_TMPL_1;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_ENABLE_DL_TMPL_1, TGT0, l_TGT0_ATTR_PROC_ENABLE_DL_TMPL_1));
fapi2::ATTR_PROC_TMPL_0_PACING_Type l_TGT0_ATTR_PROC_TMPL_0_PACING;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_TMPL_0_PACING, TGT0, l_TGT0_ATTR_PROC_TMPL_0_PACING));
fapi2::ATTR_PROC_TMPL_1_PACING_Type l_TGT0_ATTR_PROC_TMPL_1_PACING;
@@ -64,6 +66,12 @@ fapi2::ReturnCode p9a_omi_init_scom(const fapi2::Target<fapi2::TARGET_TYPE_MCC>&
l_scom_buffer.insert<6, 1, 63, uint64_t>(l_MCP_CHAN0_DSTL_DSTLCFG_TMPL4_DISABLE_ON );
}
+ if ((l_TGT0_ATTR_PROC_ENABLE_DL_TMPL_1 == fapi2::ENUM_ATTR_PROC_ENABLE_DL_TMPL_1_DISABLED))
+ {
+ constexpr auto l_MCP_CHAN0_DSTL_DSTLCFG_TMPL1_DIS_ON = 0x1;
+ l_scom_buffer.insert<3, 1, 63, uint64_t>(l_MCP_CHAN0_DSTL_DSTLCFG_TMPL1_DIS_ON );
+ }
+
FAPI_TRY(fapi2::putScom(TGT0, 0x701090bull, l_scom_buffer));
}
{
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_io_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_io_scom.C
index 67b67cd85..94a44a309 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_io_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_io_scom.C
@@ -36,23 +36,8 @@ constexpr uint64_t literal_0b10000 = 0b10000;
constexpr uint64_t literal_0b1011 = 0b1011;
constexpr uint64_t literal_0b1010 = 0b1010;
constexpr uint64_t literal_0b1100 = 0b1100;
-constexpr uint64_t literal_0b000000 = 0b000000;
-constexpr uint64_t literal_0x0 = 0x0;
-constexpr uint64_t literal_0b010 = 0b010;
-constexpr uint64_t literal_0b001 = 0b001;
-constexpr uint64_t literal_0b0010 = 0b0010;
-constexpr uint64_t literal_0b0001 = 0b0001;
-constexpr uint64_t literal_0b101 = 0b101;
-constexpr uint64_t literal_0b100 = 0b100;
-constexpr uint64_t literal_0b0000 = 0b0000;
-constexpr uint64_t literal_0b110 = 0b110;
-constexpr uint64_t literal_0b00 = 0b00;
-constexpr uint64_t literal_0b01110 = 0b01110;
-constexpr uint64_t literal_0b0010101 = 0b0010101;
-constexpr uint64_t literal_0b0010110 = 0b0010110;
-constexpr uint64_t literal_0b1000110 = 0b1000110;
-
-fapi2::ReturnCode p9a_omi_io_scom(const fapi2::Target<fapi2::TARGET_TYPE_OMIC>& TGT0,
+
+fapi2::ReturnCode p9a_omi_io_scom(const fapi2::Target<fapi2::TARGET_TYPE_OMI>& TGT0,
const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT1, const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT2)
{
{
@@ -66,2172 +51,652 @@ fapi2::ReturnCode p9a_omi_io_scom(const fapi2::Target<fapi2::TARGET_TYPE_OMIC>&
uint64_t l_def_IS_SIM = (l_TGT1_ATTR_IS_SIMULATION == literal_1);
fapi2::buffer<uint64_t> l_scom_buffer;
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000000701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000010701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000010701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000020701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000020701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000030701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000030701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000040701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000040701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000050701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000050701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000060701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000060701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000070701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000070701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000080701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000080701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000090701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000090701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000000a0701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000000a0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000000b0701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_2_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000000b0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000000c0701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000000c0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000000d0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800000000701183full, l_scom_buffer ));
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
if (l_def_IS_HW)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
}
else if (l_def_IS_SIM)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
}
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000000d0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800000000701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000000e0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800000010701183full, l_scom_buffer ));
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
if (l_def_IS_HW)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
}
else if (l_def_IS_SIM)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
}
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000000e0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800000010701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000000f0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800000020701183full, l_scom_buffer ));
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
if (l_def_IS_HW)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
}
else if (l_def_IS_SIM)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_3_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
}
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000000f0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800000020701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000100701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800000030701183full, l_scom_buffer ));
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
if (l_def_IS_HW)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
}
else if (l_def_IS_SIM)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
}
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000100701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800000030701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000110701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800000040701183full, l_scom_buffer ));
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_4_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_4_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_4_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_4_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
if (l_def_IS_HW)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_4_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_4_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
}
else if (l_def_IS_SIM)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_4_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_4_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
}
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000110701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800000040701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000120701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800000050701183full, l_scom_buffer ));
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_5_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_5_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_5_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_5_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
if (l_def_IS_HW)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_5_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_5_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
}
else if (l_def_IS_SIM)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_5_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_0_RXPACK_RD_SLICE_5_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
}
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000120701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800000050701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000130701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800000060701183full, l_scom_buffer ));
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
if (l_def_IS_HW)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
}
else if (l_def_IS_SIM)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_4_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
}
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000130701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800000060701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000140701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800000070701183full, l_scom_buffer ));
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
if (l_def_IS_HW)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
}
else if (l_def_IS_SIM)
{
constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
+ l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_0_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
+ (l_MCP_OMI2_IOO_CPLT_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
}
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000140701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800000070701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000150701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000150701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000160701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_2_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000160701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800000170701103full, l_scom_buffer ));
-
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF = 0x0;
- l_scom_buffer.insert<53, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF );
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF );
-
- if (l_def_IS_HW)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF = 0x0;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF );
- }
- else if (l_def_IS_SIM)
- {
- constexpr auto
- l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON = 0x1;
- l_scom_buffer.insert<55, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXPACKS_5_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_ON );
- }
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800000170701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028000701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028010701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028010701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028020701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028020701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028030701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028030701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028040701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028040701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028050701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028050701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028060701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028060701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028070701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028070701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028080701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028080701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028090701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028090701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000280a0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000280a0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000280b0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000280b0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000280c0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800028000701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000280c0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800028000701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000280d0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800028010701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000280d0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800028010701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000280e0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800028020701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000280e0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800028020701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000280f0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800028030701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000280f0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800028030701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028100701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800028040701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028100701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800028040701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028110701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800028050701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028110701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800028050701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028120701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800028060701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028120701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800028060701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028130701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800028070701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028130701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028140701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028140701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028150701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028150701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028160701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028160701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800028170701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800028170701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030000701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030010701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030010701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030020701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030020701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030030701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030030701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030040701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030040701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030050701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030050701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030060701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030060701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030070701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030070701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800028070701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030080701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800030000701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030080701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800030000701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030090701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800030010701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030090701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800030010701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000300a0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800030020701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000300a0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800030020701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000300b0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800030030701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000300b0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800030030701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000300c0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800030040701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000300c0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800030040701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000300d0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800030050701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000300d0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800030050701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000300e0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800030060701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000300e0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800030060701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000300f0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800030070701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000300f0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030100701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030100701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030110701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030110701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030120701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030120701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030130701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030130701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030140701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030140701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030150701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030150701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030160701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030160701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800030170701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800030170701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098000701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098010701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098010701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098020701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098020701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098030701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098030701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800030070701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098040701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800098000701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098040701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800098000701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098050701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800098010701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098050701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800098010701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098060701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800098020701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098060701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800098020701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098070701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800098030701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098070701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800098030701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098080701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800098040701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098080701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800098040701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098090701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800098050701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098090701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800098050701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000980a0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800098060701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000980a0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800098060701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000980b0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800098070701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000980b0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800098070701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000980c0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000980c0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000980d0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000980d0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000980e0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000980e0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000980f0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000980f0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098100701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098100701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098110701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098110701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098120701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098120701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098130701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098130701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098140701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098140701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098150701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098150701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098160701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098160701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800098170701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800098170701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0000701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0010701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0010701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0020701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0020701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0030701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0030701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0040701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0040701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0050701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0050701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0060701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0060701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0070701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0070701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0080701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0080701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0090701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0090701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a00a0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a00a0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a00b0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a00b0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a00c0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a00c0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a00d0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a00d0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a00e0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a00e0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a00f0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0000701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a00f0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0000701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0100701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0010701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0100701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0010701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0110701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0020701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0110701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0020701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0120701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0030701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0120701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0030701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0130701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0040701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0130701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0040701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0140701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0050701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0140701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0050701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0150701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0060701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0150701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0060701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0160701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0070701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0160701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000a0170701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0170701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0000701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0010701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0010701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0020701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0020701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0030701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0030701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0040701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0040701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0050701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0050701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0060701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0060701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0070701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0070701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0080701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0080701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0090701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0090701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000a0070701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c00a0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0000701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c00a0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0000701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c00b0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0010701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c00b0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0010701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c00c0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0020701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c00c0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0020701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c00d0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0030701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c00d0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0030701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c00e0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0040701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c00e0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0040701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c00f0701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0050701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c00f0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0050701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0100701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0060701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0100701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0060701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0110701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0070701183full, l_scom_buffer ));
l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0110701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0120701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0120701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0130701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0130701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0140701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0140701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0150701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0150701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0160701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0160701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c0170701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<52, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<57, 5, 59, uint64_t>(literal_0b10000 );
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b1011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0170701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8000701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8010701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8010701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8020701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8020701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8030701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8030701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8040701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8040701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8050701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8050701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8060701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8060701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8070701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8070701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8080701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8080701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8090701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8090701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c80a0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c80a0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c80b0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c80b0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c80c0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c80c0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c80d0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c80d0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c80e0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c80e0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c80f0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c80f0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c0070701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8100701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8000701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8100701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8000701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8110701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8010701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8110701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8010701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8120701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8020701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8120701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8020701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8130701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8030701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8130701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8030701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8140701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8040701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8140701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8040701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8150701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8050701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8150701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8050701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8160701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8060701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8160701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8060701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8170701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x8000c8070701183full, l_scom_buffer ));
l_scom_buffer.insert<53, 4, 60, uint64_t>(literal_0b1010 );
l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b0011 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8170701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228000701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228010701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228010701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228020701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228020701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228030701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228030701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228040701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228040701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228050701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228050701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228060701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228060701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228070701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228070701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228080701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228080701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228090701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228090701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8002280a0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8002280a0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8002280b0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8002280b0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8002280c0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8002280c0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8002280d0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8002280d0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8002280e0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8002280e0701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x8002280f0701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x8002280f0701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x8000c8070701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228100701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800228000701183full, l_scom_buffer ));
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228100701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800228000701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228110701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800228010701183full, l_scom_buffer ));
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228110701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800228010701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228120701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800228020701183full, l_scom_buffer ));
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228120701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800228020701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228130701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800228030701183full, l_scom_buffer ));
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228130701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800228030701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228140701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800228040701183full, l_scom_buffer ));
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228140701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800228040701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228150701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800228050701183full, l_scom_buffer ));
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228150701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800228050701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228160701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800228060701183full, l_scom_buffer ));
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228160701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800228060701183full, l_scom_buffer));
}
{
- FAPI_TRY(fapi2::getScom( TGT0, 0x800228170701103full, l_scom_buffer ));
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800228070701183full, l_scom_buffer ));
l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b1100 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800228170701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800800000701103full, l_scom_buffer ));
-
- constexpr auto l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_PG_SPARE_MODE_4_OFF = 0x0;
- l_scom_buffer.insert<52, 1, 63, uint64_t>(l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_PG_SPARE_MODE_4_OFF );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800800000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800808000701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<48, 6, 58, uint64_t>(literal_0b000000 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800808000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800818000701103full, l_scom_buffer ));
-
- constexpr auto l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RECAL_REQ_DL_MASK_OFF = 0x0;
- l_scom_buffer.insert<54, 1, 63, uint64_t>(l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RECAL_REQ_DL_MASK_OFF );
- constexpr auto l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RECAL_ABORT_DL_MASK_OFF = 0x0;
- l_scom_buffer.insert<57, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RECAL_ABORT_DL_MASK_OFF );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800818000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800830000701103full, l_scom_buffer ));
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<56, 4, 60, uint64_t>(literal_0x0 );
- }
-
- FAPI_TRY(fapi2::putScom(TGT0, 0x800830000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800840000701103full, l_scom_buffer ));
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0x0 );
- }
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<52, 4, 60, uint64_t>(literal_0x0 );
- }
-
- FAPI_TRY(fapi2::putScom(TGT0, 0x800840000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800858000701103full, l_scom_buffer ));
-
- if (l_def_IS_HW)
- {
- l_scom_buffer.insert<48, 3, 61, uint64_t>(literal_0b010 );
- }
- else if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<48, 3, 61, uint64_t>(literal_0b001 );
- }
-
- if (l_def_IS_HW)
- {
- l_scom_buffer.insert<51, 3, 61, uint64_t>(literal_0b010 );
- }
- else if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<51, 3, 61, uint64_t>(literal_0b001 );
- }
-
- if (l_def_IS_HW)
- {
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0010 );
- }
- else if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0001 );
- }
-
- l_scom_buffer.insert<54, 3, 61, uint64_t>(literal_0b101 );
- l_scom_buffer.insert<57, 3, 61, uint64_t>(literal_0b101 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800858000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800860000701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<48, 3, 61, uint64_t>(literal_0b010 );
- l_scom_buffer.insert<51, 3, 61, uint64_t>(literal_0b010 );
- l_scom_buffer.insert<54, 3, 61, uint64_t>(literal_0b010 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800860000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800868000701103full, l_scom_buffer ));
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0x0 );
- }
-
- if (l_def_IS_HW)
- {
- l_scom_buffer.insert<60, 3, 61, uint64_t>(literal_0b100 );
- }
- else if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<60, 3, 61, uint64_t>(literal_0b010 );
- }
-
- FAPI_TRY(fapi2::putScom(TGT0, 0x800868000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800878000701103full, l_scom_buffer ));
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<56, 4, 60, uint64_t>(literal_0x0 );
- }
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0x0 );
- }
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b0000 );
- }
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<52, 4, 60, uint64_t>(literal_0b0000 );
- }
-
- FAPI_TRY(fapi2::putScom(TGT0, 0x800878000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800880000701103full, l_scom_buffer ));
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0x0 );
- }
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<56, 4, 60, uint64_t>(literal_0x0 );
- }
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b0000 );
- }
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<52, 4, 60, uint64_t>(literal_0b0000 );
- }
-
- FAPI_TRY(fapi2::putScom(TGT0, 0x800880000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800888000701103full, l_scom_buffer ));
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0x0 );
- }
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<56, 4, 60, uint64_t>(literal_0x0 );
- }
-
- if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<52, 4, 60, uint64_t>(literal_0x0 );
- }
-
- FAPI_TRY(fapi2::putScom(TGT0, 0x800888000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800970000701103full, l_scom_buffer ));
-
- constexpr auto l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RC_ENABLE_CTLE_1ST_LATCH_OFFSET_CAL_ON = 0x1;
- l_scom_buffer.insert<48, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RC_ENABLE_CTLE_1ST_LATCH_OFFSET_CAL_ON );
- constexpr auto l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RC_ENABLE_AUTO_RECAL_OFF = 0x0;
- l_scom_buffer.insert<51, 1, 63, uint64_t>
- (l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RC_ENABLE_AUTO_RECAL_OFF );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800970000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800988000701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<48, 3, 61, uint64_t>(literal_0b110 );
- l_scom_buffer.insert<51, 2, 62, uint64_t>(literal_0b00 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800988000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800c0c000701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<48, 6, 58, uint64_t>(literal_0b000000 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800c0c000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800f1c000701103full, l_scom_buffer ));
-
- l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b01110 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800f1c000701103full, l_scom_buffer));
- }
- {
- FAPI_TRY(fapi2::getScom( TGT0, 0x800f2c000701103full, l_scom_buffer ));
-
- if (l_def_IS_HW)
- {
- l_scom_buffer.insert<48, 7, 57, uint64_t>(literal_0b0010101 );
- }
- else if (l_def_IS_SIM)
- {
- l_scom_buffer.insert<48, 7, 57, uint64_t>(literal_0b0010110 );
- }
-
- l_scom_buffer.insert<55, 7, 57, uint64_t>(literal_0b1000110 );
- FAPI_TRY(fapi2::putScom(TGT0, 0x800f2c000701103full, l_scom_buffer));
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800228070701183full, l_scom_buffer));
}
};
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_io_scom.H b/src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_io_scom.H
index 447304e4f..1bfe9e07a 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_io_scom.H
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_omi_io_scom.H
@@ -31,13 +31,13 @@
#include <fapi2.H>
-typedef fapi2::ReturnCode (*p9a_omi_io_scom_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_OMIC>&,
+typedef fapi2::ReturnCode (*p9a_omi_io_scom_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_OMI>&,
const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>&, const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);
extern "C"
{
- fapi2::ReturnCode p9a_omi_io_scom(const fapi2::Target<fapi2::TARGET_TYPE_OMIC>& TGT0,
+ fapi2::ReturnCode p9a_omi_io_scom(const fapi2::Target<fapi2::TARGET_TYPE_OMI>& TGT0,
const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT1, const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT2);
}
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_omic_io_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9a_omic_io_scom.C
new file mode 100644
index 000000000..6cf208fa3
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_omic_io_scom.C
@@ -0,0 +1,299 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/initfiles/p9a_omic_io_scom.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include "p9a_omic_io_scom.H"
+#include <stdint.h>
+#include <stddef.h>
+#include <fapi2.H>
+
+using namespace fapi2;
+
+constexpr uint64_t literal_0b000000 = 0b000000;
+constexpr uint64_t literal_1 = 1;
+constexpr uint64_t literal_0x0 = 0x0;
+constexpr uint64_t literal_0 = 0;
+constexpr uint64_t literal_0b010 = 0b010;
+constexpr uint64_t literal_0b001 = 0b001;
+constexpr uint64_t literal_0b0010 = 0b0010;
+constexpr uint64_t literal_0b0001 = 0b0001;
+constexpr uint64_t literal_0b101 = 0b101;
+constexpr uint64_t literal_0b100 = 0b100;
+constexpr uint64_t literal_0b0000 = 0b0000;
+constexpr uint64_t literal_0b110 = 0b110;
+constexpr uint64_t literal_0b00 = 0b00;
+constexpr uint64_t literal_0b01110 = 0b01110;
+constexpr uint64_t literal_0b0010101 = 0b0010101;
+constexpr uint64_t literal_0b0010110 = 0b0010110;
+constexpr uint64_t literal_0b1000110 = 0b1000110;
+
+fapi2::ReturnCode p9a_omic_io_scom(const fapi2::Target<fapi2::TARGET_TYPE_OMIC>& TGT0,
+ const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT1, const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT2)
+{
+ {
+ fapi2::ATTR_EC_Type l_chip_ec;
+ fapi2::ATTR_NAME_Type l_chip_id;
+ FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, TGT2, l_chip_id));
+ FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_EC, TGT2, l_chip_ec));
+ fapi2::ATTR_IS_SIMULATION_Type l_TGT1_ATTR_IS_SIMULATION;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, TGT1, l_TGT1_ATTR_IS_SIMULATION));
+ uint64_t l_def_IS_SIM = (l_TGT1_ATTR_IS_SIMULATION == literal_1);
+ uint64_t l_def_IS_HW = (l_TGT1_ATTR_IS_SIMULATION == literal_0);
+ fapi2::buffer<uint64_t> l_scom_buffer;
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800800000701103full, l_scom_buffer ));
+
+ constexpr auto l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_PG_SPARE_MODE_4_OFF = 0x0;
+ l_scom_buffer.insert<52, 1, 63, uint64_t>(l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_PG_SPARE_MODE_4_OFF );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800800000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800808000701103full, l_scom_buffer ));
+
+ l_scom_buffer.insert<48, 6, 58, uint64_t>(literal_0b000000 );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800808000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800818000701103full, l_scom_buffer ));
+
+ constexpr auto l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RECAL_REQ_DL_MASK_OFF = 0x0;
+ l_scom_buffer.insert<54, 1, 63, uint64_t>(l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RECAL_REQ_DL_MASK_OFF );
+ constexpr auto l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RECAL_ABORT_DL_MASK_OFF = 0x0;
+ l_scom_buffer.insert<57, 1, 63, uint64_t>
+ (l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RECAL_ABORT_DL_MASK_OFF );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800818000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800830000701103full, l_scom_buffer ));
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<56, 4, 60, uint64_t>(literal_0x0 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800830000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800840000701103full, l_scom_buffer ));
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0x0 );
+ }
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<52, 4, 60, uint64_t>(literal_0x0 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800840000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800858000701103full, l_scom_buffer ));
+
+ if (l_def_IS_HW)
+ {
+ l_scom_buffer.insert<48, 3, 61, uint64_t>(literal_0b010 );
+ }
+ else if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<48, 3, 61, uint64_t>(literal_0b001 );
+ }
+
+ if (l_def_IS_HW)
+ {
+ l_scom_buffer.insert<51, 3, 61, uint64_t>(literal_0b010 );
+ }
+ else if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<51, 3, 61, uint64_t>(literal_0b001 );
+ }
+
+ if (l_def_IS_HW)
+ {
+ l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0010 );
+ }
+ else if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0b0001 );
+ }
+
+ l_scom_buffer.insert<54, 3, 61, uint64_t>(literal_0b101 );
+ l_scom_buffer.insert<57, 3, 61, uint64_t>(literal_0b101 );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800858000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800860000701103full, l_scom_buffer ));
+
+ l_scom_buffer.insert<48, 3, 61, uint64_t>(literal_0b010 );
+ l_scom_buffer.insert<51, 3, 61, uint64_t>(literal_0b010 );
+ l_scom_buffer.insert<54, 3, 61, uint64_t>(literal_0b010 );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800860000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800868000701103full, l_scom_buffer ));
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0x0 );
+ }
+
+ if (l_def_IS_HW)
+ {
+ l_scom_buffer.insert<60, 3, 61, uint64_t>(literal_0b100 );
+ }
+ else if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<60, 3, 61, uint64_t>(literal_0b010 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800868000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800878000701103full, l_scom_buffer ));
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<56, 4, 60, uint64_t>(literal_0x0 );
+ }
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0x0 );
+ }
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b0000 );
+ }
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<52, 4, 60, uint64_t>(literal_0b0000 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800878000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800880000701103full, l_scom_buffer ));
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<60, 4, 60, uint64_t>(literal_0x0 );
+ }
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<56, 4, 60, uint64_t>(literal_0x0 );
+ }
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b0000 );
+ }
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<52, 4, 60, uint64_t>(literal_0b0000 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800880000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800888000701103full, l_scom_buffer ));
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0x0 );
+ }
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<56, 4, 60, uint64_t>(literal_0x0 );
+ }
+
+ if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<52, 4, 60, uint64_t>(literal_0x0 );
+ }
+
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800888000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800970000701103full, l_scom_buffer ));
+
+ constexpr auto l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RC_ENABLE_CTLE_1ST_LATCH_OFFSET_CAL_ON = 0x1;
+ l_scom_buffer.insert<48, 1, 63, uint64_t>
+ (l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RC_ENABLE_CTLE_1ST_LATCH_OFFSET_CAL_ON );
+ constexpr auto l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RC_ENABLE_AUTO_RECAL_OFF = 0x0;
+ l_scom_buffer.insert<51, 1, 63, uint64_t>
+ (l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RC_ENABLE_AUTO_RECAL_OFF );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800970000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800978000701103full, l_scom_buffer ));
+
+ constexpr auto l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_DC_ENABLE_CM_COARSE_CAL_OFF = 0x0;
+ l_scom_buffer.insert<48, 1, 63, uint64_t>
+ (l_MCP_OMI0_IOO_CPLT_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_DC_ENABLE_CM_COARSE_CAL_OFF );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800978000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800988000701103full, l_scom_buffer ));
+
+ l_scom_buffer.insert<48, 3, 61, uint64_t>(literal_0b110 );
+ l_scom_buffer.insert<51, 2, 62, uint64_t>(literal_0b00 );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800988000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800c0c000701103full, l_scom_buffer ));
+
+ l_scom_buffer.insert<48, 6, 58, uint64_t>(literal_0b000000 );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800c0c000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800f1c000701103full, l_scom_buffer ));
+
+ l_scom_buffer.insert<48, 5, 59, uint64_t>(literal_0b01110 );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800f1c000701103full, l_scom_buffer));
+ }
+ {
+ FAPI_TRY(fapi2::getScom( TGT0, 0x800f2c000701103full, l_scom_buffer ));
+
+ if (l_def_IS_HW)
+ {
+ l_scom_buffer.insert<48, 7, 57, uint64_t>(literal_0b0010101 );
+ }
+ else if (l_def_IS_SIM)
+ {
+ l_scom_buffer.insert<48, 7, 57, uint64_t>(literal_0b0010110 );
+ }
+
+ l_scom_buffer.insert<55, 7, 57, uint64_t>(literal_0b1000110 );
+ FAPI_TRY(fapi2::putScom(TGT0, 0x800f2c000701103full, l_scom_buffer));
+ }
+
+ };
+fapi_try_exit:
+ return fapi2::current_err;
+}
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9a_omic_io_scom.H b/src/import/chips/p9/procedures/hwp/initfiles/p9a_omic_io_scom.H
new file mode 100644
index 000000000..a4d94c54e
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9a_omic_io_scom.H
@@ -0,0 +1,45 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/initfiles/p9a_omic_io_scom.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef _INIT_P9A_OMIC_IO_SCOM_PROCEDURE_H_
+#define _INIT_P9A_OMIC_IO_SCOM_PROCEDURE_H_
+
+
+#include <stddef.h>
+#include <stdint.h>
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9a_omic_io_scom_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_OMIC>&,
+ const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>&, const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);
+
+extern "C"
+{
+
+ fapi2::ReturnCode p9a_omic_io_scom(const fapi2::Target<fapi2::TARGET_TYPE_OMIC>& TGT0,
+ const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT1, const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT2);
+
+}
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9n_mca_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9n_mca_scom.C
index ce08da173..d770b6998 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9n_mca_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9n_mca_scom.C
@@ -59,8 +59,8 @@ constexpr uint64_t literal_17 = 17;
constexpr uint64_t literal_1867 = 1867;
constexpr uint64_t literal_2134 = 2134;
constexpr uint64_t literal_2401 = 2401;
-constexpr uint64_t literal_2666 = 2666;
constexpr uint64_t literal_9 = 9;
+constexpr uint64_t literal_2666 = 2666;
constexpr uint64_t literal_10 = 10;
constexpr uint64_t literal_11 = 11;
constexpr uint64_t literal_24 = 24;
@@ -144,7 +144,15 @@ fapi2::ReturnCode p9n_mca_scom(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& TGT0
fapi2::ATTR_EFF_DRAM_CL_Type l_TGT2_ATTR_EFF_DRAM_CL;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_EFF_DRAM_CL, TGT2, l_TGT2_ATTR_EFF_DRAM_CL));
uint64_t l_def_MSS_FREQ_EQ_2133 = ((l_TGT1_ATTR_MSS_FREQ >= literal_1867) && (l_TGT1_ATTR_MSS_FREQ < literal_2134));
+ fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE_Type l_TGT2_ATTR_EFF_HYBRID_MEMORY_TYPE;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE, TGT2, l_TGT2_ATTR_EFF_HYBRID_MEMORY_TYPE));
+ fapi2::ATTR_EFF_HYBRID_Type l_TGT2_ATTR_EFF_HYBRID;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_EFF_HYBRID, TGT2, l_TGT2_ATTR_EFF_HYBRID));
+ uint64_t l_def_NOT_NVDIMM = ((l_TGT2_ATTR_EFF_HYBRID[l_def_PORT_INDEX][literal_0] == literal_0)
+ || (l_TGT2_ATTR_EFF_HYBRID_MEMORY_TYPE[l_def_PORT_INDEX][literal_0] == literal_0));
uint64_t l_def_MSS_FREQ_EQ_2400 = ((l_TGT1_ATTR_MSS_FREQ >= literal_2134) && (l_TGT1_ATTR_MSS_FREQ < literal_2401));
+ uint64_t l_def_IS_NVDIMM = ((l_TGT2_ATTR_EFF_HYBRID[l_def_PORT_INDEX][literal_0] == literal_1)
+ && (l_TGT2_ATTR_EFF_HYBRID_MEMORY_TYPE[l_def_PORT_INDEX][literal_0] == literal_1));
uint64_t l_def_MSS_FREQ_EQ_2666 = (l_TGT1_ATTR_MSS_FREQ >= literal_2666);
fapi2::ATTR_MSS_EFF_DPHY_WLO_Type l_TGT2_ATTR_MSS_EFF_DPHY_WLO;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_EFF_DPHY_WLO, TGT2, l_TGT2_ATTR_MSS_EFF_DPHY_WLO));
@@ -447,11 +455,16 @@ fapi2::ReturnCode p9n_mca_scom(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& TGT0
{
l_scom_buffer.insert<36, 6, 58, uint64_t>((literal_7 + l_TGT2_ATTR_EFF_DRAM_CL[l_def_PORT_INDEX]) );
}
- else if ((((l_def_MSS_FREQ_EQ_2400 == literal_1)
- && (l_TGT2_ATTR_EFF_DIMM_TYPE[l_def_PORT_INDEX][literal_0] == literal_1)) && l_def_IS_HW))
+ else if (((((l_def_MSS_FREQ_EQ_2400 == literal_1)
+ && (l_TGT2_ATTR_EFF_DIMM_TYPE[l_def_PORT_INDEX][literal_0] == literal_1)) && l_def_IS_HW) && l_def_NOT_NVDIMM))
{
l_scom_buffer.insert<36, 6, 58, uint64_t>((literal_8 + l_TGT2_ATTR_EFF_DRAM_CL[l_def_PORT_INDEX]) );
}
+ else if (((((l_def_MSS_FREQ_EQ_2400 == literal_1)
+ && (l_TGT2_ATTR_EFF_DIMM_TYPE[l_def_PORT_INDEX][literal_0] == literal_1)) && l_def_IS_HW) && l_def_IS_NVDIMM))
+ {
+ l_scom_buffer.insert<36, 6, 58, uint64_t>((literal_9 + l_TGT2_ATTR_EFF_DRAM_CL[l_def_PORT_INDEX]) );
+ }
else if ((((l_def_MSS_FREQ_EQ_2666 == literal_1)
&& (l_TGT2_ATTR_EFF_DIMM_TYPE[l_def_PORT_INDEX][literal_0] == literal_1)) && l_def_IS_HW))
{
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_regs.H b/src/import/chips/p9/procedures/hwp/io/p9_io_regs.H
index f98504953..5b5cdac9f 100644
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_regs.H
+++ b/src/import/chips/p9/procedures/hwp/io/p9_io_regs.H
@@ -193,6 +193,14 @@
#define EDIP_RX_BER_TIMEOUT 0x800888000000003f, 56, 4 // rx_ber_timeout, used for when making bit error measurements with a servo op (see workbook table 4.10 for timer settings)
#define EDIP_RX_CTL_MODE16_EO_PG 0x800888000000003f, 48, 16 // register -- description
#define EDIP_CHAN_FAIL_MASK 0x0000000000000020, 15, 8 // scom mode reg spares.
+#define EDIP_RX_PG_SPARE_MODE_0 0x800800000000003f, 48, 1 // per-group spare mode latch.
+#define EDIP_RX_PG_SPARE_MODE_1 0x800800000000003f, 49, 1 // per-group spare mode latch.
+#define EDIP_RX_PG_SPARE_MODE_2 0x800800000000003f, 50, 1 // per-group spare mode latch.
+#define EDIP_RX_RC_ENABLE_CM_FINE_CAL 0x8008b8000000003f, 56, 1 // rx recalibration common mode fine calibration enable
+#define EDIP_RX_EO_ENABLE_DAC_H1_CAL 0x8008b0000000003f, 50, 1 // rx eye optimization h! dac calibration to reference
+#define EDIP_RX_EO_ENABLE_DAC_H1_TO_A_CAL 0x8008b0000000003f, 61, 1 // rx eye optimization h! dac to amplitude dac cross-calibration
+#define EDIP_RX_A_INTEG_COARSE_GAIN 0x800028000000003f, 48, 4 // this is integrator coarse gain control used in making common mode adjustments.
+
#define EDI_RX_WTM_STATE 0x800950000000003f, 48, 5 // main wiretest state machine current state (rjr)): \r\n\tx00: idle \r\n\tx01: drv data wt \r\n\tx02: drv clock wt \r\n\tx03: drv data 0 \r\n\tx04: drv clock 0 \r\n\tx05: rx wt \r\n\tx06: wait all ones \r\n\tx07: reset pll \r\n\tx08: wait pll \r\n\tx09: drive clock \r\n\tx0a: drive data 1 \r\n\tx0b: wait all zeroes \r\n\tx0c: drive data 0 \r\n\tx0d: done \r\n\tx0e: unused \r\n\tx0f: unused \r\n\tx10: wait prev done \r\n\tx11: drv prev done \r\n\tx12: drv all done \r\n\tx13: wait all done \r\n\tx14: init tx fifo \r\n\tx15: unused \r\n\tx16: unused \r\n\tx17: unused \r\n\tx18: set c & d dr strength \r\n\tx19: set data only dr strength \r\n\tx1a: clock fail \r\n\tx1b: all bad lanes \r\n\tx1c: wt timeout fail \r\n\tx1d: pll/dll fail \r\n\tx1e: all ones fail \r\n\tx1f: all zeroes fail \r\n\trjr
@@ -2496,7 +2504,6 @@
#define EDIP_RX_A_OFFSET_O0 0x800020000000003f, 48, 7 // this is the vertical offset of the odd low threshold sampling latch.
#define EDIP_RX_A_OFFSET_O1 0x800020000000003f, 56, 7 // this is the vertical offset of the odd high threshold sampling latch.
#define EDIP_RX_DAC_CNTL4_EO_PL 0x800020000000003f, 48, 16 // register -- description
-#define EDIP_RX_A_INTEG_COARSE_GAIN 0x800028000000003f, 48, 4 // this is integrator coarse gain control used in making common mode adjustments.
#define EDIP_RX_A_EVEN_INTEG_FINE_GAIN 0x800028000000003f, 52, 5 // this is integrator gain control used in making common mode adjustments.
#define EDIP_RX_A_ODD_INTEG_FINE_GAIN 0x800028000000003f, 57, 5 // this is integrator gain control used in making common mode adjustments.
#define EDIP_RX_DAC_CNTL5_EO_PL 0x800028000000003f, 48, 16 // register -- description
@@ -2703,9 +2710,6 @@
#define EDIP_RX_A_PATH_OFF_EVEN 0x800398000000003f, 48, 6 // eye opt a bank even path offset
#define EDIP_RX_A_PATH_OFF_ODD 0x800398000000003f, 54, 6 // eye opt a bank odd path offset
#define EDIP_RX_WORK_STAT3_EO_PL 0x800398000000003f, 48, 16 // register -- description
-#define EDIP_RX_PG_SPARE_MODE_0 0x800800000000003f, 48, 1 // per-group spare mode latch.
-#define EDIP_RX_PG_SPARE_MODE_1 0x800800000000003f, 49, 1 // per-group spare mode latch.
-#define EDIP_RX_PG_SPARE_MODE_2 0x800800000000003f, 50, 1 // per-group spare mode latch.
#define EDIP_RX_PG_SPARE_MODE_3 0x800800000000003f, 51, 1 // per-group spare mode latch.
#define EDIP_RX_PG_SPARE_MODE_4 0x800800000000003f, 52, 1 // chicken switch for hw219893. fix is to prevent the rx_sls_hndshk_state sm and the rx_dyn_recal_hndshk_state sm from ever being allowed to run at the same time. setting the cs turns this feature off.
#define EDIP_RX_SPARE_MODE_PG 0x800800000000003f, 48, 16 // register -- description
@@ -2803,7 +2807,6 @@
#define EDIP_RX_EO_STEP_CNTL_EDI_ALIAS 0x8008b0000000003f, 48, 16 // rx eye optimization step control edi alias
#define EDIP_RX_EO_ENABLE_INTEG_LATCH_OFFSET_CAL 0x8008b0000000003f, 48, 1 // rx eye optimization latch offset adjustment enable with integrator-based disable
#define EDIP_RX_EO_ENABLE_CTLE_COARSE_CAL 0x8008b0000000003f, 49, 1 // rx eye optimization coarse ctle/peakin enable
-#define EDIP_RX_EO_ENABLE_DAC_H1_CAL 0x8008b0000000003f, 50, 1 // rx eye optimization h! dac calibration to reference
#define EDIP_RX_EO_ENABLE_VGA_CAL 0x8008b0000000003f, 51, 1 // rx eye optimization vga gainand offset adjust enable
#define EDIP_RX_EO_ENABLE_DFE_H1_CAL 0x8008b0000000003f, 52, 1 // rx eye optimization dfe h1 adjust enable
#define EDIP_RX_EO_ENABLE_H1AP_TWEAK 0x8008b0000000003f, 53, 1 // rx eye optimization h1/an pr adjust enable
@@ -2814,7 +2817,6 @@
#define EDIP_RX_EO_ENABLE_RESULT_CHECK 0x8008b0000000003f, 58, 1 // rx eye optimization final results check enable
#define EDIP_RX_EO_ENABLE_CTLE_EDGE_TRACK_ONLY 0x8008b0000000003f, 59, 1 // rx eye optimization ctle/peakin enable with edge tracking only
#define EDIP_RX_EO_ENABLE_DFE_H2_H12_CAL 0x8008b0000000003f, 60, 1 // rx eye optimization dfe h2 to h12 calibration enable
-#define EDIP_RX_EO_ENABLE_DAC_H1_TO_A_CAL 0x8008b0000000003f, 61, 1 // rx eye optimization h! dac to amplitude dac cross-calibration
#define EDIP_RX_EO_ENABLE_FINAL_L2U_ADJ 0x8008b0000000003f, 62, 1 // rx eye optimization final rx fifo load-to-unload delay adjustment enable
#define EDIP_RX_EO_ENABLE_DONE_SIGNALING 0x8008b0000000003f, 63, 1 // rx eye optimization eye opt done signaling enable
#define EDIP_RX_CTL_MODE21_EO_PG 0x8008b0000000003f, 48, 16 // register -- description
@@ -2827,7 +2829,6 @@
#define EDIP_RX_RC_ENABLE_H1AP_TWEAK 0x8008b8000000003f, 53, 1 // rx recalibration h1/an pr adjust enable
#define EDIP_RX_RC_ENABLE_DDC 0x8008b8000000003f, 54, 1 // rx recalibration dynamic data centering enable
#define EDIP_RX_RC_ENABLE_CM_COARSE_CAL 0x8008b8000000003f, 55, 1 // rx recalibration common mode coarse calibration enable
-#define EDIP_RX_RC_ENABLE_CM_FINE_CAL 0x8008b8000000003f, 56, 1 // rx recalibration common mode fine calibration enable
#define EDIP_RX_RC_ENABLE_BER_TEST 0x8008b8000000003f, 57, 1 // rx recalibration unsupported, leave at 0. bit error rate test enable
#define EDIP_RX_RC_ENABLE_RESULT_CHECK 0x8008b8000000003f, 58, 1 // rx recalibration unsupported, leave at 0. final results check enable
#define EDIP_RX_RC_ENABLE_CTLE_EDGE_TRACK_ONLY 0x8008b8000000003f, 59, 1 // rx recalibration ctle/peaking enable with edge tracking only
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.C b/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.C
index 8e421dab6..5d2fab537 100644
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.C
+++ b/src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.C
@@ -730,6 +730,58 @@ fapi_try_exit:
return fapi2::current_err;
}
+
+/**
+ * @brief Xbus Common Mode Workaround
+ * @param[in] i_tgt FAPI2 Target
+ * @param[in] i_grp Clock Group
+ * @retval ReturnCode
+ */
+fapi2::ReturnCode p9x_cm_workaround( const XBUS_TGT i_tgt, const uint8_t i_grp )
+{
+ FAPI_IMP( "p9x_cm_workaround: I/O EDI+ Xbus Entering" );
+ const uint8_t CMDAC = 5; // Initialize with a CMDAC = 2
+ const uint8_t XBUS_LANES = 17;
+ const uint8_t LN0 = 0;
+ uint32_t l_cm_crs = 0;
+ uint64_t l_data = 0;
+ uint8_t l_workaround_en = 0;
+
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_proc =
+ i_tgt.getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+
+ FAPI_TRY( FAPI_ATTR_GET( fapi2::ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND, l_proc, l_workaround_en ) );
+
+ if( l_workaround_en )
+ {
+ FAPI_DBG( "p9x_cm_workaround: I/O EDI+ Xbus Executing" );
+ FAPI_TRY( io::rmw( EDIP_RX_PG_SPARE_MODE_0, i_tgt, i_grp, LN0, ((CMDAC >> 2) & 0x1)));
+ FAPI_TRY( io::rmw( EDIP_RX_PG_SPARE_MODE_1, i_tgt, i_grp, LN0, ((CMDAC >> 1) & 0x1)));
+ FAPI_TRY( io::rmw( EDIP_RX_PG_SPARE_MODE_2, i_tgt, i_grp, LN0, ((CMDAC >> 0) & 0x1)));
+ FAPI_TRY( io::rmw( EDIP_RX_RC_ENABLE_CM_FINE_CAL, i_tgt, i_grp, LN0, 0));
+ FAPI_TRY( io::rmw( EDIP_RX_EO_ENABLE_DAC_H1_TO_A_CAL, i_tgt, i_grp, LN0, 1));
+ FAPI_TRY( io::rmw( EDIP_RX_EO_ENABLE_DAC_H1_CAL, i_tgt, i_grp, LN0, 1));
+
+ for( uint8_t l_lane = 0; l_lane < XBUS_LANES; ++l_lane )
+ {
+ FAPI_TRY( io::read( EDIP_RX_A_INTEG_COARSE_GAIN, i_tgt, i_grp, l_lane, l_data ));
+ l_cm_crs = io::get( EDIP_RX_A_INTEG_COARSE_GAIN, l_data );
+ l_cm_crs = ( l_cm_crs * 5 ) / 10;
+ FAPI_TRY( io::rmw( EDIP_RX_A_INTEG_COARSE_GAIN, i_tgt, i_grp, l_lane, l_cm_crs));
+ }
+ }
+ else
+ {
+ FAPI_DBG( "p9x_cm_workaround: I/O EDI+ Xbus Skipping" );
+ }
+
+fapi_try_exit:
+ FAPI_IMP( "p9x_cm_workaround: I/O EDI+ Xbus Exiting" );
+ return fapi2::current_err;
+}
+
+
+
/**
* @brief Rx Dc Calibration
* @param[in] i_tgt FAPI2 Target
@@ -842,6 +894,9 @@ fapi2::ReturnCode rx_dccal_poll_grp( const XBUS_TGT i_tgt, const uint8_t i_grp
// Restore the invalid bits, Wiretest will modify these as training is run.
FAPI_TRY( set_lanes_invalid( i_tgt, i_grp, 1 ), "Error Setting Lane Invalid to 1" );
+ // Data Compression Workaround
+ FAPI_TRY( p9x_cm_workaround( i_tgt, i_grp ), "p9x_cm_workaround call failed" );
+
FAPI_DBG( "I/O EDI+ Xbus Rx Dccal Complete on Group(%d)", i_grp );
diff --git a/src/import/chips/p9/procedures/hwp/io/p9a_io_omi_dccal.C b/src/import/chips/p9/procedures/hwp/io/p9a_io_omi_dccal.C
index 10748a148..dff06ace3 100644
--- a/src/import/chips/p9/procedures/hwp/io/p9a_io_omi_dccal.C
+++ b/src/import/chips/p9/procedures/hwp/io/p9a_io_omi_dccal.C
@@ -722,6 +722,46 @@ fapi_try_exit:
return fapi2::current_err;
}
+/**
+ * @brief Init PHY Tx FIFO Logic
+ * @param[in] i_tgt FAPI2 Target
+ * @param[in] i_lave_vector Lanve Vector
+ * @retval ReturnCode
+ */
+fapi2::ReturnCode p9_omi_tx_fifo_init(const OMIC_TGT i_tgt, const uint32_t i_lane_vector)
+{
+ FAPI_IMP("p9_omi_tx_fifo_init: I/O OMI Entering");
+ const uint8_t GRP0 = 0;
+ const uint8_t LANES = 24;
+ fapi2::buffer<uint64_t> l_data = 0;
+
+ // Power up Per-Lane Registers
+ for(uint8_t l_lane = 0; l_lane < LANES; ++l_lane)
+ {
+ if(((0x1 << l_lane) & i_lane_vector) != 0)
+ {
+ // - Clear TX_UNLOAD_CLK_DISABLE
+ FAPI_TRY(io::read(OPT_TX_MODE2_PL, i_tgt, GRP0, l_lane, l_data));
+ io::set(OPT_TX_UNLOAD_CLK_DISABLE, 0, l_data);
+ FAPI_TRY(io::write(OPT_TX_MODE2_PL, i_tgt, GRP0, l_lane, l_data));
+
+ // - Set TX_FIFO_INIT
+ l_data.flush<0>();
+ io::set(OPT_TX_FIFO_INIT, 1, l_data);
+ FAPI_TRY(io::write(OPT_TX_CNTL1G_PL, i_tgt, GRP0, l_lane, l_data));
+
+ // - Set TX_UNLOAD_CLK_DISABLE
+ FAPI_TRY(io::read(OPT_TX_MODE2_PL, i_tgt, GRP0, l_lane, l_data));
+ io::set(OPT_TX_UNLOAD_CLK_DISABLE, 1, l_data );
+ FAPI_TRY(io::write(OPT_TX_MODE2_PL, i_tgt, GRP0, l_lane, l_data));
+ }
+ }
+
+fapi_try_exit:
+ FAPI_IMP("p9_omi_tx_fifo_init: I/O OMI Exiting");
+ return fapi2::current_err;
+}
+
} // end namespace P9A_IO_OMI_DCCAL
using namespace P9A_IO_OMI_DCCAL;
@@ -784,6 +824,9 @@ fapi2::ReturnCode p9a_io_omi_dccal(const OMIC_TGT i_tgt, const uint32_t i_lane_v
FAPI_TRY(set_omi_flywheel_off(i_tgt, i_lane_vector, 0));
FAPI_TRY(set_omi_pr_edge_track_cntl(i_tgt, i_lane_vector, 0));
+ // Run Tx FIFO Init
+ FAPI_TRY(p9_omi_tx_fifo_init(i_tgt, i_lane_vector));
+
fapi_try_exit:
FAPI_IMP("p9_io_omi_dccal: I/O OMI Exiting");
return fapi2::current_err;
diff --git a/src/import/chips/p9/procedures/hwp/io/p9a_io_omi_scominit.C b/src/import/chips/p9/procedures/hwp/io/p9a_io_omi_scominit.C
index b73642b5f..06ce72238 100644
--- a/src/import/chips/p9/procedures/hwp/io/p9a_io_omi_scominit.C
+++ b/src/import/chips/p9/procedures/hwp/io/p9a_io_omi_scominit.C
@@ -52,6 +52,7 @@
#include <p9_io_scom.H>
#include <p9_io_regs.H>
#include <p9a_omi_io_scom.H>
+#include <p9a_omic_io_scom.H>
#include <p9a_io_omi_scominit.H>
#include <p9_obus_scom_addresses.H>
#include <p9a_mc_scom_addresses.H>
@@ -78,6 +79,8 @@ fapi2::ReturnCode p9a_io_omi_scominit(const fapi2::Target<fapi2::TARGET_TYPE_OMI
// get a proc target
fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_proc_target = i_target.getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+ auto l_omi_lst = i_target.getChildren<fapi2::TARGET_TYPE_OMI>();
+
// assert IO reset to power-up bus endpoint logic
FAPI_TRY(io::rmw(OPT_IORESET_HARD_BUS0, i_target, GROUP_00, LANE_00, SET_RESET));
@@ -87,9 +90,15 @@ fapi2::ReturnCode p9a_io_omi_scominit(const fapi2::Target<fapi2::TARGET_TYPE_OMI
FAPI_TRY(io::rmw(OPT_IORESET_HARD_BUS0, i_target, GROUP_00, LANE_00, CLEAR_RESET));
FAPI_INF("Invoke FAPI procedure core: input_target");
- FAPI_EXEC_HWP(rc, p9a_omi_io_scom, i_target, l_system_target, l_proc_target);
+ FAPI_EXEC_HWP(rc, p9a_omic_io_scom, i_target, l_system_target, l_proc_target);
+
+ for (auto l_omi_target : l_omi_lst)
+ {
+ FAPI_EXEC_HWP(rc, p9a_omi_io_scom, l_omi_target, l_system_target, l_proc_target);
+ }
- // configure FIR
+ // configure FIR if p9a_omi_io_scom passed
+ if ( fapi2::current_err == fapi2::FAPI2_RC_SUCCESS )
{
FAPI_TRY(fapi2::putScom(i_target,
P9A_OMIC_FIR_ACTION0_REG,
@@ -106,7 +115,8 @@ fapi2::ReturnCode p9a_io_omi_scominit(const fapi2::Target<fapi2::TARGET_TYPE_OMI
}
// mark HWP exit
- FAPI_INF("p9a_io_omi_scominit: ...Exiting");
+ FAPI_INF("p9a_io_omi_scominit: ...Exiting, rc = 0x%X",
+ (uint32_t)fapi2::current_err);
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_base.H b/src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_base.H
index 67a3240e3..bb3f737d2 100644
--- a/src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_base.H
+++ b/src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_base.H
@@ -46,7 +46,7 @@
/// Image Magic Numbers
-HCD_CONST64(CPMR_MAGIC_NUMBER, ULL(0x43504d525f312e30)) // CPMR_1.0
+HCD_CONST64(CPMR_MAGIC_NUMBER, ULL(0x43504d525f322e30)) // CPMR_2.0
HCD_CONST64(CME_MAGIC_NUMBER , ULL(0x434d455f5f312e30)) // CME__1.0
HCD_CONST64(QPMR_MAGIC_NUMBER, ULL(0x51504d525f312e30)) // QPMR_1.0
@@ -434,6 +434,7 @@ HCD_CONST(CME_QM_FLAG_SYS_WOF_ENABLE, 0x1000)
HCD_CONST(CME_QM_FLAG_SYS_DYN_FMIN_ENABLE, 0x0800)
HCD_CONST(CME_QM_FLAG_SYS_DYN_FMAX_ENABLE, 0x0400)
HCD_CONST(CME_QM_FLAG_SYS_JUMP_PROTECT, 0x0200)
+HCD_CONST(CME_QM_FLAG_PER_QUAD_VDM_ENABLE, 0x0100)
HCD_CONST(CME_QM_FLAG_PSTATE_PHANTOM_HALT_EN, 0x0001)
/// CME Hcode
@@ -460,6 +461,13 @@ HCD_CONST(CME_QUAD_PSTATE_SIZE, HALF_KB)
HCD_CONST(CME_REGION_SIZE, (64 * ONE_KB))
+
+// HOMER compatibility
+
+HCD_CONST(STOP_API_CPU_SAVE_VER, 0x02)
+HCD_CONST(SELF_SAVE_RESTORE_VER, 0x02)
+HCD_CONST(SMF_SUPPORT_SIGNATURE_OFFSET, 0x1300)
+HCD_CONST(SMF_SELF_SIGNATURE, (0x5f534d46))
// Debug
HCD_CONST(CPMR_TRACE_REGION_OFFSET, (512 * ONE_KB))
diff --git a/src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_occ_sram.H b/src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_occ_sram.H
index 57323d935..86bd06003 100644
--- a/src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_occ_sram.H
+++ b/src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_occ_sram.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -76,6 +76,7 @@ HCD_CONST(OCC_SRAM_OCC_REGION_SIZE, (512 * ONE_KB))
HCD_CONST(OCC_SRAM_BEFORE_PGPE_REGION_SIZE_TOTAL,
(OCC_SRAM_IPC_REGION_SIZE + OCC_SRAM_GPE0_REGION_SIZE + OCC_SRAM_GPE1_REGION_SIZE))
+
//--------------------------------------------------------------------------------------
/// PGPE Base
@@ -192,5 +193,7 @@ HCD_CONST( OCC_SRAM_PGPE_TRACE_START,
(OCC_SRAM_PGPE_HEADER_ADDR + PGPE_HEADER_SIZE));
+HCD_CONST(OCC_SRAM_SHARED_DATA_BASE_ADDR,
+ (OCC_SRAM_PGPE_BASE_ADDR + OCC_SRAM_PGPE_REGION_SIZE - PGPE_OCC_SHARED_SRAM_SIZE))
#endif /* __P9_HCD_MEMMAP_OCC_SRAM_H__ */
diff --git a/src/import/chips/p9/procedures/hwp/lib/p9_hcode_image_defines.H b/src/import/chips/p9/procedures/hwp/lib/p9_hcode_image_defines.H
index 64d81508c..618108f22 100644
--- a/src/import/chips/p9/procedures/hwp/lib/p9_hcode_image_defines.H
+++ b/src/import/chips/p9/procedures/hwp/lib/p9_hcode_image_defines.H
@@ -374,8 +374,10 @@ HCD_HDR_UINT32(g_wof_table_length, 0 ); // WOF Table length
HCD_HDR_UINT32(g_pgpe_core_throttle_assert_cnt, 0 ); // Core throttle assert count
HCD_HDR_UINT32(g_pgpe_core_throttle_deassert_cnt, 0 ); // Core throttle de-aasert count
HCD_HDR_UINT32(g_pgpe_aux_controls, 0 ); // Auxiliary Controls
+HCD_HDR_UINT32(g_pgpe_optrace_pointer, 0 ); // Operational Trace OCC SRAM Pointer
HCD_HDR_UINT32(g_pgpe_doptrace_offset, 0 ); // Deep Operational Trace Main Memory Buffer Offset
HCD_HDR_UINT32(g_pgpe_doptrace_length, 0 ); // Deep Opeartional Trace Main Memory Buffer Length
+HCD_HDR_UINT32(g_pgpe_wof_values_address, 0 ); // SRAM address where PGPE Produced WOF values are located
#ifdef __ASSEMBLER__
.endm
#else
diff --git a/src/import/chips/p9/procedures/hwp/lib/p9_pm_hcd_flags.h b/src/import/chips/p9/procedures/hwp/lib/p9_pm_hcd_flags.h
index 5f3ebba57..dec2af939 100644
--- a/src/import/chips/p9/procedures/hwp/lib/p9_pm_hcd_flags.h
+++ b/src/import/chips/p9/procedures/hwp/lib/p9_pm_hcd_flags.h
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -65,6 +65,7 @@ enum PM_GPE_OCCFLG_DEFS
PIB_I2C_MASTER_ENGINE_2_LOCK_BIT1 = 19, //BIT0 ored BIT1 gives the field
PIB_I2C_MASTER_ENGINE_3_LOCK_BIT0 = 20, //BIT0 ored BIT1 gives the field
PIB_I2C_MASTER_ENGINE_3_LOCK_BIT1 = 21, //BIT0 ored BIT1 gives the field
+ PGPE_OCS_DIRTY = 26,
PGPE_PM_RESET_SUPPRESS = 27,
WOF_HCODE_MODE_BIT0 = 28,
WOF_HCODE_MODE_BIT1 = 29,
@@ -77,6 +78,7 @@ enum PM_GPE_OCCFLG2_DEFS
{
OCCFLG2_DEAD_CORES_START = 0,
OCCFLG2_DEAD_CORES_LENGTH = 24,
+ OCCFLG2_ENABLE_PRODUCE_WOF_VALUES = 24,
OCCFLG2_PGPE_HCODE_FIT_ERR_INJ = 27,
PM_CALLOUT_ACTIVE = 28,
STOP_RECOVERY_TRIGGER_ENABLE = 29,
@@ -127,6 +129,7 @@ enum PM_CME_FLAGS_DEFS
CME_FLAGS_DROOP_SUSPEND_ENTRY = 14,
CME_FLAGS_SAFE_MODE = 16,
CME_FLAGS_PSTATES_SUSPENDED = 17,
+ CME_FLAGS_DB0_COMM_RECV_STARVATION_CNT_ENABLED = 18,
CME_FLAGS_SPWU_CHECK_ENABLE = 22,
CME_FLAGS_BLOCK_ENTRY_STOP11 = 23,
CME_FLAGS_PSTATES_ENABLED = 24,
diff --git a/src/import/chips/p9/procedures/hwp/lib/p9_pstates_cmeqm.h b/src/import/chips/p9/procedures/hwp/lib/p9_pstates_cmeqm.h
index d7739af81..373bd8d8d 100644
--- a/src/import/chips/p9/procedures/hwp/lib/p9_pstates_cmeqm.h
+++ b/src/import/chips/p9/procedures/hwp/lib/p9_pstates_cmeqm.h
@@ -35,6 +35,7 @@
#define __P9_PSTATES_CME_H__
#include <p9_pstates_common.h>
+#include <p9_hcd_memmap_base.H>
/// @}
@@ -161,6 +162,23 @@ typedef struct
uint16_t r_core_header;
} resistance_entry_t;
+typedef struct __attribute__((packed))
+{
+ uint16_t r_package_common;
+ uint16_t r_quad;
+ uint16_t r_core;
+ uint16_t r_quad_header;
+ uint16_t r_core_header;
+ uint8_t r_vdm_cal_version;
+ uint8_t r_avg_min_scale_fact;
+ uint16_t r_undervolt_vmin_floor_limit;
+ uint8_t r_min_bin_protect_pc_adder;
+ uint8_t r_min_bin_protect_bin_adder;
+ uint8_t r_undervolt_allowed;
+ uint8_t reserve[10];
+}
+resistance_entry_per_quad_t;
+
typedef struct
{
poundw_entry_t poundw[NUM_OP_POINTS];
@@ -178,6 +196,35 @@ typedef struct
PoundW_data vpd_w_data;
} LP_VDMParmBlock;
+typedef struct __attribute__((packed))
+{
+ uint16_t ivdd_tdp_ac_current_10ma;
+ uint16_t ivdd_tdp_dc_current_10ma;
+ uint8_t vdm_overvolt_small_thresholds;
+ uint8_t vdm_large_extreme_thresholds;
+ uint8_t vdm_normal_freq_drop; // N_S and N_L Drop
+ uint8_t vdm_normal_freq_return; // L_S and S_N Return
+ uint8_t vdm_vid_compare_per_quad[MAX_QUADS_PER_CHIP];
+ uint8_t vdm_cal_state_avg_min_per_quad[MAX_QUADS_PER_CHIP];
+ uint16_t vdm_cal_state_vmin;
+ uint8_t vdm_cal_state_avg_core_dts;
+ uint16_t vdm_cal_state_avg_core_current;
+ uint16_t vdm_spare;
+}
+poundw_entry_per_quad_t;
+
+typedef struct __attribute__((packed))
+{
+ poundw_entry_per_quad_t poundw[NUM_OP_POINTS];
+ resistance_entry_per_quad_t resistance_data;
+}
+PoundW_data_per_quad;
+
+
+typedef struct
+{
+ PoundW_data_per_quad vpd_w_data;
+} LP_VDMParmBlock_PerQuad;
/// The layout of the data created by the Pstate table creation firmware for
/// comsumption by the Pstate GPE. This data will reside in the Quad
diff --git a/src/import/chips/p9/procedures/hwp/lib/p9_pstates_common.h b/src/import/chips/p9/procedures/hwp/lib/p9_pstates_common.h
index b35d2c0ab..92631a91f 100644
--- a/src/import/chips/p9/procedures/hwp/lib/p9_pstates_common.h
+++ b/src/import/chips/p9/procedures/hwp/lib/p9_pstates_common.h
@@ -240,6 +240,21 @@ typedef struct
} SysPowerDistParms;
+/// AVSBUS Topology
+///
+/// AVS Bus and Rail numbers for VDD, VDN, VCS, and VIO
+///
+typedef struct
+{
+ uint8_t vdd_avsbus_num;
+ uint8_t vdd_avsbus_rail;
+ uint8_t vdn_avsbus_num;
+ uint8_t vdn_avsbus_rail;
+ uint8_t vcs_avsbus_num;
+ uint8_t vcs_avsbus_rail;
+ uint8_t vio_avsbus_num;
+ uint8_t vio_avsbus_rail;
+} AvsBusTopology_t;
//
// WOF Voltage, Frequency Ratio Tables
diff --git a/src/import/chips/p9/procedures/hwp/lib/p9_pstates_occ.h b/src/import/chips/p9/procedures/hwp/lib/p9_pstates_occ.h
index 6ef85286e..2fd82683d 100644
--- a/src/import/chips/p9/procedures/hwp/lib/p9_pstates_occ.h
+++ b/src/import/chips/p9/procedures/hwp/lib/p9_pstates_occ.h
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -205,6 +205,8 @@ typedef struct
// AC tdp vdd nominal
uint16_t lac_tdp_vdd_nominal_10ma;
+ AvsBusTopology_t avs_bus_topology;
+
} __attribute__((aligned(128))) OCCPstateParmBlock;
#ifdef __cplusplus
diff --git a/src/import/chips/p9/procedures/hwp/lib/p9_pstates_pgpe.h b/src/import/chips/p9/procedures/hwp/lib/p9_pstates_pgpe.h
index a1b10e4cc..be48537d3 100644
--- a/src/import/chips/p9/procedures/hwp/lib/p9_pstates_pgpe.h
+++ b/src/import/chips/p9/procedures/hwp/lib/p9_pstates_pgpe.h
@@ -350,6 +350,10 @@ typedef struct
//Jump-value slopes
int16_t PsVDMJumpSlopes[VPD_NUM_SLOPES_REGION][NUM_JUMP_VALUES];
+ uint8_t pad2[2];
+
+ //AvsBusTopology
+ AvsBusTopology_t avs_bus_topology;
// @todo DPLL Droop Settings. These need communication to SGPE for STOP
diff --git a/src/import/chips/p9/procedures/hwp/memory/lab/sdk/example/C/mss_lab_sfwrite.C b/src/import/chips/p9/procedures/hwp/memory/lab/sdk/example/C/mss_lab_sfwrite.C
index 58b382a97..8fd2fb737 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lab/sdk/example/C/mss_lab_sfwrite.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lab/sdk/example/C/mss_lab_sfwrite.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,8 +33,10 @@
// *HWP Level: 3
// *HWP Consumed by: Memory
-#include <mss_lab_tools.H>
+#include <generic/memory/lab/mss_lab_tools.H>
+#include <lib/shared/nimbus_defaults.H>
+#include <lib/shared/nimbus_defaults.H>
#include <generic/memory/lib/utils/poll.H>
#include <lib/mcbist/address.H>
#include <lib/mcbist/memdiags.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C
deleted file mode 100644
index 60dc06bcc..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C
+++ /dev/null
@@ -1,376 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file ccs.C
-/// @brief Run and manage the CCS engine
-///
-// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
-// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#include <fapi2.H>
-
-#include <mss.H>
-#include <lib/ccs/ccs.H>
-#include <lib/fir/check.H>
-#include <lib/phy/mss_lrdimm_training.H>
-
-#ifdef LRDIMM_CAPABLE
- #include <lib/workarounds/quad_encode_workarounds.H>
-#endif
-
-using fapi2::TARGET_TYPE_MCBIST;
-using fapi2::TARGET_TYPE_MCA;
-
-using fapi2::FAPI2_RC_SUCCESS;
-
-namespace mss
-{
-namespace ccs
-{
-
-///
-/// @brief Determines our rank configuration type across all ports
-/// @param[in] i_target the MCBIST target on which to operate
-/// @param[out] o_rank_config the rank configuration
-/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS if ok
-///
-fapi2::ReturnCode get_rank_config(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- std::vector<rank_configuration>& o_rank_config)
-{
- o_rank_config.clear();
- // Create one per port, we then use relative indexing to get us the number we need
- o_rank_config = std::vector<rank_configuration>(PORTS_PER_MCBIST);
-
- for(const auto& l_mca : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target))
- {
- rank_configuration l_config;
- FAPI_TRY(get_rank_config(l_mca, l_config));
- o_rank_config[mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(l_mca)] = l_config;
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines our rank configuration type
-/// @param[in] i_target the MCA target on which to operate
-/// @param[out] o_rank_config the rank configuration
-/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS if ok
-///
-fapi2::ReturnCode get_rank_config(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- rank_configuration& o_rank_config)
-{
- constexpr uint8_t QUAD_RANK_ENABLE = 4;
- o_rank_config = rank_configuration::DUAL_DIRECT;
-
- uint8_t l_num_master_ranks[MAX_DIMM_PER_PORT] = {};
- FAPI_TRY(mss::eff_num_master_ranks_per_dimm(i_target, l_num_master_ranks));
-
- // We only need to check DIMM0
- // Our number of ranks should be the same between DIMM's 0/1
- // Check if we have the right number for encoded mode
- o_rank_config = l_num_master_ranks[0] == QUAD_RANK_ENABLE ?
- rank_configuration::QUAD_ENCODED :
- rank_configuration::DUAL_DIRECT;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Start or stop the CCS engine
-/// @param[in] i_target The MCBIST containing the CCS engine
-/// @param[in] i_start_stop bool MSS_CCS_START for starting, MSS_CCS_STOP otherwise
-/// @return FAPI2_RC_SUCCESS iff success
-///
-template<>
-fapi2::ReturnCode start_stop( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target, const bool i_start_stop )
-{
- typedef ccsTraits<TARGET_TYPE_MCBIST> TT;
-
- fapi2::buffer<uint64_t> l_buf;
-
- // Do we need to read this? We are setting the only bit defined in the scomdef? BRS
- FAPI_TRY(mss::getScom(i_target, TT::CNTLQ_REG, l_buf));
-
- FAPI_TRY( mss::putScom(i_target, TT::CNTLQ_REG,
- i_start_stop ? l_buf.setBit<TT::CCS_START>() : l_buf.setBit<TT::CCS_STOP>()) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determine the CCS failure type
-/// @param[in] i_target MCBIST target
-/// @param[in] i_type the failure type
-/// @param[in] i_mca The port the CCS instruction is training
-/// @return ReturnCode associated with the fail.
-/// @note FFDC is handled here, caller doesn't need to do it
-///
-fapi2::ReturnCode fail_type( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const uint64_t& i_type,
- const fapi2::Target<TARGET_TYPE_MCA>& i_mca )
-{
- fapi2::ReturnCode l_failing_rc(fapi2::FAPI2_RC_SUCCESS);
- // Including the MCA_TARGET here and below at CAL_TIMEOUT since these problems likely lie at the MCA level
- // So we disable the PORT and hopefully that's it
- // If the problem lies with the MCBIST, it'll just have to loop
- FAPI_ASSERT(STAT_READ_MISCOMPARE != i_type,
- fapi2::MSS_CCS_READ_MISCOMPARE()
- .set_MCBIST_TARGET(i_target)
- .set_FAIL_TYPE(i_type)
- .set_MCA_TARGET(i_mca),
- "%s CCS FAIL Read Miscompare", mss::c_str(i_mca));
-
- // This error is likely due to a bad CCS engine/ MCBIST
- FAPI_ASSERT(STAT_UE_SUE != i_type,
- fapi2::MSS_CCS_UE_SUE()
- .set_FAIL_TYPE(i_type)
- .set_MCBIST_TARGET(i_target),
- "%s CCS FAIL UE or SUE Error", mss::c_str(i_target));
-
- FAPI_ASSERT(STAT_CAL_TIMEOUT != i_type,
- fapi2::MSS_CCS_CAL_TIMEOUT()
- .set_FAIL_TYPE(i_type)
- .set_MCBIST_TARGET(i_target)
- .set_MCA_TARGET(i_mca),
- "%s CCS FAIL Calibration Operation Time Out", mss::c_str(i_mca));
-
- // Problem with the CCS engine
- FAPI_ASSERT(STAT_HUNG != i_type,
- fapi2::MSS_CCS_HUNG().set_MCBIST_TARGET(i_target),
- "%s CCS appears hung", mss::c_str(i_target));
-fapi_try_exit:
- // Due to the PRD update, we need to check for FIR's
- // If any FIR's have lit up, this CCS fail could have been caused by the FIR
- // So, let PRD retrigger this step to see if we can resolve the issue
- return mss::check::fir_or_pll_fail<mss::mc_type::NIMBUS>(i_target, fapi2::current_err);
-}
-
-///
-/// @brief Execute the contents of the CCS array
-/// @param[in] i_target The MCBIST containing the array
-/// @param[in] i_program the MCBIST ccs program - to get the polling parameters
-/// @param[in] i_port The port target that the array is for
-/// @return FAPI2_RC_SUCCESS iff success
-///
-template<>
-fapi2::ReturnCode execute_inst_array(const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- ccs::program<TARGET_TYPE_MCBIST>& i_program,
- const fapi2::Target<TARGET_TYPE_MCA>& i_port)
-{
- typedef ccsTraits<TARGET_TYPE_MCBIST> TT;
-
- fapi2::buffer<uint64_t> status;
-
- FAPI_TRY(start_stop(i_target, mss::START), "%s Error in execute_inst_array", mss::c_str(i_port) );
-
- mss::poll(i_target, TT::STATQ_REG, i_program.iv_poll,
- [&status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
- {
- FAPI_INF("ccs statq 0x%llx, remaining: %d", stat_reg, poll_remaining);
- status = stat_reg;
- return status.getBit<TT::CCS_IN_PROGRESS>() != 1;
- },
- i_program.iv_probes);
-
- // Check for done and success. DONE being the only bit set.
- if (status == STAT_QUERY_SUCCESS)
- {
- FAPI_INF("%s CCS Executed Successfully.", mss::c_str(i_port) );
- goto fapi_try_exit;
- }
-
- // So we failed or we're still in progress. Mask off the fail bits
- // and run this through the FFDC generator.
- // TK: Put the const below into a traits class? -- JLH
- FAPI_TRY( fail_type(i_target, status & 0x1C00000000000000, i_port), "Error in execute_inst_array" );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Execute a set of CCS instructions
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the vector of instructions
-/// @param[in] i_ports the vector of ports
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note assumes the CCS engine has been configured.
-///
-template<>
-fapi2::ReturnCode execute( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- ccs::program<TARGET_TYPE_MCBIST>& i_program,
- const std::vector< fapi2::Target<TARGET_TYPE_MCA> >& i_ports)
-{
- typedef ccsTraits<TARGET_TYPE_MCBIST> TT;
-
- // Subtract one for the idle we insert at the end
- constexpr size_t CCS_INSTRUCTION_DEPTH = 32 - 1;
- constexpr uint64_t CCS_ARR0_ZERO = MCBIST_CCS_INST_ARR0_00;
- constexpr uint64_t CCS_ARR1_ZERO = MCBIST_CCS_INST_ARR1_00;
-
- ccs::instruction_t<TARGET_TYPE_MCBIST> l_des = ccs::des_command<TARGET_TYPE_MCBIST>();
-
- FAPI_INF("loading ccs instructions (%d) for %s", i_program.iv_instructions.size(), mss::c_str(i_target));
-
- auto l_inst_iter = i_program.iv_instructions.begin();
-
- std::vector<rank_configuration> l_rank_configs;
- FAPI_TRY(get_rank_config(i_target, l_rank_configs));
-
- // Stop the CCS engine just for giggles - it might be running ...
- FAPI_TRY( start_stop(i_target, mss::states::STOP), "Error in ccs::execute" );
-
- FAPI_ASSERT( mss::poll(i_target, TT::STATQ_REG, poll_parameters(),
- [](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
- {
- FAPI_INF("ccs statq (stop) 0x%llx, remaining: %d", stat_reg, poll_remaining);
- return stat_reg.getBit<TT::CCS_IN_PROGRESS>() != 1;
- }),
- fapi2::MSS_CCS_HUNG_TRYING_TO_STOP().set_MCBIST_TARGET(i_target) );
-
- while (l_inst_iter != i_program.iv_instructions.end())
- {
-
- // Kick off the CCS engine - per port. No broadcast mode for CCS (per Shelton 9/23/15)
- for (const auto& p : i_ports)
- {
- const auto l_port_index = mss::relative_pos<TARGET_TYPE_MCBIST>(p);
- size_t l_inst_count = 0;
-
- uint64_t l_total_delay = 0;
- uint64_t l_delay = 0;
- uint64_t l_repeat = 0;
- uint8_t l_current_cke = 0;
-
- // Shove the instructions into the CCS engine, in 32 instruction chunks, and execute them
- for (; l_inst_iter != i_program.iv_instructions.end()
- && l_inst_count < CCS_INSTRUCTION_DEPTH; ++l_inst_count, ++l_inst_iter)
- {
- // First, update the current instruction's chip selects for the current port
- FAPI_TRY(l_inst_iter->configure_rank(p, l_rank_configs[l_port_index]), "Error in rank config");
-
- l_inst_iter->arr0.extractToRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(l_current_cke);
-
- // Make sure this instruction leads to the next. Notice this limits this mechanism to pretty
- // simple (straight line) CCS programs. Anything with a loop or such will need another mechanism.
- l_inst_iter->arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_GOTO_CMD,
- MCBIST_CCS_INST_ARR1_00_GOTO_CMD_LEN>(l_inst_count + 1);
- FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_inst_iter->arr0), "Error in ccs::execute" );
- FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_inst_iter->arr1), "Error in ccs::execute" );
-
- // arr1 contains a specification of the delay and repeat after this instruction, as well
- // as a repeat. Total up the delays as we go so we know how long to wait before polling
- // the CCS engine for completion
- l_inst_iter->arr1.extractToRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(l_delay);
- l_inst_iter->arr1.extractToRight<MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT,
- MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT>(l_repeat);
-
- l_total_delay += l_delay * (l_repeat + 1);
-
- FAPI_INF("css inst %d: 0x%016lX 0x%016lX (0x%lx, 0x%lx) delay: 0x%x (0x%x) %s",
- l_inst_count, l_inst_iter->arr0, l_inst_iter->arr1,
- CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count,
- l_delay, l_total_delay, mss::c_str(i_target));
- }
-
- // Check our program for any delays. If there isn't a iv_initial_delay configured, then
- // we use the delay we just summed from the instructions.
- if (i_program.iv_poll.iv_initial_delay == 0)
- {
- i_program.iv_poll.iv_initial_delay = cycles_to_ns(i_target, l_total_delay);
- }
-
- if (i_program.iv_poll.iv_initial_sim_delay == 0)
- {
- i_program.iv_poll.iv_initial_sim_delay = cycles_to_simcycles(l_total_delay);
- }
-
- FAPI_INF("executing ccs instructions (%d:%d, %d) for %s",
- i_program.iv_instructions.size(), l_inst_count, i_program.iv_poll.iv_initial_delay, mss::c_str(i_target));
-
- // Deselect
- l_des.arr0.insertFromRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(l_current_cke);
-
- // Insert a DES as our last instruction. DES is idle state anyway and having this
- // here as an instruction forces the CCS engine to wait the delay specified in
- // the last instruction in this array (which it otherwise doesn't do.)
- l_des.arr1.setBit<MCBIST_CCS_INST_ARR1_00_END>();
- FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_des.arr0), "Error in ccs::execute" );
- FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_des.arr1), "Error in ccs::execute" );
-
- FAPI_INF("css inst %d fixup: 0x%016lX 0x%016lX (0x%lx, 0x%lx) %s",
- l_inst_count, l_des.arr0, l_des.arr1,
- CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count, mss::c_str(i_target));
-
-
- FAPI_INF("executing CCS array for port %d (%s)", l_port_index, mss::c_str(p));
- FAPI_TRY( select_ports( i_target, l_port_index), "Error in ccs execute" );
- FAPI_TRY( execute_inst_array(i_target, i_program, p), "Error in ccs execute" );
- }
- }
-
-#if LRDIMM_CAPABLE
-
- if(mss::workarounds::contains_command_mrs(i_program.iv_instructions))
- {
- // Get ranks in pair bombs out if we can't get any ranks in this pair, so we should be safe here
- for (const auto& p : i_ports)
- {
- FAPI_TRY(mss::workarounds::fix_shadow_register_corruption(p));
- }
- }
-
-#endif
-
-fapi_try_exit:
- i_program.iv_instructions.clear();
- return fapi2::current_err;
-}
-
-///
-/// @brief Nimbus specialization for modeq_copy_cke_to_spare_cke
-/// @param[in] fapi2::Target<TARGET_TYPE_MCBIST>& the target to effect
-/// @param[in,out] the buffer representing the mode register
-/// @param[in] mss::states - mss::ON iff Copy CKE signals to CKE Spare on both ports
-/// @note no-op for p9n
-///
-template<>
-void copy_cke_to_spare_cke<TARGET_TYPE_MCBIST>( const fapi2::Target<TARGET_TYPE_MCBIST>&,
- fapi2::buffer<uint64_t>&, states )
-{
- return;
-}
-
-} // namespace
-} // namespace
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_nimbus.C b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_nimbus.C
new file mode 100644
index 000000000..d3725beee
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_nimbus.C
@@ -0,0 +1,243 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_nimbus.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file ccs_nimbus.C
+/// @brief Run and manage the CCS engine
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+
+#include <mss.H>
+#include <lib/fir/check.H>
+#include <lib/phy/mss_lrdimm_training.H>
+#include <lib/shared/nimbus_defaults.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
+#include <lib/ccs/ccs_nimbus.H>
+
+#ifdef LRDIMM_CAPABLE
+ #include <lib/workarounds/quad_encode_workarounds.H>
+#endif
+
+using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_MCA;
+using fapi2::FAPI2_RC_SUCCESS;
+
+// Generates linkage
+constexpr std::pair<uint64_t, uint64_t> ccsTraits<mss::mc_type::NIMBUS>::CS_N[];
+constexpr std::pair<uint64_t, uint64_t> ccsTraits<mss::mc_type::NIMBUS>::CS_ND[];
+
+namespace mss
+{
+namespace ccs
+{
+
+///
+/// @brief Select the port(s) to be used by the CCS - EXPLORER specialization
+/// @param[in] i_target the target to effect
+/// @param[in] i_ports the buffer representing the ports
+///
+template<>
+fapi2::ReturnCode select_ports<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ uint64_t i_ports)
+{
+ typedef ccsTraits<mss::mc_type::NIMBUS> TT;
+ fapi2::buffer<uint64_t> l_data;
+ fapi2::buffer<uint64_t> l_ports;
+
+ // Not handling multiple ports here, can't do that for CCS. BRS
+ FAPI_TRY( l_ports.setBit(i_ports) );
+
+ FAPI_TRY( mss::getScom(i_target, TT::MCB_CNTL_REG, l_data) );
+ l_data.insert<TT::MCB_CNTL_PORT_SEL, TT::MCB_CNTL_PORT_SEL_LEN>(l_ports);
+ FAPI_TRY( mss::putScom(i_target, TT::MCB_CNTL_REG, l_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Execute a set of CCS instructions - multiple ports - NIMBUS specialization
+/// @param[in] i_program the vector of instructions
+/// @param[in] i_ports the vector of ports
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template<>
+fapi2::ReturnCode cleanup_from_execute<fapi2::TARGET_TYPE_MCA, mss::mc_type::NIMBUS>(const ccs::program& i_program,
+ const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCA> >& i_ports)
+{
+#if LRDIMM_CAPABLE
+
+ if(mss::workarounds::contains_command_mrs(i_program.iv_instructions))
+ {
+ // Get ranks in pair bombs out if we can't get any ranks in this pair, so we should be safe here
+ for (const auto& p : i_ports)
+ {
+ FAPI_TRY(mss::workarounds::fix_shadow_register_corruption(p));
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+#else
+ return fapi2::FAPI2_RC_SUCCESS;
+
+#endif
+}
+
+///
+/// @brief Determine the CCS failure type
+/// @param[in] i_target MCBIST target
+/// @param[in] i_type the failure type
+/// @param[in] i_port The port the CCS instruction is training
+/// @return ReturnCode associated with the fail.
+/// @note FFDC is handled here, caller doesn't need to do it
+///
+template<>
+fapi2::ReturnCode fail_type( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
+ const uint64_t i_type,
+ const fapi2::Target<TARGET_TYPE_MCA>& i_port )
+{
+ typedef ccsTraits<mss::mc_type::NIMBUS> TT;
+
+ fapi2::ReturnCode l_failing_rc(fapi2::FAPI2_RC_SUCCESS);
+ // Including the MCA_TARGET here and below at CAL_TIMEOUT since these problems likely lie at the MCA level
+ // So we disable the PORT and hopefully that's it
+ // If the problem lies with the MCBIST, it'll just have to loop
+ FAPI_ASSERT(TT::STAT_READ_MISCOMPARE != i_type,
+ fapi2::MSS_NIMBUS_CCS_READ_MISCOMPARE()
+ .set_MCBIST_TARGET(i_target)
+ .set_FAIL_TYPE(i_type)
+ .set_MCA_TARGET(i_port),
+ "%s CCS FAIL Read Miscompare", mss::c_str(i_port));
+
+ // This error is likely due to a bad CCS engine/ MCBIST
+ FAPI_ASSERT(TT::STAT_UE_SUE != i_type,
+ fapi2::MSS_NIMBUS_CCS_UE_SUE()
+ .set_FAIL_TYPE(i_type)
+ .set_MCBIST_TARGET(i_target),
+ "%s CCS FAIL UE or SUE Error", mss::c_str(i_target));
+
+ FAPI_ASSERT(TT::STAT_CAL_TIMEOUT != i_type,
+ fapi2::MSS_NIMBUS_CCS_CAL_TIMEOUT()
+ .set_FAIL_TYPE(i_type)
+ .set_MCBIST_TARGET(i_target)
+ .set_MCA_TARGET(i_port),
+ "%s CCS FAIL Calibration Operation Time Out", mss::c_str(i_port));
+
+ // Problem with the CCS engine
+ FAPI_ASSERT(TT::STAT_HUNG != i_type,
+ fapi2::MSS_NIMBUS_CCS_HUNG().set_MCBIST_TARGET(i_target),
+ "%s CCS appears hung", mss::c_str(i_target));
+fapi_try_exit:
+ // Due to the PRD update, we need to check for FIR's
+ // If any FIR's have lit up, this CCS fail could have been caused by the FIR
+ // So, let PRD retrigger this step to see if we can resolve the issue
+ return mss::check::fir_or_pll_fail<mss::mc_type::NIMBUS>(i_target, fapi2::current_err);
+}
+
+///
+/// @brief Create, initialize an instruction which indicates an initial cal
+/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
+/// @param[in] i_rp the rank-pair (rank) to cal
+/// @return the initial cal instruction
+///
+instruction_t initial_cal_command(const uint64_t i_rp)
+{
+ using TT = ccsTraits<mss::mc_type::NIMBUS>;
+
+ // An initial cal arr0 looks just like a DES, but we set the initial cal bits
+ instruction_t l_inst = des_command();
+
+ // ACT is low - per Centaur spec (Shelton to confirm for Nimbus) BRS
+ l_inst.arr0.template clearBit<TT::ARR0_DDR_ACTN>();
+
+ l_inst.arr0.template insertFromRight<TT::ARR0_DDR_CAL_TYPE, TT::ARR0_DDR_CAL_TYPE_LEN>(0b1100);
+ l_inst.arr1.template setBit<TT::ARR1_DDR_CALIBRATION_ENABLE>();
+
+#ifdef USE_LOTS_OF_IDLES
+ // Idles is 0xFFFF - per Centaur spec (Shelton to confirm for Nimbus) BRS
+ l_inst.arr1.template insertFromRight<TT::ARR1_IDLES, TT::ARR1_IDLES_LEN>(0xFFFF);
+#else
+ l_inst.arr1.template insertFromRight<TT::ARR1_IDLES, TT::ARR1_IDLES_LEN>(0x0);
+#endif
+
+ // The rank we're calibrating is enacoded - it's an int. So rank 3 is 0011 not 0001
+ l_inst.arr1.template insertFromRight<TT::ARR1_DDR_CAL_RANK, TT::ARR1_DDR_CAL_RANK_LEN>(i_rp);
+
+ return l_inst;
+}
+
+///
+/// @brief Nimbus specialization for modeq_copy_cke_to_spare_cke
+/// @param[in] fapi2::Target<TARGET_TYPE_MCBIST>& the target to effect
+/// @param[in,out] the buffer representing the mode register
+/// @param[in] mss::states - mss::ON iff Copy CKE signals to CKE Spare on both ports
+/// @note no-op for p9n
+///
+template<>
+void copy_cke_to_spare_cke<TARGET_TYPE_MCBIST>( const fapi2::Target<TARGET_TYPE_MCBIST>&,
+ fapi2::buffer<uint64_t>&, states )
+{
+ return;
+}
+
+///
+/// @brief Updates the initial delays based upon the total delays passed in - Nimbus specialization
+/// @param[in] i_target the target type on which to operate
+/// @param[in] i_delay the calculated delays from CCS
+/// @param[in,out] io_program the program for which to update the delays
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template<>
+fapi2::ReturnCode update_initial_delays<fapi2::TARGET_TYPE_MCBIST, mss::mc_type::NIMBUS>
+( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const uint64_t i_delay,
+ ccs::program& io_program)
+{
+ // Check our program for any delays. If there isn't a iv_initial_delay configured, then
+ // we use the delay we just summed from the instructions.
+ if (io_program.iv_poll.iv_initial_delay == 0)
+ {
+ io_program.iv_poll.iv_initial_delay = cycles_to_ns(i_target, i_delay);
+ }
+
+ if (io_program.iv_poll.iv_initial_sim_delay == 0)
+ {
+ io_program.iv_poll.iv_initial_sim_delay = cycles_to_simcycles(i_delay);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+} // namespace ccs
+} // namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_nimbus.H b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_nimbus.H
new file mode 100644
index 000000000..ec0a73dc7
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_nimbus.H
@@ -0,0 +1,58 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_nimbus.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file ccs_nimbus.C
+/// @brief Run and manage the CCS engine
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_CCS_NIMBUS_H_
+#define _MSS_CCS_NIMBUS_H_
+
+#include <fapi2.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
+
+namespace mss
+{
+namespace ccs
+{
+
+///
+/// @brief Create, initialize an instruction which indicates an initial cal
+/// @param[in] i_rp the rank-pair (rank) to cal
+/// @return the initial cal instruction
+///
+instruction_t initial_cal_command(const uint64_t i_rp);
+
+} // namespace ccs
+} // namespace mss
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_traits_nimbus.H b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_traits_nimbus.H
new file mode 100644
index 000000000..c3b93cd5d
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_traits_nimbus.H
@@ -0,0 +1,274 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs_traits_nimbus.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file ccs_traits_nimbus.H
+/// @brief Run and manage the CCS engine
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_CCS_TRAITS_NIMBUS_H_
+#define _MSS_CCS_TRAITS_NIMBUS_H_
+
+#include <fapi2.H>
+#include <p9_mc_scom_addresses.H>
+#include <p9_mc_scom_addresses_fld.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <lib/shared/mss_const.H>
+#include <lib/mss_attribute_accessors.H>
+#include <generic/memory/lib/ccs/ccs_traits.H>
+
+///
+/// @class ccsTraits
+/// @brief Nimbus CCS Engine traits
+///
+template<>
+class ccsTraits<mss::mc_type::NIMBUS>
+{
+ public:
+ static constexpr fapi2::TargetType PORT_TARGET_TYPE = fapi2::TARGET_TYPE_MCA;
+ static constexpr uint64_t MODEQ_REG = MCBIST_CCS_MODEQ;
+ static constexpr uint64_t MCB_CNTL_REG = MCBIST_MCB_CNTLQ;
+ static constexpr uint64_t CNTLQ_REG = MCBIST_CCS_CNTLQ;
+ static constexpr uint64_t STATQ_REG = MCBIST_CCS_STATQ;
+
+ static constexpr uint64_t PORTS_PER_MC_TARGET = mss::PORTS_PER_MCBIST;
+ static constexpr uint64_t CCS_MAX_DIMM_PER_PORT = mss::MAX_DIMM_PER_PORT;
+ static constexpr uint64_t CCS_MAX_MRANK_PER_PORT = mss::MAX_MRANK_PER_PORT;
+ static constexpr uint64_t CCS_MAX_RANK_PER_DIMM = mss::MAX_RANK_PER_DIMM;
+ static constexpr uint64_t CCS_MAX_RANKS_DIMM1 = mss::MAX_RANKS_DIMM1;
+
+ static constexpr uint64_t NTTM_READ_DELAY = 0x40;
+ static constexpr uint64_t NTTM_MODE_FORCE_READ = 33;
+
+
+ // Command Pass Disable Delay Time for Nimbus
+ static constexpr uint64_t TIMING_TCPDED = 4;
+
+ enum
+ {
+ // Non address values that are needed for helper functions
+
+ // ODT values used for beautification
+ // Attribute locations
+ ATTR_ODT_DIMM0_R0 = 0,
+ ATTR_ODT_DIMM0_R1 = 1,
+ ATTR_ODT_DIMM1_R0 = 4,
+ ATTR_ODT_DIMM1_R1 = 5,
+
+ // Right justified output - makes it so we can use insertFromRight
+ CCS_ODT_DIMM0_R0 = 4,
+ CCS_ODT_DIMM0_R1 = 5,
+ CCS_ODT_DIMM1_R0 = 6,
+ CCS_ODT_DIMM1_R1 = 7,
+
+ // Default ODT cycle length is 5 - one for the preamble and 4 for the data
+ DEFAULT_ODT_CYCLE_LEN = 5,
+
+ // CCS MODEQ
+ STOP_ON_ERR = MCBIST_CCS_MODEQ_STOP_ON_ERR,
+ UE_DISABLE = MCBIST_CCS_MODEQ_UE_DISABLE,
+ DATA_COMPARE_BURST_SEL = MCBIST_CCS_MODEQ_DATA_COMPARE_BURST_SEL,
+ DATA_COMPARE_BURST_SEL_LEN = MCBIST_CCS_MODEQ_DATA_COMPARE_BURST_SEL_LEN,
+ DDR_CAL_TIMEOUT_CNT = MCBIST_CCS_MODEQ_DDR_CAL_TIMEOUT_CNT,
+ DDR_CAL_TIMEOUT_CNT_LEN = MCBIST_CCS_MODEQ_DDR_CAL_TIMEOUT_CNT_LEN,
+ CFG_PARITY_AFTER_CMD = MCBIST_CCS_MODEQ_CFG_PARITY_AFTER_CMD,
+ COPY_CKE_TO_SPARE_CKE = MCBIST_CCS_MODEQ_COPY_CKE_TO_SPARE_CKE,
+ DISABLE_ECC_ARRAY_CHK = MCBIST_CCS_MODEQ_DISABLE_ECC_ARRAY_CHK,
+ DISABLE_ECC_ARRAY_CORRECTION = MCBIST_CCS_MODEQ_DISABLE_ECC_ARRAY_CORRECTION,
+ CFG_DGEN_FIXED_MODE = MCBIST_CCS_MODEQ_CFG_DGEN_FIXED_MODE,
+ DDR_CAL_TIMEOUT_CNT_MULT = MCBIST_CCS_MODEQ_DDR_CAL_TIMEOUT_CNT_MULT,
+ DDR_CAL_TIMEOUT_CNT_MULT_LEN = MCBIST_CCS_MODEQ_DDR_CAL_TIMEOUT_CNT_MULT_LEN,
+ IDLE_PAT_ADDRESS_0_13 = MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_0_13,
+ IDLE_PAT_ADDRESS_0_13_LEN = MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_0_13_LEN,
+ IDLE_PAT_ADDRESS_17 = MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_17,
+ IDLE_PAT_BANK_GROUP_1 = MCBIST_CCS_MODEQ_IDLE_PAT_BANK_GROUP_1,
+ IDLE_PAT_BANK_0_1 = MCBIST_CCS_MODEQ_IDLE_PAT_BANK_0_1,
+ IDLE_PAT_BANK_0_1_LEN = MCBIST_CCS_MODEQ_IDLE_PAT_BANK_0_1_LEN,
+ IDLE_PAT_BANK_GROUP_0 = MCBIST_CCS_MODEQ_IDLE_PAT_BANK_GROUP_0,
+ IDLE_PAT_ACTN = MCBIST_CCS_MODEQ_IDLE_PAT_ACTN,
+ IDLE_PAT_ADDRESS_16 = MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_16,
+ IDLE_PAT_ADDRESS_15 = MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_15,
+ IDLE_PAT_ADDRESS_14 = MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_14,
+ NTTM_MODE = MCBIST_CCS_MODEQ_NTTM_MODE,
+ NTTM_RW_DATA_DLY = MCBIST_CCS_MODEQ_NTTM_RW_DATA_DLY,
+ NTTM_RW_DATA_DLY_LEN = MCBIST_CCS_MODEQ_NTTM_RW_DATA_DLY_LEN,
+ IDLE_PAT_BANK_2 = MCBIST_CCS_MODEQ_IDLE_PAT_BANK_2,
+ DDR_PARITY_ENABLE = MCBIST_CCS_MODEQ_DDR_PARITY_ENABLE,
+ IDLE_PAT_PARITY = MCBIST_CCS_MODEQ_IDLE_PAT_PARITY,
+
+ // MCB_CNTRL
+ MCB_CNTL_PORT_SEL = MCBIST_MCB_CNTLQ_MCBCNTL_PORT_SEL,
+ MCB_CNTL_PORT_SEL_LEN = MCBIST_MCB_CNTLQ_MCBCNTL_PORT_SEL_LEN,
+
+ // CCS CNTL
+ CCS_START = MCBIST_CCS_CNTLQ_START,
+ CCS_STOP = MCBIST_CCS_CNTLQ_STOP,
+
+ // CCS STATQ
+ CCS_IN_PROGRESS = MCBIST_CCS_STATQ_IP,
+
+ // ARR0
+ ARR0_DDR_ADDRESS_0_13 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13,
+ ARR0_DDR_ADDRESS_0_13_LEN = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13_LEN,
+ ARR0_DDR_ADDRESS_0_9 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13, // Useful for rd/wr cmds
+ ARR0_DDR_ADDRESS_0_9_LEN = 10, // CA bits are 9:0, total length of 10
+ ARR0_DDR_ADDRESS_10 = 10, // ADR10 is the 10th bit from the left in Nimbus ARR0
+ ARR0_DDR_ADDRESS_17 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_17,
+ ARR0_DDR_BANK_GROUP_1 = MCBIST_CCS_INST_ARR0_00_DDR_BANK_GROUP_1,
+ ARR0_DDR_RESETN = MCBIST_CCS_INST_ARR0_00_DDR_RESETN,
+ ARR0_DDR_BANK_0_1 = MCBIST_CCS_INST_ARR0_00_DDR_BANK_0_1,
+ ARR0_DDR_BANK_0_1_LEN = MCBIST_CCS_INST_ARR0_00_DDR_BANK_0_1_LEN,
+ ARR0_DDR_BANK_GROUP_0 = MCBIST_CCS_INST_ARR0_00_DDR_BANK_GROUP_0,
+ ARR0_DDR_ACTN = MCBIST_CCS_INST_ARR0_00_DDR_ACTN,
+ ARR0_DDR_ADDRESS_16 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_16,
+ ARR0_DDR_ADDRESS_15 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_15,
+ ARR0_DDR_ADDRESS_14 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_14,
+ ARR0_DDR_CKE = MCBIST_CCS_INST_ARR0_00_DDR_CKE,
+ ARR0_DDR_CKE_LEN = MCBIST_CCS_INST_ARR0_00_DDR_CKE_LEN,
+ ARR0_DDR_CSN_0_1 = MCBIST_CCS_INST_ARR0_00_DDR_CSN_0_1,
+ ARR0_DDR_CSN_0_1_LEN = MCBIST_CCS_INST_ARR0_00_DDR_CSN_0_1_LEN,
+ ARR0_DDR_CID_0_1 = MCBIST_CCS_INST_ARR0_00_DDR_CID_0_1,
+ ARR0_DDR_CID_0_1_LEN = MCBIST_CCS_INST_ARR0_00_DDR_CID_0_1_LEN,
+ ARR0_DDR_CSN_2_3 = MCBIST_CCS_INST_ARR0_00_DDR_CSN_2_3,
+ ARR0_DDR_CSN_2_3_LEN = MCBIST_CCS_INST_ARR0_00_DDR_CSN_2_3_LEN,
+ ARR0_DDR_CID_2 = MCBIST_CCS_INST_ARR0_00_DDR_CID_2,
+ ARR0_DDR_ODT = MCBIST_CCS_INST_ARR0_00_DDR_ODT,
+ ARR0_DDR_ODT_LEN = MCBIST_CCS_INST_ARR0_00_DDR_ODT_LEN,
+ ARR0_DDR_CAL_TYPE = MCBIST_CCS_INST_ARR0_00_DDR_CAL_TYPE,
+ ARR0_DDR_CAL_TYPE_LEN = MCBIST_CCS_INST_ARR0_00_DDR_CAL_TYPE_LEN,
+ ARR0_DDR_PARITY = MCBIST_CCS_INST_ARR0_00_DDR_PARITY,
+ ARR0_DDR_BANK_2 = MCBIST_CCS_INST_ARR0_00_DDR_BANK_2,
+ ARR0_LOOP_BREAK_MODE = MCBIST_CCS_INST_ARR0_00_LOOP_BREAK_MODE,
+ ARR0_LOOP_BREAK_MODE_LEN = MCBIST_CCS_INST_ARR0_00_LOOP_BREAK_MODE_LEN,
+
+ // ARR1
+ ARR1_IDLES = MCBIST_CCS_INST_ARR1_00_IDLES,
+ ARR1_IDLES_LEN = MCBIST_CCS_INST_ARR1_00_IDLES_LEN,
+ ARR1_REPEAT_CMD_CNT = MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT,
+ ARR1_REPEAT_CMD_CNT_LEN = MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT_LEN,
+ ARR1_READ_OR_WRITE_DATA = MCBIST_CCS_INST_ARR1_00_READ_OR_WRITE_DATA,
+ ARR1_READ_OR_WRITE_DATA_LEN = MCBIST_CCS_INST_ARR1_00_READ_OR_WRITE_DATA_LEN,
+ ARR1_READ_COMPARE_REQUIRED = MCBIST_CCS_INST_ARR1_00_READ_COMPARE_REQUIRED,
+ ARR1_DDR_CAL_RANK = MCBIST_CCS_INST_ARR1_00_DDR_CAL_RANK,
+ ARR1_DDR_CAL_RANK_LEN = MCBIST_CCS_INST_ARR1_00_DDR_CAL_RANK_LEN,
+ ARR1_DDR_CALIBRATION_ENABLE = MCBIST_CCS_INST_ARR1_00_DDR_CALIBRATION_ENABLE,
+ ARR1_END = MCBIST_CCS_INST_ARR1_00_END,
+ ARR1_GOTO_CMD = MCBIST_CCS_INST_ARR1_00_GOTO_CMD,
+ ARR1_GOTO_CMD_LEN = MCBIST_CCS_INST_ARR1_00_GOTO_CMD_LEN,
+
+ // CCS array constants
+ CCS_ARRAY_LEN = 32,
+ CCS_ARR0_START = MCBIST_CCS_INST_ARR0_00,
+ CCS_ARR1_START = MCBIST_CCS_INST_ARR1_00,
+ };
+
+ ///
+ /// @brief Enums for CCS return codes
+ ///
+ enum
+ {
+ // Success is defined as done-bit set, no others.
+ STAT_QUERY_SUCCESS = 0x4000000000000000,
+
+ // Bit positions 3:5
+ STAT_ERR_MASK = 0x1C00000000000000,
+ STAT_READ_MISCOMPARE = 0x1000000000000000,
+ STAT_UE_SUE = 0x0800000000000000,
+ STAT_CAL_TIMEOUT = 0x0400000000000000,
+
+ // If the fail type isn't one of these, we're hung
+ STAT_HUNG = 0x0ull,
+ };
+
+
+ // CSN Regular Settings
+ static constexpr std::pair<uint64_t, uint64_t> CS_N[mss::MAX_RANK_PER_DIMM] =
+ {
+ // CS0 L, CS1 H, CID0-> L => Rank 0
+ { 0b01, 0b00 },
+
+ // CS0 L, CS1 H, CID0-> H => Rank 1
+ { 0b01, 0b11 },
+
+ // CS0 H, CS1 L, CID0-> L => Rank 2
+ { 0b10, 0b00 },
+
+ // CS0 H, CS1 L, CID0-> H => Rank 3
+ { 0b10, 0b11 },
+ };
+
+
+ // CSN Setup for Dual Direct Mode
+ // For DIMM0 .first is the CSN_0_1 setting, .second is the CSN_2_3 setting.
+ // For DIMM1 .first is the CSN_2_3 setting, .second is the CSN_0_1 setting.
+ static constexpr std::pair<uint64_t, uint64_t> CS_ND[mss::MAX_RANK_PER_DIMM] =
+ {
+ // CS0 L CS1 H => CS2 => H CS3 => H Rank 0
+ { 0b01, 0b11 },
+
+ // CS0 H CS1 L => CS2 => H CS3 => H Rank 1
+ { 0b10, 0b11 },
+
+ // CS0 H CS1 H => CS2 => L CS3 => H Rank 2
+ { 0b11, 0b01 },
+
+ // CS0 H CS1 H => CS2 => H CS3 => L Rank 3
+ { 0b11, 0b10 },
+ };
+
+ ///
+ /// @brief Gets the attribute for checking our rank configuration
+ /// @param[in] i_target the port target on which to operate
+ /// @param[out] o_ranks the rank data
+ /// @return SUCCESS iff the code executes successfully
+ ///
+ static fapi2::ReturnCode get_rank_config_attr(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ uint8_t (&o_array)[2])
+ {
+ return mss::eff_num_master_ranks_per_dimm(i_target, o_array);
+ }
+
+ ///
+ /// @brief Gets the attribute for checking our rank configuration
+ /// @param[in] i_target the port target on which to operate
+ /// @param[out] o_ranks the rank data
+ /// @return The fully setup nimbus error
+ ///
+ static fapi2::MSS_CCS_HUNG_TRYING_TO_STOP setup_trying_to_stop_err(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>&
+ i_target)
+ {
+ return fapi2::MSS_CCS_HUNG_TRYING_TO_STOP().set_MCBIST_TARGET(i_target);
+ }
+
+ // Lab values
+ static constexpr uint64_t LAB_MRS_CMD = 0x000008F000000000;
+};
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load.C
index ae62be201..1b42026a4 100755
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -34,10 +34,15 @@
// *HWP Consumed by: FSP:HB
#include <fapi2.H>
-
#include <mss.H>
+#include <lib/shared/nimbus_defaults.H>
+#include <lib/shared/mss_const.H>
+
#include <lib/dimm/bcw_load.H>
#include <lib/dimm/bcw_load_ddr4.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
+
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
@@ -58,7 +63,7 @@ template<>
fapi2::ReturnCode bcw_load<TARGET_TYPE_MCBIST>( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
{
// A vector of CCS instructions. We'll ask the targets to fill it, and then we'll execute it
- ccs::program<TARGET_TYPE_MCBIST> l_program;
+ ccs::program l_program;
// Clear the initial delays. This will force the CCS engine to recompute the delay based on the
// instructions in the CCS instruction vector
@@ -91,7 +96,7 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode perform_bcw_load<DEFAULT_KIND>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
uint8_t l_type = 0;
uint8_t l_gen = 0;
@@ -121,7 +126,7 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode perform_bcw_load<KIND_LRDIMM_DDR4>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
FAPI_DBG("perform bcw_load for %s [expecting lrdimm (ddr4)]", mss::c_str(i_target));
FAPI_TRY( bcw_load_ddr4(i_target, io_inst), "Failed bcw load for lrdimm %s", mss::c_str(i_target));
@@ -138,7 +143,7 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode perform_bcw_load<KIND_RDIMM_DDR4>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
FAPI_INF("Skipping BCW loading for %s since this is valid only for LRDIMMs", mss::c_str(i_target));
return fapi2::FAPI2_RC_SUCCESS;
@@ -152,7 +157,7 @@ fapi2::ReturnCode perform_bcw_load<KIND_RDIMM_DDR4>( const fapi2::Target<TARGET_
///
template<>
fapi2::ReturnCode perform_bcw_load<FORCE_DISPATCH>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
uint8_t l_type = 0;
uint8_t l_gen = 0;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load.H
index be5f1bfc5..4bdfe0033 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,10 +39,14 @@
#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
+#include <lib/shared/mss_const.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
#include <generic/memory/lib/utils/c_str.H>
#include <lib/shared/mss_kind.H>
+
namespace mss
{
@@ -113,7 +117,7 @@ struct perform_bcw_load_overload< KIND_LRDIMM_DDR4 >
template< mss::kind_t K = FORCE_DISPATCH >
typename std::enable_if< perform_bcw_load_overload<DEFAULT_KIND>::available, fapi2::ReturnCode>::type
perform_bcw_load( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
//
// We know we registered overloads for perform_bcw_load, so we need the entry point to
@@ -129,7 +133,7 @@ perform_bcw_load( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
///
template<>
fapi2::ReturnCode perform_bcw_load<FORCE_DISPATCH>( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Perform the bcw_load operations (DEFAULT_KIND specialization)
@@ -139,7 +143,7 @@ fapi2::ReturnCode perform_bcw_load<FORCE_DISPATCH>( const fapi2::Target<fapi2::T
///
template<>
fapi2::ReturnCode perform_bcw_load<DEFAULT_KIND>( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
//
// Boilerplate dispatcher
@@ -157,7 +161,7 @@ fapi2::ReturnCode perform_bcw_load<DEFAULT_KIND>( const fapi2::Target<fapi2::TAR
template< kind_t K, bool B = perform_bcw_load_overload<K>::available >
inline fapi2::ReturnCode perform_bcw_load_dispatch( const kind_t& i_kind,
const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
// We dispatch to another kind if:
// We don't have an overload defined (B == false)
@@ -182,7 +186,7 @@ inline fapi2::ReturnCode perform_bcw_load_dispatch( const kind_t& i_kind,
template<>
inline fapi2::ReturnCode perform_bcw_load_dispatch<DEFAULT_KIND>(const kind_t&,
const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
return perform_bcw_load<DEFAULT_KIND>(i_target, io_inst);
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.C
index 266e7ce56..0712939f3 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.C
@@ -36,11 +36,13 @@
#include <lib/shared/nimbus_defaults.H>
#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
+#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/c_str.H>
#include <lib/utils/mss_nimbus_conversions.H>
#include <lib/eff_config/timing.H>
-#include <lib/ccs/ccs.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
#include <lib/dimm/bcw_load_ddr4.H>
#include <lib/dimm/ddr4/control_word_ddr4.H>
#include <lib/dimm/ddr4/data_buffer_ddr4.H>
@@ -48,6 +50,7 @@
#include <lib/workarounds/ccs_workarounds.H>
#include <generic/memory/lib/spd/spd_utils.H>
+
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCS;
@@ -67,10 +70,8 @@ namespace mss
/// @return FAPI2_RC_SUCCESS if and only if ok
///
fapi2::ReturnCode bcw_load_ddr4( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
- constexpr uint64_t SAFE_DELAY = 2000; // Waiting a safe amount of time as the LRDIMM spec
- // doesn't give us an explicit value for this delay
FAPI_INF("bcw_load_ddr4 %s", mss::c_str(i_target) );
uint8_t l_sim = 0;
@@ -104,21 +105,21 @@ fapi2::ReturnCode bcw_load_ddr4( const fapi2::Target<TARGET_TYPE_DIMM>& i_target
{ FUNC_SPACE_0, DQ_DRIVER_CW, eff_dimm_ddr4_bc03, mss::tmrc() , CW4_DATA_LEN, cw_info::BCW},
{ FUNC_SPACE_0, MDQ_RTT_CW, eff_dimm_ddr4_bc04, mss::tmrc() , CW4_DATA_LEN, cw_info::BCW},
{ FUNC_SPACE_0, MDQ_DRIVER_CW, eff_dimm_ddr4_bc05, mss::tmrc() , CW4_DATA_LEN, cw_info::BCW},
- { FUNC_SPACE_0, CMD_SPACE_CW, eff_dimm_ddr4_bc06, mss::tmrc() , CW4_DATA_LEN, cw_info::BCW},
- { FUNC_SPACE_0, RANK_PRESENCE_CW, eff_dimm_ddr4_bc07, mss::tmrc() , CW4_DATA_LEN, cw_info::BCW},
+ { FUNC_SPACE_0, CMD_SPACE_CW, eff_dimm_ddr4_bc06, BCW_SAFE_DELAY , CW4_DATA_LEN, cw_info::BCW}, // using tmrd_l2 causes an error - safe delay works
+ { FUNC_SPACE_0, RANK_PRESENCE_CW, eff_dimm_ddr4_bc07, BCW_SAFE_DELAY , CW4_DATA_LEN, cw_info::BCW}, // using tmrd_l2 causes an error - safe delay works
{ FUNC_SPACE_0, RANK_SELECTION_CW, eff_dimm_ddr4_bc08, mss::tmrc() , CW4_DATA_LEN, cw_info::BCW},
{ FUNC_SPACE_0, POWER_SAVING_CW, eff_dimm_ddr4_bc09, mss::tmrc() , CW4_DATA_LEN, cw_info::BCW},
{ FUNC_SPACE_0, OPERATING_SPEED, eff_dimm_ddr4_bc0a, l_tDLLK , CW4_DATA_LEN, cw_info::BCW},
{ FUNC_SPACE_0, VOLT_AND_SLEW_RATE_CW, eff_dimm_ddr4_bc0b, mss::tmrc() , CW4_DATA_LEN, cw_info::BCW},
- { FUNC_SPACE_0, BUFF_TRAIN_MODE_CW, eff_dimm_ddr4_bc0c, mss::tmrc() , CW4_DATA_LEN, cw_info::BCW},
+ { FUNC_SPACE_0, BUFF_TRAIN_MODE_CW, eff_dimm_ddr4_bc0c, mss::tmrd_l2() , CW4_DATA_LEN, cw_info::BCW},
{ FUNC_SPACE_0, LDQ_OPERATION_CW, eff_dimm_ddr4_bc0d, mss::tmrc() , CW4_DATA_LEN, cw_info::BCW},
{ FUNC_SPACE_0, PARITY_CW, eff_dimm_ddr4_bc0e, mss::tmrc() , CW4_DATA_LEN, cw_info::BCW},
{ FUNC_SPACE_0, ERROR_STATUS_CW, eff_dimm_ddr4_bc0f, mss::tmrc() , CW4_DATA_LEN, cw_info::BCW},
// 8-bit BCW's now
// Function space 0 - we're already there, so that's nice
- { FUNC_SPACE_0, BUFF_CONFIG_CW, eff_dimm_ddr4_f0bc1x, mss::tmrc(), CW8_DATA_LEN, cw_info::BCW},
- { FUNC_SPACE_0, LRDIMM_OPERATING_SPEED, eff_dimm_ddr4_f0bc6x, SAFE_DELAY, CW8_DATA_LEN, cw_info::BCW},
+ { FUNC_SPACE_0, BUFF_CONFIG_CW, eff_dimm_ddr4_f0bc1x, mss::tmrd_l2() , CW8_DATA_LEN, cw_info::BCW},
+ { FUNC_SPACE_0, LRDIMM_OPERATING_SPEED, eff_dimm_ddr4_f0bc6x, BCW_SAFE_DELAY, CW8_DATA_LEN, cw_info::BCW},
// Function space 2
{ FUNC_SPACE_2, FUNC_SPACE_SELECT_CW, FUNC_SPACE_2, mss::tmrd(), CW8_DATA_LEN, cw_info::BCW},
@@ -126,8 +127,8 @@ fapi2::ReturnCode bcw_load_ddr4( const fapi2::Target<TARGET_TYPE_DIMM>& i_target
// Function space 5
{ FUNC_SPACE_5, FUNC_SPACE_SELECT_CW, FUNC_SPACE_5, mss::tmrd(), CW8_DATA_LEN, cw_info::BCW},
- { FUNC_SPACE_5, HOST_VREF_CW, eff_dimm_ddr4_f5bc5x, SAFE_DELAY, CW8_DATA_LEN, cw_info::BCW},
- { FUNC_SPACE_5, DRAM_VREF_CW, eff_dimm_ddr4_f5bc6x, SAFE_DELAY, CW8_DATA_LEN, cw_info::BCW},
+ { FUNC_SPACE_5, HOST_VREF_CW, eff_dimm_ddr4_f5bc5x, BCW_SAFE_DELAY, CW8_DATA_LEN, cw_info::BCW},
+ { FUNC_SPACE_5, DRAM_VREF_CW, eff_dimm_ddr4_f5bc6x, BCW_SAFE_DELAY, CW8_DATA_LEN, cw_info::BCW},
// Function space 6
{ FUNC_SPACE_6, FUNC_SPACE_SELECT_CW, FUNC_SPACE_6, mss::tmrd(), CW8_DATA_LEN, cw_info::BCW},
@@ -142,7 +143,7 @@ fapi2::ReturnCode bcw_load_ddr4( const fapi2::Target<TARGET_TYPE_DIMM>& i_target
};
// DES first - make sure those CKE go high and stay there
- io_inst.push_back(mss::ccs::des_command<TARGET_TYPE_MCBIST>());
+ io_inst.push_back(mss::ccs::des_command());
// Issues the CW's
FAPI_TRY( control_word_engine(i_target, l_bcw_info, l_sim, io_inst),
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.H
index 7e68d32d0..31ef02983 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,7 +38,9 @@
#include <fapi2.H>
#include <vector>
-#include <lib/ccs/ccs.H>
+#include <lib/shared/mss_const.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
namespace mss
{
@@ -51,6 +53,6 @@ namespace mss
/// @return FAPI2_RC_SUCCESS if and only if ok
///
fapi2::ReturnCode bcw_load_ddr4( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
}
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/control_word_ddr4.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/control_word_ddr4.H
index ab28d5b82..60b3c077b 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/control_word_ddr4.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/control_word_ddr4.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,9 +40,10 @@
#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
-
+#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <lib/ccs/ccs.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
namespace mss
{
@@ -276,7 +277,6 @@ struct cw_data
/// @brief Control word engine that sets the CCS instruction
/// @tparam T the buffer control word type (4 bit or 8 bit)
/// @tparam TT traits type defaults to cwTraits<T>
-/// @tparam OT the TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_data control word data to send
/// @param[in] i_sim true if in simulation mode
@@ -284,12 +284,12 @@ struct cw_data
/// @param[out] o_instruction CCS instruction we created
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< control_word T, typename TT = cwTraits<T>, fapi2::TargetType OT >
+template< control_word T, typename TT = cwTraits<T> >
fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const cw_data& i_data,
const bool i_sim,
const bool i_turn_on_cke,
- ccs::instruction_t<OT>& o_instruction)
+ ccs::instruction_t& o_instruction)
{
// You're probably asking "Why always turn off CKE's? What is this madness?"
// Well, due to a vendor sensitivity, we need to have the CKE's off until we run RC09 at the very end
@@ -298,7 +298,7 @@ fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIM
// Therefore, we want to setup all RCW commands to have CKE's off across both DIMM's
// We then manually turn on the CKE's associated with a specific DIMM
constexpr bool CKE_OFF = false;
- ccs::instruction_t<OT> l_inst = ccs::rcd_command<OT>(i_target, i_sim, CKE_OFF);
+ ccs::instruction_t l_inst = ccs::rcd_command(i_target, i_sim, CKE_OFF);
// Turn on the CKE's for the ranks we're not touching, if it's needed
// Note: we only have the whole CKE field, not the per DIMM one by default
@@ -359,7 +359,6 @@ fapi_try_exit:
/// @brief Control word engine that sets the CCS instruction
/// @tparam T the buffer control word type (4 bit or 8 bit)
/// @tparam TT traits type defaults to cwTraits<T>
-/// @tparam OT the TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_data control word data to send
/// @param[in] i_sim true if in simulation mode
@@ -367,14 +366,14 @@ fapi_try_exit:
/// @param[in] i_turn_on_cke flag that states whether we want CKE on for this RCW (defaulted to true)
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< control_word T, typename TT = cwTraits<T>, fapi2::TargetType OT >
+template< control_word T, typename TT = cwTraits<T> >
fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const cw_data& i_data,
const bool i_sim,
- std::vector< ccs::instruction_t<OT> >& io_inst,
+ std::vector< ccs::instruction_t >& io_inst,
const bool i_turn_on_cke = true)
{
- ccs::instruction_t<OT> l_inst;
+ ccs::instruction_t l_inst;
FAPI_TRY(control_word_engine<T>(i_target, i_data, i_sim, i_turn_on_cke, l_inst));
io_inst.push_back(l_inst);
@@ -386,7 +385,6 @@ fapi_try_exit:
/// @brief Control word engine that sets the CCS instruction
/// @tparam T the buffer control word type (4 bit or 8 bit)
/// @tparam TT traits type defaults to cwTraits<T>
-/// @tparam OT the TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_data_list a vector of control word data to send
/// @param[in] i_sim true if in simulation mode
@@ -394,11 +392,11 @@ fapi_try_exit:
/// @param[in] i_turn_on_cke flag that states whether we want CKE on for all RCWs in the vector (defaulted to true)
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< control_word T, typename TT = cwTraits<T>, fapi2::TargetType OT >
+template< control_word T, typename TT = cwTraits<T> >
fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const std::vector<cw_data>& i_data_list,
const bool i_sim,
- std::vector< ccs::instruction_t<OT> >& io_inst,
+ std::vector< ccs::instruction_t >& io_inst,
const bool i_turn_on_cke = true)
{
FAPI_ASSERT( !i_data_list.empty(),
@@ -495,7 +493,6 @@ struct cw_info
///
/// @brief Control word engine that sets the CCS instruction
-/// @tparam OT the TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_info control word data and information about how to send it
/// @param[in] i_sim true if in simulation mode
@@ -503,12 +500,11 @@ struct cw_info
/// @param[out] o_instruction CCS instruction we created
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType OT >
-fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const cw_info& i_info,
- const bool i_sim,
- const bool i_turn_on_cke,
- ccs::instruction_t<OT>& o_instruction)
+inline fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const cw_info& i_info,
+ const bool i_sim,
+ const bool i_turn_on_cke,
+ ccs::instruction_t& o_instruction)
{
// BCW 4-bit
if(i_info.iv_is_bcw && i_info.iv_data_len == CW4_DATA_LEN)
@@ -548,7 +544,6 @@ fapi_try_exit:
///
/// @brief Control word engine that sets the CCS instruction
-/// @tparam OT the TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_info_list a vector of control word data to send
/// @param[in] i_sim true if in simulation mode
@@ -556,12 +551,11 @@ fapi_try_exit:
/// @param[in] i_turn_on_cke flag that states whether we want CKE on for all RCWs in the vector (defaulted to true)
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType OT >
-fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<cw_info>& i_info_list,
- const bool i_sim,
- std::vector< ccs::instruction_t<OT> >& io_inst,
- const bool i_turn_on_cke = true)
+inline fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<cw_info>& i_info_list,
+ const bool i_sim,
+ std::vector< ccs::instruction_t >& io_inst,
+ const bool i_turn_on_cke = true)
{
FAPI_ASSERT( !i_info_list.empty(),
fapi2::MSS_EMPTY_VECTOR().
@@ -571,7 +565,7 @@ fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIM
for (const auto& l_info : i_info_list)
{
- ccs::instruction_t<OT> l_inst;
+ ccs::instruction_t l_inst;
FAPI_TRY( control_word_engine(i_target, l_info, i_sim, i_turn_on_cke, l_inst) );
io_inst.push_back(l_inst);
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H
index d2bffc509..8cdb81f55 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H
@@ -44,6 +44,9 @@
#include <lib/phy/dp16.H>
#include <lib/dimm/ddr4/control_word_ddr4.H>
#include <lib/eff_config/timing.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
+
namespace mss
{
@@ -96,6 +99,9 @@ enum db02_def : size_t
HOST_VREF_CW = 0x5, // Func space 5
DRAM_VREF_CW = 0x6, // Func space 5
BUFF_TRAIN_CONFIG_CW = 0x4, // Func space 6
+
+ // Safe delays for BCW's
+ BCW_SAFE_DELAY = 2000,
};
namespace ddr4
@@ -132,7 +138,7 @@ enum command : size_t
///
inline fapi2::ReturnCode function_space_select(const fapi2::Target< fapi2::TARGET_TYPE_DIMM >& i_target,
const uint64_t i_func_space,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
FAPI_ASSERT(i_func_space <= MAX_FUNC_SPACE,
fapi2::MSS_LRDIMM_FUNC_SPACE_OUT_OF_RANGE()
@@ -243,13 +249,13 @@ fapi_try_exit:
template< mss::control_word T >
static fapi2::ReturnCode settings_boilerplate(const fapi2::Target< fapi2::TARGET_TYPE_DIMM >& i_target,
const cw_data& i_data,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
uint8_t l_sim = 0;
mss::is_simulation(l_sim);
// DES first - make sure those CKE go high and stay there
- io_inst.push_back(mss::ccs::des_command<fapi2::TARGET_TYPE_MCBIST>());
+ io_inst.push_back(mss::ccs::des_command());
FAPI_TRY( function_space_select(i_target, i_data.iv_func_space, io_inst),
"%s. Failed to select function space %d",
@@ -271,17 +277,15 @@ fapi_try_exit:
///
/// @brief Sets data buffer training mode control word
-/// @tparam T TargetType of the CCS instruction
/// @param[in] i_target the DIMM target
/// @param[in] i_mode buffer training mode
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff ok
/// @note Sets buffer control word (BC0C) setting
///
-template< fapi2::TargetType T >
inline fapi2::ReturnCode set_buffer_training( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const training i_mode,
- std::vector< ccs::instruction_t<T> >& io_inst )
+ std::vector< ccs::instruction_t >& io_inst )
{
// This doesn't need to be reused so it is left local to this function scope
static const std::vector< std::pair<training, uint64_t> > BUFF_TRAINING =
@@ -302,7 +306,7 @@ inline fapi2::ReturnCode set_buffer_training( const fapi2::Target<fapi2::TARGET_
uint64_t l_encoding = 0;
fapi2::Assert(find_value_from_key(BUFF_TRAINING, i_mode, l_encoding));
- cw_data l_data(FUNC_SPACE_0, BUFF_TRAIN_MODE_CW, l_encoding, mss::tmrc());
+ cw_data l_data(FUNC_SPACE_0, BUFF_TRAIN_MODE_CW, l_encoding, mss::tmrd_l2());
FAPI_TRY( settings_boilerplate<BCW_4BIT>(i_target, l_data, io_inst) );
fapi_try_exit:
@@ -362,17 +366,15 @@ fapi_try_exit:
///
/// @brief Sets rank presence control word
-/// @tparam T TargetType of the CCS instruction
/// @param[in] i_target the DIMM target
/// @param[in] i_num_package_ranks num of package ranks for LRDIMM
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff ok
/// @note Sets buffer control word (BC07) setting
///
-template< fapi2::TargetType T>
inline fapi2::ReturnCode set_rank_presence( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const uint64_t i_num_package_ranks,
- std::vector< ccs::instruction_t<T> >& io_inst )
+ std::vector< ccs::instruction_t >& io_inst )
{
// Helper function handles error checking
uint64_t l_encoding = 0;
@@ -391,7 +393,6 @@ fapi_try_exit:
///
/// @brief Sets Upper/Lower nibble DRAM interface receive enable training control word
/// @tparam T the nibble of in training (upper/lower)
-/// @tparam OT TargetType of the CCS instruction
/// @param[in] i_target the DIMM target
/// @param[in] i_rank DIMM0 rank [0:3] or DIMM1 rank [4:7]
/// @param[in] i_trained_timing the delay MDQS receive enable timing
@@ -399,11 +400,11 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff ok
/// @note Sets buffer control word ( F[3:0]BC2x ) setting
///
-template< mss::nibble N, fapi2::TargetType OT>
+template< mss::nibble N >
fapi2::ReturnCode set_mrep_timing_control( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
const uint64_t i_trained_timing,
- std::vector< ccs::instruction_t<OT> >& io_inst )
+ std::vector< ccs::instruction_t >& io_inst )
{
constexpr size_t MAX_DELAY = 63;
@@ -430,17 +431,15 @@ fapi_try_exit:
///
/// @brief Sets command space control word
-/// @tparam T TargetType of the CCS instruction
/// @param[in] i_target the DIMM target
/// @param[in] i_command command name
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff ok
/// @note Sets buffer control word (BC06) setting
///
-template< fapi2::TargetType T>
inline fapi2::ReturnCode set_command_space( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const command i_command,
- std::vector< ccs::instruction_t<T> >& io_inst )
+ std::vector< ccs::instruction_t >& io_inst )
{
constexpr uint64_t MAX_VALID_CMD = 4;
@@ -453,9 +452,8 @@ inline fapi2::ReturnCode set_command_space( const fapi2::Target<fapi2::TARGET_TY
}
// From the DDR4DB02 Spec: BC06 - Command Space Control Word
- // After issuing a data buffer command via writes to BC06 waiting for tMRC(16 tCK)
- // is required before the next DRAM command or BCW write can be issued.
- cw_data l_data(FUNC_SPACE_0, CMD_SPACE_CW, i_command, mss::tmrc());
+ // Waiting safe delay here as we've seen issues in the lab where the required tMRD_l2 isn't sufficient
+ cw_data l_data(FUNC_SPACE_0, CMD_SPACE_CW, i_command, BCW_SAFE_DELAY);
FAPI_TRY( settings_boilerplate<BCW_4BIT>(i_target, l_data, io_inst) );
fapi_try_exit:
@@ -464,17 +462,15 @@ fapi_try_exit:
///
/// @brief Sets per buffer addressibility (PBA) mode
-/// @tparam T TargetType of the CCS instruction
/// @param[in] i_target the DIMM target
/// @param[in] i_state mss::ON or mss::OFF
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff ok
/// @note Sets DA0 setting for buffer control word (F0BC1x)
///
-template< fapi2::TargetType T>
inline fapi2::ReturnCode set_pba_mode( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mss::states i_state,
- std::vector< ccs::instruction_t<T> >& io_inst )
+ std::vector< ccs::instruction_t >& io_inst )
{
// PBA position is really bit 0, but we're right justified on our bit ordering here, so it's bit7
constexpr uint64_t PBA_POSITION = 7;
@@ -495,7 +491,7 @@ inline fapi2::ReturnCode set_pba_mode( const fapi2::Target<fapi2::TARGET_TYPE_DI
FAPI_TRY(mss::eff_dimm_ddr4_f0bc1x(i_target, l_nominal_bc_value));
{
- cw_data l_data(FUNC_SPACE_0, BUFF_CONFIG_CW, l_nominal_bc_value, mss::tmrc());
+ cw_data l_data(FUNC_SPACE_0, BUFF_CONFIG_CW, l_nominal_bc_value, mss::tmrd_l2());
l_data.iv_data.writeBit<PBA_POSITION>(i_state);
FAPI_INF("%s data 0x%02x", mss::c_str(i_target), l_data.iv_data);
FAPI_TRY( settings_boilerplate<BCW_8BIT>(i_target, l_data, io_inst) );
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.C
index 7676df23b..be59fe5e0 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.C
@@ -36,11 +36,15 @@
#include <lib/shared/nimbus_defaults.H>
#include <vector>
#include <fapi2.H>
+#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/c_str.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>
#include <lib/dimm/ddr4/latch_wr_vref.H>
#include <lib/dimm/rank.H>
#include <lib/workarounds/ccs_workarounds.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
+
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_DIMM;
@@ -62,7 +66,7 @@ namespace ddr4
fapi2::ReturnCode add_latch_wr_vref_commands( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs06_data& i_mrs06,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
// JEDEC has a 3 step latching process for WR VREF
// 1) enter into VREFDQ training mode, with the desired range value is XXXXXX
@@ -111,7 +115,7 @@ fapi2::ReturnCode latch_wr_vref_commands_by_rank_pair( const fapi2::Target<fapi2
const auto l_mcbist = find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
// Warning: l_dimm is not a valid Target and will crash Cronus if used before it gets filled in by mss::rank::get_dimm_target_from_rank
fapi2::Target<fapi2::TARGET_TYPE_DIMM> l_dimm;
- mss::ccs::program<fapi2::TARGET_TYPE_MCBIST, fapi2::TARGET_TYPE_MCA> l_program;
+ ccs::program l_program;
std::vector<uint64_t> l_ranks;
// Gets the ranks on which to latch the VREF's
@@ -173,7 +177,7 @@ fapi2::ReturnCode setup_latch_wr_vref_commands_by_rank( const fapi2::Target<fapi
const uint64_t i_rank,
const uint8_t i_train_range,
const uint8_t i_train_value,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
// Check to make sure our ctor worked ok
mrs06_data l_mrs06( i_target, fapi2::current_err );
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.H
index 0cb2a285e..4874000b8 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.H
@@ -38,10 +38,14 @@
#include <vector>
#include <fapi2.H>
+#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/c_str.H>
#include <lib/dimm/mrs_load.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>
#include <lib/eff_config/timing.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
+
namespace mss
{
@@ -65,7 +69,7 @@ enum wr_vref_override : uint8_t
fapi2::ReturnCode add_latch_wr_vref_commands( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs06_data& i_mrs06,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Add latching commands for WR VREF to the instruction array
@@ -121,7 +125,7 @@ fapi2::ReturnCode setup_latch_wr_vref_commands_by_rank( const fapi2::Target<fapi
const uint64_t i_rank,
const uint8_t i_train_range,
const uint8_t i_train_value,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
} // close namespace DDR4
} // close namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs00.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs00.C
index 71deb5bbe..0f0229a71 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs00.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs00.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,7 +36,12 @@
#include <fapi2.H>
#include <mss.H>
+#include <lib/shared/mss_const.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>
+#include <lib/shared/nimbus_defaults.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
+
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_DIMM;
@@ -91,7 +96,7 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs00(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank)
{
// Check to make sure our ctor worked ok
@@ -113,7 +118,7 @@ fapi_try_exit:
///
fapi2::ReturnCode mrs00(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs00_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank)
{
// Map from Write Recovery attribute value to bits in the MRS.
@@ -202,7 +207,7 @@ fapi_try_exit:
/// @param[out] o_cas_latency the cas latency
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs00_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs00_decode_helper(const ccs::instruction_t& i_inst,
const uint64_t i_rank,
uint8_t& o_burst_length,
uint8_t& o_read_burst_type,
@@ -248,7 +253,7 @@ fapi2::ReturnCode mrs00_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIS
/// @param[in] i_rank ths rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs00_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs00_decode(const ccs::instruction_t& i_inst,
const uint64_t i_rank)
{
uint8_t l_burst_length = 0;
@@ -264,10 +269,10 @@ fapi2::ReturnCode mrs00_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_i
fapi2::ReturnCode (*mrs00_data::make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs00_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank) = &mrs00;
-fapi2::ReturnCode (*mrs00_data::decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode (*mrs00_data::decode)(const ccs::instruction_t& i_inst,
const uint64_t i_rank) = &mrs00_decode;
} // ns ddr4
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs01.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs01.C
index 834ee1ead..cc5896c5c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs01.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs01.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,7 +36,12 @@
#include <fapi2.H>
#include <mss.H>
+#include <lib/shared/mss_const.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>
+#include <lib/shared/nimbus_defaults.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
+
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_DIMM;
@@ -86,7 +91,7 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs01(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank)
{
// Check to make sure our ctor worked ok
@@ -108,7 +113,7 @@ fapi_try_exit:
///
fapi2::ReturnCode mrs01(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs01_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank)
{
// Little table to map Output Driver Imepdance Control. 34Ohm is index 0,
@@ -188,7 +193,7 @@ fapi_try_exit:
/// @param[out] o_rtt_nom the rtt_nom setting
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs01_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs01_decode_helper(const ccs::instruction_t& i_inst,
const uint64_t i_rank,
uint8_t& o_dll_enable,
uint8_t& o_wrl_enable,
@@ -226,7 +231,7 @@ fapi2::ReturnCode mrs01_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIS
/// @param[in] i_rank ths rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs01_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs01_decode(const ccs::instruction_t& i_inst,
const uint64_t i_rank)
{
uint8_t l_dll_enable = 0;
@@ -243,10 +248,10 @@ fapi2::ReturnCode mrs01_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_i
fapi2::ReturnCode (*mrs01_data::make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs01_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank) = &mrs01;
-fapi2::ReturnCode (*mrs01_data::decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode (*mrs01_data::decode)(const ccs::instruction_t& i_inst,
const uint64_t i_rank) = &mrs01_decode;
} // ns ddr4
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs02.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs02.C
index fe819814b..43f90a0ee 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs02.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs02.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -81,7 +81,7 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs02(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank)
{
// Check to make sure our ctor worked ok
@@ -105,7 +105,7 @@ fapi_try_exit:
///
fapi2::ReturnCode mrs02(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs02_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank)
{
constexpr uint64_t CWL_LENGTH = 3;
@@ -170,7 +170,7 @@ fapi_try_exit:
/// @param[out] o_rtt_wr the rtt_wr setting
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs02_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs02_decode_helper(const ccs::instruction_t& i_inst,
const uint64_t i_rank,
uint8_t& o_write_crc,
fapi2::buffer<uint8_t>& o_lpasr,
@@ -199,7 +199,7 @@ fapi2::ReturnCode mrs02_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIS
/// @param[in] i_rank ths rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs02_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs02_decode(const ccs::instruction_t& i_inst,
const uint64_t i_rank)
{
uint8_t l_write_crc = 0;
@@ -212,10 +212,10 @@ fapi2::ReturnCode mrs02_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_i
fapi2::ReturnCode (*mrs02_data::make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs02_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank) = &mrs02;
-fapi2::ReturnCode (*mrs02_data::decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode (*mrs02_data::decode)(const ccs::instruction_t& i_inst,
const uint64_t i_rank) = &mrs02_decode;
} // ns ddr4
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs03.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs03.C
index 06b9eb88c..4c797864b 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs03.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs03.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -106,7 +106,7 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs03(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank)
{
// Check to make sure our ctor worked ok
@@ -130,7 +130,7 @@ fapi_try_exit:
///
fapi2::ReturnCode mrs03(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs03_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank)
{
//Some consts for the swizzle action
@@ -186,7 +186,7 @@ fapi_try_exit:
/// @param[out] o_read_fromat the mpr read format setting
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs03_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs03_decode_helper(const ccs::instruction_t& i_inst,
const uint64_t i_rank,
uint8_t& o_mpr_mode,
uint8_t& o_geardown,
@@ -228,7 +228,7 @@ fapi2::ReturnCode mrs03_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIS
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs03_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs03_decode(const ccs::instruction_t& i_inst,
const uint64_t i_rank)
{
uint8_t l_mpr_mode = 0;
@@ -246,10 +246,10 @@ fapi2::ReturnCode mrs03_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_i
fapi2::ReturnCode (*mrs03_data::make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs03_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank) = &mrs03;
-fapi2::ReturnCode (*mrs03_data::decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode (*mrs03_data::decode)(const ccs::instruction_t& i_inst,
const uint64_t i_rank) = &mrs03_decode;
} // ns ddr4
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs04.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs04.C
index b28dae69e..736f338de 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs04.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs04.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -105,7 +105,7 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs04(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank)
{
// Check to make sure our ctor worked ok
@@ -127,7 +127,7 @@ fapi_try_exit:
///
fapi2::ReturnCode mrs04(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs04_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank)
{
constexpr uint64_t CS_CMD_LATENCY_LENGTH = 3;
@@ -186,7 +186,7 @@ fapi_try_exit:
/// @param[out] o_cs_cmd_latency_buffer the cs to cmd/addr latency mode setting
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs04_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs04_decode_helper(const ccs::instruction_t& i_inst,
const uint64_t i_rank,
uint8_t& o_max_pd_mode,
uint8_t& o_temp_refresh_range,
@@ -232,7 +232,7 @@ fapi2::ReturnCode mrs04_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIS
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs04_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs04_decode(const ccs::instruction_t& i_inst,
const uint64_t i_rank)
{
uint8_t l_max_pd_mode = 0;
@@ -255,10 +255,10 @@ fapi2::ReturnCode mrs04_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_i
fapi2::ReturnCode (*mrs04_data::make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs04_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank) = &mrs04;
-fapi2::ReturnCode (*mrs04_data::decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode (*mrs04_data::decode)(const ccs::instruction_t& i_inst,
const uint64_t i_rank) = &mrs04_decode;
} // ns ddr4
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs05.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs05.C
index a4c5be8c6..e9be70395 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs05.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs05.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -91,7 +91,7 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs05(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank)
{
// Check to make sure our ctor worked ok
@@ -113,7 +113,7 @@ fapi_try_exit:
///
fapi2::ReturnCode mrs05(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs05_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank)
{
constexpr uint64_t CA_PARITY_LATENCY_LENGTH = 3;
@@ -188,7 +188,7 @@ fapi_try_exit:
/// @param[out] o_rtt_park_buffer the rtt_park setting
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs05_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs05_decode_helper(const ccs::instruction_t& i_inst,
const uint64_t i_rank,
uint8_t& o_crc_error_clear,
uint8_t& o_ca_parity_error_status,
@@ -231,7 +231,7 @@ fapi2::ReturnCode mrs05_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIS
/// @param[in] i_rank ths rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs05_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs05_decode(const ccs::instruction_t& i_inst,
const uint64_t i_rank)
{
fapi2::buffer<uint8_t> l_ca_parity_latency_buffer;
@@ -252,10 +252,10 @@ fapi2::ReturnCode mrs05_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_i
fapi2::ReturnCode (*mrs05_data::make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs05_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank) = &mrs05;
-fapi2::ReturnCode (*mrs05_data::decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode (*mrs05_data::decode)(const ccs::instruction_t& i_inst,
const uint64_t i_rank) = &mrs05_decode;
} // ns ddr4
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs06.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs06.C
index bfc1fc885..554271727 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs06.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs06.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -79,7 +79,7 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs06(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank)
{
// Check to make sure our ctor worked ok
@@ -101,7 +101,7 @@ fapi_try_exit:
///
fapi2::ReturnCode mrs06(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs06_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank)
{
@@ -159,7 +159,7 @@ fapi_try_exit:
/// @param[out] o_vrefdq_train_value_buffer the vrefdq training value
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs06_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs06_decode_helper(const ccs::instruction_t& i_inst,
const uint64_t i_rank,
uint8_t& o_vrefdq_train_range,
uint8_t& o_vrefdq_train_enable,
@@ -188,7 +188,7 @@ fapi2::ReturnCode mrs06_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIS
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs06_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs06_decode(const ccs::instruction_t& i_inst,
const uint64_t i_rank)
{
fapi2::buffer<uint8_t> l_tccd_l_buffer;
@@ -202,10 +202,10 @@ fapi2::ReturnCode mrs06_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_i
fapi2::ReturnCode (*mrs06_data::make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs06_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank) = &mrs06;
-fapi2::ReturnCode (*mrs06_data::decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode (*mrs06_data::decode)(const ccs::instruction_t& i_inst,
const uint64_t i_rank) = &mrs06_decode;
} // ns ddr4
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C
index cec455f6a..3ac509b6c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -62,7 +62,7 @@ template< >
fapi2::ReturnCode mrs_engine( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs_data<fapi2::TARGET_TYPE_MCBIST>& i_data,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst )
+ std::vector< ccs::instruction_t >& io_inst )
{
FAPI_TRY( mrs_engine(i_target, i_data, i_rank, i_data.iv_delay, io_inst) );
@@ -138,7 +138,7 @@ namespace ddr4
/// @return FAPI2_RC_SUCCESS if and only if ok
///
fapi2::ReturnCode mrs_load( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
FAPI_INF("ddr4::mrs_load %s", mss::c_str(i_target));
@@ -146,28 +146,82 @@ fapi2::ReturnCode mrs_load( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
const size_t DOUBLE_TMRD = 2 * mss::tmrd();
const size_t DOUBLE_TMOD = 2 * mss::tmod(i_target);
- static const std::vector< mrs_data<TARGET_TYPE_MCBIST> > MRS_DATA =
+ // tDLLK to wait for DLL Reset
+ uint64_t tDLLK = 0;
+ FAPI_TRY( mss::tdllk(i_target, tDLLK) );
+
{
- // JEDEC ordering of MRS per DDR4 power on sequence
- { 3, mrs03, mrs03_decode, DOUBLE_TMRD },
- { 6, mrs06, mrs06_decode, DOUBLE_TMRD },
- { 5, mrs05, mrs05_decode, DOUBLE_TMRD },
- { 4, mrs04, mrs04_decode, DOUBLE_TMRD },
- { 2, mrs02, mrs02_decode, DOUBLE_TMRD },
- { 1, mrs01, mrs01_decode, DOUBLE_TMRD },
- // We need to wait tmod before zqcl, a non-mrs command
- { 0, mrs00, mrs00_decode, DOUBLE_TMOD },
- };
-
- std::vector< uint64_t > l_ranks;
- FAPI_TRY( mss::rank::ranks(i_target, l_ranks) );
-
- // Load MRS
- for (const auto& d : MRS_DATA)
+ const std::vector< mrs_data<TARGET_TYPE_MCBIST> > MRS_DATA =
+ {
+ // JEDEC ordering of MRS per DDR4 power on sequence
+ { 3, mrs03, mrs03_decode, DOUBLE_TMRD },
+ { 6, mrs06, mrs06_decode, DOUBLE_TMRD },
+ { 5, mrs05, mrs05_decode, DOUBLE_TMRD },
+ { 4, mrs04, mrs04_decode, DOUBLE_TMRD },
+ { 2, mrs02, mrs02_decode, DOUBLE_TMRD },
+ { 1, mrs01, mrs01_decode, DOUBLE_TMRD },
+ // We need to wait tmod before zqcl, a non-mrs command
+ // Adding Per Glancy's request, to ensure DLL locking time
+ { 0, mrs00, mrs00_decode, DOUBLE_TMOD + tDLLK },
+ };
+
+ std::vector< uint64_t > l_ranks;
+ FAPI_TRY( mss::rank::ranks(i_target, l_ranks) );
+
+ // Load MRS
+ for (const auto& d : MRS_DATA)
+ {
+ for (const auto& r : l_ranks)
+ {
+ FAPI_TRY( mrs_engine(i_target, d, r, io_inst) );
+ }
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Perform the mrs_load DDR4 operations for nvdimm restore - TARGET_TYPE_DIMM specialization
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] io_inst a vector of CCS instructions we should add to
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+fapi2::ReturnCode mrs_load_nvdimm( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
+ std::vector< ccs::instruction_t >& io_inst)
+{
+ FAPI_INF("ddr4::mrs_load_nvdimm %s", mss::c_str(i_target));
+
+ // tDLLK to wait for DLL Reset
+ uint64_t tDLLK = 0;
+ FAPI_TRY( mss::tdllk(i_target, tDLLK) );
+
{
- for (const auto& r : l_ranks)
+ const std::vector< mrs_data<TARGET_TYPE_MCBIST> > MRS_DATA =
+ {
+ // JEDEC ordering of MRS per DDR4 NVDIMM restore sequence
+ // Need to perform DLL off to on procedure (mrs01&mrs00)
+ // before all the other MRS's
+ { 1, mrs01, mrs01_decode, mss::tmrd() },
+ { 0, mrs00, mrs00_decode, mss::tmod(i_target) + tDLLK },
+ { 3, mrs03, mrs03_decode, mss::tmrd() },
+ { 6, mrs06, mrs06_decode, mss::tmrd() },
+ { 5, mrs05, mrs05_decode, mss::tmrd() },
+ { 4, mrs04, mrs04_decode, mss::tmrd() },
+ { 2, mrs02, mrs02_decode, mss::tmrd() },
+ };
+
+ std::vector< uint64_t > l_ranks;
+ FAPI_TRY( mss::rank::ranks(i_target, l_ranks) );
+
+ // Load MRS
+ for (const auto& d : MRS_DATA)
{
- FAPI_TRY( mrs_engine(i_target, d, r, io_inst) );
+ for (const auto& r : l_ranks)
+ {
+ FAPI_TRY( mrs_engine(i_target, d, r, io_inst) );
+ }
}
}
@@ -234,7 +288,7 @@ fapi_try_exit:
template<>
fapi2::ReturnCode rtt_nom_override(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
uint8_t l_rtt_nom_override_disable = 0;
uint8_t l_rtt_wr_value[MAX_RANK_PER_DIMM] = {0};
@@ -274,7 +328,7 @@ fapi_try_exit:
template<>
fapi2::ReturnCode rtt_wr_disable(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
uint8_t l_rtt_wr_value[MAX_RANK_PER_DIMM] = {0};
@@ -302,7 +356,7 @@ fapi_try_exit:
template<>
fapi2::ReturnCode rtt_nom_restore(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
uint8_t l_rtt_nom_override_disable = 0;
uint8_t l_rtt_nom_value[MAX_RANK_PER_DIMM] = {0};
@@ -335,7 +389,7 @@ fapi_try_exit:
template<>
fapi2::ReturnCode rtt_wr_restore(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
// Get original RTT_WR value
uint8_t l_rtt_wr_value[MAX_RANK_PER_DIMM] = {0};
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H
index bd8277daa..5e6aa5c35 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H
@@ -41,6 +41,9 @@
#include <generic/memory/lib/utils/c_str.H>
#include <lib/dimm/mrs_load.H>
#include <lib/eff_config/timing.H>
+#include <lib/shared/mss_const.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
namespace mss
{
@@ -99,13 +102,11 @@ enum rtt_nom_settings
///
/// @brief Mirror (front to back) the ADR bits of a CCS instruction - implementation
-/// @tparam T typename of the ccs::instruction_t
/// @param[in, out] io_inst reference to a CCS instruction to be mirrored
/// @return FAPI2_RC_SUCESS iff ok
/// @note written this way so this is easier to test
///
-template<fapi2::TargetType T>
-void address_mirror_impl(ccs::instruction_t<T>& io_inst)
+inline void address_mirror_impl(ccs::instruction_t& io_inst)
{
// Nothing fancy here, just mirror the bits we're told to mirror in Table 14 — Address Mirroring and Inversion
mss::template swap<A3, A4>(io_inst.arr0);
@@ -118,17 +119,15 @@ void address_mirror_impl(ccs::instruction_t<T>& io_inst)
///
/// @brief Mirror (front to back) the ADR bits of a CCS instruction
-/// @tparam T typename of the ccs::instruction_t
/// @param[in] i_target target to use to get mirroring attribute
/// @param[in] i_rank the rank in question
/// @param[in, out] io_inst reference to a CCS instruction to be mirrored
/// @return FAPI2_RC_SUCESS iff ok
/// @note assumes the input is from an even number rank
///
-template<fapi2::TargetType T>
-fapi2::ReturnCode address_mirror(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank,
- ccs::instruction_t<T>& io_inst)
+inline fapi2::ReturnCode address_mirror(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint64_t i_rank,
+ ccs::instruction_t& io_inst)
{
// We only mirror if the mirroring attribute is set.
uint8_t l_mirror = 0;
@@ -147,19 +146,17 @@ fapi_try_exit:
///
/// @brief Invert (side to side) the ADR bits of a CCS instruction
-/// @tparam T the target type of the ccs instruction
/// @param[in] i_target the DIMM target of the ccs command
/// @param[in] i_inst const reference to a CCS instruction.
/// @param[in] l_is_a17 Boolean for whether A17 bit is enabled or not
/// @return ccs instruction with the ADR bits inverted (side-to-side)
///
-template<fapi2::TargetType T>
-ccs::instruction_t<T> address_invert(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const ccs::instruction_t<T>& i_inst,
- const bool i_is_a17 = false)
+inline ccs::instruction_t address_invert(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const ccs::instruction_t& i_inst,
+ const bool i_is_a17 = false)
{
// Copy the input as the output doesn't all change.
- ccs::instruction_t<T> i_out(i_inst);
+ ccs::instruction_t i_out(i_inst);
// Nothing fancy here, just negate the bits we're told to negate in Table 14 — Address Mirroring and Inversion
mss::template negate<A3>(i_out.arr0);
@@ -189,7 +186,6 @@ ccs::instruction_t<T> address_invert(const fapi2::Target<fapi2::TARGET_TYPE_DIMM
///
/// @brief Helper function to make a CCS instruction for an MRS
-/// @tparam T TargetType of the CCS instruction
/// @tparam D the mrs data structure to send out
/// @param[in] i_target a fapi2::Target DIMM
/// @param[in] i_data the completed MRS data to send
@@ -197,11 +193,11 @@ ccs::instruction_t<T> address_invert(const fapi2::Target<fapi2::TARGET_TYPE_DIMM
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T, typename D >
+template< typename D >
static inline fapi2::ReturnCode make_ccs_helper( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const D& i_data,
const uint64_t i_rank,
- ccs::instruction_t<T>& io_inst )
+ ccs::instruction_t& io_inst )
{
FAPI_TRY( D::make_ccs_instruction(i_target, i_data, io_inst, i_rank),
"Failed making a CCS instruction for templated MRS data. MR%d rank %d on %s",
@@ -219,11 +215,10 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS if and only if ok
///
template< >
-inline fapi2::ReturnCode make_ccs_helper(
- const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const mrs_data<fapi2::TARGET_TYPE_MCBIST>& i_data,
- const uint64_t i_rank,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst )
+inline fapi2::ReturnCode make_ccs_helper( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs_data<fapi2::TARGET_TYPE_MCBIST>& i_data,
+ const uint64_t i_rank,
+ ccs::instruction_t& io_inst )
{
FAPI_TRY( i_data.iv_func(i_target, io_inst, i_rank),
"Failed making a CCS instruction for mrs_data<TARGET_TYPE_MCBIST> specialization. MR%d rank %d on %s",
@@ -235,17 +230,16 @@ fapi_try_exit:
///
/// @brief Helper function to decode MRS and trace CCS instructions
-/// @tparam T TargetType of the CCS instruction
/// @tparam D the mrs data structure to send out
/// @param[in] i_data the completed MRS data to send
/// @param[in] i_rank the rank to send to
/// @param[in] i_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T, typename D >
+template< typename D >
static inline fapi2::ReturnCode decode_helper(const D& i_data,
const uint64_t i_rank,
- const ccs::instruction_t<T>& i_inst )
+ const ccs::instruction_t& i_inst )
{
// Dump out the 'decoded' MRS and trace the CCS instructions.
FAPI_TRY( D::decode(i_inst, i_rank),
@@ -278,7 +272,7 @@ fapi2::ReturnCode is_a17_needed(const fapi2::Target<T>& i_target,
template< >
inline fapi2::ReturnCode decode_helper(const mrs_data<fapi2::TARGET_TYPE_MCBIST>& i_data,
const uint64_t i_rank,
- const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst )
+ const ccs::instruction_t& i_inst )
{
// Dump out the 'decoded' MRS and trace the CCS instructions.
FAPI_TRY( i_data.iv_dumper(i_inst, i_rank),
@@ -292,7 +286,6 @@ fapi_try_exit:
///
/// @brief Sets up MRS CCS instructions
-/// @tparam T TargetType of the CCS instruction
/// @tparam D the mrs data structure to send out
/// @param[in] i_target a fapi2::Target DIMM
/// @param[in] i_data the completed MRS data to send
@@ -301,15 +294,15 @@ fapi_try_exit:
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T, typename D >
+template< typename D >
fapi2::ReturnCode mrs_engine( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const D& i_data,
const uint64_t i_rank,
const uint64_t i_delay_in_cycles,
- std::vector< ccs::instruction_t<T> >& io_inst )
+ std::vector< ccs::instruction_t >& io_inst )
{
- ccs::instruction_t<T> l_inst_a_side = ccs::mrs_command<T>(i_rank, i_data.iv_mrs);
- ccs::instruction_t<T> l_inst_b_side;
+ ccs::instruction_t l_inst_a_side = ccs::mrs_command(i_rank, i_data.iv_mrs);
+ ccs::instruction_t l_inst_b_side;
bool l_is_a17 = false;
// Thou shalt send 2 MRS, one for the a-side and the other inverted for the b-side.
@@ -355,7 +348,6 @@ fapi_try_exit:
///
/// @brief Sets up MRS CCS instructions
-/// @tparam T TargetType of the CCS instruction
/// @tparam D the mrs data structure to send out
/// @param[in] i_target a fapi2::Target DIMM
/// @param[in] i_data the completed MRS data to send
@@ -363,11 +355,11 @@ fapi_try_exit:
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T, typename D >
+template< typename D >
fapi2::ReturnCode mrs_engine( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const D& i_data,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<T> >& io_inst );
+ std::vector< ccs::instruction_t >& io_inst );
namespace ddr4
{
@@ -395,7 +387,7 @@ class mrs06_data;
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs00(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
///
@@ -406,7 +398,7 @@ fapi2::ReturnCode mrs00(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs01(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
///
@@ -417,7 +409,7 @@ fapi2::ReturnCode mrs01(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs02(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
///
/// @brief Configure the ARR0 of the CCS isntruction for mrs03
@@ -427,7 +419,7 @@ fapi2::ReturnCode mrs02(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs03(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
///
/// @brief Configure the ARR0 of the CCS isntruction for mrs04
@@ -437,7 +429,7 @@ fapi2::ReturnCode mrs03(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs04(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
///
/// @brief Configure the ARR0 of the CCS isntruction for mrs05
@@ -447,7 +439,7 @@ fapi2::ReturnCode mrs04(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs05(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
///
/// @brief Configure the ARR0 of the CCS isntruction for mrs06
@@ -457,7 +449,7 @@ fapi2::ReturnCode mrs05(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs06(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
/// }@
@@ -478,7 +470,7 @@ fapi2::ReturnCode mrs06(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
///
fapi2::ReturnCode mrs00(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs00_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
///
@@ -491,7 +483,7 @@ fapi2::ReturnCode mrs00(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
///
fapi2::ReturnCode mrs01(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs01_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
///
@@ -504,7 +496,7 @@ fapi2::ReturnCode mrs01(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
///
fapi2::ReturnCode mrs02(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs02_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
///
@@ -517,7 +509,7 @@ fapi2::ReturnCode mrs02(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
///
fapi2::ReturnCode mrs03(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs03_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
///
@@ -530,7 +522,7 @@ fapi2::ReturnCode mrs03(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
///
fapi2::ReturnCode mrs04(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs04_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
///
@@ -543,7 +535,7 @@ fapi2::ReturnCode mrs04(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
///
fapi2::ReturnCode mrs05(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs05_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
///
@@ -556,7 +548,7 @@ fapi2::ReturnCode mrs05(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
///
fapi2::ReturnCode mrs06(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs06_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
/// }@
@@ -579,7 +571,7 @@ fapi2::ReturnCode mrs06(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
/// @param[out] o_cas_latency the cas latency
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs00_decode_helper(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs00_decode_helper(const ccs::instruction_t& i_inst,
const uint64_t i_rank,
uint8_t& o_burst_length,
uint8_t& o_read_burst_type,
@@ -595,7 +587,7 @@ fapi2::ReturnCode mrs00_decode_helper(const ccs::instruction_t<fapi2::TARGET_TYP
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs00_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs00_decode(const ccs::instruction_t& i_inst,
const uint64_t i_rank);
///
@@ -611,7 +603,7 @@ fapi2::ReturnCode mrs00_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIS
/// @param[out] o_rtt_nom the rtt_nom setting
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs01_decode_helper(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs01_decode_helper(const ccs::instruction_t& i_inst,
const uint64_t i_rank,
uint8_t& o_dll_enable,
uint8_t& o_wrl_enable,
@@ -628,7 +620,7 @@ fapi2::ReturnCode mrs01_decode_helper(const ccs::instruction_t<fapi2::TARGET_TYP
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs01_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs01_decode(const ccs::instruction_t& i_inst,
const uint64_t i_rank);
///
@@ -641,7 +633,7 @@ fapi2::ReturnCode mrs01_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIS
/// @param[out] o_rtt_wr the rtt_wr setting
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs02_decode_helper(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs02_decode_helper(const ccs::instruction_t& i_inst,
const uint64_t i_rank,
uint8_t& o_write_crc,
fapi2::buffer<uint8_t>& o_lpasr,
@@ -655,7 +647,7 @@ fapi2::ReturnCode mrs02_decode_helper(const ccs::instruction_t<fapi2::TARGET_TYP
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs02_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs02_decode(const ccs::instruction_t& i_inst,
const uint64_t i_rank);
///
@@ -672,7 +664,7 @@ fapi2::ReturnCode mrs02_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIS
/// @param[out] o_read_fromat the mpr read format setting
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs03_decode_helper(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs03_decode_helper(const ccs::instruction_t& i_inst,
const uint64_t i_rank,
uint8_t& o_mpr_mode,
uint8_t& o_geardown,
@@ -690,7 +682,7 @@ fapi2::ReturnCode mrs03_decode_helper(const ccs::instruction_t<fapi2::TARGET_TYP
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs03_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs03_decode(const ccs::instruction_t& i_inst,
const uint64_t i_rank);
///
@@ -709,7 +701,7 @@ fapi2::ReturnCode mrs03_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIS
/// @param[out] o_cs_cmd_latency_buffer the cs to cmd/addr latency mode setting
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs04_decode_helper(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs04_decode_helper(const ccs::instruction_t& i_inst,
const uint64_t i_rank,
uint8_t& o_max_pd_mode,
uint8_t& o_temp_refresh_range,
@@ -730,7 +722,7 @@ fapi2::ReturnCode mrs04_decode_helper(const ccs::instruction_t<fapi2::TARGET_TYP
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs04_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs04_decode(const ccs::instruction_t& i_inst,
const uint64_t i_rank);
///
@@ -748,7 +740,7 @@ fapi2::ReturnCode mrs04_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIS
/// @param[out] o_rtt_park_buffer the rtt_park setting
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs05_decode_helper(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs05_decode_helper(const ccs::instruction_t& i_inst,
const uint64_t i_rank,
uint8_t& o_crc_error_clear,
uint8_t& o_ca_parity_error_status,
@@ -767,7 +759,7 @@ fapi2::ReturnCode mrs05_decode_helper(const ccs::instruction_t<fapi2::TARGET_TYP
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs05_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs05_decode(const ccs::instruction_t& i_inst,
const uint64_t i_rank);
///
@@ -780,7 +772,7 @@ fapi2::ReturnCode mrs05_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIS
/// @param[out] o_vrefdq_train_value_buffer the vrefdq training value
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs06_decode_helper(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs06_decode_helper(const ccs::instruction_t& i_inst,
const uint64_t i_rank,
uint8_t& o_vrefdq_train_range,
uint8_t& o_vrefdq_train_enable,
@@ -794,7 +786,7 @@ fapi2::ReturnCode mrs06_decode_helper(const ccs::instruction_t<fapi2::TARGET_TYP
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode mrs06_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+fapi2::ReturnCode mrs06_decode(const ccs::instruction_t& i_inst,
const uint64_t i_rank);
///
@@ -818,10 +810,10 @@ struct mrs00_data
// dynaimc polymorphism and I avoid that where possible.
static fapi2::ReturnCode (*make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs00_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
- static fapi2::ReturnCode (*decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+ static fapi2::ReturnCode (*decode)(const ccs::instruction_t& i_inst,
const uint64_t i_rank);
///
@@ -909,10 +901,10 @@ struct mrs01_data
// Helper function needed by the lab tooling to find our instruction maker and our dumper
static fapi2::ReturnCode (*make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs01_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
- static fapi2::ReturnCode (*decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+ static fapi2::ReturnCode (*decode)(const ccs::instruction_t& i_inst,
const uint64_t i_rank);
///
@@ -1011,10 +1003,10 @@ struct mrs02_data
// Helper function needed by the lab tooling to find our instruction maker and our dumper
static fapi2::ReturnCode (*make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs02_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
- static fapi2::ReturnCode (*decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+ static fapi2::ReturnCode (*decode)(const ccs::instruction_t& i_inst,
const uint64_t i_rank);
///
@@ -1091,10 +1083,10 @@ struct mrs03_data
// Helper function needed by the lab tooling to find our instruction maker and our dumper
static fapi2::ReturnCode (*make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs03_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
- static fapi2::ReturnCode (*decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+ static fapi2::ReturnCode (*decode)(const ccs::instruction_t& i_inst,
const uint64_t i_rank);
///
@@ -1196,10 +1188,10 @@ struct mrs04_data
// Helper function needed by the lab tooling to find our instruction maker and our dumper
static fapi2::ReturnCode (*make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs04_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
- static fapi2::ReturnCode (*decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+ static fapi2::ReturnCode (*decode)(const ccs::instruction_t& i_inst,
const uint64_t i_rank);
///
@@ -1322,10 +1314,10 @@ struct mrs05_data
// Helper function needed by the lab tooling to find our instruction maker and our dumper
static fapi2::ReturnCode (*make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs05_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
- static fapi2::ReturnCode (*decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+ static fapi2::ReturnCode (*decode)(const ccs::instruction_t& i_inst,
const uint64_t i_rank);
///
@@ -1436,10 +1428,10 @@ struct mrs06_data
// Helper function needed by the lab tooling to find our instruction maker and our dumper
static fapi2::ReturnCode (*make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const mrs06_data& i_data,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ ccs::instruction_t& io_inst,
const uint64_t i_rank);
- static fapi2::ReturnCode (*decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+ static fapi2::ReturnCode (*decode)(const ccs::instruction_t& i_inst,
const uint64_t i_rank);
///
@@ -1516,7 +1508,16 @@ struct mrs06_data
/// @return FAPI2_RC_SUCCESS if and only if ok
///
fapi2::ReturnCode mrs_load( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
+
+///
+/// @brief Perform the mrs_load DDR4 operations for nvdimm restore - TARGET_TYPE_DIMM specialization
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] io_inst a vector of CCS instructions we should add to
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+fapi2::ReturnCode mrs_load_nvdimm( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Sets WR LVL mode
@@ -1720,18 +1721,16 @@ fapi_try_exit:
///
/// @brief Makes CCS instruction to set WR LVL Mode
-/// @tparam T TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_mode setting for WR LVL mode
/// @param[in] i_rank DIMM rank
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T >
-fapi2::ReturnCode wr_lvl(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const mss::states i_mode,
- const uint64_t i_rank,
- std::vector< ccs::instruction_t<T> >& io_inst )
+inline fapi2::ReturnCode wr_lvl(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mss::states i_mode,
+ const uint64_t i_rank,
+ std::vector< ccs::instruction_t >& io_inst )
{
// Spec states we need to use tmod for our delay, so we do
const uint64_t l_delay = mss::tmod(i_target);
@@ -1754,18 +1753,16 @@ fapi_try_exit:
///
/// @brief Makes CCS instruction to set MPR Mode
-/// @tparam T TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_mode setting for MPR mode
/// @param[in] i_rank DIMM rank
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T >
-fapi2::ReturnCode mpr_load(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint8_t i_mode,
- const uint64_t i_rank,
- std::vector< ccs::instruction_t<T> >& io_inst )
+inline fapi2::ReturnCode mpr_load(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint8_t i_mode,
+ const uint64_t i_rank,
+ std::vector< ccs::instruction_t >& io_inst )
{
// From DDR4 spec section 4.10.3 MPR Reads:
// tMRD and tMOD must be satisfied after enabling/disabling MPR mode
@@ -1789,7 +1786,6 @@ fapi_try_exit:
///
/// @brief Makes CCS instruction to set MPR Mode
-/// @tparam T TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_mode setting for MPR mode
/// @param[in] i_rd_format MPR read format
@@ -1797,12 +1793,11 @@ fapi_try_exit:
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T >
-fapi2::ReturnCode mpr_load(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint8_t i_mode,
- const uint8_t i_rd_format,
- const uint64_t i_rank,
- std::vector< ccs::instruction_t<T> >& io_inst )
+inline fapi2::ReturnCode mpr_load(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint8_t i_mode,
+ const uint8_t i_rd_format,
+ const uint64_t i_rank,
+ std::vector< ccs::instruction_t >& io_inst )
{
// From DDR4 spec section 4.10.3 MPR Reads:
// tMRD and tMOD must be satisfied after enabling/disabling MPR mode
@@ -1830,18 +1825,16 @@ fapi_try_exit:
///
/// @brief Makes CCS instruction to set RTT_NOM value
-/// @tparam T TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_value values to set to RTT_NOM
/// @param[in] i_rank DIMM rank
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T >
-fapi2::ReturnCode rtt_nom_load(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint8_t i_value[MAX_RANK_PER_DIMM],
- const uint64_t i_rank,
- std::vector< ccs::instruction_t<T> >& io_inst )
+inline fapi2::ReturnCode rtt_nom_load(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint8_t i_value[MAX_RANK_PER_DIMM],
+ const uint64_t i_rank,
+ std::vector< ccs::instruction_t >& io_inst )
{
// tMRD (clock cycles) must be satisfied after an MRS command
constexpr uint64_t l_delay = mss::tmrd();
@@ -1864,18 +1857,16 @@ fapi_try_exit:
///
/// @brief Makes CCS instruction to set RTT_WR value
-/// @tparam T TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_value values to set to RTT_WR
/// @param[in] i_rank DIMM rank
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T >
-fapi2::ReturnCode rtt_wr_load(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint8_t i_value[MAX_RANK_PER_DIMM],
- const uint64_t i_rank,
- std::vector< ccs::instruction_t<T> >& io_inst )
+inline fapi2::ReturnCode rtt_wr_load(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint8_t i_value[MAX_RANK_PER_DIMM],
+ const uint64_t i_rank,
+ std::vector< ccs::instruction_t >& io_inst )
{
// tMRD (clock cycles) must be satisfied after an MRS command
constexpr uint64_t l_delay = mss::tmrd();
@@ -1898,23 +1889,21 @@ fapi_try_exit:
///
/// @brief Makes CCS instruction for an MPR read
-/// @tparam T TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_mode MPR location
/// @param[in] i_rank DIMM rank
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T >
-fapi2::ReturnCode mpr_read( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_mpr_loc,
- const uint64_t i_rank,
- std::vector< ccs::instruction_t<T> >& io_inst )
+inline fapi2::ReturnCode mpr_read( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint64_t i_mpr_loc,
+ const uint64_t i_rank,
+ std::vector< ccs::instruction_t >& io_inst )
{
// Right now we only have support for RD and RDA
// Unclear if we want the API select the type of read command right now
// Note the auto precharge is ignored with MPR mode on so we just do a read cmd
- ccs::instruction_t<T> l_inst = ccs::rd_command<T> (i_rank, i_mpr_loc);
+ ccs::instruction_t l_inst = ccs::rd_command (i_rank, i_mpr_loc);
// In MPR Mode:
// Reads (back-to-back) from Page 0 may use tCCD_S or tCCD_L timing between read commands
@@ -1948,18 +1937,16 @@ fapi_try_exit:
///
/// @brief Makes CCS instruction to set precharge all command
-/// @tparam T TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_rank DIMM rank
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T >
-fapi2::ReturnCode precharge_all( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank,
- std::vector< ccs::instruction_t<T> >& io_inst )
+inline fapi2::ReturnCode precharge_all( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint64_t i_rank,
+ std::vector< ccs::instruction_t >& io_inst )
{
- ccs::instruction_t<T> l_inst = ccs::precharge_all_command<T> (i_rank);
+ ccs::instruction_t l_inst = ccs::precharge_all_command (i_rank);
// From the DDR4 Spec tRP is the precharge command period
uint8_t l_delay = 0;
@@ -1995,58 +1982,54 @@ fapi2::ReturnCode rtt_wr_to_rtt_nom_helper(const fapi2::Target<T>& i_target,
///
/// @brief Executes CCS instructions to set RTT_WR value into RTT_NOM
/// @tparam T TargetType of the DIMM
-/// @tparam CT TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_rank selected rank
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T, fapi2::TargetType CT >
+template< fapi2::TargetType T >
fapi2::ReturnCode rtt_nom_override(const fapi2::Target<T>& i_target,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<CT> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Executes CCS instructions to disable RTT_WR
/// @tparam T TargetType of the DIMM
-/// @tparam CT TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_rank selected rank
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T, fapi2::TargetType CT >
+template< fapi2::TargetType T >
fapi2::ReturnCode rtt_wr_disable(const fapi2::Target<T>& i_target,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<CT> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Executes CCS instructions to restore original value to RTT_NOM
/// @tparam T TargetType of the DIMM
-/// @tparam CT TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_rank selected rank
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T, fapi2::TargetType CT >
+template< fapi2::TargetType T >
fapi2::ReturnCode rtt_nom_restore(const fapi2::Target<T>& i_target,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<CT> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Executes CCS instructions to restore original value to RTT_WR
/// @tparam T TargetType of the DIMM
-/// @tparam CT TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_rank selected rank
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< fapi2::TargetType T, fapi2::TargetType CT >
+template< fapi2::TargetType T >
fapi2::ReturnCode rtt_wr_restore(const fapi2::Target<T>& i_target,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<CT> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
} // ddr4
} // mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C
index 869e18f25..8c19b99f9 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,23 +33,25 @@
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
-#include <lib/shared/nimbus_defaults.H>
#include <fapi2.H>
#include <vector>
+#include <lib/shared/mss_const.H>
+#include <lib/shared/nimbus_defaults.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
#include <lib/dimm/ddr4/nvdimm_utils.H>
#include <lib/mc/mc.H>
-#include <lib/ccs/ccs.H>
#include <lib/dimm/rank.H>
#include <lib/mss_attribute_accessors.H>
+#include <lib/mcbist/mcbist.H>
+#include <lib/utils/mss_nimbus_conversions.H>
#include <generic/memory/lib/utils/poll.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <generic/memory/lib/utils/mc/gen_mss_port.H>
#include <lib/mcbist/address.H>
#include <lib/mcbist/memdiags.H>
-#include <lib/mcbist/mcbist.H>
#include <lib/mcbist/settings.H>
-#include <lib/utils/mss_nimbus_conversions.H>
#include <generic/memory/lib/utils/pos.H>
#include <lib/mc/port.H>
#include <lib/phy/dp16.H>
@@ -82,7 +84,7 @@ fapi2::ReturnCode get_maint_addr_mode_en( const fapi2::Target<fapi2::TARGET_TYPE
mss::states& o_state )
{
const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- typedef mcbistTraits<TARGET_TYPE_MCBIST> TT;
+ typedef mcbistTraits<> TT;
fapi2::buffer<uint64_t> l_data;
FAPI_TRY( mss::getScom(l_mcbist, TT::MCBAGRAQ_REG, l_data),
@@ -105,7 +107,7 @@ fapi2::ReturnCode change_maint_addr_mode_en( const fapi2::Target<fapi2::TARGET_T
const mss::states i_state )
{
const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- typedef mcbistTraits<TARGET_TYPE_MCBIST> TT;
+ typedef mcbistTraits<> TT;
fapi2::buffer<uint64_t> l_data;
FAPI_TRY( mss::getScom(l_mcbist, TT::MCBAGRAQ_REG, l_data),
@@ -213,10 +215,10 @@ fapi2::ReturnCode self_refresh_exit_helper( const fapi2::Target<fapi2::TARGET_TY
mss::mcbist::address l_start = 0, l_end = 0;
mss::mcbist::end_boundary l_end_boundary = mss::mcbist::end_boundary::STOP_AFTER_SLAVE_RANK;
l_start.set_port(l_port);
- mss::mcbist::stop_conditions l_stop_conditions;
+ mss::mcbist::stop_conditions<> l_stop_conditions;
// Read with targeted scrub
- FAPI_TRY ( mss::memdiags::targeted_scrub(l_mcbist,
+ FAPI_TRY ( mss::memdiags::targeted_scrub<mss::mc_type::NIMBUS>(l_mcbist,
l_stop_conditions,
l_start,
l_end,
@@ -264,10 +266,14 @@ template<>
fapi2::ReturnCode self_refresh_entry( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target )
{
fapi2::buffer<uint64_t> l_mbarpc0_data, l_mbastr0_data;
+ const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
// Entry time to 0 for immediate entry
constexpr uint64_t l_str_entry_time = 0;
+ // Stop mcbist (scrub) in case of MPIPL. It will get restarted in the later istep
+ FAPI_TRY(mss::mcbist::start_stop(l_mcbist, mss::states::STOP));
+
// Step 1 - In MBARPC0Q, disable power domain control, set domain to MAXALL_MIN0,
// and disable minimum domain reduction (allow immediate entry of STR)
FAPI_TRY(mss::mc::read_mbarpc0(i_target, l_mbarpc0_data));
@@ -322,49 +328,6 @@ fapi_try_exit:
}
///
-/// @brief Disable powerdown mode in rc09
-/// @param[in] i_target, a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in,out] io_inst a vector of CCS instructions we should add to
-/// @return FAPI2_RC_SUCCESS if and only if ok
-///
-fapi2::ReturnCode rc09_disable_powerdown( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
-{
- FAPI_INF("rc09_disable_powerdown %s", mss::c_str(i_target));
-
- constexpr uint8_t POWER_DOWN_BIT = 4;
- constexpr bool l_sim = false;
- constexpr uint8_t FS0 = 0; // Function space 0
- constexpr uint64_t CKE_HIGH = mss::ON;
- fapi2::buffer<uint8_t> l_rc09_cw = 0;
- std::vector<uint64_t> l_ranks;
-
- FAPI_TRY(mss::eff_dimm_ddr4_rc09(i_target, l_rc09_cw));
-
- // Clear power down enable bit.
- l_rc09_cw.clearBit<POWER_DOWN_BIT>();
-
- FAPI_TRY( mss::rank::ranks(i_target, l_ranks) );
-
- // DES to ensure we exit powerdown properly
- FAPI_DBG("deselect for %s", mss::c_str(i_target));
- io_inst.push_back( ccs::des_command<TARGET_TYPE_MCBIST>() );
-
- static const cw_data l_rc09_4bit_data( FS0, 9, l_rc09_cw, mss::tmrd() );
-
- // Load RC09
- FAPI_TRY( control_word_engine<RCW_4BIT>(i_target, l_rc09_4bit_data, l_sim, io_inst, CKE_HIGH),
- "Failed to load 4-bit RC09 control word for %s",
- mss::c_str(i_target));
-
- // Hold the CKE high
- mss::ccs::workarounds::hold_cke_high(io_inst);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief Load the rcd control words
/// @param[in] i_target, a fapi2::Target<TARGET_TYPE_DIMM>
/// @param[in,out] io_inst a vector of CCS instructions we should add to
@@ -373,11 +336,11 @@ fapi_try_exit:
/// with NVDIMMs
///
fapi2::ReturnCode rcd_load_nvdimm( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
FAPI_INF("rcd_load_nvdimm %s", mss::c_str(i_target));
- constexpr uint64_t CKE_LOW = mss::OFF;
+ constexpr uint64_t CKE_HIGH = mss::ON;
constexpr bool l_sim = false;
// Per DDR4RCD02, tSTAB is us. We want this in cycles for the CCS.
@@ -425,17 +388,19 @@ fapi2::ReturnCode rcd_load_nvdimm( const fapi2::Target<TARGET_TYPE_DIMM>& i_targ
};
// Load 4-bit data
- FAPI_TRY( control_word_engine<RCW_4BIT>(i_target, l_rcd_4bit_data, l_sim, io_inst, CKE_LOW),
+ // Keeping the CKE high as this will be done not in powerdown/STR mode. Not affected for
+ // the RCD supplier on nvdimm
+ FAPI_TRY( control_word_engine<RCW_4BIT>(i_target, l_rcd_4bit_data, l_sim, io_inst, CKE_HIGH),
"Failed to load 4-bit control words for %s",
mss::c_str(i_target));
// Load 8-bit data
- FAPI_TRY( control_word_engine<RCW_8BIT>(i_target, l_rcd_8bit_data, l_sim, io_inst, CKE_LOW),
+ FAPI_TRY( control_word_engine<RCW_8BIT>(i_target, l_rcd_8bit_data, l_sim, io_inst, CKE_HIGH),
"Failed to load 8-bit control words for %s",
mss::c_str(i_target));
// Load RC09 with CKE_LOW
- FAPI_TRY( control_word_engine<RCW_4BIT>(i_target, l_rc09_4bit_data, l_sim, io_inst, CKE_LOW),
+ FAPI_TRY( control_word_engine<RCW_4BIT>(i_target, l_rc09_4bit_data, l_sim, io_inst, CKE_HIGH),
"Failed to load 4-bit RC09 control word for %s",
mss::c_str(i_target));
@@ -456,34 +421,13 @@ fapi2::ReturnCode rcd_restore( const fapi2::Target<TARGET_TYPE_MCA>& i_target )
std::vector<uint64_t> l_ranks;
// A vector of CCS instructions. We'll ask the targets to fill it, and then we'll execute it
- ccs::program<TARGET_TYPE_MCBIST> l_program;
+ ccs::program l_program;
// Clear the initial delays. This will force the CCS engine to recompute the delay based on the
// instructions in the CCS instruction vector
l_program.iv_poll.iv_initial_delay = 0;
l_program.iv_poll.iv_initial_sim_delay = 0;
- // We expect to come in with the port in STR. Before proceeding with
- // restoring the RCD, power down needs to be disabled first on the RCD so
- // the rest of the CWs can be restored with CKE low
- for ( const auto& d : mss::find_targets<TARGET_TYPE_DIMM>(i_target) )
- {
- FAPI_DBG("rc09_disable_powerdown for %s", mss::c_str(d));
- FAPI_TRY( rc09_disable_powerdown(d, l_program.iv_instructions),
- "Failed rc09_disable_powerdown() for %s", mss::c_str(d) );
- }// dimms
-
- // Exit STR first so CKE is back to high and rcd isn't ignoring us
- FAPI_TRY( self_refresh_exit( i_target ) );
-
- FAPI_TRY( mss::ccs::workarounds::nvdimm::execute(l_mcbist, l_program, i_target),
- "Failed to execute ccs for %s", mss::c_str(i_target) );
-
- // Now, drive CKE back to low via STR entry instead of pde (we have data in the drams!)
- FAPI_TRY( self_refresh_entry( i_target ) );
-
- l_program = ccs::program<TARGET_TYPE_MCBIST>(); //Reset the program
-
// Now, fill the program with instructions to program the RCD
for ( const auto& d : mss::find_targets<TARGET_TYPE_DIMM>(i_target) )
{
@@ -513,7 +457,7 @@ fapi2::ReturnCode post_restore_zqcal( const fapi2::Target<fapi2::TARGET_TYPE_MCA
const auto& l_mcbist = mss::find_target<TARGET_TYPE_MCBIST>(i_target);
std::vector<uint64_t> l_ranks;
uint8_t l_trp[MAX_DIMM_PER_PORT];
- ccs::program<TARGET_TYPE_MCBIST> l_program;
+ ccs::program l_program;
// Get tRP
FAPI_TRY(mss::eff_dram_trp(mss::find_target<fapi2::TARGET_TYPE_MCS>(i_target), l_trp));
@@ -526,9 +470,9 @@ fapi2::ReturnCode post_restore_zqcal( const fapi2::Target<fapi2::TARGET_TYPE_MCA
for ( const auto r : l_ranks)
{
FAPI_DBG("precharge_all_command for %s", mss::c_str(d));
- l_program.iv_instructions.push_back( ccs::precharge_all_command<TARGET_TYPE_MCBIST>(r, l_trp[0]) );
+ l_program.iv_instructions.push_back( ccs::precharge_all_command(r, l_trp[0]) );
FAPI_DBG("zqcal_command for %s", mss::c_str(d));
- l_program.iv_instructions.push_back( ccs::zqcl_command<TARGET_TYPE_MCBIST>(r, mss::tzqinit()) );
+ l_program.iv_instructions.push_back( ccs::zqcl_command(r, mss::tzqinit()) );
}
}// dimms
@@ -608,12 +552,12 @@ fapi2::ReturnCode post_restore_transition( const fapi2::Target<fapi2::TARGET_TYP
FAPI_TRY(get_refresh_overrun_mask(i_target, l_refresh_overrun_mask));
FAPI_TRY(change_refresh_overrun_mask(i_target, mss::states::ON));
- // Restore the rcd
- FAPI_TRY( rcd_restore( i_target ) );
-
// Exit STR
FAPI_TRY( self_refresh_exit( i_target ) );
+ // Restore the rcd
+ FAPI_TRY( rcd_restore( i_target ) );
+
// Load the MRS
FAPI_TRY( mss::mrs_load( i_target, NVDIMM_WORKAROUND ) );
@@ -635,6 +579,26 @@ fapi_try_exit:
}
///
+/// @brief Helper to change the BAR valid state. Consumed by hostboot
+/// @param[in] i_target the target associated with this subroutine
+/// @return FAPI2_RC_SUCCESS iff setup was successful
+///
+fapi2::ReturnCode change_bar_valid_state( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint8_t i_state)
+{
+ const auto& l_mcs = mss::find_target<fapi2::TARGET_TYPE_MCS>(i_target);
+ fapi2::buffer<uint64_t> l_data;
+
+ FAPI_TRY( mss::getScom(l_mcs, MCS_MCFGP, l_data) );
+ l_data.writeBit<MCS_MCFGP_VALID>(i_state);
+ FAPI_INF("Changing MCS_MCFGP_VALID to %d on %s", i_state, mss::c_str(l_mcs));
+ FAPI_TRY( mss::putScom(l_mcs, MCS_MCFGP, l_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Preload the CCS with the EPOW sequence
/// @param[in] i_target the target associated with this subroutine
/// @return FAPI2_RC_SUCCESS iff setup was successful
@@ -643,15 +607,15 @@ fapi_try_exit:
///
fapi2::ReturnCode preload_epow_sequence( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target )
{
- typedef ccsTraits<fapi2::TARGET_TYPE_MCBIST> TT;
+ typedef ccsTraits<mss::mc_type::NIMBUS> TT;
const auto& l_mcbist = mss::find_target<TARGET_TYPE_MCBIST>(i_target);
const auto& l_dimms = mss::find_targets<TARGET_TYPE_DIMM>(i_target);
constexpr uint64_t CS_N_ACTIVE = 0b00;
uint8_t l_trp = 0;
uint16_t l_trfc = 0;
std::vector<uint64_t> l_ranks;
- ccs::program<TARGET_TYPE_MCBIST> l_program;
- ccs::instruction_t<TARGET_TYPE_MCBIST> l_inst;
+ ccs::program l_program;
+ ccs::instruction_t l_inst;
// Get tRP and tRFC
FAPI_TRY(mss::eff_dram_trp(i_target, l_trp));
@@ -662,14 +626,14 @@ fapi2::ReturnCode preload_epow_sequence( const fapi2::Target<fapi2::TARGET_TYPE_
// Start the program with DES and wait for tRFC
// All CKE = high, all CSn = high, Reset_n = high, wait tRFC
- l_inst = ccs::des_command<TARGET_TYPE_MCBIST>(l_trfc);
+ l_inst = ccs::des_command(l_trfc);
l_inst.arr0.setBit<TT::ARR0_DDR_RESETN>();
FAPI_INF("des_command() arr0 = 0x%016lx , arr1 = 0x%016lx", l_inst.arr0, l_inst.arr1);
l_program.iv_instructions.push_back(l_inst);
// Precharge all command
// All CKE = high, all CSn = low, Reset_n = high, wait tRP
- l_inst = ccs::precharge_all_command<TARGET_TYPE_MCBIST>(0, l_trp);
+ l_inst = ccs::precharge_all_command(0, l_trp);
l_inst.arr0.insertFromRight<TT::ARR0_DDR_CSN_0_1, TT::ARR0_DDR_CSN_0_1_LEN>(CS_N_ACTIVE);
l_inst.arr0.insertFromRight<TT::ARR0_DDR_CSN_2_3, TT::ARR0_DDR_CSN_2_3_LEN>(CS_N_ACTIVE);
l_inst.arr0.setBit<TT::ARR0_DDR_RESETN>();
@@ -678,7 +642,7 @@ fapi2::ReturnCode preload_epow_sequence( const fapi2::Target<fapi2::TARGET_TYPE_
// Self-refresh entry command
// All CKE = low, all CSn = low, Reset_n = high, wait tCKSRE
- l_inst = ccs::self_refresh_entry_command<TARGET_TYPE_MCBIST>(0, mss::tcksre(l_dimms[0]));
+ l_inst = ccs::self_refresh_entry_command(0, mss::tcksre(l_dimms[0]));
l_inst.arr0.insertFromRight<TT::ARR0_DDR_CSN_0_1, TT::ARR0_DDR_CSN_0_1_LEN>(CS_N_ACTIVE);
l_inst.arr0.insertFromRight<TT::ARR0_DDR_CSN_2_3, TT::ARR0_DDR_CSN_2_3_LEN>(CS_N_ACTIVE);
l_inst.arr0.insertFromRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(mss::CKE_LOW);
@@ -688,7 +652,7 @@ fapi2::ReturnCode preload_epow_sequence( const fapi2::Target<fapi2::TARGET_TYPE_
// Push in an empty instruction for RESETn
// All CKE = low, all CSn = high (default), Reset_n = low
- l_inst = ccs::instruction_t<TARGET_TYPE_MCBIST>();
+ l_inst = ccs::instruction_t();
FAPI_INF("Assert RESETn arr0 = 0x%016lx , arr1 = 0x%016lx", l_inst.arr0, l_inst.arr1);
l_program.iv_instructions.push_back(l_inst);
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.H
index a3c4914a4..8345cae05 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.H
@@ -34,11 +34,11 @@
// *HWP Consumed by: FSP:HB
#include <fapi2.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <lib/shared/mss_const.H>
-#include <lib/ccs/ccs.H>
#include <lib/phy/dp16.H>
#include <lib/mc/port.H>
+#include <generic/memory/lib/ccs/ccs.H>
namespace mss
{
@@ -182,15 +182,6 @@ template< fapi2::TargetType T >
fapi2::ReturnCode self_refresh_exit( const fapi2::Target<T>& i_target );
///
-/// @brief Disable powerdown mode in rc09
-/// @param[in] i_target, a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in,out] io_inst a vector of CCS instructions we should add to
-/// @return FAPI2_RC_SUCCESS if and only if ok
-///
-fapi2::ReturnCode rc09_disable_powerdown( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
-
-///
/// @brief Load the rcd control words
/// @param[in] i_target, a fapi2::Target<TARGET_TYPE_DIMM>
/// @param[in,out] io_inst a vector of CCS instructions we should add to
@@ -199,7 +190,7 @@ fapi2::ReturnCode rc09_disable_powerdown( const fapi2::Target<fapi2::TARGET_TYPE
/// with NVDIMMs
///
fapi2::ReturnCode rcd_load_nvdimm( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Restore the rcd after restoring the nvdimm data
@@ -237,6 +228,14 @@ template< fapi2::TargetType T >
fapi2::ReturnCode post_restore_transition( const fapi2::Target<T>& i_target );
///
+/// @brief Helper to change the BAR valid state. Consumed by hostboot
+/// @param[in] i_target the target associated with this subroutine
+/// @return FAPI2_RC_SUCCESS iff setup was successful
+///
+fapi2::ReturnCode change_bar_valid_state( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint8_t i_state);
+
+///
/// @brief Preload the CCS with the EPOW sequence
/// @param[in] i_target the target associated with this subroutine
/// @return FAPI2_RC_SUCCESS iff setup was successful
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pba.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pba.C
index c1cab4997..a864ea8d2 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pba.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pba.C
@@ -35,10 +35,11 @@
#include <lib/shared/nimbus_defaults.H>
#include <fapi2.H>
-
+#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/ccs/ccs.H>
+#include <lib/utils/nimbus_find.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
#include <lib/dimm/ddr4/data_buffer_ddr4.H>
#include <lib/phy/phy_cntrl.H>
#include <lib/dimm/ddr4/pba.H>
@@ -113,7 +114,7 @@ fapi_try_exit:
///
fapi2::ReturnCode enter( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target )
{
- ccs::program<fapi2::TARGET_TYPE_MCBIST> l_program;
+ ccs::program l_program;
const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
@@ -145,7 +146,7 @@ fapi_try_exit:
///
fapi2::ReturnCode exit( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target )
{
- ccs::program<fapi2::TARGET_TYPE_MCBIST> l_program;
+ ccs::program l_program;
const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
@@ -200,10 +201,10 @@ fapi2::ReturnCode execute_commands( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>
// Issue PBA commands
{
- ccs::program<fapi2::TARGET_TYPE_MCBIST> l_program;
+ ccs::program l_program;
// Inserts the DES command to ensure we keep our CKE high
- l_program.iv_instructions.push_back(mss::ccs::des_command<fapi2::TARGET_TYPE_MCBIST>());
+ l_program.iv_instructions.push_back(mss::ccs::des_command());
// Makes a copy of the vector, so we can do the function space swaps correctly
auto l_bcws = i_bcws;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pba.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pba.H
index 34706d492..c2d47fed3 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pba.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pba.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,8 +39,9 @@
#include <fapi2.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/ccs/ccs.H>
+#include <lib/utils/nimbus_find.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
#include <lib/dimm/ddr4/data_buffer_ddr4.H>
#include <map>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.C
index a89cee0e2..8eb698a62 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,10 +37,13 @@
#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>
+#include <lib/shared/mss_const.H>
+#include <lib/mc/port.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/ccs/ccs.H>
+#include <lib/utils/nimbus_find.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
#include <lib/dimm/mrs_load.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>
#include <lib/dimm/ddr4/latch_wr_vref.H>
@@ -49,6 +52,7 @@
#include <lib/dimm/ddr4/pda.H>
#include <lib/workarounds/ccs_workarounds.H>
+
namespace mss
{
@@ -209,7 +213,7 @@ fapi_try_exit:
///
fapi2::ReturnCode add_enable( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst )
+ std::vector< ccs::instruction_t >& io_inst )
{
mss::ddr4::mrs03_data l_mrs03( i_target, fapi2::current_err );
FAPI_TRY( fapi2::current_err, "%s Unable to construct MRS03 data from attributes", mss::c_str(i_target));
@@ -232,7 +236,7 @@ fapi_try_exit:
fapi2::ReturnCode enter( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank )
{
- ccs::program<fapi2::TARGET_TYPE_MCBIST> l_program;
+ ccs::program l_program;
const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
@@ -261,7 +265,7 @@ fapi_try_exit:
///
fapi2::ReturnCode add_disable( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst )
+ std::vector< ccs::instruction_t >& io_inst )
{
mss::ddr4::mrs03_data l_mrs03( i_target, fapi2::current_err );
FAPI_TRY( fapi2::current_err, "%s Unable to construct MRS03 data from attributes", mss::c_str(i_target));
@@ -284,7 +288,7 @@ fapi_try_exit:
fapi2::ReturnCode exit( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank )
{
- ccs::program<fapi2::TARGET_TYPE_MCBIST> l_program;
+ ccs::program l_program;
const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
@@ -344,7 +348,7 @@ fapi2::ReturnCode execute_wr_vref_latch( const fapi2::Target<fapi2::TARGET_TYPE_
// Issue MRS commands
{
- ccs::program<fapi2::TARGET_TYPE_MCBIST> l_program;
+ ccs::program l_program;
FAPI_TRY(mss::ddr4::add_latch_wr_vref_commands( i_target,
i_mrs,
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.H
index 379b0a2ba..c28dcceac 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/pda.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,14 +38,18 @@
#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
+#include <lib/mc/port.H>
+#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/ccs/ccs.H>
+#include <lib/utils/nimbus_find.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
#include <lib/phy/write_cntrl.H>
#include <lib/dimm/mrs_load.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>
+
#include <map>
namespace mss
@@ -170,7 +174,7 @@ fapi2::ReturnCode blast_dram_config( const fapi2::Target<fapi2::TARGET_TYPE_MCA>
///
fapi2::ReturnCode add_enable( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst );
+ std::vector< ccs::instruction_t >& io_inst );
///
/// @brief Enters into and configures PDA mode
@@ -190,7 +194,7 @@ fapi2::ReturnCode enter( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
///
fapi2::ReturnCode add_disable( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst );
+ std::vector< ccs::instruction_t >& io_inst );
///
/// @brief Exits out of and disables PDA mode
@@ -313,7 +317,7 @@ class commands
// Check for a valid rank
FAPI_ASSERT(mss::rank::is_rank_on_dimm(i_target, i_rank),
fapi2::MSS_INVALID_RANK().
- set_MCA_TARGET(mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target)).
+ set_PORT_TARGET(mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target)).
set_RANK(i_rank).
set_FUNCTION(mss::ffdc_function_codes::PDA_ADD_COMMAND),
"%s does not have rank %lu", mss::c_str(i_target), i_rank);
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C
index 6e53bddd8..e522f970f 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,13 +36,17 @@
#include <lib/shared/nimbus_defaults.H>
#include <vector>
#include <fapi2.H>
+#include <lib/shared/mss_const.H>
#include <lib/dimm/ddr4/zqcal.H>
#include <lib/dimm/ddr4/data_buffer_ddr4.H>
-#include <lib/ccs/ccs.H>
+#include <lib/mc/port.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
#include <lib/eff_config/timing.H>
#include <lib/workarounds/ccs_workarounds.H>
+
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_DIMM;
@@ -61,15 +65,15 @@ namespace mss
template<>
fapi2::ReturnCode setup_dram_zqcal( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
- ccs::instruction_t<TARGET_TYPE_MCBIST> l_inst;
+ ccs::instruction_t l_inst;
uint64_t tDLLK = 0;
FAPI_TRY( mss::tdllk(i_target, tDLLK) );
// Note: this isn't general - assumes Nimbus via MCBIST instruction here BRS
- l_inst = ccs::zqcl_command<TARGET_TYPE_MCBIST>(i_rank);
+ l_inst = ccs::zqcl_command(i_rank);
// Doubling tZQ to better margin per lab request
{
@@ -98,7 +102,7 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode setup_data_buffer_zqcal( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
// For LRDIMMs, program BCW to send ZQCal Long command to all data buffers
// in broadcast mode
@@ -128,7 +132,7 @@ template<>
fapi2::ReturnCode setup_and_execute_zqcal( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const fapi2::buffer<uint32_t>& i_cal_steps_enabled)
{
- mss::ccs::program<TARGET_TYPE_MCBIST> l_program;
+ mss::ccs::program l_program;
for ( const auto& d : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target) )
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.H
index d78a512f1..d80febc3b 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,7 +38,11 @@
#include <vector>
#include <fapi2.H>
-#include <lib/ccs/ccs.H>
+#include <lib/mc/port.H>
+#include <lib/shared/mss_const.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
+
namespace mss
{
@@ -46,28 +50,26 @@ namespace mss
///
/// @brief Setup DRAM ZQCL
/// @tparam T the target type associated with this cal
-/// @tparam TT the target type of the CCS instruction
/// @param[in] i_target the target associated with this cal
/// @param[in] i_rank the current rank
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
-template< fapi2::TargetType T, fapi2::TargetType TT >
+template< fapi2::TargetType T >
fapi2::ReturnCode setup_dram_zqcal( const fapi2::Target<T>& i_target,
const uint64_t i_rank,
- std::vector< ccs::instruction_t<TT> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Setup LRDIMM data buffer ZQCL
/// @tparam T the target type associated with this cal
-/// @tparam TT the target type of the CCS instruction
/// @param[in] i_target the target associated with this cal
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
-template< fapi2::TargetType T, fapi2::TargetType TT >
+template< fapi2::TargetType T >
fapi2::ReturnCode setup_data_buffer_zqcal( const fapi2::Target<T>& i_target,
- std::vector< ccs::instruction_t<TT> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Setup and execute DRAM ZQCL
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
index 38f6e9bae..2c3a3a757 100755..100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
@@ -44,13 +44,14 @@
#include <lib/dimm/ddr4/mrs_load_ddr4.H>
#include <lib/dimm/rank.H>
#include <lib/utils/mss_nimbus_conversions.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <lib/dimm/eff_dimm.H>
#include <lib/dimm/mrs_load.H>
#include <lib/shared/mss_kind.H>
#include <lib/phy/dp16.H>
#include <lib/mss_attribute_accessors_manual.H>
#include <generic/memory/lib/utils/freq/gen_mss_freq.H>
+#include <lib/workarounds/eff_config_workarounds.H>
namespace mss
{
@@ -366,16 +367,6 @@ enum invalid_freq_function_encoding : uint8_t
F0BC6X = 0x60,
};
-///
-/// @brief encoding for MSS_INVALID_TIMING so we can look up functions based on encoding
-///
-enum invalid_timing_function_encoding : uint8_t
-{
- TRRD_S = 0,
- TRRD_L = 1,
- TFAW = 2,
-};
-
/////////////////////////
// Non-member function implementations
/////////////////////////
@@ -1577,6 +1568,7 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_dimm::dimm_rc03()
{
+ constexpr uint8_t NVDIMM_RCW_WORKAROUND_VALUE = 0x08;
fapi2::buffer<uint8_t> l_buffer;
uint8_t l_attrs_dimm_rc03[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
@@ -1599,6 +1591,10 @@ fapi2::ReturnCode eff_dimm::dimm_rc03()
l_buffer.insertFromRight<CA_START, LEN>(l_ca_output_drive)
.insertFromRight<CS_START, LEN>(l_cs_output_drive);
}
+
+ // Update the value if the NVDIMM workaround is needed
+ FAPI_TRY(mss::workarounds::eff_config::nvdimm_rc_drive_strength(iv_dimm, NVDIMM_RCW_WORKAROUND_VALUE, l_buffer));
+
// Retrieve MCS attribute data
FAPI_TRY( eff_dimm_ddr4_rc03(iv_mcs, &l_attrs_dimm_rc03[0][0]) );
@@ -1618,6 +1614,7 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_dimm::dimm_rc04()
{
+ constexpr uint8_t NVDIMM_RCW_WORKAROUND_VALUE = 0x0a;
uint8_t l_attrs_dimm_rc04[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
uint8_t l_odt_output_drive = 0;
uint8_t l_cke_output_drive = 0;
@@ -1641,6 +1638,9 @@ fapi2::ReturnCode eff_dimm::dimm_rc04()
.insertFromRight<ODT_START, LEN>(l_odt_output_drive);
}
+ // Update the value if the NVDIMM workaround is needed
+ FAPI_TRY(mss::workarounds::eff_config::nvdimm_rc_drive_strength(iv_dimm, NVDIMM_RCW_WORKAROUND_VALUE, l_buffer));
+
// Retrieve MCS attribute data
FAPI_TRY( eff_dimm_ddr4_rc04(iv_mcs, &l_attrs_dimm_rc04[0][0]) );
@@ -1660,6 +1660,7 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_dimm::dimm_rc05()
{
+ constexpr uint8_t NVDIMM_RCW_WORKAROUND_VALUE = 0x0a;
uint8_t l_attrs_dimm_rc05[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
uint8_t l_a_side_output_drive = 0;
uint8_t l_b_side_output_drive = 0;
@@ -1683,6 +1684,9 @@ fapi2::ReturnCode eff_dimm::dimm_rc05()
.insertFromRight<A_START, LEN>(l_a_side_output_drive);
}
+ // Update the value if the NVDIMM workaround is needed
+ FAPI_TRY(mss::workarounds::eff_config::nvdimm_rc_drive_strength(iv_dimm, NVDIMM_RCW_WORKAROUND_VALUE, l_buffer));
+
// Retrieve MCS attribute data
FAPI_TRY( eff_dimm_ddr4_rc05(iv_mcs, &l_attrs_dimm_rc05[0][0]) );
@@ -2960,36 +2964,44 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_lrdimm::vref_dq_train_value_and_range()
{
- constexpr uint8_t VREF_73PERCENT = 0x14;
- constexpr uint8_t VREF_83PERCENT = 0x24;
- constexpr uint8_t TRAIN_VALUE[NUM_VALID_RANKS_CONFIGS] =
- {
- VREF_73PERCENT, // 2 ranks per DIMM
- VREF_83PERCENT, // 4 ranks per DIMM
- };
- // Yes, range1 has a value of 0 this is taken from the JEDEC spec
- constexpr uint8_t RANGE1 = 0x00;
- constexpr uint8_t TRAIN_RANGE[NUM_VALID_RANKS_CONFIGS] =
- {
- RANGE1,
- RANGE1,
- };
-
-
+ // Bits for range decode from the SPD
+ constexpr uint8_t RANK0 = 7;
+ constexpr uint8_t RANK1 = 6;
+ constexpr uint8_t RANK2 = 5;
+ constexpr uint8_t RANK3 = 4;
uint8_t l_vref_dq_train_value[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
uint8_t l_vref_dq_train_range[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
+ fapi2::buffer<uint8_t > l_range;
// Gets the attributes
FAPI_TRY( eff_vref_dq_train_value(iv_mcs, &l_vref_dq_train_value[0][0][0]) );
FAPI_TRY( eff_vref_dq_train_range(iv_mcs, &l_vref_dq_train_range[0][0][0]) );
- // Using hardcoded values for 2R settings from the IBM SI team
- // It should be good enough to get us going
- for(uint64_t l_rank = 0; l_rank < MAX_RANK_PER_DIMM; ++l_rank)
- {
- l_vref_dq_train_value[iv_port_index][iv_dimm_index][mss::index(l_rank)] = TRAIN_VALUE[iv_master_ranks_index];
- l_vref_dq_train_range[iv_port_index][iv_dimm_index][mss::index(l_rank)] = TRAIN_RANGE[iv_master_ranks_index];
- }
+ // Value is easy, just drop the values in from the SPD
+ FAPI_TRY( iv_spd_decoder.dram_vref_dq_rank0(l_vref_dq_train_value[iv_port_index][iv_dimm_index][ATTR_RANK0]));
+ FAPI_TRY( iv_spd_decoder.dram_vref_dq_rank1(l_vref_dq_train_value[iv_port_index][iv_dimm_index][ATTR_RANK1]));
+ FAPI_TRY( iv_spd_decoder.dram_vref_dq_rank2(l_vref_dq_train_value[iv_port_index][iv_dimm_index][ATTR_RANK2]));
+ FAPI_TRY( iv_spd_decoder.dram_vref_dq_rank3(l_vref_dq_train_value[iv_port_index][iv_dimm_index][ATTR_RANK3]));
+
+ // Range requires some decoding
+ FAPI_TRY( iv_spd_decoder.dram_vref_dq_range(l_range));
+
+ // Do the decode for each rank
+ l_vref_dq_train_range[iv_port_index][iv_dimm_index][ATTR_RANK0] = l_range.getBit<RANK0>() ?
+ fapi2::ENUM_ATTR_EFF_VREF_DQ_TRAIN_RANGE_RANGE2 :
+ fapi2::ENUM_ATTR_EFF_VREF_DQ_TRAIN_RANGE_RANGE1;
+
+ l_vref_dq_train_range[iv_port_index][iv_dimm_index][ATTR_RANK1] = l_range.getBit<RANK1>() ?
+ fapi2::ENUM_ATTR_EFF_VREF_DQ_TRAIN_RANGE_RANGE2 :
+ fapi2::ENUM_ATTR_EFF_VREF_DQ_TRAIN_RANGE_RANGE1;
+
+ l_vref_dq_train_range[iv_port_index][iv_dimm_index][ATTR_RANK2] = l_range.getBit<RANK2>() ?
+ fapi2::ENUM_ATTR_EFF_VREF_DQ_TRAIN_RANGE_RANGE2 :
+ fapi2::ENUM_ATTR_EFF_VREF_DQ_TRAIN_RANGE_RANGE1;
+
+ l_vref_dq_train_range[iv_port_index][iv_dimm_index][ATTR_RANK3] = l_range.getBit<RANK3>() ?
+ fapi2::ENUM_ATTR_EFF_VREF_DQ_TRAIN_RANGE_RANGE2 :
+ fapi2::ENUM_ATTR_EFF_VREF_DQ_TRAIN_RANGE_RANGE1;
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_VREF_DQ_TRAIN_VALUE, iv_mcs, l_vref_dq_train_value),
"Failed setting attribute for ATTR_EFF_VREF_DQ_TRAIN_VALUE");
@@ -4090,7 +4102,7 @@ fapi2::ReturnCode eff_dimm::dram_trrd_s()
l_trrd_s_in_nck);
}
- FAPI_TRY( trrd_s( iv_dimm, iv_dram_width, l_jedec_trrd) );
+ FAPI_TRY( trrd_s( iv_dimm, iv_dram_width, iv_freq, l_jedec_trrd) );
// Taking the worst case between the required minimum JEDEC value and the proposed value from SPD
if (l_jedec_trrd != l_trrd_s_in_nck)
@@ -4166,7 +4178,7 @@ fapi2::ReturnCode eff_dimm::dram_trrd_l()
l_trrd_l_in_nck);
}
- FAPI_TRY( trrd_l( iv_dimm, iv_dram_width, l_jedec_trrd) );
+ FAPI_TRY( trrd_l( iv_dimm, iv_dram_width, iv_freq, l_jedec_trrd) );
// Taking the worst case between the required minimum JEDEC value and the proposed value from SPD
if (l_jedec_trrd != l_trrd_l_in_nck)
@@ -4265,7 +4277,7 @@ fapi2::ReturnCode eff_dimm::dram_tfaw()
l_tfaw_in_nck);
}
- FAPI_TRY( mss::tfaw(iv_dimm, iv_dram_width, l_jedec_tfaw_in_nck), "Failed tfaw()" );
+ FAPI_TRY( mss::tfaw(iv_dimm, iv_dram_width, iv_freq, l_jedec_tfaw_in_nck), "Failed tfaw()" );
// Taking the worst case between the required minimum JEDEC value and the proposed value from SPD
if (l_jedec_tfaw_in_nck != l_tfaw_in_nck)
@@ -4334,11 +4346,15 @@ fapi2::ReturnCode eff_dimm::dram_tras()
// which will give the best timing value for the dimm
// (like 2400 MT/s) which may be different than the system
// speed (if we were being limited by VPD or MRW restrictions)
- const uint64_t l_tras_in_ps = mss::tras(iv_dimm);
+ uint64_t l_tras_in_ps;
+ uint64_t l_freq = 0;
+ uint8_t l_tras_in_nck = 0;
// Calculate nck
std::vector<uint8_t> l_attrs_dram_tras(PORTS_PER_MCS, 0);
- uint8_t l_tras_in_nck = 0;
+
+ FAPI_TRY( freq(mss::find_target<fapi2::TARGET_TYPE_MCBIST>(iv_dimm), l_freq) );
+ l_tras_in_ps = mss::tras(iv_dimm, l_freq);
// Cast needed for calculations to be done on the same integral type
// as required by template deduction. We have iv_tCK_in_ps as a signed
@@ -4471,20 +4487,22 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_lrdimm::dram_rtt_nom()
{
- constexpr uint8_t DRAM_RTT_VALUES[NUM_VALID_RANKS_CONFIGS] =
- {
- 0b111, // 2R - 34Ohm
- 0b111, // 4R - 34Ohm
- };
+ std::vector< uint64_t > l_ranks;
+ uint8_t l_decoder_val = 0;
uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
FAPI_TRY( eff_dram_rtt_nom(iv_mcs, &l_mcs_attrs[0][0][0]) );
- for(uint64_t l_rank = 0; l_rank < MAX_RANK_PER_DIMM; ++l_rank)
+ // Get the value from the LRDIMM SPD
+ FAPI_TRY( iv_spd_decoder.dram_rtt_nom(iv_freq, l_decoder_val));
+
+ // Plug into every rank position for the attribute so it'll fit the same style as the RDIMM value
+ // Same value for every rank for LRDIMMs
+ FAPI_TRY(mss::rank::ranks(iv_dimm, l_ranks));
+
+ for (const auto& l_rank : l_ranks)
{
- // Gets the ODT scheme for the DRAM for this DIMM - we only want to toggle ODT to the DIMM we are writing to
- // We do a bitwise mask here to only get the ODT for the current DIMM
- l_mcs_attrs[iv_port_index][iv_dimm_index][mss::index(l_rank)] = DRAM_RTT_VALUES[iv_master_ranks_index];
+ l_mcs_attrs[iv_port_index][iv_dimm_index][mss::index(l_rank)] = l_decoder_val;
}
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RTT_NOM, iv_mcs, l_mcs_attrs) );
@@ -4553,25 +4571,22 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_lrdimm::dram_rtt_wr()
{
- constexpr uint8_t DRAM_RTT_VALUES[NUM_VALID_RANKS_CONFIGS] =
- {
- 0b000, // 2R - disable
- 0b001, // 4R - 120Ohm
- };
+ std::vector< uint64_t > l_ranks;
+ uint8_t l_decoder_val = 0;
uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
FAPI_TRY( eff_dram_rtt_wr(iv_mcs, &l_mcs_attrs[0][0][0]) );
- // The host is in charge of ensuring good termination from the buffer to the DRAM
- // That means that we need to know and set the settings
- // Currently, our SI team thinks that the 2R single drop open power settings will work for BUP
- // We're going to hard code in those settings the above story can be used as a catchall to improve settings if need be
- // Loops through all ranks
- for(uint64_t l_rank = 0; l_rank < MAX_RANK_PER_DIMM; ++l_rank)
+ // Get the value from the LRDIMM SPD
+ FAPI_TRY( iv_spd_decoder.dram_rtt_wr(iv_freq, l_decoder_val));
+
+ // Plug into every rank position for the attribute so it'll fit the same style as the RDIMM value
+ // Same value for every rank for LRDIMMs
+ FAPI_TRY(mss::rank::ranks(iv_dimm, l_ranks));
+
+ for (const auto& l_rank : l_ranks)
{
- // Gets the ODT scheme for the DRAM for this DIMM - we only want to toggle ODT to the DIMM we are writing to
- // We do a bitwise mask here to only get the ODT for the current DIMM
- l_mcs_attrs[iv_port_index][iv_dimm_index][l_rank] = DRAM_RTT_VALUES[iv_master_ranks_index];
+ l_mcs_attrs[iv_port_index][iv_dimm_index][mss::index(l_rank)] = l_decoder_val;
}
// Set the attribute
@@ -4632,28 +4647,27 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_lrdimm::dram_rtt_park()
{
- constexpr uint8_t DRAM_RTT_VALUES[NUM_VALID_RANKS_CONFIGS] =
- {
- 0b000, // 2R - disable
- 0b010, // 4R - 120Ohm
- };
-
uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
+ uint8_t l_decoder_val_01 = 0;
+ uint8_t l_decoder_val_23 = 0;
FAPI_TRY( eff_dram_rtt_park(iv_mcs, &l_mcs_attrs[0][0][0]) );
- // The host is in charge of ensuring good termination from the buffer to the DRAM
- // That means that we need to know and set the settings
- // Currently, our SI team thinks that the 2R single drop open power settings will work for BUP
- // We're going to hard code in those settings the above story can be used as a catchall to improve settings if need be
- // Loops through all ranks
- for(uint64_t l_rank = 0; l_rank < MAX_RANK_PER_DIMM; ++l_rank)
- {
- // Gets the ODT scheme for the DRAM for this DIMM - we only want to toggle ODT to the DIMM we are writing to
- // We do a bitwise mask here to only get the ODT for the current DIMM
- l_mcs_attrs[iv_port_index][iv_dimm_index][mss::index(l_rank)] = DRAM_RTT_VALUES[iv_master_ranks_index];
- }
+ // Get the value from the LRDIMM SPD
+ FAPI_TRY( iv_spd_decoder.dram_rtt_park_ranks0_1(iv_freq, l_decoder_val_01),
+ "%s failed to decode RTT_PARK for ranks 0/1", mss::c_str(iv_mcs) );
+ FAPI_TRY( iv_spd_decoder.dram_rtt_park_ranks2_3(iv_freq, l_decoder_val_23),
+ "%s failed to decode RTT_PARK for ranks 2/3", mss::c_str(iv_mcs) );
+ // Setting the four rank values for this dimm
+ // Rank 0 and 1 have the same value, l_decoder_val_01
+ // Rank 2 and 3 have the same value, l_decoder_val_23
+ l_mcs_attrs[iv_port_index][iv_dimm_index][ATTR_RANK0] = l_decoder_val_01;
+ l_mcs_attrs[iv_port_index][iv_dimm_index][ATTR_RANK1] = l_decoder_val_01;
+ l_mcs_attrs[iv_port_index][iv_dimm_index][ATTR_RANK2] = l_decoder_val_23;
+ l_mcs_attrs[iv_port_index][iv_dimm_index][ATTR_RANK3] = l_decoder_val_23;
+
+ // Set the attribute
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_RTT_PARK, iv_mcs, l_mcs_attrs) );
fapi_try_exit:
@@ -4956,13 +4970,18 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_lrdimm::dimm_bc04()
{
+ uint8_t l_decoder_val = 0;
// Retrieve MCS attribute data
uint8_t l_attrs_dimm_bc04[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
FAPI_TRY( eff_dimm_ddr4_bc04(iv_mcs, &l_attrs_dimm_bc04[0][0]) );
- // Taken from SI spreadsheet and JEDEC - we want 60 Ohms, so 0x01 for a value
- l_attrs_dimm_bc04[iv_port_index][iv_dimm_index] = 0x01;
+ // So the encoding from the SPD is the same as the encoding for the buffer control encoding
+ // Simple grab and insert
+ // Value is checked in decoder function for validity
+ FAPI_TRY( iv_spd_decoder.data_buffer_mdq_rtt(iv_freq, l_decoder_val) );
+ l_attrs_dimm_bc04[iv_port_index][iv_dimm_index] = l_decoder_val;
+ // Update MCS attribute
FAPI_INF("%s: BC04 settting (MDQ_RTT): %d", mss::c_str(iv_dimm), l_attrs_dimm_bc04[iv_port_index][iv_dimm_index] );
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC04, iv_mcs, l_attrs_dimm_bc04) );
@@ -4980,20 +4999,20 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_lrdimm::dimm_bc05()
{
- // Taken from the SI spreadsheet - we want 34 Ohms so 0x01
- fapi2::buffer<uint8_t> l_result(0x01);
+ uint8_t l_decoder_val = 0;
// Retrieve MCS attribute data
uint8_t l_attrs_dimm_bc05[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
FAPI_TRY( eff_dimm_ddr4_bc05(iv_mcs, &l_attrs_dimm_bc05[0][0]) );
- // Using a writeBit for clarity sake
- // Enabling DQ/DQS drivers
- l_result.writeBit<BC05_DRAM_DQ_DRIVER_DISABLE_POS>(BC05_DRAM_DQ_DRIVER_ENABLE);
- l_attrs_dimm_bc05[iv_port_index][iv_dimm_index] = l_result;
+ // Same as BC04, grab from SPD and put into BC
+ FAPI_TRY( iv_spd_decoder.data_buffer_mdq_drive_strength(iv_freq, l_decoder_val) );
+ l_attrs_dimm_bc05[iv_port_index][iv_dimm_index] = l_decoder_val;
- FAPI_INF("%s: BC05 settting (MDQ Drive Strength): 0x%02x", mss::c_str(iv_dimm),
+ FAPI_INF("%s: BC05 settting (MDQ Drive Strength): %d", mss::c_str(iv_dimm),
l_attrs_dimm_bc05[iv_port_index][iv_dimm_index] );
+
+ // Updates the attribute
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_BC05, iv_mcs, l_attrs_dimm_bc05) );
fapi_try_exit:
@@ -5514,20 +5533,17 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_lrdimm::dimm_f5bc6x()
{
- constexpr uint8_t VREF_73PERCENT = 0x14;
- constexpr uint8_t VREF_83PERCENT = 0x24;
- constexpr uint8_t RD_VREF[NUM_VALID_RANKS_CONFIGS] =
- {
- VREF_73PERCENT, // 2 ranks per DIMM
- VREF_83PERCENT, // 4 ranks per DIMM
- };
+ uint8_t l_decode = 0;
uint8_t l_attrs_dimm_f5bc6x[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
// Retrieve MCS attribute data
FAPI_TRY( eff_dimm_ddr4_f5bc6x(iv_mcs, &l_attrs_dimm_f5bc6x[0][0]) );
+ // Gets the SPD value
+ FAPI_TRY( iv_spd_decoder.data_buffer_vref_dq(l_decode));
+
// F5BC6x is just the VREF training range
- l_attrs_dimm_f5bc6x[iv_port_index][iv_dimm_index] = RD_VREF[iv_master_ranks_index];
+ l_attrs_dimm_f5bc6x[iv_port_index][iv_dimm_index] = l_decode;
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_F5BC6x, iv_mcs, l_attrs_dimm_f5bc6x),
"Failed setting attribute for ATTR_EFF_DIMM_DDR4_F5BC6x");
@@ -5678,7 +5694,7 @@ fapi2::ReturnCode eff_dimm::decode_vpd(const fapi2::Target<TARGET_TYPE_MCS>& i_t
set_MAX(mss::VPD_KEYWORD_MAX).
set_ACTUAL(l_vpd_info.iv_size).
set_KEYWORD(fapi2::MemVpdData::MT).
- set_MCS_TARGET(i_target),
+ set_VPD_TARGET(i_target),
"VPD MT keyword size retrieved: %d, is larger than max: %d for %s",
l_vpd_info.iv_size, mss::VPD_KEYWORD_MAX, mss::c_str(i_target));
@@ -5702,7 +5718,7 @@ fapi2::ReturnCode eff_dimm::decode_vpd(const fapi2::Target<TARGET_TYPE_MCS>& i_t
set_MAX(mss::VPD_KEYWORD_MAX).
set_ACTUAL(l_vpd_info.iv_size).
set_KEYWORD(fapi2::MemVpdData::MR).
- set_MCS_TARGET(i_target),
+ set_VPD_TARGET(i_target),
"VPD MR keyword size retrieved: %d, is larger than max: %d for %s",
l_vpd_info.iv_size, mss::VPD_KEYWORD_MAX, mss::c_str(i_target));
@@ -5723,7 +5739,7 @@ fapi2::ReturnCode eff_dimm::decode_vpd(const fapi2::Target<TARGET_TYPE_MCS>& i_t
set_MAX(mss::VPD_KEYWORD_MAX).
set_ACTUAL(l_vpd_info.iv_size).
set_KEYWORD(fapi2::MemVpdData::CK).
- set_MCS_TARGET(i_target),
+ set_VPD_TARGET(i_target),
"VPD CK keyword size retrieved: %d, is larger than max: %d for %s",
l_vpd_info.iv_size, mss::VPD_KEYWORD_MAX, mss::c_str(i_target));
@@ -5742,7 +5758,7 @@ fapi2::ReturnCode eff_dimm::decode_vpd(const fapi2::Target<TARGET_TYPE_MCS>& i_t
set_MAX(mss::VPD_KEYWORD_MAX).
set_ACTUAL(l_vpd_info.iv_size).
set_KEYWORD(fapi2::MemVpdData::DQ).
- set_MCS_TARGET(i_target),
+ set_VPD_TARGET(i_target),
"VPD DQ keyword size retrieved: %d, is larger than max: %d for %s",
l_vpd_info.iv_size, mss::VPD_KEYWORD_MAX, mss::c_str(i_target));
@@ -5989,10 +6005,13 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_lrdimm::odt_wr()
{
+ // Values were obtained experimentally
+ // For 2R, opposite termination is ideal
+ // For 4R, terminating everything is ideal
constexpr uint8_t DRAM_ODT_VALUES[NUM_VALID_RANKS_CONFIGS][MAX_RANK_PER_DIMM] =
{
{ 0x44, 0x88, 0x00, 0x00, }, // 2 ranks per DIMM
- { 0x44, 0x88, 0x44, 0x88, }, // 4 ranks per DIMM
+ { 0xcc, 0xcc, 0xcc, 0xcc, }, // 4 ranks per DIMM
};
// Masks on the ODT for a specific DIMM
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H
index f60adaf7c..477b7114c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H
@@ -38,7 +38,7 @@
#include <generic/memory/lib/spd/common/rcw_settings.H>
#include <lib/spd/spd_factory.H>
#include <lib/eff_config/timing.H>
-#include <generic/memory/lib/data_engine/pre_data_init.H>
+#include <lib/eff_config/pre_data_init.H>
#include <generic/memory/lib/spd/spd_utils.H>
namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/kind.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/kind.H
deleted file mode 100644
index ee707c821..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/kind.H
+++ /dev/null
@@ -1,263 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/kind.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file dimm.H
-/// @brief Encapsulation for dimms of all types
-///
-// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
-// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: HB:FSP
-
-#ifndef _MSS_DIMM_H_
-#define _MSS_DIMM_H_
-
-#include <fapi2.H>
-
-#include <lib/mss_attribute_accessors.H>
-#include <generic/memory/lib/utils/c_str.H>
-
-namespace mss
-{
-
-namespace dimm
-{
-
-///
-/// @class mss::dimm::kind
-/// @brief A class containing information about a dimm like ranks, density, configuration - what kind of dimm is it?
-///
-class kind
-{
- public:
-
- ///
- /// @brief Generate a vector of DIMM kind from a vector of DIMM
- /// @param[in] i_dimm a vector of DIMM
- /// @return std::vector of dimm::kind relating to the DIMM passed in
- ///
- static std::vector<kind> vector(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& i_dimm)
- {
- std::vector<kind> l_kinds;
-
- for (const auto& d : i_dimm)
- {
- l_kinds.push_back( kind(d) );
- }
-
- return l_kinds;
- }
-
- ///
- /// @brief operator=() - assign kinds (needed to sort vectors of kinds)
- /// @param[in] i_rhs the right hand side of the assignment statement
- /// @return reference to this
- ///
- inline kind& operator=(const kind& i_rhs)
- {
- iv_target = i_rhs.iv_target;
- iv_master_ranks = i_rhs.iv_master_ranks;
- iv_total_ranks = i_rhs.iv_total_ranks;
- iv_dram_density = i_rhs.iv_dram_density;
- iv_dram_width = i_rhs.iv_dram_width;
- iv_dram_generation = i_rhs.iv_dram_generation;
- iv_dimm_type = i_rhs.iv_dimm_type;
- iv_rows = i_rhs.iv_rows;
- iv_size = i_rhs.iv_size;
- iv_mfgid = i_rhs.iv_mfgid;
- iv_stack_type = i_rhs.iv_stack_type;
- iv_hybrid = i_rhs.iv_hybrid;
- iv_hybrid_memory_type = i_rhs.iv_hybrid_memory_type;
- iv_rcd_mfgid = i_rhs.iv_rcd_mfgid;
- return *this;
- }
-
- ///
- /// @brief operator==() - are two kinds the same?
- /// @param[in] i_rhs the right hand side of the comparison statement
- /// @return bool true iff the two kind are of the same kind
- /// @warning this does not compare the targets (iv_target,) just the values
- /// Also does not compare the mfgid as that's not really part of the DIMM kind but is additional information
- ///
- inline bool operator==(const kind& i_rhs) const
- {
- return ((iv_master_ranks == i_rhs.iv_master_ranks) &&
- (iv_total_ranks == i_rhs.iv_total_ranks) &&
- (iv_dram_density == i_rhs.iv_dram_density) &&
- (iv_dram_width == i_rhs.iv_dram_width) &&
- (iv_dram_generation == i_rhs.iv_dram_generation) &&
- (iv_dimm_type == i_rhs.iv_dimm_type) &&
- (iv_rows == i_rhs.iv_rows) &&
- (iv_size == i_rhs.iv_size) &&
- (iv_stack_type == i_rhs.iv_stack_type) &&
- (iv_hybrid == i_rhs.iv_hybrid) &&
- (iv_hybrid_memory_type == i_rhs.iv_hybrid_memory_type) &&
- (iv_rcd_mfgid == i_rhs.iv_rcd_mfgid));
- }
-
- ///
- /// @brief operator!=() - are two kinds different?
- /// @param[in] i_rhs the right hand side of the comparison statement
- /// @return bool true iff the two kind are of different
- /// @warning this does not compare the targets (iv_target,) just the values
- ///
- inline bool operator!=(const kind& i_rhs) const
- {
- return !(this->operator==(i_rhs));
- }
-
- ///
- /// @brief Construct a dimm::kind data structure - information about the kind of DIMM this is
- /// @param[in] i_target a DIMM target
- ///
- kind(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target):
- iv_target(i_target)
- {
- FAPI_TRY( mss::eff_dram_gen(i_target, iv_dram_generation) );
- FAPI_TRY( mss::eff_dimm_type(i_target, iv_dimm_type) );
- FAPI_TRY( mss::eff_dram_density(i_target, iv_dram_density) );
- FAPI_TRY( mss::eff_dram_width(i_target, iv_dram_width) );
- FAPI_TRY( mss::eff_num_master_ranks_per_dimm(i_target, iv_master_ranks) );
- FAPI_TRY( mss::eff_num_ranks_per_dimm(i_target, iv_total_ranks) );
- FAPI_TRY( mss::eff_dram_row_bits(i_target, iv_rows) );
- FAPI_TRY( mss::eff_dimm_size(i_target, iv_size) );
- FAPI_TRY( mss::eff_dram_mfg_id(i_target, iv_mfgid) );
- FAPI_TRY( mss::eff_prim_stack_type( i_target, iv_stack_type) );
- FAPI_TRY( mss::eff_hybrid( i_target, iv_hybrid ));
- FAPI_TRY( mss::eff_hybrid_memory_type( i_target, iv_hybrid_memory_type ));
- FAPI_TRY( mss::eff_rcd_mfg_id(i_target, iv_rcd_mfgid) );
- return;
-
- fapi_try_exit:
- // Not 100% sure what to do here ...
- FAPI_ERR("error initializing DIMM structure: %s 0x%016lx", mss::c_str(i_target), uint64_t(fapi2::current_err));
- fapi2::Assert(false);
- }
-
- ///
- /// @brief Construct a DIMM kind used to identify this DIMM for tables.
- /// @param[in] i_master_ranks number of master ranks on the DIMM
- /// @param[in] i_total_ranks total number of ranks on the DIMM
- /// @param[in] i_dram_density density of the DRAM
- /// @param[in] i_dram_width width of the DRAM
- /// @param[in] i_dram_generation DRAM generation
- /// @param[in] i_dimm_type DIMM type (e.g. RDIMM)
- /// @param[in] i_rows number of rows in the DRAM
- /// @param[in] i_size the overal size of the DIMM in GB
- /// @param[in] i_mfgid the dram manufacturer id of the dimm, defaulted to 0
- /// @param[in] i_stack_type dram die type, single die package or 3DS
- /// @param[in] i_hybrid, default not hybrid
- /// @param[in] i_hybrid_memory_type, defult none
- /// @param[in] i_rcd_mfgid dimm register and data buffer manufacturer id, default 0
- /// @note can't be constexpr as fapi2::Target doesn't have a constexpr ctor.
- ///
- kind( const uint8_t i_master_ranks,
- const uint8_t i_total_ranks,
- const uint8_t i_dram_density,
- const uint8_t i_dram_width,
- const uint8_t i_dram_generation,
- const uint8_t i_dimm_type,
- const uint8_t i_rows,
- const uint32_t i_size,
- const uint16_t i_mfgid = 0,
- const uint8_t i_stack_type = fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_SDP,
- const uint8_t i_hybrid = fapi2::ENUM_ATTR_EFF_HYBRID_NOT_HYBRID,
- const uint8_t i_hybrid_memory_type = fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NONE,
- const uint16_t i_rcd_mfgid = 0):
- iv_target(0),
- iv_master_ranks(i_master_ranks),
- iv_total_ranks(i_total_ranks),
- iv_dram_density(i_dram_density),
- iv_dram_width(i_dram_width),
- iv_dram_generation(i_dram_generation),
- iv_dimm_type(i_dimm_type),
- iv_rows(i_rows),
- // TK consider calculating size rather than requiring it be set.
- iv_size(i_size),
- iv_mfgid(i_mfgid),
- iv_stack_type(i_stack_type),
- iv_hybrid(i_hybrid),
- iv_hybrid_memory_type(i_hybrid_memory_type),
- iv_rcd_mfgid(i_rcd_mfgid)
- {
- // Bit of an idiot-check to be sure a hand-crafted dimm::kind make sense wrt slaves, masters, packages, etc.
- // Both of these are checked in eff_config. If they are messed up, they should be caught there
- if (iv_master_ranks > iv_total_ranks)
- {
- FAPI_ERR("Not enough total ranks? master: %d total: %d",
- iv_master_ranks,
- iv_total_ranks);
- fapi2::Assert(false);
- }
-
- if ((iv_total_ranks % iv_master_ranks) != 0)
- {
- FAPI_ERR("total or master ranks seems incorrect. master: %d total: %d",
- iv_master_ranks,
- iv_total_ranks);
- fapi2::Assert(false);
- }
- }
-
- fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
- uint8_t iv_master_ranks;
- uint8_t iv_total_ranks;
- uint8_t iv_dram_density;
- uint8_t iv_dram_width;
- uint8_t iv_dram_generation;
- uint8_t iv_dimm_type;
- uint8_t iv_rows;
- uint32_t iv_size;
- uint16_t iv_mfgid;
- uint8_t iv_stack_type;
- uint8_t iv_hybrid;
- uint8_t iv_hybrid_memory_type;
- uint16_t iv_rcd_mfgid;
-
- ///
- /// @brief equal_config
- /// @param[in] i_input_compare the i_kind to compare against
- /// @return bool true iff the two kind are of the same kind for xlate purposes
- /// @warning this does not compare the targets (iv_target,), mfgid, prim_stack_type nor hybrid type
- ///
- inline bool equal_config(const kind& i_input_compare) const
- {
- return ((iv_master_ranks == i_input_compare.iv_master_ranks) &&
- (iv_total_ranks == i_input_compare.iv_total_ranks) &&
- (iv_dram_density == i_input_compare.iv_dram_density) &&
- (iv_dram_width == i_input_compare.iv_dram_width) &&
- (iv_dram_generation == i_input_compare.iv_dram_generation) &&
- (iv_dimm_type == i_input_compare.iv_dimm_type) &&
- (iv_rows == i_input_compare.iv_rows) &&
- (iv_size == i_input_compare.iv_size));
- }
-};
-
-}
-
-}
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.C
index aae4cce28..8928a6f98 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.C
@@ -62,7 +62,7 @@ fapi2::ReturnCode mrs_load<TARGET_TYPE_MCA>( const fapi2::Target<TARGET_TYPE_MCA
const auto& l_mcbist = mss::find_target<TARGET_TYPE_MCBIST>(i_target);
// A vector of CCS instructions. We'll ask the targets to fill it, and then we'll execute it
- ccs::program<TARGET_TYPE_MCBIST> l_program;
+ ccs::program l_program;
// Clear the initial delays. This will force the CCS engine to recompute the delay based on the
// instructions in the CCS instruction vector
@@ -72,7 +72,17 @@ fapi2::ReturnCode mrs_load<TARGET_TYPE_MCA>( const fapi2::Target<TARGET_TYPE_MCA
for ( const auto& d : find_targets<TARGET_TYPE_DIMM>(i_target) )
{
FAPI_DBG("mrs load for %s", mss::c_str(d));
- FAPI_TRY( perform_mrs_load(d, l_program.iv_instructions) );
+
+ // TK - break out the nvdimm stuff into function
+ if (i_nvdimm_workaround)
+ {
+ FAPI_DBG("nvdimm workaround detected. loading mrs for restore sequence");
+ FAPI_TRY( ddr4::mrs_load_nvdimm(d, l_program.iv_instructions) );
+ }
+ else
+ {
+ FAPI_TRY( perform_mrs_load(d, l_program.iv_instructions) );
+ }
}
// We have to configure the CCS engine to let it know which port these instructions are
@@ -121,7 +131,7 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode perform_mrs_load<DEFAULT_KIND>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
uint8_t l_type = 0;
uint8_t l_gen = 0;
@@ -151,7 +161,7 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode perform_mrs_load<KIND_RDIMM_DDR4>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
FAPI_DBG("perform mrs_load for %s [expecting rdimm (ddr4)]", mss::c_str(i_target));
FAPI_TRY( ddr4::mrs_load(i_target, io_inst) );
@@ -168,7 +178,7 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode perform_mrs_load<KIND_LRDIMM_DDR4>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
FAPI_DBG("perform mrs_load for %s [expecting lrdimm (ddr4)]", mss::c_str(i_target));
FAPI_TRY( ddr4::mrs_load(i_target, io_inst) );
@@ -186,7 +196,7 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode perform_mrs_load<FORCE_DISPATCH>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
uint8_t l_type = 0;
uint8_t l_gen = 0;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.H
index f19679bc7..f18050f12 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.H
@@ -38,10 +38,13 @@
#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
+#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/c_str.H>
#include <lib/shared/mss_kind.H>
-#include <lib/ccs/ccs.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
+
namespace mss
{
@@ -90,15 +93,15 @@ struct mrs_data
// The attribute getter. For MRS we pass in the ARR0 of the CCS instruction
// as that allows us to encapsulate the attribute processing and the bit
// manipulation in one function.
- fapi2::ReturnCode (*iv_func)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&, ccs::instruction_t<T>&, const uint64_t);
- fapi2::ReturnCode (*iv_dumper)(const ccs::instruction_t<T>&, const uint64_t);
+ fapi2::ReturnCode (*iv_func)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&, ccs::instruction_t&, const uint64_t);
+ fapi2::ReturnCode (*iv_dumper)(const ccs::instruction_t&, const uint64_t);
// The delay needed after this MRS word is written
uint64_t iv_delay;
mrs_data( const uint64_t i_mrs,
- fapi2::ReturnCode (*i_func)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&, ccs::instruction_t<T>&, const uint64_t),
- fapi2::ReturnCode (*i_dumper)(const ccs::instruction_t<T>&, const uint64_t),
+ fapi2::ReturnCode (*i_func)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&, ccs::instruction_t&, const uint64_t),
+ fapi2::ReturnCode (*i_dumper)(const ccs::instruction_t&, const uint64_t),
const uint64_t i_delay ):
iv_mrs(i_mrs),
iv_func(i_func),
@@ -174,7 +177,7 @@ struct perform_mrs_load_overload< KIND_LRDIMM_DDR4 >
template< mss::kind_t K = FORCE_DISPATCH >
typename std::enable_if< perform_mrs_load_overload<DEFAULT_KIND>::available, fapi2::ReturnCode>::type
perform_mrs_load( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Function to perform mrs load overloads
@@ -186,7 +189,7 @@ perform_mrs_load( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
///
template<>
fapi2::ReturnCode perform_mrs_load<FORCE_DISPATCH>( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Function to perform mrs load overloads
/// @param[in] i_target the dimm target for the mrs's
@@ -197,7 +200,7 @@ fapi2::ReturnCode perform_mrs_load<FORCE_DISPATCH>( const fapi2::Target<fapi2::T
///
template<>
fapi2::ReturnCode perform_mrs_load<DEFAULT_KIND>( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Function to perform mrs load overloads
/// @param[in] i_kind the i_target's dimm_kind struct
@@ -208,7 +211,7 @@ fapi2::ReturnCode perform_mrs_load<DEFAULT_KIND>( const fapi2::Target<fapi2::TAR
template< kind_t K, bool B = perform_mrs_load_overload<K>::available >
inline fapi2::ReturnCode perform_mrs_load_dispatch( const kind_t& i_kind,
const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
// We dispatch to another kind if:
// We don't have an overload defined (B == false)
@@ -232,7 +235,7 @@ inline fapi2::ReturnCode perform_mrs_load_dispatch( const kind_t& i_kind,
template<>
inline fapi2::ReturnCode perform_mrs_load_dispatch<DEFAULT_KIND>(const kind_t&,
const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
return perform_mrs_load<DEFAULT_KIND>(i_target, io_inst);
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/nimbus_kind.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/nimbus_kind.H
new file mode 100644
index 000000000..6c8d16bc0
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/nimbus_kind.H
@@ -0,0 +1,85 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/nimbus_kind.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file nimbus_kind.H
+/// @brief Encapsulation for dimms of all types
+///
+// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_NIMBUS_KIND_H_
+#define _MSS_NIMBUS_KIND_H_
+
+#include <fapi2.H>
+
+#include <lib/shared/mss_const.H>
+#include <lib/mss_attribute_accessors.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/utils/dimm/kind.H>
+
+namespace mss
+{
+
+namespace dimm
+{
+
+///
+/// @class mss::dimm::kind specilization for NIMBUS
+/// @brief A class containing information about a dimm like ranks, density, configuration - what kind of dimm is it?
+///
+template<>
+inline kind<mss::mc_type::NIMBUS>::kind(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target) :
+ iv_target(i_target),
+ iv_module_height(0)
+{
+ FAPI_TRY( mss::eff_dram_gen(i_target, iv_dram_generation) );
+ FAPI_TRY( mss::eff_dimm_type(i_target, iv_dimm_type) );
+ FAPI_TRY( mss::eff_dram_density(i_target, iv_dram_density) );
+ FAPI_TRY( mss::eff_dram_width(i_target, iv_dram_width) );
+ FAPI_TRY( mss::eff_num_master_ranks_per_dimm(i_target, iv_master_ranks) );
+ FAPI_TRY( mss::eff_num_ranks_per_dimm(i_target, iv_total_ranks) );
+ FAPI_TRY( mss::eff_dram_row_bits(i_target, iv_rows) );
+ FAPI_TRY( mss::eff_dimm_size(i_target, iv_size) );
+ FAPI_TRY( mss::eff_dram_mfg_id(i_target, iv_mfgid) );
+ FAPI_TRY( mss::eff_prim_stack_type( i_target, iv_stack_type) );
+ FAPI_TRY( mss::eff_hybrid( i_target, iv_hybrid ));
+ FAPI_TRY( mss::eff_hybrid_memory_type( i_target, iv_hybrid_memory_type ));
+ FAPI_TRY( mss::eff_rcd_mfg_id(i_target, iv_rcd_mfgid) );
+ return;
+
+fapi_try_exit:
+ // Not 100% sure what to do here ...
+ FAPI_ERR("error initializing DIMM structure: %s 0x%016lx", mss::c_str(i_target), uint64_t(fapi2::current_err));
+ fapi2::Assert(false);
+}
+
+
+} //ns dimm
+} //ns mss
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.C
index 37af40a5b..1026634b1 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -902,6 +902,25 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief Return a vector of rank numbers which represent the ranks for this dimm
+/// @param[in] i_dimm_target TARGET_TYPE_DIMM
+/// @param[out] o_ranks a vector of ranks for dimm (numbers)
+/// @return FAPI2_RC_SUCCESS iff all is ok
+///
+template<>
+fapi2::ReturnCode ranks_on_dimm_helper<mss::mc_type::NIMBUS>(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&
+ i_dimm_target,
+ std::vector<uint64_t>& o_ranks)
+{
+ std::vector<uint64_t> l_ranks;
+ FAPI_TRY( mss::rank::ranks(i_dimm_target, l_ranks) );
+ o_ranks = l_ranks;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
} // namespace rank
} // namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H
index 901ed1a8c..130697bbb 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H
@@ -41,7 +41,7 @@
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>
#include <generic/memory/lib/utils/scom.H>
-#include <lib/utils/num.H>
+#include <generic/memory/lib/utils/num.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <lib/shared/mss_const.H>
#include <lib/phy/phy_cntrl.H>
@@ -1033,7 +1033,7 @@ inline fapi2::ReturnCode set_rank_field( const fapi2::Target<T>& i_target,
FAPI_ASSERT( false,
fapi2::MSS_INVALID_RANK()
.set_RANK(i_rank)
- .set_MCA_TARGET(i_target)
+ .set_PORT_TARGET(i_target)
.set_FUNCTION(SET_RANK_FIELD),
"%s Invalid rank (%d) in set_rank_field",
mss::c_str(i_target),
@@ -1101,7 +1101,7 @@ inline fapi2::ReturnCode get_rank_field( const fapi2::Target<T>& i_target,
FAPI_ASSERT( false,
fapi2::MSS_INVALID_RANK()
.set_RANK(i_rank)
- .set_MCA_TARGET(i_target)
+ .set_PORT_TARGET(i_target)
.set_FUNCTION(GET_RANK_FIELD),
"%s Invalid rank (%d) in get_ranks_in_pair",
mss::c_str(i_target),
@@ -1171,7 +1171,7 @@ inline fapi2::ReturnCode set_pair_valid( const fapi2::Target<T>& i_target,
FAPI_ASSERT( false,
fapi2::MSS_INVALID_RANK()
.set_RANK(i_rank)
- .set_MCA_TARGET(i_target)
+ .set_PORT_TARGET(i_target)
.set_FUNCTION(SET_PAIR_VALID),
"%s Invalid rank (%d) in get_ranks_in_pair",
mss::c_str(i_target),
@@ -1243,7 +1243,7 @@ inline fapi2::ReturnCode get_pair_valid( const fapi2::Target<T> i_target,
FAPI_ASSERT( false,
fapi2::MSS_INVALID_RANK()
.set_RANK(i_rank)
- .set_MCA_TARGET(i_target)
+ .set_PORT_TARGET(i_target)
.set_FUNCTION(GET_PAIR_VALID),
"%s Invalid rank (%d) passed into get get_pair_valid",
mss::c_str(i_target),
@@ -1350,7 +1350,7 @@ fapi2::ReturnCode get_ranks_in_pair( const fapi2::Target<T>& i_target,
FAPI_ASSERT( l_ordinal < MAX_RANK_PER_DIMM,
fapi2::MSS_INVALID_RANK()
.set_RANK(l_ordinal)
- .set_MCA_TARGET(i_target)
+ .set_PORT_TARGET(i_target)
.set_FUNCTION(GET_RANKS_IN_PAIR),
"%s Invalid rank (%d) in set_ranks_in_pair",
mss::c_str(i_target),
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load.C
index c999666cd..17bba3a88 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,7 +38,7 @@
#include <mss.H>
#include <lib/dimm/rcd_load.H>
#include <lib/dimm/rcd_load_ddr4.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
@@ -60,7 +60,7 @@ fapi2::ReturnCode rcd_load<TARGET_TYPE_MCA>( const fapi2::Target<TARGET_TYPE_MCA
const auto& l_mcbist = mss::find_target<TARGET_TYPE_MCBIST>(i_target);
// A vector of CCS instructions. We'll ask the targets to fill it, and then we'll execute it
- ccs::program<TARGET_TYPE_MCBIST> l_program;
+ ccs::program l_program;
uint8_t l_sim = 0;
// Clear the initial delays. This will force the CCS engine to recompute the delay based on the
@@ -76,7 +76,7 @@ fapi2::ReturnCode rcd_load<TARGET_TYPE_MCA>( const fapi2::Target<TARGET_TYPE_MCA
// So we use the power down entry command to achieve this
if(!l_sim)
{
- l_program.iv_instructions.push_back( ccs::pde_command<TARGET_TYPE_MCBIST>() );
+ l_program.iv_instructions.push_back( ccs::pde_command() );
}
FAPI_DBG("rcd load for %s", mss::c_str(d));
@@ -119,7 +119,7 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode perform_rcd_load<DEFAULT_KIND>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& i_inst)
+ std::vector< ccs::instruction_t >& i_inst)
{
uint8_t l_type = 0;
uint8_t l_gen = 0;
@@ -149,7 +149,7 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode perform_rcd_load<KIND_RDIMM_DDR4>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& i_inst)
+ std::vector< ccs::instruction_t >& i_inst)
{
uint8_t l_sim = 0;
FAPI_TRY( mss::is_simulation(l_sim) );
@@ -170,7 +170,7 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode perform_rcd_load<KIND_LRDIMM_DDR4>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& i_inst)
+ std::vector< ccs::instruction_t >& i_inst)
{
uint8_t l_sim = 0;
FAPI_TRY( mss::is_simulation(l_sim) );
@@ -191,7 +191,7 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode perform_rcd_load<FORCE_DISPATCH>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& i_inst)
+ std::vector< ccs::instruction_t >& i_inst)
{
uint8_t l_type = 0;
uint8_t l_gen = 0;
@@ -206,4 +206,32 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief Helper function to bring CKE high and hold for 400 cycles
+/// @param[in] i_target MCA target on which to operate
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+fapi2::ReturnCode draminit_cke_helper( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target)
+{
+
+ auto l_des = mss::ccs::des_command();
+ mss::ccs::program l_program;
+
+ // Also a Deselect command must be registered as required from the Spec.
+ // Register DES instruction, which pulls CKE high. Idle 400 cycles, and then begin RCD loading
+ // Note: This only is sent to one of the MCA as we still have the mux_addr_sel bit set, meaning
+ // we'll PDE/DES all DIMM at the same time.
+ l_des.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(400);
+ l_program.iv_instructions.push_back(l_des);
+
+ FAPI_TRY( mss::ccs::execute(mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target),
+ l_program,
+ i_target),
+ "%s Failed execute in p9_mss_draminit",
+ mss::c_str(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
} // namespace
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load.H
index b9ee410d6..bfb73ae92 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,9 +39,11 @@
#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
-
#include <generic/memory/lib/utils/c_str.H>
#include <lib/shared/mss_kind.H>
+#include <lib/shared/mss_const.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
namespace mss
{
@@ -112,7 +114,7 @@ struct perform_rcd_load_overload< KIND_LRDIMM_DDR4 >
template< mss::kind_t K = FORCE_DISPATCH >
typename std::enable_if< perform_rcd_load_overload<DEFAULT_KIND>::available, fapi2::ReturnCode>::type
perform_rcd_load( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& i_inst);
+ std::vector< ccs::instruction_t >& i_inst);
//
// We know we registered overloads for perform_rcd_load, so we need the entry point to
@@ -121,11 +123,11 @@ perform_rcd_load( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
//
template<>
fapi2::ReturnCode perform_rcd_load<FORCE_DISPATCH>( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& i_inst);
+ std::vector< ccs::instruction_t >& i_inst);
template<>
fapi2::ReturnCode perform_rcd_load<DEFAULT_KIND>( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& i_inst);
+ std::vector< ccs::instruction_t >& i_inst);
///
/// @brief Start the rcd_load_dispatch boilerplate -- specialization for recursion dispatcher
@@ -137,7 +139,7 @@ fapi2::ReturnCode perform_rcd_load<DEFAULT_KIND>( const fapi2::Target<fapi2::TAR
template< kind_t K, bool B = perform_rcd_load_overload<K>::available >
inline fapi2::ReturnCode perform_rcd_load_dispatch( const kind_t& i_kind,
const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& i_inst)
+ std::vector< ccs::instruction_t >& i_inst)
{
// We dispatch to another kind if:
// We don't have an overload defined (B == false)
@@ -162,10 +164,17 @@ inline fapi2::ReturnCode perform_rcd_load_dispatch( const kind_t& i_kind,
template<>
inline fapi2::ReturnCode perform_rcd_load_dispatch<DEFAULT_KIND>(const kind_t&,
const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& i_inst)
+ std::vector< ccs::instruction_t >& i_inst)
{
return perform_rcd_load<DEFAULT_KIND>(i_target, i_inst);
}
+///
+/// @brief Helper function to bring CKE high and hold for 400 cycles
+/// @param[in] i_target MCA target on which to operate
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+fapi2::ReturnCode draminit_cke_helper( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target);
+
}
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.C
index 690b7e180..d9cc10e5b 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -60,7 +60,7 @@ namespace mss
///
fapi2::ReturnCode rcd_load_ddr4( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
const bool i_sim,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
FAPI_INF("rcd_load_ddr4 %s", mss::c_str(i_target));
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.H
index bb70c20b6..0c6f8162c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -53,6 +53,6 @@ namespace mss
///
fapi2::ReturnCode rcd_load_ddr4( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const bool i_sim,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
}
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc.H
deleted file mode 100644
index 5a657edac..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc.H
+++ /dev/null
@@ -1,789 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file ecc.H
-/// @brief Top level API for MSS ECC
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_ECC_H_
-#define _MSS_ECC_H_
-
-#include <fapi2.H>
-#include <lib/mcbist/mcbist.H>
-#include <lib/mcbist/address.H>
-#include <lib/ecc/ecc_traits.H>
-#include <lib/ecc/galois.H>
-#include <lib/ecc/hw_mark_store.H>
-#include <lib/ecc/fw_mark_store.H>
-#include <lib/ecc/mainline_nce_trap.H>
-#include <lib/ecc/mainline_rce_trap.H>
-#include <lib/ecc/mainline_mpe_trap.H>
-#include <lib/ecc/mainline_ue_trap.H>
-#include <lib/ecc/mainline_aue_trap.H>
-#include <lib/ecc/mbs_error_vector_trap.H>
-#include <lib/ecc/maint_current_trap.H>
-#include <lib/ecc/read_error_count_regs.H>
-#include <lib/ecc/modal_symbol_count.H>
-#include <lib/ecc/mark_shadow_reg.H>
-
-namespace mss
-{
-
-namespace ecc
-{
-
-///
-/// @brief Get Hardware Mark Store
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[in] i_rank the desired rank
-/// @param[out] o_galois the Galois code of the mark
-/// @param[out] o_confirmed true if the mark is a chipmark
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_hwms( const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- uint64_t& o_galois,
- mss::states& o_confirmed )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::hwms::read(i_target, i_rank, l_buffer) );
- mss::ecc::hwms::get_chipmark(l_buffer, o_galois);
- mss::ecc::hwms::get_confirmed(l_buffer, o_confirmed);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Set Hardware Mark Store
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[in] i_rank the desired rank
-/// @param[in] i_galois the Galois code of the mark, or set to 0 to clear mark
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode set_hwms( const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_galois )
-{
- fapi2::buffer<uint64_t> l_buffer;
- uint8_t l_symbol = 0;
-
- // galois value of 0 means to clear the mark so only fill in fields if non-zero
- if (i_galois != 0)
- {
- // check for valid Galois code
- FAPI_TRY( mss::ecc::galois_to_symbol( (uint8_t)i_galois, l_symbol) );
-
- mss::ecc::hwms::set_chipmark(l_buffer, i_galois);
- mss::ecc::hwms::set_confirmed(l_buffer, mss::YES);
- mss::ecc::hwms::set_exit_1(l_buffer, mss::YES);
- }
-
- FAPI_TRY( mss::ecc::hwms::write(i_target, i_rank, l_buffer) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Firmware Mark Store
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[in] i_rank the desired rank
-/// @param[out] o_galois the Galois code of the mark
-/// @param[out] o_type the type code of the mark
-/// @param[out] o_region the region code of the mark
-/// @param[out] o_address the starting address of the mark
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_fwms( const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- uint64_t& o_galois,
- mss::ecc::fwms::mark_type& o_type,
- mss::ecc::fwms::mark_region& o_region,
- mss::mcbist::address& o_address )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::fwms::read(i_target, i_rank, l_buffer) );
- mss::ecc::fwms::get_mark(l_buffer, o_galois);
- mss::ecc::fwms::get_type(l_buffer, o_type);
- mss::ecc::fwms::get_region(l_buffer, o_region);
- mss::ecc::fwms::get_address(l_buffer, o_address);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Set Firmware Mark Store
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[in] i_rank the desired rank
-/// @param[in] i_galois the Galois code of the mark, or set to 0 to clear mark
-/// @param[in] i_type the type code of the mark
-/// @param[in] i_region the region code of the mark
-/// @param[in] i_address the starting address of the mark
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode set_fwms( const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_galois,
- const mss::ecc::fwms::mark_type i_type,
- const mss::ecc::fwms::mark_region i_region,
- const mss::mcbist::address i_address )
-{
- fapi2::buffer<uint64_t> l_buffer = 0;
- uint8_t l_symbol = 0;
-
- // galois value of 0 means to clear the mark so only fill in fields if non-zero
- if (i_galois != 0)
- {
- // check for valid Galois code
- FAPI_TRY( mss::ecc::galois_to_symbol( (uint8_t)i_galois, l_symbol) );
-
- mss::ecc::fwms::set_mark(l_buffer, i_galois);
- mss::ecc::fwms::set_type(l_buffer, i_type);
- mss::ecc::fwms::set_region(l_buffer, i_region);
- mss::ecc::fwms::set_address(l_buffer, i_address);
- mss::ecc::fwms::set_exit_1(l_buffer, mss::YES);
- }
-
- FAPI_TRY( mss::ecc::fwms::write(i_target, i_rank, l_buffer) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Query Hardware Marks
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_marks vector of Galois codes of any marks set
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-/// @note no rank information is returned
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_hw_marks( const fapi2::Target<T>& i_target,
- std::vector<uint64_t>& o_marks )
-{
- fapi2::buffer<uint64_t> l_buffer;
- uint64_t l_galois = 0;
- auto l_confirmed = mss::states::NO;
-
- o_marks.clear();
-
- for (uint64_t l_rank = 0; l_rank < MAX_MRANK_PER_PORT; ++l_rank)
- {
- FAPI_TRY( get_hwms(i_target, l_rank, l_galois, l_confirmed) );
-
- if (l_confirmed == mss::states::YES)
- {
- o_marks.push_back(l_galois);
- }
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Query Firmware Marks
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_marks vector of Galois codes of any marks set
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-/// @note no rank information is returned
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_fw_marks( const fapi2::Target<T>& i_target,
- std::vector<uint64_t>& o_marks )
-{
- fapi2::buffer<uint64_t> l_buffer;
- uint64_t l_galois = 0;
- auto l_type = mss::ecc::fwms::mark_type::CHIP;
- auto l_region = mss::ecc::fwms::mark_region::UNIVERSAL;
- mss::mcbist::address l_address;
-
- o_marks.clear();
-
- for (uint64_t l_rank = 0; l_rank < MAX_MRANK_PER_PORT; ++l_rank)
- {
- FAPI_TRY( get_fwms(i_target, l_rank, l_galois, l_type, l_region, l_address) );
-
- if (l_region != mss::ecc::fwms::mark_region::DISABLED)
- {
- o_marks.push_back(l_galois);
- }
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Mainline NCE address traps
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_address the trap address of the last mainline nce
-/// @param[out] o_on_rce mss::YES if nce is part of an rce
-/// @param[out] o_is_tce mss::YES if nce is a tce
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_nce_addr_trap( const fapi2::Target<T>& i_target,
- mss::mcbist::address& o_address,
- mss::states& o_on_rce,
- mss::states& o_is_tce )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::mainline_nce_trap::read(i_target, l_buffer) );
- mss::ecc::mainline_nce_trap::get_address(l_buffer, o_address);
- mss::ecc::mainline_nce_trap::get_nce_on_rce(l_buffer, o_on_rce);
- mss::ecc::mainline_nce_trap::get_nce_is_tce(l_buffer, o_is_tce);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Mainline NCE error vector traps
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_galois the Galois code
-/// @param[out] o_magnitude the magnitude of the error
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_nce_error_vector_trap( const fapi2::Target<T>& i_target,
- uint64_t& o_galois,
- uint64_t& o_magnitude )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::mbs_error_vector_trap::read(i_target, l_buffer) );
- mss::ecc::mbs_error_vector_trap::get_nce_galois(i_target, l_buffer, o_galois);
- mss::ecc::mbs_error_vector_trap::get_nce_magnitude(i_target, l_buffer, o_magnitude);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Mainline TCE address traps
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_address the trap address of the last mainline nce
-/// @param[out] o_on_rce mss::YES if nce is part of an rce
-/// @param[out] o_is_tce mss::YES if nce is a tce
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_tce_addr_trap( const fapi2::Target<T>& i_target,
- mss::mcbist::address& o_address,
- mss::states& o_on_rce,
- mss::states& o_is_tce )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::mainline_nce_trap::read(i_target, l_buffer) );
- mss::ecc::mainline_nce_trap::get_address(l_buffer, o_address);
- mss::ecc::mainline_nce_trap::get_nce_on_rce(l_buffer, o_on_rce);
- mss::ecc::mainline_nce_trap::get_nce_is_tce(l_buffer, o_is_tce);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Mainline TCE error vector traps
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_nce_galois the Galois code
-/// @param[out] o_nce_magnitude the magnitude of the error
-/// @param[out] o_tce_galois the Galois code
-/// @param[out] o_tce_magnitude the magnitude of the error
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_tce_error_vector_trap( const fapi2::Target<T>& i_target,
- uint64_t& o_nce_galois,
- uint64_t& o_nce_magnitude,
- uint64_t& o_tce_galois,
- uint64_t& o_tce_magnitude )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::mbs_error_vector_trap::read(i_target, l_buffer) );
- mss::ecc::mbs_error_vector_trap::get_nce_galois(i_target, l_buffer, o_nce_galois);
- mss::ecc::mbs_error_vector_trap::get_nce_magnitude(i_target, l_buffer, o_nce_magnitude);
- mss::ecc::mbs_error_vector_trap::get_tce_galois(i_target, l_buffer, o_tce_galois);
- mss::ecc::mbs_error_vector_trap::get_tce_magnitude(i_target, l_buffer, o_tce_magnitude);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Mainline MPE address traps
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_address the trap address of the last mainline mpe
-/// @param[out] o_on_rce mss::YES if mpe is part of an rce
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_mpe_addr_trap( const fapi2::Target<T>& i_target,
- mss::mcbist::address& o_address,
- mss::states& o_on_rce )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::mainline_mpe_trap::read(i_target, l_buffer) );
- mss::ecc::mainline_mpe_trap::get_address(l_buffer, o_address);
- mss::ecc::mainline_mpe_trap::get_mpe_on_rce(l_buffer, o_on_rce);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Mainline RCE address traps
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_address the trap address of the last mainline rce
-/// @param[out] o_nce_on_rce mss::YES if nce is part of an rce
-/// @param[out] o_tce_on_rce mss::YES if tce is part of an rce
-/// @param[out] o_mpe_on_rce mss::YES if mpe is part of an rce
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_rce_addr_trap( const fapi2::Target<T>& i_target,
- mss::mcbist::address& o_address,
- mss::states& o_nce_on_rce,
- mss::states& o_tce_on_rce,
- mss::states& o_mpe_on_rce )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::mainline_rce_trap::read(i_target, l_buffer) );
- mss::ecc::mainline_rce_trap::get_address(l_buffer, o_address);
-
- FAPI_TRY( mss::ecc::mainline_nce_trap::read(i_target, l_buffer) );
- mss::ecc::mainline_nce_trap::get_nce_on_rce(l_buffer, o_nce_on_rce);
- mss::ecc::mainline_nce_trap::get_nce_is_tce(l_buffer, o_tce_on_rce);
-
- FAPI_TRY( mss::ecc::mainline_mpe_trap::read(i_target, l_buffer) );
- mss::ecc::mainline_mpe_trap::get_mpe_on_rce(l_buffer, o_mpe_on_rce);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Mainline UE address traps
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_address the trap address of the last mainline ue
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_ue_addr_trap( const fapi2::Target<T>& i_target,
- mss::mcbist::address& o_address )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::mainline_ue_trap::read(i_target, l_buffer) );
- mss::ecc::mainline_ue_trap::get_address(l_buffer, o_address);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Mainline AUE address traps
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_address the trap address of the last mainline aue
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_aue_addr_trap( const fapi2::Target<T>& i_target,
- mss::mcbist::address& o_address )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::mainline_aue_trap::read(i_target, l_buffer) );
- mss::ecc::mainline_aue_trap::get_address(l_buffer, o_address);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get IMPE address traps
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_chipmark the mark location (Galois code) of the last mark placed
-/// @param[out] o_rank the rank of the last mark placed
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_impe_addr_trap( const fapi2::Target<T>& i_target,
- uint64_t& o_chipmark,
- uint64_t& o_rank )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::mark_shadow_reg::read(i_target, l_buffer) );
- mss::ecc::mark_shadow_reg::get_chipmark(l_buffer, o_chipmark);
- mss::ecc::mark_shadow_reg::get_rank(l_buffer, o_rank);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Maint Current address traps
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_address the last address executed
-/// @param[out] o_port_trap port value if MCBCFGQ_cfg_current_addr_trap_update_dis == 0
-/// @param[out] o_dimm_trap dimm value if MCBCFGQ_cfg_current_addr_trap_update_dis == 0
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_maint_current_addr_trap( const fapi2::Target<T>& i_target,
- mss::mcbist::address& o_address,
- uint64_t& o_port_trap,
- uint64_t& o_dimm_trap )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::maint_current_trap::read(i_target, l_buffer) );
- mss::ecc::maint_current_trap::get_address(l_buffer, o_address);
- mss::ecc::maint_current_trap::get_port(l_buffer, o_port_trap);
- mss::ecc::maint_current_trap::get_dimm(l_buffer, o_dimm_trap);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Per Symbol Error Counts
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_error_counts vector of symbol error counts
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode get_per_symbol_error_counts( const fapi2::Target<T>& i_target,
- std::vector<uint64_t>& o_error_counts )
-{
- fapi2::buffer<uint64_t> l_buffer;
- uint64_t l_count = 0;
- o_error_counts.clear();
-
- for (uint64_t l_index = 0; l_index < TT::NUM_MBSSYM_REGS; ++l_index)
- {
- FAPI_TRY( mss::ecc::modal_symbol_count::read(i_target, l_index, l_buffer) );
-
- for (uint64_t l_symbol = 0; l_symbol < TT::MODAL_SYMBOL_COUNTERS_PER_REG; ++l_symbol)
- {
- l_count = 0;
- mss::ecc::modal_symbol_count::get_count(l_buffer, l_symbol, l_count);
- o_error_counts.push_back(l_count);
- }
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Intermittent NCE error count
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_count count of intermittent NCE events
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_intermittent_nce_count( const fapi2::Target<T>& i_target,
- uint64_t& o_count )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::read_error_count_reg0::read(i_target, l_buffer) );
- mss::ecc::read_error_count_reg0::get_intermittent_ce_count(l_buffer, o_count);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Soft NCE error count
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_count count of soft NCE events
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_soft_nce_count( const fapi2::Target<T>& i_target,
- uint64_t& o_count )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::read_error_count_reg0::read(i_target, l_buffer) );
- mss::ecc::read_error_count_reg0::get_soft_ce_count(l_buffer, o_count);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Hard NCE error count
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_count count of hard NCE events
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_hard_nce_count( const fapi2::Target<T>& i_target,
- uint64_t& o_count )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::read_error_count_reg0::read(i_target, l_buffer) );
- mss::ecc::read_error_count_reg0::get_hard_ce_count(l_buffer, o_count);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Intermittent MCE error count
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_count count of intermittent MCE events
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_intermittent_mce_count( const fapi2::Target<T>& i_target,
- uint64_t& o_count )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::read_error_count_reg0::read(i_target, l_buffer) );
- mss::ecc::read_error_count_reg0::get_intermittent_mce_count(l_buffer, o_count);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Soft MCE error count
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_count count of soft MCE events
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_soft_mce_count( const fapi2::Target<T>& i_target,
- uint64_t& o_count )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::read_error_count_reg0::read(i_target, l_buffer) );
- mss::ecc::read_error_count_reg0::get_soft_mce_count(l_buffer, o_count);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get Hard MCE error count
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_count count of hard MCE events
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_hard_mce_count( const fapi2::Target<T>& i_target,
- uint64_t& o_count )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::read_error_count_reg1::read(i_target, l_buffer) );
- mss::ecc::read_error_count_reg1::get_hard_mce_count(l_buffer, o_count);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get ICE (IMPE) error count
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_count count of ICE events
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_ice_count( const fapi2::Target<T>& i_target,
- uint64_t& o_count )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::read_error_count_reg1::read(i_target, l_buffer) );
- mss::ecc::read_error_count_reg1::get_ice_count(l_buffer, o_count);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get UE error count
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_count count of UE events
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_ue_count( const fapi2::Target<T>& i_target,
- uint64_t& o_count )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::read_error_count_reg1::read(i_target, l_buffer) );
- mss::ecc::read_error_count_reg1::get_ue_count(l_buffer, o_count);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get AUE error count
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_count count of AUE events
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_aue_count( const fapi2::Target<T>& i_target,
- uint64_t& o_count )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::read_error_count_reg1::read(i_target, l_buffer) );
- mss::ecc::read_error_count_reg1::get_aue_count(l_buffer, o_count);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get RCE error count
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_count count of RCE events
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_rce_count( const fapi2::Target<T>& i_target,
- uint64_t& o_count )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::read_error_count_reg1::read(i_target, l_buffer) );
- mss::ecc::read_error_count_reg1::get_rce_count(l_buffer, o_count);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Get MCE symbol count
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_symbol0_count count of symbol 0 errors
-/// @param[out] o_symbol1_count count of symbol 1 errors
-/// @param[out] o_symbol2_count count of symbol 2 errors
-/// @param[out] o_symbol3_count count of symbol 3 errors
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode get_mce_symbol_count( const fapi2::Target<T>& i_target,
- uint64_t& o_symbol0_count,
- uint64_t& o_symbol1_count,
- uint64_t& o_symbol2_count,
- uint64_t& o_symbol3_count )
-{
- fapi2::buffer<uint64_t> l_buffer;
-
- FAPI_TRY( mss::ecc::mark_symbol_count_reg::read(i_target, l_buffer) );
- mss::ecc::mark_symbol_count_reg::get_symbol0_count(l_buffer, o_symbol0_count);
- mss::ecc::mark_symbol_count_reg::get_symbol1_count(l_buffer, o_symbol1_count);
- mss::ecc::mark_symbol_count_reg::get_symbol2_count(l_buffer, o_symbol2_count);
- mss::ecc::mark_symbol_count_reg::get_symbol3_count(l_buffer, o_symbol3_count);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Clear all MAINT.ECC counters
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the fapi2 target
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode clear_all_counters( const fapi2::Target<T>& i_target )
-{
- return ( mss::mcbist::reset_errors(i_target) );
-}
-
-
-} // close namespace ecc
-
-} // close namespace mss
-
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits.H
deleted file mode 100644
index 7be0ef146..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits.H
+++ /dev/null
@@ -1,331 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file ecc_traits.H
-/// @brief Traits class for the MC ECC syndrome registers
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_ECC_TRAITS_H_
-#define _MSS_ECC_TRAITS_H_
-
-#include <p9_mc_scom_addresses.H>
-#include <p9_mc_scom_addresses_fld.H>
-#include <lib/shared/mss_const.H>
-
-namespace mss
-{
-
-///
-/// @class eccTraits
-/// @brief a collection of traits associated with the MC ECC interface
-/// @tparam T fapi2::TargetType representing the memory controller
-///
-template< fapi2::TargetType T >
-class eccTraits;
-
-///
-/// @class eccTraits
-/// @brief a collection of traits associated with the Centaur MC ECC interface
-///
-template<>
-class eccTraits<fapi2::TARGET_TYPE_MBA>
-{
-};
-
-///
-/// @class eccTraits
-/// @brief a collection of traits associated with the Nimbus MC ECC interface
-///
-template<>
-class eccTraits<fapi2::TARGET_TYPE_MCA>
-{
- public:
- // MCA ECC registers - must be 64 bits.
- static constexpr uint64_t HARDWARE_MS0_REG = MCA_HWMS0;
- static constexpr uint64_t HARDWARE_MS1_REG = MCA_WDF_HWMS1;
- static constexpr uint64_t HARDWARE_MS2_REG = MCA_HWMS2;
- static constexpr uint64_t HARDWARE_MS3_REG = MCA_HWMS3;
- static constexpr uint64_t HARDWARE_MS4_REG = MCA_HWMS4;
- static constexpr uint64_t HARDWARE_MS5_REG = MCA_HWMS5;
- static constexpr uint64_t HARDWARE_MS6_REG = MCA_HWMS6;
- static constexpr uint64_t HARDWARE_MS7_REG = MCA_HWMS7;
- static constexpr uint64_t FIRMWARE_MS0_REG = MCA_FWMS0;
- static constexpr uint64_t FIRMWARE_MS1_REG = MCA_WREITE_FWMS1;
- static constexpr uint64_t FIRMWARE_MS2_REG = MCA_FWMS2;
- static constexpr uint64_t FIRMWARE_MS3_REG = MCA_FWMS3;
- static constexpr uint64_t FIRMWARE_MS4_REG = MCA_FWMS4;
- static constexpr uint64_t FIRMWARE_MS5_REG = MCA_FWMS5;
- static constexpr uint64_t FIRMWARE_MS6_REG = MCA_FWMS6;
- static constexpr uint64_t FIRMWARE_MS7_REG = MCA_FWMS7;
- static constexpr uint64_t MARK_SHADOW_REG = MCA_MSR;
-
- // MCBIST ECC registers - Register API uses an MCA target instead
- // of MCBIST since MCA's relative position is needed to find
- // correct reg+field
- constexpr static const uint64_t MAINLINE_NCE_REGS[] =
- {
- MCBIST_MBNCER0Q,
- MCBIST_MBNCER1Q,
- MCBIST_MBNCER2Q,
- MCBIST_MBNCER3Q,
- };
-
- constexpr static const uint64_t MAINLINE_RCE_REGS[] =
- {
- MCBIST_MBRCER0Q,
- MCBIST_MBRCER1Q,
- MCBIST_MBRCER2Q,
- MCBIST_MBRCER3Q
- };
-
- constexpr static const uint64_t MAINLINE_MPE_REGS[] =
- {
- MCBIST_MBMPER0Q,
- MCBIST_MBMPER1Q,
- MCBIST_MBMPER2Q,
- MCBIST_MBMPER3Q
- };
-
- constexpr static const uint64_t MAINLINE_UE_REGS[] =
- {
- MCBIST_MBUER0Q,
- MCBIST_MBUER1Q,
- MCBIST_MBUER2Q,
- MCBIST_MBUER3Q
- };
-
- constexpr static const uint64_t MAINLINE_AUE_REGS[] =
- {
- MCBIST_MBAUER0Q,
- MCBIST_MBAUER1Q,
- MCBIST_MBAUER2Q,
- MCBIST_MBAUER3Q
- };
-
- // Note that these registers store info for a pair of ports
- // (thus the duplication)
- constexpr static const uint64_t ERROR_VECTOR_REGS[] =
- {
- MCBIST_MBSEVR0Q,
- MCBIST_MBSEVR0Q,
- MCBIST_MBSEVR1Q,
- MCBIST_MBSEVR1Q
- };
-
- // Fields, can be any size.
- enum
- {
- HARDWARE_MS_CHIPMARK = MCA_HWMS0_CHIPMARK,
- HARDWARE_MS_CHIPMARK_LEN = MCA_HWMS0_CHIPMARK_LEN,
- HARDWARE_MS_CONFIRMED = MCA_HWMS0_CONFIRMED,
- HARDWARE_MS_EXIT1 = MCA_HWMS0_EXIT_1,
- FIRMWARE_MS_MARK = MCA_FWMS0_MARK,
- FIRMWARE_MS_MARK_LEN = MCA_FWMS0_MARK_LEN,
- FIRMWARE_MS_TYPE = MCA_FWMS0_TYPE,
- FIRMWARE_MS_REGION = MCA_FWMS0_REGION,
- FIRMWARE_MS_REGION_LEN = MCA_FWMS0_REGION_LEN,
- FIRMWARE_MS_ADDRESS = MCA_FWMS0_ADDRESS,
- FIRMWARE_MS_ADDRESS_LEN = MCA_FWMS0_ADDRESS_LEN,
- FIRMWARE_MS_EXIT1 = MCA_FWMS0_EXIT_1,
- NCE_ADDR_TRAP = MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ADDR_TRAP,
- NCE_ADDR_TRAP_LEN = MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ADDR_TRAP_LEN,
- NCE_ON_RCE = MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ON_RCE,
- NCE_IS_TCE = MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_IS_TCE,
- RCE_ADDR_TRAP = MCBIST_MBRCER0Q_PORT_0_MAINLINE_RCE_ADDR_TRAP,
- RCE_ADDR_TRAP_LEN = MCBIST_MBRCER0Q_PORT_0_MAINLINE_RCE_ADDR_TRAP_LEN,
- MPE_ADDR_TRAP = MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ADDR_TRAP,
- MPE_ADDR_TRAP_LEN = MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ADDR_TRAP_LEN,
- MPE_ON_RCE = MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ON_RCE,
- UE_ADDR_TRAP = MCBIST_MBUER0Q_PORT_0_MAINLINE_UE_ADDR_TRAP,
- UE_ADDR_TRAP_LEN = MCBIST_MBUER0Q_PORT_0_MAINLINE_UE_ADDR_TRAP_LEN,
- AUE_ADDR_TRAP = MCBIST_MBAUER0Q_PORT_0_MAINLINE_AUE_ADDR_TRAP,
- AUE_ADDR_TRAP_LEN = MCBIST_MBAUER0Q_PORT_0_MAINLINE_AUE_ADDR_TRAP_LEN,
- P0_NCE_GALOIS = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_GALOIS_FIELD,
- P0_NCE_GALOIS_LEN = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_GALOIS_FIELD_LEN,
- P0_NCE_MAGNITUDE = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_MAGNITUDE_FIELD,
- P0_NCE_MAGNITUDE_LEN = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_MAGNITUDE_FIELD_LEN,
- P0_TCE_GALOIS = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_GALOIS_FIELD,
- P0_TCE_GALOIS_LEN = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_GALOIS_FIELD_LEN,
- P0_TCE_MAGNITUDE = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_MAGNITUDE_FIELD,
- P0_TCE_MAGNITUDE_LEN = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_MAGNITUDE_FIELD_LEN,
- P1_NCE_GALOIS = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_NCE_GALOIS_FIELD,
- P1_NCE_GALOIS_LEN = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_NCE_GALOIS_FIELD_LEN,
- P1_NCE_MAGNITUDE = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_NCE_MAGNITUDE_FIELD,
- P1_NCE_MAGNITUDE_LEN = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_NCE_MAGNITUDE_FIELD_LEN,
- P1_TCE_GALOIS = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_TCE_GALOIS_FIELD,
- P1_TCE_GALOIS_LEN = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_TCE_GALOIS_FIELD_LEN,
- P1_TCE_MAGNITUDE = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_TCE_MAGNITUDE_FIELD,
- P1_TCE_MAGNITUDE_LEN = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_TCE_MAGNITUDE_FIELD_LEN,
- CURRENT_ADDR_TRAP = MCBIST_MCBMCATQ_CFG_CURRENT_ADDR_TRAP,
- CURRENT_ADDR_TRAP_LEN = MCBIST_MCBMCATQ_CFG_CURRENT_ADDR_TRAP_LEN,
- CURRENT_PORT = MCBIST_MCBMCATQ_CFG_CURRENT_PORT_TRAP,
- CURRENT_PORT_LEN = MCBIST_MCBMCATQ_CFG_CURRENT_PORT_TRAP_LEN,
- CURRENT_DIMM = MCBIST_MCBMCATQ_CFG_CURRENT_DIMM_TRAP,
- SHADOW_CHIPMARK = MCA_MSR_CHIPMARK,
- SHADOW_CHIPMARK_LEN = MCA_MSR_CHIPMARK_LEN,
- SHADOW_RANK = MCA_MSR_RANK,
- SHADOW_RANK_LEN = MCA_MSR_RANK_LEN,
-
- };
-
- // Symbol to Galois code mapping table
- // Reference: Nimbus workbook, Section 13.1.6.2: Firmware Mark Store
- constexpr static const uint8_t symbol2galois[] =
- {
- 0x80, 0xa0, 0x90, 0xf0,
- 0x08, 0x0a, 0x09, 0x0f,
- 0x98, 0xda, 0xb9, 0x7f,
- 0x91, 0xd7, 0xb2, 0x78,
- 0x28, 0xea, 0x49, 0x9f,
- 0x9a, 0xd4, 0xbd, 0x76,
- 0x60, 0xb0, 0xc0, 0x20,
- 0x06, 0x0b, 0x0c, 0x02,
- 0xc6, 0xfb, 0x1c, 0x42,
- 0xca, 0xf4, 0x1d, 0x46,
- 0xd6, 0x8b, 0x3c, 0xc2,
- 0xcb, 0xf3, 0x1f, 0x4e,
- 0xe0, 0x10, 0x50, 0xd0,
- 0x0e, 0x01, 0x05, 0x0d,
- 0x5e, 0x21, 0xa5, 0x3d,
- 0x5b, 0x23, 0xaf, 0x3e,
- 0xfe, 0x61, 0x75, 0x5d,
- 0x51, 0x27, 0xa2, 0x38
- };
-
- // Symbol to DQ index mapping table
- // Reference: Nimbus workbook, Section 13.1.6.2: Firmware Mark Store
- constexpr static const uint8_t symbol2dq[] =
- {
- 71, 70, 69, 68,
- 67, 66, 65, 64,
- 63, 62, 61, 60,
- 55, 54, 53, 52,
- 47, 46, 45, 44,
- 39, 38, 37, 36,
- 31, 30, 29, 28,
- 23, 22, 21, 20,
- 15, 14, 13, 12,
- 7, 6, 5, 4,
- 59, 58, 57, 56,
- 51, 50, 49, 48,
- 43, 42, 41, 40,
- 35, 34, 33, 32,
- 27, 26, 25, 24,
- 19, 18, 17, 16,
- 11, 10, 9, 8,
- 3, 2, 1, 0
- };
-
-};
-
-///
-/// @class eccTraits
-/// @brief a collection of traits associated with the Nimbus MC ECC interface
-///
-template<>
-class eccTraits<fapi2::TARGET_TYPE_MCBIST>
-{
- public:
- // MCBIST ECC registers - must be 64 bits.
- static constexpr uint64_t READ_ERROR_COUNT_REG0 = MCBIST_MBSEC0Q;
- static constexpr uint64_t READ_ERROR_COUNT_REG1 = MCBIST_MBSEC1Q;
- static constexpr uint64_t MARK_SYMBOL_COUNT_REG = MCBIST_MBSMSECQ;
- static constexpr uint64_t MODAL_SYM_COUNT0_REG = MCBIST_MBSSYMEC0Q;
- static constexpr uint64_t MODAL_SYM_COUNT1_REG = MCBIST_MBSSYMEC1Q;
- static constexpr uint64_t MODAL_SYM_COUNT2_REG = MCBIST_MBSSYMEC2Q;
- static constexpr uint64_t MODAL_SYM_COUNT3_REG = MCBIST_MBSSYMEC3Q;
- static constexpr uint64_t MODAL_SYM_COUNT4_REG = MCBIST_MBSSYMEC4Q;
- static constexpr uint64_t MODAL_SYM_COUNT5_REG = MCBIST_MBSSYMEC5Q;
- static constexpr uint64_t MODAL_SYM_COUNT6_REG = MCBIST_MBSSYMEC6Q;
- static constexpr uint64_t MODAL_SYM_COUNT7_REG = MCBIST_MBSSYMEC7Q;
- static constexpr uint64_t MODAL_SYM_COUNT8_REG = MCBIST_MBSSYMEC8Q;
-
- // Stores the symbol counter registers in a vector for easier access for MCBIST
- static const std::vector<uint64_t> SYMBOL_COUNT_REG;
-
- // Fields, can be any size.
- enum
- {
- INTERMITTENT_CE_COUNT = MCBIST_MBSEC0Q_INTERMITTENT_CE_COUNT,
- INTERMITTENT_CE_COUNT_LEN = MCBIST_MBSEC0Q_INTERMITTENT_CE_COUNT_LEN,
- SOFT_CE_COUNT = MCBIST_MBSEC0Q_SOFT_CE_COUNT,
- SOFT_CE_COUNT_LEN = MCBIST_MBSEC0Q_SOFT_CE_COUNT_LEN,
- HARD_CE_COUNT = MCBIST_MBSEC0Q_HARD_CE_COUNT,
- HARD_CE_COUNT_LEN = MCBIST_MBSEC0Q_HARD_CE_COUNT_LEN,
- INTERMITTENT_MCE_COUNT = MCBIST_MBSEC0Q_INTERMITTENT_MCE_COUNT,
- INTERMITTENT_MCE_COUNT_LEN = MCBIST_MBSEC0Q_INTERMITTENT_MCE_COUNT_LEN,
- SOFT_MCE_COUNT = MCBIST_MBSEC0Q_SOFT_MCE_COUNT,
- SOFT_MCE_COUNT_LEN = MCBIST_MBSEC0Q_SOFT_MCE_COUNT_LEN,
- HARD_MCE_COUNT = MCBIST_MBSEC1Q_HARD_MCE_COUNT,
- HARD_MCE_COUNT_LEN = MCBIST_MBSEC1Q_HARD_MCE_COUNT_LEN,
- ICE_COUNT = MCBIST_MBSEC1Q_ICE_COUNT,
- ICE_COUNT_LEN = MCBIST_MBSEC1Q_ICE_COUNT_LEN,
- UE_COUNT = MCBIST_MBSEC1Q_UE_COUNT,
- UE_COUNT_LEN = MCBIST_MBSEC1Q_UE_COUNT_LEN,
- AUE_COUNT = MCBIST_MBSEC1Q_AUE,
- AUE_COUNT_LEN = MCBIST_MBSEC1Q_AUE_LEN,
- RCE_COUNT = MCBIST_MBSEC1Q_RCE_COUNT,
- RCE_COUNT_LEN = MCBIST_MBSEC1Q_RCE_COUNT_LEN,
- SYMBOL0_COUNT = MCBIST_MBSMSECQ_MCE_SYMBOL0_COUNT,
- SYMBOL0_COUNT_LEN = MCBIST_MBSMSECQ_MCE_SYMBOL0_COUNT_LEN,
- SYMBOL1_COUNT = MCBIST_MBSMSECQ_MCE_SYMBOL1_COUNT,
- SYMBOL1_COUNT_LEN = MCBIST_MBSMSECQ_MCE_SYMBOL1_COUNT_LEN,
- SYMBOL2_COUNT = MCBIST_MBSMSECQ_MCE_SYMBOL2_COUNT,
- SYMBOL2_COUNT_LEN = MCBIST_MBSMSECQ_MCE_SYMBOL2_COUNT_LEN,
- SYMBOL3_COUNT = MCBIST_MBSMSECQ_MCE_SYMBOL3_COUNT,
- SYMBOL3_COUNT_LEN = MCBIST_MBSMSECQ_MCE_SYMBOL3_COUNT_LEN,
- MODAL_SYMBOL_COUNTER_00 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_00,
- MODAL_SYMBOL_COUNTER_00_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_00_LEN,
- MODAL_SYMBOL_COUNTER_01 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_01,
- MODAL_SYMBOL_COUNTER_01_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_01_LEN,
- MODAL_SYMBOL_COUNTER_02 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_02,
- MODAL_SYMBOL_COUNTER_02_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_02_LEN,
- MODAL_SYMBOL_COUNTER_03 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_03,
- MODAL_SYMBOL_COUNTER_03_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_03_LEN,
- MODAL_SYMBOL_COUNTER_04 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_04,
- MODAL_SYMBOL_COUNTER_04_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_04_LEN,
- MODAL_SYMBOL_COUNTER_05 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_05,
- MODAL_SYMBOL_COUNTER_05_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_05_LEN,
- MODAL_SYMBOL_COUNTER_06 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_06,
- MODAL_SYMBOL_COUNTER_06_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_06_LEN,
- MODAL_SYMBOL_COUNTER_07 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_07,
- MODAL_SYMBOL_COUNTER_07_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_07_LEN,
-
- // and a couple constants
- NUM_MBSSYM_REGS = 9,
- MODAL_SYMBOL_COUNTERS_PER_REG = 8,
- };
-
-};
-
-} // close namespace mss
-
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits_nimbus.C b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits_nimbus.C
index 196e6d509..3fd43e6a3 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits_nimbus.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits_nimbus.C
@@ -22,3 +22,49 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file ecc_traits_nimbus.C
+/// @brief Traits class for the MC ECC syndrome registers
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include <lib/shared/mss_const.H>
+#include <lib/shared/nimbus_defaults.H>
+#include <lib/ecc/ecc_traits_nimbus.H>
+
+namespace mss
+{
+
+// we need these declarations here in order for the linker to see the definitions
+// in the eccTraits class
+constexpr const uint64_t eccTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCA>::MAINLINE_NCE_REGS[];
+constexpr const uint64_t eccTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCA>::MAINLINE_RCE_REGS[];
+constexpr const uint64_t eccTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCA>::MAINLINE_MPE_REGS[];
+constexpr const uint64_t eccTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCA>::MAINLINE_UE_REGS[];
+constexpr const uint64_t eccTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCA>::MAINLINE_AUE_REGS[];
+constexpr const uint64_t eccTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCA>::ERROR_VECTOR_REGS[];
+
+constexpr const uint8_t eccTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCA>::symbol2galois[];
+constexpr const uint8_t eccTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCA>::symbol2dq[];
+
+// Definition of the symbol error count registers
+const std::vector< uint64_t > eccTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCBIST>::SYMBOL_COUNT_REG =
+{
+ MCBIST_MBSSYMEC0Q,
+ MCBIST_MBSSYMEC1Q,
+ MCBIST_MBSSYMEC2Q,
+ MCBIST_MBSSYMEC3Q,
+ MCBIST_MBSSYMEC4Q,
+ MCBIST_MBSSYMEC5Q,
+ MCBIST_MBSSYMEC6Q,
+ MCBIST_MBSSYMEC7Q,
+ MCBIST_MBSSYMEC8Q,
+};
+
+} // close namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits_nimbus.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits_nimbus.H
index 55acc5ffc..6a13b0c41 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits_nimbus.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits_nimbus.H
@@ -22,3 +22,322 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file ecc_traits_nimbus.H
+/// @brief Traits class for the MC ECC syndrome registers
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_ECC_TRAITS_NIMBUS_H_
+#define _MSS_ECC_TRAITS_NIMBUS_H_
+
+#include <p9_mc_scom_addresses.H>
+#include <p9_mc_scom_addresses_fld.H>
+#include <lib/shared/mss_const.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+
+namespace mss
+{
+
+///
+/// @class eccTraits
+/// @brief a collection of traits associated with the Nimbus MC ECC interface
+///
+template<>
+class eccTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCA>
+{
+ public:
+ // MCA ECC registers - must be 64 bits.
+ static constexpr uint64_t HARDWARE_MS0_REG = MCA_HWMS0;
+ static constexpr uint64_t HARDWARE_MS1_REG = MCA_WDF_HWMS1;
+ static constexpr uint64_t HARDWARE_MS2_REG = MCA_HWMS2;
+ static constexpr uint64_t HARDWARE_MS3_REG = MCA_HWMS3;
+ static constexpr uint64_t HARDWARE_MS4_REG = MCA_HWMS4;
+ static constexpr uint64_t HARDWARE_MS5_REG = MCA_HWMS5;
+ static constexpr uint64_t HARDWARE_MS6_REG = MCA_HWMS6;
+ static constexpr uint64_t HARDWARE_MS7_REG = MCA_HWMS7;
+ static constexpr uint64_t FIRMWARE_MS0_REG = MCA_FWMS0;
+ static constexpr uint64_t FIRMWARE_MS1_REG = MCA_WREITE_FWMS1;
+ static constexpr uint64_t FIRMWARE_MS2_REG = MCA_FWMS2;
+ static constexpr uint64_t FIRMWARE_MS3_REG = MCA_FWMS3;
+ static constexpr uint64_t FIRMWARE_MS4_REG = MCA_FWMS4;
+ static constexpr uint64_t FIRMWARE_MS5_REG = MCA_FWMS5;
+ static constexpr uint64_t FIRMWARE_MS6_REG = MCA_FWMS6;
+ static constexpr uint64_t FIRMWARE_MS7_REG = MCA_FWMS7;
+ static constexpr uint64_t MARK_SHADOW_REG = MCA_MSR;
+ static constexpr uint64_t ECC_MAX_MRANK_PER_PORT = MAX_MRANK_PER_PORT;
+ static constexpr uint64_t ECC_MAX_DQ_BITS = MAX_DQ_BITS;
+ static constexpr uint64_t ECC_MAX_SYMBOLS = MAX_DQ_BITS;
+
+ // MCBIST ECC registers - Register API uses an MCA target instead
+ // of MCBIST since MCA's relative position is needed to find
+ // correct reg+field
+ constexpr static const uint64_t MAINLINE_NCE_REGS[] =
+ {
+ MCBIST_MBNCER0Q,
+ MCBIST_MBNCER1Q,
+ MCBIST_MBNCER2Q,
+ MCBIST_MBNCER3Q,
+ };
+
+ constexpr static const uint64_t MAINLINE_RCE_REGS[] =
+ {
+ MCBIST_MBRCER0Q,
+ MCBIST_MBRCER1Q,
+ MCBIST_MBRCER2Q,
+ MCBIST_MBRCER3Q
+ };
+
+ constexpr static const uint64_t MAINLINE_MPE_REGS[] =
+ {
+ MCBIST_MBMPER0Q,
+ MCBIST_MBMPER1Q,
+ MCBIST_MBMPER2Q,
+ MCBIST_MBMPER3Q
+ };
+
+ constexpr static const uint64_t MAINLINE_UE_REGS[] =
+ {
+ MCBIST_MBUER0Q,
+ MCBIST_MBUER1Q,
+ MCBIST_MBUER2Q,
+ MCBIST_MBUER3Q
+ };
+
+ constexpr static const uint64_t MAINLINE_AUE_REGS[] =
+ {
+ MCBIST_MBAUER0Q,
+ MCBIST_MBAUER1Q,
+ MCBIST_MBAUER2Q,
+ MCBIST_MBAUER3Q
+ };
+
+ // Note that these registers store info for a pair of ports
+ // (thus the duplication)
+ constexpr static const uint64_t ERROR_VECTOR_REGS[] =
+ {
+ MCBIST_MBSEVR0Q,
+ MCBIST_MBSEVR0Q,
+ MCBIST_MBSEVR1Q,
+ MCBIST_MBSEVR1Q
+ };
+
+ // Fields, can be any size.
+ enum
+ {
+ HARDWARE_MS_CHIPMARK = MCA_HWMS0_CHIPMARK,
+ HARDWARE_MS_CHIPMARK_LEN = MCA_HWMS0_CHIPMARK_LEN,
+ HARDWARE_MS_CONFIRMED = MCA_HWMS0_CONFIRMED,
+ HARDWARE_MS_EXIT1 = MCA_HWMS0_EXIT_1,
+ FIRMWARE_MS_MARK = MCA_FWMS0_MARK,
+ FIRMWARE_MS_MARK_LEN = MCA_FWMS0_MARK_LEN,
+ FIRMWARE_MS_TYPE = MCA_FWMS0_TYPE,
+ FIRMWARE_MS_REGION = MCA_FWMS0_REGION,
+ FIRMWARE_MS_REGION_LEN = MCA_FWMS0_REGION_LEN,
+ FIRMWARE_MS_ADDRESS = MCA_FWMS0_ADDRESS,
+ FIRMWARE_MS_ADDRESS_LEN = MCA_FWMS0_ADDRESS_LEN,
+ FIRMWARE_MS_EXIT1 = MCA_FWMS0_EXIT_1,
+ NCE_ADDR_TRAP = MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ADDR_TRAP,
+ NCE_ADDR_TRAP_LEN = MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ADDR_TRAP_LEN,
+ NCE_ON_RCE = MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_ON_RCE,
+ NCE_IS_TCE = MCBIST_MBNCER0Q_PORT_0_MAINLINE_NCE_IS_TCE,
+ RCE_ADDR_TRAP = MCBIST_MBRCER0Q_PORT_0_MAINLINE_RCE_ADDR_TRAP,
+ RCE_ADDR_TRAP_LEN = MCBIST_MBRCER0Q_PORT_0_MAINLINE_RCE_ADDR_TRAP_LEN,
+ MPE_ADDR_TRAP = MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ADDR_TRAP,
+ MPE_ADDR_TRAP_LEN = MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ADDR_TRAP_LEN,
+ MPE_ON_RCE = MCBIST_MBMPER0Q_PORT_0_MAINLINE_MPE_ON_RCE,
+ UE_ADDR_TRAP = MCBIST_MBUER0Q_PORT_0_MAINLINE_UE_ADDR_TRAP,
+ UE_ADDR_TRAP_LEN = MCBIST_MBUER0Q_PORT_0_MAINLINE_UE_ADDR_TRAP_LEN,
+ AUE_ADDR_TRAP = MCBIST_MBAUER0Q_PORT_0_MAINLINE_AUE_ADDR_TRAP,
+ AUE_ADDR_TRAP_LEN = MCBIST_MBAUER0Q_PORT_0_MAINLINE_AUE_ADDR_TRAP_LEN,
+ P0_NCE_GALOIS = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_GALOIS_FIELD,
+ P0_NCE_GALOIS_LEN = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_GALOIS_FIELD_LEN,
+ P0_NCE_MAGNITUDE = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_MAGNITUDE_FIELD,
+ P0_NCE_MAGNITUDE_LEN = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_NCE_MAGNITUDE_FIELD_LEN,
+ P0_TCE_GALOIS = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_GALOIS_FIELD,
+ P0_TCE_GALOIS_LEN = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_GALOIS_FIELD_LEN,
+ P0_TCE_MAGNITUDE = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_MAGNITUDE_FIELD,
+ P0_TCE_MAGNITUDE_LEN = MCBIST_MBSEVR0Q_PORT_0_MAINLINE_TCE_MAGNITUDE_FIELD_LEN,
+ P1_NCE_GALOIS = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_NCE_GALOIS_FIELD,
+ P1_NCE_GALOIS_LEN = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_NCE_GALOIS_FIELD_LEN,
+ P1_NCE_MAGNITUDE = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_NCE_MAGNITUDE_FIELD,
+ P1_NCE_MAGNITUDE_LEN = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_NCE_MAGNITUDE_FIELD_LEN,
+ P1_TCE_GALOIS = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_TCE_GALOIS_FIELD,
+ P1_TCE_GALOIS_LEN = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_TCE_GALOIS_FIELD_LEN,
+ P1_TCE_MAGNITUDE = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_TCE_MAGNITUDE_FIELD,
+ P1_TCE_MAGNITUDE_LEN = MCBIST_MBSEVR0Q_PORT_1_MAINLINE_TCE_MAGNITUDE_FIELD_LEN,
+ CURRENT_ADDR_TRAP = MCBIST_MCBMCATQ_CFG_CURRENT_ADDR_TRAP,
+ CURRENT_ADDR_TRAP_LEN = MCBIST_MCBMCATQ_CFG_CURRENT_ADDR_TRAP_LEN,
+ CURRENT_PORT = MCBIST_MCBMCATQ_CFG_CURRENT_PORT_TRAP,
+ CURRENT_PORT_LEN = MCBIST_MCBMCATQ_CFG_CURRENT_PORT_TRAP_LEN,
+ CURRENT_DIMM = MCBIST_MCBMCATQ_CFG_CURRENT_DIMM_TRAP,
+ SHADOW_CHIPMARK = MCA_MSR_CHIPMARK,
+ SHADOW_CHIPMARK_LEN = MCA_MSR_CHIPMARK_LEN,
+ SHADOW_RANK = MCA_MSR_RANK,
+ SHADOW_RANK_LEN = MCA_MSR_RANK_LEN,
+
+ // Address trap format
+ TRAP_ADDRESS_PORT = 0,
+ TRAP_ADDRESS_PORT_LEN = 2,
+ TRAP_ADDRESS_DIMM = 2,
+ TRAP_ADDRESS_DIMM_LEN = 1,
+ TRAP_ADDRESS_MRANK = 3,
+ TRAP_ADDRESS_MRANK_LEN = 2,
+ TRAP_ADDRESS_SRANK = 5,
+ TRAP_ADDRESS_SRANK_LEN = 3,
+ TRAP_ADDRESS_ROW = 8,
+ TRAP_ADDRESS_ROW_LEN = 18,
+ TRAP_ADDRESS_COL = 26,
+ TRAP_ADDRESS_COL_LEN = 7,
+ TRAP_ADDRESS_BANK = 33,
+ TRAP_ADDRESS_BANK_LEN = 3,
+ TRAP_ADDRESS_BANK_GROUP = 36,
+ TRAP_ADDRESS_BANK_GROUP_LEN = 2,
+
+ TRAP_ADDRESS = 0,
+ TRAP_ADDRESS_LEN = 38,
+ };
+
+ // Symbol to Galois code mapping table
+ // Reference: Nimbus workbook, Section 13.1.6.2: Firmware Mark Store
+ constexpr static const uint8_t symbol2galois[] =
+ {
+ 0x80, 0xa0, 0x90, 0xf0,
+ 0x08, 0x0a, 0x09, 0x0f,
+ 0x98, 0xda, 0xb9, 0x7f,
+ 0x91, 0xd7, 0xb2, 0x78,
+ 0x28, 0xea, 0x49, 0x9f,
+ 0x9a, 0xd4, 0xbd, 0x76,
+ 0x60, 0xb0, 0xc0, 0x20,
+ 0x06, 0x0b, 0x0c, 0x02,
+ 0xc6, 0xfb, 0x1c, 0x42,
+ 0xca, 0xf4, 0x1d, 0x46,
+ 0xd6, 0x8b, 0x3c, 0xc2,
+ 0xcb, 0xf3, 0x1f, 0x4e,
+ 0xe0, 0x10, 0x50, 0xd0,
+ 0x0e, 0x01, 0x05, 0x0d,
+ 0x5e, 0x21, 0xa5, 0x3d,
+ 0x5b, 0x23, 0xaf, 0x3e,
+ 0xfe, 0x61, 0x75, 0x5d,
+ 0x51, 0x27, 0xa2, 0x38
+ };
+
+ // Symbol to DQ index mapping table
+ // Reference: Nimbus workbook, Section 13.1.6.2: Firmware Mark Store
+ constexpr static const uint8_t symbol2dq[] =
+ {
+ 71, 70, 69, 68,
+ 67, 66, 65, 64,
+ 63, 62, 61, 60,
+ 55, 54, 53, 52,
+ 47, 46, 45, 44,
+ 39, 38, 37, 36,
+ 31, 30, 29, 28,
+ 23, 22, 21, 20,
+ 15, 14, 13, 12,
+ 7, 6, 5, 4,
+ 59, 58, 57, 56,
+ 51, 50, 49, 48,
+ 43, 42, 41, 40,
+ 35, 34, 33, 32,
+ 27, 26, 25, 24,
+ 19, 18, 17, 16,
+ 11, 10, 9, 8,
+ 3, 2, 1, 0
+ };
+
+};
+
+///
+/// @class eccTraits
+/// @brief a collection of traits associated with the Nimbus MC ECC interface
+///
+template<>
+class eccTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCBIST>
+{
+ public:
+ // MCBIST ECC registers - must be 64 bits.
+ static constexpr uint64_t READ_ERROR_COUNT_REG0 = MCBIST_MBSEC0Q;
+ static constexpr uint64_t READ_ERROR_COUNT_REG1 = MCBIST_MBSEC1Q;
+ static constexpr uint64_t MARK_SYMBOL_COUNT_REG = MCBIST_MBSMSECQ;
+ static constexpr uint64_t MODAL_SYM_COUNT0_REG = MCBIST_MBSSYMEC0Q;
+ static constexpr uint64_t MODAL_SYM_COUNT1_REG = MCBIST_MBSSYMEC1Q;
+ static constexpr uint64_t MODAL_SYM_COUNT2_REG = MCBIST_MBSSYMEC2Q;
+ static constexpr uint64_t MODAL_SYM_COUNT3_REG = MCBIST_MBSSYMEC3Q;
+ static constexpr uint64_t MODAL_SYM_COUNT4_REG = MCBIST_MBSSYMEC4Q;
+ static constexpr uint64_t MODAL_SYM_COUNT5_REG = MCBIST_MBSSYMEC5Q;
+ static constexpr uint64_t MODAL_SYM_COUNT6_REG = MCBIST_MBSSYMEC6Q;
+ static constexpr uint64_t MODAL_SYM_COUNT7_REG = MCBIST_MBSSYMEC7Q;
+ static constexpr uint64_t MODAL_SYM_COUNT8_REG = MCBIST_MBSSYMEC8Q;
+ static constexpr uint64_t MPE_ADDR_TRAP_REG = MCBIST_MCBMCATQ;
+ static constexpr uint64_t ECC_MAX_MRANK_PER_PORT = MAX_MRANK_PER_PORT;
+ static constexpr uint64_t ECC_MAX_DQ_BITS = MAX_DQ_BITS;
+ static constexpr uint64_t ECC_MAX_SYMBOLS = MAX_DQ_BITS;
+
+ // Stores the symbol counter registers in a vector for easier access for MCBIST
+ static constexpr uint64_t REQUIRED_NUMBER_OF_SYMBOL_REGS = 9;
+ static const std::vector<uint64_t> SYMBOL_COUNT_REG;
+
+ // Fields, can be any size.
+ enum
+ {
+ INTERMITTENT_CE_COUNT = MCBIST_MBSEC0Q_INTERMITTENT_CE_COUNT,
+ INTERMITTENT_CE_COUNT_LEN = MCBIST_MBSEC0Q_INTERMITTENT_CE_COUNT_LEN,
+ SOFT_CE_COUNT = MCBIST_MBSEC0Q_SOFT_CE_COUNT,
+ SOFT_CE_COUNT_LEN = MCBIST_MBSEC0Q_SOFT_CE_COUNT_LEN,
+ HARD_CE_COUNT = MCBIST_MBSEC0Q_HARD_CE_COUNT,
+ HARD_CE_COUNT_LEN = MCBIST_MBSEC0Q_HARD_CE_COUNT_LEN,
+ INTERMITTENT_MCE_COUNT = MCBIST_MBSEC0Q_INTERMITTENT_MCE_COUNT,
+ INTERMITTENT_MCE_COUNT_LEN = MCBIST_MBSEC0Q_INTERMITTENT_MCE_COUNT_LEN,
+ SOFT_MCE_COUNT = MCBIST_MBSEC0Q_SOFT_MCE_COUNT,
+ SOFT_MCE_COUNT_LEN = MCBIST_MBSEC0Q_SOFT_MCE_COUNT_LEN,
+ HARD_MCE_COUNT = MCBIST_MBSEC1Q_HARD_MCE_COUNT,
+ HARD_MCE_COUNT_LEN = MCBIST_MBSEC1Q_HARD_MCE_COUNT_LEN,
+ ICE_COUNT = MCBIST_MBSEC1Q_ICE_COUNT,
+ ICE_COUNT_LEN = MCBIST_MBSEC1Q_ICE_COUNT_LEN,
+ UE_COUNT = MCBIST_MBSEC1Q_UE_COUNT,
+ UE_COUNT_LEN = MCBIST_MBSEC1Q_UE_COUNT_LEN,
+ AUE_COUNT = MCBIST_MBSEC1Q_AUE,
+ AUE_COUNT_LEN = MCBIST_MBSEC1Q_AUE_LEN,
+ RCE_COUNT = MCBIST_MBSEC1Q_RCE_COUNT,
+ RCE_COUNT_LEN = MCBIST_MBSEC1Q_RCE_COUNT_LEN,
+ SYMBOL0_COUNT = MCBIST_MBSMSECQ_MCE_SYMBOL0_COUNT,
+ SYMBOL0_COUNT_LEN = MCBIST_MBSMSECQ_MCE_SYMBOL0_COUNT_LEN,
+ SYMBOL1_COUNT = MCBIST_MBSMSECQ_MCE_SYMBOL1_COUNT,
+ SYMBOL1_COUNT_LEN = MCBIST_MBSMSECQ_MCE_SYMBOL1_COUNT_LEN,
+ SYMBOL2_COUNT = MCBIST_MBSMSECQ_MCE_SYMBOL2_COUNT,
+ SYMBOL2_COUNT_LEN = MCBIST_MBSMSECQ_MCE_SYMBOL2_COUNT_LEN,
+ SYMBOL3_COUNT = MCBIST_MBSMSECQ_MCE_SYMBOL3_COUNT,
+ SYMBOL3_COUNT_LEN = MCBIST_MBSMSECQ_MCE_SYMBOL3_COUNT_LEN,
+ MODAL_SYMBOL_COUNTER_00 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_00,
+ MODAL_SYMBOL_COUNTER_00_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_00_LEN,
+ MODAL_SYMBOL_COUNTER_01 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_01,
+ MODAL_SYMBOL_COUNTER_01_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_01_LEN,
+ MODAL_SYMBOL_COUNTER_02 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_02,
+ MODAL_SYMBOL_COUNTER_02_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_02_LEN,
+ MODAL_SYMBOL_COUNTER_03 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_03,
+ MODAL_SYMBOL_COUNTER_03_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_03_LEN,
+ MODAL_SYMBOL_COUNTER_04 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_04,
+ MODAL_SYMBOL_COUNTER_04_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_04_LEN,
+ MODAL_SYMBOL_COUNTER_05 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_05,
+ MODAL_SYMBOL_COUNTER_05_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_05_LEN,
+ MODAL_SYMBOL_COUNTER_06 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_06,
+ MODAL_SYMBOL_COUNTER_06_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_06_LEN,
+ MODAL_SYMBOL_COUNTER_07 = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_07,
+ MODAL_SYMBOL_COUNTER_07_LEN = MCBIST_MBSSYMEC0Q_MODAL_SYMBOL_COUNTER_07_LEN,
+
+ // and a couple constants
+ NUM_MBSSYM_REGS = 9,
+ MODAL_SYMBOL_COUNTERS_PER_REG = 8,
+ };
+
+};
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/fw_mark_store.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/fw_mark_store.H
deleted file mode 100644
index c27603b6b..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/fw_mark_store.H
+++ /dev/null
@@ -1,619 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/fw_mark_store.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file fw_mark_store.H
-/// @brief Subroutines for the MC firmware mark store registers
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_FW_MARK_STORE_H_
-#define _MSS_FW_MARK_STORE_H_
-
-#include <fapi2.H>
-#include <lib/mcbist/address.H>
-#include <generic/memory/lib/utils/scom.H>
-#include <lib/ecc/ecc_traits.H>
-#include <lib/shared/mss_const.H>
-
-namespace mss
-{
-
-namespace ecc
-{
-
-namespace fwms
-{
-
-///
-/// @brief chip mark type enums
-///
-enum mark_type
-{
- SYMBOL = 1,
- CHIP = 0
-};
-
-///
-/// @brief Chip Mark Region. Used for region field values in the FWMS regs
-///
-enum mark_region
-{
- DISABLED = 0b000,
- RESERVED = 0b001,
- BANK = 0b010,
- BANKGROUP = 0b011,
- SRANK = 0b100,
- MRANK = 0b101,
- DIMM = 0b110,
- UNIVERSAL = 0b111
-};
-
-///
-/// @brief Read Firmware Mark Store (FWMS) register
-/// @tparam R master rank number
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< uint64_t R, fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode read_rank( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- static_assert((R < MAX_MRANK_PER_PORT), "Master rank index failed range check");
- FAPI_TRY( mss::getScom(i_target, (TT::FIRMWARE_MS0_REG + R), o_data) );
- FAPI_INF("read_rank<%d>: 0x%016lx", R, o_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Read Firmware Mark Store (FWMS) rank 0 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank0( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<0>(i_target, o_data) );
-}
-
-///
-/// @brief Read Firmware Mark Store (FWMS) rank 1 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank1( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<1>(i_target, o_data) );
-}
-
-///
-/// @brief Read Firmware Mark Store (FWMS) rank 2 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank2( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<2>(i_target, o_data) );
-}
-
-///
-/// @brief Read Firmware Mark Store (FWMS) rank 3 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank3( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<3>(i_target, o_data) );
-}
-
-///
-/// @brief Read Firmware Mark Store (FWMS) rank 4 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank4( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<4>(i_target, o_data) );
-}
-
-///
-/// @brief Read Firmware Mark Store (FWMS) rank 5 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank5( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<5>(i_target, o_data) );
-}
-
-///
-/// @brief Read Firmware Mark Store (FWMS) rank 6 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank6( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<6>(i_target, o_data) );
-}
-
-///
-/// @brief Read Firmware Mark Store (FWMS) rank 7 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank7( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<7>(i_target, o_data) );
-}
-
-///
-/// @brief Read Firmware Mark Store (FWMS) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_rank the master rank index
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- fapi2::buffer<uint64_t>& o_data )
-{
- switch (i_rank)
- {
- case(0):
- return ( read_rank0(i_target, o_data) );
-
- case(1):
- return ( read_rank1(i_target, o_data) );
-
- case(2):
- return ( read_rank2(i_target, o_data) );
-
- case(3):
- return ( read_rank3(i_target, o_data) );
-
- case(4):
- return ( read_rank4(i_target, o_data) );
-
- case(5):
- return ( read_rank5(i_target, o_data) );
-
- case(6):
- return ( read_rank6(i_target, o_data) );
-
- case(7):
- return ( read_rank7(i_target, o_data) );
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_RANK_PASSED()
- .set_RANK(i_rank)
- .set_TARGET(i_target)
- .set_FUNCTION(FWMS_READ),
- "%s Invalid rank passed to fwms::ecc::read (%d)",
- mss::c_str(i_target),
- i_rank);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write Firmware Mark Store (FWMS) register
-/// @tparam R master rank number
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< uint64_t R, fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode write_rank( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- static_assert((R < MAX_MRANK_PER_PORT), "Master rank index failed range check");
- FAPI_TRY( mss::putScom(i_target, (TT::FIRMWARE_MS0_REG + R), i_data) );
- FAPI_INF("write_rank<%d>: 0x%016lx", R, i_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write Firmware Mark Store (FWMS) rank 0 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank0( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<0>(i_target, i_data) );
-}
-
-///
-/// @brief Write Firmware Mark Store (FWMS) rank 1 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank1( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<1>(i_target, i_data) );
-}
-
-///
-/// @brief Write Firmware Mark Store (FWMS) rank 2 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank2( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<2>(i_target, i_data) );
-}
-
-///
-/// @brief Write Firmware Mark Store (FWMS) rank 3 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank3( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<3>(i_target, i_data) );
-}
-
-///
-/// @brief Write Firmware Mark Store (FWMS) rank 4 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank4( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<4>(i_target, i_data) );
-}
-
-///
-/// @brief Write Firmware Mark Store (FWMS) rank 5 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank5( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<5>(i_target, i_data) );
-}
-
-///
-/// @brief Write Firmware Mark Store (FWMS) rank 6 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank6( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<6>(i_target, i_data) );
-}
-
-///
-/// @brief Write Firmware Mark Store (FWMS) rank 7 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank7( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<7>(i_target, i_data) );
-}
-
-///
-/// @brief Write Firmware Mark Store (FWMS) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_rank the master rank index
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const fapi2::buffer<uint64_t>& i_data )
-{
- switch (i_rank)
- {
- case(0):
- return ( write_rank0(i_target, i_data) );
-
- case(1):
- return ( write_rank1(i_target, i_data) );
-
- case(2):
- return ( write_rank2(i_target, i_data) );
-
- case(3):
- return ( write_rank3(i_target, i_data) );
-
- case(4):
- return ( write_rank4(i_target, i_data) );
-
- case(5):
- return ( write_rank5(i_target, i_data) );
-
- case(6):
- return ( write_rank6(i_target, i_data) );
-
- case(7):
- return ( write_rank7(i_target, i_data) );
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_RANK_PASSED()
- .set_RANK(i_rank)
- .set_TARGET(i_target)
- .set_FUNCTION(FWMS_WRITE),
- "%s Invalid rank passed to fwms::ecc::write (%d)",
- mss::c_str(i_target),
- i_rank);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief set_mark
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note FWMS0_MARK: mark (Galois field code)
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_mark( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::FIRMWARE_MS_MARK, TT::FIRMWARE_MS_MARK_LEN>(i_value);
- FAPI_INF("set_mark: 0x%02lx", i_value);
-}
-
-///
-/// @brief get_mark
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note FWMS0_MARK: mark (Galois field code)
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_mark( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::FIRMWARE_MS_MARK, TT::FIRMWARE_MS_MARK_LEN>(o_value);
- FAPI_INF("get_mark: 0x%02lx", o_value);
-}
-
-///
-/// @brief set_type
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note FWMS0_TYPE: mark type
-/// @note Dial enums:
-/// @note SYMBOL=>0b1
-/// @note CHIP=>0b0
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_type( fapi2::buffer<uint64_t>& io_data, const mark_type i_value )
-{
- io_data.writeBit<TT::FIRMWARE_MS_TYPE>(i_value);
- FAPI_INF("set_type: 0x%01lx", i_value);
-}
-
-///
-/// @brief get_type
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note FWMS0_TYPE: mark type
-/// @note Dial enums:
-/// @note SYMBOL=>0b1
-/// @note CHIP=>0b0
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_type( const fapi2::buffer<uint64_t>& i_data, mark_type& o_value )
-{
- o_value = mark_type(i_data.getBit<TT::FIRMWARE_MS_TYPE>());
- FAPI_INF("get_type: 0x%01lx", o_value);
-}
-
-///
-/// @brief set_region
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note FWMS0_REGION: Selects mark region (address range to which mark applies)
-/// @note Dial enums:
-/// @note DISABLED=>0b000
-/// @note RESERVED=>0b001
-/// @note BANK=>0b010
-/// @note BANKGROUP=>0b011
-/// @note SRANK=>0b100
-/// @note MRANK=>0b101
-/// @note DIMM=>0b110
-/// @note UNIVERSAL=>0b111
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_region( fapi2::buffer<uint64_t>& io_data, const mark_region i_value )
-{
- io_data.insertFromRight<TT::FIRMWARE_MS_REGION, TT::FIRMWARE_MS_REGION_LEN>(i_value);
- FAPI_INF("set_region: 0x%02lx", i_value);
-}
-
-///
-/// @brief get_region
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note FWMS0_REGION: Selects mark region (address range to which mark applies)
-/// @note Dial enums:
-/// @note DISABLED=>0b000
-/// @note RESERVED=>0b001
-/// @note BANK=>0b010
-/// @note BANKGROUP=>0b011
-/// @note SRANK=>0b100
-/// @note MRANK=>0b101
-/// @note DIMM=>0b110
-/// @note UNIVERSAL=>0b111
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_region( const fapi2::buffer<uint64_t>& i_data, mark_region& o_value )
-{
- uint64_t l_temp = 0;
- i_data.extractToRight<TT::FIRMWARE_MS_REGION, TT::FIRMWARE_MS_REGION_LEN>(l_temp);
- o_value = mark_region(l_temp);
- FAPI_INF("get_region: 0x%02lx", o_value);
-}
-
-///
-/// @brief set_address
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_address mcbist::address form of address field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
-{
- // construct fwms::address from mcbist::address
- const auto l_addr = address<T>(i_address);
- io_data.insert<TT::FIRMWARE_MS_ADDRESS, TT::FIRMWARE_MS_ADDRESS_LEN, TT::FIRMWARE_MS_ADDRESS>(l_addr);
- FAPI_INF("set_address: 0x%016lx", uint64_t(l_addr));
-}
-
-///
-/// @brief get_address
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_address mcbist::address form of address field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
-{
- // construct fwms::address from i_data
- const auto l_addr = address<T>(uint64_t(i_data));
- // construct mcbist::address from fwms::address
- o_address = mcbist::address(l_addr);
- FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
-}
-
-///
-/// @brief set_exit_1
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_state mss::YES or mss::NO - desired state
-/// @note FWMS0_EXIT_1: When set, bypass-enabled reads using this mark will use exit 1
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_exit_1( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
-{
- io_data.writeBit<TT::FIRMWARE_MS_EXIT1>(i_state);
- FAPI_INF("set_exit_1: 0x%01lx", i_state);
-}
-
-///
-/// @brief get_exit_1
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_state mss::YES or mss::NO - representing the state of the field
-/// @note FWMS0_EXIT_1: When set, bypass-enabled reads using this mark will use exit 1
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_exit_1( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state )
-{
- o_state = (i_data.getBit<TT::FIRMWARE_MS_EXIT1>() == false) ? mss::NO : mss::YES;
- FAPI_INF("get_exit_1: 0x%01lx", o_state);
-}
-
-} // close namespace fwms
-
-} // close namespace ecc
-
-} // close namespace mss
-
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/galois.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/galois.H
deleted file mode 100644
index 981350955..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/galois.H
+++ /dev/null
@@ -1,190 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/galois.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file galois.H
-/// @brief Translate ECC mark Galois codes to symbol and DQ
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: HB:FSP
-
-#ifndef _MSS_ECC_GALOIS_H_
-#define _MSS_ECC_GALOIS_H_
-
-#include <lib/ecc/ecc_traits.H>
-
-namespace mss
-{
-
-namespace ecc
-{
-
-///
-/// @brief Return symbol value from a given Galois code
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_galois the Galois code
-/// @param[out] o_symbol symbol value represented by given Galois code
-/// @return FAPI2_RC_SUCCESS iff all is ok
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-fapi2::ReturnCode galois_to_symbol( const uint8_t i_galois, uint8_t& o_symbol )
-{
- const auto& l_p = std::find(TT::symbol2galois, (TT::symbol2galois + MAX_DQ_BITS), i_galois);
-
- FAPI_ASSERT( l_p != (TT::symbol2galois + MAX_DQ_BITS),
- fapi2::MSS_INVALID_GALOIS_TO_SYMBOL()
- .set_GALOIS(i_galois),
- "Invalid Galois code: 0x%02x",
- i_galois);
-
- o_symbol = (l_p - TT::symbol2galois);
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Return Galois code from a given symbol value
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_symbol the symbol value
-/// @param[out] o_galois Galois code represented by given symbol
-/// @return FAPI2_RC_SUCCESS iff all is ok
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-fapi2::ReturnCode symbol_to_galois( const uint8_t i_symbol, uint8_t& o_galois )
-{
- FAPI_ASSERT( i_symbol < MAX_DQ_BITS,
- fapi2::MSS_INVALID_SYMBOL_FOR_GALOIS()
- .set_SYMBOL(i_symbol),
- "Invalid symbol: %d",
- i_symbol);
-
- o_galois = TT::symbol2galois[i_symbol];
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Return symbol value from a given DQ index
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_dq the DQ index
-/// @param[out] o_symbol symbol value represented by given DQ index
-/// @return FAPI2_RC_SUCCESS iff all is ok
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-fapi2::ReturnCode dq_to_symbol( const uint8_t i_dq, uint8_t& o_symbol )
-{
- const auto& l_p = std::find(TT::symbol2dq, (TT::symbol2dq + MAX_DQ_BITS), i_dq);
-
- FAPI_ASSERT( l_p != (TT::symbol2dq + MAX_DQ_BITS),
- fapi2::MSS_INVALID_DQ_TO_SYMBOL()
- .set_DQ(i_dq),
- "Invalid DQ index: %d",
- i_dq);
-
- o_symbol = (l_p - TT::symbol2dq);
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Return DQ index from a given symbol value
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_symbol the symbol value
-/// @param[out] o_dq DQ index represented by given symbol value
-/// @return FAPI2_RC_SUCCESS iff all is ok
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-fapi2::ReturnCode symbol_to_dq( const uint8_t i_symbol, uint8_t& o_dq )
-{
- FAPI_ASSERT( i_symbol < MAX_DQ_BITS,
- fapi2::MSS_INVALID_SYMBOL_TO_DQ()
- .set_SYMBOL(i_symbol),
- "symbol_to_dq: invalid symbol: %d",
- i_symbol);
-
- o_dq = TT::symbol2dq[i_symbol];
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Return DQ index from a given Galois code
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_galois the Galois code
-/// @param[out] o_dq DQ index represented by given Galois code
-/// @return FAPI2_RC_SUCCESS iff all is ok
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-fapi2::ReturnCode galois_to_dq( const uint8_t i_galois, uint8_t& o_dq )
-{
- uint8_t l_symbol = 0;
-
- FAPI_TRY( galois_to_symbol<T>(i_galois, l_symbol), "Failed galois_to_symbol");
- FAPI_TRY( symbol_to_dq<T>(l_symbol, o_dq), "Failed symbol_to_dq" );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Return Galois code from a given DQ index
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_dq the DQ index
-/// @param[out] o_galois Galois code represented by given symbol
-/// @return FAPI2_RC_SUCCESS iff all is ok
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-fapi2::ReturnCode dq_to_galois( const uint8_t i_dq, uint8_t& o_galois )
-{
- uint8_t l_symbol = 0;
-
- FAPI_TRY( mss::ecc::dq_to_symbol<T>(i_dq, l_symbol), "Failed dq_to_symbol");
- FAPI_TRY( mss::ecc::symbol_to_galois<T>(l_symbol, o_galois) , "Failed symbol_to_galois" );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-} // close namespace ecc
-
-} // close namespace mss
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/hw_mark_store.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/hw_mark_store.H
deleted file mode 100644
index 7a206c5bb..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/hw_mark_store.H
+++ /dev/null
@@ -1,507 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/hw_mark_store.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file hw_mark_store.H
-/// @brief Subroutines for the MC hardware mark store registers
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_HW_MARK_STORE_H_
-#define _MSS_HW_MARK_STORE_H_
-
-#include <fapi2.H>
-#include <lib/ecc/ecc_traits.H>
-#include <generic/memory/lib/utils/scom.H>
-#include <lib/shared/mss_const.H>
-
-namespace mss
-{
-
-namespace ecc
-{
-
-namespace hwms
-{
-
-///
-/// @brief Read Hardware Mark Store (HWMS) register
-/// @tparam R master rank number
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< uint64_t R, fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode read_rank( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- static_assert((R < MAX_MRANK_PER_PORT), "Master rank index failed range check");
- FAPI_TRY( mss::getScom(i_target, (TT::HARDWARE_MS0_REG + R), o_data) );
- FAPI_INF("read_rank<%d>: 0x%016lx", R, o_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Read Hardware Mark Store (HWMS) rank 0 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank0( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<0>(i_target, o_data) );
-}
-
-///
-/// @brief Read Hardware Mark Store (HWMS) rank 1 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank1( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<1>(i_target, o_data) );
-}
-
-///
-/// @brief Read Hardware Mark Store (HWMS) rank 2 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank2( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<2>(i_target, o_data) );
-}
-
-///
-/// @brief Read Hardware Mark Store (HWMS) rank 3 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank3( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<3>(i_target, o_data) );
-}
-
-///
-/// @brief Read Hardware Mark Store (HWMS) rank 4 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank4( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<4>(i_target, o_data) );
-}
-
-///
-/// @brief Read Hardware Mark Store (HWMS) rank 5 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank5( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<5>(i_target, o_data) );
-}
-
-///
-/// @brief Read Hardware Mark Store (HWMS) rank 6 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank6( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<6>(i_target, o_data) );
-}
-
-///
-/// @brief Read Hardware Mark Store (HWMS) rank 7 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_rank7( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_rank<7>(i_target, o_data) );
-}
-
-///
-/// @brief Read Hardware Mark Store (HWMS) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_rank the master rank index
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- fapi2::buffer<uint64_t>& o_data )
-{
- switch (i_rank)
- {
- case(0):
- return ( read_rank0(i_target, o_data) );
-
- case(1):
- return ( read_rank1(i_target, o_data) );
-
- case(2):
- return ( read_rank2(i_target, o_data) );
-
- case(3):
- return ( read_rank3(i_target, o_data) );
-
- case(4):
- return ( read_rank4(i_target, o_data) );
-
- case(5):
- return ( read_rank5(i_target, o_data) );
-
- case(6):
- return ( read_rank6(i_target, o_data) );
-
- case(7):
- return ( read_rank7(i_target, o_data) );
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_RANK_PASSED()
- .set_RANK(i_rank)
- .set_TARGET(i_target)
- .set_FUNCTION(HWMS_READ),
- "%s Invalid rank passed to fwms::ecc::hwms::read (%d)",
- mss::c_str(i_target),
- i_rank);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write Hardware Mark Store (HWMS) register
-/// @tparam R master rank number
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< uint64_t R, fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode write_rank( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- static_assert((R < MAX_MRANK_PER_PORT), "Master rank index failed range check");
- FAPI_TRY( mss::putScom(i_target, (TT::HARDWARE_MS0_REG + R), i_data) );
- FAPI_INF("write_rank<%d>: 0x%016lx", R, i_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write Hardware Mark Store (HWMS) rank 0 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank0( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<0>(i_target, i_data) );
-}
-
-///
-/// @brief Write Hardware Mark Store (HWMS) rank 1 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank1( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<1>(i_target, i_data) );
-}
-
-///
-/// @brief Write Hardware Mark Store (HWMS) rank 2 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank2( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<2>(i_target, i_data) );
-}
-
-///
-/// @brief Write Hardware Mark Store (HWMS) rank 3 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank3( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<3>(i_target, i_data) );
-}
-
-///
-/// @brief Write Hardware Mark Store (HWMS) rank 4 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank4( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<4>(i_target, i_data) );
-}
-
-///
-/// @brief Write Hardware Mark Store (HWMS) rank 5 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank5( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<5>(i_target, i_data) );
-}
-
-///
-/// @brief Write Hardware Mark Store (HWMS) rank 6 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank6( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<6>(i_target, i_data) );
-}
-
-///
-/// @brief Write Hardware Mark Store (HWMS) rank 7 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_rank7( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_rank<7>(i_target, i_data) );
-}
-
-///
-/// @brief Write Hardware Mark Store (HWMS) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_rank the master rank index
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const fapi2::buffer<uint64_t>& i_data )
-{
- switch (i_rank)
- {
- case(0):
- return ( write_rank0(i_target, i_data) );
-
- case(1):
- return ( write_rank1(i_target, i_data) );
-
- case(2):
- return ( write_rank2(i_target, i_data) );
-
- case(3):
- return ( write_rank3(i_target, i_data) );
-
- case(4):
- return ( write_rank4(i_target, i_data) );
-
- case(5):
- return ( write_rank5(i_target, i_data) );
-
- case(6):
- return ( write_rank6(i_target, i_data) );
-
- case(7):
- return ( write_rank7(i_target, i_data) );
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_RANK_PASSED()
- .set_RANK(i_rank)
- .set_TARGET(i_target)
- .set_FUNCTION(HWMS_WRITE),
- "%s Invalid rank passed to fwms::ecc::hwms::write(%d)",
- mss::c_str(i_target),
- i_rank);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief set_chipmark
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note HWMS0_CHIPMARK: Hardware chipmark (Galois field code)
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_chipmark( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::HARDWARE_MS_CHIPMARK, TT::HARDWARE_MS_CHIPMARK_LEN>(i_value);
- FAPI_INF("set_chipmark: 0x%02lx", i_value);
-}
-
-///
-/// @brief get_chipmark
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note HWMS0_CHIPMARK: Hardware chipmark (Galois field code)
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_chipmark( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::HARDWARE_MS_CHIPMARK, TT::HARDWARE_MS_CHIPMARK_LEN>(o_value);
- FAPI_INF("get_chipmark: 0x%02lx", o_value);
-}
-
-///
-/// @brief set_confirmed
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_state mss::YES or mss::NO - desired state
-/// @note HWMS0_CONFIRMED: chipmark confirmed
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_confirmed( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
-{
- io_data.writeBit<TT::HARDWARE_MS_CONFIRMED>(i_state);
- FAPI_INF("set_confirmed: 0x%01lx", i_state);
-}
-
-///
-/// @brief get_confirmed
-/// @tparam T fapi2 Target Type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_state mss::YES or mss::NO - representing the state of the field
-/// @note HWMS0_CONFIRMED: chipmark confirmed
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_confirmed( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state )
-{
- o_state = (i_data.getBit<TT::HARDWARE_MS_CONFIRMED>() == false) ? mss::NO : mss::YES;
- FAPI_INF("get_confirmed: 0x%01lx", o_state);
-}
-
-///
-/// @brief set_exit_1
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_state mss::YES or mss::NO - desired state
-/// @note HWMS0_EXIT_1: When set, bypass-enabled reads using this mark will
-/// @note use exit 1; otherwise exit 0
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_exit_1( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
-{
- io_data.writeBit<TT::HARDWARE_MS_EXIT1>(i_state);
- FAPI_INF("set_exit_1: 0x%01lx", i_state);
-}
-
-///
-/// @brief get_exit_1
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_state mss::YES or mss::NO - representing the state of the field
-/// @note HWMS0_EXIT_1: When set, bypass-enabled reads using this mark will
-/// @note use exit 1; otherwise exit 0
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_exit_1( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state )
-{
- o_state = (i_data.getBit<TT::HARDWARE_MS_EXIT1>() == false) ? mss::NO : mss::YES;
- FAPI_INF("get_exit_1: 0x%01lx", o_state);
-}
-
-} // close namespace hwms
-
-} // close namespace ecc
-
-} // close namespace mss
-
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_aue_trap.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_aue_trap.H
deleted file mode 100644
index c6d4a239a..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_aue_trap.H
+++ /dev/null
@@ -1,130 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_aue_trap.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file mainline_aue_trap.H
-/// @brief Subroutines for the MC mainline aue address trap registers (MBAUER*Q)
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_MAINLINE_AUE_TRAP_H_
-#define _MSS_MAINLINE_AUE_TRAP_H_
-
-#include <fapi2.H>
-#include <lib/mcbist/address.H>
-#include <generic/memory/lib/utils/scom.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/ecc/ecc_traits.H>
-
-namespace mss
-{
-
-namespace ecc
-{
-
-namespace mainline_aue_trap
-{
-
-///
-/// @brief Read MBS Mainline AUE Address Trap (MBAUER*Q) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- const auto& l_mcbist_target = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- const auto& l_port = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_target);
-
- FAPI_TRY( mss::getScom(l_mcbist_target, (TT::MAINLINE_AUE_REGS[l_port]), o_data) );
- FAPI_INF("%s read: 0x%016lx", mss::c_str(i_target), o_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write MBS Mainline AUE Address Trap (MBAUER*Q) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- const auto& l_mcbist_target = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- const auto& l_port = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_target);
-
- FAPI_TRY( mss::putScom(l_mcbist_target, (TT::MAINLINE_AUE_REGS[l_port]), i_data) );
- FAPI_INF("%s write: 0x%016lx", mss::c_str(i_target), i_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief set_address
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_address mcbist::address form of address field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
-{
- io_data.insertFromRight<TT::AUE_ADDR_TRAP, TT::AUE_ADDR_TRAP_LEN>(uint64_t(i_address));
- FAPI_INF("set_address: 0x%016lx", uint64_t(i_address));
-}
-
-///
-/// @brief get_address
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_address mcbist::address form of address field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
-{
- uint64_t l_addr = 0;
- i_data.extractToRight<TT::AUE_ADDR_TRAP, TT::AUE_ADDR_TRAP_LEN>(l_addr);
- o_address = mcbist::address(l_addr);
- FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
-}
-
-} // close namespace mainline_aue_trap
-
-} // close namespace ecc
-
-} // close namespace mss
-
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_mpe_trap.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_mpe_trap.H
deleted file mode 100644
index a8ea60c98..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_mpe_trap.H
+++ /dev/null
@@ -1,162 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_mpe_trap.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file mainline_mpe_trap.H
-/// @brief Subroutines for the MC mainline mpe address trap registers (MBNCER*Q)
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_MAINLINE_MPE_TRAP_H_
-#define _MSS_MAINLINE_MPE_TRAP_H_
-
-#include <fapi2.H>
-#include <lib/mcbist/address.H>
-#include <generic/memory/lib/utils/scom.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/ecc/ecc_traits.H>
-
-namespace mss
-{
-
-namespace ecc
-{
-
-namespace mainline_mpe_trap
-{
-
-///
-/// @brief Read MBS Mainline MPE Address Trap (MBMPER*Q) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- const auto& l_mcbist_target = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- const auto& l_port = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_target);
-
- FAPI_TRY( mss::getScom(l_mcbist_target, (TT::MAINLINE_MPE_REGS[l_port]), o_data) );
- FAPI_INF("%s read: 0x%016lx", mss::c_str(i_target), o_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write MBS Mainline MPE Address Trap (MBMPER*Q) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- const auto& l_mcbist_target = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- const auto& l_port = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_target);
-
- FAPI_TRY( mss::putScom(l_mcbist_target, (TT::MAINLINE_MPE_REGS[l_port]), i_data) );
- FAPI_INF("%s write: 0x%016lx", mss::c_str(i_target), i_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief set_address
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_address mcbist::address form of address field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
-{
- io_data.insertFromRight<TT::MPE_ADDR_TRAP, TT::MPE_ADDR_TRAP_LEN>(uint64_t(i_address));
- FAPI_INF("set_address: 0x%016lx", uint64_t(i_address));
-}
-
-///
-/// @brief get_address
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_address mcbist::address form of address field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
-{
- uint64_t l_addr = 0;
- i_data.extractToRight<TT::MPE_ADDR_TRAP, TT::MPE_ADDR_TRAP_LEN>(l_addr);
- o_address = mcbist::address(l_addr);
- FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
-}
-
-///
-/// @brief set_mpe_on_rce
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_state mss::YES or mss::NO - desired state
-/// @note MBMPER0Q_PORT_0_MAINLINE_MPE_ON_RCE: Indicates whether if this error
-/// @note came on the retry of a UE, RCD, or AUE as part of an RCE
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_mpe_on_rce( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
-{
- io_data.writeBit<TT::MPE_ON_RCE>(i_state);
- FAPI_INF("set_mpe_on_rce: 0x%01lx", i_state);
-}
-
-///
-/// @brief get_mpe_on_rce
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_state mss::YES or mss::NO - representing the state of the field
-/// @note MBMPER0Q_PORT_0_MAINLINE_MPE_ON_RCE: Indicates whether if this error
-/// @note came on the retry of a UE, RCD, or AUE as part of an RCE
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_mpe_on_rce( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state )
-{
- o_state = (i_data.getBit<TT::MPE_ON_RCE>() == false) ? mss::NO : mss::YES;
- FAPI_INF("get_mpe_on_rce: 0x%01lx", o_state);
-}
-
-} // close namespace mainline_mpe_trap
-
-} // close namespace ecc
-
-} // close namespace mss
-
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_nce_trap.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_nce_trap.H
deleted file mode 100644
index 038ed1e6e..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_nce_trap.H
+++ /dev/null
@@ -1,195 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_nce_trap.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file mainline_nce_trap.H
-/// @brief Subroutines for the MC mainline nce address trap registers (MBNCER*Q)
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_MAINLINE_NCE_TRAP_H_
-#define _MSS_MAINLINE_NCE_TRAP_H_
-
-#include <fapi2.H>
-#include <lib/mcbist/address.H>
-#include <generic/memory/lib/utils/scom.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/ecc/ecc_traits.H>
-#include <generic/memory/lib/utils/pos.H>
-
-namespace mss
-{
-
-namespace ecc
-{
-
-namespace mainline_nce_trap
-{
-
-///
-/// @brief Read MBS Mainline NCE Address Trap (MBNCER*Q) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- const auto& l_mcbist_target = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- const auto& l_port = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_target);
-
- FAPI_TRY( mss::getScom(l_mcbist_target, (TT::MAINLINE_NCE_REGS[l_port]), o_data) );
- FAPI_INF("%s read: 0x%016lx", mss::c_str(i_target), o_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write MBS Mainline NCE Address Trap (MBNCER*Q) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- const auto& l_mcbist_target = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- const auto& l_port = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_target);
-
- FAPI_TRY( mss::putScom(l_mcbist_target, (TT::MAINLINE_NCE_REGS[l_port]), i_data) );
- FAPI_INF("%s write: 0x%016lx", mss::c_str(i_target), i_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief set_address
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_address mcbist::address form of address field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
-{
- io_data.insertFromRight<TT::NCE_ADDR_TRAP, TT::NCE_ADDR_TRAP_LEN>(uint64_t(i_address));
- FAPI_INF("set_address: 0x%016lx", uint64_t(i_address));
-}
-
-///
-/// @brief get_address
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_address mcbist::address form of address field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
-{
- uint64_t l_addr = 0;
- i_data.extractToRight<TT::NCE_ADDR_TRAP, TT::NCE_ADDR_TRAP_LEN>(l_addr);
- o_address = mcbist::address(l_addr);
- FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
-}
-
-///
-/// @brief set_nce_on_rce
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_state mss::YES or mss::NO - desired state
-/// @note MBNCER0Q_PORT_0_MAINLINE_NCE_ON_RCE: Indicates whether if this NCE came on the
-/// @note retry of a UE, RCD, or AUE as part of an RCE
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_nce_on_rce( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
-{
- io_data.writeBit<TT::NCE_ON_RCE>(i_state);
- FAPI_INF("set_nce_on_rce: 0x%01lx", i_state);
-}
-
-///
-/// @brief get_nce_on_rce
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_state mss::YES or mss::NO - representing the state of the field
-/// @note MBNCER0Q_PORT_0_MAINLINE_NCE_ON_RCE: Indicates whether if this NCE came on the
-/// @note retry of a UE, RCD, or AUE as part of an RCE
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_nce_on_rce( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state )
-{
- o_state = (i_data.getBit<TT::NCE_ON_RCE>() == false) ? mss::NO : mss::YES;
- FAPI_INF("get_nce_on_rce: 0x%01lx", o_state);
-}
-
-///
-/// @brief set_nce_is_tce
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_state mss::YES or mss::NO - desired state
-/// @note MBNCER0Q_PORT_0_MAINLINE_NCE_IS_TCE: Indicates if this NCE is actually
-/// @note a two symbol error (TCE)
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_nce_is_tce( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
-{
- io_data.writeBit<TT::NCE_IS_TCE>(i_state);
- FAPI_INF("set_nce_is_tce: 0x%01lx", i_state);
-}
-
-///
-/// @brief get_nce_is_tce
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_state mss::YES or mss::NO - representing the state of the field
-/// @note MBNCER0Q_PORT_0_MAINLINE_NCE_IS_TCE: Indicates if this NCE is actually
-/// @note a two symbol error (TCE)
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_nce_is_tce( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state )
-{
- o_state = (i_data.getBit<TT::NCE_IS_TCE>() == false) ? mss::NO : mss::YES;
- FAPI_INF("get_nce_is_tce: 0x%01lx", o_state);
-}
-
-} // close namespace mainline_nce_trap
-
-} // close namespace ecc
-
-} // close namespace mss
-
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_rce_trap.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_rce_trap.H
deleted file mode 100644
index 35a0135b3..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_rce_trap.H
+++ /dev/null
@@ -1,130 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_rce_trap.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file mainline_rce_trap.H
-/// @brief Subroutines for the MC mainline rce address trap registers (MBRCER*Q)
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_MAINLINE_RCE_TRAP_H_
-#define _MSS_MAINLINE_RCE_TRAP_H_
-
-#include <fapi2.H>
-#include <lib/mcbist/address.H>
-#include <generic/memory/lib/utils/scom.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/ecc/ecc_traits.H>
-
-namespace mss
-{
-
-namespace ecc
-{
-
-namespace mainline_rce_trap
-{
-
-///
-/// @brief Read MBS Mainline RCE Address Trap (MBRCER*Q) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- const auto& l_mcbist_target = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- const auto& l_port = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_target);
-
- FAPI_TRY( mss::getScom(l_mcbist_target, (TT::MAINLINE_RCE_REGS[l_port]), o_data) );
- FAPI_INF("read: 0x%016lx", o_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write MBS Mainline RCE Address Trap (MBRCER*Q) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- const auto& l_mcbist_target = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- const auto& l_port = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_target);
-
- FAPI_TRY( mss::putScom(l_mcbist_target, (TT::MAINLINE_RCE_REGS[l_port]), i_data) );
- FAPI_INF("write: 0x%016lx", i_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief set_address
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_address mcbist::address form of address field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
-{
- io_data.insertFromRight<TT::RCE_ADDR_TRAP, TT::RCE_ADDR_TRAP_LEN>(uint64_t(i_address));
- FAPI_INF("set_address: 0x%016lx", uint64_t(i_address));
-}
-
-///
-/// @brief get_address
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_address mcbist::address form of address field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
-{
- uint64_t l_addr = 0;
- i_data.extractToRight<TT::RCE_ADDR_TRAP, TT::RCE_ADDR_TRAP_LEN>(l_addr);
- o_address = mcbist::address(l_addr);
- FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
-}
-
-} // close namespace mainline_rce_trap
-
-} // close namespace ecc
-
-} // close namespace mss
-
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_ue_trap.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_ue_trap.H
deleted file mode 100644
index 516f9181e..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_ue_trap.H
+++ /dev/null
@@ -1,130 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/mainline_ue_trap.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file mainline_ue_trap.H
-/// @brief Subroutines for the MC mainline ue address trap registers (MBUER*Q)
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_MAINLINE_UE_TRAP_H_
-#define _MSS_MAINLINE_UE_TRAP_H_
-
-#include <fapi2.H>
-#include <lib/mcbist/address.H>
-#include <generic/memory/lib/utils/scom.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/ecc/ecc_traits.H>
-
-namespace mss
-{
-
-namespace ecc
-{
-
-namespace mainline_ue_trap
-{
-
-///
-/// @brief Read MBS Mainline UE Address Trap (MBUER*Q) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- const auto& l_mcbist_target = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- const auto& l_port = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_target);
-
- FAPI_TRY( mss::getScom(l_mcbist_target, (TT::MAINLINE_UE_REGS[l_port]), o_data) );
- FAPI_INF("read: 0x%016lx", o_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write MBS Mainline UE Address Trap (MBUER*Q) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- const auto& l_mcbist_target = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- const auto& l_port = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_target);
-
- FAPI_TRY( mss::putScom(l_mcbist_target, (TT::MAINLINE_UE_REGS[l_port]), i_data) );
- FAPI_INF("write: 0x%016lx", i_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief set_address
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_address mcbist::address form of address field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
-{
- io_data.insertFromRight<TT::UE_ADDR_TRAP, TT::UE_ADDR_TRAP_LEN>(uint64_t(i_address));
- FAPI_INF("set_address: 0x%016lx", uint64_t(i_address));
-}
-
-///
-/// @brief get_address
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_address mcbist::address form of address field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
-{
- uint64_t l_addr = 0;
- i_data.extractToRight<TT::UE_ADDR_TRAP, TT::UE_ADDR_TRAP_LEN>(l_addr);
- o_address = mcbist::address(l_addr);
- FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
-}
-
-} // close namespace mainline_ue_trap
-
-} // close namespace ecc
-
-} // close namespace mss
-
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/maint_current_trap.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/maint_current_trap.H
deleted file mode 100644
index a06a2ccbe..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/maint_current_trap.H
+++ /dev/null
@@ -1,187 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/maint_current_trap.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file maint_current_trap.H
-/// @brief Subroutines for the MC maint current address trap register (MCBMCATQ)
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_MAINT_CURRENT_TRAP_H_
-#define _MSS_MAINT_CURRENT_TRAP_H_
-
-#include <fapi2.H>
-#include <lib/mcbist/address.H>
-#include <generic/memory/lib/utils/scom.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/ecc/ecc_traits.H>
-
-namespace mss
-{
-
-namespace ecc
-{
-
-namespace maint_current_trap
-{
-
-///
-/// @brief Read MBS Mainline MPE Address Trap (MCBMCATQ) register
-/// @param[in] i_target the fapi2 target of the MCA
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-inline fapi2::ReturnCode read( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- const auto& l_mcbist_target = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
-
- FAPI_TRY( mss::getScom(l_mcbist_target, MCBIST_MCBMCATQ, o_data) );
- FAPI_INF("read: 0x%016lx", o_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write MBS Mainline MPE Address Trap (MCBMCATQ) register
-/// @param[in] i_target the fapi2 target of the MCA
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-inline fapi2::ReturnCode write( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const fapi2::buffer<uint64_t>& i_data )
-{
- const auto& l_mcbist_target = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
-
- FAPI_TRY( mss::putScom(l_mcbist_target, MCBIST_MCBMCATQ, i_data) );
- FAPI_INF("write: 0x%016lx", i_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief set_address
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_address mcbist::address form of address field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
-{
- io_data.insertFromRight<TT::CURRENT_ADDR_TRAP, TT::CURRENT_ADDR_TRAP_LEN>(uint64_t(i_address));
- FAPI_INF("set_address: 0x%016lx", uint64_t(i_address));
-}
-
-///
-/// @brief get_address
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_address mcbist::address form of address field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
-{
- uint64_t l_addr = 0;
- i_data.extractToRight<TT::CURRENT_ADDR_TRAP, TT::CURRENT_ADDR_TRAP_LEN>(l_addr);
- o_address = mcbist::address(l_addr);
- FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
-}
-
-///
-/// @brief set_port
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value - desired value
-/// @note MCBMCATQ_CFG_CURRENT_PORT_TRAP: If MCBCFGQ_cfg_current_addr_trap_update_dis = 0, then this
-/// @note field will store port. This field is ONLY valid in maint_addr_mode. Garabage otherwise.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_port( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::CURRENT_PORT, TT::CURRENT_PORT_LEN>(i_value);
- FAPI_INF("set_port: 0x%01lx", i_value);
-}
-
-///
-/// @brief get_port
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value - representing the field value
-/// @note MCBMCATQ_CFG_CURRENT_PORT_TRAP: If MCBCFGQ_cfg_current_addr_trap_update_dis = 0, then this
-/// @note field will store port. This field is ONLY valid in maint_addr_mode. Garabage otherwise.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_port( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::CURRENT_PORT, TT::CURRENT_PORT_LEN>(o_value);
- FAPI_INF("get_port: 0x%01lx", o_value);
-}
-
-///
-/// @brief set_dimm
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value - desired value
-/// @note MCBMCATQ_CFG_CURRENT_DIMM_TRAP: If MCBCFGQ_cfg_current_addr_trap_update_dis = 0, then this
-/// @note field will store dimm select.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_dimm( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.writeBit<TT::CURRENT_DIMM>(i_value);
- FAPI_INF("set_dimm: 0x%01lx", i_value);
-}
-
-///
-/// @brief get_dimm
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value - representing the field value
-/// @note MCBMCATQ_CFG_CURRENT_DIMM_TRAP: If MCBCFGQ_cfg_current_addr_trap_update_dis = 0, then this
-/// @note field will store dimm select.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_dimm( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- o_value = i_data.getBit<TT::CURRENT_DIMM>();
- FAPI_INF("get_dimm: 0x%01lx", o_value);
-}
-
-} // close namespace maint_current_trap
-
-} // close namespace ecc
-
-} // close namespace mss
-
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mark_shadow_reg.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mark_shadow_reg.H
deleted file mode 100644
index 6f413559b..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mark_shadow_reg.H
+++ /dev/null
@@ -1,149 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/mark_shadow_reg.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file mark_shadow_reg.H
-/// @brief Subroutines for the MC mark shadow registers (MSR)
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_MARK_SHADOW_REG_H_
-#define _MSS_MARK_SHADOW_REG_H_
-
-#include <fapi2.H>
-#include <lib/mcbist/address.H>
-#include <generic/memory/lib/utils/scom.H>
-#include <lib/ecc/ecc_traits.H>
-
-namespace mss
-{
-
-namespace ecc
-{
-
-namespace mark_shadow_reg
-{
-
-///
-/// @brief Read Mark Shadow register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- FAPI_TRY( mss::getScom(i_target, TT::MARK_SHADOW_REG, o_data) );
- FAPI_INF("%s read: 0x%016lx", mss::c_str(i_target), o_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write Mark Shadow register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- FAPI_TRY( mss::putScom(i_target, TT::MARK_SHADOW_REG, i_data) );
- FAPI_INF("%s write: 0x%016lx", mss::c_str(i_target), i_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief set_chipmark
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_chipmark( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::SHADOW_CHIPMARK, TT::SHADOW_CHIPMARK_LEN>(i_value);
- FAPI_INF("set_chipmark: 0x%016lx", i_value);
-}
-
-///
-/// @brief get_chipmark
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_chipmark( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::SHADOW_CHIPMARK, TT::SHADOW_CHIPMARK_LEN>(o_value);
- FAPI_INF("get_chipmark: 0x%016lx", o_value);
-}
-
-///
-/// @brief set_rank
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void set_rank( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::SHADOW_RANK, TT::SHADOW_RANK_LEN>(i_value);
- FAPI_INF("set_rank: 0x%016lx", i_value);
-}
-
-///
-/// @brief get_rank
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<T> >
-inline void get_rank( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::SHADOW_RANK, TT::SHADOW_RANK_LEN>(o_value);
- FAPI_INF("get_rank: 0x%016lx", o_value);
-}
-
-} // close namespace mark_shadow_reg
-
-} // close namespace ecc
-
-} // close namespace mss
-
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/modal_symbol_count.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/modal_symbol_count.H
deleted file mode 100644
index f19185fee..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/modal_symbol_count.H
+++ /dev/null
@@ -1,573 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/modal_symbol_count.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file modal_symbol_count.H
-/// @brief Subroutines for the MC modal symbol count (MBSSYMEC*Q) registers
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_MODAL_SYMBOL_COUNT_H_
-#define _MSS_MODAL_SYMBOL_COUNT_H_
-
-#include <fapi2.H>
-#include <lib/ecc/ecc_traits.H>
-#include <generic/memory/lib/utils/scom.H>
-#include <lib/shared/mss_const.H>
-
-namespace mss
-{
-
-namespace ecc
-{
-
-namespace modal_symbol_count
-{
-
-///
-/// @brief Read modal symbol count (MBSSYMEC*Q) register
-/// @tparam N the register index (0-8)
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< uint64_t N, fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode read_index( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- static_assert((N < TT::NUM_MBSSYM_REGS), "Modal symbol count reg index failed range check");
- FAPI_TRY( mss::getScom(i_target, (TT::MODAL_SYM_COUNT0_REG + N), o_data) );
- FAPI_INF("read_index<%d>: 0x%016lx", N, o_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Read modal symbol count (MBSSYMEC*Q) 0 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_index0( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_index<0>(i_target, o_data) );
-}
-
-///
-/// @brief Read modal symbol count (MBSSYMEC*Q) 1 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_index1( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_index<1>(i_target, o_data) );
-}
-
-///
-/// @brief Read modal symbol count (MBSSYMEC*Q) 2 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_index2( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_index<2>(i_target, o_data) );
-}
-
-///
-/// @brief Read modal symbol count (MBSSYMEC*Q) 3 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_index3( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_index<3>(i_target, o_data) );
-}
-
-///
-/// @brief Read modal symbol count (MBSSYMEC*Q) 4 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_index4( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_index<4>(i_target, o_data) );
-}
-
-///
-/// @brief Read modal symbol count (MBSSYMEC*Q) 5 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_index5( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_index<5>(i_target, o_data) );
-}
-
-///
-/// @brief Read modal symbol count (MBSSYMEC*Q) 6 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_index6( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_index<6>(i_target, o_data) );
-}
-
-///
-/// @brief Read modal symbol count (MBSSYMEC*Q) 7 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_index7( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_index<7>(i_target, o_data) );
-}
-
-///
-/// @brief Read modal symbol count (MBSSYMEC*Q) 8 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read_index8( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- return ( read_index<8>(i_target, o_data) );
-}
-
-///
-/// @brief Read modal symbol count (MBSSYMEC*Q) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_index the register index
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target,
- const uint64_t i_index,
- fapi2::buffer<uint64_t>& o_data )
-{
- switch (i_index)
- {
- case(0):
- return ( read_index0(i_target, o_data) );
-
- case(1):
- return ( read_index1(i_target, o_data) );
-
- case(2):
- return ( read_index2(i_target, o_data) );
-
- case(3):
- return ( read_index3(i_target, o_data) );
-
- case(4):
- return ( read_index4(i_target, o_data) );
-
- case(5):
- return ( read_index5(i_target, o_data) );
-
- case(6):
- return ( read_index6(i_target, o_data) );
-
- case(7):
- return ( read_index7(i_target, o_data) );
-
- case(8):
- return ( read_index8(i_target, o_data) );
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_INDEX_PASSED()
- .set_INDEX(i_index)
- .set_FUNCTION(SYMBOL_COUNT_READ),
- "%s Invalid index passed to fwms::ecc::modal_symbol_count::read (%d)",
- mss::c_str(i_target),
- i_index);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write modal symbol count (MBSSYMEC*Q) register
-/// @tparam N the register index (0-8)
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< uint64_t N, fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode write_index( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- static_assert((N < TT::NUM_MBSSYM_REGS), "Modal symbol count reg index failed range check");
- FAPI_TRY( mss::putScom(i_target, (TT::MODAL_SYM_COUNT0_REG + N), i_data) );
- FAPI_INF("write_index<%d>: 0x%016lx", N, i_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write modal symbol count (MBSSYMEC*Q) 0 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_index0( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_index<0>(i_target, i_data) );
-}
-
-///
-/// @brief Write modal symbol count (MBSSYMEC*Q) 1 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_index1( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_index<1>(i_target, i_data) );
-}
-
-///
-/// @brief Write modal symbol count (MBSSYMEC*Q) 2 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_index2( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_index<2>(i_target, i_data) );
-}
-
-///
-/// @brief Write modal symbol count (MBSSYMEC*Q) 3 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_index3( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_index<3>(i_target, i_data) );
-}
-
-///
-/// @brief Write modal symbol count (MBSSYMEC*Q) 4 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_index4( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_index<4>(i_target, i_data) );
-}
-
-///
-/// @brief Write modal symbol count (MBSSYMEC*Q) 5 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_index5( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_index<5>(i_target, i_data) );
-}
-
-///
-/// @brief Write modal symbol count (MBSSYMEC*Q) 6 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_index6( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_index<6>(i_target, i_data) );
-}
-
-///
-/// @brief Write modal symbol count (MBSSYMEC*Q) 7 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_index7( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_index<7>(i_target, i_data) );
-}
-
-///
-/// @brief Write modal symbol count (MBSSYMEC*Q) 8 register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write_index8( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- return ( write_index<8>(i_target, i_data) );
-}
-
-///
-/// @brief Write Hardware Mark Store (HWMS) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_index the register index
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target,
- const uint64_t i_index,
- const fapi2::buffer<uint64_t>& i_data )
-{
- switch (i_index)
- {
- case(0):
- return ( write_index0(i_target, i_data) );
-
- case(1):
- return ( write_index1(i_target, i_data) );
-
- case(2):
- return ( write_index2(i_target, i_data) );
-
- case(3):
- return ( write_index3(i_target, i_data) );
-
- case(4):
- return ( write_index4(i_target, i_data) );
-
- case(5):
- return ( write_index5(i_target, i_data) );
-
- case(6):
- return ( write_index6(i_target, i_data) );
-
- case(7):
- return ( write_index7(i_target, i_data) );
-
- case(8):
- return ( write_index8(i_target, i_data) );
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_INDEX_PASSED()
- .set_INDEX(i_index)
- .set_FUNCTION(SYMBOL_COUNT_WRITE),
- "%s Invalid index passed to fwms::ecc::modal_symbol_count::write (%d)",
- mss::c_str(i_target),
- i_index);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief set_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_index the counter index
-/// @param[in] i_value the value of the field
-/// @note MBSSYMEC*Q_MODAL_SYMBOL_COUNTER_XX: Functional mode determined by MBSTRQ_Symbol_counter_mode:
-/// @note if 00, 0:7 = Maint NCE counter for Symbol XX if 01, 0:3 = MCBIST error counter for nibble (XX/4)
-/// @note and rank (XX%4)*2 4:7 = MCBIST error counter for nibble (XX/4) and rank ((XX%4)*2)+1 if 10,
-/// @note 0:3 = MCBIST error counter for port XX/18 and nibble XX%18 4:7 = MCBIST error rank map for
-/// @note port XX/18 and nibble XX%18
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_index, const uint64_t i_value )
-{
- static_assert ( TT::MODAL_SYMBOL_COUNTERS_PER_REG <= 8,
- "mss::ecc_count::modal_symbol_count: Modal symbol count field index failed range check" );
- const uint64_t l_field = i_index % TT::MODAL_SYMBOL_COUNTERS_PER_REG;
-
- switch (l_field)
- {
- case 0:
- io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_00, TT::MODAL_SYMBOL_COUNTER_00_LEN>(i_value);
- break;
-
- case 1:
- io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_01, TT::MODAL_SYMBOL_COUNTER_01_LEN>(i_value);
- break;
-
- case 2:
- io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_02, TT::MODAL_SYMBOL_COUNTER_02_LEN>(i_value);
- break;
-
- case 3:
- io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_03, TT::MODAL_SYMBOL_COUNTER_03_LEN>(i_value);
- break;
-
- case 4:
- io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_04, TT::MODAL_SYMBOL_COUNTER_04_LEN>(i_value);
- break;
-
- case 5:
- io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_05, TT::MODAL_SYMBOL_COUNTER_05_LEN>(i_value);
- break;
-
- case 6:
- io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_06, TT::MODAL_SYMBOL_COUNTER_06_LEN>(i_value);
- break;
-
- case 7:
- io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_07, TT::MODAL_SYMBOL_COUNTER_07_LEN>(i_value);
- break;
-
- default:
- // Shouldn't happen due to modulo above, but here just in case - JLH
- FAPI_ERR("Modal symbol count field index failed range check");
- fapi2::Assert(false);
- break;
- }
-
- FAPI_INF("set_count(%d): 0x%02lx", l_field, i_value);
-}
-
-///
-/// @brief get_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[in] i_index the counter index
-/// @param[out] o_value the value of the field
-/// @note MBSSYMEC*Q_MODAL_SYMBOL_COUNTER_XX: Functional mode determined by MBSTRQ_Symbol_counter_mode:
-/// @note if 00, 0:7 = Maint NCE counter for Symbol XX if 01, 0:3 = MCBIST error counter for nibble (XX/4)
-/// @note and rank (XX%4)*2 4:7 = MCBIST error counter for nibble (XX/4) and rank ((XX%4)*2)+1 if 10,
-/// @note 0:3 = MCBIST error counter for port XX/18 and nibble XX%18 4:7 = MCBIST error rank map for
-/// @note port XX/18 and nibble XX%18
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_count( const fapi2::buffer<uint64_t>& i_data, const uint64_t i_index, uint64_t& o_value )
-{
- const uint64_t l_field = i_index % TT::MODAL_SYMBOL_COUNTERS_PER_REG;
- static_assert ( TT::MODAL_SYMBOL_COUNTERS_PER_REG <= 8,
- "mss::ecc_count::get_count: Modal symbol count field index failed range check" );
-
- switch (l_field)
- {
- case 0:
- i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_00, TT::MODAL_SYMBOL_COUNTER_00_LEN>(o_value);
- break;
-
- case 1:
- i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_01, TT::MODAL_SYMBOL_COUNTER_01_LEN>(o_value);
- break;
-
- case 2:
- i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_02, TT::MODAL_SYMBOL_COUNTER_02_LEN>(o_value);
- break;
-
- case 3:
- i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_03, TT::MODAL_SYMBOL_COUNTER_03_LEN>(o_value);
- break;
-
- case 4:
- i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_04, TT::MODAL_SYMBOL_COUNTER_04_LEN>(o_value);
- break;
-
- case 5:
- i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_05, TT::MODAL_SYMBOL_COUNTER_05_LEN>(o_value);
- break;
-
- case 6:
- i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_06, TT::MODAL_SYMBOL_COUNTER_06_LEN>(o_value);
- break;
-
- case 7:
- i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_07, TT::MODAL_SYMBOL_COUNTER_07_LEN>(o_value);
- break;
-
- default:
- // shouldn't happen due to modulo above, but here just in case
- FAPI_ERR("Modal symbol count field index failed range check");
- fapi2::Assert(false);
- break;
- }
-
- FAPI_INF("get_count(%d): 0x%02lx", l_field, o_value);
-}
-
-} // close namespace modal_symbol_count
-
-} // close namespace ecc
-
-} // close namespace mss
-
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mbs_error_vector_trap.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/nimbus_mbs_error_vector_trap.H
index 4ed773988..fe6525231 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/mbs_error_vector_trap.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/nimbus_mbs_error_vector_trap.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/mbs_error_vector_trap.H $ */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/nimbus_mbs_error_vector_trap.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -24,22 +24,24 @@
/* IBM_PROLOG_END_TAG */
///
-/// @file mbs_error_vector_trap.H
+/// @file nimbus_mbs_error_vector_trap.H
/// @brief Subroutines for the MC MBS error vector trap registers (MBSEVR*Q)
///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
-#ifndef _MSS_MBS_ERROR_VECTOR_TRAP_H_
-#define _MSS_MBS_ERROR_VECTOR_TRAP_H_
+#ifndef _NIMBUS_MBS_ERROR_VECTOR_TRAP_H_
+#define _NIMBUS_MBS_ERROR_VECTOR_TRAP_H_
#include <fapi2.H>
#include <generic/memory/lib/utils/scom.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/ecc/ecc_traits.H>
+#include <lib/utils/nimbus_find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+#include <generic/memory/lib/ecc/mbs_error_vector_trap.H>
namespace mss
{
@@ -51,54 +53,14 @@ namespace mbs_error_vector_trap
{
///
-/// @brief Read MBS Error Vector Trap (MBSEVR*Q) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- const auto& l_mcbist_target = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- const auto& l_port = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_target);
-
- FAPI_TRY( mss::getScom(l_mcbist_target, (TT::ERROR_VECTOR_REGS[l_port]), o_data) );
- FAPI_INF("%s read: 0x%016lx", mss::c_str(i_target), o_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write MBS Error Vector Trap (MBSEVR*Q) register
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mc
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- const auto& l_mcbist_target = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- const auto& l_port = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_target);
-
- FAPI_TRY( mss::putScom(l_mcbist_target, (TT::ERROR_VECTOR_REGS[l_port]), i_data) );
- FAPI_INF("%s write: 0x%016lx", mss::c_str(i_target), i_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief set_nce_galois
/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
+/// @tparam TT traits type defaults to eccTraits<mc_type::NIMBUS, T>
/// @param[in] i_target the fapi2 target of the mc
/// @param[in, out] io_data the register value
/// @param[in] i_value the value of the field
///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::NIMBUS, T> >
inline void set_nce_galois( const fapi2::Target<T>& i_target,
fapi2::buffer<uint64_t>& io_data,
const uint64_t i_value)
@@ -121,12 +83,12 @@ inline void set_nce_galois( const fapi2::Target<T>& i_target,
///
/// @brief get_nce_galois
/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
+/// @tparam TT traits type defaults to eccTraits<mc_type::NIMBUS, T>
/// @param[in] i_target the fapi2 target of the mc
/// @param[in] i_data the register value
/// @param[out] i_value the value of the field
///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::NIMBUS, T> >
inline void get_nce_galois( const fapi2::Target<T>& i_target,
const fapi2::buffer<uint64_t>& i_data,
uint64_t& o_value)
@@ -149,12 +111,12 @@ inline void get_nce_galois( const fapi2::Target<T>& i_target,
///
/// @brief set_nce_magnitude
/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
+/// @tparam TT traits type defaults to eccTraits<mc_type::NIMBUS, T>
/// @param[in] i_target the fapi2 target of the mc
/// @param[in, out] io_data the register value
/// @param[in] i_value the value of the field
///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::NIMBUS, T> >
inline void set_nce_magnitude( const fapi2::Target<T>& i_target,
fapi2::buffer<uint64_t>& io_data,
const uint64_t i_value)
@@ -177,12 +139,12 @@ inline void set_nce_magnitude( const fapi2::Target<T>& i_target,
///
/// @brief get_nce_magnitude
/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
+/// @tparam TT traits type defaults to eccTraits<mc_type::NIMBUS, T>
/// @param[in] i_target the fapi2 target of the mc
/// @param[in] i_data the register value
/// @param[out] i_value the value of the field
///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::NIMBUS, T> >
inline void get_nce_magnitude( const fapi2::Target<T>& i_target,
const fapi2::buffer<uint64_t>& i_data,
uint64_t& o_value)
@@ -205,12 +167,12 @@ inline void get_nce_magnitude( const fapi2::Target<T>& i_target,
///
/// @brief set_tce_galois
/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
+/// @tparam TT traits type defaults to eccTraits<mc_type::NIMBUS, T>
/// @param[in] i_target the fapi2 target of the mc
/// @param[in, out] io_data the register value
/// @param[in] i_value the value of the field
///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::NIMBUS, T> >
inline void set_tce_galois( const fapi2::Target<T>& i_target,
fapi2::buffer<uint64_t>& io_data,
const uint64_t i_value)
@@ -233,12 +195,12 @@ inline void set_tce_galois( const fapi2::Target<T>& i_target,
///
/// @brief get_tce_galois
/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
+/// @tparam TT traits type defaults to eccTraits<mc_type::NIMBUS, T>
/// @param[in] i_target the fapi2 target of the mc
/// @param[in] i_data the register value
/// @param[out] i_value the value of the field
///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::NIMBUS, T> >
inline void get_tce_galois( const fapi2::Target<T>& i_target,
const fapi2::buffer<uint64_t>& i_data,
uint64_t& o_value)
@@ -261,12 +223,12 @@ inline void get_tce_galois( const fapi2::Target<T>& i_target,
///
/// @brief set_tce_magnitude
/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
+/// @tparam TT traits type defaults to eccTraits<mc_type::NIMBUS, T>
/// @param[in] i_target the fapi2 target of the mc
/// @param[in, out] io_data the register value
/// @param[in] i_value the value of the field
///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::NIMBUS, T> >
inline void set_tce_magnitude( const fapi2::Target<T>& i_target,
fapi2::buffer<uint64_t>& io_data,
const uint64_t i_value)
@@ -289,12 +251,12 @@ inline void set_tce_magnitude( const fapi2::Target<T>& i_target,
///
/// @brief get_tce_magnitude
/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
+/// @tparam TT traits type defaults to eccTraits<mc_type::NIMBUS, T>
/// @param[in] i_target the fapi2 target of the mc
/// @param[in] i_data the register value
/// @param[out] i_value the value of the field
///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
+template< fapi2::TargetType T, typename TT = eccTraits<mc_type::NIMBUS, T> >
inline void get_tce_magnitude( const fapi2::Target<T>& i_target,
const fapi2::buffer<uint64_t>& i_data,
uint64_t& o_value)
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/read_error_count_regs.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/read_error_count_regs.H
deleted file mode 100644
index 834f01b19..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/read_error_count_regs.H
+++ /dev/null
@@ -1,648 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/read_error_count_regs.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file mainline_ue_trap.H
-/// @brief Subroutines for the MBS Memory Scrub/Read Error Count registers (MBSEC*Q)
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_READ_ERROR_COUNT_REGS_H_
-#define _MSS_READ_ERROR_COUNT_REGS_H_
-
-#include <fapi2.H>
-#include <lib/mcbist/address.H>
-#include <generic/memory/lib/utils/scom.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/ecc/ecc_traits.H>
-
-namespace mss
-{
-
-namespace ecc
-{
-
-namespace read_error_count_reg0
-{
-
-///
-/// @brief Read MBS Memory Scrub/Read Error Count Register 0 (MBSEC0Q)
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mcbist
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- FAPI_TRY( mss::getScom(i_target, TT::READ_ERROR_COUNT_REG0, o_data) );
- FAPI_INF("%s read: 0x%016lx", mss::c_str(i_target), o_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write MBS Memory Scrub/Read Error Count Register 0 (MBSEC0Q)
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mcbist
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- FAPI_TRY( mss::putScom(i_target, TT::READ_ERROR_COUNT_REG0, i_data) );
- FAPI_INF("%s write: 0x%016lx", mss::c_str(i_target), i_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief set_intermittent_ce_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note MBSEC0Q_INTERMITTENT_CE_COUNT: Intermittent CE Count This is a 12-bit count of
-/// @note intermittent CE events. Will freeze its value upon incrementing to the max
-/// @note value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_intermittent_ce_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::INTERMITTENT_CE_COUNT, TT::INTERMITTENT_CE_COUNT_LEN>(i_value);
- FAPI_INF("set_intermittent_ce_count: 0x%03lx", i_value);
-}
-
-///
-/// @brief get_intermittent_ce_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note MBSEC0Q_INTERMITTENT_CE_COUNT: Intermittent CE Count This is a 12-bit count of
-/// @note intermittent CE events. Will freeze its value upon incrementing to the max
-/// @note value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_intermittent_ce_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::INTERMITTENT_CE_COUNT, TT::INTERMITTENT_CE_COUNT_LEN>(o_value);
- FAPI_INF("get_intermittent_ce_count: 0x%03lx", o_value);
-}
-
-///
-/// @brief set_soft_ce_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note MBSEC0Q_SOFT_CE_COUNT: Soft CE Count This is a 12-bit count of
-/// @note soft CE events. Will freeze its value upon incrementing to the max
-/// @note value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_soft_ce_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::SOFT_CE_COUNT, TT::SOFT_CE_COUNT_LEN>(i_value);
- FAPI_INF("set_soft_ce_count: 0x%03lx", i_value);
-}
-
-///
-/// @brief get_soft_ce_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note MBSEC0Q_SOFT_CE_COUNT: Soft CE Count This is a 12-bit count of
-/// @note soft CE events. Will freeze its value upon incrementing to the max
-/// @note value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_soft_ce_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::SOFT_CE_COUNT, TT::SOFT_CE_COUNT_LEN>(o_value);
- FAPI_INF("get_soft_ce_count: 0x%03lx", o_value);
-}
-
-///
-/// @brief set_hard_ce_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note MBSEC0Q_HARD_CE_COUNT: Hard CE Count This is a 12-bit count of
-/// @note hard CE events. Will freeze its value upon incrementing to the max
-/// @note value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_hard_ce_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::HARD_CE_COUNT, TT::HARD_CE_COUNT_LEN>(i_value);
- FAPI_INF("set_hard_ce_count: 0x%03lx", i_value);
-}
-
-///
-/// @brief get_hard_ce_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note MBSEC0Q_HARD_CE_COUNT: Hard CE Count This is a 12-bit count of
-/// @note hard CE events. Will freeze its value upon incrementing to the max
-/// @note value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_hard_ce_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::HARD_CE_COUNT, TT::HARD_CE_COUNT_LEN>(o_value);
- FAPI_INF("get_hard_ce_count: 0x%03lx", o_value);
-}
-
-///
-/// @brief set_intermittent_mce_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note MBSEC0Q_INTERMITTENT_MCE_COUNT: Intermittent MCE Count This is a 12-bit count of
-/// @note intermittent Marked Chip Correctable Error events. Will freeze its value upon
-/// @note incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_intermittent_mce_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::INTERMITTENT_MCE_COUNT, TT::INTERMITTENT_MCE_COUNT_LEN>(i_value);
- FAPI_INF("set_intermittent_mce_count: 0x%03lx", i_value);
-}
-
-///
-/// @brief get_intermittent_mce_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note MBSEC0Q_INTERMITTENT_MCE_COUNT: Intermittent MCE Count This is a 12-bit count of
-/// @note intermittent Marked Chip Correctable Error events. Will freeze its value upon
-/// @note incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_intermittent_mce_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::INTERMITTENT_MCE_COUNT, TT::INTERMITTENT_MCE_COUNT_LEN>(o_value);
- FAPI_INF("get_intermittent_mce_count: 0x%03lx", o_value);
-}
-
-///
-/// @brief set_soft_mce_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note MBSEC0Q_SOFT_MCE_COUNT: Soft MCE Count This is a 12-bit count of
-/// @note soft Marked Chip Correctable Error events. Will freeze its value upon
-/// @note incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_soft_mce_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::SOFT_MCE_COUNT, TT::SOFT_MCE_COUNT_LEN>(i_value);
- FAPI_INF("set_soft_mce_count: 0x%03lx", i_value);
-}
-
-///
-/// @brief get_soft_mce_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note MBSEC0Q_SOFT_MCE_COUNT: Soft MCE Count This is a 12-bit count of
-/// @note soft Marked Chip Correctable Error events. Will freeze its value upon
-/// @note incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_soft_mce_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::SOFT_MCE_COUNT, TT::SOFT_MCE_COUNT_LEN>(o_value);
- FAPI_INF("get_soft_mce_count: 0x%03lx", o_value);
-}
-
-} // close namespace read_error_count_reg0
-
-namespace read_error_count_reg1
-{
-
-///
-/// @brief Read MBS Memory Scrub/Read Error Count Register 1 (MBSEC1Q)
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mcbist
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- FAPI_TRY( mss::getScom(i_target, TT::READ_ERROR_COUNT_REG1, o_data) );
- FAPI_INF("%s read: 0x%016lx", mss::c_str(i_target), o_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write MBS Memory Scrub/Read Error Count Register 1 (MBSEC1Q)
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mcbist
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- FAPI_TRY( mss::putScom(i_target, TT::READ_ERROR_COUNT_REG1, i_data) );
- FAPI_INF("%s write: 0x%016lx", mss::c_str(i_target), i_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief set_hard_mce_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note MBSEC0Q_HARD_MCE_COUNT: Hard MCE Count This is a 12-bit count of
-/// @note hard Marked Chip Correctable Error events. Will freeze its value upon
-/// @note incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_hard_mce_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::HARD_MCE_COUNT, TT::HARD_MCE_COUNT_LEN>(i_value);
- FAPI_INF("set_hard_mce_count: 0x%03lx", i_value);
-}
-
-///
-/// @brief get_hard_mce_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note MBSEC0Q_HARD_MCE_COUNT: Hard MCE Count This is a 12-bit count of
-/// @note hard Marked Chip Correctable Error events. Will freeze its value upon
-/// @note incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_hard_mce_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::HARD_MCE_COUNT, TT::HARD_MCE_COUNT_LEN>(o_value);
- FAPI_INF("get_hard_mce_count: 0x%03lx", o_value);
-}
-
-///
-/// @brief set_ice_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note MBSEC0Q_ICE_COUNT: ICE (IMPE) Count This is a 12-bit count of
-/// @note Intermittent Marked-Placed Chip Error events. Will freeze its value upon
-/// @note incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_ice_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::ICE_COUNT, TT::ICE_COUNT_LEN>(i_value);
- FAPI_INF("set_ice_count: 0x%03lx", i_value);
-}
-
-///
-/// @brief get_ice_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note MBSEC0Q_ICE_COUNT: ICE (IMPE) Count This is a 12-bit count of
-/// @note Intermittent Marked-Placed Chip Error events. Will freeze its value upon
-/// @note incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_ice_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::ICE_COUNT, TT::ICE_COUNT_LEN>(o_value);
- FAPI_INF("get_ice_count: 0x%03lx", o_value);
-}
-
-///
-/// @brief set_ue_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note MBSEC0Q_UE_COUNT: UE Count This is a 12-bit count of
-/// @note Uncorrectable Error events. Will freeze its value upon
-/// @note incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_ue_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::UE_COUNT, TT::UE_COUNT_LEN>(i_value);
- FAPI_INF("set_ue_count: 0x%03lx", i_value);
-}
-
-///
-/// @brief get_ue_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note MBSEC0Q_UE_COUNT: UE Count This is a 12-bit count of
-/// @note Uncorrectable Error events. Will freeze its value upon
-/// @note incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_ue_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::UE_COUNT, TT::UE_COUNT_LEN>(o_value);
- FAPI_INF("get_ue_count: 0x%03lx", o_value);
-}
-
-///
-/// @brief set_aue_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note MBSEC0Q_AUE_COUNT: AUE Count This is a 12-bit count of
-/// @note AUE Parity Error events. Will freeze its value upon
-/// @note incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_aue_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::AUE_COUNT, TT::AUE_COUNT_LEN>(i_value);
- FAPI_INF("set_aue_count: 0x%03lx", i_value);
-}
-
-///
-/// @brief get_aue_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note MBSEC0Q_AUE_COUNT: AUE Count This is a 12-bit count of
-/// @note AUE Parity Error events. Will freeze its value upon
-/// @note incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_aue_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::AUE_COUNT, TT::AUE_COUNT_LEN>(o_value);
- FAPI_INF("get_aue_count: 0x%03lx", o_value);
-}
-
-///
-/// @brief set_rce_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note MBSEC0Q_RCE_COUNT: RCE Count This is a 12-bit count of
-/// @note Retried Correctable Error events. Will freeze its value upon
-/// @note incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_rce_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::RCE_COUNT, TT::RCE_COUNT_LEN>(i_value);
- FAPI_INF("set_rce_count: 0x%03lx", i_value);
-}
-
-///
-/// @brief get_rce_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note MBSEC0Q_RCE_COUNT: RCE Count This is a 12-bit count of
-/// @note Retried Correctable Error events. Will freeze its value upon
-/// @note incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_rce_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::RCE_COUNT, TT::RCE_COUNT_LEN>(o_value);
- FAPI_INF("get_rce_count: 0x%03lx", o_value);
-}
-
-} // close namespace read_error_count_reg1
-
-namespace mark_symbol_count_reg
-{
-
-///
-/// @brief Read MBS Mark Symbol Error Count Register (MBSMSECQ)
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mcbist
-/// @param[out] o_data the value of the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- FAPI_TRY( mss::getScom(i_target, TT::MARK_SYMBOL_COUNT_REG, o_data) );
- FAPI_INF("read: 0x%016lx", o_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Write MBS Mark Symbol Error Count Register (MBSMSECQ)
-/// @tparam T fapi2 Target Type - derived from i_target's type
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_target the fapi2 target of the mcbist
-/// @param[in] i_data the value to write to the register
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- FAPI_TRY( mss::putScom(i_target, TT::MARK_SYMBOL_COUNT_REG, i_data) );
- FAPI_INF("write: 0x%016lx", i_data);
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief set_symbol0_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note MBSMSECQ_MCE_SYMBOL0_COUNT: MCE Symbol 0 Error Count This is a 8-bit count
-/// @note that increments on MCE when Symbol 0 under chip mark takes error. Will freeze
-/// @note its value upon incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_symbol0_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::SYMBOL0_COUNT, TT::SYMBOL0_COUNT_LEN>(i_value);
- FAPI_INF("set_symbol0_count: 0x%03lx", i_value);
-}
-
-///
-/// @brief get_symbol0_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note MBSMSECQ_MCE_SYMBOL0_COUNT: MCE Symbol 0 Error Count This is a 8-bit count
-/// @note that increments on MCE when Symbol 0 under chip mark takes error. Will freeze
-/// @note its value upon incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_symbol0_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::SYMBOL0_COUNT, TT::SYMBOL0_COUNT_LEN>(o_value);
- FAPI_INF("get_symbol0_count: 0x%03lx", o_value);
-}
-
-///
-/// @brief set_symbol1_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note MBSMSECQ_MCE_SYMBOL1_COUNT: MCE Symbol 1 Error Count This is a 8-bit count
-/// @note that increments on MCE when Symbol 1 under chip mark takes error. Will freeze
-/// @note its value upon incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_symbol1_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::SYMBOL1_COUNT, TT::SYMBOL1_COUNT_LEN>(i_value);
- FAPI_INF("set_symbol1_count: 0x%03lx", i_value);
-}
-
-///
-/// @brief get_symbol1_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note MBSMSECQ_MCE_SYMBOL1_COUNT: MCE Symbol 1 Error Count This is a 8-bit count
-/// @note that increments on MCE when Symbol 1 under chip mark takes error. Will freeze
-/// @note its value upon incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_symbol1_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::SYMBOL1_COUNT, TT::SYMBOL1_COUNT_LEN>(o_value);
- FAPI_INF("get_symbol1_count: 0x%03lx", o_value);
-}
-
-///
-/// @brief set_symbol2_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note MBSMSECQ_MCE_SYMBOL2_COUNT: MCE Symbol 2 Error Count This is a 8-bit count
-/// @note that increments on MCE when Symbol 2 under chip mark takes error. Will freeze
-/// @note its value upon incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_symbol2_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::SYMBOL2_COUNT, TT::SYMBOL2_COUNT_LEN>(i_value);
- FAPI_INF("set_symbol2_count: 0x%03lx", i_value);
-}
-
-///
-/// @brief get_symbol2_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note MBSMSECQ_MCE_SYMBOL2_COUNT: MCE Symbol 2 Error Count This is a 8-bit count
-/// @note that increments on MCE when Symbol 2 under chip mark takes error. Will freeze
-/// @note its value upon incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_symbol2_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::SYMBOL2_COUNT, TT::SYMBOL2_COUNT_LEN>(o_value);
- FAPI_INF("get_symbol2_count: 0x%03lx", o_value);
-}
-
-///
-/// @brief set_symbol3_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in, out] io_data the register value
-/// @param[in] i_value the value of the field
-/// @note MBSMSECQ_MCE_SYMBOL3_COUNT: MCE Symbol 3 Error Count This is a 8-bit count
-/// @note that increments on MCE when Symbol 3 under chip mark takes error. Will freeze
-/// @note its value upon incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void set_symbol3_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
-{
- io_data.insertFromRight<TT::SYMBOL3_COUNT, TT::SYMBOL3_COUNT_LEN>(i_value);
- FAPI_INF("set_symbol3_count: 0x%03lx", i_value);
-}
-
-///
-/// @brief get_symbol3_count
-/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @param[in] i_data the register value
-/// @param[out] o_value the value of the field
-/// @note MBSMSECQ_MCE_SYMBOL3_COUNT: MCE Symbol 3 Error Count This is a 8-bit count
-/// @note that increments on MCE when Symbol 3 under chip mark takes error. Will freeze
-/// @note its value upon incrementing to the max value until reset.
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = eccTraits<T> >
-inline void get_symbol3_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
-{
- i_data.extractToRight<TT::SYMBOL3_COUNT, TT::SYMBOL3_COUNT_LEN>(o_value);
- FAPI_INF("get_symbol3_count: 0x%03lx", o_value);
-}
-
-} // close namespace mark_symbol_count_reg
-
-} // close namespace ecc
-
-} // close namespace mss
-
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/memory_size.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/memory_size.C
index 35e1dd62e..61326898d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/memory_size.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/memory_size.C
@@ -38,7 +38,7 @@
#include <lib/mss_attribute_accessors.H>
#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/memory_size.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
namespace mss
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_mss_voltage.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_mss_voltage.C
index d895897ca..df3390257 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_mss_voltage.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_mss_voltage.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,7 +42,7 @@
// Generic libraries
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <generic/memory/lib/spd/spd_facade.H>
#include <generic/memory/lib/utils/voltage/gen_mss_voltage_traits.H>
#include <generic/memory/lib/utils/voltage/gen_mss_volt.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C
index 281fe8c56..d8358a8a5 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C
@@ -34,7 +34,7 @@
// *HWP Level: 3
// *HWP Consumed by: CI
-#include <generic/memory/lib/data_engine/pre_data_init.H>
+#include <lib/eff_config/pre_data_init.H>
namespace mss
{
diff --git a/src/import/generic/memory/lib/data_engine/p9n/p9n_data_init_traits.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/p9n_data_init_traits.H
index 5f0207b14..93d3e43d6 100644
--- a/src/import/generic/memory/lib/data_engine/p9n/p9n_data_init_traits.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/p9n_data_init_traits.H
@@ -1,7 +1,7 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/generic/memory/lib/data_engine/p9n/p9n_data_init_traits.H $ */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/eff_config/p9n_data_init_traits.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
@@ -50,7 +50,7 @@ namespace mss
/// @note NIMBUS, DIMM_TYPE specialization
///
template<>
-class preDataInitTraits<mss::proc_type::NIMBUS, DIMM_TYPE>
+class preDataInitTraits<mss::proc_type::NIMBUS, pre_data_init_fields::DIMM_TYPE>
{
public:
using attr_type = fapi2::ATTR_EFF_DIMM_TYPE_Type;
@@ -91,7 +91,7 @@ class preDataInitTraits<mss::proc_type::NIMBUS, DIMM_TYPE>
/// @note NIMBUS, DRAM_GEN specialization
///
template<>
-class preDataInitTraits<mss::proc_type::NIMBUS, DRAM_GEN>
+class preDataInitTraits<mss::proc_type::NIMBUS, pre_data_init_fields::DRAM_GEN>
{
public:
using attr_type = fapi2::ATTR_EFF_DRAM_GEN_Type;
@@ -132,7 +132,7 @@ class preDataInitTraits<mss::proc_type::NIMBUS, DRAM_GEN>
/// @note NIMBUS, HYBRID specialization
///
template<>
-class preDataInitTraits<mss::proc_type::NIMBUS, HYBRID>
+class preDataInitTraits<mss::proc_type::NIMBUS, pre_data_init_fields::HYBRID>
{
public:
using attr_type = fapi2::ATTR_EFF_HYBRID_Type;
@@ -173,7 +173,7 @@ class preDataInitTraits<mss::proc_type::NIMBUS, HYBRID>
/// @note NIMBUS, HYBRID_MEDIA specialization
///
template<>
-class preDataInitTraits<mss::proc_type::NIMBUS, HYBRID_MEDIA>
+class preDataInitTraits<mss::proc_type::NIMBUS, pre_data_init_fields::HYBRID_MEDIA>
{
public:
using attr_type = fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE_Type;
@@ -214,7 +214,7 @@ class preDataInitTraits<mss::proc_type::NIMBUS, HYBRID_MEDIA>
/// @note NIMBUS, MRANKS specialization
///
template<>
-class preDataInitTraits<mss::proc_type::NIMBUS, MRANKS>
+class preDataInitTraits<mss::proc_type::NIMBUS, pre_data_init_fields::MRANKS>
{
public:
using attr_type = fapi2::ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_Type;
@@ -255,39 +255,35 @@ class preDataInitTraits<mss::proc_type::NIMBUS, MRANKS>
/// @note NIMBUS, DIMM_RANKS_CNFG specialization
///
template<>
-class preDataInitTraits<mss::proc_type::NIMBUS, DIMM_RANKS_CNFG>
+struct preDataInitTraits<mss::proc_type::NIMBUS, pre_data_init_fields::DIMM_RANKS_CNFG>
{
- public:
- using attr_type = fapi2::ATTR_EFF_DIMM_RANKS_CONFIGED_Type;
- static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_TargetType;
- static constexpr generic_ffdc_codes FFDC_CODE = SET_DIMM_RANKS_CNFG;
+ using attr_type = fapi2::ATTR_EFF_DIMM_RANKS_CONFIGED_Type;
+ static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DIMM_RANKS_CNFG;
- ///
- /// @brief attribute getter
- /// @param[in] i_target the MCS target
- /// @param[out] o_setting array to populate
- /// @return FAPI2_RC_SUCCESS iff okay
- ///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
- {
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_DIMM_RANKS_CONFIGED, i_target, o_setting) );
-
- fapi_try_exit:
- return fapi2::current_err;
- }
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the MCS target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return FAPI_ATTR_GET(fapi2::ATTR_EFF_DIMM_RANKS_CONFIGED, i_target, o_setting);
+ }
- ///
- /// @brief attribute setter
- /// @param[in] i_target the MCS target
- /// @param[in] i_setting array to set
- /// @return FAPI2_RC_SUCCESS iff okay
- ///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
- {
- return FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_RANKS_CONFIGED, i_target, i_setting);
- }
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the MCS target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_RANKS_CONFIGED, i_target, i_setting);
+ }
};
///
@@ -296,7 +292,7 @@ class preDataInitTraits<mss::proc_type::NIMBUS, DIMM_RANKS_CNFG>
/// @note AXONE, DIMM_TYPE_METADATA specialization
///
template<>
-struct attrEngineTraits<generic_metadata_fields, DIMM_TYPE_METADATA>
+struct attrEngineTraits<proc_type::NIMBUS, generic_metadata_fields, generic_metadata_fields::DIMM_TYPE_METADATA>
{
using attr_type = fapi2::ATTR_MEM_DIMM_TYPE_METADATA_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -377,7 +373,7 @@ class dimmPosTraits<mss::mc_type::NIMBUS>
/// @note generic_metadata_fields, DRAM_GEN_METADATA specialization
///
template<>
-struct attrEngineTraits<generic_metadata_fields, DRAM_GEN_METADATA>
+struct attrEngineTraits<proc_type::NIMBUS, generic_metadata_fields, generic_metadata_fields::DRAM_GEN_METADATA>
{
using attr_type = fapi2::ATTR_MEM_DRAM_GEN_METADATA_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -427,7 +423,7 @@ struct attrEngineTraits<generic_metadata_fields, DRAM_GEN_METADATA>
/// @note generic_metadata_fields, DIMM_POS_METADATA specialization
///
template<>
-struct attrEngineTraits<generic_metadata_fields, DIMM_POS_METADATA>
+struct attrEngineTraits<proc_type::NIMBUS, generic_metadata_fields, generic_metadata_fields::DIMM_POS_METADATA>
{
using attr_type = fapi2::ATTR_MEM_DIMM_POS_METADATA_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -472,17 +468,6 @@ struct attrEngineTraits<generic_metadata_fields, DIMM_POS_METADATA>
}
};
-///
-/// @brief Value traits for attr_eff_engine_fields
-/// @class attrEngineTraits
-/// @note attr_eff_engine_fields
-///
-template < >
-struct attrEnumTraits<generic_metadata_fields>
-{
- static constexpr size_t DISPATCHER = ATTR_METADATA_DISPATCHER;
-};
-
}// mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C
index 5a8f25ab3..75c378da8 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C
@@ -34,6 +34,8 @@
// *HWP Consumed by: FSP:HB
#include <fapi2.H>
+#include <lib/shared/nimbus_defaults.H>
+#include <lib/shared/mss_const.H>
#include <vpd_access.H>
#include <mss.H>
#include <algorithm>
@@ -65,7 +67,7 @@ namespace code
/// @return fapi2::FAPI2_RC_SUCCESS if no LRDIMM, otherwise a MSS_PLUG_RULE error code
/// @note This function will commit error logs representing the mixing failure
///
-fapi2::ReturnCode check_lrdimm( const std::vector<dimm::kind>& i_kinds )
+fapi2::ReturnCode check_lrdimm( const std::vector<dimm::kind<>>& i_kinds )
{
fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
@@ -100,7 +102,7 @@ fapi_try_exit:
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_xlate_config(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds)
+ const std::vector<dimm::kind<>>& i_kinds)
{
if (i_kinds.size() > 1)
{
@@ -149,7 +151,7 @@ fapi_try_exit:
/// @note The DIMM kind should be a DIMM on the MCA
///
fapi2::ReturnCode check_system_supported_dram_width(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const dimm::kind& i_kind,
+ const dimm::kind<>& i_kind,
const fapi2::buffer<uint8_t>& i_mrw_supported_list)
{
// Contains a mapping of the DRAM width to the bitmap value to be checked for support
@@ -194,7 +196,7 @@ fapi_try_exit:
/// This function will commit error logs if a DIMM has an unsupported DRAM width
///
fapi2::ReturnCode check_system_supported_dram_width(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds)
+ const std::vector<dimm::kind<>>& i_kinds)
{
fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
@@ -220,7 +222,7 @@ fapi_try_exit:
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_dram_width(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds)
+ const std::vector<dimm::kind<>>& i_kinds)
{
fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
@@ -249,7 +251,7 @@ fapi_try_exit:
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_hybrid(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds)
+ const std::vector<dimm::kind<>>& i_kinds)
{
// Make sure we don't get a stale error
fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
@@ -295,10 +297,11 @@ fapi_try_exit:
fapi2::ReturnCode dimm_slot_is_nv_capable(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
bool& o_is_capable)
{
- const auto l_pos = mss::pos(i_target);
-
+ uint8_t l_pos = 0;
fapi2::buffer<uint64_t> l_plug_rules_bitmap = 0;
+ FAPI_TRY( mss::mrw_nvdimm_slot_position(i_target, l_pos) );
+
FAPI_TRY( mss::mrw_nvdimm_plug_rules(l_plug_rules_bitmap) );
o_is_capable = l_plug_rules_bitmap.getBit(l_pos);
@@ -319,7 +322,7 @@ fapi_try_exit:
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_nvdimm(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds)
+ const std::vector<dimm::kind<>>& i_kinds)
{
fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
bool l_nvdimm_in_port = false;
@@ -370,7 +373,7 @@ fapi_try_exit:
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_stack_type(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds)
+ const std::vector<dimm::kind<>>& i_kinds)
{
fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
@@ -473,7 +476,7 @@ bool unsupported_rank_helper(const uint64_t i_dimm0_ranks,
/// @note This function will commit error logs representing the mixing failure
///
fapi2::ReturnCode dimm_type_mixing(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds)
+ const std::vector<dimm::kind<>>& i_kinds)
{
fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
@@ -609,7 +612,7 @@ fapi_try_exit:
/// @param[in] i_kinds a vector of DIMM kind structs
/// @return fapi2::ReturnCode
///
-fapi2::ReturnCode check_gen( const std::vector<dimm::kind>& i_kinds )
+fapi2::ReturnCode check_gen( const std::vector<dimm::kind<>>& i_kinds )
{
fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
@@ -641,7 +644,7 @@ fapi_try_exit:
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_rank_config(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds,
+ const std::vector<dimm::kind<>>& i_kinds,
const uint64_t i_ranks_override)
{
// We need to keep track of current_err ourselves as the FAPI_ASSERT_NOEXIT macro doesn't.
@@ -687,8 +690,8 @@ fapi2::ReturnCode check_rank_config(const fapi2::Target<TARGET_TYPE_MCA>& i_targ
// (really probably that's the only case it catches but <shhhhh>.)
// I don't think f/w supports std::count ... There aren't many DIMM on this port ...
uint64_t l_rank_count = 0;
- const dimm::kind* l_dimm0_kind = nullptr;
- const dimm::kind* l_dimm1_kind = nullptr;
+ const dimm::kind<>* l_dimm0_kind = nullptr;
+ const dimm::kind<>* l_dimm1_kind = nullptr;
for (const auto& k : i_kinds)
{
@@ -766,7 +769,7 @@ fapi_try_exit:
/// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code
///
fapi2::ReturnCode check_nvdimm_pairing(const fapi2::Target<fapi2::TARGET_TYPE_MCS> i_target,
- const std::vector<dimm::kind>& l_kinds)
+ const std::vector<dimm::kind<>>& l_kinds)
{
// 3 scenarios where the pairing rule would fail:
// (1). Odd number of NVDIMMs installed
@@ -866,7 +869,7 @@ fapi2::ReturnCode plug_rule::enforce_plug_rules(const fapi2::Target<fapi2::TARGE
// Enforce the NVDIMM pairing rule
{
- const auto l_dimm_kinds = mss::dimm::kind::vector(l_dimms);
+ const auto l_dimm_kinds = mss::dimm::kind<>::vector(l_dimms);
FAPI_TRY( plug_rule::check_nvdimm_pairing(i_target, l_dimm_kinds) );
}
@@ -895,7 +898,7 @@ fapi2::ReturnCode plug_rule::enforce_plug_rules(const fapi2::Target<fapi2::TARGE
// Safe, even though the VPD decoder can get us here before the rest of eff_config has completed.
// We'll only use the master rank information to enforce the rank config rules (which will have been
// decoded and are valid before VPD was asked for.)
- const auto l_dimm_kinds = mss::dimm::kind::vector(l_dimms);
+ const auto l_dimm_kinds = mss::dimm::kind<>::vector(l_dimms);
uint64_t l_ranks_override = 0;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H
index a730fa9a4..24da77869 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H
@@ -38,7 +38,7 @@
#include <fapi2.H>
#include <cstdint>
-#include <lib/dimm/kind.H>
+#include <lib/dimm/nimbus_kind.H>
namespace mss
{
@@ -106,7 +106,7 @@ fapi2::ReturnCode empty_slot_zero(const fapi2::Target<T>& i_target);
/// @return std::pair representing the type and the count.
/// @note the vector of kinds comes back sorted by DIMM type.
///
-std::pair<uint8_t, uint64_t> dimm_type_helper(std::vector<dimm::kind>& io_kinds);
+std::pair<uint8_t, uint64_t> dimm_type_helper(std::vector<dimm::kind<>>& io_kinds);
///
/// @brief Rank violation helper
@@ -142,7 +142,7 @@ inline void rank_violation(const fapi2::Target<T>& i_target, const uint8_t l_dim
/// @note This function will commit error logs representing the mixing failure
///
fapi2::ReturnCode dimm_type_mixing(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds);
+ const std::vector<dimm::kind<>>& i_kinds);
///
/// @brief Enforce rank configs
@@ -155,7 +155,7 @@ fapi2::ReturnCode dimm_type_mixing(const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_rank_config(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds,
+ const std::vector<dimm::kind<>>& i_kinds,
const uint64_t i_ranks_override);
///
@@ -167,7 +167,7 @@ fapi2::ReturnCode check_rank_config(const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
/// @note The DIMM kind should be a DIMM on the MCA
///
fapi2::ReturnCode check_system_supported_dram_width(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const dimm::kind& i_kind,
+ const dimm::kind<>& i_kind,
const fapi2::buffer<uint8_t>& i_mrw_supported_list);
///
@@ -179,7 +179,7 @@ fapi2::ReturnCode check_system_supported_dram_width(const fapi2::Target<fapi2::T
/// This function will commit error logs if a DIMM has an unsupported DRAM width
///
fapi2::ReturnCode check_system_supported_dram_width(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds);
+ const std::vector<dimm::kind<>>& i_kinds);
///
/// @brief Enforce DRAM width checks
@@ -190,7 +190,7 @@ fapi2::ReturnCode check_system_supported_dram_width(const fapi2::Target<fapi2::T
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_dram_width(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds);
+ const std::vector<dimm::kind<>>& i_kinds);
///
/// @brief Enforce DRAM stack type checks
@@ -201,7 +201,7 @@ fapi2::ReturnCode check_dram_width(const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_stack_type(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds);
+ const std::vector<dimm::kind<>>& i_kinds);
///
/// @brief Enforce hybrid DIMM checks
@@ -212,7 +212,7 @@ fapi2::ReturnCode check_stack_type(const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_hybrid(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds);
+ const std::vector<dimm::kind<>>& i_kinds);
///
/// @brief Enforces that NVDIMM are plugged in the proper location
@@ -223,7 +223,7 @@ fapi2::ReturnCode check_hybrid(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_ta
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_nvdimm(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds);
+ const std::vector<dimm::kind<>>& i_kinds);
///
/// @brief Enforce the NVDIMM pairing per MCS
@@ -232,7 +232,7 @@ fapi2::ReturnCode check_nvdimm(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_ta
/// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code
///
fapi2::ReturnCode check_nvdimm_pairing(const fapi2::Target<fapi2::TARGET_TYPE_MCS> i_target,
- const std::vector<dimm::kind>& l_kinds);
+ const std::vector<dimm::kind<>>& l_kinds);
// Adding in code based plug rules - as supporting code gets added, the following checks can be deleted
namespace code
@@ -244,7 +244,7 @@ namespace code
/// @return fapi2::FAPI2_RC_SUCCESS if no LRDIMM, otherwise a MSS_PLUG_RULE error code
/// @note This function will commit error logs representing the mixing failure
///
-fapi2::ReturnCode check_lrdimm( const std::vector<dimm::kind>& i_kinds );
+fapi2::ReturnCode check_lrdimm( const std::vector<dimm::kind<>>& i_kinds );
///
/// @brief Enforce equivalent rank and row configs
@@ -255,7 +255,7 @@ fapi2::ReturnCode check_lrdimm( const std::vector<dimm::kind>& i_kinds );
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_xlate_config(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds);
+ const std::vector<dimm::kind<>>& i_kinds);
} // code
diff --git a/src/import/generic/memory/lib/data_engine/pre_data_init.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/pre_data_init.H
index df19a86ef..14d25f63b 100644
--- a/src/import/generic/memory/lib/data_engine/pre_data_init.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/pre_data_init.H
@@ -1,7 +1,7 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/generic/memory/lib/data_engine/pre_data_init.H $ */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/eff_config/pre_data_init.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
@@ -41,11 +41,122 @@
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <generic/memory/lib/spd/spd_facade.H>
#include <generic/memory/lib/utils/find.H>
-#include <generic/memory/lib/data_engine/p9n/p9n_data_init_traits.H>
+#include <lib/eff_config/p9n_data_init_traits.H>
#include <generic/memory/lib/data_engine/data_engine_utils.H>
namespace mss
{
+// TK - Remove generalizations since this is dubbed Nimbus specific implementation
+
+///
+/// @class DataSetterTraits2D
+/// @brief Traits for setting eff_config data
+/// @tparam P proc_type
+/// @tparam X size of 1st array index
+/// @tparam Y size of 2nd array index
+///
+template < proc_type P, size_t X, size_t Y >
+struct DataSetterTraits2D;
+
+///
+/// @class DataSetterTraits - Nimbus, [PORT][DIMM] array specialization
+/// @brief Traits for setting eff_config data
+///
+template < >
+struct DataSetterTraits2D < proc_type::NIMBUS,
+ mcTypeTraits<mc_type::NIMBUS>::PORTS_PER_MCS,
+ mcTypeTraits<mc_type::NIMBUS>::DIMMS_PER_PORT
+ >
+{
+ static constexpr fapi2::TargetType TARGET = fapi2::TARGET_TYPE_MCA;
+};
+
+///
+/// @brief Helper function to update a 2D array output
+/// @tparam P proc_type
+/// @tparam X size of 1st array index
+/// @tparam Y size of 2nd array index
+/// @tparam T Input/output data type
+/// @tparam TT defaulted to DataSetterTraits2D<P, X, Y>
+/// @param[in] i_target the DIMM target
+/// @param[in] i_setting array to set
+/// @param[in] i_ffdc_code FFDC function code
+/// @param[out] o_data attribute data structure to set
+/// @warning This is Nimbus specific until MCA alias to MEM_PORT
+///
+template < proc_type P,
+ size_t X,
+ size_t Y,
+ typename T,
+ typename TT = DataSetterTraits2D<P, X, Y>
+ >
+fapi2::ReturnCode update_data(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const T i_setting,
+ const generic_ffdc_codes i_ffdc_code,
+ T (&o_data)[X][Y])
+{
+ // Currenlty only valid for a DIMM target, for Nimbus, traits enforces this at compile time
+ // Use case is currently for pre_eff_config which is supported in both Axone and Nimbus
+ const auto l_port_index = mss::index( find_target<TT::TARGET>(i_target) );
+ const auto l_dimm_index = mss::index(i_target);
+
+ FAPI_ASSERT( l_port_index < X,
+ fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
+ .set_INDEX(l_port_index)
+ .set_LIST_SIZE(X)
+ .set_FUNCTION(i_ffdc_code)
+ .set_TARGET(i_target),
+ "Port index (%d) was larger than max (%d) on %s",
+ l_port_index,
+ X,
+ mss::spd::c_str(i_target) );
+
+ FAPI_ASSERT( l_dimm_index < Y,
+ fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
+ .set_INDEX(l_dimm_index)
+ .set_LIST_SIZE(Y)
+ .set_FUNCTION(i_ffdc_code)
+ .set_TARGET(i_target),
+ "DIMM index (%d) was larger than max (%d) on %s",
+ l_dimm_index,
+ Y,
+ mss::spd::c_str(i_target) );
+
+ o_data[l_port_index][l_dimm_index] = i_setting;
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Sets attr data fields
+/// @tparam P proc_type
+/// @tparam TT data engine class traits (e.g. preDataInitTraits, etc.)
+/// @tparam T FAPI2 target type
+/// @tparam IT Input data type
+/// @param[in] i_target the FAPI target
+/// @param[in] i_setting value we want to set attr with
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+template< proc_type P,
+ typename TT,
+ fapi2::TargetType T,
+ typename IT >
+inline fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target,
+ const IT i_setting)
+{
+ const auto l_attr_target = mss::find_target<TT::TARGET_TYPE>(i_target);
+ typename TT::attr_type l_attr_list = {};
+ FAPI_TRY( TT::get_attr(l_attr_target, l_attr_list) );
+
+ FAPI_TRY( update_data<P>(i_target, i_setting, TT::FFDC_CODE, l_attr_list) );
+ FAPI_TRY( TT::set_attr(l_attr_target, l_attr_list) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
///
/// @brief Sets preliminary data fields
@@ -121,7 +232,7 @@ class pre_data_engine
FAPI_TRY(iv_spd_data.base_module(l_base_module_type));
FAPI_TRY(lookup_table_check(iv_dimm, BASE_MODULE_TYPE_MAP, SET_ATTR_DIMM_TYPE, l_base_module_type, l_dimm_type));
- FAPI_TRY( (set_field<P, DIMM_TYPE>(iv_dimm, l_dimm_type)) );
+ FAPI_TRY( (set_field<P, pre_data_init_fields::DIMM_TYPE>(iv_dimm, l_dimm_type)) );
fapi_try_exit:
return fapi2::current_err;
@@ -139,7 +250,7 @@ class pre_data_engine
FAPI_TRY(iv_spd_data.device_type(l_device_type));
FAPI_TRY(lookup_table_check(iv_dimm, DRAM_GEN_MAP, SET_ATTR_DRAM_GEN, l_device_type, l_dram_gen));
- FAPI_TRY( (set_field<P, DRAM_GEN>(iv_dimm, l_dram_gen)) );
+ FAPI_TRY( (set_field<P, pre_data_init_fields::DRAM_GEN>(iv_dimm, l_dram_gen)) );
fapi_try_exit:
return fapi2::current_err;
@@ -157,7 +268,7 @@ class pre_data_engine
FAPI_TRY(iv_spd_data.hybrid(l_spd_hybrid_type));
FAPI_TRY(lookup_table_check(iv_dimm, HYBRID_MAP, SET_ATTR_HYBRID, l_spd_hybrid_type, l_hybrid));
- FAPI_TRY( (set_field<P, HYBRID>(iv_dimm, l_hybrid)) );
+ FAPI_TRY( (set_field<P, pre_data_init_fields::HYBRID>(iv_dimm, l_hybrid)) );
fapi_try_exit:
return fapi2::current_err;
@@ -175,7 +286,7 @@ class pre_data_engine
FAPI_TRY(iv_spd_data.hybrid_media(l_spd_hybrid_media));
FAPI_TRY(lookup_table_check(iv_dimm, HYBRID_MAP, SET_ATTR_HYBRID, l_spd_hybrid_media, l_hybrid_media));
- FAPI_TRY( (set_field<P, HYBRID_MEDIA>(iv_dimm, l_hybrid_media)) );
+ FAPI_TRY( (set_field<P, pre_data_init_fields::HYBRID_MEDIA>(iv_dimm, l_hybrid_media)) );
fapi_try_exit:
return fapi2::current_err;
@@ -190,7 +301,7 @@ class pre_data_engine
uint8_t l_master_ranks = 0;
FAPI_TRY( get_master_ranks(l_master_ranks) );
- FAPI_TRY( (set_field<P, MRANKS>(iv_dimm, l_master_ranks)) );
+ FAPI_TRY( (set_field<P, pre_data_init_fields::MRANKS>(iv_dimm, l_master_ranks)) );
fapi_try_exit:
return fapi2::current_err;
@@ -213,7 +324,7 @@ class pre_data_engine
FAPI_TRY( l_ranks_configed.setBit(0, l_master_ranks),
"%s. Failed to setBit", spd::c_str(iv_dimm) );
- FAPI_TRY( (set_field<P, DIMM_RANKS_CNFG>(iv_dimm, uint8_t(l_ranks_configed))) );
+ FAPI_TRY( (set_field<P, pre_data_init_fields::DIMM_RANKS_CNFG>(iv_dimm, uint8_t(l_ranks_configed))) );
fapi_try_exit:
return fapi2::current_err;
@@ -277,12 +388,15 @@ inline fapi2::ReturnCode set_pre_init_attrs<mss::proc_type::NIMBUS>( const fapi2
FAPI_TRY(l_data_engine.set_hybrid_media(), "Failed to set Hybrid Media %s", mss::spd::c_str(i_target) );
// Number of master ranks needed for VPD decoding
- // and dimm_ranks_configured is a PRD attr...
FAPI_TRY(l_data_engine.set_master_ranks(), "Failed to set Master ranks %s", mss::spd::c_str(i_target) );
+
+ // and dimm_ranks_configured is a PRD attr...
FAPI_TRY(l_data_engine.set_dimm_ranks_configured(), "Failed to set DIMM ranks configured %s",
mss::spd::c_str(i_target) );
- FAPI_TRY( mss::attr_derived_engine<mss::generic_metadata_fields>::set(i_target) );
+ // Adding metadata c-str fields derived from attrs set above
+ FAPI_TRY( (mss::gen::attr_engine<proc_type::NIMBUS, mss::generic_metadata_fields>::set(i_target)),
+ "Failed attr_engine<proc_type::NIMBUS, mss::generic_metadata_fields>::set for %s", mss::spd::c_str(i_target) );
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.C
index ebc203f2e..ebf1650ea 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -31,173 +31,10 @@
#include <fapi2.H>
#include <mss.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <lib/eff_config/timing.H>
namespace mss
{
-enum temp_mode : uint8_t
-{
- NORMAL = 1,
- EXTENDED = 2,
-};
-
-// Proposed DDR4 Full spec update(79-4B)
-// Item No. 1716.78C
-// pg.46
-// Table 24 - tREFI and tRFC parameters (in ps)
-constexpr uint64_t TREFI_BASE = 7800000;
-
-// Proposed DDR4 3DS Addendum
-// Item No. 1727.58A
-// pg. 69 - 71
-// Table 42 - Refresh parameters by logical rank density
-static const std::vector<std::pair<uint8_t, uint64_t> > TRFC_DLR1 =
-{
- // { density in GBs, tRFC4(min) in picoseconds }
- {4, 90000},
- {8, 120000},
- {16, 185000},
-};
-
-// Proposed DDR4 3DS Addendum
-// Item No. 1727.58A
-// pg. 69 - 71
-// Table 42 - Refresh parameters by logical rank density
-static const std::vector<std::pair<uint8_t, uint64_t> > TRFC_DLR2 =
-{
- // { density in GBs, tRFC4(min) in picoseconds }
- {4, 55000},
- {8, 90000},
- {16, 120000},
-};
-
-// Proposed DDR4 3DS Addendum
-// Item No. 1727.58A
-// pg. 69 - 71
-// Table 42 - Refresh parameters by logical rank density
-static const std::vector<std::pair<uint8_t, uint64_t> > TRFC_DLR4 =
-{
- // { density in GBs, tRFC4(min) in picoseconds }
- {4, 40000},
- {8, 55000},
- {16, 90000},
-};
-
-///
-/// @brief Calculates refresh interval time
-/// @param[in] i_mode fine refresh rate mode
-/// @param[in] i_refresh_request_rate refresh rate
-/// @param[out] o_value timing val in ps
-/// @return fapi2::ReturnCode
-///
-fapi2::ReturnCode calc_trefi( const refresh_rate i_mode,
- const uint8_t i_refresh_request_rate,
- uint64_t& o_timing )
-{
- uint64_t l_refresh_request = 0;
- constexpr double TEN_PERCENT_FASTER = 0.90;
-
- switch(i_refresh_request_rate)
- {
- case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_SINGLE:
- l_refresh_request = TREFI_BASE;
- break;
-
- case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_DOUBLE:
- // We are truncating but there is no remainder with TREFI_BASE, so we are okay
- l_refresh_request = TREFI_BASE / 2;
- break;
-
- case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_SINGLE_10_PERCENT_FASTER:
- // We are truncating but there is no remainder with TREFI_BASE, so we are okay
- // 10% faster so 100% - 10% = 90%
- l_refresh_request = TREFI_BASE * TEN_PERCENT_FASTER;
- break;
-
- case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_DOUBLE_10_PERCENT_FASTER:
- // We are truncating but there is no remainder with TREFI_BASE, so we are okay
- // 10% faster so 100% - 10% = 90%
- l_refresh_request = (TREFI_BASE / 2) * TEN_PERCENT_FASTER;
- break;
-
- default:
- // Will catch incorrect MRW value set
- FAPI_ASSERT(false,
- fapi2::MSS_INVALID_REFRESH_RATE_REQUEST().set_REFRESH_RATE_REQUEST(i_refresh_request_rate),
- "Incorrect refresh request rate received: %d ", i_refresh_request_rate);
- break;
- }
-
- o_timing = (l_refresh_request / i_mode);
-
- FAPI_INF( "tREFI (ps): %d, refresh request (ps): %d, tREFI_base (ps): %d, REF%dX",
- o_timing, l_refresh_request, TREFI_BASE, i_mode );
-
- // FAPI_ASSERT doesn't set current_err as good
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-/// @brief Calculates Minimum Refresh Recovery Delay Time (different logical rank)
-/// @param[in] i_mode fine refresh rate mode
-/// @param[in] i_density SDRAM density
-/// @param[out] o_trfc_in_ps timing val in ps
-/// @return fapi2::FAPI2_RC_SUCCESS iff okay
-///
-fapi2::ReturnCode calc_trfc_dlr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint8_t i_refresh_mode,
- const uint8_t i_density,
- uint64_t& o_trfc_in_ps)
-{
- bool l_is_val_found = 0;
-
- // Selects appropriate tRFC based on fine refresh mode
- switch(i_refresh_mode)
- {
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_NORMAL:
- l_is_val_found = find_value_from_key(TRFC_DLR1, i_density, o_trfc_in_ps);
- break;
-
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_2X:
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_2X:
- l_is_val_found = find_value_from_key(TRFC_DLR2, i_density, o_trfc_in_ps);
- break;
-
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_4X:
- case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_4X:
- l_is_val_found = find_value_from_key(TRFC_DLR4, i_density, o_trfc_in_ps);
- break;
-
- default:
- // Fine Refresh Mode will be a platform attribute set by the MRW,
- // which they "shouldn't" mess up as long as use "attribute" enums.
- // if openpower messes this up we can at least catch it
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_FINE_REFRESH()
- .set_REFRESH_MODE(i_refresh_mode),
- "Incorrect Fine Refresh Mode received: %d ",
- i_refresh_mode);
- break;
- }// switch
-
- FAPI_ASSERT( l_is_val_found,
- fapi2::MSS_FAILED_TO_FIND_TRFC()
- .set_SDRAM_DENSITY(i_density)
- .set_REFRESH_MODE(i_refresh_mode)
- .set_DIMM_TARGET(i_target),
- "%s: Unable to find tRFC (ps) from map with SDRAM density key %d with %d refresh mode",
- mss::c_str(i_target),
- i_density,
- i_refresh_mode);
-
- // Again, FAPI_ASSERT doesn't set current_err to good, only to bad
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
}// mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H
index 8b8215b96..e09fa1a17 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H
@@ -38,106 +38,15 @@
#include <cstdint>
#include <fapi2.H>
#include <lib/mss_attribute_accessors.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/dimm/mss_timing.H>
#include <lib/utils/mss_nimbus_conversions.H>
namespace mss
{
///
-/// @brief Enums for ffdc error callout so we know which function had the error
-///
-enum functions
-{
- TRAS = 0,
- TFAW_HALF_KB_PAGE_HELPER = 1,
- TFAW_ONE_KB_PAGE_HELPER = 2,
- TFAW_TW_KB_PAGE_HELPER = 3,
- TFAW_SLR_X4_HELPER = 4,
- TFAW_SLR_X8_HELPER = 5,
- TRRD_S_SLR = 6,
- TRRD_L_SLR = 7,
- TRRD_L_HALF_AND_1KB_PAGE_HELPER = 8,
- TRRD_S_HALF_AND_1KB_PAGE_HELPER = 9,
- TRRD_S_2KB_PAGE_HELPER = 10,
- TDLLK = 11,
-};
-
-enum refresh_rate : uint8_t
-{
- REF1X = 1, ///< Refresh rate 1X
- REF2X = 2, ///< Refresh rate 2X
- REF4X = 4, ///< Refresh rate 4X
-};
-
-namespace spd
-{
-
-///
-/// @brief Returns clock cycles form picoseconds based on speed bin
-/// Uses SPD rounding algorithm for DDR4
-/// @tparam T the target type from which to get the mt/s
-/// @tparam OT the output type, derrived from the parameters
-/// @param[in] i_target target for the frequency attribute
-/// @param[in] timing_in_ps timing parameter in ps
-/// @return the clock cycles of timing parameter (provided in ps)
-/// @note Uses DDR4 SPD Contents Rounding Algorithm
-/// @note Item 2220.46
-///
-template<fapi2::TargetType T, typename OT>
-inline OT ps_to_nck( const fapi2::Target<T>& i_target, const OT& i_timing_in_ps)
-{
- uint64_t l_freq = 0;
- OT l_tck_in_ps = 0;
- OT l_temp_nck = 0;
-
- FAPI_TRY( mss::freq( find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq) );
-
- // No time if MT/s is 0 (well, infinite really but shut up)
- if (l_freq == 0)
- {
- return 0;
- }
-
- FAPI_TRY( freq_to_ps(l_freq, l_tck_in_ps),
- "Failed freq() accessor" );
- FAPI_TRY( calc_nck(i_timing_in_ps, l_tck_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_temp_nck),
- "Failed calc_nck()" );
-
- return l_temp_nck;
-
-fapi_try_exit:
- // We simply can't work if we can't get the frequency or
- // if we get an unsupported value that can't be converted to a valid tCK (clock period)
- // ...so this should be ok
- FAPI_ERR("Can't get MSS_FREQ, obtained an invalid MSS_FREQ (%d), or overflow occurred - stopping", l_freq);
- fapi2::Assert(false);
-
- // Keeps compiler happy
- return 0;
-}
-
-///
-/// @brief Returns clock cycles from nanoseconds
-/// Uses SPD rounding algorithm for DDR4
-/// @tparam T the target type from which to get the mt/s
-/// @tparam OT the output type, derrived from the parameters
-/// @param[in] timing_in_ps timing parameter in ps
-/// @param[out] o_value_nck the end calculation in nck
-/// @return the clock cycles of timing parameter (provided in ps)F
-/// @note Uses DDR4 SPD Contents Rounding Algorithm
-/// @note Item 2220.46
-///
-template<fapi2::TargetType T, typename OT>
-inline OT ns_to_nck( const fapi2::Target<T>& i_target, const OT& i_timing_in_ns)
-{
- return ps_to_nck(i_target, i_timing_in_ns * CONVERT_PS_IN_A_NS);
-}
-
-}// spd
-
-///
/// @brief Returns application clock period (tCK) based on dimm transfer rate
/// @tparam T the fapi2 target
/// @tparam OT output type
@@ -159,30 +68,6 @@ fapi_try_exit:
}
///
-/// @brief Calculates refresh interval time
-/// @param[in] i_mode fine refresh rate mode
-/// @param[in] i_temp_refresh_range temperature refresh range
-/// @param[out] o_value timing val in ps
-/// @return fapi2::ReturnCode
-///
-fapi2::ReturnCode calc_trefi( const refresh_rate i_mode,
- const uint8_t i_temp_refresh_range,
- uint64_t& o_timing );
-
-///
-/// @brief Calculates Minimum Refresh Recovery Delay Time (different logical rank)
-/// @param[in] i_target a target for attributes
-/// @param[in] i_mode fine refresh rate mode
-/// @param[in] i_density SDRAM density
-/// @param[out] o_trfc_in_ps timing val in ps
-/// @return fapi2::FAPI2_RC_SUCCESS iff okay
-///
-fapi2::ReturnCode calc_trfc_dlr( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint8_t i_refresh_mode,
- const uint8_t i_density,
- uint64_t& o_trfc_in_ps );
-
-///
/// @brief DLL locking time *in clocks*
/// @tparam T the fapi2::TargetType of i_target
/// @tparam OT the type of the output location
@@ -582,602 +467,6 @@ fapi_try_exit:
}
///
-/// @brief tRTP *in ps*
-/// @return constexpr value of RTP = 7500 ps
-///
-constexpr uint64_t trtp()
-{
- // Per JEDEC spec, defaults to 7500 ps for all frequencies.
- // (technically max of 7.5 ns or 4 nclk, which is always 7.5ns for DDR4)
- return 7500;
-}
-
-///
-/// @brief Return the minimum allowable tRAS in picoseconds
-/// @param[in] i_target the fapi2 target
-/// @return value in picoseconds
-///
-inline uint64_t tras(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target)
-{
- uint64_t l_freq = 0;
- uint64_t l_tras = 0;
-
- // Frequency is used to determine tRAS
- FAPI_TRY( freq(mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq) );
-
- switch(l_freq)
- {
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- l_tras = 34000;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- l_tras = 33000;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- l_tras = 32000;
- break;
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_FREQ_PASSED_IN()
- .set_FREQ(l_freq)
- .set_FUNCTION(TRAS)
- .set_DIMM_TARGET(i_target),
- "%s Invalid frequency %lu",
- mss::c_str(i_target),
- l_freq);
- }
-
- return l_tras;
-
-fapi_try_exit:
-
- // We simply can't work if we can't get the frequency or
- // if we get an unsupported value that can't be converted to a valid tCK (clock period)
- // ...so this should be ok
- FAPI_ERR("Can't get MSS_FREQ or obtained an invalid MSS_FREQ (%d) - stopping", l_freq);
- fapi2::Assert(false);
-
- // Keeps compiler happy
- return 0;
-}
-
-///
-/// @brief Helper function to find tFAW based speed (MT/s) for 1/2 KB page
-/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_output timing in clocks (nck)
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note this is only for non-3DS DIMM
-///
-template< fapi2::TargetType T >
-static fapi2::ReturnCode tfaw_half_kb_page_helper(const fapi2::Target<T>& i_target,
- uint64_t& o_output)
-{
- // Values derived from DDR4 Spec (79-4A)
- // 13.3 Timing Parameters by Speed Grade
- // Table 132. Pg 240
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- uint64_t l_freq = 0;
- FAPI_TRY( freq(find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq),
- "Failed to invoke freq accessor" );
-
- // It could have been more "efficient" to hand-calculate the answer and
- // use compile time constants to return the answer. To avoid magic
- // numbers and to align (more closely) with the DDR4 JEDEC spec,
- // we let the std library do the work for us for maintainability.
- // Could have used compile-time constants to denote the numbers below
- // but they are "random" and vary.
- switch(l_freq)
- {
- // static_cast is needed for template deduction of std::max API
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- o_output = std::max( 16, spd::ns_to_nck(i_target, 17) );
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- o_output = std::max( 16, spd::ns_to_nck(i_target, 15) );
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- o_output = std::max( 16, spd::ns_to_nck(i_target, 13) );
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- o_output = std::max( 16, spd::ns_to_nck(i_target, 12) );
- break;
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_FREQ_PASSED_IN()
- .set_FREQ(l_freq)
- .set_FUNCTION(TFAW_HALF_KB_PAGE_HELPER)
- .set_DIMM_TARGET(i_target),
- "%s Invalid frequency %lu",
- mss::c_str(i_target),
- l_freq);
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Helper function to find tFAW based speed (MT/s) for 1KB page
-/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_output timing in clocks (nck)
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note this is only for non-3DS DIMM
-///
-template< fapi2::TargetType T >
-static fapi2::ReturnCode tfaw_1kb_page_helper(const fapi2::Target<T>& i_target,
- uint64_t& o_output)
-{
- // Values derived from DDR4 Spec (79-4A)
- // 13.3 Timing Parameters by Speed Grade
- // Table 132. Pg 240
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- uint64_t l_freq = 0;
- FAPI_TRY( freq(find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq),
- "Failed to invoke freq accessor" );
-
- // It could have been more "efficient" to hand-calculate the answer and
- // use compile time constants to return the answer. To avoid magic
- // numbers and to align (more closely) with the DDR4 JEDEC spec,
- // we let the std library do the work for us for maintainability (and ease of debug?).
- // Could have used compile-time constants to denote the numbers below
- // but they are "random" and vary.
- switch(l_freq)
- {
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- o_output = std::max( 20, spd::ns_to_nck(i_target, 23) );
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- o_output = std::max( 20, spd::ns_to_nck(i_target, 21) );
- break;
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_FREQ_PASSED_IN()
- .set_FREQ(l_freq)
- .set_FUNCTION(TFAW_ONE_KB_PAGE_HELPER)
- .set_DIMM_TARGET(i_target),
- "%s Invalid frequency %lu",
- mss::c_str(i_target),
- l_freq);
- break;
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Helper function to find tFAW based speed (MT/s) for 2KB page
-/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_output timing in clocks (nck)
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note this is only for non-3DS DIMM
-///
-template< fapi2::TargetType T >
-static fapi2::ReturnCode tfaw_2kb_page_helper(const fapi2::Target<T>& i_target,
- uint64_t& o_output)
-{
-
- // Values derived from DDR4 Spec (79-4A)
- // 13.3 Timing Parameters by Speed Grade
- // Table 132. Pg 240
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- // It could have been more "efficient" to hand-calculate the answer and
- // use compile time constants to return the answer. To avoid magic
- // numbers and to align (more closely) with the DDR4 JEDEC spec,
- // we let the std library do the work for us for maintainability.
- // Could have used compile-time constants to denote the numbers below
- // but they are "random" and vary.
- uint64_t l_freq = 0;
- FAPI_TRY( freq(find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq),
- "Failed to invoke freq accessor" );
-
- switch(l_freq)
- {
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- o_output = std::max( 28, spd::ns_to_nck(i_target, 30) );
- break;
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_FREQ_PASSED_IN()
- .set_FREQ(l_freq)
- .set_FUNCTION(TFAW_TW_KB_PAGE_HELPER)
- .set_DIMM_TARGET(i_target),
- "%s Invalid frequency %lu",
- mss::c_str(i_target),
- l_freq);
- break;
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Return the minimum allowable tFAW in nck
-/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
-/// @param[in] i_target the fapi2 target
-/// @param[in] i_dram_width the page size
-/// @param[out] o_tFAW timing in clocks (nck)
-/// @return FAPI2_RC_SUCCESS iff okay
-//
-template< fapi2::TargetType T >
-fapi2::ReturnCode tfaw( const fapi2::Target<T>& i_target,
- const uint8_t i_dram_width,
- uint64_t& o_tFAW )
-{
- switch(i_dram_width)
- {
- case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4:
- FAPI_TRY( tfaw_half_kb_page_helper(i_target, o_tFAW) );
- break;
-
- case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8:
- FAPI_TRY( tfaw_1kb_page_helper(i_target, o_tFAW) );
- break;
-
- case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X16:
- FAPI_TRY( tfaw_2kb_page_helper(i_target, o_tFAW) );
- break;
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_DRAM_WIDTH()
- .set_DRAM_WIDTH(i_dram_width)
- .set_DIMM_TARGET(i_target),
- "Invalid DRAM width with %d for target %s",
- i_dram_width,
- mss::c_str(i_target));
- break;
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief tFAW_dlr *in nck*
-/// @return 16nck
-/// @note From DDR4 3DS Spec
-/// 12.2 Timing Parameters by Speed Grade
-///
-constexpr uint64_t tfaw_dlr()
-{
- return 16;
-}
-
-///
-/// @brief tRRD_dlr *in nck*
-/// @return 4nck
-/// @note From DDR4 3DS Spec
-/// 12.2 Timing Parameters by Speed Grade
-///
-constexpr uint64_t trrd_dlr()
-{
- return 4;
-}
-
-///
-/// @brief Helper function to find tRRD_L based speed (MT/s) for 1KB page
-/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_output timing in clocks (nck)
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note this is only for non-3DS DIMM
-///
-template< fapi2::TargetType T >
-static fapi2::ReturnCode trrd_l_half_and_1kb_page_helper(const fapi2::Target<T>& i_target,
- uint64_t& o_output)
-{
- // Values derived from DDR4 Spec (79-4A)
- // 13.3 Timing Parameters by Speed Grade
- // Table 132. Pg 240
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- uint64_t l_freq = 0;
- FAPI_TRY( freq(find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq),
- "Failed to invoke freq accessor" );
-
- // It could have been more "efficient" to hand-calculate the answer and
- // use compile time constants to return the answer. To avoid magic
- // numbers and to align (more closely) with the DDR4 JEDEC spec,
- // we let the std library do the work for us for maintainability (and ease of debug?).
- // Could have used compile-time constants to denote the numbers below
- // but they are "random" and vary.
- switch(l_freq)
- {
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- // From the spec: Max(4nCK,5.3ns)
- o_output = std::max( 4, spd::ps_to_nck(i_target, 5300) );
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- // Max(4nCK,4.9ns)
- o_output = std::max( 4, spd::ps_to_nck(i_target, 4900) );
- break;
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_FREQ_PASSED_IN()
- .set_FREQ(l_freq)
- .set_FUNCTION(TRRD_L_HALF_AND_1KB_PAGE_HELPER)
- .set_DIMM_TARGET(i_target),
- "%s Invalid frequency %lu",
- mss::c_str(i_target),
- l_freq);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Helper function to find tRRD_L based speed (MT/s) for 2KB page
-/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_output timing in clocks (nck)
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note this is only for non-3DS DIMM
-///
-template< fapi2::TargetType T >
-static fapi2::ReturnCode trrd_l_2kb_page_helper(const fapi2::Target<T>& i_target,
- uint64_t& o_output)
-{
-
- // Values derived from DDR4 Spec (79-4A)
- // 13.3 Timing Parameters by Speed Grade
- // Table 132. Pg 240
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- uint64_t l_freq = 0;
- FAPI_TRY( freq(find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq),
- "Failed to invoke freq accessor" );
-
- // It could have been more "efficient" to hand-calculate the answer and
- // use compile time constants to return the answer. To avoid magic
- // numbers and to align (more closely) with the DDR4 JEDEC spec,
- // we let the std library do the work for us for maintainability (and ease of debug?).
- // Could have used compile-time constants to denote the numbers below
- // but they are "random" and vary.
- switch(l_freq)
- {
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- o_output = std::max( 4, spd::ps_to_nck(i_target, 6400) );
- break;
-
- default:
- FAPI_TRY(fapi2::FAPI2_RC_INVALID_PARAMETER, "%s Invalid frequency %lu", mss::c_str(i_target), l_freq);
- break;
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Return the minimum allowable tRRD_L in nck
-/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
-/// @param[in] i_target the fapi2 target
-/// @param[in] i_dram_width the page size
-/// @param[out] o_output timing in clocks (nck)
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note this is only for non-3DS DIMM
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode trrd_l( const fapi2::Target<T>& i_target,
- const uint8_t i_dram_width,
- uint64_t& o_tRRD_L )
-{
- switch(i_dram_width)
- {
- case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4:
- case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8:
- FAPI_TRY( trrd_l_half_and_1kb_page_helper(i_target, o_tRRD_L), "Error calculating trrd l for half and 1kb page" );
- break;
-
- case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X16:
- FAPI_TRY( trrd_l_2kb_page_helper(i_target, o_tRRD_L) );
- break;
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_PAGE_SIZE()
- .set_DRAM_WIDTH(i_dram_width)
- .set_DIMM_TARGET(i_target),
- "%s Recieved an invalid page size: %lu",
- mss::c_str(i_target),
- i_dram_width);
- break;
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Helper function to find tRRD_S based speed (MT/s) for 1KB page
-/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_output timing in clocks (nck)
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note this is only for non-3DS DIMM
-///
-template< fapi2::TargetType T >
-static fapi2::ReturnCode trrd_s_half_and_1kb_page_helper(const fapi2::Target<T>& i_target,
- uint64_t& o_output)
-{
- // Values derived from DDR4 Spec (79-4A)
- // 13.3 Timing Parameters by Speed Grade
- // Table 132. Pg 240
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- uint64_t l_freq = 0;
- FAPI_TRY( freq(find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq),
- "Failed to invoke freq accessor" );
-
- // It could have been more "efficient" to hand-calculate the answer and
- // use compile time constants to return the answer. To avoid magic
- // numbers and to align (more closely) with the DDR4 JEDEC spec,
- // we let the std library do the work for us for maintainability (and ease of debug?).
- // Could have used compile-time constants to denote the numbers below
- // but they are "random" and vary.
- switch(l_freq)
- {
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- o_output = std::max( 4, spd::ps_to_nck(i_target, 4200) );
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- o_output = std::max( 4, spd::ps_to_nck(i_target, 3700) );
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- o_output = std::max( 4, spd::ps_to_nck(i_target, 3300) );
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- o_output = std::max( 4, spd::ps_to_nck(i_target, 3000) );
- break;
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_FREQ_PASSED_IN()
- .set_FREQ(l_freq)
- .set_FUNCTION(TRRD_S_HALF_AND_1KB_PAGE_HELPER)
- .set_DIMM_TARGET(i_target),
- "%s Invalid frequency %lu",
- mss::c_str(i_target),
- l_freq);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Helper function to find tRRD_S based speed (MT/s) for 2KB page
-/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
-/// @param[in] i_target the fapi2 target
-/// @param[out] o_output timing in clocks (nck)
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note this is only for non-3DS DIMM
-///
-template< fapi2::TargetType T >
-static fapi2::ReturnCode trrd_s_2kb_page_helper(const fapi2::Target<T>& i_target,
- uint64_t& o_output)
-{
- // Values derived from DDR4 Spec (79-4A)
- // 13.3 Timing Parameters by Speed Grade
- // Table 132. Pg 240
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- uint64_t l_freq = 0;
- FAPI_TRY( freq(find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq),
- "Failed to invoke freq accessor" );
-
- // It could have been more "efficient" to hand-calculate the answer and
- // use compile time constants to return the answer. To avoid magic
- // numbers and to align (more closely) with the DDR4 JEDEC spec,
- // we let the std library do the work for us for maintainability (and ease of debug?).
- // Could have used compile-time constants to denote the numbers below
- // but they are "random" and vary.
- switch(l_freq)
- {
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- o_output = std::max( 4, spd::ps_to_nck(i_target, 5300) );
- break;
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_FREQ_PASSED_IN()
- .set_FREQ(l_freq)
- .set_FUNCTION(TRRD_S_2KB_PAGE_HELPER)
- .set_DIMM_TARGET(i_target),
- "%s Invalid frequency %lu",
- mss::c_str(i_target),
- l_freq);
- break;
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Return the minimum allowable tRRD_S in nck
-/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
-/// @param[in] i_target the fapi2 target
-/// @param[in] i_dram_width the page size
-/// @param[out] o_tRRD_S timing in clocks (nck)
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note this is only for non-3DS DIMM
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode trrd_s( const fapi2::Target<T>& i_target,
- const uint8_t i_dram_width,
- uint64_t& o_tRRD_S )
-{
- switch(i_dram_width)
- {
- case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4:
- case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8:
- FAPI_TRY( trrd_s_half_and_1kb_page_helper(i_target, o_tRRD_S), "Error calculating trrd_s for half and 1kb page" );
- break;
-
- case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X16:
- FAPI_TRY( trrd_s_2kb_page_helper(i_target, o_tRRD_S) );
- break;
-
- default:
- FAPI_ASSERT( false,
- fapi2::MSS_INVALID_PAGE_SIZE()
- .set_DRAM_WIDTH(i_dram_width)
- .set_DIMM_TARGET(i_target),
- "%s Recieved an invalid page size: %lu",
- mss::c_str(i_target),
- i_dram_width);
- break;
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief VREF DQ Enter time *in clocks*
/// @tparam T the fapi2::TargetType of i_target
/// @param[in] i_target a target for attributes
@@ -1215,25 +504,5 @@ constexpr uint64_t tccd_s()
return 4;
}
-namespace lrdimm
-{
-
-///
-/// @brief Return the VREF to VREF change time long
-/// @tparam fapi2::TargetType T - type of the target on which to operate
-/// @param[in] i_target the fapi2 target
-/// @return value in clocks
-/// @note VREF time change long is used for changing by more than one VREF tick
-///
-template< fapi2::TargetType T >
-inline uint64_t vref_time_long(const fapi2::Target<T>& i_target)
-{
- // Taken from the LRDIMM spec
- constexpr uint64_t VREF_TIME_LONG_NS = 500;
- return mss::spd::ns_to_nck(i_target, VREF_TIME_LONG_NS);
-}
-
-} // ns lrdimm
-
} // mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C b/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C
index de7b6003b..224dfc050 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C
@@ -38,12 +38,12 @@
#include <p9_mc_scom_addresses_fld.H>
#include <p9_perv_scom_addresses.H>
#include <p9_perv_scom_addresses_fld.H>
-#include <generic/memory/lib/utils/find_magic.H>
+#include <lib/utils/find_magic.H>
#include <generic/memory/lib/utils/scom.H>
#include <lib/fir/fir.H>
#include <lib/fir/check.H>
#include <generic/memory/lib/utils/assert_noexit.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/fir/memdiags_fir.C b/src/import/chips/p9/procedures/hwp/memory/lib/fir/memdiags_fir.C
deleted file mode 100644
index f4ab6727c..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/fir/memdiags_fir.C
+++ /dev/null
@@ -1,175 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/fir/memdiags_fir.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file memdiags_fir.C
-/// @brief Subroutines for memdiags/prd FIR
-///
-// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP HWP Backup: Marc Gollub <gollub@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#include <lib/shared/nimbus_defaults.H>
-#include <fapi2.H>
-#include <p9_mc_scom_addresses.H>
-#include <p9_mc_scom_addresses_fld.H>
-
-#include <generic/memory/lib/utils/scom.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/fir/fir.H>
-#include <lib/fir/memdiags_fir.H>
-#include <lib/mc/port.H>
-#include <lib/workarounds/mcbist_workarounds.H>
-
-using fapi2::TARGET_TYPE_MCBIST;
-using fapi2::TARGET_TYPE_MCA;
-
-namespace mss
-{
-
-namespace unmask
-{
-
-///
-/// @brief Unmask and setup actions for memdiags related FIR
-/// @param[in] i_target the fapi2::Target MCBIST
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
-///
-template<>
-fapi2::ReturnCode after_memdiags( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
-{
- fapi2::ReturnCode l_rc;
- fapi2::buffer<uint64_t> dsm0_buffer;
- fapi2::buffer<uint64_t> l_mnfg_buffer;
- uint64_t rd_tag_delay = 0;
- uint64_t wr_done_delay = 0;
- fapi2::buffer<uint64_t> l_aue_buffer;
- fapi2::ATTR_CHIP_EC_FEATURE_HW414700_Type l_checkstop_flag;
- constexpr uint64_t MNFG_THRESHOLDS_ATTR = 63;
-
- // Broadcast mode workaround for UEs causing out of sync
- FAPI_TRY(mss::workarounds::mcbist::broadcast_out_of_sync(i_target, mss::ON));
-
- for (const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target))
- {
- fir::reg<MCA_FIR> l_ecc64_fir_reg(p, l_rc);
- FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCA_FIR);
-
- fir::reg<MCA_MBACALFIRQ> l_cal_fir_reg(p, l_rc);
- FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCA_MBACALFIRQ);
-
- // Read out the wr_done and rd_tag delays and find min
- // and set the RCD Protect Time to this value
- FAPI_TRY (mss::read_dsm0q_register(p, dsm0_buffer) );
- mss::get_wrdone_delay(dsm0_buffer, wr_done_delay);
- mss::get_rdtag_delay(dsm0_buffer, rd_tag_delay);
- const auto rcd_protect_time = std::min(wr_done_delay, rd_tag_delay);
- FAPI_TRY (mss::change_rcd_protect_time(p, rcd_protect_time) );
-
- l_ecc64_fir_reg.checkstop<MCA_FIR_MAINLINE_AUE>()
- .recoverable_error<MCA_FIR_MAINLINE_UE>()
- .checkstop<MCA_FIR_MAINLINE_IAUE>()
- .recoverable_error<MCA_FIR_MAINLINE_IUE>();
-
- l_cal_fir_reg.recoverable_error<MCA_MBACALFIRQ_PORT_FAIL>();
-
- // If ATTR_CHIP_EC_FEATURE_HW414700 is enabled set checkstops
- auto l_chip_target = mss::find_target<fapi2::TARGET_TYPE_PROC_CHIP>(i_target);
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_HW414700, l_chip_target, l_checkstop_flag) );
-
- // If the system is running DD2 chips override some recoverable firs with checkstop
- // Due to a known hardware defect with DD2 certain errors are not handled properly
- // As a result, these firs are marked as checkstop for DD2 to avoid any mishandling
- if (l_checkstop_flag)
- {
- l_ecc64_fir_reg.checkstop<MCA_FIR_MAINLINE_UE>()
- .checkstop<MCA_FIR_MAINLINE_RCD>();
- l_cal_fir_reg.checkstop<MCA_MBACALFIRQ_PORT_FAIL>();
- }
-
- // If MNFG FLAG Threshhold is enabled skip IUE unflagging
- FAPI_TRY ( mss::mnfg_flags(l_mnfg_buffer) );
-
- if ( !(l_mnfg_buffer.getBit<MNFG_THRESHOLDS_ATTR>()) )
- {
- l_ecc64_fir_reg.recoverable_error<MCA_FIR_MAINTENANCE_IUE>();
- }
-
- FAPI_TRY(l_ecc64_fir_reg.write(), "unable to write fir::reg %d", MCA_FIR);
- FAPI_TRY(l_cal_fir_reg.write(), "unable to write fir::reg %d", MCA_MBACALFIRQ);
-
- // Change Maint AUE and IAUE to checkstop without unmasking
- // Normal setup modifies masked bits in addition to setting checkstop
- // This causes issues if error has occured, manually scoming to avoid this
- FAPI_TRY( mss::getScom(p, MCA_ACTION1, l_aue_buffer) );
- l_aue_buffer.clearBit<MCA_FIR_MAINTENANCE_AUE>();
- l_aue_buffer.clearBit<MCA_FIR_MAINTENANCE_IAUE>();
- FAPI_TRY( mss::putScom(p, MCA_ACTION1, l_aue_buffer) );
-
- // Note: We also want to include the following setup RCD recovery and port fail
- FAPI_TRY( mss::change_port_fail_disable(p, mss::LOW) );
- FAPI_TRY( mss::change_rcd_recovery_disable(p, mss::LOW) );
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Unmask and setup actions for scrub related FIR
-/// @param[in] i_target the fapi2::Target MCBIST
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
-///
-template<>
-fapi2::ReturnCode after_background_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
-{
- for (const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target))
- {
- fapi2::ReturnCode l_rc;
- fir::reg<MCA_FIR> l_ecc64_fir_reg(p, l_rc);
- FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCA_FIR);
-
- l_ecc64_fir_reg.recoverable_error<MCA_FIR_MAINLINE_MPE_RANK_0_TO_7,
- MCA_FIR_MAINLINE_MPE_RANK_0_TO_7_LEN>()
- .recoverable_error<MCA_FIR_MAINLINE_NCE>()
- .recoverable_error<MCA_FIR_MAINLINE_TCE>()
- .recoverable_error<MCA_FIR_MAINLINE_IMPE>()
- .recoverable_error<MCA_FIR_MAINTENANCE_IMPE>();
-
- FAPI_TRY(l_ecc64_fir_reg.write(), "unable to write fir::reg %d", MCA_FIR);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-}
-}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.C b/src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.C
index 3d28935f8..744e7412f 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.C
@@ -37,9 +37,11 @@
#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>
-#include <generic/memory/lib/utils/find_magic.H>
+#include <lib/utils/find_magic.H>
#include <generic/memory/lib/utils/scom.H>
+#include <lib/utils/nimbus_find.H>
#include <lib/fir/fir.H>
+#include <lib/mc/port.H>
#include <lib/fir/unmask.H>
#include <lib/workarounds/mcbist_workarounds.H>
@@ -80,8 +82,6 @@ fapi2::ReturnCode after_draminit_mc<mss::mc_type::NIMBUS>( const fapi2::Target<T
// Broadcast mode workaround for UEs causing out of sync
FAPI_TRY(mss::workarounds::mcbist::broadcast_out_of_sync(i_target, mss::OFF));
- FAPI_TRY(mss::workarounds::mcbist::wat_debug_attention(i_target));
-
for (const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target))
{
fir::reg<MCA_FIR> l_mca_fir_reg(p, l_rc);
@@ -252,5 +252,125 @@ fapi_try_exit:
}
+
+///
+/// @brief Unmask and setup actions for memdiags related FIR
+/// @param[in] i_target the fapi2::Target MCBIST
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode after_memdiags<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target )
+{
+ fapi2::ReturnCode l_rc1, l_rc2;
+ fapi2::buffer<uint64_t> dsm0_buffer;
+ fapi2::buffer<uint64_t> l_mnfg_buffer;
+ uint64_t rd_tag_delay = 0;
+ uint64_t wr_done_delay = 0;
+ fapi2::buffer<uint64_t> l_aue_buffer;
+ fapi2::ATTR_CHIP_EC_FEATURE_HW414700_Type l_checkstop_flag;
+ constexpr uint64_t MNFG_THRESHOLDS_ATTR = 63;
+
+ // Broadcast mode workaround for UEs causing out of sync
+ FAPI_TRY(mss::workarounds::mcbist::broadcast_out_of_sync(i_target, mss::ON));
+
+ for (const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target))
+ {
+ fir::reg<MCA_FIR> l_ecc64_fir_reg(p, l_rc1);
+ fir::reg<MCA_MBACALFIRQ> l_cal_fir_reg(p, l_rc2);
+ uint64_t rcd_protect_time = 0;
+ const auto l_chip_target = mss::find_target<fapi2::TARGET_TYPE_PROC_CHIP>(i_target);
+
+ FAPI_TRY(l_rc1, "unable to create fir::reg for %d", MCA_FIR);
+ FAPI_TRY(l_rc2, "unable to create fir::reg for %d", MCA_MBACALFIRQ);
+
+ // Read out the wr_done and rd_tag delays and find min
+ // and set the RCD Protect Time to this value
+ FAPI_TRY (mss::read_dsm0q_register(p, dsm0_buffer) );
+ mss::get_wrdone_delay(dsm0_buffer, wr_done_delay);
+ mss::get_rdtag_delay(dsm0_buffer, rd_tag_delay);
+ rcd_protect_time = std::min(wr_done_delay, rd_tag_delay);
+ FAPI_TRY (mss::change_rcd_protect_time(p, rcd_protect_time) );
+
+ l_ecc64_fir_reg.checkstop<MCA_FIR_MAINLINE_AUE>()
+ .recoverable_error<MCA_FIR_MAINLINE_UE>()
+ .checkstop<MCA_FIR_MAINLINE_IAUE>()
+ .recoverable_error<MCA_FIR_MAINLINE_IUE>();
+
+ l_cal_fir_reg.recoverable_error<MCA_MBACALFIRQ_PORT_FAIL>();
+
+ // If ATTR_CHIP_EC_FEATURE_HW414700 is enabled set checkstops
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_HW414700, l_chip_target, l_checkstop_flag) );
+
+ // If the system is running DD2 chips override some recoverable firs with checkstop
+ // Due to a known hardware defect with DD2 certain errors are not handled properly
+ // As a result, these firs are marked as checkstop for DD2 to avoid any mishandling
+ if (l_checkstop_flag)
+ {
+ l_ecc64_fir_reg.checkstop<MCA_FIR_MAINLINE_UE>()
+ .checkstop<MCA_FIR_MAINLINE_RCD>();
+ l_cal_fir_reg.checkstop<MCA_MBACALFIRQ_PORT_FAIL>();
+ }
+
+ // If MNFG FLAG Threshhold is enabled skip IUE unflagging
+ FAPI_TRY ( mss::mnfg_flags(l_mnfg_buffer) );
+
+ if ( !(l_mnfg_buffer.getBit<MNFG_THRESHOLDS_ATTR>()) )
+ {
+ l_ecc64_fir_reg.recoverable_error<MCA_FIR_MAINTENANCE_IUE>();
+ }
+
+ FAPI_TRY(l_ecc64_fir_reg.write(), "unable to write fir::reg %d", MCA_FIR);
+ FAPI_TRY(l_cal_fir_reg.write(), "unable to write fir::reg %d", MCA_MBACALFIRQ);
+
+ // Change Maint AUE and IAUE to checkstop without unmasking
+ // Normal setup modifies masked bits in addition to setting checkstop
+ // This causes issues if error has occured, manually scoming to avoid this
+ FAPI_TRY( mss::getScom(p, MCA_ACTION1, l_aue_buffer) );
+ l_aue_buffer.clearBit<MCA_FIR_MAINTENANCE_AUE>();
+ l_aue_buffer.clearBit<MCA_FIR_MAINTENANCE_IAUE>();
+ FAPI_TRY( mss::putScom(p, MCA_ACTION1, l_aue_buffer) );
+
+ // Note: We also want to include the following setup RCD recovery and port fail
+ FAPI_TRY( mss::change_port_fail_disable(p, mss::LOW) );
+ FAPI_TRY( mss::change_rcd_recovery_disable(p, mss::LOW) );
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Unmask and setup actions for scrub related FIR
+/// @param[in] i_target the fapi2::Target MCBIST
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode after_background_scrub<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>&
+ i_target )
+{
+ for (const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target))
+ {
+ fapi2::ReturnCode l_rc;
+ fir::reg<MCA_FIR> l_ecc64_fir_reg(p, l_rc);
+ FAPI_TRY(l_rc, "unable to create fir::reg 0x%016lx for %s", MCA_FIR, mss::c_str(p));
+
+ l_ecc64_fir_reg.recoverable_error<MCA_FIR_MAINLINE_MPE_RANK_0_TO_7,
+ MCA_FIR_MAINLINE_MPE_RANK_0_TO_7_LEN>()
+ .recoverable_error<MCA_FIR_MAINLINE_NCE>()
+ .recoverable_error<MCA_FIR_MAINLINE_TCE>()
+ .recoverable_error<MCA_FIR_MAINLINE_IMPE>()
+ .recoverable_error<MCA_FIR_MAINTENANCE_IMPE>();
+
+ FAPI_TRY(l_ecc64_fir_reg.write(), "unable to write fir::reg 0x%016lx for %s", MCA_FIR, mss::c_str(p));
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
}
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.H b/src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.H
index 7a4d271bc..a6ae3863f 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -45,7 +45,57 @@ namespace mss
namespace unmask
{
+///
+/// @brief Unmask and setup actions performed after draminit_mc
+/// @param[in] i_target the fapi2::Target of the MCBIST
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode after_draminit_mc<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target );
+
+///
+/// @brief Unmask and setup actions performed after draminit_training
+/// @param[in] i_target the fapi2::Target of the MCBIST
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode after_draminit_training<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>&
+ i_target );
+///
+/// @brief Unmask and setup actions performed after mss_scominit
+/// (yeah, it's clearing bits - it's ok)
+/// @param[in] i_target the fapi2::Target of the MCBIST
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode after_scominit<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target );
+
+///
+/// @brief Unmask and setup actions performed after mss_ddr_phy_reset
+/// @param[in] i_target the fapi2::Target of the MCBIST
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode after_phy_reset<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target );
+
+
+///
+/// @brief Unmask and setup actions for memdiags related FIR
+/// @param[in] i_target the fapi2::Target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode after_memdiags<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target );
+
+///
+/// @brief Unmask and setup actions for scrub related FIR
+/// @param[in] i_target the fapi2::Target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode after_background_scrub<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>&
+ i_target );
}
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_freq_traits.H b/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_freq_traits.H
index 4818eeeb1..9ef0fc6a3 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_freq_traits.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_freq_traits.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -57,6 +57,7 @@ class frequency_traits<mss::proc_type::NIMBUS>
//////////////////////////////////////////////////////////////
static constexpr fapi2::TargetType PORT_TARGET_TYPE = fapi2::TARGET_TYPE_MCA;
static constexpr fapi2::TargetType FREQ_TARGET_TYPE = fapi2::TARGET_TYPE_MCBIST;
+ static constexpr fapi2::TargetType FREQ_DOMAIN_TARGET_TYPE = fapi2::TARGET_TYPE_MCBIST;
static constexpr fapi2::TargetType VPD_TARGET_TYPE = fapi2::TARGET_TYPE_MCS;
//////////////////////////////////////////////////////////////
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C b/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C
index 8c9b1ccc5..277847f73 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C
@@ -46,7 +46,7 @@
// Generic libraries
#include <generic/memory/lib/utils/assert_noexit.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <generic/memory/lib/spd/spd_facade.H>
#include <generic/memory/lib/spd/spd_utils.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.C b/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.C
index c56b1ff90..a37418f13 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.C
@@ -34,9 +34,11 @@
// *HWP Consumed by: FSP:HB
#include <fapi2.H>
-#include <lib/utils/dump_regs.H>
+
+#include <lib/shared/nimbus_defaults.H>
+#include <generic/memory/lib/utils/dump_regs.H>
#include <lib/mc/mc.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCS;
@@ -88,8 +90,7 @@ fapi2::ReturnCode set_pwr_cntrl_reg(const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
uint8_t l_pwr_cntrl = 0;
fapi2::buffer<uint64_t> l_data;
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_MRW_POWER_CONTROL_REQUESTED, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
- l_pwr_cntrl), "Error in set_pwr_cntrl_reg");
+ FAPI_TRY(mrw_power_control_requested(l_pwr_cntrl), "Error in set_pwr_cntrl_reg");
FAPI_TRY(read_mbarpc0(i_target, l_data));
l_data.insertFromRight<TT::CFG_MIN_MAX_DOMAINS, TT::CFG_MIN_MAX_DOMAINS_LEN>(MAXALL_MINALL);
@@ -138,8 +139,7 @@ fapi2::ReturnCode set_str_reg(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_tar
uint8_t l_str_enable = 0;
fapi2::buffer<uint64_t> l_data;
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_MRW_POWER_CONTROL_REQUESTED, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
- l_str_enable), "Error in set_pwr_cntrl_reg");
+ FAPI_TRY(mrw_power_control_requested(l_str_enable), "Error in set_pwr_cntrl_reg");
FAPI_TRY(read_mbastr0(i_target, l_data));
//Write bit if STR should be enabled
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.H b/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.H
index fdef40a8d..b589c0479 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.H
@@ -41,7 +41,7 @@
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>
#include <lib/mss_attribute_accessors.H>
-#include <lib/dimm/kind.H>
+#include <lib/dimm/nimbus_kind.H>
#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/scom.H>
@@ -123,6 +123,7 @@ class mcTraits<fapi2::TARGET_TYPE_MCA>
EMERGENCY_M = MCA_MBA_FARB4Q_EMERGENCY_M,
EMERGENCY_M_LEN = MCA_MBA_FARB4Q_EMERGENCY_M_LEN,
CFG_STR_ENABLE = MCA_MBASTR0Q_CFG_STR_ENABLE,
+ CFG_STR_STATE = MCA_MBA_FARB6Q_CFG_STR_STATE,
MIN_DOMAIN_REDUCTION_ENABLE = MCA_MBARPC0Q_CFG_MIN_DOMAIN_REDUCTION_ENABLE,
MIN_MAX_DOMAINS_ENABLE = MCA_MBARPC0Q_CFG_MIN_MAX_DOMAINS_ENABLE,
@@ -189,6 +190,43 @@ enum
namespace mc
{
+///
+/// @brief Reads the contents of the FARB6Q
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to mcTraits<T>
+/// @param[in] i_target the target on which to operate
+/// @param[out] o_data the register data
+/// @return fapi2::fapi2_rc_success if ok
+///
+template< fapi2::TargetType T, typename TT = mcTraits<T> >
+inline fapi2::ReturnCode read_farb6q( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ o_data = 0;
+
+ FAPI_TRY( mss::getScom(i_target, TT::FARB6Q, o_data ), "%s failed to read FARB6Q regiser", mss::c_str(i_target));
+ FAPI_DBG("%s FARB6Q has data 0x%016lx", mss::c_str(i_target), o_data);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Writes the contents of the FARB6Q
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to mcTraits<T>
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_data the register data
+/// @return fapi2::fapi2_rc_success if ok
+///
+template< fapi2::TargetType T, typename TT = mcTraits<T> >
+inline fapi2::ReturnCode write_farb6q( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ FAPI_TRY( mss::putScom(i_target, TT::FARB6Q, i_data ), "%s failed to write FARB6Q regiser", mss::c_str(i_target));
+ FAPI_DBG("%s FARB6Q has data 0x%016lx", mss::c_str(i_target), i_data);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
///
/// @brief Reads the contents of the MBARPC0
@@ -407,6 +445,20 @@ inline void get_enter_self_time_refresh_time( const fapi2::buffer<uint64_t>& i_d
}
///
+/// @brief Gets the port self time refresh state
+/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCA
+/// @tparam TT traits type defaults to mcTraits<T>
+/// @param[in] i_data the value of the register
+/// @param[out] o_state the current STR state of the given port
+///
+template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = mcTraits<T> >
+inline void get_self_time_refresh_state( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state )
+{
+ o_state = i_data.getBit<TT::CFG_STR_STATE>() ? mss::states::ON : mss::states::OFF;
+ FAPI_DBG("get_self_time_refresh_state to %d", o_state);
+}
+
+///
/// @brief set the PWR CNTRL register
/// @param[in] i_target the mca target
/// @return fapi2::fapi2_rc_success if ok
@@ -485,7 +537,7 @@ fapi2::ReturnCode calculate_perf2(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i
/// @param[out] fapi2::buffer<uint64_t> o_xlate2 - xlt register 2's value
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode setup_xlate_map_helper( std::vector<dimm::kind>& i_dimm_kinds,
+fapi2::ReturnCode setup_xlate_map_helper( std::vector<dimm::kind<>>& i_dimm_kinds,
fapi2::buffer<uint64_t>& o_xlate0,
fapi2::buffer<uint64_t>& o_xlate1,
fapi2::buffer<uint64_t>& o_xlate2 );
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/perf_reg.C b/src/import/chips/p9/procedures/hwp/memory/lib/mc/perf_reg.C
index 62d36ae0b..84ae50e3c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/perf_reg.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/perf_reg.C
@@ -35,6 +35,7 @@
#include <fapi2.H>
+#include <lib/shared/nimbus_defaults.H>
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>
@@ -42,8 +43,7 @@
#include <lib/shared/mss_const.H>
#include <lib/mc/mc.H>
#include <generic/memory/lib/utils/scom.H>
-#include <lib/dimm/kind.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <generic/memory/lib/utils/pos.H>
using fapi2::TARGET_TYPE_MCA;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C
index 9ca4fae85..fc3f7b568 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,8 +38,9 @@
#include <lib/mc/port.H>
#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/scom.H>
-#include <lib/ecc/ecc.H>
+#include <generic/memory/lib/ecc/ecc.H>
#include <lib/workarounds/mca_workarounds.H>
+#include <lib/ecc/nimbus_mbs_error_vector_trap.H>
namespace mss
{
@@ -306,207 +307,18 @@ fapi_try_exit:
}
///
-/// @brief Convert a bitmap from the BAD_DQ_BITMAP attribute to a vector of bad DQ indexes
-/// @param[in] i_bad_bits an 8-bit bitmap of bad bits
-/// @param[in] i_nibble which nibble of the bitmap to convert
-/// @return std::vector of DQ bits marked as bad in the bitmap
-///
-std::vector<uint64_t> bad_bit_helper(const uint8_t i_bad_bits, const size_t i_nibble)
-{
- std::vector<uint64_t> l_output;
- fapi2::buffer<uint8_t> l_bit_buffer(i_bad_bits);
-
- const size_t l_start = (i_nibble == 0) ? 0 : BITS_PER_NIBBLE;
-
- for (size_t l_offset = 0; l_offset < BITS_PER_NIBBLE; ++l_offset)
- {
- if (l_bit_buffer.getBit(l_start + l_offset))
- {
- l_output.push_back(l_start + l_offset);
- }
- }
-
- return l_output;
-}
-
-///
-/// @brief Place a symbol mark in a Firmware Mark Store register
-/// @param[in] i_target the DIMM target
-/// @param[in] i_rank the rank
-/// @param[in] i_dq the bad DQ bit
-/// @return FAPI2_RC_SUCCESS if and only if ok
-///
-template<>
-fapi2::ReturnCode place_symbol_mark(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq)
-{
- const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
- const auto l_dimm_idx = mss::index(i_target);
- const auto l_rank_idx = mss::index(i_rank);
-
- uint8_t l_galois = 0;
- mss::mcbist::address l_addr;
-
- // For symbol marks, we set the appropriate Firmware Mark Store reg, with the symbol's
- // Galois code, mark_type=SYMBOL, mark_region=MRANK, and the address of the DIMM+MRANK
- // TODO RTC:165133 Remove static_cast once Galois API is updated to accept uint64_t input
- FAPI_TRY( mss::ecc::dq_to_galois(static_cast<uint8_t>(i_dq), l_galois) );
-
- l_addr.set_dimm(l_dimm_idx).set_master_rank(l_rank_idx);
-
- FAPI_INF("%s Setting firmware symbol mark on rank:%d dq:%d galois:0x%02x",
- mss::c_str(i_target), i_rank, i_dq, l_galois);
- FAPI_TRY( mss::ecc::set_fwms(l_mca, i_rank, l_galois, mss::ecc::fwms::mark_type::SYMBOL,
- mss::ecc::fwms::mark_region::MRANK, l_addr) );
-
- // Apply workaround for HW474117 if we place a symbol mark
- FAPI_TRY( mss::workarounds::disable_bypass(l_mca) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Place a chip mark in a Hardware Mark Store register
-/// @param[in] i_target the DIMM target
-/// @param[in] i_rank the rank
-/// @param[in] i_dq one of the bad DQ bits in the bad nibble
-/// @return FAPI2_RC_SUCCESS if and only if ok
-///
-template<>
-fapi2::ReturnCode place_chip_mark(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq)
-{
- const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
-
- uint8_t l_galois = 0;
- uint8_t l_symbol = 0;
-
- // For chip marks, we set the appropriate Hardware Mark Store reg, with the Galois code
- // of the first (smallest) symbol in the bad nibble, and both confirmed and exit1 bits set
- FAPI_TRY( mss::ecc::dq_to_symbol(static_cast<uint8_t>(i_dq), l_symbol) );
-
- // Round down to the nearest "nibble" to get the correct symbol, then get the Galois code for it
- l_symbol = (l_symbol / BITS_PER_NIBBLE) * BITS_PER_NIBBLE;
- FAPI_TRY( mss::ecc::symbol_to_galois(l_symbol, l_galois) );
-
- FAPI_INF("%s Setting hardware (chip) mark on rank:%d galois:0x%02x", mss::c_str(i_target), i_rank, l_galois);
- FAPI_TRY( mss::ecc::set_hwms(l_mca, i_rank, l_galois) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Restore symbol and chip marks according to BAD_DQ_BITMAP attribute, helper function for unit testing
-/// Specialization for TARGET_TYPE_DIMM
-/// @param[in] i_target the DIMM target
-/// @param[in] i_bad_bits the bad bits values from the VPD, for the specified DIMM
-/// @param[out] o_repairs_applied 8-bit mask, where a bit set means a rank had repairs applied (bit0-7 = rank0-7)
-/// @param[out] o_repairs_exceeded 2-bit mask, where a bit set means a DIMM had more bad bits than could be repaired (bit0-1 = DIMM0-1)
-/// @return FAPI2_RC_SUCCESS if and only if ok
-///
-template<>
-fapi2::ReturnCode restore_repairs_helper<fapi2::TARGET_TYPE_DIMM, BAD_BITS_RANKS, BAD_DQ_BYTE_COUNT>(
- const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint8_t i_bad_bits[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT],
- fapi2::buffer<uint8_t>& o_repairs_applied,
- fapi2::buffer<uint8_t>& o_repairs_exceeded)
-{
- FAPI_INF("%s Restore repair marks from bad DQ data", mss::c_str(i_target));
-
- std::vector<uint64_t> l_ranks;
- const auto l_dimm_idx = mss::index(i_target);
-
- FAPI_TRY( mss::rank::ranks(i_target, l_ranks) );
-
- // loop through ranks
- for (const auto l_rank : l_ranks)
- {
- const auto l_rank_idx = mss::index(l_rank);
-
- repair_state_machine<fapi2::TARGET_TYPE_DIMM> l_machine;
-
- // loop through bytes
- for (uint64_t l_byte = 0; l_byte < (MAX_DQ_NIBBLES / NIBBLES_PER_BYTE); ++l_byte)
- {
- for (size_t l_nibble = 0; l_nibble < NIBBLES_PER_BYTE; ++l_nibble)
- {
- const auto l_bad_dq_vector = bad_bit_helper(i_bad_bits[l_rank_idx][l_byte], l_nibble);
- FAPI_DBG("Total bad bits on DIMM:%d rank:%d nibble%d: %d",
- l_dimm_idx, l_rank, (l_byte * NIBBLES_PER_BYTE) + l_nibble, l_bad_dq_vector.size());
-
- // apply repairs and update repair machine state
- // if there are no bad bits (l_bad_dq_vector.size() == 0) no action is necessary
- if (l_bad_dq_vector.size() == 1)
- {
- // l_bad_dq_vector is per byte, so multiply up to get the bad dq's index
- const uint64_t l_dq = l_bad_dq_vector[0] + (l_byte * BITS_PER_BYTE);
- FAPI_TRY( l_machine.one_bad_dq(i_target, l_rank, l_dq, o_repairs_applied, o_repairs_exceeded) );
- }
- else if (l_bad_dq_vector.size() > 1)
- {
- // l_bad_dq_vector is per byte, so multiply up to get the bad dq's index
- const uint64_t l_dq = l_bad_dq_vector[0] + (l_byte * BITS_PER_BYTE);
- FAPI_TRY( l_machine.multiple_bad_dq(i_target, l_rank, l_dq, o_repairs_applied, o_repairs_exceeded) );
- }
-
- // if repairs have been exceeded, we're done
- if (o_repairs_exceeded.getBit(l_dimm_idx))
- {
- FAPI_INF("Repairs exceeded on DIMM %s", mss::c_str(i_target));
- return fapi2::FAPI2_RC_SUCCESS;
- }
- } // end loop through nibbles
- } // end loop through bytes
- } // end loop through ranks
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Restore symbol and chip marks according to BAD_DQ_BITMAP attribute
-/// Specialization for TARGET_TYPE_MCA
-/// @param[in] i_target A target representing a port
-/// @param[out] o_repairs_applied 8-bit mask, where a bit set means a rank had repairs applied (bit0-7 = rank0-7)
-/// @param[out] o_repairs_exceeded 2-bit mask, where a bit set means a DIMM had more bad bits than could be repaired (bit0-1 = DIMM0-1)
+/// @brief Set up memory controller specific settings for ECC registers (at the end of draminit_mc)
+/// @param[in] i_target the target
+/// @param[in,out] io_data contents of RECR register
/// @return FAPI2_RC_SUCCESS if and only if ok
+/// @note mc_type::NIMBUS specialization
///
template<>
-fapi2::ReturnCode restore_repairs( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- fapi2::buffer<uint8_t>& o_repairs_applied,
- fapi2::buffer<uint8_t>& o_repairs_exceeded)
+fapi2::ReturnCode ecc_reg_settings_draminit_mc<mss::mc_type::NIMBUS>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ fapi2::buffer<uint64_t>& io_data )
{
- uint8_t l_bad_bits[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT] = {};
-
- o_repairs_applied = 0;
- o_repairs_exceeded = 0;
-
- for (const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target))
- {
- FAPI_TRY( mss::bad_dq_bitmap(l_dimm, &(l_bad_bits[0][0])) );
-
- FAPI_TRY( (restore_repairs_helper<fapi2::TARGET_TYPE_DIMM, BAD_BITS_RANKS, BAD_DQ_BYTE_COUNT>(
- l_dimm, l_bad_bits, o_repairs_applied, o_repairs_exceeded)) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Set a new state in the repair state machine
-/// @tparam T, the fapi2 target type of the DIMM
-/// @param[in,out] io_machine the repair state machine
-/// @param[in] i_state shared pointer to the new state to set
-///
-template< fapi2::TargetType T >
-void repair_state<T>::set_state(repair_state_machine<T>& io_machine, std::shared_ptr<repair_state<T>> i_state)
-{
- io_machine.update_state(i_state);
+ return fapi2::FAPI2_RC_SUCCESS;
}
///
@@ -802,48 +614,4 @@ fapi2::ReturnCode chip_and_symbol_mark<fapi2::TARGET_TYPE_DIMM>::multiple_bad_dq
return fapi2::FAPI2_RC_SUCCESS;
}
-///
-/// @brief Perform a repair for a single bad DQ bit in a nibble
-/// @tparam T, the fapi2 target type of the DIMM
-/// @param[in] i_target the DIMM target
-/// @param[in] i_rank the rank
-/// @param[in] i_dq the DQ bit index
-/// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
-/// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
-/// @return FAPI2_RC_SUCCESS if and only if ok
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode repair_state_machine<T>::one_bad_dq(const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded)
-{
- FAPI_TRY( iv_repair_state->one_bad_dq(*this, i_target, i_rank, i_dq, io_repairs_applied, io_repairs_exceeded) );
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Perform a repair for multiple bad DQ bits in a nibble
-/// @tparam T, the fapi2 target type of the DIMM
-/// @param[in] i_target the DIMM target
-/// @param[in] i_rank the rank
-/// @param[in] i_dq one of the bad DQ bit indexes
-/// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
-/// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
-/// @return FAPI2_RC_SUCCESS if and only if ok
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode repair_state_machine<T>::multiple_bad_dq(const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded)
-{
- FAPI_TRY( iv_repair_state->multiple_bad_dq(*this, i_target, i_rank, i_dq, io_repairs_applied, io_repairs_exceeded) );
-fapi_try_exit:
- return fapi2::current_err;
-}
-
} // ns mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
index 33131ad4f..f11f9aafa 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,12 +40,12 @@
#include <lib/mss_attribute_accessors.H>
#include <lib/shared/mss_const.H>
+#include <lib/utils/mss_nimbus_conversions.H>
#include <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/c_str.H>
#include <generic/memory/lib/utils/mc/gen_mss_port.H>
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>
-#include <lib/utils/mss_nimbus_conversions.H>
#include <lib/dimm/rank.H>
#include <lib/mcbist/address.H>
@@ -75,9 +75,14 @@ template<>
class portTraits<mss::mc_type::NIMBUS>
{
public:
+
+ // PORT_TYPE
+ static constexpr enum fapi2::TargetType PORT_TYPE = fapi2::TARGET_TYPE_MCA;
+
static constexpr uint64_t FARB0Q_REG = MCA_MBA_FARB0Q;
static constexpr uint64_t FARB1Q_REG = MCA_MBA_FARB1Q;
static constexpr uint64_t FARB5Q_REG = MCA_MBA_FARB5Q;
+ static constexpr uint64_t FARB6Q_REG = MCA_MBA_FARB6Q;
static constexpr uint64_t REFRESH_REG = MCA_MBAREF0Q;
static constexpr uint64_t ECC_REG = MCA_RECR;
static constexpr uint64_t CAL0Q_REG = MCA_MBA_CAL0Q;
@@ -134,6 +139,10 @@ class portTraits<mss::mc_type::NIMBUS>
PORT_FAIL_DISABLE = MCA_MBA_FARB0Q_CFG_PORT_FAIL_DISABLE,
OE_ALWAYS_ON = MCA_MBA_FARB0Q_CFG_OE_ALWAYS_ON,
RCD_RECOVERY_DISABLE = MCA_MBA_FARB0Q_CFG_DISABLE_RCD_RECOVERY,
+ BW_WINDOW_SIZE = MCA_MBA_FARB0Q_CFG_BW_WINDOW_SIZE,
+ BW_WINDOW_SIZE_LEN = MCA_MBA_FARB0Q_CFG_BW_WINDOW_SIZE_LEN,
+ BW_SNAPSHOT = MCA_MBA_FARB6Q_CFG_BW_SNAPSHOT,
+ BW_SNAPSHOT_LEN = MCA_MBA_FARB6Q_CFG_BW_SNAPSHOT_LEN,
CAL0Q_CAL_INTERVAL_TMR0_ENABLE = MCA_MBA_CAL0Q_CFG_CAL_INTERVAL_TMR0_ENABLE,
CAL0Q_TIME_BASE_TMR0 = MCA_MBA_CAL0Q_CFG_TIME_BASE_TMR0,
@@ -247,9 +256,9 @@ class portTraits<mss::mc_type::NIMBUS>
RECR_ENABLE_UE_NOISE_WINDOW = MCA_RECR_MBSECCQ_ENABLE_UE_NOISE_WINDOW,
RECR_TCE_CORRECTION = MCA_RECR_MBSECCQ_ENABLE_TCE_CORRECTION,
RECR_READ_POINTER_DLY = MCA_RECR_MBSECCQ_READ_POINTER_DELAY,
+ RECR_READ_POINTER_DLY_LEN = MCA_RECR_MBSECCQ_READ_POINTER_DELAY_LEN,
RECR_MBSECCQ_DATA_INVERSION = MCA_RECR_MBSECCQ_DATA_INVERSION,
RECR_MBSECCQ_DATA_INVERSION_LEN = MCA_RECR_MBSECCQ_DATA_INVERSION_LEN,
- RECR_READ_POINTER_DLY_LEN = MCA_RECR_MBSECCQ_READ_POINTER_DELAY_LEN,
DSM0Q_RDTAG_DLY = MCA_MBA_DSM0Q_CFG_RDTAG_DLY,
DSM0Q_RDTAG_DLY_LEN = MCA_MBA_DSM0Q_CFG_RDTAG_DLY_LEN,
DSM0Q_WRDONE_DLY = MCA_MBA_DSM0Q_CFG_WRDONE_DLY,
@@ -681,7 +690,7 @@ fapi2::ReturnCode configure_cid_parity( const fapi2::Target<T>& i_target)
l_state = mss::states::OFF_N;
}
- FAPI_DBG( "Change RDTAG_DLY to %d for %s", l_state, mss::c_str(i_target) );
+ FAPI_DBG( "Change CID_PARITY to %d for %s", l_state, mss::c_str(i_target) );
FAPI_TRY( read_farb1q_register(i_target, l_data) );
set_cid_parity<T>(l_state, l_data);
@@ -814,6 +823,23 @@ template<>
fapi2::ReturnCode enable_periodic_cal( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target );
+///
+/// @brief Change the state of the force_str bit - mc_type::NIMBUS specialization
+/// @tparam MC the memory controller type
+/// @param[in] i_target the target
+/// @param[in] i_state the state
+/// @return FAPI2_RC_SUCCESS if and only if ok
+/// @note This bit doesn't exist on Nimbus, so this is a no-op
+///
+template<>
+inline fapi2::ReturnCode change_force_str<DEFAULT_MC_TYPE>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const states i_state )
+{
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+
//
// We expect to come in to draminit with the following setup:
// 1. ENABLE_RESET_N (FARB5Q(6)) 0
@@ -956,558 +982,21 @@ fapi_try_exit:
return fapi2::current_err;
}
+/// @brief Get the attributes for the reorder queue setting
+/// @param[in] const ref to the mc target
+/// @param[out] uint8_t& reference to store the value
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Contains the settings for write/read reorder
+/// queue
///
-/// @brief Configures the write reorder queue for MCBIST operations
-/// @param[in] i_target the target to effect
-/// @param[in] i_state to set the bit too
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-inline fapi2::ReturnCode configure_wrq(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const mss::states i_state)
-{
- typedef portTraits<mss::mc_type::NIMBUS> TT;
-
- fapi2::buffer<uint64_t> l_data;
-
- // Gets the reg
- FAPI_TRY(mss::getScom(i_target, TT::WRQ_REG, l_data), "%s failed to getScom from MCA_MBA_WRQ0Q", mss::c_str(i_target));
-
- // Sets the bit
- l_data.writeBit<TT::WRQ_FIFO_MODE>(i_state == mss::states::ON);
-
- // Sets the regs
- FAPI_TRY(mss::putScom(i_target, TT::WRQ_REG, l_data), "%s failed to putScom to MCA_MBA_WRQ0Q", mss::c_str(i_target));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Configures the write reorder queue bit
-/// @param[in] i_target the target to effect
-/// @param[in] i_state to set the bit too
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-inline fapi2::ReturnCode configure_wrq(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- const mss::states i_state)
-{
- // Loops through all MCA targets, hitting all the registers
- for( const auto& l_mca : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target) )
- {
- FAPI_TRY(configure_wrq(l_mca, i_state));
- }
-
- // In case we don't have any MCA's
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Configures the read reorder queue for MCBIST operations
-/// @param[in] i_target the target to effect
-/// @param[in] i_state to set the bit too
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-inline fapi2::ReturnCode configure_rrq(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const mss::states i_state)
-{
- typedef portTraits<mss::mc_type::NIMBUS> TT;
-
- fapi2::buffer<uint64_t> l_data;
-
- // Gets the reg
- FAPI_TRY(mss::getScom(i_target, TT::RRQ_REG, l_data), "%s failed to getScom from MCA_MBA_RRQ0Q", mss::c_str(i_target));
-
- // Sets the bit
- l_data.writeBit<TT::RRQ_FIFO_MODE>(i_state == mss::states::ON);
-
- // Sets the regs
- FAPI_TRY(mss::putScom(i_target, TT::RRQ_REG, l_data), "%s failed to putScom to MCA_MBA_RRQ0Q", mss::c_str(i_target));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Configures the read reorder queue bit
-/// @param[in] i_target the target to effect
-/// @param[in] i_state to set the bit too
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-inline fapi2::ReturnCode configure_rrq(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- const mss::states i_state)
-{
- // Loops through all MCA targets, hitting all the registers
- for( const auto& l_mca : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target) )
- {
- FAPI_TRY(configure_rrq(l_mca, i_state));
- }
-
- // In case we don't have any MCA's
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Resets the write/read reorder queue values - needs to be called after MCBIST execution
-/// @tparam T, the fapi2 target type of the target
-/// @param[in] i_target the target to effect
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T>
-fapi2::ReturnCode reset_reorder_queue_settings(const fapi2::Target<T>& i_target)
+template< >
+inline fapi2::ReturnCode reorder_queue_setting<mss::mc_type::NIMBUS>(const
+ fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ uint8_t& o_value)
{
- uint8_t l_reorder_queue = 0;
- FAPI_TRY(reorder_queue_setting(i_target, l_reorder_queue));
-
- // Changes the reorder queue settings
- {
- // Two settings are FIFO and REORDER. FIFO is a 1 in the registers, while reorder is a 0 state
- const mss::states l_state = ((l_reorder_queue == fapi2::ENUM_ATTR_MSS_REORDER_QUEUE_SETTING_FIFO) ?
- mss::states::ON : mss::states::OFF);
- FAPI_TRY(configure_rrq(i_target, l_state), "%s failed to reset read reorder queue settings", mss::c_str(i_target));
- FAPI_TRY(configure_wrq(i_target, l_state), "%s failed to reset read reorder queue settings", mss::c_str(i_target));
- }
-
-
-fapi_try_exit:
- return fapi2::current_err;
+ return mss::reorder_queue_setting(i_target, o_value);
}
-///
-/// @brief Convert a bitmap from the BAD_DQ_BITMAP attribute to a vector of bad DQ indexes
-/// @param[in] i_bad_bits an 8-bit bitmap of bad bits
-/// @param[in] i_nibble which nibble of the bitmap to convert
-/// @return std::vector of DQ bits marked as bad in the bitmap
-///
-std::vector<uint64_t> bad_bit_helper(const uint8_t i_bad_bits, const size_t i_nibble);
-
-///
-/// @brief Place a symbol mark in a Firmware Mark Store register
-/// @tparam T, the fapi2 target type of the DIMM (derived)
-/// @param[in] i_target the DIMM target
-/// @param[in] i_rank the rank
-/// @param[in] i_dq the bad DQ bit
-/// @return FAPI2_RC_SUCCESS if and only if ok
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode place_symbol_mark(const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq);
-
-///
-/// @brief Place a chip mark in a Hardware Mark Store register
-/// @tparam T, the fapi2 target type of the DIMM (derived)
-/// @param[in] i_target the DIMM target
-/// @param[in] i_rank the rank
-/// @param[in] i_dq one of the bad DQ bits in the bad nibble
-/// @return FAPI2_RC_SUCCESS if and only if ok
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode place_chip_mark(const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq);
-
-// Forward declaration for use in repair_state classes
-template< fapi2::TargetType T >
-class repair_state_machine;
-
-///
-/// @class mss::repair_state
-/// @brief A class for keeping track of bad bit repair states in a repair_state_machine
-/// @tparam T, the fapi2 target type of the DIMM
-/// @note this is a base class
-///
-template< fapi2::TargetType T >
-class repair_state
-{
- public:
- /// @brief default contructor
- repair_state() = default;
- /// @brief default destructor
- virtual ~repair_state() = default;
-
- ///
- /// @brief Perform a repair for a single bad DQ bit in a nibble
- /// @param[in,out] io_machine the repair state machine
- /// @param[in] i_target the DIMM target
- /// @param[in] i_rank the rank
- /// @param[in] i_dq the DQ bit index
- /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
- /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
- /// @return FAPI2_RC_SUCCESS if and only if ok
- ///
- virtual fapi2::ReturnCode one_bad_dq(repair_state_machine<T>& io_machine,
- const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded) = 0;
-
- ///
- /// @brief Perform a repair for multiple bad DQ bits in a nibble
- /// @param[in,out] io_machine the repair state machine
- /// @param[in] i_target the DIMM target
- /// @param[in] i_rank the rank
- /// @param[in] i_dq one of the bad DQ bit indexes
- /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
- /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
- /// @return FAPI2_RC_SUCCESS if and only if ok
- ///
- virtual fapi2::ReturnCode multiple_bad_dq(repair_state_machine<T>& io_machine,
- const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded) = 0;
-
- protected:
- ///
- /// @brief Set a new state in the repair state machine
- /// @param[in,out] io_machine the repair state machine
- /// @param[in] i_state pointer to the new state to set
- ///
- void set_state(repair_state_machine<T>& io_machine, std::shared_ptr<repair_state<T>> i_state);
-};
-
-///
-/// @class mss::no_fails
-/// @brief repair_state class for no fails (no marks applied)
-/// @tparam T, the fapi2 target type of the DIMM
-///
-template< fapi2::TargetType T >
-class no_fails : public repair_state<T>
-{
- public:
- /// @brief default contructor
- no_fails() = default;
- /// @brief default destructor
- ~no_fails() = default;
-
- ///
- /// @brief Perform a repair for a single bad DQ bit in a nibble
- /// @param[in,out] io_machine the repair state machine
- /// @param[in] i_target the DIMM target
- /// @param[in] i_rank the rank
- /// @param[in] i_dq the DQ bit index
- /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
- /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
- /// @return FAPI2_RC_SUCCESS if and only if ok
- ///
- fapi2::ReturnCode one_bad_dq(repair_state_machine<T>& io_machine,
- const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded) override;
-
- ///
- /// @brief Perform a repair for multiple bad DQ bits in a nibble
- /// @param[in,out] io_machine the repair state machine
- /// @param[in] i_target the DIMM target
- /// @param[in] i_rank the rank
- /// @param[in] i_dq one of the bad DQ bit indexes
- /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
- /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
- /// @return FAPI2_RC_SUCCESS if and only if ok
- ///
- fapi2::ReturnCode multiple_bad_dq(repair_state_machine<T>& io_machine,
- const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded) override;
-};
-
-///
-/// @class mss::symbol_mark_only
-/// @brief repair_state class for when only a symbol mark has been used
-/// @tparam T, the fapi2 target type of the DIMM
-///
-template< fapi2::TargetType T >
-class symbol_mark_only : public repair_state<T>
-{
- public:
- /// @brief default contructor
- symbol_mark_only() = default;
- /// @brief default destructor
- ~symbol_mark_only() = default;
-
- ///
- /// @brief Perform a repair for a single bad DQ bit in a nibble
- /// @param[in,out] io_machine the repair state machine
- /// @param[in] i_target the DIMM target
- /// @param[in] i_rank the rank
- /// @param[in] i_dq the DQ bit index
- /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
- /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
- /// @return FAPI2_RC_SUCCESS if and only if ok
- ///
- fapi2::ReturnCode one_bad_dq(repair_state_machine<T>& io_machine,
- const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded) override;
-
- ///
- /// @brief Perform a repair for multiple bad DQ bits in a nibble
- /// @param[in,out] io_machine the repair state machine
- /// @param[in] i_target the DIMM target
- /// @param[in] i_rank the rank
- /// @param[in] i_dq one of the bad DQ bit indexes
- /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
- /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
- /// @return FAPI2_RC_SUCCESS if and only if ok
- ///
- fapi2::ReturnCode multiple_bad_dq(repair_state_machine<T>& io_machine,
- const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded) override;
-};
-
-///
-/// @class mss::symbol_mark_plus_unrepaired_dq
-/// @brief repair_state class for when only a symbol mark has been used, and one DQ bit remains unrepaired
-/// @tparam T, the fapi2 target type of the DIMM
-///
-template< fapi2::TargetType T >
-class symbol_mark_plus_unrepaired_dq : public repair_state<T>
-{
- public:
- /// @brief default contructor
- symbol_mark_plus_unrepaired_dq() = default;
- /// @brief default destructor
- ~symbol_mark_plus_unrepaired_dq() = default;
-
- ///
- /// @brief Perform a repair for a single bad DQ bit in a nibble
- /// @param[in,out] io_machine the repair state machine
- /// @param[in] i_target the DIMM target
- /// @param[in] i_rank the rank
- /// @param[in] i_dq the DQ bit index
- /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
- /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
- /// @return FAPI2_RC_SUCCESS if and only if ok
- ///
- fapi2::ReturnCode one_bad_dq(repair_state_machine<T>& io_machine,
- const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded) override;
-
- ///
- /// @brief Perform a repair for multiple bad DQ bits in a nibble
- /// @param[in,out] io_machine the repair state machine
- /// @param[in] i_target the DIMM target
- /// @param[in] i_rank the rank
- /// @param[in] i_dq one of the bad DQ bit indexes
- /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
- /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
- /// @return FAPI2_RC_SUCCESS if and only if ok
- ///
- fapi2::ReturnCode multiple_bad_dq(repair_state_machine<T>& io_machine,
- const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded) override;
-};
-
-///
-/// @class mss::chip_mark_only
-/// @brief repair_state class for when only a chip mark has been used
-/// @tparam T, the fapi2 target type of the DIMM
-///
-template< fapi2::TargetType T >
-class chip_mark_only : public repair_state<T>
-{
- public:
- /// @brief default contructor
- chip_mark_only() = default;
- /// @brief default destructor
- ~chip_mark_only() = default;
-
- ///
- /// @brief Perform a repair for a single bad DQ bit in a nibble
- /// @param[in,out] io_machine the repair state machine
- /// @param[in] i_target the DIMM target
- /// @param[in] i_rank the rank
- /// @param[in] i_dq the DQ bit index
- /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
- /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
- /// @return FAPI2_RC_SUCCESS if and only if ok
- ///
- fapi2::ReturnCode one_bad_dq(repair_state_machine<T>& io_machine,
- const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded) override;
-
- ///
- /// @brief Perform a repair for multiple bad DQ bits in a nibble
- /// @param[in,out] io_machine the repair state machine
- /// @param[in] i_target the DIMM target
- /// @param[in] i_rank the rank
- /// @param[in] i_dq one of the bad DQ bit indexes
- /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
- /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
- /// @return FAPI2_RC_SUCCESS if and only if ok
- ///
- fapi2::ReturnCode multiple_bad_dq(repair_state_machine<T>& io_machine,
- const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded) override;
-};
-
-///
-/// @class mss::chip_mark_only
-/// @brief repair_state class for when both a chip mark and a symbol mark have been used
-/// @tparam T, the fapi2 target type of the DIMM
-///
-template< fapi2::TargetType T >
-class chip_and_symbol_mark : public repair_state<T>
-{
- public:
- /// @brief default contructor
- chip_and_symbol_mark() = default;
- /// @brief default destructor
- ~chip_and_symbol_mark() = default;
-
- ///
- /// @brief Perform a repair for a single bad DQ bit in a nibble
- /// @param[in,out] io_machine the repair state machine
- /// @param[in] i_target the DIMM target
- /// @param[in] i_rank the rank
- /// @param[in] i_dq the DQ bit index
- /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
- /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
- /// @return FAPI2_RC_SUCCESS if and only if ok
- ///
- fapi2::ReturnCode one_bad_dq(repair_state_machine<T>& io_machine,
- const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded) override;
-
- ///
- /// @brief Perform a repair for multiple bad DQ bits in a nibble
- /// @param[in,out] io_machine the repair state machine
- /// @param[in] i_target the DIMM target
- /// @param[in] i_rank the rank
- /// @param[in] i_dq one of the bad DQ bit indexes
- /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
- /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
- /// @return FAPI2_RC_SUCCESS if and only if ok
- ///
- fapi2::ReturnCode multiple_bad_dq(repair_state_machine<T>& io_machine,
- const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded) override;
-};
-
-///
-/// @class mss::repair_state_machine
-/// @brief state machine class used in restore_repairs_helper
-/// @tparam T, the fapi2 target type of the DIMM
-///
-template< fapi2::TargetType T >
-class repair_state_machine
-{
- public:
- /// @brief constructor
- repair_state_machine()
- : iv_repair_state(std::make_shared<no_fails<T>>()) {}
-
- /// @brief default destructor
- ~repair_state_machine() = default;
-
- ///
- /// @brief Perform a repair for a single bad DQ bit in a nibble
- /// @param[in] i_target the DIMM target
- /// @param[in] i_rank the rank
- /// @param[in] i_dq the DQ bit index
- /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
- /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
- /// @return FAPI2_RC_SUCCESS if and only if ok
- ///
- fapi2::ReturnCode one_bad_dq(const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded);
-
- ///
- /// @brief Perform a repair for multiple bad DQ bits in a nibble
- /// @param[in] i_target the DIMM target
- /// @param[in] i_rank the rank
- /// @param[in] i_dq one of the bad DQ bit indexes
- /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
- /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
- /// @return FAPI2_RC_SUCCESS if and only if ok
- ///
- fapi2::ReturnCode multiple_bad_dq(const fapi2::Target<T>& i_target,
- const uint64_t i_rank,
- const uint64_t i_dq,
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded);
-
- ///
- /// @brief Update the state of the state machine
- /// @param[in] i_state shared pointer to the new state
- ///
- void update_state(std::shared_ptr<repair_state<T>> i_state)
- {
- iv_repair_state = i_state;
- }
-
- private:
- std::shared_ptr<repair_state<T>> iv_repair_state;
-};
-
-// TODO RTC: 157753 tparam R can be pulled from an MCA trait once we have it
-///
-/// @brief Restore symbol and chip marks according to BAD_DQ_BITMAP attribute, helper function for unit testing
-/// @tparam T, the fapi2 target type of the DIMM (derived)
-/// @tparam R the maximum rank per DIMM
-/// @tparam B the number of bytes per rank in the bad_dq_bitmap attribute
-/// @param[in] i_target A target representing a DIMM
-/// @param[in] i_bad_bits the bad bits values from the VPD, for the specified DIMM
-/// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
-/// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
-/// @return FAPI2_RC_SUCCESS if and only if ok
-///
-template< fapi2::TargetType T, uint64_t R, uint64_t B >
-fapi2::ReturnCode restore_repairs_helper( const fapi2::Target<T>& i_target,
- const uint8_t i_bad_bits[R][B],
- fapi2::buffer<uint8_t>& io_repairs_applied,
- fapi2::buffer<uint8_t>& io_repairs_exceeded);
-
-///
-/// @brief Restore symbol and chip marks according to BAD_DQ_BITMAP attribute
-/// @tparam T, the fapi2 target type of the port (derived)
-/// @param[in] i_target A target representing a port
-/// @param[out] o_repairs_applied bit mask, where a bit set means a rank had repairs applied (bit0 = rank0, etc)
-/// @param[out] o_repairs_exceeded bit mask, where a bit set means a DIMM had more bad bits than could be repaired (bit0 = DIMM0 etc)
-/// @return FAPI2_RC_SUCCESS if and only if ok
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode restore_repairs( const fapi2::Target<T>& i_target,
- fapi2::buffer<uint8_t>& o_repairs_applied,
- fapi2::buffer<uint8_t>& o_repairs_exceeded);
-
}// mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C b/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C
index 31ac6eade..cc13cd96c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C
@@ -35,6 +35,7 @@
#include <fapi2.H>
+#include <lib/shared/nimbus_defaults.H>
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>
@@ -43,8 +44,8 @@
#include <lib/mc/mc.H>
#include <lib/mc/xlate.H>
#include <generic/memory/lib/utils/scom.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/dimm/kind.H>
+#include <lib/utils/nimbus_find.H>
+#include <lib/dimm/nimbus_kind.H>
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_DIMM;
@@ -59,7 +60,7 @@ static const std::vector<xlate_setup> xlate_map =
{
// 1R 4Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -72,7 +73,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 4Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -85,7 +86,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 8Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -98,7 +99,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 8Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -111,7 +112,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 16Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -124,7 +125,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 16Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -137,7 +138,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 4Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -150,7 +151,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 4Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -163,7 +164,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 8Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -176,7 +177,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 8Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -189,7 +190,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 16Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -202,7 +203,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 16Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -215,7 +216,7 @@ static const std::vector<xlate_setup> xlate_map =
// 4R 4Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -228,7 +229,7 @@ static const std::vector<xlate_setup> xlate_map =
// 4R 8Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -241,7 +242,7 @@ static const std::vector<xlate_setup> xlate_map =
// 4R 4Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -254,7 +255,7 @@ static const std::vector<xlate_setup> xlate_map =
// 4R 8Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -267,7 +268,7 @@ static const std::vector<xlate_setup> xlate_map =
// 4R 16Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -280,7 +281,7 @@ static const std::vector<xlate_setup> xlate_map =
// 4R 16Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -299,7 +300,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 2H 3DS 4Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -312,7 +313,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 2H 3DS 4Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -325,7 +326,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 2H 3DS 8Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -338,7 +339,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 2H 3DS 8Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -351,7 +352,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 2H 3DS 16Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -364,7 +365,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 2H 3DS 16Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -377,7 +378,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 4H 3DS 4Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -390,7 +391,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 4H 3DS 4Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -403,7 +404,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 4H 3DS 8Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -416,7 +417,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 4H 3DS 8Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -429,7 +430,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 4H 3DS 16Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -442,7 +443,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 4H 3DS 16Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -455,7 +456,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 8H 3DS 4Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -468,7 +469,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 8H 3DS 4Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -481,7 +482,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 8H 3DS 8Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -494,7 +495,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 8H 3DS 8Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -507,7 +508,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 8H 3DS 16Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -520,7 +521,7 @@ static const std::vector<xlate_setup> xlate_map =
// 1R 8H 3DS 16Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -533,7 +534,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 2H 3DS 4Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -546,7 +547,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 2H 3DS 4Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -559,7 +560,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 2H 3DS 8Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -572,7 +573,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 2H 3DS 8Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -585,7 +586,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 2H 3DS 16Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -598,7 +599,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 2H 3DS 16Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -611,7 +612,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 4H 3DS 4Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -624,7 +625,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 4H 3DS 4Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -637,7 +638,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 4H 3DS 8Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -650,7 +651,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 4H 3DS 8Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -663,7 +664,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 4H 3DS 16Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -676,7 +677,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 4H 3DS 16Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -689,7 +690,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 8H 3DS 4Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_16R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -702,7 +703,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 8H 3DS 4Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_16R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -715,7 +716,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 8H 3DS 8Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_16R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -728,7 +729,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 8H 3DS 8Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_16R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -741,7 +742,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 8H 3DS 16Gbx8 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_16R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8,
@@ -754,7 +755,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 8H 3DS 16Gbx4 DDR4 RDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_16R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -773,7 +774,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 8Gbx4 32GB DDR4 LRDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -786,7 +787,7 @@ static const std::vector<xlate_setup> xlate_map =
// 4R 8Gbx4 64GB DDR4 LRDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -803,7 +804,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 2H 3DS 8Gbx4 64GB DDR4 LRDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -816,7 +817,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 4H 3DS 8Gbx4 64GB DDR4 LRDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -829,7 +830,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 2H 3DS 16Gbx4 128GB DDR4 LRDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -842,7 +843,7 @@ static const std::vector<xlate_setup> xlate_map =
// 2R 4H 3DS 16Gbx4 256GB DDR4 LRDIMM
{
- dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
+ dimm::kind<>(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R,
fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R,
fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G,
fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4,
@@ -867,7 +868,7 @@ static bool all_slots_1R_helper(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
const auto& l_mca = mss::find_target<TARGET_TYPE_MCA>(i_target);
const auto& l_dimms = mss::find_targets<TARGET_TYPE_DIMM>(l_mca);
- const std::vector<dimm::kind> l_dimm_kinds = dimm::kind::vector(l_dimms);
+ const std::vector<dimm::kind<>> l_dimm_kinds = dimm::kind<>::vector(l_dimms);
bool l_all_slots_1R = false;
// If we only have 1 DIMM, we don't have two slots with 1R DIMM. If we need to check, iterate
@@ -993,7 +994,7 @@ fapi_try_exit:
/// @note Called for 2R4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R2T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R2T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1038,7 +1039,7 @@ fapi_try_exit:
/// @note Called for 2R 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R2T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R2T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1075,7 +1076,7 @@ fapi_try_exit:
/// @note Called for 2R 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R2T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R2T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1112,7 +1113,7 @@ fapi_try_exit:
/// @note Called for 2R 2H 3DS 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R4T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R4T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1142,7 +1143,7 @@ fapi_try_exit:
/// @note Called for 2R 2H 3DS 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R4T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R4T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1175,7 +1176,7 @@ fapi_try_exit:
/// @note Called for 2R 2H 3DS 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R4T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R4T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1208,7 +1209,7 @@ fapi_try_exit:
/// @note Called for 2R 4H 3DS 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R8T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R8T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1238,7 +1239,7 @@ fapi_try_exit:
/// @note Called for 2R 4H 3DS 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R8T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R8T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1271,7 +1272,7 @@ fapi_try_exit:
/// @note Called for 2R 4H 3DS 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R8T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R8T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1304,7 +1305,7 @@ fapi_try_exit:
/// @note Called for 2R 8H 3DS 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R16T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R16T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1341,7 +1342,7 @@ fapi_try_exit:
/// @note Called for 2R 8H 3DS 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R16T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R16T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1374,7 +1375,7 @@ fapi_try_exit:
/// @note Called for 2R 8H 3DS 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R16T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R16T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1408,7 +1409,7 @@ fapi_try_exit:
/// @note Called for 1R 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R1T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R1T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1510,7 +1511,7 @@ fapi_try_exit:
/// @note Called for 1R 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R1T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R1T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1547,7 +1548,7 @@ fapi_try_exit:
/// @note Called for 1R 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R1T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R1T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1584,7 +1585,7 @@ fapi_try_exit:
/// @note Called for 1R 2H 3DS 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R2T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R2T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1615,7 +1616,7 @@ fapi_try_exit:
/// @note Called for 1R 2H 3DS 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R2T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R2T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1648,7 +1649,7 @@ fapi_try_exit:
/// @note Called for 1R 2H 3DS 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R2T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R2T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1681,7 +1682,7 @@ fapi_try_exit:
/// @note Called for 1R 4H 3DS 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R4T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R4T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1718,7 +1719,7 @@ fapi_try_exit:
/// @note Called for 1R 4H 3DS 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R4T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R4T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1751,7 +1752,7 @@ fapi_try_exit:
/// @note Called for 1R 4H 3DS 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R4T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R4T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1784,7 +1785,7 @@ fapi_try_exit:
/// @note Called for 1R 8H 3DS 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R8T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R8T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1819,7 +1820,7 @@ fapi_try_exit:
/// @note Called for 1R 8H 3DS 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R8T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R8T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1852,7 +1853,7 @@ fapi_try_exit:
/// @note Called for 1R 8H 3DS 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R8T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R8T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1885,7 +1886,7 @@ fapi_try_exit:
/// @note Called for 4R 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_4R4T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_4R4T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1920,7 +1921,7 @@ fapi_try_exit:
/// @note Called for 4R 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_4R4T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_4R4T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1953,7 +1954,7 @@ fapi_try_exit:
/// @note Called for 4R 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_4R4T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_4R4T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1983,7 +1984,7 @@ fapi_try_exit:
/// @param[out] fapi2::buffer<uint64_t> io_xlate2 - xlt register 2's value
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode setup_xlate_map_helper( std::vector<dimm::kind>& io_dimm_kinds,
+fapi2::ReturnCode setup_xlate_map_helper( std::vector<dimm::kind<>>& io_dimm_kinds,
fapi2::buffer<uint64_t>& io_xlate0,
fapi2::buffer<uint64_t>& io_xlate1,
fapi2::buffer<uint64_t>& io_xlate2 )
@@ -1999,7 +2000,8 @@ fapi2::ReturnCode setup_xlate_map_helper( std::vector<dimm::kind>& io_dimm_kinds
// However, we need to set that DIMM's D bit in the location of the largest DIMM's D-bit map (I know that's
// hard to grok - set the D bit in the smallest DIMM but in the location mapped for the largest.) So we
// keep track of the largest DIMM so when we set it up, we make sure to set the D-bit in the other.
- std::sort(io_dimm_kinds.begin(), io_dimm_kinds.end(), [](const dimm::kind & a, const dimm::kind & b) -> bool
+ std::sort(io_dimm_kinds.begin(), io_dimm_kinds.end(), [](const dimm::kind<>& a,
+ const dimm::kind<>& b) -> bool
{
return a.iv_size > b.iv_size;
});
@@ -2106,7 +2108,7 @@ fapi2::ReturnCode setup_xlate_map(const fapi2::Target<TARGET_TYPE_MCA>& i_target
const auto l_dimms = mss::find_targets<TARGET_TYPE_DIMM>(i_target);
// We need to keep around specifications of both DIMM as we set the D bit based on the sizes of the DIMM
- std::vector<dimm::kind> l_dimm_kinds = dimm::kind::vector(l_dimms);
+ std::vector<dimm::kind<>> l_dimm_kinds = dimm::kind<>::vector(l_dimms);
FAPI_INF("Setting up xlate registers for MCA%d (%d)", mss::pos(i_target), mss::index(i_target));
@@ -2131,7 +2133,7 @@ fapi_try_exit:
/// @note Called for 1R 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R1T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R1T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2156,7 +2158,7 @@ fapi_try_exit:
/// @note Called for 1R 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R1T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R1T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2181,7 +2183,7 @@ fapi_try_exit:
/// @note Called for 1R 2H 3DS 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R2T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R2T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2206,7 +2208,7 @@ fapi_try_exit:
/// @note Called for 1R 2H 3DS 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R2T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R2T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2231,7 +2233,7 @@ fapi_try_exit:
/// @note Called for 1R 4H 3DS 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R4T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R4T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2256,7 +2258,7 @@ fapi_try_exit:
/// @note Called for 1R 4H 3DS 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R4T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R4T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2281,7 +2283,7 @@ fapi_try_exit:
/// @note Called for 1R 8H 3DS 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R8T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R8T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2306,7 +2308,7 @@ fapi_try_exit:
/// @note Called for 1R 8H 3DS 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R8T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R8T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2331,7 +2333,7 @@ fapi_try_exit:
/// @note Called for 2R 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R2T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R2T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2356,7 +2358,7 @@ fapi_try_exit:
/// @note Called for 2R16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R2T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R2T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2381,7 +2383,7 @@ fapi_try_exit:
/// @note Called for 2R 2H 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R4T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R4T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2406,7 +2408,7 @@ fapi_try_exit:
/// @note Called for 2R 2H 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R4T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R4T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2431,7 +2433,7 @@ fapi_try_exit:
/// @note Called for 2R 4H 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R8T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R8T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2456,7 +2458,7 @@ fapi_try_exit:
/// @note Called for 2R 4H 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R8T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R8T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2481,7 +2483,7 @@ fapi_try_exit:
/// @note Called for 2R 8H 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R16T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R16T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2506,7 +2508,7 @@ fapi_try_exit:
/// @note Called for 2R 8H 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R16T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R16T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2531,7 +2533,7 @@ fapi_try_exit:
/// @note Called for 4R 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_4R4T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_4R4T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2556,7 +2558,7 @@ fapi_try_exit:
/// @note Called for 4R 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_4R4T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_4R4T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2581,7 +2583,7 @@ fapi_try_exit:
/// @note Called for 1R 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R1T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R1T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2609,7 +2611,7 @@ fapi_try_exit:
/// @note Called for 1R 2H 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R2T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R2T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2640,7 +2642,7 @@ fapi_try_exit:
/// @note Called for 1R 4H 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R4T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R4T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2671,7 +2673,7 @@ fapi_try_exit:
/// @note Called for 1R 4H 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R8T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R8T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2702,7 +2704,7 @@ fapi_try_exit:
/// @note Called for 2R 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R2T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R2T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2733,7 +2735,7 @@ fapi_try_exit:
/// @note Called for 2R 2H 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R4T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R4T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2764,7 +2766,7 @@ fapi_try_exit:
/// @note Called for 2R 4H 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R8T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R8T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2795,7 +2797,7 @@ fapi_try_exit:
/// @note Called for 2R 8H 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R16T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R16T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -2826,7 +2828,7 @@ fapi_try_exit:
/// @note Called for 4R 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_4R4T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_4R4T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.H b/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.H
index 9a168c0b5..5b7db7076 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -44,7 +44,7 @@
#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <lib/dimm/kind.H>
+#include <lib/dimm/nimbus_kind.H>
namespace mss
{
@@ -495,8 +495,8 @@ struct xlate_setup
/// @param[in] i_kind a DIMM kind structure representing the ... err... kind of DIMM
/// @param[in] i_func a function pointer to a function which does the configuring
///
- xlate_setup( const dimm::kind i_kind,
- fapi2::ReturnCode (*i_func)( const dimm::kind&, const uint64_t, const bool,
+ xlate_setup( const dimm::kind<> i_kind,
+ fapi2::ReturnCode (*i_func)( const dimm::kind<>&, const uint64_t, const bool,
fapi2::buffer<uint64_t>&, fapi2::buffer<uint64_t>&, fapi2::buffer<uint64_t>& ) ):
iv_kind(i_kind),
iv_func(i_func)
@@ -504,10 +504,10 @@ struct xlate_setup
}
// Keep around the kind of DIMM this nugget represents
- dimm::kind iv_kind;
+ dimm::kind<> iv_kind;
// The function to call to setup the translation registers to setup for our DIMM kind.
- fapi2::ReturnCode (*iv_func)( const dimm::kind&, const uint64_t, const bool,
+ fapi2::ReturnCode (*iv_func)( const dimm::kind<>&, const uint64_t, const bool,
fapi2::buffer<uint64_t>&, fapi2::buffer<uint64_t>&, fapi2::buffer<uint64_t>& );
};
@@ -522,7 +522,7 @@ struct xlate_setup
/// @note Called for 2R4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R2T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R2T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -540,7 +540,7 @@ fapi2::ReturnCode xlate_dimm_2R2T4Gbx4( const dimm::kind& i_kind,
/// @note Called for 2R 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R2T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R2T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -558,7 +558,7 @@ fapi2::ReturnCode xlate_dimm_2R2T8Gbx4( const dimm::kind& i_kind,
/// @note Called for 2R 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R2T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R2T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -576,7 +576,7 @@ fapi2::ReturnCode xlate_dimm_2R2T16Gbx4( const dimm::kind& i_kind,
/// @note Called for 2R 2H 3DS 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R4T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R4T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -594,7 +594,7 @@ fapi2::ReturnCode xlate_dimm_2R4T4Gbx4( const dimm::kind& i_kind,
/// @note Called for 2R 2H 3DS 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R4T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R4T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -612,7 +612,7 @@ fapi2::ReturnCode xlate_dimm_2R4T8Gbx4( const dimm::kind& i_kind,
/// @note Called for 2R 2H 3DS 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R4T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R4T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -630,7 +630,7 @@ fapi2::ReturnCode xlate_dimm_2R4T16Gbx4( const dimm::kind& i_kind,
/// @note Called for 2R 4H 3DS 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R8T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R8T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -648,7 +648,7 @@ fapi2::ReturnCode xlate_dimm_2R8T4Gbx4( const dimm::kind& i_kind,
/// @note Called for 2R 4H 3DS 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R8T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R8T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -666,7 +666,7 @@ fapi2::ReturnCode xlate_dimm_2R8T8Gbx4( const dimm::kind& i_kind,
/// @note Called for 2R 4H 3DS 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R8T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R8T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -684,7 +684,7 @@ fapi2::ReturnCode xlate_dimm_2R8T16Gbx4( const dimm::kind& i_kind,
/// @note Called for 2R 8H 3DS 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R16T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R16T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -702,7 +702,7 @@ fapi2::ReturnCode xlate_dimm_2R16T4Gbx4( const dimm::kind& i_kind,
/// @note Called for 2R 8H 3DS 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R16T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R16T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -719,7 +719,7 @@ fapi2::ReturnCode xlate_dimm_2R16T8Gbx4( const dimm::kind& i_kind,
/// @note Called for 2R 8H 3DS 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R16T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R16T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -737,7 +737,7 @@ fapi2::ReturnCode xlate_dimm_2R16T16Gbx4( const dimm::kind& i_kind,
/// @note Called for 1R 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R1T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R1T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -754,7 +754,7 @@ fapi2::ReturnCode xlate_dimm_1R1T4Gbx4( const dimm::kind& i_kind,
/// @note Called for 1R 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R1T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R1T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -772,7 +772,7 @@ fapi2::ReturnCode xlate_dimm_1R1T8Gbx4( const dimm::kind& i_kind,
/// @note Called for 1R 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R1T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R1T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -790,7 +790,7 @@ fapi2::ReturnCode xlate_dimm_1R1T16Gbx4( const dimm::kind& i_kind,
/// @note Called for 1R 2H 3DS 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R2T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R2T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -808,7 +808,7 @@ fapi2::ReturnCode xlate_dimm_1R2T4Gbx4( const dimm::kind& i_kind,
/// @note Called for 1R 2H 3DS 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R2T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R2T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -826,7 +826,7 @@ fapi2::ReturnCode xlate_dimm_1R2T8Gbx4( const dimm::kind& i_kind,
/// @note Called for 1R 2H 3DS 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R2T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R2T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -844,7 +844,7 @@ fapi2::ReturnCode xlate_dimm_1R2T16Gbx4( const dimm::kind& i_kind,
/// @note Called for 1R 4H 3DS 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R4T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R4T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -862,7 +862,7 @@ fapi2::ReturnCode xlate_dimm_1R4T4Gbx4( const dimm::kind& i_kind,
/// @note Called for 1R 4H 3DS 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R4T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R4T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -880,7 +880,7 @@ fapi2::ReturnCode xlate_dimm_1R4T8Gbx4( const dimm::kind& i_kind,
/// @note Called for 1R 4H 3DS 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R4T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R4T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -898,7 +898,7 @@ fapi2::ReturnCode xlate_dimm_1R4T16Gbx4( const dimm::kind& i_kind,
/// @note Called for 1R 8H 3DS 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R8T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R8T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -915,7 +915,7 @@ fapi2::ReturnCode xlate_dimm_1R8T4Gbx4( const dimm::kind& i_kind,
/// @note Called for 1R 8H 3DS 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R8T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R8T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -933,7 +933,7 @@ fapi2::ReturnCode xlate_dimm_1R8T8Gbx4( const dimm::kind& i_kind,
/// @note Called for 1R 8H 3DS 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R8T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R8T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -951,7 +951,7 @@ fapi2::ReturnCode xlate_dimm_1R8T16Gbx4( const dimm::kind& i_kind,
/// @note Called for 4R 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_4R4T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_4R4T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -968,7 +968,7 @@ fapi2::ReturnCode xlate_dimm_4R4T4Gbx4( const dimm::kind& i_kind,
/// @note Called for 4R 8Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_4R4T8Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_4R4T8Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -985,7 +985,7 @@ fapi2::ReturnCode xlate_dimm_4R4T8Gbx4( const dimm::kind& i_kind,
/// @note Called for 4R 16Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_4R4T16Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_4R4T16Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1000,7 +1000,7 @@ fapi2::ReturnCode xlate_dimm_4R4T16Gbx4( const dimm::kind& i_kind,
/// @param[out] fapi2::buffer<uint64_t> o_xlate2 - xlt register 2's value
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode setup_xlate_map_helper( std::vector<dimm::kind>& i_dimm_kinds,
+fapi2::ReturnCode setup_xlate_map_helper( std::vector<dimm::kind<>>& i_dimm_kinds,
fapi2::buffer<uint64_t>& o_xlate0,
fapi2::buffer<uint64_t>& io_xlate1,
fapi2::buffer<uint64_t>& io_xlate2 );
@@ -1016,7 +1016,7 @@ fapi2::ReturnCode setup_xlate_map_helper( std::vector<dimm::kind>& i_dimm_kinds,
/// @note Called for 1R4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R1T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R1T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1034,7 +1034,7 @@ fapi2::ReturnCode xlate_dimm_1R1T4Gbx4( const dimm::kind& i_kind,
/// @note Called for 1R 2 total ranks 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R2T4Gbx4( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R2T4Gbx4( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1052,7 +1052,7 @@ fapi2::ReturnCode xlate_dimm_1R2T4Gbx4( const dimm::kind& i_kind,
/// @note Called for 1R 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R1T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R1T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1070,7 +1070,7 @@ fapi2::ReturnCode xlate_dimm_1R1T8Gbx8( const dimm::kind& i_kind,
/// @note Called for 1R 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R1T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R1T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1088,7 +1088,7 @@ fapi2::ReturnCode xlate_dimm_1R1T16Gbx8( const dimm::kind& i_kind,
/// @note Called for 1R 2H 3DS 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R2T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R2T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1106,7 +1106,7 @@ fapi2::ReturnCode xlate_dimm_1R2T8Gbx8( const dimm::kind& i_kind,
/// @note Called for 1R 2H 3DS 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R2T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R2T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1124,7 +1124,7 @@ fapi2::ReturnCode xlate_dimm_1R2T16Gbx8( const dimm::kind& i_kind,
/// @note Called for 1R 4H 3DS 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R4T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R4T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1142,7 +1142,7 @@ fapi2::ReturnCode xlate_dimm_1R4T8Gbx8( const dimm::kind& i_kind,
/// @note Called for 1R 4H 3DS 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R4T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R4T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1160,7 +1160,7 @@ fapi2::ReturnCode xlate_dimm_1R4T16Gbx8( const dimm::kind& i_kind,
/// @note Called for 1R 8H 3DS 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R8T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R8T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1177,7 +1177,7 @@ fapi2::ReturnCode xlate_dimm_1R8T8Gbx8( const dimm::kind& i_kind,
/// @note Called for 1R 8H 3DS 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R8T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R8T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1195,7 +1195,7 @@ fapi2::ReturnCode xlate_dimm_1R8T16Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R2T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R2T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1213,7 +1213,7 @@ fapi2::ReturnCode xlate_dimm_2R2T8Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R2T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R2T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1231,7 +1231,7 @@ fapi2::ReturnCode xlate_dimm_2R2T16Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R 2H 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R4T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R4T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1249,7 +1249,7 @@ fapi2::ReturnCode xlate_dimm_2R4T8Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R 2H 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R4T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R4T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1267,7 +1267,7 @@ fapi2::ReturnCode xlate_dimm_2R4T16Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R 4H 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R8T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R8T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1285,7 +1285,7 @@ fapi2::ReturnCode xlate_dimm_2R8T8Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R 4H 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R8T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R8T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1303,7 +1303,7 @@ fapi2::ReturnCode xlate_dimm_2R8T16Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R 8H 8Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R16T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R16T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1321,7 +1321,7 @@ fapi2::ReturnCode xlate_dimm_2R16T8Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R 8H 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R16T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R16T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1339,7 +1339,7 @@ fapi2::ReturnCode xlate_dimm_2R16T16Gbx8( const dimm::kind& i_kind,
/// @note Called for 4R 4Gbx4 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_4R4T8Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_4R4T8Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1357,7 +1357,7 @@ fapi2::ReturnCode xlate_dimm_4R4T8Gbx8( const dimm::kind& i_kind,
/// @note Called for 4R 16Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_4R4T16Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_4R4T16Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1375,7 +1375,7 @@ fapi2::ReturnCode xlate_dimm_4R4T16Gbx8( const dimm::kind& i_kind,
/// @note Called for 1R 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R1T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R1T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1393,7 +1393,7 @@ fapi2::ReturnCode xlate_dimm_1R1T4Gbx8( const dimm::kind& i_kind,
/// @note Called for 1R 2H 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R2T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R2T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1411,7 +1411,7 @@ fapi2::ReturnCode xlate_dimm_1R2T4Gbx8( const dimm::kind& i_kind,
/// @note Called for 1R 4H 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R4T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R4T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1429,7 +1429,7 @@ fapi2::ReturnCode xlate_dimm_1R4T4Gbx8( const dimm::kind& i_kind,
/// @note Called for 1R 4H 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_1R8T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_1R8T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1447,7 +1447,7 @@ fapi2::ReturnCode xlate_dimm_1R8T4Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R2T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R2T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1465,7 +1465,7 @@ fapi2::ReturnCode xlate_dimm_2R2T4Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R2T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R2T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1483,7 +1483,7 @@ fapi2::ReturnCode xlate_dimm_2R2T4Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R 2H 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R4T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R4T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1501,7 +1501,7 @@ fapi2::ReturnCode xlate_dimm_2R4T4Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R 2H 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R4T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R4T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1519,7 +1519,7 @@ fapi2::ReturnCode xlate_dimm_2R4T4Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R 4H 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R8T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R8T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1537,7 +1537,7 @@ fapi2::ReturnCode xlate_dimm_2R8T4Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R 4H 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R8T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R8T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1555,7 +1555,7 @@ fapi2::ReturnCode xlate_dimm_2R8T4Gbx8( const dimm::kind& i_kind,
/// @note Called for 2R 8H 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_2R16T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_2R16T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
@@ -1573,7 +1573,7 @@ fapi2::ReturnCode xlate_dimm_2R16T4Gbx8( const dimm::kind& i_kind,
/// @note Called for 4R 4Gbx8 DDR4 RDIMM
/// @return FAPI2_RC_SUCCESS iff okay
///
-fapi2::ReturnCode xlate_dimm_4R4T4Gbx8( const dimm::kind& i_kind,
+fapi2::ReturnCode xlate_dimm_4R4T4Gbx8( const dimm::kind<>& i_kind,
const uint64_t i_offset,
const bool i_largest,
fapi2::buffer<uint64_t>& io_xlate0,
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/address.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/address.H
index 3a7a4ee2c..fcfd9a3e4 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/address.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/address.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,489 +38,13 @@
#include <fapi2.H>
#include <utility>
-#include <lib/ecc/ecc_traits.H>
-
-namespace mss
-{
-
-namespace ecc
-{
-
-namespace fwms
-{
-
-///
-/// @class address
-/// @brief Converts Firmware Mark Store ADDRESS field into mcbist::address
-/// @tparam T fapi2 Target Type defaults to fapi2::TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @note template argument defaults are in forward declaration in lib/mcbist/address.H
-/// @note 12 = dimm
-/// @note 13:14 = mrank
-/// @note 15:17 = srank
-/// @note 18:19 = bank group
-/// @note 20:22 = bank
-///
-// See declaration below
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-class address;
-
-} // close namespace fwms
-} // close namespace ecc
-
-namespace mcbist
-{
-
-///
-/// @class address
-/// @brief Represents a physical address in memory
-/// @note
-/// 0:1 port select
-/// 2 dimm select
-/// 3:4 mrank(0 to 1)
-/// 5:7 srank(0 to 2)
-/// 8:25 row(0 to 17)
-/// 26:32 col(3 to 9)
-/// 33:35 bank(0 to 2)
-/// 36:37 bank_group(0 to 1)
-///
-class address
-{
- private:
- // How far over we shift to align the address in either the register or a buffer
- enum { MAGIC_PAD = 26 };
-
- public:
-
- // first is the start bit of the field, second is the length
- typedef std::pair<uint64_t, uint64_t> field;
-
- constexpr static field PORT = {0, 2};
- constexpr static field DIMM = {2, 1};
- constexpr static field MRANK = {3, 2};
- constexpr static field SRANK = {5, 3};
- constexpr static field ROW = {8, 18};
- constexpr static field COL = {26, 7};
- constexpr static field BANK = {33, 3};
- constexpr static field BANK_GROUP = {36, 2};
- constexpr static field LAST_VALID = BANK_GROUP;
-
- address() = default;
-
- static constexpr uint64_t LARGEST_ADDRESS = ~0 >> MAGIC_PAD;
-
- // Used when accessing an integral value containing a port and DIMM combination
- static constexpr uint64_t DIMM_BIT = 63;
- static constexpr uint64_t PORT_START = 61;
- static constexpr uint64_t PORT_LEN = 2;
-
- ///
- /// @brief Construct an address from a uint64_t (scom'ed value)
- /// @param[in] i_value representing an address; say from a trap register
- ///
- /// @note This assumes input has the same bit layout as this address
- /// structure, and this is presently not the case for the trap registers (3/16).
- /// These are presently unused, however. There is an open defect against the
- /// design team to correct this.
- /// @warn Assumes right-aligned value; bit 63 is shifted to represent the Bank Group
- address( const uint64_t i_value ):
- iv_address(i_value << MAGIC_PAD)
- {
- }
-
- ///
- /// @brief Construct an address from an ecc::fwms::address
- /// @tparam T fapi2 Target Type
- /// @param[in] i_address representing an address field from a firmware mark store register
- ///
- template< fapi2::TargetType T >
- address( const ecc::fwms::address<T>& i_address )
- {
- fapi2::buffer<uint64_t> l_value = uint64_t(i_address);
- uint64_t l_temp = 0;
- l_value.extractToRight<ecc::fwms::address<T>::DIMM.first, ecc::fwms::address<T>::DIMM.second>(l_temp);
- this->set_field<DIMM>(l_temp);
- l_value.extractToRight<ecc::fwms::address<T>::MRANK.first, ecc::fwms::address<T>::MRANK.second>(l_temp);
- this->set_field<MRANK>(l_temp);
- l_value.extractToRight<ecc::fwms::address<T>::SRANK.first, ecc::fwms::address<T>::SRANK.second>(l_temp);
- this->set_field<SRANK>(l_temp);
- l_value.extractToRight<ecc::fwms::address<T>::BANK_GROUP.first, ecc::fwms::address<T>::BANK_GROUP.second>(l_temp);
- this->set_field<BANK_GROUP>(l_temp);
- l_value.extractToRight<ecc::fwms::address<T>::BANK.first, ecc::fwms::address<T>::BANK.second>(l_temp);
- this->set_field<BANK>(l_temp);
- }
-
- ///
- /// @brief Conversion operator to uint64_t
- /// @warn Right-aligns the address
- ///
- inline operator uint64_t() const
- {
- return iv_address >> MAGIC_PAD;
- }
-
- ///
- /// @brief Set a field for an address
- /// @tparam F the field to set
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- ///
- template< const field& F >
- inline address& set_field( const uint64_t i_value )
- {
- iv_address.insertFromRight<F.first, F.second>(i_value);
- return *this;
- }
-
- ///
- /// @brief Get a field from an address
- /// @tparam F the field to get
- /// @return right-aligned uint64_t representing the value
- ///
- template< const field& F >
- inline uint64_t get_field() const
- {
- uint64_t l_value = 0;
- iv_address.extractToRight<F.first, F.second>(l_value);
- return l_value;
- }
-
- ///
- /// @brief Get a range of addresses.
- /// @tparam[in] F the left-most valid field. So, if the address was for master rank,
- /// the left-most valid field would be MRANK
- /// @param[out] o_end representing an address to end at
- /// @note this pointer is the start address
- ///
- template< const field& F >
- inline void get_range( address& o_end ) const
- {
- constexpr uint64_t START = F.first + F.second;
- constexpr uint64_t LEN = (LAST_VALID.first + LAST_VALID.second) - START;
-
- // All we need to do is fill in the bits to the right of the last valid field
- o_end.iv_address = iv_address;
- o_end.iv_address.setBit<START, LEN>();
- }
-
-
- ///
- /// @brief Get an end address for sim mode
- /// @param[out] o_end representing an address to end at
- /// @note this pointer is the start address
- ///
- inline void get_sim_end_address( address& o_end ) const
- {
- // This magic number represents a range of addresses which cover all
- // cache lines the training algorithms touch. By effecting 0 - this end
- // address you'll effect everything which has bad ECC in the sim.
- constexpr uint64_t l_magic_sim_number = 0b1000000;
-
- get_range<COL>(o_end);
- o_end.set_column(l_magic_sim_number);
- return;
- }
-
- ///
- /// @brief Get a range of addresses given a master rank
- /// @param[in] i_start representing an address to start from
- /// @param[out] o_end representing an address to end at
- ///
- inline static void get_mrank_range( const address& i_start, address& o_end )
- {
- i_start.get_range<MRANK>(o_end);
- }
-
- ///
- /// @brief Get a range of addresses given a master rank
- /// @param[in] i_port representing the port for the starting address
- /// @param[in] i_dimm representing the dimm for the starting address
- /// @param[in] i_mrank representing the master rank for the starting address
- /// @param[out] o_start representing an address to start from
- /// @param[out] o_end representing an address to end at
- ///
- inline static void get_mrank_range( const uint64_t i_port, const uint64_t i_dimm, const uint64_t i_mrank,
- address& o_start, address& o_end )
- {
- o_start.set_port(i_port).set_dimm(i_dimm).set_master_rank(i_mrank);
- get_mrank_range(o_start, o_end);
- }
-
- ///
- /// @brief Get a range of addresses given a slave rank
- /// @param[in] i_start representing an address to start from
- /// @param[out] o_end representing an address to end at
- ///
- inline static void get_srank_range( const address& i_start, address& o_end )
- {
- i_start.get_range<SRANK>(o_end);
- }
-
- ///
- /// @brief Get a range of addresses given a slave rank
- /// @param[in] i_port representing the port for the starting address
- /// @param[in] i_dimm representing the dimm for the starting address
- /// @param[in] i_mrank representing the master rank for the starting address
- /// @param[in] i_srank representing the slave rank for the starting address
- /// @param[out] o_start representing an address to start from
- /// @param[out] o_end representing an address to end at
- ///
- inline static void get_srank_range( const uint64_t i_port, const uint64_t i_dimm,
- const uint64_t i_mrank, const uint64_t i_srank,
- address& o_start, address& o_end )
- {
- o_start.set_port(i_port).set_dimm(i_dimm).set_master_rank(i_mrank).set_slave_rank(i_srank);
- get_srank_range(o_start, o_end);
- }
-
- ///
- /// @brief Set the port value for an address
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- ///
- inline address& set_port( const uint64_t i_value )
- {
- return set_field<PORT>(i_value);
- }
-
- ///
- /// @brief Get the port value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_port() const
- {
- return get_field<PORT>();
- }
-
- ///
- /// @brief Set the DIMM value for an address
- /// @param[in] i_value the value to set
- /// @note 0 is the DIMM[0] != 0 is DIMM[1]
- /// @return address& for method chaining
- ///
- inline address& set_dimm( const uint64_t i_value )
- {
- return set_field<DIMM>(i_value);
- }
-
- ///
- /// @brief Get the DIMM value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_dimm() const
- {
- return get_field<DIMM>();
- }
-
- ///
- /// @brief Set the port and DIMM value for an address
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- /// @note Useful for indexing all ports/DIMM on a controller
- ///
- inline address& set_port_dimm( const fapi2::buffer<uint64_t> i_value )
- {
- uint64_t l_read_port = 0;
-
- i_value.extractToRight<PORT_START, PORT_LEN>(l_read_port);
- return set_dimm(i_value.getBit<DIMM_BIT>()).set_port(l_read_port);
- }
-
- ///
- /// @brief Get the port and DIMM value for an address
- /// @return right-aligned uint64_t representing the value
- /// @note Useful for indexing all ports/DIMM on a controller
- ///
- inline uint64_t get_port_dimm() const
- {
- fapi2::buffer<uint64_t> l_value;
-
- l_value.insertFromRight<PORT_START, PORT_LEN>(get_port());
- l_value.writeBit<DIMM_BIT>(get_dimm());
-
- return l_value;
- }
-
- ///
- /// @brief Set the master rank value for an address
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- ///
- inline address& set_master_rank( const uint64_t i_value )
- {
- return set_field<MRANK>(i_value);
- }
-
- ///
- /// @brief Get the master rank value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_master_rank() const
- {
- return get_field<MRANK>();
- }
-
-
- ///
- /// @brief Set the slave rank value for an address
- /// @param[in] i_value the value to set
- ///
- inline void set_slave_rank( const uint64_t i_value )
- {
- set_field<SRANK>(i_value);
- }
-
- ///
- /// @brief Get the slave rank value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_slave_rank() const
- {
- return get_field<SRANK>();
- }
-
-
- ///
- /// @brief Set the row value for an address
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- ///
- inline address& set_row( const uint64_t i_value )
- {
- return set_field<ROW>(i_value);
- }
-
- ///
- /// @brief Get the row value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_row() const
- {
- return get_field<ROW>();
- }
-
-
- ///
- /// @brief Set the column value for an address
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- ///
- inline address& set_column( const uint64_t i_value )
- {
- return set_field<COL>(i_value);
- }
-
- ///
- /// @brief Get the column value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_column() const
- {
- return get_field<COL>();
- }
-
-
- ///
- /// @brief Set the bank value for an address
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- ///
- inline address& set_bank( const uint64_t i_value )
- {
- return set_field<BANK>(i_value);
- }
-
- ///
- /// @brief Get the bank value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_bank() const
- {
- return get_field<BANK>();
- }
-
- ///
- /// @brief Set the bank group value for an address
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- ///
- inline address& set_bank_group( const uint64_t i_value )
- {
- return set_field<BANK_GROUP>(i_value);
- }
-
- ///
- /// @brief Get the bank group value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_bank_group() const
- {
- return get_field<BANK_GROUP>();
- }
-
- private:
- // We use a fapi2 buffer as it has static compile-time support
- fapi2::buffer<uint64_t> iv_address;
-};
-
-} // close namespace mcbist
-
-// Documented above in its declaration.
-template< fapi2::TargetType T, typename TT >
-class ecc::fwms::address
-{
- public:
- // first is the start bit of the field, second is the length
- typedef std::pair<uint64_t, uint64_t> field;
-
- constexpr static field DIMM = {TT::FIRMWARE_MS_ADDRESS, 1};
- constexpr static field MRANK = {TT::FIRMWARE_MS_ADDRESS + 1, 2};
- constexpr static field SRANK = {TT::FIRMWARE_MS_ADDRESS + 3, 3};
- constexpr static field BANK_GROUP = {TT::FIRMWARE_MS_ADDRESS + 6, 2};
- constexpr static field BANK = {TT::FIRMWARE_MS_ADDRESS + 8, 3};
- constexpr static field LAST_VALID = BANK;
-
- address() = default;
-
- ///
- /// @brief Construct an address from a uint64_t (scom'ed value)
- /// @param[in] i_value representing raw value from FWMS register
- ///
- address( const uint64_t& i_value ):
- iv_value(i_value)
- {
- }
-
- ///
- /// @brief Construct an address from an mcbist::address
- /// @param[in] i_mcbist_address mcbist formatted address
- /// @note Construction of mcbist::address from ecc::fwms::address
- /// @note located in mcbist::address class
- ///
- address( const mcbist::address& i_mcbist_address )
- {
- iv_value.insertFromRight<DIMM.first, DIMM.second>(i_mcbist_address.get_field<mcbist::address::DIMM>());
- iv_value.insertFromRight<MRANK.first, MRANK.second>(i_mcbist_address.get_field<mcbist::address::MRANK>());
- iv_value.insertFromRight<SRANK.first, SRANK.second>(i_mcbist_address.get_field<mcbist::address::SRANK>());
- iv_value.insertFromRight<BANK_GROUP.first, BANK_GROUP.second>
- (i_mcbist_address.get_field<mcbist::address::BANK_GROUP>());
- iv_value.insertFromRight<BANK.first, BANK.second>(i_mcbist_address.get_field<mcbist::address::BANK>());
- }
-
- ///
- /// @brief Conversion operator to uint64_t
- ///
- inline operator uint64_t() const
- {
- uint64_t l_temp = 0;
- iv_value.extract<TT::FIRMWARE_MS_ADDRESS, TT::FIRMWARE_MS_ADDRESS_LEN, TT::FIRMWARE_MS_ADDRESS>(l_temp);
- return l_temp;
- }
-
- private:
- fapi2::buffer<uint64_t> iv_value;
-};
-
-} // close namespace mss
+#include <lib/shared/mss_const.H>
+#include <lib/ecc/ecc_traits_nimbus.H>
+#include <lib/mcbist/mcbist_traits.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_ecc_trap_address.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_fwms_address.H>
+
+// This file is still necessary to put traits and generic code together
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C
index f5ef0e24c..f002b31e9 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C
@@ -35,8 +35,8 @@
#include <lib/shared/nimbus_defaults.H>
#include <fapi2.H>
+#include <lib/mss_attribute_accessors.H>
#include <lib/mcbist/mcbist.H>
-#include <lib/utils/dump_regs.H>
#include <lib/workarounds/mcbist_workarounds.H>
#include <generic/memory/lib/utils/pos.H>
@@ -47,7 +47,22 @@ using fapi2::TARGET_TYPE_MCS;
namespace mss
{
-const std::pair<uint64_t, uint64_t> mcbistTraits<fapi2::TARGET_TYPE_MCBIST>::address_pairs[] =
+///
+/// @brief Gets the attribute for freq
+/// @param[in] const ref to the target
+/// @param[out] uint64_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Frequency of this memory channel in MT/s (Mega Transfers per second)
+///
+template<>
+fapi2::ReturnCode freq<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCBIST>(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>&
+ i_target, uint64_t& o_value)
+{
+ return mss::freq(i_target, o_value);
+}
+
+const std::pair<uint64_t, uint64_t> mcbistTraits<>::address_pairs[] =
{
{ START_ADDRESS_0, END_ADDRESS_0 },
{ START_ADDRESS_1, END_ADDRESS_1 },
@@ -55,7 +70,7 @@ const std::pair<uint64_t, uint64_t> mcbistTraits<fapi2::TARGET_TYPE_MCBIST>::add
{ START_ADDRESS_3, END_ADDRESS_3 },
};
-const std::vector< mss::mcbist::op_type > mcbistTraits<fapi2::TARGET_TYPE_MCBIST>::FIFO_MODE_REQUIRED_OP_TYPES =
+const std::vector< mss::mcbist::op_type > mcbistTraits<>::FIFO_MODE_REQUIRED_OP_TYPES =
{
mss::mcbist::op_type::WRITE ,
mss::mcbist::op_type::READ ,
@@ -67,463 +82,63 @@ const std::vector< mss::mcbist::op_type > mcbistTraits<fapi2::TARGET_TYPE_MCBIST
mss::mcbist::op_type::READ_READ_WRITE ,
};
-namespace mcbist
-{
-
-///
-/// @brief Load MCBIST maint pattern given a pattern
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_pattern an mcbist::patterns
-/// @param[in] i_invert whether to invert the pattern or not
-/// @note this overload disappears when we have real patterns.
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< >
-fapi2::ReturnCode load_maint_pattern( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const pattern& i_pattern,
- const bool i_invert )
+// These valus are pulled out of the MCBIST specification
+// The index is the fixed width - the value is the LFSR_MASK value to be used
+const std::vector< uint64_t > mcbistTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCBIST>::LFSR_MASK_VALUES =
{
- // Init the fapi2 return code
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- // Array access control
- fapi2::buffer<uint64_t> l_aacr;
- // Array access data
- fapi2::buffer<uint64_t> l_aadr;
-
- // first we must setup the access control register
- // Setup the array address
- // enable the auto increment bit
- // set ecc mode bit on
- l_aacr
- .writeBit<MCA_WREITE_AACR_BUFFER>(mss::states::OFF)
- .insertFromRight<MCA_WREITE_AACR_ADDRESS, MCA_WREITE_AACR_ADDRESS_LEN>(mss::mcbist::rmw_address::DW0)
- .writeBit<MCA_WREITE_AACR_AUTOINC>(mss::states::ON)
- .writeBit<MCA_WREITE_AACR_ECCGEN>(mss::states::ON);
-
- // This loop will be run twice to write the pattern twice. Once per 64B write.
- // When MCBIST maint mode is in 64B mode it will only use the first 64B when in 128B mode
- // MCBIST maint will use all 128B (it will perform two consecutive writes)
- const auto l_ports = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target);
- // Init the port map
-
- for (const auto& p : l_ports)
- {
- l_aacr.insertFromRight<MCA_WREITE_AACR_ADDRESS, MCA_WREITE_AACR_ADDRESS_LEN>(mss::mcbist::rmw_address::DW0);
-
- for (auto l_num_reads = 0; l_num_reads < 2; ++l_num_reads)
- {
- FAPI_INF("Setting the array access control register.");
- FAPI_TRY( mss::putScom(p, MCA_WREITE_AACR, l_aacr) );
-
- for (const auto& l_cache_line : i_pattern)
- {
- fapi2::buffer<uint64_t> l_value_first = i_invert ? ~l_cache_line.first : l_cache_line.first;
- fapi2::buffer<uint64_t> l_value_second = i_invert ? ~l_cache_line.second : l_cache_line.second;
- FAPI_INF("Loading cache line pattern 0x%016lx 0x%016lx", l_value_first, l_value_second);
- FAPI_TRY( mss::putScom(p, MCA_AADR, l_value_first) );
-
- // In order for the data to actually be written into the RMW buffer, we must issue a putscom to the MCA_AAER register
- // This register is used for the ECC, we will just write all zero to this register. The ECC will be auto generated
- // when the aacr MCA_WREITE_AACR_ECCGEN bit is set
- FAPI_TRY( mss::putScom(p, MCA_AAER, 0) );
-
- // No need to increment the address because the logic does it automatically when MCA_WREITE_AACR_AUTOINC is set
- FAPI_TRY( mss::putScom(p, MCA_AADR, l_value_second) );
-
- // In order for the data to actually be written into the RMW buffer, we must issue a putscom to the MCA_AAER register
- // This register is used for the ECC, we will just write all zero to this register. The ECC will be auto generated
- // when the aacr MCA_WREITE_AACR_ECCGEN bit is set
- FAPI_TRY( mss::putScom(p, MCA_AAER, 0) );
- }
-
- l_aacr.insertFromRight<MCA_WREITE_AACR_ADDRESS, MCA_WREITE_AACR_ADDRESS_LEN>(mss::mcbist::rmw_address::DW8);
- }
- }
-
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load MCBIST data compare mask registers
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< >
-fapi2::ReturnCode load_data_compare_mask( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const mcbist::program<TARGET_TYPE_MCBIST>& i_program )
-{
- typedef mcbistTraits<TARGET_TYPE_MCBIST> TT;
-
- // Init the fapi2 return code
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- // Load the MCBCM Data compare masks
-
- const auto l_ports = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target);
- FAPI_INF("Loading the MCBIST data compare mask registers!");
-
- for (const auto& p : l_ports)
- {
- FAPI_TRY( mss::putScom(p, TT::COMPARE_MASK, i_program.iv_compare_mask) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Load MCBIST 24b random data seeds given a pattern index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_random24_data_seed mcbist::random24_data_seed
-/// @param[in] i_random24_map mcbist::random24_seed_map
-/// @param[in] i_invert whether to invert the pattern or not
-/// @note this overload disappears when we have real patterns.
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< >
-fapi2::ReturnCode load_random24b_seeds( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const random24_data_seed& i_random24_data_seed,
- const random24_seed_map& i_random24_map,
- const bool i_invert )
-{
- // Init the fapi2 return code
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- const uint64_t l_random_addr0 = MCBIST_MCBRDS0Q;
- const uint64_t l_random_addr1 = MCBIST_MCBRDS1Q;
- uint64_t l_index = 0;
- uint64_t l_map_index = 0;
- uint64_t l_map_offset = 0;
-
- fapi2::buffer<uint64_t> l_mcbrsd0q;
- fapi2::buffer<uint64_t> l_mcbrsd1q;
-
-
- // We are going to loop through the random seeds and load them into the random seed registers
- // Because the 24b random data seeds share the same registers as the 24b random data byte LFSR maps
- // we will load those as well
-
- for (const auto& l_seed : i_random24_data_seed)
- {
- FAPI_INF("Loading 24b random seed index %ld ", l_index);
- fapi2::buffer<uint64_t> l_value = i_invert ? ~l_seed : l_seed;
-
- // Print an informational message to indicate if a random seed is 0
- // TK Do we want an error here? 0 may be used on purpose to hold a byte at all 0 on purpose
- if ( l_value == 0 )
- {
- FAPI_INF("Warning: Random 24b data seed is set to 0 for seed index %d", l_index);
- }
-
- // If we are processing the first 24b random data seed we will add it to the fapi buffer
- // we won't load it yet because the second 24b seed will be loaded into the same register
- if ( l_index == 0 )
- {
- l_mcbrsd0q.insertFromRight<MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0, MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0_LEN>(l_value);
- }
- // The second 24b random data seed is loaded into the same register as the first seed
- // therefore we will add the second seed tothe fapi buffer and then issue the putscom
- else if (l_index == 1 )
- {
- l_mcbrsd0q.insertFromRight<MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1, MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1_LEN>(l_value);
- FAPI_INF("Loading 24b random seeds 0 and 1 0x%016lx ", l_mcbrsd0q);
- FAPI_TRY( mss::putScom(i_target, l_random_addr0, l_mcbrsd0q) );
- }
- // The third 24b random data seed occupies the same register as the random data byte maps. Therefore we first
- // add the third random 24b data seed to the register and then loop through all of the byte mappings a total of
- // 9. ach of the byte mappings associates a byte of the random data to a byte in the 24b random data LFSRs
- // Each byte map is offset by 4 bits in the register.
- else
- {
- l_mcbrsd1q.insertFromRight<MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2, MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2_LEN>(l_value);
-
- for (const auto& l_map : i_random24_map)
- {
- l_map_offset = MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING + (l_map_index * RANDOM24_SEED_MAP_FIELD_LEN);
- l_mcbrsd1q.insertFromRight(l_map, l_map_offset, RANDOM24_SEED_MAP_FIELD_LEN);
- FAPI_INF("Loading 24b random seed map index %ld ", l_map_index);
- FAPI_ASSERT( l_map_index < mss::mcbist::MAX_NUM_RANDOM24_MAPS,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(l_map_index),
- "Attempting to load a 24b random data seed map which does not exist %d", l_map_index );
- ++l_map_index;
- }
-
- FAPI_TRY( mss::putScom(i_target, l_random_addr1, l_mcbrsd1q) );
- }
-
- FAPI_ASSERT( l_index < MAX_NUM_RANDOM24_SEEDS,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(l_index),
- "Attempting to load a 24b random data seed which does not exist %d", l_index );
- ++l_index;
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load a set of MCBIST subtests in to the MCBIST registers
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] the target to effect
-/// @param[in] the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note assumes the MCBIST engine has been configured.
-///
-template<>
-fapi2::ReturnCode load_mcbmr( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const mcbist::program<TARGET_TYPE_MCBIST>& i_program )
-{
-
- // Leave if there are no subtests.
- if (0 == i_program.iv_subtests.size())
- {
- FAPI_INF("no subtests, nothing to do");
- return fapi2::current_err;
- }
-
- // List of the 8 MCBIST registers - each holds 4 subtests.
- static const std::vector< uint64_t > l_memory_registers =
- {
- MCBIST_MCBMR0Q, MCBIST_MCBMR1Q, MCBIST_MCBMR2Q, MCBIST_MCBMR3Q,
- MCBIST_MCBMR4Q, MCBIST_MCBMR5Q, MCBIST_MCBMR6Q, MCBIST_MCBMR7Q,
- };
-
- std::vector< uint64_t > l_memory_register_buffers =
- {
- 0, 0, 0, 0, 0, 0, 0, 0,
- };
-
- static const size_t SUBTEST_PER_REG = 4;
- static const size_t SUBTEST_PER_PROGRAM = 32;
-
- static const auto BITS_IN_SUBTEST = sizeof(mcbist::subtest_t<TARGET_TYPE_MCBIST>().iv_mcbmr) * 8;
- static const auto LEFT_SHIFT = (sizeof(uint64_t) * 8) - BITS_IN_SUBTEST;
-
- ssize_t l_bin = -1;
- size_t l_register_shift = 0;
-
- // We'll shift this in to position to indicate which subtest is the last
- static const uint64_t l_done_bit( 0x8000000000000000 >> MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DONE );
-
- // TK: For now limit MCBIST programs to 32 subtests.
- const auto l_program_size = i_program.iv_subtests.size();
- FAPI_ASSERT( l_program_size <= SUBTEST_PER_PROGRAM,
- fapi2::MSS_MCBIST_PROGRAM_TOO_BIG().set_PROGRAM_LENGTH(l_program_size),
- "mcbist program of length %d exceeds arbitrary maximum of %d", l_program_size, SUBTEST_PER_PROGRAM );
-
- // Distribute the program over the 8 MCBIST subtest registers
- // We need the index, so increment thru i_program.iv_subtests.size()
- for (size_t l_index = 0; l_index < l_program_size; ++l_index)
- {
- l_bin = (l_index % SUBTEST_PER_REG) == 0 ? l_bin + 1 : l_bin;
- l_register_shift = (l_index % SUBTEST_PER_REG) * BITS_IN_SUBTEST;
-
- l_memory_register_buffers[l_bin] |=
- (uint64_t(i_program.iv_subtests[l_index].iv_mcbmr) << LEFT_SHIFT) >> l_register_shift;
-
- FAPI_DBG("putting subtest %d (0x%x) in MCBMR%dQ shifted %d 0x%016llx",
- l_index, i_program.iv_subtests[l_index].iv_mcbmr, l_bin,
- l_register_shift, l_memory_register_buffers[l_bin]);
- }
-
- // l_bin and l_register_shift are the values for the last subtest we'll tell the MCBIST about.
- // We need to set that subtest's done-bit so the MCBIST knows it's the end of the line
- l_memory_register_buffers[l_bin] |= l_done_bit >> l_register_shift;
- FAPI_DBG("setting MCBMR%dQ subtest %llu as the last subtest 0x%016llx",
- l_bin, l_register_shift, l_memory_register_buffers[l_bin]);
-
- // ... and slam the values in to the registers.
- // Could just decrement l_bin, but that scoms the subtests in backwards and is confusing
- for (auto l_index = 0; l_index <= l_bin; ++l_index)
- {
- FAPI_TRY( mss::putScom(i_target, l_memory_registers[l_index], l_memory_register_buffers[l_index]) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Poll the mcbist engine and check for errors
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program, the mcbist program which is executing
-/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode poll( const fapi2::Target<T>& i_target, const program<T>& i_program )
-{
- fapi2::buffer<uint64_t> l_status;
-
- static const uint64_t l_done = fapi2::buffer<uint64_t>().setBit<TT::MCBIST_DONE>();
- static const uint64_t l_fail = fapi2::buffer<uint64_t>().setBit<TT::MCBIST_FAIL>();
- static const uint64_t l_in_progress = fapi2::buffer<uint64_t>().setBit<TT::MCBIST_IN_PROGRESS>();
-
- // A small vector of addresses to poll during the polling loop
- const std::vector<mss::poll_probe<fapi2::TARGET_TYPE_MCBIST>> l_probes =
- {
- {i_target, "mcbist current address", MCBIST_MCBMCATQ},
- };
-
- mss::poll(i_target, TT::STATQ_REG, i_program.iv_poll,
- [&l_status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
- {
- FAPI_DBG("mcbist statq 0x%llx, remaining: %d", stat_reg, poll_remaining);
- l_status = stat_reg;
- return l_status.getBit<TT::MCBIST_IN_PROGRESS>() != 1;
- },
- l_probes);
-
- // Check to see if we're still in progress - meaning we timed out.
- FAPI_ASSERT((l_status & l_in_progress) != l_in_progress,
- fapi2::MSS_MCBIST_TIMEOUT().set_MCBIST_TARGET(i_target),
- "MCBIST timed out %s", mss::c_str(i_target));
-
- // The control register has a bit for done-and-happy and a bit for done-and-unhappy
- if ( ((l_status & l_done) == l_done) || ((l_status & l_fail) == l_fail) )
- {
- FAPI_INF("MCBIST completed, processing errors");
-
- // We're done. It doesn't mean that there were no errors.
- FAPI_TRY( i_program.process_errors(i_target) );
-
- // If we're here there were no errors, but lets report if the fail bit was set anyway.
- FAPI_ASSERT( (l_status & l_fail) != l_fail,
- fapi2::MSS_MCBIST_UNKNOWN_FAILURE()
- .set_MCBIST_TARGET(i_target)
- .set_STATUS_REGISTER(l_status),
- "%s MCBIST reported a fail, but process_errors didn't find it 0x%016llx",
- mss::c_str(i_target), l_status );
-
- // And if we're here all is good with the world.
- return fapi2::current_err;
- }
-
- FAPI_ASSERT(false,
- fapi2::MSS_MCBIST_DATA_FAIL()
- .set_MCBIST_TARGET(i_target)
- .set_STATUS_REGISTER(l_status),
- "%s MCBIST executed but we got corrupted data in the control register 0x%016llx",
- mss::c_str(i_target), l_status );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
+ 0x000000031,
+ 0x00000001F,
+ 0x001000000,
+ 0x100000000,
+ 0x004000003,
+ 0x000080000,
+ 0x040000018,
+ 0x008000000,
+ 0x010006000,
+ 0x004000000,
+ 0x001000000,
+ 0x003200000,
+ 0x001880000,
+ 0x000200000,
+ 0x000610000,
+ 0x000100000,
+ 0x000040000,
+ 0x000010000,
+ 0x000023000,
+ 0x000002000,
+ 0x000000400,
+ 0x000002000,
+ 0x000005008,
+ 0x000002000,
+ 0x000001088,
+ 0x000000B00,
+ 0x0000004A0,
+ 0x000000100,
+ 0x000000040,
+ 0x000000010,
+ 0x000000038,
+ 0x000000008,
+ 0x000000010,
+ 0x000000004,
+ 0x000000004,
+ 0x000000002,
+ 0x000000001,
+};
-///
-/// @brief Execute the mcbist program
-/// @param[in] i_target the target to effect
-/// @param[in] i_program, the mcbist program to execute
-/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
-///
-template<>
-fapi2::ReturnCode execute( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const program<TARGET_TYPE_MCBIST>& i_program )
+namespace mcbist
{
- typedef mcbistTraits<TARGET_TYPE_MCBIST> TT;
-
- fapi2::buffer<uint64_t> l_status;
- bool l_poll_result = false;
- poll_parameters l_poll_parameters;
-
- // Before we go off into the bushes, lets see if there are any instructions in the
- // program. If not, we can save everyone the hassle
- FAPI_ASSERT(0 != i_program.iv_subtests.size(),
- fapi2::MSS_MEMDIAGS_NO_MCBIST_SUBTESTS().set_MCBIST_TARGET(i_target),
- "Attempt to run an MCBIST program with no subtests on %s", mss::c_str(i_target));
-
- // Implement any mcbist work-arounds.
- // I'm going to do the unthinkable here - and cast away the const of the mcbist program input.
- // The work arounds need to change this, and so it needs to not be const. However, I don't want
- // to risk general const-correctness by changing the input parameter to non-const. So, I use
- // const_cast<> (ducks out of the way of the flying adjectives.) These are work-arounds ...
- FAPI_TRY( workarounds::mcbist::end_of_rank(i_target, const_cast<program<TARGET_TYPE_MCBIST>&>(i_program)) );
-
- FAPI_TRY( clear_errors(i_target) );
-
- // Configures the write/read FIFO bit
- FAPI_TRY( load_fifo_mode( i_target, i_program) );
-
- // Slam the address generator config
- FAPI_TRY( load_addr_gen(i_target, i_program) );
-
- // Slam the parameters in to the mcbist parameter register
- FAPI_TRY( load_mcbparm(i_target, i_program) );
-
- // Slam the configured address maps down
- FAPI_TRY( load_mcbamr( i_target, i_program) );
-
- // Slam the config register down
- FAPI_TRY( load_config( i_target, i_program) );
-
- // Slam the control register down
- FAPI_TRY( load_control( i_target, i_program) );
-
- // Load the patterns and any associated bits for random, etc
- FAPI_TRY( load_data_config( i_target, i_program) );
-
- // Load the thresholds
- FAPI_TRY( load_thresholds( i_target, i_program) );
-
- // Slam the subtests in to the mcbist registers
- // Always do this last so the action file triggers see the other bits set
- FAPI_TRY( load_mcbmr(i_target, i_program) );
-
- // Start the engine, and then poll for completion
- FAPI_TRY(start_stop(i_target, mss::START));
-
- // Verify that the in-progress bit has been set, so we know we started
- // Don't use the program's poll as it could be a very long time. Use the default poll.
- l_poll_result = mss::poll(i_target, TT::STATQ_REG, l_poll_parameters,
- [&l_status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
- {
- FAPI_DBG("looking for mcbist start, mcbist statq 0x%llx, remaining: %d", stat_reg, poll_remaining);
- l_status = stat_reg;
- // We're done polling when either we see we're in progress or we see we're done.
- return (l_status.getBit<TT::MCBIST_IN_PROGRESS>() == true) || (l_status.getBit<TT::MCBIST_DONE>() == true);
- });
-
- // So we've either run/are running or we timed out waiting for the start.
- FAPI_ASSERT( l_poll_result == true,
- fapi2::MSS_MEMDIAGS_MCBIST_FAILED_TO_START().set_MCBIST_TARGET(i_target),
- "The MCBIST engine failed to start its program" );
-
- // If the user asked for async mode, we can leave. Otherwise, poll and check for errors
- if (!i_program.iv_async)
- {
- return mcbist::poll(i_target, i_program);
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
///
/// @brief Get a list of ports involved in the program
-/// Specialization for program<fapi2::TARGET_TYPE_MCBIST>
+/// Specialization for program<>
/// @param[in] i_target the target for this program
/// @return vector of port targets
///
template<>
-template<>
std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCA>>
- program<fapi2::TARGET_TYPE_MCBIST>::get_port_list<fapi2::TARGET_TYPE_MCA>( const
- fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target ) const
+ program<>::get_port_list( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target ) const
{
- typedef mss::mcbistTraits<TARGET_TYPE_MCBIST> TT;
+ using TT = mss::mcbistTraits<>;
std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCA>> l_list;
@@ -542,81 +157,6 @@ std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCA>>
return l_list;
}
-///
-/// @brief Read entries from MCBIST Read Modify Write (RMW) array
-/// Specialization for fapi2::TARGET_TYPE_MCA
-/// @param[in] i_target the target to effect
-/// @param[in] i_start_addr the array address to read first
-/// @param[in] i_num_entries the number of array entries to read
-/// @param[in] i_roll_over_for_compare_mode set to true if only using first
-/// NUM_COMPARE_INFO_ENTRIES of array, so array address rolls over at correct value
-/// @param[out] o_data vector of output data
-/// @param[out] o_ecc_data vector of ecc data
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note The number of entries in the array depends on i_roll_over_for_compare_mode parameter:
-/// (NUM_COMPARE_LOG_ENTRIES for false, NUM_COMPARE_INFO_ENTRIES for true) but user may read more than
-/// that since reads work in a circular buffer fashion
-///
-template<>
-fapi2::ReturnCode read_rmw_array(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const uint64_t i_start_addr,
- const uint64_t i_num_entries,
- const bool i_roll_over_for_compare_mode,
- std::vector< fapi2::buffer<uint64_t> >& o_data,
- std::vector< fapi2::buffer<uint64_t> >& o_ecc_data)
-{
- typedef mcbistTraits<fapi2::TARGET_TYPE_MCA> TT;
-
- fapi2::buffer<uint64_t> l_control_value;
- fapi2::buffer<uint64_t> l_data;
- uint64_t l_array_addr = i_start_addr;
-
- // Clear out any stale values from output vectors
- o_data.clear();
- o_ecc_data.clear();
-
- // Set the control register for the RMW array
- l_control_value.writeBit<TT::RMW_WRT_BUFFER_SEL>(TT::SELECT_RMW_BUFFER)
- // set start address
- .insertFromRight<TT::RMW_WRT_ADDRESS, TT::RMW_WRT_ADDRESS_LEN>(l_array_addr)
- // enable the auto increment bit
- .setBit<TT::RMW_WRT_AUTOINC>()
- // set ecc mode bit off
- .clearBit<TT::RMW_WRT_ECCGEN>();
-
- FAPI_INF("Setting the RMW array access control register.");
- FAPI_TRY( mss::putScom(i_target, TT::RMW_WRT_BUF_CTL_REG, l_control_value) );
-
- for (uint8_t l_index = 0; l_index < i_num_entries; ++l_index)
- {
- // Read info out of RMW array and put into output vector
- // Note that since we enabled AUTOINC above, reading ECC_REG will increment
- // the array pointer so the next DATA_REG read will read the next array entry
- FAPI_TRY( mss::getScom(i_target, TT::RMW_WRT_BUF_DATA_REG, l_data) );
-
- FAPI_INF("RMW data index %d is: %016lx", l_array_addr, l_data);
- o_data.push_back(l_data);
-
- // Need to read ecc register to increment array index
- FAPI_TRY( mss::getScom(i_target, TT::RMW_WRT_BUF_ECC_REG, l_data) );
- o_ecc_data.push_back(l_data);
- ++l_array_addr;
-
- // Need to manually roll over address if we go beyond NUM_COMPARE_INFO_ENTRIES
- // Since actual array is bigger than what is used for compare mode
- if (i_roll_over_for_compare_mode &&
- (l_array_addr >= TT::NUM_COMPARE_INFO_ENTRIES))
- {
- FAPI_INF("Rolling over the RMW array access control register address from %d to %d.", (i_start_addr + l_index), 0);
- l_control_value.clearBit<TT::RMW_WRT_ADDRESS, TT::RMW_WRT_ADDRESS_LEN>();
- FAPI_TRY( mss::putScom(i_target, TT::RMW_WRT_BUF_CTL_REG, l_control_value) );
- l_array_addr = 0;
- }
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
///
/// @brief Read entries from MCBIST Read Buffer (RB) array
@@ -635,7 +175,7 @@ fapi2::ReturnCode read_rb_array(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_t
std::vector< fapi2::buffer<uint64_t> >& o_data,
std::vector< fapi2::buffer<uint64_t> >& o_ecc_data)
{
- typedef mcbistTraits<fapi2::TARGET_TYPE_MCS> TT;
+ using TT = mcbistTraits<DEFAULT_MC_TYPE, fapi2::TARGET_TYPE_MCS>;
fapi2::buffer<uint64_t> l_control_value;
fapi2::buffer<uint64_t> l_data;
@@ -687,7 +227,7 @@ fapi_try_exit:
/// @param[in] i_targets the vector of targets to analyze - specialization for MCA target type
/// @return l_capable - yes iff these vector of targets are broadcast capable
///
-template< >
+template<>
const mss::states is_broadcast_capable(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCA>>& i_targets)
{
// If we don't have MCA's exit out
@@ -810,7 +350,7 @@ const mss::states is_broadcast_capable(const fapi2::Target<fapi2::TARGET_TYPE_MC
// 2) Check that all of the DIMM kinds are equal - if they are, then we can do broadcast mode
const auto l_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target);
- const auto l_dimm_kinds = mss::dimm::kind::vector(l_dimms);
+ const auto l_dimm_kinds = mss::dimm::kind<>::vector(l_dimms);
const auto l_dimm_kind_check = is_broadcast_capable(l_dimm_kinds);
// 3) if both 1/2 are true, then broadcastable, otherwise false
@@ -832,7 +372,7 @@ fapi_try_exit:
/// @param[in] i_target the target to effect
/// @return l_capable - yes iff these vector of targets are broadcast capable
///
-const mss::states is_broadcast_capable(const std::vector<mss::dimm::kind>& i_kinds)
+const mss::states is_broadcast_capable(const std::vector<mss::dimm::kind<>>& i_kinds)
{
// If we don't have any DIMM kinds exit out
if(i_kinds.size() == 0)
@@ -848,7 +388,7 @@ const mss::states is_broadcast_capable(const std::vector<mss::dimm::kind>& i_kin
// Now, find if we have any kinds that differ from our first kind
// Note: starts on the next DIMM kind due to the fact that something always equals itself
const auto l_kind_it = std::find_if(i_kinds.begin() + 1,
- i_kinds.end(), [&l_expected_kind]( const mss::dimm::kind & i_rhs) -> bool
+ i_kinds.end(), [&l_expected_kind]( const mss::dimm::kind<>& i_rhs) -> bool
{
// If they're different, we found a DIMM that is differs
return (l_expected_kind != i_rhs);
@@ -911,7 +451,7 @@ fapi_try_exit:
///
template< >
fapi2::ReturnCode enable_broadcast_mode(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- mcbist::program<fapi2::TARGET_TYPE_MCBIST>& io_program)
+ mcbist::program<>& io_program)
{
// constexpr's for beautification
constexpr bool ENABLE = true;
@@ -934,6 +474,52 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief Configures broadcast mode, if it is needed
+/// @param[in] i_target the target to effect
+/// @param[in,out] io_program the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template<>
+fapi2::ReturnCode configure_broadcast_mode(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ mcbist::program<>& io_program)
+{
+ // If we're not capable to do broadcast mode on this target, exit out
+ const auto l_broadcast_capable = is_broadcast_capable(i_target);
+
+ if(l_broadcast_capable == mss::states::NO)
+ {
+ FAPI_INF("%s is not broadcast capable, skipping enablement of broadcast mode", mss::c_str(i_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Enable broadcast mode
+ FAPI_INF("%s is broadcast capable, enabling broadcast mode", mss::c_str(i_target));
+ return enable_broadcast_mode(i_target, io_program);
+}
+
+///
+/// @brief Clear the errors helper. Chip can specialise this
+/// function to put any necessary workaround in it.
+/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
+///
+template< >
+fapi2::ReturnCode clear_error_helper( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const program<>& i_program )
+{
+ // Implement any mcbist work-arounds.
+ // I'm going to do the unthinkable here - and cast away the const of the mcbist program input.
+ // The work arounds need to change this, and so it needs to not be const. However, I don't want
+ // to risk general const-correctness by changing the input parameter to non-const. So, I use
+ // const_cast<> (ducks out of the way of the flying adjectives.) These are work-arounds ...
+ FAPI_TRY( workarounds::mcbist::end_of_rank(i_target, const_cast<program<>&>(i_program)) );
+
+ FAPI_TRY( clear_errors(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
} // namespace MCBIST
// Note: outside of the mcbist namespace
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H
index bba494154..f708a8869 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,3156 +42,27 @@
#include <p9_mc_scom_addresses_fld.H>
#include <lib/shared/mss_const.H>
-#include <generic/memory/lib/utils/find.H>
-#include <generic/memory/lib/utils/poll.H>
-#include <generic/memory/lib/utils/memory_size.H>
+#include <lib/ecc/ecc_traits_nimbus.H>
+#include <lib/mc/port.H>
#include <lib/utils/mss_nimbus_conversions.H>
#include <lib/utils/bit_count.H>
-#include <lib/utils/num.H>
-#include <lib/mcbist/patterns.H>
-#include <lib/mcbist/settings.H>
-#include <lib/mc/port.H>
-#include <lib/dimm/kind.H>
+#include <lib/dimm/nimbus_kind.H>
+#include <lib/mcbist/mcbist_traits.H>
+#include <lib/workarounds/mcbist_workarounds.H>
+#include <generic/memory/lib/utils/num.H>
+#include <generic/memory/lib/utils/poll.H>
+#include <generic/memory/lib/utils/memory_size.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist.H>
+#include <generic/memory/lib/utils/dump_regs.H>
namespace mss
{
-
-// I have a dream that the MCBIST engine code can be shared among controllers. So, I drive the
-// engine from a set of traits. This might be folly. Allow me to dream. BRS
-
-///
-/// @class mcbistTraits
-/// @brief a collection of traits associated with the MCBIST engine or hardware
-///
-template< fapi2::TargetType T >
-class mcbistTraits;
-
-///
-/// @class mcbistTraits
-/// @brief a collection of traits associated with the Centaur MCBIST engine or hardware
-///
-template<>
-class mcbistTraits<fapi2::TARGET_TYPE_MEMBUF_CHIP>
-{
-};
-
-///
-/// @class mcbistTraits
-/// @brief a collection of traits associated with the Nimbus MCBIST engine or hardware
-///
-template<>
-class mcbistTraits<fapi2::TARGET_TYPE_MCBIST>
-{
- public:
- /// MCBIST "memory registers" - config for subtests.
- static constexpr uint64_t MCBMR0_REG = MCBIST_MCBMR0Q;
- static constexpr uint64_t CFGQ_REG = MCBIST_MCBCFGQ;
- static constexpr uint64_t CNTLQ_REG = MCBIST_MCB_CNTLQ;
- static constexpr uint64_t STATQ_REG = MCBIST_MCB_CNTLSTATQ;
- static constexpr uint64_t MCBSTATQ_REG = MCBIST_MCBSTATQ;
- static constexpr uint64_t MCBPARMQ_REG = MCBIST_MCBPARMQ;
- static constexpr uint64_t MCBAGRAQ_REG = MCBIST_MCBAGRAQ;
- static constexpr uint64_t SRERR0_REG = MCBIST_MBSEC0Q;
- static constexpr uint64_t SRERR1_REG = MCBIST_MBSEC1Q;
- static constexpr uint64_t THRESHOLD_REG = MCBIST_MBSTRQ;
- static constexpr uint64_t FIRQ_REG = MCBIST_MCBISTFIRQ;
- static constexpr uint64_t LAST_ADDR_REG = MCBIST_MCBMCATQ;
-
- static constexpr uint64_t MCBAMR0A0Q_REG = MCBIST_MCBAMR0A0Q;
- static constexpr uint64_t MCBAMR1A0Q_REG = MCBIST_MCBAMR1A0Q;
- static constexpr uint64_t MCBAMR2A0Q_REG = MCBIST_MCBAMR2A0Q;
- static constexpr uint64_t MCBAMR3A0Q_REG = MCBIST_MCBAMR3A0Q;
-
- // MCBIST FIR registers
- static constexpr uint64_t MCBFIRMASK_REG = MCBIST_MCBISTFIRMASK;
- static constexpr uint64_t MCBFIRQ_REG = MCBIST_MCBISTFIRQ;
-
- // All of the pattern registers are calculated off of this base
- static constexpr uint64_t PATTERN0_REG = MCBIST_MCBFD0Q;
-
- static constexpr uint64_t DATA_ROTATE_CNFG_REG = MCBIST_MCBDRCRQ;
- static constexpr uint64_t DATA_ROTATE_SEED_REG = MCBIST_MCBDRSRQ;
-
- static constexpr uint64_t START_ADDRESS_0 = MCBIST_MCBSA0Q;
- static constexpr uint64_t START_ADDRESS_1 = MCBIST_MCBSA1Q;
- static constexpr uint64_t START_ADDRESS_2 = MCBIST_MCBSA2Q;
- static constexpr uint64_t START_ADDRESS_3 = MCBIST_MCBSA3Q;
-
- static constexpr uint64_t END_ADDRESS_0 = MCBIST_MCBEA0Q;
- static constexpr uint64_t END_ADDRESS_1 = MCBIST_MCBEA1Q;
- static constexpr uint64_t END_ADDRESS_2 = MCBIST_MCBEA2Q;
- static constexpr uint64_t END_ADDRESS_3 = MCBIST_MCBEA3Q;
-
- static constexpr uint64_t RANDOM_DATA_SEED0 = MCBIST_MCBRDS0Q;
- static constexpr uint64_t RANDOM_DATA_SEED1 = MCBIST_MCBRDS1Q;
-
-
- // MCBIST Compare Masks, used to setup the ECC traps
- // TK there is one reg per port, does writing to this one write to all?
- static constexpr uint64_t COMPARE_MASK = MCA_MCBCM;
-
- static constexpr uint64_t PATTERN_COUNT = 4;
-
- // Sometimes we want to access the start/end address registers based off
- // of an index, like master rank. This allows us to do that.
- static const std::pair<uint64_t, uint64_t> address_pairs[];
-
- // Subtest types that need to be run in FIFO mode
- static const std::vector< mss::mcbist::op_type > FIFO_MODE_REQUIRED_OP_TYPES;
-
- enum
- {
- // Subtest control bits. These are the same in all '16 bit subtest' field
- COMPL_1ST_CMD = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_1ST_CMD,
- COMPL_2ND_CMD = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_2ND_CMD,
- COMPL_3RD_CMD = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_3RD_CMD,
- ADDR_REV_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_REV_MODE,
- ADDR_RAND_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_RAND_MODE,
-
- // Goto subtests use the compl_1st - rand_mode to define the subtest to jump to
- GOTO_SUBTEST = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_1ST_CMD,
- GOTO_SUBTEST_LEN = 5,
-
- ECC_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ECC_MODE,
- DATA_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DATA_MODE,
- DATA_MODE_LEN = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DATA_MODE_LEN,
- ADDR_SEL = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_SEL,
- ADDR_SEL_LEN = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_SEL_LEN,
- OP_TYPE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_OP_TYPE,
- OP_TYPE_LEN = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_OP_TYPE_LEN,
- DONE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DONE,
-
- SYNC_EN = MCBIST_MCBCFGQ_BROADCAST_SYNC_EN,
- SYNC_WAIT = MCBIST_MCBCFGQ_BROADCAST_SYNC_WAIT,
- SYNC_WAIT_LEN = MCBIST_MCBCFGQ_BROADCAST_SYNC_WAIT_LEN,
-
- PORT_SEL = MCBIST_MCB_CNTLQ_MCBCNTL_PORT_SEL,
- PORT_SEL_LEN = MCBIST_MCB_CNTLQ_MCBCNTL_PORT_SEL_LEN,
-
- MCBIST_START = MCBIST_MCB_CNTLQ_START,
- MCBIST_STOP = MCBIST_MCB_CNTLQ_STOP,
- MCBIST_RESUME = MCBIST_MCB_CNTLQ_RESUME_FROM_PAUSE,
- MCBIST_RESET_ERRORS = MCBIST_MCB_CNTLQ_RESET_ERROR_LOGS,
-
- MCBIST_IN_PROGRESS = MCBIST_MCB_CNTLSTATQ_IP,
- MCBIST_DONE = MCBIST_MCB_CNTLSTATQ_DONE,
- MCBIST_FAIL = MCBIST_MCB_CNTLSTATQ_FAIL,
-
- MIN_CMD_GAP = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP,
- MIN_CMD_GAP_LEN = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_LEN,
- MIN_GAP_TIMEBASE = MCBIST_MCBPARMQ_CFG_MIN_GAP_TIMEBASE,
- MIN_CMD_GAP_BLIND_STEER = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_BLIND_STEER,
- MIN_CMD_GAP_BLIND_STEER_LEN = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_BLIND_STEER_LEN,
- MIN_GAP_TIMEBASE_BLIND_STEER = MCBIST_MCBPARMQ_CFG_MIN_GAP_TIMEBASE_BLIND_STEER,
- RANDCMD_WGT = MCBIST_MCBPARMQ_CFG_RANDCMD_WGT,
- RANDCMD_WGT_LEN = MCBIST_MCBPARMQ_CFG_RANDCMD_WGT_LEN,
- CLOCK_MONITOR_EN = MCBIST_MCBPARMQ_CFG_CLOCK_MONITOR_EN,
- EN_RANDCMD_GAP = MCBIST_MCBPARMQ_CFG_EN_RANDCMD_GAP,
- RANDGAP_WGT = MCBIST_MCBPARMQ_CFG_RANDGAP_WGT,
- RANDGAP_WGT_LEN = MCBIST_MCBPARMQ_CFG_RANDGAP_WGT_LEN,
- BC4_EN = MCBIST_MCBPARMQ_CFG_BC4_EN,
-
- FIXED_WIDTH = MCBIST_MCBAGRAQ_CFG_FIXED_WIDTH,
- FIXED_WIDTH_LEN = MCBIST_MCBAGRAQ_CFG_FIXED_WIDTH_LEN,
- ADDR_COUNTER_MODE = MCBIST_MCBAGRAQ_CFG_ADDR_COUNTER_MODE,
- ADDR_COUNTER_MODE_LEN = MCBIST_MCBAGRAQ_CFG_ADDR_COUNTER_MODE_LEN,
- MAINT_ADDR_MODE_EN = MCBIST_MCBAGRAQ_CFG_MAINT_ADDR_MODE_EN,
- MAINT_BROADCAST_MODE_EN = MCBIST_MCBAGRAQ_CFG_MAINT_BROADCAST_MODE_EN,
- MAINT_DETECT_SRANK_BOUNDARIES = MCBIST_MCBAGRAQ_CFG_MAINT_DETECT_SRANK_BOUNDARIES,
-
- CFG_CMD_TIMEOUT_MODE = MCBIST_MCBCFGQ_CFG_CMD_TIMEOUT_MODE,
- CFG_CMD_TIMEOUT_MODE_LEN = MCBIST_MCBCFGQ_CFG_CMD_TIMEOUT_MODE_LEN,
- RESET_KEEPER = MCBIST_MCBCFGQ_RESET_KEEPER,
- CFG_CURRENT_ADDR_TRAP_UPDATE_DIS = MCBIST_MCBCFGQ_CFG_CURRENT_ADDR_TRAP_UPDATE_DIS,
- CFG_CCS_RETRY_DIS = MCBIST_MCBCFGQ_CFG_CCS_RETRY_DIS,
- CFG_RESET_CNTS_START_OF_RANK = MCBIST_MCBCFGQ_CFG_RESET_CNTS_START_OF_RANK,
- CFG_LOG_COUNTS_IN_TRACE = MCBIST_MCBCFGQ_CFG_LOG_COUNTS_IN_TRACE,
- SKIP_INVALID_ADDR_DIMM_DIS = MCBIST_MCBCFGQ_SKIP_INVALID_ADDR_DIMM_DIS,
- REFRESH_ONLY_SUBTEST_EN = MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_EN,
- REFRESH_ONLY_SUBTEST_TIMEBASE_SEL = MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_TIMEBASE_SEL,
- REFRESH_ONLY_SUBTEST_TIMEBASE_SEL_LEN = MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_TIMEBASE_SEL_LEN,
- RAND_ADDR_ALL_ADDR_MODE_EN = MCBIST_MCBCFGQ_RAND_ADDR_ALL_ADDR_MODE_EN,
- MCBIST_CFG_REF_WAIT_TIME = MCBIST_MCBCFGQ_MCBIST_CFG_REF_WAIT_TIME,
- MCBIST_CFG_REF_WAIT_TIME_LEN = MCBIST_MCBCFGQ_MCBIST_CFG_REF_WAIT_TIME_LEN,
- CFG_MCB_LEN64 = MCBIST_MCBCFGQ_CFG_MCB_LEN64,
- CFG_PAUSE_ON_ERROR_MODE = MCBIST_MCBCFGQ_CFG_PAUSE_ON_ERROR_MODE,
- CFG_PAUSE_ON_ERROR_MODE_LEN = MCBIST_MCBCFGQ_CFG_PAUSE_ON_ERROR_MODE_LEN,
- MCBIST_CFG_PAUSE_AFTER_CCS_SUBTEST = MCBIST_MCBCFGQ_MCBIST_CFG_PAUSE_AFTER_CCS_SUBTEST,
- MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR = MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR,
- MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST = MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST,
- CFG_ENABLE_SPEC_ATTN = MCBIST_MCBCFGQ_CFG_ENABLE_SPEC_ATTN,
- CFG_ENABLE_HOST_ATTN = MCBIST_MCBCFGQ_CFG_ENABLE_HOST_ATTN,
- MCBIST_CFG_PAUSE_AFTER_RANK = MCBIST_MCBCFGQ_CFG_MCBIST_CFG_FORCE_PAUSE_AFTER_RANK,
-
- LOGGED_ERROR_ON_PORT_INDICATOR = MCBIST_MCBSTATQ_MCBIST_LOGGED_ERROR_ON_PORT_INDICATOR,
- LOGGED_ERROR_ON_PORT_INDICATOR_LEN = MCBIST_MCBSTATQ_MCBIST_LOGGED_ERROR_ON_PORT_INDICATOR_LEN,
- SUBTEST_NUM_INDICATOR = MCBIST_MCBSTATQ_MCBIST_SUBTEST_NUM_INDICATOR,
- SUBTEST_NUM_INDICATOR_LEN = MCBIST_MCBSTATQ_MCBIST_SUBTEST_NUM_INDICATOR_LEN,
-
- UE_COUNT = MCBIST_MBSEC1Q_UE_COUNT,
- UE_COUNT_LEN = MCBIST_MBSEC1Q_UE_COUNT_LEN,
-
- CFG_AMAP_DIMM_SELECT = MCBIST_MCBAMR0A0Q_CFG_AMAP_DIMM_SELECT,
- CFG_AMAP_DIMM_SELECT_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_DIMM_SELECT_LEN,
- CFG_AMAP_MRANK0 = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK0,
- CFG_AMAP_MRANK0_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK0_LEN,
- CFG_AMAP_MRANK1 = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK1,
- CFG_AMAP_MRANK1_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK1_LEN,
- CFG_AMAP_SRANK0 = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK0,
- CFG_AMAP_SRANK0_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK0_LEN,
- CFG_AMAP_SRANK1 = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK1,
- CFG_AMAP_SRANK1_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK1_LEN,
- CFG_AMAP_SRANK2 = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK2,
- CFG_AMAP_SRANK2_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK2_LEN,
- CFG_AMAP_BANK2 = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK2,
- CFG_AMAP_BANK2_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK2_LEN ,
- CFG_AMAP_BANK1 = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK1,
- CFG_AMAP_BANK1_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK1_LEN ,
- CFG_AMAP_BANK0 = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK0,
- CFG_AMAP_BANK0_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK0_LEN ,
-
- CFG_AMAP_BANK_GROUP1 = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP1,
- CFG_AMAP_BANK_GROUP1_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP1_LEN ,
- CFG_AMAP_BANK_GROUP0 = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP0,
- CFG_AMAP_BANK_GROUP0_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP0_LEN ,
- CFG_AMAP_ROW17 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW17,
- CFG_AMAP_ROW17_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW17_LEN,
- CFG_AMAP_ROW16 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW16,
- CFG_AMAP_ROW16_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW16_LEN,
- CFG_AMAP_ROW15 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW15,
- CFG_AMAP_ROW15_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW15_LEN,
- CFG_AMAP_ROW14 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW14,
- CFG_AMAP_ROW14_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW14_LEN,
- CFG_AMAP_ROW13 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW13,
- CFG_AMAP_ROW13_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW13_LEN,
- CFG_AMAP_ROW12 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12,
- CFG_AMAP_ROW12_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12_LEN,
- CFG_AMAP_ROW11 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW11,
- CFG_AMAP_ROW11_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW11_LEN,
- CFG_AMAP_ROW10 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW10,
- CFG_AMAP_ROW10_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW10_LEN,
-
- CFG_AMAP_ROW9 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW9,
- CFG_AMAP_ROW9_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW9_LEN,
- CFG_AMAP_ROW8 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW8,
- CFG_AMAP_ROW8_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW8_LEN,
- CFG_AMAP_ROW7 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW7,
- CFG_AMAP_ROW7_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW7_LEN,
- CFG_AMAP_ROW6 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW6,
- CFG_AMAP_ROW6_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW6_LEN,
- CFG_AMAP_ROW5 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW5,
- CFG_AMAP_ROW5_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW5_LEN,
- CFG_AMAP_ROW4 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW4,
- CFG_AMAP_ROW4_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW4_LEN,
- CFG_AMAP_ROW3 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW3,
- CFG_AMAP_ROW3_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW3_LEN,
- CFG_AMAP_ROW2 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW2,
- CFG_AMAP_ROW2_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW2_LEN,
- CFG_AMAP_ROW1 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW1,
- CFG_AMAP_ROW1_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW1_LEN,
- CFG_AMAP_ROW0 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW0,
- CFG_AMAP_ROW0_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW0_LEN,
-
- CFG_AMAP_COL9 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL9,
- CFG_AMAP_COL9_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL9_LEN,
- CFG_AMAP_COL8 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL8,
- CFG_AMAP_COL8_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL8_LEN,
- CFG_AMAP_COL7 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL7,
- CFG_AMAP_COL7_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL7_LEN,
- CFG_AMAP_COL6 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL6,
- CFG_AMAP_COL6_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL6_LEN,
- CFG_AMAP_COL5 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL5,
- CFG_AMAP_COL5_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL5_LEN,
- CFG_AMAP_COL4 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL4,
- CFG_AMAP_COL4_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL4_LEN,
- CFG_AMAP_COL3 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL3,
- CFG_AMAP_COL3_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL3_LEN,
- CFG_AMAP_COL2 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL2,
- CFG_AMAP_COL2_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL2_LEN,
-
- CFG_DATA_ROT_SEED1 = MCBIST_MCBDRSRQ_CFG_DATA_ROT_SEED,
- CFG_DATA_ROT_SEED1_LEN = MCBIST_MCBDRSRQ_CFG_DATA_ROT_SEED_LEN,
- CFG_DATA_ROT = MCBIST_MCBDRCRQ_CFG_DATA_ROT,
- CFG_DATA_ROT_LEN = MCBIST_MCBDRCRQ_CFG_DATA_ROT_LEN,
- CFG_DATA_ROT_SEED2 = MCBIST_MCBDRCRQ_CFG_DATA_ROT_SEED,
- CFG_DATA_ROT_SEED2_LEN = MCBIST_MCBDRCRQ_CFG_DATA_ROT_SEED_LEN,
- CFG_DATA_SEED_MODE = MCBIST_MCBDRCRQ_CFG_DATA_SEED_MODE,
- CFG_DATA_SEED_MODE_LEN = MCBIST_MCBDRCRQ_CFG_DATA_SEED_MODE_LEN,
-
- CFG_TRAP_CE_ENABLE = MCA_MCBCM_MCBIST_TRAP_CE_ENABLE,
- CFG_TRAP_UE_ENABLE = MCA_MCBCM_MCBIST_TRAP_UE_ENABLE,
- CFG_TRAP_MPE_ENABLE = MCA_MCBCM_MCBIST_TRAP_MPE_ENABLE,
-
- CFG_DGEN_RNDD_SEED0 = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0,
- CFG_DGEN_RNDD_SEED0_LEN = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0_LEN,
- CFG_DGEN_RNDD_SEED1 = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1,
- CFG_DGEN_RNDD_SEED1_LEN = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1_LEN,
- CFG_DGEN_RNDD_SEED2 = MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2,
- CFG_DGEN_RNDD_SEED2_LEN = MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2_LEN,
- CFG_DGEN_RNDD_DATA_MAPPING = MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING,
- CFG_DGEN_RNDD_DATA_MAPPING_LEN = MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING_LEN,
-
- // Bit mapping for MCBIST error log control data (address+ in Nimbus doc)
- ERROR_LOG_SUBTEST = 0,
- ERROR_LOG_SUBTEST_LEN = 5,
- ERROR_LOG_SUBCMD = 5,
- ERROR_LOG_SUBCMD_LEN = 2,
- ERROR_LOG_ADDR_DIMM = 7,
- ERROR_LOG_ADDR_MRANK = 8,
- ERROR_LOG_ADDR_MRANK_LEN = 2,
- ERROR_LOG_ADDR_SRANK = 10,
- ERROR_LOG_ADDR_SRANK_LEN = 3,
- ERROR_LOG_ADDR_BANK_GROUP = 13,
- ERROR_LOG_ADDR_BANK_GROUP_LEN = 2,
- ERROR_LOG_ADDR_BANK = 15,
- ERROR_LOG_ADDR_BANK_LEN = 3,
- ERROR_LOG_ADDR_ROW = 18,
- ERROR_LOG_ADDR_ROW_LEN = 18,
- ERROR_LOG_ADDR_COLUMN = 36,
- ERROR_LOG_ADDR_COLUMN_LEN = 8,
- ERROR_LOG_BEAT = 44,
- ERROR_LOG_BEAT_LEN = 2,
- ERROR_LOG_TYPE = 46,
- ERROR_LOG_TYPE_LEN = 2,
-
- //MCBIST FIR mask
- MCB_PROGRAM_COMPLETE = MCBIST_MCBISTFIRQ_MCBIST_PROGRAM_COMPLETE,
- MCB_WAT_DEBUG_ATTN = MCBIST_MCBISTFIRQ_WAT_DEBUG_ATTN,
- MCB_PROGRAM_COMPLETE_MASK = MCB_PROGRAM_COMPLETE,
- MCB_WAT_DEBUG_ATTN_MASK = MCB_WAT_DEBUG_ATTN,
- };
-
-};
-
-///
-/// @class mcbistTraits
-/// @brief a collection of traits associated with the Nimbus MCA
-///
-template<>
-class mcbistTraits<fapi2::TARGET_TYPE_MCA>
-{
- public:
- // MCBIST error log related registers
- static constexpr uint64_t ERROR_LOG_PTR_REG = MCA_ELPR;
- static constexpr uint64_t RMW_WRT_BUF_CTL_REG = MCA_WREITE_AACR;
- static constexpr uint64_t RMW_WRT_BUF_DATA_REG = MCA_AADR;
- static constexpr uint64_t RMW_WRT_BUF_ECC_REG = MCA_AAER;
-
- enum
- {
- // Register field constants
- ERROR_LOG_PTR = MCA_ELPR_LOG_POINTER,
- ERROR_LOG_PTR_LEN = MCA_ELPR_LOG_POINTER_LEN,
- ERROR_LOG_FULL = MCA_ELPR_LOG_FULL,
- RMW_WRT_BUFFER_SEL = MCA_WREITE_AACR_BUFFER,
- RMW_WRT_ADDRESS = MCA_WREITE_AACR_ADDRESS,
- RMW_WRT_ADDRESS_LEN = MCA_WREITE_AACR_ADDRESS_LEN,
- RMW_WRT_AUTOINC = MCA_WREITE_AACR_AUTOINC,
- RMW_WRT_ECCGEN = MCA_WREITE_AACR_ECCGEN,
-
- // Constants used for field settings
- SELECT_RMW_BUFFER = 0,
- SELECT_WRT_BUFFER = 1,
-
- // Other constants
- NUM_COMPARE_LOG_ENTRIES = 64,
- // In compare mode, there is one "info" entry per 4 data (log) entries
- // so compare mode only uses 16 info entries total in the rmw array
- NUM_COMPARE_DATA_PER_INFO_LOG = 4,
- NUM_COMPARE_INFO_ENTRIES = 16,
- };
-
-};
-
-///
-/// @class mcbistTraits
-/// @brief a collection of traits associated with the Nimbus MCS
-///
-template<>
-class mcbistTraits<fapi2::TARGET_TYPE_MCS>
-{
- public:
- // MCBIST error log related registers
- static constexpr uint64_t RD_BUF_CTL_REG = MCS_PORT02_AACR;
- static constexpr uint64_t RD_BUF_DATA_REG = MCS_PORT02_AADR;
- static constexpr uint64_t RD_BUF_ECC_REG = MCS_PORT02_AAER;
-
- enum
- {
- // Register field constants
- RB_BUFFER_SEL = MCS_PORT02_AACR_BUFFER,
- RB_ADDRESS = MCS_PORT02_AACR_ADDRESS,
- RB_ADDRESS_LEN = MCS_PORT02_AACR_ADDRESS_LEN,
- RB_AUTOINC = MCS_PORT02_AACR_AUTOINC,
-
- // Other constants
- NUM_COMPARE_LOG_ENTRIES = 64,
- };
-
-};
-
-///
-/// @brief Return the estimated time an MCBIST subtest will take to complete
-/// Useful for initial polling delays, probably isn't accurate for much else
-/// as it doesn't take refresh in to account (which will necessarily slow down
-/// the program.)
-/// @param[in] i_target the target from which to gather memory frequency
-/// @param[in] i_bytes number of *bytes* in the address range
-/// @param[in] i_64B_per mss::YES if the command is 64B, mss::NO if it's 128B. Defaults to mss::YES
-/// @return the initial polling delay for this program in ns
-///
-template< fapi2::TargetType T >
-inline uint64_t calculate_initial_delay(const fapi2::Target<T>& i_target,
- const uint64_t i_bytes,
- const bool i_64B_per = mss::YES)
-{
- // TODO RTC: 164104 Update MCBIST delay calculator. As we learn more about what
- // the lab really needs, we can probably make this function better.
- const uint64_t l_bytes_per_cmd = (i_64B_per == mss::YES) ? 64 : 128;
-
- // Best case is a command takes 4 cycles. Given the number of commands and address space size
- // we can get some idea of how long to wait before we start polling.
- return cycles_to_ns(i_target, (i_bytes / l_bytes_per_cmd) * mss::CYCLES_PER_CMD);
-}
-
namespace mcbist
{
-///
-/// @class subtest_t
-/// @brief encapsulation of an MCBIST subtest.
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-class subtest_t
-{
- public:
- subtest_t( const uint16_t i_data = 0 ):
- iv_mcbmr(i_data)
- {}
-
- ///
- /// @brief Checks if the op type requires FIFO mode to be on
- /// @return bool fifo_mode_requried - true if FIFO mode is required to be forced on
- ///
- inline bool fifo_mode_required() const
- {
- // Gets the op type for this subtest
- uint64_t l_value_to_find = 0;
- iv_mcbmr.extractToRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(l_value_to_find);
-
- // Finds if this op type is in the vector that stores the OP types that require FIFO mode to be run
- const auto l_op_type_it = std::find(TT::FIFO_MODE_REQUIRED_OP_TYPES.begin(), TT::FIFO_MODE_REQUIRED_OP_TYPES.end(),
- l_value_to_find);
-
- // If the op type is required (aka was found), it will be less than end
- // std::find returns the ending iterator if it was not found, so this will return false in that case
- return l_op_type_it != TT::FIFO_MODE_REQUIRED_OP_TYPES.end();
- }
-
- ///
- /// @brief Convert to a 16 bit int
- /// @return the subtest as a 16 bit integer, useful for testing
- ///
- inline operator uint16_t()
- {
- return uint16_t(iv_mcbmr);
- }
-
- ///
- /// @brief Complement the data for the first subcommand
- /// @param[in] i_state the desired state (mss::ON or mss::OFF)
- ///
- inline void change_compliment_1st_cmd( const mss::states i_state )
- {
- iv_mcbmr.template writeBit<TT::COMPL_1ST_CMD>(i_state);
- return;
- }
-
- ///
- /// @brief Complement the data for the second subcommand
- /// @param[in] i_state the desired state (mss::ON or mss::OFF)
- /// @return void
- ///
- inline void change_compliment_2nd_cmd( const mss::states i_state )
- {
- iv_mcbmr.template writeBit<TT::COMPL_2ND_CMD>(i_state);
- return;
- }
-
- ///
- /// @brief Complement the data for the third subcommand
- /// @param[in] i_state the desired state (mss::ON or mss::OFF)
- /// @return void
- ///
- inline void change_compliment_3rd_cmd( const mss::states i_state )
- {
- iv_mcbmr.template writeBit<TT::COMPL_3RD_CMD>(i_state);
- return;
- }
-
- ///
- /// @brief Enable a specific port for this test - maint address mode
- /// @param[in] i_port the port desired to be enabled - int 0, 1, 2, 3
- /// @note The port number is relative to the MCBIST
- /// @return void
- ///
- inline void enable_port( const uint64_t i_port )
- {
- constexpr uint64_t l_len = (TT::COMPL_2ND_CMD - TT::COMPL_1ST_CMD) + 1;
- iv_mcbmr.template insertFromRight<TT::COMPL_1ST_CMD, l_len>(i_port);
- return;
- }
-
- ///
- /// @brief Enable a specific dimm for this test - maint address mode
- /// @param[in] i_dimm the dimm desired to be enabled - int 0, 1
- /// @return void
- ///
- inline void enable_dimm( const uint64_t i_dimm )
- {
- iv_mcbmr.template writeBit<TT::COMPL_3RD_CMD>(i_dimm);
- return;
- }
-
- ///
- /// @brief Get the port from this subtest
- /// @note The port number is relative to the MCBIST
- /// @return the port of the subtest
- ///
- inline uint64_t get_port() const
- {
- uint64_t l_port = 0;
- constexpr uint64_t l_len = (TT::COMPL_2ND_CMD - TT::COMPL_1ST_CMD) + 1;
- iv_mcbmr.template extractToRight<TT::COMPL_1ST_CMD, l_len>(l_port);
- return l_port;
- }
-
- ///
- /// @brief Get the DIMM from this subtest
- /// @return the DIMM this subtest has been configured for
- ///
- inline uint64_t get_dimm() const
- {
- return iv_mcbmr.template getBit<TT::COMPL_3RD_CMD>() ? 1 : 0;
- }
-
- ///
- /// @brief Add the subtest to go to
- /// @param[in] the subtest to jump to
- /// @return void
- ///
- inline void change_goto_subtest( const uint64_t i_jmp_to )
- {
- iv_mcbmr.template insertFromRight<TT::GOTO_SUBTEST, TT::GOTO_SUBTEST_LEN>(i_jmp_to);
- FAPI_INF("changing subtest to jump to %d (0x%02x)", i_jmp_to, iv_mcbmr);
- return;
- }
-
- ///
- /// @brief Generate addresses in reverse order
- /// @param[in] i_state the desired state of the function; mss:ON, mss::OFF
- /// @return void
- ///
- inline void change_addr_rev_mode( const mss::states i_state )
- {
- iv_mcbmr.template writeBit<TT::ADDR_REV_MODE>(i_state);
- return;
- }
-
- ///
- /// @brief Generate addresses in random order
- /// @param[in] i_state the desired state of the function; mss:ON, mss::OFF
- /// @return void
- ///
- inline void change_addr_rand_mode( const mss::states i_state )
- {
- iv_mcbmr.template writeBit<TT::ADDR_RAND_MODE>(i_state);
- return;
- }
-
- ///
- /// @brief Generate and check data with ECC
- /// @param[in] i_state the desired state of the function; mss:ON, mss::OFF
- /// @return void
- ///
- inline void change_ecc_mode( const mss::states i_state )
- {
- iv_mcbmr.template writeBit<TT::ECC_MODE>(i_state);
- return;
- }
-
- ///
- /// @brief Set the 'done after this test' bit
- /// @param[in] i_state the desired state of the function; mss:ON, mss::OFF
- /// @return void
- ///
- inline void change_done( const mss::states i_state )
- {
- iv_mcbmr.template writeBit<TT::DONE>(i_state);
- return;
- }
-
- ///
- /// @brief Set the data mode for this subtest
- /// @param[in] i_mode the desired mcbist::data_mode
- /// @return void
- ///
- inline void change_data_mode( const data_mode i_mode )
- {
- iv_mcbmr.template insertFromRight<TT::DATA_MODE, TT::DATA_MODE_LEN>(i_mode);
- return;
- }
-
- ///
- /// @brief Set the operation type for this subtest
- /// @param[in] i_mode the desired mcbist::op_type
- /// @return void
- ///
- inline void change_op_type( const op_type i_type )
- {
- iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(i_type);
- return;
- }
-
- ///
- /// @brief Configure which address registers to use for this subtest
- /// @param[in] i_index 0 = MCBSA0Q, 1 = MCBSA1Q, ...
- /// @note wraps to 0-3 no matter what value you pass in.
- /// @return void
- ///
- inline void change_addr_sel( const uint16_t i_index )
- {
- // Roll the index around - tidy support for an index which is out of range.
- constexpr uint16_t MAX_ADDRESS_START_END_REGISTERS = 3 + 1;
- iv_mcbmr.template insertFromRight<TT::ADDR_SEL, TT::ADDR_SEL_LEN>(i_index % MAX_ADDRESS_START_END_REGISTERS);
- FAPI_INF("changed address select to index %d (0x%x)", i_index, iv_mcbmr);
- return;
- }
-
- //
- // @brief operator== for mcbist subtests
- // @param[in] i_rhs the right hand side of the compare
- // @return bool, true iff i_rhs == this
- inline bool operator==(const subtest_t<T>& i_rhs) const
- {
- return i_rhs.iv_mcbmr == iv_mcbmr;
- }
-
- /// The mcbist 'memory register' for this subtest.
- // Note that it is only 16 bits.
- // Each 64b memory register contains multiple 16 bit subtest definitions.
- // As we create a vector of subtests, we'll drop them in to their appropriate
- // MCBMR register before executing.
- fapi2::buffer<uint16_t> iv_mcbmr;
-};
-
-///
-/// @brief Return a write subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> write_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 0000 - we want subtest type to be a Write (W)
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::WRITE);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 12 = 1 - ecc
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- // 14:15 = 0 address select config registers 0
-
- return l_subtest;
-}
-
-
-///
-/// @brief Return an alter subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> alter_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 1011 - we want subtest type to be a Alter
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::ALTER);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return an display subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> display_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 1100 - we want subtest type to be a Display
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::DISPLAY);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return an scrub subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> scrub_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 1001 - we want subtest type to be a Scrub
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::SCRUB_RRWR);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return a steer subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> steer_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 1010 - we want subtest type to be a Steer
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::STEER_RW);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return a read subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> read_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 0001 - we want subtest type to be a Read (R)
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::READ);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return a read write subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> read_write_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 0010 - we want subtest type to be a Read Write (RW)
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::READ_WRITE);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return a read write read subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> read_write_read_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 0100 - we want subtest type to be a Read Write Read (RWR) 7
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::READ_WRITE_READ);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return a random subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> random_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 0110 - we want subtest type to be a Random Seq, a randomly chosen read or write
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::RAND_SEQ);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return a goto subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] the subtest we should go to
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> goto_subtest( const uint64_t i_jump_to )
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 0111 - we want subtest type to be a Goto
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::GOTO_SUBTEST_N);
-
- // Plug in the subtest the user passed in
- l_subtest.change_goto_subtest(i_jump_to);
- return l_subtest;
-}
-
-///
-/// @brief Return an init subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> init_subtest()
-{
- return write_subtest<T>();
-}
-
-///
-/// @brief A class representing a series of MCBIST subtests, and the
-/// MCBIST engine parameters associated with running the subtests
-/// @tparam T fapi2::TargetType representing the fapi2 target which
-/// contains the MCBIST engine (e.g., fapi2::TARGET_TYPE_MCBIST)
-/// @tparam TT, the mssTraits associtated with T
-/// @note MCBIST Memory Parameter Register defaults to
-/// - issue commands as fast as possible
-/// - even weighting of read/write if random addressing
-/// - disable clock monitoring
-/// - random command gap is disabled
-/// - BC4 disabled
-/// - no selected ports
-/// @note Address Generation Config Register defaults to
-/// - 0 fixed slots
-/// - All address counter modes on (so addr configs are start + len)
-/// - maint address mode enabled
-/// - maint broadcast mode disabled
-/// - maint slave rank boundary detect disabled
-/// @note Config register defaults to
-/// - BROADCAST_SYNC_EN disabled
-/// - BROADCAST_SYNC_WAIT 0
-/// - TIMEOUT_MODE - wait 524288 cycles until timeout is called
-/// - RESET_KEEPER - 0
-/// - CURRENT_ADDR_TRAP_UPDATE_DIS - 0
-/// - CCS_RETRY_DIS - 0
-/// - RESET_CNTS_START_OF_RANK - 0
-/// - LOG_COUNTS_IN_TRACE - 0
-/// - SKIP_INVALID_ADDR_DIMM_DIS - 0
-/// - REFRESH_ONLY_SUBTEST_EN - 0
-/// - REFRESH_ONLY_SUBTEST_TIMEBASE_SEL(0:1) - 0
-/// - RAND_ADDR_ALL_ADDR_MODE_EN - 0
-/// - REF_WAIT_TIME(0:13) - 0
-/// - MCB_LEN64 - 1
-/// - PAUSE_ON_ERROR_MODE(0:1) - don't pause on error
-/// - PAUSE_AFTER_CCS_SUBTEST - don't puase after CCS subtest
-/// - FORCE_PAUSE_AFTER_ADDR - don't pause after current address
-/// - FORCE_PAUSE_AFTER_SUBTEST - no pause after subtest
-/// - ENABLE_SPEC_ATTN - disabled
-/// - ENABLE_HOST_ATTN - enabled
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-class program
-{
- public:
- // Setup our poll parameters so the MCBIST executer can see
- // whether to use the delays in the instruction stream or not
- program():
- iv_parameters(0),
- iv_addr_gen(0),
- iv_test_type(CENSHMOO), // Used as default in Centaur
- iv_addr_map0(0),
- iv_addr_map1(0),
- iv_addr_map2(0),
- iv_addr_map3(0),
- iv_data_rotate_cnfg(0),
- iv_data_rotate_seed(0),
- iv_config(0),
- iv_control(0),
- iv_async(false),
- iv_pattern(PATTERN_0),
- iv_random24_data_seed(RANDOM24_SEEDS_0),
- iv_random24_seed_map(RANDOM24_SEED_MAP_0),
- iv_compare_mask(0)
- {
- // Enable the maintenance mode addressing
- change_maint_address_mode(mss::ON);
-
- // Enable 64B lengths by default. Commands which need 128B (scrub, steer, alter, display)
- // can change this to 128B (mss::OFF).
- change_len64(mss::ON);
-
- // Turn off counting mode for all address configs
- iv_addr_gen.insertFromRight<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(0b0000);
-
- // By default if there's an error, we stop after the errored address
- iv_config.insertFromRight<TT::CFG_PAUSE_ON_ERROR_MODE,
- TT::CFG_PAUSE_ON_ERROR_MODE_LEN>(end_boundary::STOP_AFTER_ADDRESS);
-
- // All mcbist attentions are host attentions, special attention bit is already clear
- iv_config.setBit<TT::CFG_ENABLE_HOST_ATTN>();
-
- }
-
- ///
- /// @brief Change the DIMM select in the address mapping
- /// @param[in] i_bitmap DIMM select bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_dimm_select_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_DIMM_SELECT, TT::CFG_AMAP_DIMM_SELECT_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the MRANK0 address mapping when not in 5D mode
- /// @param[in] i_bitmap MRANK0 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_mrank0_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_MRANK0, TT::CFG_AMAP_MRANK0_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the MRANK0 address mapping when in 5D mode
- /// @param[in] i_bitmap MRANK0 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_mrank0_bit_5d( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK0, TT::CFG_AMAP_SRANK0_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the MRANK1 address mapping when not in 5D mode
- /// @param[in] i_bitmap MRANK1 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_mrank1_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_MRANK1, TT::CFG_AMAP_MRANK1_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the MRANK1 address mapping when in 5D mode
- /// @param[in] i_bitmap MRANK1 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_mrank1_bit_5d( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK1, TT::CFG_AMAP_SRANK1_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the MRANK2 address mapping when in 5D mode
- /// @param[in] i_bitmap MRANK2 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_mrank2_bit_5d( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK2, TT::CFG_AMAP_SRANK2_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the SRANK0 address mapping when in 5D mode
- /// @param[in] i_bitmap SRANK0 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_srank0_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK0, TT::CFG_AMAP_SRANK0_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the SRANK1 address mapping
- /// @param[in] i_bitmap SRANK1 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_srank1_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK1, TT::CFG_AMAP_SRANK1_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the SRANK2 address mapping
- /// @param[in] i_bitmap SRANK2 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_srank2_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK2, TT::CFG_AMAP_SRANK2_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the BANK2 address mapping
- /// @param[in] i_bitmap BANK2 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_bank2_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_BANK2, TT::CFG_AMAP_BANK2_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the BANK1 address mapping
- /// @param[in] i_bitmap BANK1 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_bank1_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_BANK1, TT::CFG_AMAP_BANK1_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the BANK0 address mapping
- /// @param[in] i_bitmap BANK0 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_bank0_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_BANK0, TT::CFG_AMAP_BANK0_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the BANK_GROUP1 address mapping
- /// @param[in] i_bitmap BANK_GROUP1 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_bank_group1_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_BANK_GROUP1, TT::CFG_AMAP_BANK_GROUP1_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the BANK_GROUP0 address mapping
- /// @param[in] i_bitmap BANK_GROUP0 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_bank_group0_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_BANK_GROUP0, TT::CFG_AMAP_BANK_GROUP0_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW17 address mapping
- /// @param[in] i_bitmap ROW17 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row17_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW17, TT::CFG_AMAP_ROW17_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW16 address mapping
- /// @param[in] i_bitmap ROW16 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row16_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW16, TT::CFG_AMAP_ROW16_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW15 address mapping
- /// @param[in] i_bitmap ROW15 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row15_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW15, TT::CFG_AMAP_ROW15_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW14 address mapping
- /// @param[in] i_bitmap ROW14 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row14_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW14, TT::CFG_AMAP_ROW14_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW13 address mapping
- /// @param[in] i_bitmap ROW13 bit map in the address counter
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_row13_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW13, TT::CFG_AMAP_ROW13_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW12 address mapping
- /// @param[in] i_bitmap ROW12 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row12_bit( const uint64_t i_bitmap )
- {
- // CFG_AMAP_ROW12 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12 ,
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW12, TT::CFG_AMAP_ROW12_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW11 address mapping
- /// @param[in] i_bitmap ROW11 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row11_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW11, TT::CFG_AMAP_ROW11_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW10 address mapping
- /// @param[in] i_bitmap ROW10 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row10_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW10, TT::CFG_AMAP_ROW10_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW9 address mapping
- /// @param[in] i_bitmap ROW9 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row9_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW9, TT::CFG_AMAP_ROW9_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW8 address mapping
- /// @param[in] i_bitmap ROW8 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row8_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW8, TT::CFG_AMAP_ROW8_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW7 address mapping
- /// @param[in] i_bitmap ROW7 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row7_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW7, TT::CFG_AMAP_ROW7_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW6 address mapping
- /// @param[in] i_bitmap ROW6 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row6_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW6, TT::CFG_AMAP_ROW6_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW5 address mapping
- /// @param[in] i_bitmap ROW5 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row5_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW5, TT::CFG_AMAP_ROW5_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW4 address mapping
- /// @param[in] i_bitmap ROW4 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row4_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW4, TT::CFG_AMAP_ROW4_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW3 address mapping
- /// @param[in] i_bitmap ROW3 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row3_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW3, TT::CFG_AMAP_ROW3_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW2 address mapping
- /// @param[in] i_bitmap ROW2 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row2_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW2, TT::CFG_AMAP_ROW2_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW1 address mapping
- /// @param[in] i_bitmap ROW1 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row1_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW1, TT::CFG_AMAP_ROW1_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW0 address mapping
- /// @param[in] i_bitmap ROW0 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row0_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW0, TT::CFG_AMAP_ROW0_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the COL9 address mapping
- /// @param[in] i_bitmap COL9 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col9_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL9, TT::CFG_AMAP_COL9_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the COL8 address mapping
- /// @param[in] i_bitmap COL8 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col8_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL8, TT::CFG_AMAP_COL8_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the COL7 address mapping
- /// @param[in] i_bitmap COL7 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col7_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL7, TT::CFG_AMAP_COL7_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the COL6 address mapping
- /// @param[in] i_bitmap COL6 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col6_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL6, TT::CFG_AMAP_COL6_LEN>(i_bitmap);
- return;
- }
-
- /// @brief Change the COL5 address mapping
- /// @param[in] i_bitmap COL5 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col5_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL5, TT::CFG_AMAP_COL5_LEN>(i_bitmap);
- return;
- }
-
- /// @brief Change the COL4 address mapping
- /// @param[in] i_bitmap COL4 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col4_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL4, TT::CFG_AMAP_COL4_LEN>(i_bitmap);
- return;
- }
-
- /// @brief Change the COL3 address mapping
- /// @param[in] i_bitmap COL3 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col3_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL3, TT::CFG_AMAP_COL3_LEN>(i_bitmap);
- return;
- }
-
- /// @brief Change the COL2 address mapping
- /// @param[in] i_bitmap COL2 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col2_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL2, TT::CFG_AMAP_COL2_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the mcbist 64/128 byte control
- /// @param[in] i_state mss::ON if you want 64B, mss::OFF if you want 128B
- /// @return void
- ///
- inline void change_len64( const mss::states i_state )
- {
- iv_config.writeBit<TT::CFG_MCB_LEN64>(i_state);
- return;
- }
-
- ///
- /// @brief Change the random address all address mode
- /// @param[in] i_state mss::ON if you random addressing all addresses, mss::OFF if you don't
- /// @return void
- ///
- inline void random_address_all( const mss::states i_state )
- {
- iv_config.writeBit<TT::RAND_ADDR_ALL_ADDR_MODE_EN>(i_state);
- return;
- }
-
- ///
- /// @brief Change the broadcast sync enable bit
- /// @param[in] i_state mss::ON to enable the sync pulse, mss::OFF to disable
- /// @return void
- ///
- inline void broadcast_sync_enable( const mss::states i_state )
- {
- iv_config.writeBit<TT::SYNC_EN>(i_state);
- return;
- }
-
- ///
- /// @brief Change the broadcast mode sync timbase count
- /// @param[in] i_broadcast_timebase
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_broadcast_timebase( mss::mcbist::broadcast_timebase i_broadcast_timebase )
- {
- iv_config.insertFromRight<TT::SYNC_WAIT, TT::SYNC_WAIT_LEN>(i_broadcast_timebase);
- return;
- }
-
- ///
- /// @brief Change the mcbist thresholds
- /// @param[in] i_thresholds the new thresholds/stop conditions
- /// @return void
- ///
- inline void change_thresholds( const stop_conditions& i_thresholds )
- {
- iv_thresholds = i_thresholds;
- return;
- }
-
- ///
- /// @brief Change the data rotate value
- /// @param[in] i_data_rotate
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_data_rotate( mss::mcbist::data_rotate_mode i_data_rotate )
- {
- iv_data_rotate_cnfg.insertFromRight<TT::CFG_DATA_ROT, TT::CFG_DATA_ROT_LEN>(i_data_rotate);
- return;
- }
-
- ///
- /// @brief Get the data rotate value
- /// @note Assumes data is right aligned
- /// @return the data rotate value config
- ///
- inline uint64_t get_data_rotate()
- {
- uint64_t l_data_rotate = 0;
- iv_data_rotate_cnfg.extractToRight<TT::CFG_DATA_ROT, TT::CFG_DATA_ROT_LEN>(l_data_rotate);
- return l_data_rotate;
- }
-
- ///
- /// @brief Change the data seed mode value
- /// @param[in] i_data_seed_mode
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_data_seed_mode( const mss::mcbist::data_seed_mode i_data_seed_mode )
- {
- iv_data_rotate_cnfg.insertFromRight<TT::CFG_DATA_SEED_MODE, TT::CFG_DATA_SEED_MODE_LEN>(i_data_seed_mode);
- return;
- }
-
- ///
- /// @brief Get the data seed mode value
- /// @note Assumes data is right aligned
- /// @return the data seed mode value
- ///
- inline uint64_t get_data_seed_mode()
- {
- uint64_t l_data_seed_mode = 0;
- iv_data_rotate_cnfg.extractToRight<TT::CFG_DATA_SEED_MODE, TT::CFG_DATA_SEED_MODE_LEN>(l_data_seed_mode);
- return l_data_seed_mode;
- }
-
- ///
- /// @brief Change the data rotate seed for data bits 0:63
- /// @param[in] i_width
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_data_rotate_seed1( const uint64_t i_data_rotate_seed1 )
- {
- iv_data_rotate_seed.insertFromRight<TT::CFG_DATA_ROT_SEED1, TT::CFG_DATA_ROT_SEED1_LEN>(i_data_rotate_seed1);
- return;
- }
-
- ///
- /// @brief Get the data rotate seed for data bits 0:63
- /// @note Assumes data is right aligned
- /// @return the data rotate seed for data bits 0:63
- ///
- inline uint64_t get_data_rotate_seed1()
- {
- uint64_t l_data_rotate_seed1 = 0;
- iv_data_rotate_seed.extractToRight<TT::CFG_DATA_ROT_SEED1, TT::CFG_DATA_ROT_SEED1_LEN>(l_data_rotate_seed1);
- return l_data_rotate_seed1;
- }
-
- ///
- /// @brief Change the data rotate seed for data bits 64:79
- /// @param[in] i_width
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_data_rotate_seed2( const uint64_t i_data_rotate_seed2 )
- {
- iv_data_rotate_cnfg.insertFromRight<TT::CFG_DATA_ROT_SEED2, TT::CFG_DATA_ROT_SEED2_LEN>(i_data_rotate_seed2);
- return;
- }
-
- ///
- /// @brief Get the data rotate seed for data bits 64:79
- /// @note Assumes data is right aligned
- /// @return the data rotate seed for data bits 64:79
- ///
- inline uint64_t get_data_rotate_seed2()
- {
- uint64_t l_data_rotate_seed2 = 0;
- iv_data_rotate_cnfg.extractToRight<TT::CFG_DATA_ROT_SEED2, TT::CFG_DATA_ROT_SEED2_LEN>(l_data_rotate_seed2);
- return l_data_rotate_seed2;
- }
-
- ///
- /// @brief Change the compare mask CE trap enable
- /// @param[in] i_state mss::ON to enable the trap, mss::OFF to disable the trap
- /// @return void
- ///
- inline void change_ce_trap_enable( const mss::states i_state )
- {
- iv_compare_mask.writeBit<TT::CFG_TRAP_CE_ENABLE>(i_state);
- return;
- }
-
- ///
- /// @brief Change the compare mask UE trap enable
- /// @param[in] i_state mss::ON to enable the trap, mss::OFF to disable the trap
- /// @return void
- ///
- inline void change_ue_trap_enable( const mss::states i_state )
- {
- iv_compare_mask.writeBit<TT::CFG_TRAP_UE_ENABLE>(i_state);
- return;
- }
-
- ///
- /// @brief Change the compare mask MPE trap enable
- /// @param[in] i_state mss::ON to enable the trap, mss::OFF to disable the trap
- /// @return void
- ///
- inline void change_mpe_trap_enable( const mss::states i_state )
- {
- iv_compare_mask.writeBit<TT::CFG_TRAP_MPE_ENABLE>(i_state);
- return;
- }
-
- ///
- /// @brief Change the forced pause state
- /// @param[in] i_end the end_boundary to pause at
- /// @return void
- ///
- inline void change_forced_pause( const end_boundary& i_end )
- {
- if (i_end == end_boundary::DONT_CHANGE)
- {
- return;
- }
-
- // Clear all the forced pause bits so we don't stack pauses
- iv_config.clearBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR>();
- iv_config.clearBit<TT::MCBIST_CFG_PAUSE_AFTER_RANK>();
- iv_config.clearBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST>();
- iv_addr_gen.clearBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>();
-
- switch (i_end)
- {
- case end_boundary::STOP_AFTER_ADDRESS:
- iv_config.setBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR>();
- break;
-
- case end_boundary::STOP_AFTER_SLAVE_RANK:
- iv_config.setBit<TT::MCBIST_CFG_PAUSE_AFTER_RANK>();
- iv_addr_gen.setBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>();
- break;
-
- case end_boundary::STOP_AFTER_MASTER_RANK:
- iv_config.setBit<TT::MCBIST_CFG_PAUSE_AFTER_RANK>();
- iv_addr_gen.clearBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>();
- break;
-
- case end_boundary::STOP_AFTER_SUBTEST:
- iv_config.setBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST>();
- break;
-
- // None is all set, we cleared the bits above
- case end_boundary::NONE:
- break;
-
- // Default is a no forced pause (as we cleared all the bits)
- default:
- FAPI_INF("no forced pause state - end state %d unknown", i_end);
- break;
- };
-
- return;
- }
-
- ///
- /// @brief Calculate minimum command gap for BG_SCRUB
- /// @param[in] i_target the target behind which the memory sits
- /// @param[in] i_freq the DRAM frequency
- /// @param[in] i_size the sum of all DIMM sizes
- /// @param[out] o_min_cmd_gap the setting for MCBPARMQ_CFG_MIN_CMD_GAP
- /// @param[out] o_timebase the setting for MCBPARMQ_CFG_MIN_GAP_TIMEBASE
- ///
- inline void calculate_min_cmd_gap( const fapi2::Target<T>& i_target,
- const uint64_t i_freq,
- const uint64_t i_size,
- uint64_t& o_min_cmd_gap,
- mss::states& o_timebase )
- {
- constexpr uint64_t l_seconds = SEC_IN_HOUR * BG_SCRUB_IN_HOURS;
- constexpr uint64_t MIN_CMD_GAP = 0x001;
-
- // Sanity check our inputs, just assert if bad since they come directly from eff_config
- // this will prevent us from any divide by zero problems
- if ((i_freq == 0) || (i_size == 0))
- {
- FAPI_ERR("received zero memory freq or size in calculate_min_cmd_gap");
- fapi2::Assert(false);
- }
-
- // MIN CMD GAP = TOTAL CYCLES / TOTAL ADDRESSES
- // TOTAL CYCLES = 12 hours x 60 min/hr x 60 sec/min x [DRAM freq] cycles/sec x
- // 1/2 (MEM logic runs half DRAM freq)
- const uint64_t l_mem_cycles_per_sec = (i_freq * T_PER_MT) / 2;
- const uint64_t l_total_cycles = l_seconds * l_mem_cycles_per_sec;
-
- // TOTAL ADDRESSES = sum over all dimms of ( [DIMM CAPACITY]/128B )
- const uint64_t l_total_addresses = i_size * BYTES_PER_GB / 128;
-
- const auto l_min_cmd_gap = l_total_cycles / l_total_addresses;
-
- // If we're greater than the timebase, set the multiplier and divide down to get the gap setting
- if (CMD_TIMEBASE < l_min_cmd_gap)
- {
- o_min_cmd_gap = l_min_cmd_gap / CMD_TIMEBASE;
- o_timebase = mss::ON;
- return;
- }
-
- // If we're greater than the max gap setting, get as close to 12 hours as we can instead of just truncating
- if (l_min_cmd_gap > MAX_CMD_GAP)
- {
- // work backwards to calculate what the total scrub time would be with the highest cmd gap with no multiplier...
- const uint64_t l_scrub_time_fff = (l_total_addresses * MAX_CMD_GAP) / l_mem_cycles_per_sec;
- // and with the lowest cmd gap with the multiplier
- const uint64_t l_scrub_time_001 = (l_total_addresses * CMD_TIMEBASE) / l_mem_cycles_per_sec;
-
- if ((l_seconds - l_scrub_time_fff) > (l_scrub_time_001 - l_seconds))
- {
- FAPI_INF("%s gap is greater than the field will allow. Setting to: %03x", mss::c_str(i_target), MIN_CMD_GAP);
- o_min_cmd_gap = MIN_CMD_GAP;
- o_timebase = mss::ON;
- }
- else
- {
- FAPI_INF("%s gap is greater than the field will allow. Setting to: %03x", mss::c_str(i_target), MAX_CMD_GAP);
- o_min_cmd_gap = MAX_CMD_GAP;
- o_timebase = mss::OFF;
- }
-
- return;
- }
-
- // Else, we're good to just set the calculated gap value directly
- o_min_cmd_gap = l_min_cmd_gap;
- o_timebase = mss::OFF;
- }
-
- ///
- /// @brief Change MCBIST Speed
- /// @param[in] i_target the target behind which the memory sits
- /// @param[in] i_speed the speed eunmeration
- /// @return FAPI2_RC_SUCCSS iff ok
- ///
- inline fapi2::ReturnCode change_speed( const fapi2::Target<T>& i_target, const speed i_speed )
- {
- switch (i_speed)
- {
- case speed::LUDICROUS:
- change_min_cmd_gap(0);
- change_min_gap_timebase(mss::OFF);
- return fapi2::FAPI2_RC_SUCCESS;
- break;
-
- case speed::BG_SCRUB:
- {
- uint64_t l_freq = 0;
- uint64_t l_size = 0;
- uint64_t l_min_cmd_gap = 0;
- mss::states l_timebase = mss::OFF;
-
- constexpr uint64_t l_seconds = SEC_IN_HOUR * BG_SCRUB_IN_HOURS;
-
- FAPI_TRY( mss::freq(i_target, l_freq) );
- FAPI_TRY( mss::eff_memory_size<mss::mc_type::NIMBUS>(i_target, l_size) );
-
- calculate_min_cmd_gap(i_target, l_freq, l_size, l_min_cmd_gap, l_timebase);
-
- FAPI_INF("%s setting bg scrub speed: %dMT/s, memory: %dGB, duration: %ds, gap: %d",
- mss::c_str(i_target), l_freq, l_size, l_seconds, l_min_cmd_gap);
-
- change_min_cmd_gap(l_min_cmd_gap);
- change_min_gap_timebase(l_timebase);
-
- return fapi2::FAPI2_RC_SUCCESS;
- }
- break;
-
- // Otherwise it's SAME_SPEED or something else in which case we do nothing
- default:
- break;
- };
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
- /// @brief Get a list of ports involved in the program
- /// @tparam P fapi2 target type of port
- /// @param[in] i_target the target for this program
- /// @return vector of port targets
- ///
- template< fapi2::TargetType P >
- std::vector<fapi2::Target<P>> get_port_list( const fapi2::Target<T>& i_target ) const;
-
- ///
- /// @brief Change MCBIST Stop-on-error conditions (end boundaries)
- /// @param[in] i_end the end boundary
- /// @note By default the MCBIST is programmed to always stop after an errored address. This API
- /// allows the caller to force a stop at a boundary or to force no stopping on errors
- ///
- inline void change_end_boundary( const end_boundary i_end )
- {
- // Which bit in the end boundary which siginifies this is a slave rank detect situation
- constexpr uint64_t SLAVE_RANK_INDICATED_BIT = 61;
-
- // If there's no change, just get outta here
- if (i_end == DONT_CHANGE)
- {
- return;
- }
-
- // The values of the enum were crafted so that we can simply insertFromRight into the register.
- // We take note of whether to set the slave or master rank indicator and set that as well.
- // The hardware has to have a 1 or a 0 - so there is no choice for the rank detection. So it
- // doesn't matter that we're processing other end boundaries here - they'll just look like we
- // asked for a master rank detect.
- iv_config.insertFromRight<TT::CFG_PAUSE_ON_ERROR_MODE, TT::CFG_PAUSE_ON_ERROR_MODE_LEN>(i_end);
-
- uint64_t l_detect_slave = fapi2::buffer<uint64_t>(i_end).getBit<SLAVE_RANK_INDICATED_BIT>();
- iv_addr_gen.writeBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>( l_detect_slave );
- FAPI_INF("load MCBIST end boundaries 0x%016lx detect slave? %s",
- i_end, (l_detect_slave == 1 ? "yes" : "no") );
- }
-
- ///
- /// @brief Change the mcbist min command gap
- /// @param[in] i_gap minimum number of cycles between commands when cfg_en_randcmd_gap is a 0 (disabled)
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_min_cmd_gap( const uint64_t i_gap )
- {
- iv_parameters.insertFromRight<TT::MIN_CMD_GAP, TT::MIN_CMD_GAP_LEN>(i_gap);
- return;
- }
-
- ///
- /// @brief Change the mcbist gap timebase
- /// @param[in] i_tb When set to mss::ON and cfg_en_randcmd_gap is a 0, then the number of minimum
- /// cycles between commands will be cfg_min_cmd_gap multiplied by 2^13.
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_min_gap_timebase( const bool i_tb )
- {
- iv_parameters.writeBit<TT::MIN_GAP_TIMEBASE>(i_tb);
- return;
- }
-
- ///
- /// @brief Change the mcbist min command gap blind steer
- /// @param[in] i_gap min gap between commands when doing steering
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_min_cmd_gap_blind_steer( const uint64_t i_gap )
- {
- iv_parameters.insertFromRight<TT::MIN_CMD_GAP_BLIND_STEER, TT::MIN_CMD_GAP_BLIND_STEER_LEN>(i_gap);
- return;
- }
-
- ///
- /// @brief Change the mcbist gap timebase for blind steer
- /// @param[in] i_program the program in question
- /// @param[in] i_tb When set to mss::ON and cfg_en_randcmd_gap is a 0, then the number of minimum
- /// cycles between commands will be cfg_min_cmd_gap multiplied by 2^13.
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_min_gap_timebase_blind_steer( const bool i_tb )
- {
- iv_parameters.writeBit<TT::MIN_GAP_TIMEBASE_BLIND_STEER>(i_tb);
- return;
- }
-
- ///
- /// @brief Change the weights for random mcbist reads, writes
- /// @param[in] i_weight
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_randcmd_wgt( const uint64_t i_weight )
- {
- iv_parameters.insertFromRight<TT::RANDCMD_WGT, TT::RANDCMD_WGT_LEN>(i_weight);
- return;
- }
-
- ///
- /// @brief Change the weights for random mcbist command gaps
- /// @param[in] i_program the program in question
- /// @param[in] i_weight
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_randgap_wgt( const uint64_t i_weight )
- {
- iv_parameters.insertFromRight<TT::RANDGAP_WGT, TT::RANDGAP_WGT_LEN>(i_weight);
- return;
- }
-
- ///
- /// @brief Enable or disable mcbist clock monitoring
- /// @param[in] i_monitor mss::ON to monitor
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_clock_monitor_en( const bool i_monitor )
- {
- iv_parameters.writeBit<TT::CLOCK_MONITOR_EN>(i_monitor);
- return;
- }
-
- ///
- /// @brief Enable or disable mcbist random command gaps
- /// @param[in] i_rndgap mss::ON to enable
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_en_randcmd_gap( const bool i_rndgap )
- {
- iv_parameters.writeBit<TT::EN_RANDCMD_GAP>(i_rndgap);
- return;
- }
-
- ///
- /// @brief Enable or disable mcbist BC4 support
- /// @param[in] i_bc4 mss::ON to enable
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_bc4_en( const bool i_bc4 )
- {
- iv_parameters.writeBit<TT::BC4_EN>(i_bc4);
- return;
- }
-
- ///
- /// @brief Change fixed width address generator config
- /// @param[in] i_width
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_fixed_width( const uint64_t i_width )
- {
- iv_addr_gen.insertFromRight<TT::FIXED_WIDTH, TT::FIXED_WIDTH_LEN>(i_width);
- return;
- }
-
- ///
- /// @brief Get the fixed width address config
- /// @note Assumes data is right aligned
- /// @return the fixed width address config
- ///
- inline uint64_t get_fixed_width()
- {
- uint64_t l_fixed_width = 0;
- iv_addr_gen.extractToRight<TT::FIXED_WIDTH, TT::FIXED_WIDTH_LEN>(l_fixed_width);
- return l_fixed_width;
- }
-
- ///
- /// @brief Enable or disable address counting mode for address config 0
- /// @param[in] i_mode mss::ON to enable
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_address_counter_mode0( const bool i_mode )
- {
- fapi2::buffer<uint64_t> l_value;
- iv_addr_gen.extract<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- l_value.writeBit<0>(i_mode);
- iv_addr_gen.insert<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- return;
- }
-
- ///
- /// @brief Enable or disable address counting mode for address config 1
- /// @param[in] i_mode mss::ON to enable
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_address_counter_mode1( const bool i_mode )
- {
- fapi2::buffer<uint64_t> l_value;
- iv_addr_gen.extract<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- l_value.writeBit<1>(i_mode);
- iv_addr_gen.insert<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- return;
- }
-
- ///
- /// @brief Enable or disable address counting mode for address config 2
- /// @param[in] i_mode mss::ON to enable
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_address_counter_mode2( const bool i_mode )
- {
- fapi2::buffer<uint64_t> l_value;
- iv_addr_gen.extract<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- l_value.writeBit<2>(i_mode);
- iv_addr_gen.insert<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- return;
- }
-
- ///
- /// @brief Enable or disable address counting mode for address config 3
- /// @param[in] i_program, the program in question
- /// @param[in] i_mode mss::ON to enable
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_address_counter_mode3( const bool i_mode )
- {
- fapi2::buffer<uint64_t> l_value;
- iv_addr_gen.extract<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- l_value.writeBit<3>(i_mode);
- iv_addr_gen.insert<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- return;
- }
-
-
- ///
- /// @brief Enable or disable maint address mode
- /// @param[in] i_mode mss::ON to enable
- /// @warn Address counter modes must be 0 for this to work.
- /// @note When enabled subtest complement bits become 3-bit port-dimm selector field
- /// (Note: when turning this off, make sure you clear or reprogram complement bits)
- /// @return void
- ///
- inline void change_maint_address_mode( const bool i_mode )
- {
- iv_addr_gen.writeBit<TT::MAINT_ADDR_MODE_EN>(i_mode);
- return;
- }
-
- ///
- /// @brief Enable or disable broadcast mode
- /// @param[in] i_program the program in question
- /// @param[in] i_mode mss::ON to enable
- /// @warn Maint address mode must be enabled for this to work
- /// @return void
- ///
- inline void change_maint_broadcast_mode( const bool i_mode )
- {
- iv_addr_gen.writeBit<TT::MAINT_BROADCAST_MODE_EN>(i_mode);
- return;
- }
-
-
- ///
- /// @brief Enable or disable slave rank boundary detect
- /// @param[in] i_program the program in question
- /// @param[in] i_mode mss::ON to enable
- /// @return void
- ///
- inline void change_srank_boundaries( const bool i_mode )
- {
- iv_addr_gen.writeBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>(i_mode);
- return;
- }
-
- ///
- /// @brief Enable or disable async mode
- /// @param[in] i_program the program in question
- /// @param[in] i_mode mss::ON to enable, programs will run async
- /// @return void
- ///
- inline void change_async( const bool i_mode )
- {
- iv_async = i_mode;
- return;
- }
-
- ///
- /// @brief Select the port(s) to be used by the MCBIST
- /// @param[in] i_ports uint64_t representing the ports. Multiple bits set imply broadcast
- /// i_ports is a right-aligned uint64_t, of which only the right-most 4 bits are used. The register
- /// field is defined such that the left-most bit in the field represents port 0, the right most
- /// bit in the field represents port 3. So, to run on port 0, i_ports should be 0b1000. 0b0001
- /// (or 0x1) is port 3 - not port 0
- /// @return void
- ///
- inline void select_ports( const uint64_t i_ports )
- {
- iv_control.insertFromRight<TT::PORT_SEL, TT::PORT_SEL_LEN>(i_ports);
- FAPI_INF("mcbist select ports: iv_control 0x%016lx (ports: 0x%x)", iv_control, i_ports);
- return;
- }
-
- ///
- /// @brief Process mcbist errors
- /// @tparam MCBIST target type
- /// @tparam T fapi2::TargetType representing the fapi2 target which
- /// contains the MCBIST engine (e.g., fapi2::TARGET_TYPE_MCBIST)
- /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
- /// This shouldn't be called in firmware? Check with PRD
- ///
- inline fapi2::ReturnCode process_errors( const fapi2::Target<T> i_target ) const
- {
- // Until reading the error array is documented, comparison errors 'just' result in
- // a flag indicating there was a problem on port.
- {
- fapi2::buffer<uint64_t> l_data;
- uint64_t l_port = 0;
- uint64_t l_subtest = 0;
- FAPI_TRY( mss::getScom(i_target, TT::MCBSTATQ_REG, l_data), "%s Failed getScom", mss::c_str(i_target) );
- l_data.extractToRight<TT::LOGGED_ERROR_ON_PORT_INDICATOR, TT::LOGGED_ERROR_ON_PORT_INDICATOR_LEN>(l_port);
- l_data.extractToRight<TT::SUBTEST_NUM_INDICATOR, TT::SUBTEST_NUM_INDICATOR_LEN>(l_subtest);
-
- FAPI_ASSERT( l_port == 0,
- fapi2::MSS_MEMDIAGS_COMPARE_ERROR_IN_LAST_PATTERN()
- .set_MCBIST_TARGET(i_target)
- .set_PORT(mss::first_bit_set(l_port))
- .set_SUBTEST(l_subtest),
- "%s MCBIST error on port %d subtest %d", mss::c_str(i_target), mss::first_bit_set(l_port), l_subtest );
- }
-
- // Check for UE errors
- {
- fapi2::buffer<uint64_t> l_read0;
- fapi2::buffer<uint64_t> l_read1;
-
- FAPI_TRY( mss::getScom(i_target, TT::SRERR0_REG, l_read0), "%s Failed getScom", mss::c_str(i_target) );
- FAPI_TRY( mss::getScom(i_target, TT::SRERR1_REG, l_read1), "%s Failed getScom", mss::c_str(i_target) );
-
- FAPI_ASSERT( ((l_read0 == 0) && (l_read1 == 0)),
- fapi2::MSS_MEMDIAGS_ERROR_IN_LAST_PATTERN()
- .set_MCBIST_TARGET(i_target)
- .set_STATUS0(l_read0)
- .set_STATUS1(l_read1),
- "%s MCBIST scrub/read error reg0: 0x%016lx reg1: 0x%016lx", mss::c_str(i_target), l_read0, l_read1 );
- }
-
- FAPI_INF("%s Execution success - no errors seen from MCBIST program", mss::c_str(i_target));
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
- /// @brief Store off the pattern index. We'll use this to write the patterns when we load the program
- /// @param[in] i_index an index such as mss::mcbist::PATTERN_0
- /// @return fapi2::ReturnCode checks for bad pattern index
- /// @warning if you give a pattern index which does not exist your pattern will not change.
- /// @note patterns default to PATTERN_0
- ///
- inline fapi2::ReturnCode change_pattern( const uint64_t i_pattern )
- {
- FAPI_INF("change MCBIST pattern index %d", i_pattern);
-
- // Sanity check the pattern since they're just numbers.
- FAPI_ASSERT( i_pattern <= mcbist::NO_PATTERN,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(i_pattern),
- "Attempting to change a pattern which does not exist %d", i_pattern );
-
- iv_pattern = i_pattern;
-
- return fapi2::FAPI2_RC_SUCCESS;
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
- /// @brief Store off the random 24b data seed index. We'll use this to write the 24b random data seeds when we load the program
- /// @param[in] i_index an index such as mss::mcbist::RANDOM24_SEEDS_0
- /// @return fapi2::ReturnCode checks for bad pattern index
- /// @warning if you give a pattern index which does not exist your pattern will not change.
- /// @note patterns default to PATTERN_0
- ///
- inline fapi2::ReturnCode change_random_24b_seeds( const uint64_t i_random24_seed )
- {
- FAPI_INF("change MCBIST 24b random data seeds index %d", i_random24_seed );
-
- // TK Want a new RC for random 24
- // Sanity check the pattern since they're just numbers.
- FAPI_ASSERT( i_random24_seed <= mcbist::NO_RANDOM24_SEEDS,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(i_random24_seed),
- "Attempting to change to a 24b random data seed which does not exist %d", i_random24_seed );
-
- iv_random24_data_seed = i_random24_seed;
-
- return fapi2::FAPI2_RC_SUCCESS;
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
- /// @brief Store off the random 24b data seed mapping index. We'll use this to write the 24b random data seed mappings when we load the program
- /// @param[in] i_index an index such as mss::mcbist::RANDOM24_SEEDS_0
- /// @return fapi2::ReturnCode checks for bad pattern index
- /// @warning if you give a pattern index which does not exist your pattern will not change.
- /// @note patterns default to PATTERN_0
- ///
- inline fapi2::ReturnCode change_random_24b_maps( const uint64_t i_random24_map )
- {
- FAPI_INF("change MCBIST 24b random data seed mappings index %d", i_random24_map );
-
- // TK Want a new RC for random 24
- // Sanity check the pattern since they're just numbers.
- FAPI_ASSERT( i_random24_map <= mcbist::NO_RANDOM24_SEED_MAP,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(i_random24_map),
- "Attempting to change to a random seed map which does not exist %d", i_random24_map );
-
- iv_random24_seed_map = i_random24_map;
-
- return fapi2::FAPI2_RC_SUCCESS;
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
- /// @brief checks if two programs are equal
- /// @param[in] i_rhs program to compare
- /// @return bool true if equal
- ///
- inline bool operator==( const program<T>& i_rhs ) const
- {
- //checks the vector first, to save time if they're not equal (no sense in checking everything else)
- if(iv_subtests != i_rhs.iv_subtests)
- {
- return false;
- }
-
- //checks everything else
- bool l_equal = iv_parameters == i_rhs.iv_parameters;
- l_equal &= iv_addr_gen == i_rhs.iv_addr_gen;
- l_equal &= iv_test_type == i_rhs.iv_test_type;
- l_equal &= iv_poll == i_rhs.iv_poll;
- l_equal &= iv_addr_map0 == i_rhs.iv_addr_map0;
- l_equal &= iv_addr_map1 == i_rhs.iv_addr_map1;
- l_equal &= iv_addr_map2 == i_rhs.iv_addr_map2;
- l_equal &= iv_addr_map3 == i_rhs.iv_addr_map3;
- l_equal &= iv_config == i_rhs.iv_config;
- l_equal &= iv_control == i_rhs.iv_control;
- l_equal &= iv_async == i_rhs.iv_async;
- l_equal &= iv_pattern == i_rhs.iv_pattern;
- l_equal &= iv_thresholds == i_rhs.iv_thresholds;
- l_equal &= iv_data_rotate_cnfg == i_rhs.iv_data_rotate_cnfg;
- l_equal &= iv_data_rotate_seed == i_rhs.iv_data_rotate_seed;
- l_equal &= iv_random24_data_seed == i_rhs.iv_random24_data_seed;
- l_equal &= iv_random24_seed_map == i_rhs.iv_random24_seed_map;
- l_equal &= iv_data_rotate_cnfg == i_rhs.iv_data_rotate_cnfg;
- l_equal &= iv_data_rotate_seed == i_rhs.iv_data_rotate_seed;
- l_equal &= iv_compare_mask == i_rhs.iv_compare_mask;
-
- //returns result
- return l_equal;
- }
-
- // Vector of subtests. Note the MCBIST subtests are spread across
- // 8 registers - 4 subtests fit in one 64b register
- // (16 bits/test, 4 x 16 == 64, 4x8 = 32 subtests)
- // We keep a vector of 16 bit subtests here, and we program the
- // MCBIST engine (i.e., spread the subtests over the 8 registers)
- // when we're told to execute the program.
- std::vector< subtest_t<T> > iv_subtests;
-
- // Place to hold the value of the MCBIST Memory Parameter Register. We'll scom
- // it when we execute the program.
- fapi2::buffer<uint64_t> iv_parameters;
-
- // Place to hold the value of the MCBIST Address Generation Config. We'll scom
- // it when we execute the program.
- fapi2::buffer<uint64_t> iv_addr_gen;
-
- test_type iv_test_type;
-
- poll_parameters iv_poll;
-
- // Address Map Registers
- // We might want to refactor to a vector ... BRS
- // uint64_t iv_addr_map0;
- // uint64_t iv_addr_map1;
- // uint64_t iv_addr_map2;
- // uint64_t iv_addr_map3;
- //Perhaps this isn't the right approach, we can discuss and change if needed, leaving the above comments for now
- fapi2::buffer<uint64_t> iv_addr_map0;
- fapi2::buffer<uint64_t> iv_addr_map1;
- fapi2::buffer<uint64_t> iv_addr_map2;
- fapi2::buffer<uint64_t> iv_addr_map3;
-
- // Data Rotate Seed and Config Registers
- fapi2::buffer<uint64_t> iv_data_rotate_cnfg;
- fapi2::buffer<uint64_t> iv_data_rotate_seed;
-
- // Config register
- fapi2::buffer<uint64_t> iv_config;
-
- // Control register
- fapi2::buffer<uint64_t> iv_control;
-
- // True iff we want to run in asynchronous mode
- bool iv_async;
-
- // The pattern for the pattern generator
- uint64_t iv_pattern;
-
- // The pattern for the random 24b seeds
- uint64_t iv_random24_data_seed;
-
- // The pattern for the random 24b data seed mapping
- uint64_t iv_random24_seed_map;
-
- // The pattern for the pattern generator
- fapi2::buffer<uint64_t> iv_compare_mask;
-
- // The error stop conditions, thresholds for the program
- stop_conditions iv_thresholds;
-};
-
-///
-/// @brief Load the mcbist config register
-/// @tparam T fapi2::TargetType of the MCBIST engine
-/// @tparam TT the mssTraits associtated with T
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_config( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- FAPI_INF("loading MCBIST Config 0x%016lx", i_program.iv_config);
-
- // Copy the program's config settings - we want to modify them if we're in sim.
- fapi2::buffer<uint64_t> l_config = i_program.iv_config;
-
- // If we're running in Cronus, there is no interrupt so any attention bits will
- // hang something somewhere. Make sure there's nothing in this config which can
- // turn on attention bits unless we're running in hostboot
-#ifndef __HOSTBOOT_MODULE
- l_config.template clearBit<TT::CFG_ENABLE_HOST_ATTN>();
- l_config.template clearBit<TT::CFG_ENABLE_SPEC_ATTN>();
-#endif
-
- FAPI_TRY( mss::putScom(i_target, TT::CFGQ_REG, l_config) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Load the mcbist control register
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_control( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- FAPI_INF("loading MCBIST Control 0x%016lx", i_program.iv_control);
- return mss::putScom(i_target, TT::CNTLQ_REG, i_program.iv_control);
-}
-
-
-///
-/// @brief Load the address generator config
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_addr_gen( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- FAPI_INF("loading MCBIST Address Generation 0x%016lx", i_program.iv_addr_gen);
- return mss::putScom(i_target, TT::MCBAGRAQ_REG, i_program.iv_addr_gen);
-}
-
-///
-/// @brief Configure address range based on index
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start 64b right-aligned address
-/// @param[in] i_end 64b right-aligned address
-/// @param[in] i_index which start/end pair to effect
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note Only the right-most 37 bits of the start/end are used.
-/// @warn if address counting mode is enabled in the MCBIST program, these bits are start, len
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode config_address_range( const fapi2::Target<T>& i_target, const uint64_t i_start,
- const uint64_t i_end, const uint64_t i_index )
-{
- FAPI_INF("config MCBIST address range %d start: 0x%016lx (0x%016lx), end/len 0x%016lx (0x%016lx)",
- i_index, i_start, (i_start << 26), i_end, (i_end << 26));
- FAPI_TRY( mss::putScom(i_target, TT::address_pairs[i_index].first, i_start << 26) );
- FAPI_TRY( mss::putScom(i_target, TT::address_pairs[i_index].second, i_end << 26) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Configure address range 0
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start 64b right-aligned address
-/// @param[in] i_end 64b right-aligned address
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note Only the right-most 37 bits of the start/end are used.
-/// @warn if address counting mode is enabled in the MCBIST program, these bits are start, len
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode config_address_range0( const fapi2::Target<T>& i_target, const uint64_t i_start,
- const uint64_t i_end )
-{
- return config_address_range(i_target, i_start, i_end, 0);
-}
-
-
-///
-/// @brief Configure address range 1
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start 64b right-aligned address
-/// @param[in] i_end 64b right-aligned address
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note Only the right-most 37 bits of the start/end are used.
-/// @warn if address counting mode is enabled in the MCBIST program, these bits are start, len
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode config_address_range1( const fapi2::Target<T>& i_target, const uint64_t i_start,
- const uint64_t i_end )
-{
- return config_address_range(i_target, i_start, i_end, 1);
-}
-
-
-///
-/// @brief Configure address range 2
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start 64b right-aligned address
-/// @param[in] i_end 64b right-aligned address
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note Only the right-most 37 bits of the start/end are used.
-/// @warn if address counting mode is enabled in the MCBIST program, these bits are start, len
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode config_address_range2( const fapi2::Target<T>& i_target, const uint64_t i_start,
- const uint64_t i_end )
-{
- return config_address_range(i_target, i_start, i_end, 2);
-}
-
-
-///
-/// @brief Configure address range 3
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start 64b right-aligned address
-/// @param[in] i_end 64b right-aligned address
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note Only the right-most 37 bits of the start/end are used.
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode config_address_range3( const fapi2::Target<T>& i_target, const uint64_t i_start,
- const uint64_t i_end )
-{
- return config_address_range(i_target, i_start, i_end, 3);
-}
-
-///
-/// @brief Start or stop the MCBIST engine
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start_stop bool START for starting, STOP otherwise
-/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode start_stop( const fapi2::Target<T>& i_target, bool i_start_stop )
-{
- // This is the same as the CCS start_stop ... perhaps we need one template for all
- // 'engine' control functions? BRS
- fapi2::buffer<uint64_t> l_buf;
- FAPI_TRY(mss::getScom(i_target, TT::CNTLQ_REG, l_buf));
-
- FAPI_TRY( mss::putScom(i_target, TT::CNTLQ_REG,
- i_start_stop ? l_buf.setBit<TT::MCBIST_START>() : l_buf.setBit<TT::MCBIST_STOP>()) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Resume the MCBIST engine
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode resume( const fapi2::Target<T>& i_target )
-{
- fapi2::buffer<uint64_t> l_buf;
-
- FAPI_TRY( mss::getScom(i_target, TT::CNTLQ_REG, l_buf) );
- FAPI_TRY( mss::putScom(i_target, TT::CNTLQ_REG, l_buf.setBit<TT::MCBIST_RESUME>()) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Reset the MCBIST error logs
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode reset_errors( const fapi2::Target<T>& i_target )
-{
- fapi2::buffer<uint64_t> l_buf;
-
- FAPI_TRY( mss::getScom(i_target, TT::CNTLQ_REG, l_buf) );
- FAPI_TRY( mss::putScom(i_target, TT::CNTLQ_REG, l_buf.setBit<TT::MCBIST_RESET_ERRORS>()) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Return whether or not the MCBIST engine has an operation in progress
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the target to effect
-/// @param[out] i_in_progress - false if no operation is in progress
-/// @return FAPI2_RC_SUCCESS if getScom succeeded
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode in_progress( const fapi2::Target<T>& i_target, bool o_in_progress )
-{
- fapi2::buffer<uint64_t> l_buf;
-
- FAPI_TRY(mss::getScom(i_target, TT::STATQ_REG, l_buf));
- o_in_progress = l_buf.getBit<TT::MCBIST_IN_PROGRESS>();
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Execute the mcbist program
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist program to execute
-/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode execute( const fapi2::Target<T>& i_target, const program<T>& i_program );
-
-///
-/// @brief Load a set of MCBIST subtests in to the MCBIST registers
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode load_mcbmr( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program );
-
-
-///
-/// @brief Load a set of MCBIST address map registers
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] the target to effect
-/// @param[in] the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode load_mcbamr( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- // Vector? Can decide when we fully understand the methods to twiddle the maps themselves. BRS
- FAPI_INF("load MCBIST address map register 0: 0x%016lx", i_program.iv_addr_map0);
- FAPI_TRY( mss::putScom(i_target, TT::MCBAMR0A0Q_REG, i_program.iv_addr_map0) );
-
- FAPI_INF("load MCBIST address map register 1: 0x%016lx", i_program.iv_addr_map1);
- FAPI_TRY( mss::putScom(i_target, TT::MCBAMR1A0Q_REG, i_program.iv_addr_map1) );
-
- FAPI_INF("load MCBIST address map register 2: 0x%016lx", i_program.iv_addr_map2);
- FAPI_TRY( mss::putScom(i_target, TT::MCBAMR2A0Q_REG, i_program.iv_addr_map2) );
-
- FAPI_INF("load MCBIST address map register 3: 0x%016lx", i_program.iv_addr_map3);
- FAPI_TRY( mss::putScom(i_target, TT::MCBAMR3A0Q_REG, i_program.iv_addr_map3) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Load MCBIST Memory Parameter Register
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] the target to effect
-/// @param[in] the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_mcbparm( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- FAPI_INF("load MCBIST parameter register: 0x%016lx", i_program.iv_parameters);
- return mss::putScom(i_target, TT::MCBPARMQ_REG, i_program.iv_parameters);
-}
-
-///
-/// @brief Clear mcbist errors
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target fapi2::Target<T> of the MCBIST
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode clear_errors( const fapi2::Target<T> i_target )
-{
- // TK: Clear the more detailed errors checked above
- FAPI_INF("Clear MCBIST error state");
- FAPI_TRY( mss::putScom(i_target, TT::MCBSTATQ_REG, 0) );
- FAPI_TRY( mss::putScom(i_target, TT::SRERR0_REG, 0) );
- FAPI_TRY( mss::putScom(i_target, TT::SRERR1_REG, 0) );
- FAPI_TRY( mss::putScom(i_target, TT::FIRQ_REG, 0) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load MCBIST pattern given a pattern
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_pattern an mcbist::patterns
-/// @param[in] i_invert whether to invert the pattern or not
-/// @note this overload disappears when we have real patterns.
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_pattern( const fapi2::Target<T>& i_target, const pattern& i_pattern, const bool i_invert )
-{
- uint64_t l_address = TT::PATTERN0_REG;
-
- // TODO RTC:155561 Add random pattern support.
-
- // TK: algorithm for patterns which include ECC bits in them
- // Loop over the cache lines in the pattern. We write one half of the cache line
- // to the even register and half to the odd.
- for (const auto& l_cache_line : i_pattern)
- {
- fapi2::buffer<uint64_t> l_value_first = i_invert ? ~l_cache_line.first : l_cache_line.first;
- fapi2::buffer<uint64_t> l_value_second = i_invert ? ~l_cache_line.second : l_cache_line.second;
- FAPI_INF("Loading cache line pattern 0x%016lx 0x%016lx", l_value_first, l_value_second);
- FAPI_TRY( mss::putScom(i_target, l_address, l_value_first) );
- FAPI_TRY( mss::putScom(i_target, ++l_address, l_value_second) );
- ++l_address;
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load MCBIST pattern given an index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_index the pattern index
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_pattern( const fapi2::Target<T>& i_target, uint64_t i_pattern )
-{
- if (NO_PATTERN != i_pattern)
- {
- bool l_invert = false;
-
- // Sanity check the pattern since they're just numbers.
- // Belt-and-suspenders FAPI_ASSERT as the sim-only uses this API directly.
- FAPI_ASSERT( i_pattern <= mcbist::LAST_PATTERN,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(i_pattern),
- "Attempting to load a pattern which does not exist %d", i_pattern );
-
- // The indexes are split in to even and odd where the odd indexes don't really exist.
- // They're just indicating that we want to grab the even index and invert it. So calculate
- // the proper vector index and acknowledge the inversion if necessary.
- if (mss::is_odd(i_pattern))
- {
- l_invert = true;
- i_pattern -= 1;
- }
-
- return load_pattern(i_target, patterns[i_pattern / 2], l_invert);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load MCBIST pattern given an index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_pattern( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- return load_pattern(i_target, i_program.iv_pattern);
-}
-
-///
-/// @brief Load MCBIST maint pattern given a pattern
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_pattern an mcbist::patterns
-/// @param[in] i_invert whether to invert the pattern or not
-/// @note this overload disappears when we have real patterns.
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode load_maint_pattern( const fapi2::Target<T>& i_target, const pattern& i_pattern, const bool i_invert );
-
-
-///
-/// @brief Load MCBIST maint pattern given an index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_index the pattern index
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_maint_pattern( const fapi2::Target<T>& i_target, uint64_t i_pattern )
-{
- if (NO_PATTERN != i_pattern)
- {
- bool l_invert = false;
-
- // Sanity check the pattern since they're just numbers.
- // Belt-and-suspenders FAPI_ASSERT as the sim-only uses this API directly.
- FAPI_ASSERT( i_pattern <= mcbist::LAST_PATTERN,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(i_pattern),
- "Attempting to load a pattern which does not exist %d", i_pattern );
-
- // The indexes are split in to even and odd where the odd indexes don't really exist.
- // They're just indicating that we want to grab the even index and invert it. So calculate
- // the proper vector index and acknowledge the inversion if necessary.
- if ((i_pattern % 2) != 0)
- {
- l_invert = true;
- i_pattern -= 1;
- }
-
- return load_maint_pattern(i_target, patterns[i_pattern / 2], l_invert);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load MCBIST Maint mode pattern given an index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_maint_pattern( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- return load_maint_pattern(i_target, i_program.iv_pattern);
-}
-
-
-///
-/// @brief Load MCBIST 24b random data seeds given a pattern index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_random24_data_seed mcbist::random24_data_seed
-/// @param[in] i_random24_map mcbist::random24_seed_map
-/// @param[in] i_invert whether to invert the pattern or not
-/// @note this overload disappears when we have real patterns.
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode load_random24b_seeds( const fapi2::Target<T>& i_target,
- const random24_data_seed& i_random24_data_seed,
- const random24_seed_map& i_random24_map,
- const bool i_invert );
-
-///
-/// @brief Load MCBIST 24b Random data seeds given a pattern index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_data_seed the 24b random data seed index
-/// @param[in] i_seed_map the 24b random data map index
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_random24b_seeds( const fapi2::Target<T>& i_target, uint64_t i_data_seed,
- uint64_t i_seed_map )
-{
- if ((NO_RANDOM24_SEEDS != i_data_seed) && (NO_RANDOM24_SEED_MAP != i_seed_map))
- {
- bool l_invert = false;
-
- // TK Want a new RC for random 24
- // Sanity check the pattern since they're just numbers.
- // Belt-and-suspenders FAPI_ASSERT as the sim-only uses this API directly.
- FAPI_ASSERT( i_data_seed <= mcbist::LAST_RANDOM24_SEEDS,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(i_data_seed),
- "Attempting to load a 24b random data seed set which does not exist %d", i_data_seed );
-
- // The indexes are split in to even and odd where the odd indexes don't really exist.
- // They're just indicating that we want to grab the even index and invert it. So calculate
- // the proper vector index and acknowledge the inversion if necessary.
- if ((i_data_seed % 2) != 0)
- {
- l_invert = true;
- i_data_seed -= 1;
- }
-
- return load_random24b_seeds(i_target, random24_data_seeds[i_data_seed / 2], random24_seed_maps[i_seed_map], l_invert);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load MCBIST 24b Random data seeds given a program conatining a pattern index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_random24b_seeds( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- return load_random24b_seeds(i_target, i_program.iv_random24_data_seed, i_program.iv_random24_seed_map);
-}
-
-///
-/// @brief Loads the FIFO value if needed
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_fifo_mode( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
-
- // Checks if FIFO mode is required by checking all subtests
- const auto l_subtest_it = std::find_if(i_program.iv_subtests.begin(),
- i_program.iv_subtests.end(), []( const mss::mcbist::subtest_t<T>& i_rhs) -> bool
- {
- return i_rhs.fifo_mode_required();
- });
-
- // if the FIFO load is not needed (no subtest requiring it was found), just exit out
- if(l_subtest_it == i_program.iv_subtests.end())
- {
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
- // Turns on FIFO mode
- constexpr mss::states FIFO_ON = mss::states::ON;
-
- FAPI_TRY(mss::configure_wrq(i_target, FIFO_ON));
- FAPI_TRY(mss::configure_rrq(i_target, FIFO_ON));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load MCBIST data patterns and configuration
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_data_config( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- uint64_t l_data_rotate_cnfg_addr = TT::DATA_ROTATE_CNFG_REG;
- uint64_t l_data_rotate_seed_addr = TT::DATA_ROTATE_SEED_REG;
-
- // First load the data pattern registers
- FAPI_INF("Loading the data pattern seeds!");
- FAPI_TRY( mss::mcbist::load_pattern(i_target, i_program.iv_pattern) );
-
- // Load the 24b random data pattern seeds registers
- FAPI_INF("Loading the 24b Random data pattern seeds!");
- FAPI_TRY( mss::mcbist::load_random24b_seeds(i_target, i_program.iv_random24_data_seed,
- i_program.iv_random24_seed_map) );
-
- // Load the maint data pattern into the Maint entry in the RMW buffer
- // TK Might want to only load the RMW buffer if maint commands are present in the program
- // The load takes 33 Putscoms to load 16 64B registers, might slow down mcbist programs that
- // don't need the RMW buffer maint entry loaded
- FAPI_INF("Loading the maint data pattern into the RMW buffer!");
- FAPI_TRY( mss::mcbist::load_maint_pattern(i_target, i_program.iv_pattern) );
-
- FAPI_INF("Loading the data rotate config and seeds!");
- FAPI_TRY( mss::putScom(i_target, l_data_rotate_cnfg_addr, i_program.iv_data_rotate_cnfg) );
- FAPI_TRY( mss::putScom(i_target, l_data_rotate_seed_addr, i_program.iv_data_rotate_seed) );
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Load MCBIST data compare mask registers
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode load_data_compare_mask( const fapi2::Target<T>& i_target,
- const mcbist::program<T>& i_program );
-
-///
-/// @brief Load MCBIST Thresholds
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_thresholds the thresholds
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_thresholds( const fapi2::Target<T>& i_target, const uint64_t i_thresholds )
-{
- FAPI_INF("load MCBIST threshold register: 0x%016lx", i_thresholds );
- return mss::putScom(i_target, TT::THRESHOLD_REG, i_thresholds);
-}
-
-///
-/// @brief Load MCBIST Threshold Register
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the program containing the thresholds
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_thresholds( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- return load_thresholds(i_target, i_program.iv_thresholds);
-}
-
-///
-/// @brief Read entries from MCBIST Read Modify Write (RMW) array
-/// @tparam T, the fapi2::TargetType
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start_addr the array address to read first
-/// @param[in] i_num_entries the number of array entries to read
-/// @param[in] i_roll_over_for_compare_mode set to true if only using first
-/// NUM_COMPARE_INFO_ENTRIES of array, so array address rolls over at correct value
-/// @param[out] o_data vector of output data
-/// @param[out] o_ecc_data vector of ecc data
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note The number of entries in the array depends on i_roll_over_for_compare_mode parameter:
-/// (NUM_COMPARE_LOG_ENTRIES for false, NUM_COMPARE_INFO_ENTRIES for true) but user may read more than
-/// that since reads work in a circular buffer fashion
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode read_rmw_array(const fapi2::Target<T>& i_target,
- const uint64_t i_start_addr,
- const uint64_t i_num_entries,
- const bool i_roll_over_for_compare_mode,
- std::vector< fapi2::buffer<uint64_t> >& o_data,
- std::vector< fapi2::buffer<uint64_t> >& o_ecc_data);
-
-///
-/// @brief Read entries from MCBIST Read Modify Write (RMW) array
-/// Overload for the case where o_ecc_data is not needed
-/// @tparam T, the fapi2::TargetType
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start_addr the array address to read first
-/// @param[in] i_num_entries the number of array entries to read
-/// @param[in] i_roll_over_for_compare_mode set to true if only using first
-/// NUM_COMPARE_INFO_ENTRIES of array, so array address rolls over at correct value
-/// @param[out] o_data vector of output data
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note The number of entries in the array depends on i_roll_over_for_compare_mode parameter:
-/// (NUM_COMPARE_LOG_ENTRIES for false, NUM_COMPARE_INFO_ENTRIES for true) but user may read more than
-/// that since reads work in a circular buffer fashion
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode read_rmw_array(const fapi2::Target<T>& i_target,
- const uint64_t i_start_addr,
- const uint64_t i_num_entries,
- const bool i_roll_over_for_compare_mode,
- std::vector< fapi2::buffer<uint64_t> >& o_data)
-{
- std::vector< fapi2::buffer<uint64_t> > l_temp;
- return read_rmw_array(i_target, i_start_addr, i_num_entries, i_roll_over_for_compare_mode, o_data, l_temp);
-}
-
-///
-/// @brief Read entries from MCBIST Read Buffer (RB) array
-/// @tparam T, the fapi2::TargetType
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start_addr the array address to read first
-/// @param[in] i_num_entries the number of array entries to read
-/// @param[out] o_data vector of output data
-/// @param[out] o_ecc_data vector of ecc data
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode read_rb_array(const fapi2::Target<T>& i_target,
- const uint64_t i_start_addr,
- const uint64_t i_num_entries,
- std::vector< fapi2::buffer<uint64_t> >& o_data,
- std::vector< fapi2::buffer<uint64_t> >& o_ecc_data);
-
-///
-/// @brief Read entries from MCBIST Read Buffer (RB) array
-/// Overload for the case where o_ecc_data is not needed
-/// @tparam T, the fapi2::TargetType
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start_addr the array address to read first
-/// @param[in] i_num_entries the number of array entries to read
-/// @param[out] o_data vector of output data
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode read_rb_array(const fapi2::Target<T>& i_target,
- const uint64_t i_start_addr,
- const uint64_t i_num_entries,
- std::vector< fapi2::buffer<uint64_t> >& o_data)
-{
- std::vector< fapi2::buffer<uint64_t> > l_temp;
- return read_rb_array(i_target, i_start_addr, i_num_entries, o_data, l_temp);
-}
-
-///
+////
/// @brief Checks if broadcast mode is capable of being enabled on this target
/// @param[in] i_target the target to effect
/// @param[in] i_bc_force attribute's value to force off broadcast mode
@@ -3206,20 +77,23 @@ const mss::states is_broadcast_capable_helper(const fapi2::Target<fapi2::TARGET_
///
/// @brief Checks if broadcast mode is capable of being enabled on this target
+/// @tparam MC the mc type of the T
/// @tparam T, the fapi2::TargetType
/// @param[in] i_target the target to effect
/// @return o_capable - yes iff these vector of targets are broadcast capable
///
-template< fapi2::TargetType T >
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
const mss::states is_broadcast_capable(const fapi2::Target<T>& i_target);
+
///
/// @brief Checks if broadcast mode is capable of being enabled on this vector of targets
+/// @tparam MC the mc type of the T
/// @tparam T, the fapi2::TargetType
/// @param[in] i_targets the vector of targets to analyze
/// @return o_capable - yes iff these vector of targets are broadcast capable
///
-template< fapi2::TargetType T >
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
const mss::states is_broadcast_capable(const std::vector<fapi2::Target<T>>& i_targets);
///
@@ -3227,191 +101,55 @@ const mss::states is_broadcast_capable(const std::vector<fapi2::Target<T>>& i_ta
/// @param[in] i_target the target to effect
/// @return o_capable - yes iff these vector of targets are broadcast capable
///
-const mss::states is_broadcast_capable(const std::vector<mss::dimm::kind>& i_kinds);
+const mss::states is_broadcast_capable(const std::vector<mss::dimm::kind<>>& i_kinds);
+
///
/// @brief Configures all of the ports for broadcast mode
+/// @tparam MC the mc type of the T
/// @tparam T, the fapi2::TargetType
/// @param[in] i_target the target to effect
/// @param[out] o_port_select - the configuration of the selected ports
/// @return FAPI2_RC_SUCCSS iff ok
///
-template< fapi2::TargetType T >
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
fapi2::ReturnCode setup_broadcast_port_select(const fapi2::Target<T>& i_target, uint64_t& o_port_select);
///
/// @brief Enables broadcast mode
+/// @tparam MC the mc type of the T
/// @tparam T, the fapi2::TargetType
/// @param[in] i_target the target to effect
/// @param[in,out] io_program the mcbist::program
/// @return FAPI2_RC_SUCCSS iff ok
///
-template< fapi2::TargetType T >
-fapi2::ReturnCode enable_broadcast_mode(const fapi2::Target<T>& i_target, mcbist::program<T>& io_program);
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
+fapi2::ReturnCode enable_broadcast_mode(const fapi2::Target<T>& i_target, mcbist::program<>& io_program);
///
-/// @brief Configures broadcast mode, if it is needed
-/// @tparam T, the fapi2::TargetType
+/// @brief Load MCBIST ECC (and?) spare data pattern given a pattern - explorer specialization
/// @param[in] i_target the target to effect
-/// @param[in,out] io_program the mcbist::program
+/// @param[in] i_pattern an mcbist::patterns
+/// @param[in] i_invert whether to invert the pattern or not
+/// @note this overload disappears when we have real patterns.
/// @return FAPI2_RC_SUCCSS iff ok
///
-template< fapi2::TargetType T >
-fapi2::ReturnCode configure_broadcast_mode(const fapi2::Target<T>& i_target, mcbist::program<T>& io_program)
-{
- // If we're not capable to do broadcast mode on this target, exit out
- const auto l_broadcast_capable = is_broadcast_capable(i_target);
-
- if(l_broadcast_capable == mss::states::NO)
- {
- FAPI_INF("%s is not broadcast capable, skipping enablement of broadcast mode", mss::c_str(i_target));
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
- // Enable broadcast mode
- FAPI_INF("%s is broadcast capable, enabling broadcast mode", mss::c_str(i_target));
- return enable_broadcast_mode(i_target, io_program);
-}
-
-} // mcbist namespace
-
-///
-/// @brief Reads the contents of the MCBISTFIRMASK
-/// @tparam T fapi2 Target Type - derived
-/// @tparam TT traits type defaults to mcbistTraits<T>
-/// @param[in] i_target the target on which to operate
-/// @param[out] o_data the register data
-/// @return fapi2::fapi2_rc_success if ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode read_mcbfirmask( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+template< >
+inline fapi2::ReturnCode load_eccspare_pattern<mss::mc_type::NIMBUS>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const pattern& i_pattern,
+ const bool i_invert )
{
- o_data = 0;
+ // First up assemble the pattern
+ const auto l_pattern = generate_eccspare_pattern(i_pattern, i_invert);
- FAPI_TRY( mss::getScom(i_target, TT::MCBFIRMASK_REG, o_data ), "%s failed to read MCBISTFIRMASK regiser",
- mss::c_str(i_target));
- FAPI_DBG("%s MCBISTFIRMASK has data 0x%016lx", mss::c_str(i_target), o_data);
+ FAPI_TRY(fapi2::putScom(i_target, MCBIST_MCBFDQ, l_pattern));
fapi_try_exit:
return fapi2::current_err;
}
+} // namespace MCBIST
-///
-/// @brief Writes the contents of the MCBISTFIRMASK
-/// @tparam T fapi2 Target Type - derived
-/// @tparam TT traits type defaults to mcbistTraits<T>
-/// @param[in] i_target the target on which to operate
-/// @param[in] i_data the register data
-/// @return fapi2::fapi2_rc_success if ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode write_mcbfirmask( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- FAPI_TRY( mss::putScom(i_target, TT::MCBFIRMASK_REG, i_data ), "%s failed to write MCBISTFIRMASK regiser",
- mss::c_str(i_target));
- FAPI_DBG("%s MCBISTFIRMASK has data 0x%016lx", mss::c_str(i_target), i_data);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Reads the contents of the MCBISTFIRQ
-/// @tparam T fapi2 Target Type - derived
-/// @tparam TT traits type defaults to mcbistTraits<T>
-/// @param[in] i_target the target on which to operate
-/// @param[out] o_data the register data
-/// @return fapi2::fapi2_rc_success if ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode read_mcbfirq( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- o_data = 0;
-
- FAPI_TRY( mss::getScom(i_target, TT::MCBFIRQ_REG, o_data ), "%s failed to read MCBISTFIRQ regiser",
- mss::c_str(i_target));
- FAPI_DBG("%s MCBISTFIRQ has data 0x%016lx", mss::c_str(i_target), o_data);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Writes the contents of the MCBISTFIRQ
-/// @tparam T fapi2 Target Type - derived
-/// @tparam TT traits type defaults to mcbistTraits<T>
-/// @param[in] i_target the target on which to operate
-/// @param[in] i_data the register data
-/// @return fapi2::fapi2_rc_success if ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode write_mcbfirq( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- FAPI_TRY( mss::putScom(i_target, TT::MCBFIRQ_REG, i_data ), "%s failed to write MCBISTFIRQ regiser",
- mss::c_str(i_target));
- FAPI_DBG("%s MCBISTFIRQ has data 0x%016lx", mss::c_str(i_target), i_data);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Sets the mask for program complete
-/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to mcbistTraits<T>
-/// @param[in,out] io_data the value of the register
-/// @param[in] i_state the state to write into the enable
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<T> >
-inline void set_mcbist_program_complete_mask( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
-{
- io_data.writeBit<TT::MCB_PROGRAM_COMPLETE_MASK>(i_state == mss::states::ON);
- FAPI_DBG("set_mcbist_program_complete_mask to %d 0x%016lx", i_state, io_data);
-}
-
-///
-/// @brief Sets the mask for WAT debug ATTN
-/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to mcbistTraits<T>
-/// @param[in,out] io_data the value of the register
-/// @param[in] i_state the state to write into the enable
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<T> >
-inline void set_mcbist_wat_debug_attn_mask( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
-{
- io_data.writeBit<TT::MCB_WAT_DEBUG_ATTN_MASK>(i_state == mss::states::ON);
- FAPI_DBG("set_mcbist_wat_debug_attn_mask to %d 0x%016lx", i_state, io_data);
-}
-
-///
-/// @brief Clears the program complete and WAT debug ATTN
-/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to mcbistTraits<T>
-/// @param[in,out] io_data the value of the register
-/// @param[in] i_state the state to write into the enable
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<T> >
-inline void clear_mcbist_program_complete( fapi2::buffer<uint64_t>& io_data )
-{
- io_data.writeBit<TT::MCB_PROGRAM_COMPLETE>(mss::states::OFF);
- io_data.writeBit<TT::MCB_WAT_DEBUG_ATTN>(mss::states::OFF);
- FAPI_DBG("clear_mcbist_program_complete to %d 0x%016lx", mss::states::OFF, io_data);
-}
-
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<T> >
-inline void get_mcbist_program_complete_mask( const fapi2::buffer<uint64_t> i_data, mss::states& o_state )
-{
- o_state = i_data.getBit<TT::MCB_PROGRAM_COMPLETE>() ? mss::states::HIGH : mss::states::LOW;
- FAPI_DBG("get_mcbist_program_complete_mask %d", o_state);
-}
-
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<T> >
-inline void get_mcbist_wat_debug_attn_mask( const fapi2::buffer<uint64_t> i_data, mss::states& o_state )
-{
- o_state = i_data.getBit<TT::MCB_WAT_DEBUG_ATTN>() ? mss::states::HIGH : mss::states::LOW;
- FAPI_DBG("mcbist_wat_debug_attn_mask %d", o_state);
-}
-
-} // mss namespace
+} // namespace mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist_traits.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist_traits.H
index 6936f7aff..7d9d3ab2c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist_traits.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist_traits.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,645 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mcbist_traits.H
+/// @brief Run and manage the MCBIST engine
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_MCBIST_TRAITS_H_
+#define _MSS_MCBIST_TRAITS_H_
+
+#include <fapi2.H>
+
+#include <lib/shared/mss_const.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H>
+#include <p9_mc_scom_addresses.H>
+#include <p9_mc_scom_addresses_fld.H>
+
+namespace mss
+{
+
+///
+/// @class mcbistMCTraits
+/// @brief A MC to MC_TARGET_TYPE mapping
+///
+template<>
+class mcbistMCTraits<mss::mc_type::NIMBUS>
+{
+ public:
+ static constexpr fapi2::TargetType MC_TARGET_TYPE = fapi2::TARGET_TYPE_MCBIST;
+ static constexpr fapi2::TargetType FWMS_ADDR_TARGET_TYPE = fapi2::TARGET_TYPE_MCA;
+
+ ///
+ /// @brief Returns an error for memdiags compare error in last pattern
+ /// @return memdiags error
+ ///
+ static fapi2::MSS_MEMDIAGS_COMPARE_ERROR_IN_LAST_PATTERN memdiags_compare_error_in_last_pattern()
+ {
+ return fapi2::MSS_MEMDIAGS_COMPARE_ERROR_IN_LAST_PATTERN();
+ }
+
+ ///
+ /// @brief Returns an error for memdiags error in last pattern
+ /// @return memdiags error
+ ///
+ static fapi2::MSS_MEMDIAGS_ERROR_IN_LAST_PATTERN memdiags_error_in_last_pattern()
+ {
+ return fapi2::MSS_MEMDIAGS_ERROR_IN_LAST_PATTERN();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags failed to start
+ /// @return memdiags error
+ ///
+ static fapi2::MSS_MEMDIAGS_MCBIST_FAILED_TO_START memdiags_failed_to_start()
+ {
+ return fapi2::MSS_MEMDIAGS_MCBIST_FAILED_TO_START();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags failed to stop
+ /// @return memdiags error
+ ///
+ static fapi2::MSS_MEMDIAGS_MCBIST_FAILED_TO_STOP memdiags_failed_to_stop()
+ {
+ return fapi2::MSS_MEMDIAGS_MCBIST_FAILED_TO_STOP();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags has a non-functional port
+ /// @return memdiags error
+ ///
+ static fapi2::MSS_MEMDIAGS_PORT_NOT_FUNCTIONAL memdiags_port_not_functional()
+ {
+ return fapi2::MSS_MEMDIAGS_PORT_NOT_FUNCTIONAL();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags super fast init failed to init
+ /// @return memdiags error
+ ///
+ static fapi2::MSS_MEMDIAGS_SUPERFAST_INIT_FAILED_TO_INIT memdiags_sf_init_failed_init()
+ {
+ return fapi2::MSS_MEMDIAGS_SUPERFAST_INIT_FAILED_TO_INIT();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags super fast read failed to init
+ /// @return memdiags error
+ ///
+ static fapi2::MSS_MEMDIAGS_SUPERFAST_READ_FAILED_TO_INIT memdiags_sf_read_failed_init()
+ {
+ return fapi2::MSS_MEMDIAGS_SUPERFAST_READ_FAILED_TO_INIT();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags continuous scrub failed to init
+ /// @return memdiags error
+ ///
+ static fapi2::MSS_MEMDIAGS_CONTINUOUS_SCRUB_FAILED_TO_INIT memdiags_continuous_scrub_failed_init()
+ {
+ return fapi2::MSS_MEMDIAGS_CONTINUOUS_SCRUB_FAILED_TO_INIT();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags targeted scrub failed to init
+ /// @return memdiags error
+ ///
+ static fapi2::MSS_MEMDIAGS_TARGETED_SCRUB_FAILED_TO_INIT memdiags_targeted_scrub_failed_init()
+ {
+ return fapi2::MSS_MEMDIAGS_TARGETED_SCRUB_FAILED_TO_INIT();
+ }
+
+ ///
+ /// @brief Returns an error if memdiags is already at a boundary
+ /// @return memdiags error
+ ///
+ static fapi2::MSS_MEMDIAGS_ALREADY_AT_BOUNDARY memdiags_already_at_boundary()
+ {
+ return fapi2::MSS_MEMDIAGS_ALREADY_AT_BOUNDARY();
+ }
+
+ ///
+ /// @brief Returns an error if MCBIST timesout
+ /// @return MCBIST error
+ ///
+ static fapi2::MSS_MCBIST_TIMEOUT mcbist_timeout()
+ {
+ return fapi2::MSS_MCBIST_TIMEOUT();
+ }
+
+ ///
+ /// @brief Returns an error if MCBIST has an unknown failure
+ /// @return MCBIST error
+ ///
+ static fapi2::MSS_MCBIST_UNKNOWN_FAILURE mcbist_unknown_failure()
+ {
+ return fapi2::MSS_MCBIST_UNKNOWN_FAILURE();
+ }
+
+ ///
+ /// @brief Returns an error if MCBIST has a data miscompare
+ /// @return MCBIST error
+ ///
+ static fapi2::MSS_MCBIST_DATA_FAIL mcbist_data_fail()
+ {
+ return fapi2::MSS_MCBIST_DATA_FAIL();
+ }
+};
+
+///
+/// @class mcbistTraits
+/// @brief a collection of traits associated with the Nimbus MCBIST engine or hardware
+///
+template<>
+class mcbistTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCBIST>
+{
+ public:
+
+ // PORT_TYPE used in continuous_scrub_operation
+ static constexpr enum fapi2::TargetType PORT_TYPE = fapi2::TARGET_TYPE_MCA;
+
+ // ATTN support
+ static constexpr mss::states CFG_ENABLE_ATTN_SUPPORT = mss::states::YES;
+ static constexpr mss::states BROADCAST_CAPABLE = mss::states::YES;
+
+ // Multi-ports, dimms
+ static constexpr mss::states MULTI_PORTS = mss::states::YES;
+
+ // Subtest
+ static constexpr size_t SUBTEST_PER_REG = 4;
+ static constexpr size_t SUBTEST_PER_PROGRAM = 32;
+ static constexpr size_t BITS_IN_SUBTEST = 16; // 2 Bytes
+ static constexpr size_t LEFT_SHIFT = (sizeof(uint64_t) * 8) - BITS_IN_SUBTEST;
+
+ // LARGEST_ADDRESS
+ static constexpr uint64_t LARGEST_ADDRESS = ~0 >> mss::mcbist::address::MAGIC_PAD;
+
+ // Length of expected patterns
+ static constexpr uint64_t EXPECTED_PATTERN_SIZE = 4;
+
+ // Size
+ static constexpr size_t PORTS_PER_MCBIST = mss::PORTS_PER_MCBIST;
+ static constexpr size_t MAX_DIMM_PER_PORT = mss::MAX_DIMM_PER_PORT;
+ static constexpr size_t MAX_PRIMARY_RANKS_PER_PORT = mss::MAX_PRIMARY_RANKS_PER_PORT;
+ static constexpr size_t MAX_DQ_BITS = 72;
+ static constexpr size_t MAX_DQ_NIBBLES = MAX_DQ_BITS /
+ BITS_PER_NIBBLE; ///< For ISDIMMs are 18 DQ nibbles for DQ 72 bits
+ static constexpr size_t MAX_DRAMS_X8 = MAX_DQ_BITS / BITS_PER_BYTE; ///< For x8's there are 9 DRAM for 72 bits
+ static constexpr size_t MAX_DRAMS_X4 = MAX_DQ_BITS / BITS_PER_NIBBLE; ///< For x4's there are 18 DRAM for 72 bits
+
+ /// MCBIST "memory registers" - config for subtests.
+ static constexpr uint64_t MCBMR0_REG = MCBIST_MCBMR0Q;
+ static constexpr uint64_t MCBMR1_REG = MCBIST_MCBMR1Q;
+ static constexpr uint64_t MCBMR2_REG = MCBIST_MCBMR2Q;
+ static constexpr uint64_t MCBMR3_REG = MCBIST_MCBMR3Q;
+ static constexpr uint64_t MCBMR4_REG = MCBIST_MCBMR4Q;
+ static constexpr uint64_t MCBMR5_REG = MCBIST_MCBMR5Q;
+ static constexpr uint64_t MCBMR6_REG = MCBIST_MCBMR6Q;
+ static constexpr uint64_t MCBMR7_REG = MCBIST_MCBMR7Q;
+ static constexpr uint64_t CFGQ_REG = MCBIST_MCBCFGQ;
+ static constexpr uint64_t CNTLQ_REG = MCBIST_MCB_CNTLQ;
+ static constexpr uint64_t STATQ_REG = MCBIST_MCB_CNTLSTATQ;
+ static constexpr uint64_t MCBSTATQ_REG = MCBIST_MCBSTATQ;
+ static constexpr uint64_t MCBPARMQ_REG = MCBIST_MCBPARMQ;
+ static constexpr uint64_t MCBAGRAQ_REG = MCBIST_MCBAGRAQ;
+ static constexpr uint64_t SRERR0_REG = MCBIST_MBSEC0Q;
+ static constexpr uint64_t SRERR1_REG = MCBIST_MBSEC1Q;
+ static constexpr uint64_t THRESHOLD_REG = MCBIST_MBSTRQ;
+ static constexpr uint64_t FIRQ_REG = MCBIST_MCBISTFIRQ;
+ static constexpr uint64_t LAST_ADDR_REG = MCBIST_MCBMCATQ;
+
+ static constexpr uint64_t MCBAMR0A0Q_REG = MCBIST_MCBAMR0A0Q;
+ static constexpr uint64_t MCBAMR1A0Q_REG = MCBIST_MCBAMR1A0Q;
+ static constexpr uint64_t MCBAMR2A0Q_REG = MCBIST_MCBAMR2A0Q;
+ static constexpr uint64_t MCBAMR3A0Q_REG = MCBIST_MCBAMR3A0Q;
+ static constexpr uint64_t LFSR_REG = MCBIST_MCBLFSRA0Q;
+ static const std::vector<uint64_t> LFSR_MASK_VALUES;
+
+ // MCBIST FIR registers
+ static constexpr uint64_t MCBFIRMASK_REG = MCBIST_MCBISTFIRMASK;
+ static constexpr uint64_t MCBFIRQ_REG = MCBIST_MCBISTFIRQ;
+
+ // All of the pattern registers are calculated off of this base
+ static constexpr uint64_t PATTERN0_REG = MCBIST_MCBFD0Q;
+ static constexpr uint64_t PATTERN1_REG = MCBIST_MCBFD1Q;
+ static constexpr uint64_t PATTERN2_REG = MCBIST_MCBFD2Q;
+ static constexpr uint64_t PATTERN3_REG = MCBIST_MCBFD3Q;
+ static constexpr uint64_t PATTERN4_REG = MCBIST_MCBFD4Q;
+ static constexpr uint64_t PATTERN5_REG = MCBIST_MCBFD5Q;
+ static constexpr uint64_t PATTERN6_REG = MCBIST_MCBFD6Q;
+ static constexpr uint64_t PATTERN7_REG = MCBIST_MCBFD7Q;
+
+ static constexpr uint64_t DATA_ROTATE_CNFG_REG = MCBIST_MCBDRCRQ;
+ static constexpr uint64_t DATA_ROTATE_SEED_REG = MCBIST_MCBDRSRQ;
+
+ static constexpr uint16_t MAX_ADDRESS_START_END_REGISTERS = 4;
+ static constexpr uint64_t START_ADDRESS_0 = MCBIST_MCBSA0Q;
+ static constexpr uint64_t START_ADDRESS_1 = MCBIST_MCBSA1Q;
+ static constexpr uint64_t START_ADDRESS_2 = MCBIST_MCBSA2Q;
+ static constexpr uint64_t START_ADDRESS_3 = MCBIST_MCBSA3Q;
+
+ static constexpr uint64_t END_ADDRESS_0 = MCBIST_MCBEA0Q;
+ static constexpr uint64_t END_ADDRESS_1 = MCBIST_MCBEA1Q;
+ static constexpr uint64_t END_ADDRESS_2 = MCBIST_MCBEA2Q;
+ static constexpr uint64_t END_ADDRESS_3 = MCBIST_MCBEA3Q;
+
+ static constexpr uint64_t RANDOM_DATA_SEED0 = MCBIST_MCBRDS0Q;
+ static constexpr uint64_t RANDOM_DATA_SEED1 = MCBIST_MCBRDS1Q;
+
+
+ static constexpr uint64_t MBSTRQ_CFG_PAUSE_ON_MPE = MCBIST_MBSTRQ_CFG_PAUSE_ON_MPE;
+
+
+ // MCBIST Compare Masks, used to setup the ECC traps
+ // TK there is one reg per port, does writing to this one write to all?
+ static constexpr uint64_t COMPARE_MASK = MCA_MCBCM;
+
+ static constexpr uint64_t PATTERN_COUNT = 4;
+
+ // Sometimes we want to access the start/end address registers based off
+ // of an index, like master rank. This allows us to do that.
+ static const std::pair<uint64_t, uint64_t> address_pairs[];
+ static constexpr uint64_t ADDRESS_PAIRS = 4;
+
+ // Subtest types that need to be run in FIFO mode
+ static const std::vector< mss::mcbist::op_type > FIFO_MODE_REQUIRED_OP_TYPES;
+
+ // Which bit in the end boundary which siginifies this is a slave rank detect situation
+ static constexpr uint64_t SLAVE_RANK_INDICATED_BIT = 61;
+
+ enum
+ {
+ // The start/end address config registers have common lengths and bits, just including 1 below
+ MCB_ADDR_CONFIG = MCBIST_MCBEA0Q_CFG_END_ADDR_0,
+ MCB_ADDR_CONFIG_LEN = MCBIST_MCBEA0Q_CFG_END_ADDR_0_LEN,
+
+ // Subtest control bits. These are the same in all '16 bit subtest' field
+ COMPL_1ST_CMD = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_1ST_CMD,
+ COMPL_2ND_CMD = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_2ND_CMD,
+ COMPL_3RD_CMD = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_3RD_CMD,
+ ADDR_REV_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_REV_MODE,
+ ADDR_RAND_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_RAND_MODE,
+
+ // Goto subtests use the compl_1st - rand_mode to define the subtest to jump to
+ GOTO_SUBTEST = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_1ST_CMD,
+ GOTO_SUBTEST_LEN = 5,
+
+ ECC_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ECC_MODE,
+ DATA_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DATA_MODE,
+ DATA_MODE_LEN = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DATA_MODE_LEN,
+ ADDR_SEL = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_SEL,
+ ADDR_SEL_LEN = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_SEL_LEN,
+ OP_TYPE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_OP_TYPE,
+ OP_TYPE_LEN = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_OP_TYPE_LEN,
+ DONE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DONE,
+
+ SYNC_EN = MCBIST_MCBCFGQ_BROADCAST_SYNC_EN,
+ SYNC_WAIT = MCBIST_MCBCFGQ_BROADCAST_SYNC_WAIT,
+ SYNC_WAIT_LEN = MCBIST_MCBCFGQ_BROADCAST_SYNC_WAIT_LEN,
+
+ PORT_SEL = MCBIST_MCB_CNTLQ_MCBCNTL_PORT_SEL,
+ PORT_SEL_LEN = MCBIST_MCB_CNTLQ_MCBCNTL_PORT_SEL_LEN,
+
+ MCBIST_START = MCBIST_MCB_CNTLQ_START,
+ MCBIST_STOP = MCBIST_MCB_CNTLQ_STOP,
+ MCBIST_RESUME = MCBIST_MCB_CNTLQ_RESUME_FROM_PAUSE,
+ MCBIST_RESET_ERRORS = MCBIST_MCB_CNTLQ_RESET_ERROR_LOGS,
+
+ MCBIST_IN_PROGRESS = MCBIST_MCB_CNTLSTATQ_IP,
+ MCBIST_DONE = MCBIST_MCB_CNTLSTATQ_DONE,
+ MCBIST_FAIL = MCBIST_MCB_CNTLSTATQ_FAIL,
+
+ MIN_CMD_GAP = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP,
+ MIN_CMD_GAP_LEN = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_LEN,
+ MIN_GAP_TIMEBASE = MCBIST_MCBPARMQ_CFG_MIN_GAP_TIMEBASE,
+ MIN_CMD_GAP_BLIND_STEER = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_BLIND_STEER,
+ MIN_CMD_GAP_BLIND_STEER_LEN = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_BLIND_STEER_LEN,
+ MIN_GAP_TIMEBASE_BLIND_STEER = MCBIST_MCBPARMQ_CFG_MIN_GAP_TIMEBASE_BLIND_STEER,
+ RANDCMD_WGT = MCBIST_MCBPARMQ_CFG_RANDCMD_WGT,
+ RANDCMD_WGT_LEN = MCBIST_MCBPARMQ_CFG_RANDCMD_WGT_LEN,
+ CLOCK_MONITOR_EN = MCBIST_MCBPARMQ_CFG_CLOCK_MONITOR_EN,
+ EN_RANDCMD_GAP = MCBIST_MCBPARMQ_CFG_EN_RANDCMD_GAP,
+ RANDGAP_WGT = MCBIST_MCBPARMQ_CFG_RANDGAP_WGT,
+ RANDGAP_WGT_LEN = MCBIST_MCBPARMQ_CFG_RANDGAP_WGT_LEN,
+ BC4_EN = MCBIST_MCBPARMQ_CFG_BC4_EN,
+
+ FIXED_WIDTH = MCBIST_MCBAGRAQ_CFG_FIXED_WIDTH,
+ FIXED_WIDTH_LEN = MCBIST_MCBAGRAQ_CFG_FIXED_WIDTH_LEN,
+ ADDR_COUNTER_MODE = MCBIST_MCBAGRAQ_CFG_ADDR_COUNTER_MODE,
+ ADDR_COUNTER_MODE_LEN = MCBIST_MCBAGRAQ_CFG_ADDR_COUNTER_MODE_LEN,
+ MAINT_ADDR_MODE_EN = MCBIST_MCBAGRAQ_CFG_MAINT_ADDR_MODE_EN,
+ MAINT_BROADCAST_MODE_EN = MCBIST_MCBAGRAQ_CFG_MAINT_BROADCAST_MODE_EN,
+ MAINT_DETECT_SRANK_BOUNDARIES = MCBIST_MCBAGRAQ_CFG_MAINT_DETECT_SRANK_BOUNDARIES,
+
+ CFG_CMD_TIMEOUT_MODE = MCBIST_MCBCFGQ_CFG_CMD_TIMEOUT_MODE,
+ CFG_CMD_TIMEOUT_MODE_LEN = MCBIST_MCBCFGQ_CFG_CMD_TIMEOUT_MODE_LEN,
+ RESET_KEEPER = MCBIST_MCBCFGQ_RESET_KEEPER,
+ CFG_CURRENT_ADDR_TRAP_UPDATE_DIS = MCBIST_MCBCFGQ_CFG_CURRENT_ADDR_TRAP_UPDATE_DIS,
+ CFG_CCS_RETRY_DIS = MCBIST_MCBCFGQ_CFG_CCS_RETRY_DIS,
+ CFG_RESET_CNTS_START_OF_RANK = MCBIST_MCBCFGQ_CFG_RESET_CNTS_START_OF_RANK,
+ CFG_LOG_COUNTS_IN_TRACE = MCBIST_MCBCFGQ_CFG_LOG_COUNTS_IN_TRACE,
+ SKIP_INVALID_ADDR_DIMM_DIS = MCBIST_MCBCFGQ_SKIP_INVALID_ADDR_DIMM_DIS,
+ REFRESH_ONLY_SUBTEST_EN = MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_EN,
+ REFRESH_ONLY_SUBTEST_TIMEBASE_SEL = MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_TIMEBASE_SEL,
+ REFRESH_ONLY_SUBTEST_TIMEBASE_SEL_LEN = MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_TIMEBASE_SEL_LEN,
+ RAND_ADDR_ALL_ADDR_MODE_EN = MCBIST_MCBCFGQ_RAND_ADDR_ALL_ADDR_MODE_EN,
+ MCBIST_CFG_REF_WAIT_TIME = MCBIST_MCBCFGQ_MCBIST_CFG_REF_WAIT_TIME,
+ MCBIST_CFG_REF_WAIT_TIME_LEN = MCBIST_MCBCFGQ_MCBIST_CFG_REF_WAIT_TIME_LEN,
+ CFG_MCB_LEN64 = MCBIST_MCBCFGQ_CFG_MCB_LEN64,
+ CFG_PAUSE_ON_ERROR_MODE = MCBIST_MCBCFGQ_CFG_PAUSE_ON_ERROR_MODE,
+ CFG_PAUSE_ON_ERROR_MODE_LEN = MCBIST_MCBCFGQ_CFG_PAUSE_ON_ERROR_MODE_LEN,
+ MCBIST_CFG_PAUSE_AFTER_CCS_SUBTEST = MCBIST_MCBCFGQ_MCBIST_CFG_PAUSE_AFTER_CCS_SUBTEST,
+ MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR = MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR,
+ MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST = MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST,
+ CFG_ENABLE_SPEC_ATTN = MCBIST_MCBCFGQ_CFG_ENABLE_SPEC_ATTN,
+ CFG_ENABLE_HOST_ATTN = MCBIST_MCBCFGQ_CFG_ENABLE_HOST_ATTN,
+ MCBIST_CFG_PAUSE_AFTER_RANK = MCBIST_MCBCFGQ_CFG_MCBIST_CFG_FORCE_PAUSE_AFTER_RANK,
+
+ LOGGED_ERROR_ON_PORT_INDICATOR = MCBIST_MCBSTATQ_MCBIST_LOGGED_ERROR_ON_PORT_INDICATOR,
+ LOGGED_ERROR_ON_PORT_INDICATOR_LEN = MCBIST_MCBSTATQ_MCBIST_LOGGED_ERROR_ON_PORT_INDICATOR_LEN,
+ SUBTEST_NUM_INDICATOR = MCBIST_MCBSTATQ_MCBIST_SUBTEST_NUM_INDICATOR,
+ SUBTEST_NUM_INDICATOR_LEN = MCBIST_MCBSTATQ_MCBIST_SUBTEST_NUM_INDICATOR_LEN,
+
+ UE_COUNT = MCBIST_MBSEC1Q_UE_COUNT,
+ UE_COUNT_LEN = MCBIST_MBSEC1Q_UE_COUNT_LEN,
+
+ MBSTRQ_CFG_MAINT_RCE_WITH_CE = MCBIST_MBSTRQ_CFG_MAINT_RCE_WITH_CE,
+
+ CFG_AMAP_DIMM_SELECT = MCBIST_MCBAMR0A0Q_CFG_AMAP_DIMM_SELECT,
+ CFG_AMAP_DIMM_SELECT_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_DIMM_SELECT_LEN,
+ CFG_AMAP_MRANK0 = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK0,
+ CFG_AMAP_MRANK0_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK0_LEN,
+ CFG_AMAP_MRANK1 = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK1,
+ CFG_AMAP_MRANK1_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK1_LEN,
+ CFG_AMAP_SRANK0 = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK0,
+ CFG_AMAP_SRANK0_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK0_LEN,
+ CFG_AMAP_SRANK1 = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK1,
+ CFG_AMAP_SRANK1_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK1_LEN,
+ CFG_AMAP_SRANK2 = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK2,
+ CFG_AMAP_SRANK2_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK2_LEN,
+ CFG_AMAP_BANK2 = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK2,
+ CFG_AMAP_BANK2_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK2_LEN ,
+ CFG_AMAP_BANK1 = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK1,
+ CFG_AMAP_BANK1_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK1_LEN ,
+ CFG_AMAP_BANK0 = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK0,
+ CFG_AMAP_BANK0_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK0_LEN ,
+
+ CFG_AMAP_BANK_GROUP1 = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP1,
+ CFG_AMAP_BANK_GROUP1_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP1_LEN ,
+ CFG_AMAP_BANK_GROUP0 = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP0,
+ CFG_AMAP_BANK_GROUP0_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP0_LEN ,
+ CFG_AMAP_ROW17 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW17,
+ CFG_AMAP_ROW17_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW17_LEN,
+ CFG_AMAP_ROW16 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW16,
+ CFG_AMAP_ROW16_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW16_LEN,
+ CFG_AMAP_ROW15 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW15,
+ CFG_AMAP_ROW15_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW15_LEN,
+ CFG_AMAP_ROW14 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW14,
+ CFG_AMAP_ROW14_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW14_LEN,
+ CFG_AMAP_ROW13 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW13,
+ CFG_AMAP_ROW13_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW13_LEN,
+ CFG_AMAP_ROW12 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12,
+ CFG_AMAP_ROW12_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12_LEN,
+ CFG_AMAP_ROW11 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW11,
+ CFG_AMAP_ROW11_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW11_LEN,
+ CFG_AMAP_ROW10 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW10,
+ CFG_AMAP_ROW10_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW10_LEN,
+
+ CFG_AMAP_ROW9 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW9,
+ CFG_AMAP_ROW9_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW9_LEN,
+ CFG_AMAP_ROW8 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW8,
+ CFG_AMAP_ROW8_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW8_LEN,
+ CFG_AMAP_ROW7 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW7,
+ CFG_AMAP_ROW7_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW7_LEN,
+ CFG_AMAP_ROW6 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW6,
+ CFG_AMAP_ROW6_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW6_LEN,
+ CFG_AMAP_ROW5 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW5,
+ CFG_AMAP_ROW5_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW5_LEN,
+ CFG_AMAP_ROW4 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW4,
+ CFG_AMAP_ROW4_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW4_LEN,
+ CFG_AMAP_ROW3 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW3,
+ CFG_AMAP_ROW3_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW3_LEN,
+ CFG_AMAP_ROW2 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW2,
+ CFG_AMAP_ROW2_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW2_LEN,
+ CFG_AMAP_ROW1 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW1,
+ CFG_AMAP_ROW1_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW1_LEN,
+ CFG_AMAP_ROW0 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW0,
+ CFG_AMAP_ROW0_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW0_LEN,
+
+ CFG_AMAP_COL9 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL9,
+ CFG_AMAP_COL9_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL9_LEN,
+ CFG_AMAP_COL8 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL8,
+ CFG_AMAP_COL8_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL8_LEN,
+ CFG_AMAP_COL7 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL7,
+ CFG_AMAP_COL7_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL7_LEN,
+ CFG_AMAP_COL6 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL6,
+ CFG_AMAP_COL6_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL6_LEN,
+ CFG_AMAP_COL5 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL5,
+ CFG_AMAP_COL5_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL5_LEN,
+ CFG_AMAP_COL4 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL4,
+ CFG_AMAP_COL4_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL4_LEN,
+ CFG_AMAP_COL3 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL3,
+ CFG_AMAP_COL3_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL3_LEN,
+ CFG_AMAP_COL2 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL2,
+ CFG_AMAP_COL2_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL2_LEN,
+
+ LFSR_MASK = MCBIST_MCBLFSRA0Q_CFG_LFSR_MASK_A0,
+ LFSR_MASK_LEN = MCBIST_MCBLFSRA0Q_CFG_LFSR_MASK_A0_LEN,
+
+ CFG_DATA_ROT_SEED1 = MCBIST_MCBDRSRQ_CFG_DATA_ROT_SEED,
+ CFG_DATA_ROT_SEED1_LEN = MCBIST_MCBDRSRQ_CFG_DATA_ROT_SEED_LEN,
+ CFG_DATA_ROT = MCBIST_MCBDRCRQ_CFG_DATA_ROT,
+ CFG_DATA_ROT_LEN = MCBIST_MCBDRCRQ_CFG_DATA_ROT_LEN,
+ CFG_DATA_ROT_SEED2 = MCBIST_MCBDRCRQ_CFG_DATA_ROT_SEED,
+ CFG_DATA_ROT_SEED2_LEN = MCBIST_MCBDRCRQ_CFG_DATA_ROT_SEED_LEN,
+ CFG_DATA_SEED_MODE = MCBIST_MCBDRCRQ_CFG_DATA_SEED_MODE,
+ CFG_DATA_SEED_MODE_LEN = MCBIST_MCBDRCRQ_CFG_DATA_SEED_MODE_LEN,
+
+ CFG_TRAP_CE_ENABLE = MCA_MCBCM_MCBIST_TRAP_CE_ENABLE,
+ CFG_TRAP_UE_ENABLE = MCA_MCBCM_MCBIST_TRAP_UE_ENABLE,
+ CFG_TRAP_MPE_ENABLE = MCA_MCBCM_MCBIST_TRAP_MPE_ENABLE,
+
+ CFG_DGEN_RNDD_SEED0 = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0,
+ CFG_DGEN_RNDD_SEED0_LEN = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0_LEN,
+ CFG_DGEN_RNDD_SEED1 = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1,
+ CFG_DGEN_RNDD_SEED1_LEN = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1_LEN,
+ CFG_DGEN_RNDD_SEED2 = MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2,
+ CFG_DGEN_RNDD_SEED2_LEN = MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2_LEN,
+ CFG_DGEN_RNDD_DATA_MAPPING = MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING,
+ CFG_DGEN_RNDD_DATA_MAPPING_LEN = MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING_LEN,
+
+ // THRESHOLD control bits
+ MBSTRQ_CFG_THRESH_MAG_NCE_INT = MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT,
+ MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN,
+ MBSTRQ_CFG_THRESH_MAG_NCE_SOFT = MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT,
+ MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN,
+ MBSTRQ_CFG_THRESH_MAG_NCE_HARD = MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD,
+ MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN,
+ MBSTRQ_CFG_THRESH_MAG_RCE = MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE,
+ MBSTRQ_CFG_THRESH_MAG_RCE_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE_LEN,
+ MBSTRQ_CFG_THRESH_MAG_ICE = MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE,
+ MBSTRQ_CFG_THRESH_MAG_ICE_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE_LEN,
+ MBSTRQ_CFG_THRESH_MAG_MCE_INT = MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT,
+ MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN,
+ MBSTRQ_CFG_THRESH_MAG_MCE_SOFT = MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT,
+ MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN,
+ MBSTRQ_CFG_THRESH_MAG_MCE_HARD = MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD,
+ MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN,
+ MBSTRQ_CFG_PAUSE_ON_SCE = MCBIST_MBSTRQ_CFG_PAUSE_ON_SCE,
+ MBSTRQ_CFG_PAUSE_ON_MCE = MCBIST_MBSTRQ_CFG_PAUSE_ON_MCE,
+ MBSTRQ_CFG_PAUSE_ON_UE = MCBIST_MBSTRQ_CFG_PAUSE_ON_UE,
+ MBSTRQ_CFG_PAUSE_ON_SUE = MCBIST_MBSTRQ_CFG_PAUSE_ON_SUE,
+ MBSTRQ_CFG_PAUSE_ON_AUE = MCBIST_MBSTRQ_CFG_PAUSE_ON_AUE,
+ MBSTRQ_CFG_PAUSE_ON_RCD = MCBIST_MBSTRQ_CFG_PAUSE_ON_RCD,
+ MBSTRQ_CFG_SYMBOL_COUNTER_MODE = MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE,
+ MBSTRQ_CFG_SYMBOL_COUNTER_MODE_LEN = MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE_LEN,
+ MBSTRQ_CFG_NCE_SOFT_SYMBOL_COUNT_ENABLE = MCBIST_MBSTRQ_CFG_NCE_SOFT_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_NCE_INTER_SYMBOL_COUNT_ENABLE = MCBIST_MBSTRQ_CFG_NCE_INTER_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_NCE_HARD_SYMBOL_COUNT_ENABLE = MCBIST_MBSTRQ_CFG_NCE_HARD_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_PAUSE_MCB_ERROR = MCBIST_MBSTRQ_CFG_PAUSE_MCB_ERROR,
+ MBSTRQ_CFG_PAUSE_MCB_LOG_FULL = MCBIST_MBSTRQ_CFG_PAUSE_MCB_LOG_FULL,
+ MBSTRQ_CFG_MCE_SOFT_SYMBOL_COUNT_ENABLE = MCBIST_MBSTRQ_CFG_MCE_SOFT_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_MCE_INTER_SYMBOL_COUNT_ENABLE = MCBIST_MBSTRQ_CFG_MCE_INTER_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_MCE_HARD_SYMBOL_COUNT_ENABLE = MCBIST_MBSTRQ_CFG_MCE_HARD_SYMBOL_COUNT_ENABLE,
+
+ // Bit mapping for MCBIST error log control data (address+ in Nimbus doc)
+ ERROR_LOG_SUBTEST = 0,
+ ERROR_LOG_SUBTEST_LEN = 5,
+ ERROR_LOG_SUBCMD = 5,
+ ERROR_LOG_SUBCMD_LEN = 2,
+ ERROR_LOG_ADDR_DIMM = 7,
+ ERROR_LOG_ADDR_MRANK = 8,
+ ERROR_LOG_ADDR_MRANK_LEN = 2,
+ ERROR_LOG_ADDR_SRANK = 10,
+ ERROR_LOG_ADDR_SRANK_LEN = 3,
+ ERROR_LOG_ADDR_BANK_GROUP = 13,
+ ERROR_LOG_ADDR_BANK_GROUP_LEN = 2,
+ ERROR_LOG_ADDR_BANK = 15,
+ ERROR_LOG_ADDR_BANK_LEN = 3,
+ ERROR_LOG_ADDR_ROW = 18,
+ ERROR_LOG_ADDR_ROW_LEN = 18,
+ ERROR_LOG_ADDR_COLUMN = 36,
+ ERROR_LOG_ADDR_COLUMN_LEN = 8,
+ ERROR_LOG_BEAT = 44,
+ ERROR_LOG_BEAT_LEN = 2,
+ ERROR_LOG_TYPE = 46,
+ ERROR_LOG_TYPE_LEN = 2,
+
+ //MCBIST FIR mask
+ MCB_PROGRAM_COMPLETE = MCBIST_MCBISTFIRQ_MCBIST_PROGRAM_COMPLETE,
+ MCB_WAT_DEBUG_ATTN = MCBIST_MCBISTFIRQ_WAT_DEBUG_ATTN,
+ MCB_PROGRAM_COMPLETE_MASK = MCB_PROGRAM_COMPLETE,
+ MCB_WAT_DEBUG_ATTN_MASK = MCB_WAT_DEBUG_ATTN,
+ MCB_DATA_ERROR = MCBIST_MCBISTFIRQ_MCBIST_DATA_ERROR,
+
+ //XLT address valid offset
+ XLT0_SLOT1_D_VALID = MCS_PORT13_MCP0XLT0_SLOT1_VALID,
+ XLT0_SLOT0_M1_VALID = MCS_PORT13_MCP0XLT0_SLOT0_M1_VALID,
+ XLT0_SLOT0_M0_VALID = MCS_PORT13_MCP0XLT0_SLOT0_M0_VALID,
+ XLT0_SLOT0_S2_VALID = MCS_PORT13_MCP0XLT0_SLOT0_S2_VALID,
+ XLT0_SLOT0_S1_VALID = MCS_PORT13_MCP0XLT0_SLOT0_S1_VALID,
+ XLT0_SLOT0_S0_VALID = MCS_PORT13_MCP0XLT0_SLOT0_S0_VALID,
+ XLT0_SLOT0_ROW17_VALID = MCS_PORT02_MCP0XLT0_SLOT0_ROW17_VALID,
+ XLT0_SLOT0_ROW16_VALID = MCS_PORT02_MCP0XLT0_SLOT0_ROW16_VALID,
+ XLT0_SLOT0_ROW15_VALID = MCS_PORT02_MCP0XLT0_SLOT0_ROW15_VALID,
+
+ };
+
+
+};
+
+
+///
+/// @class mcbistTraits
+/// @brief a collection of traits associated with the Nimbus MCA
+///
+template<>
+class mcbistTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCA>
+{
+ public:
+ // MCBIST error log related registers
+ static constexpr uint64_t ERROR_LOG_PTR_REG = MCA_ELPR;
+ static constexpr uint64_t RMW_WRT_BUF_CTL_REG = MCA_WREITE_AACR;
+ static constexpr uint64_t RMW_WRT_BUF_DATA_REG = MCA_AADR;
+ static constexpr uint64_t RMW_WRT_BUF_ECC_REG = MCA_AAER;
+
+ // XLT registers
+ static constexpr uint64_t XLTATE0 = MCA_MBA_MCP0XLT0;
+ static constexpr uint64_t XLTATE1 = MCA_MBA_MCP0XLT1;
+ static constexpr uint64_t XLTATE2 = MCA_MBA_MCP0XLT2;
+
+ // Maintenance data location within the array
+ static constexpr uint64_t MAINT_DATA_INDEX_START = 0b111110000;
+ static constexpr uint64_t MAINT_DATA_INDEX_END = 0b111111000;
+
+ enum
+ {
+ // Register field constants
+ ERROR_LOG_PTR = MCA_ELPR_LOG_POINTER,
+ ERROR_LOG_PTR_LEN = MCA_ELPR_LOG_POINTER_LEN,
+ ERROR_LOG_FULL = MCA_ELPR_LOG_FULL,
+ RMW_WRT_BUFFER_SEL = MCA_WREITE_AACR_BUFFER,
+ RMW_WRT_ADDRESS = MCA_WREITE_AACR_ADDRESS,
+ RMW_WRT_ADDRESS_LEN = MCA_WREITE_AACR_ADDRESS_LEN,
+ RMW_WRT_AUTOINC = MCA_WREITE_AACR_AUTOINC,
+ RMW_WRT_ECCGEN = MCA_WREITE_AACR_ECCGEN,
+
+ XLTATE_SLOT0_VALID = MCS_PORT02_MCP0XLT0_SLOT0_VALID,
+ XLTATE_SLOT1_VALID = MCS_PORT02_MCP0XLT0_SLOT1_VALID,
+
+ // Constants used for field settings
+ SELECT_RMW_BUFFER = 0,
+ SELECT_WRT_BUFFER = 1,
+
+ // Other constants
+ NUM_COMPARE_LOG_ENTRIES = 64,
+ // In compare mode, there is one "info" entry per 4 data (log) entries
+ // so compare mode only uses 16 info entries total in the rmw array
+ NUM_COMPARE_DATA_PER_INFO_LOG = 4,
+ NUM_COMPARE_INFO_ENTRIES = 16,
+ };
+
+};
+
+
+///
+/// @class mcbistTraits
+/// @brief a collection of traits associated with the Nimbus MCS
+///
+template<>
+class mcbistTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCS>
+{
+ public:
+ // MCBIST error log related registers
+ static constexpr uint64_t RD_BUF_CTL_REG = MCS_PORT02_AACR;
+ static constexpr uint64_t RD_BUF_DATA_REG = MCS_PORT02_AADR;
+ static constexpr uint64_t RD_BUF_ECC_REG = MCS_PORT02_AAER;
+
+ enum
+ {
+ // Register field constants
+ RB_BUFFER_SEL = MCS_PORT02_AACR_BUFFER,
+ RB_ADDRESS = MCS_PORT02_AACR_ADDRESS,
+ RB_ADDRESS_LEN = MCS_PORT02_AACR_ADDRESS_LEN,
+ RB_AUTOINC = MCS_PORT02_AACR_AUTOINC,
+
+ // Other constants
+ NUM_COMPARE_LOG_ENTRIES = 64,
+ };
+
+};
+
+
+} // namespace mss
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C
index b235637b5..1d4a4940c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,26 +33,16 @@
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
-#include <lib/shared/nimbus_defaults.H>
#include <fapi2.H>
+#include <lib/shared/nimbus_defaults.H>
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>
-#include <generic/memory/lib/utils/find_magic.H>
#include <lib/mcbist/memdiags.H>
#include <lib/mcbist/mcbist.H>
-#include <lib/mcbist/address.H>
-#include <lib/mcbist/settings.H>
-#include <lib/mcbist/sim.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <generic/memory/lib/utils/poll.H>
-using fapi2::TARGET_TYPE_MCBIST;
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_DIMM;
-using fapi2::TARGET_TYPE_SYSTEM;
-using fapi2::FAPI2_RC_SUCCESS;
-using fapi2::FAPI2_RC_INVALID_PARAMETER;
namespace mss
{
@@ -61,153 +51,28 @@ namespace memdiags
{
///
-/// @brief Stop the current command
-/// @param[in] i_target the target
+/// @brief Set up memory controller specific settings for pre-maint mode read
+/// @param[in] i_target the memory controller target
/// @return FAPI2_RC_SUCCESS iff ok
+/// @note mc_type::NIMBUS specialization
///
template<>
-fapi2::ReturnCode stop( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
-{
- // Too long, make shorter
- using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>;
-
- // Poll parameters are defined as TK so that we wait a nice time for operations
- // For now use the defaults
- mss::poll_parameters l_poll_parameters;
- fapi2::buffer<uint64_t> l_status;
- fapi2::buffer<uint64_t> l_last_address;
- bool l_poll_result = false;
-
- FAPI_INF("Stopping any mcbist operations which are in progress for %s", mss::c_str(i_target));
-
- // TODO RTC:153951 Add masking of FIR when stopping
- FAPI_TRY( mss::mcbist::start_stop(i_target, mss::STOP) );
-
- // Poll waiting for the engine to stop
- l_poll_result = mss::poll(i_target, TT::STATQ_REG, l_poll_parameters,
- [&l_status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
- {
- FAPI_DBG("looking for mcbist not in-progress, mcbist statq 0x%llx, remaining: %d", stat_reg, poll_remaining);
- l_status = stat_reg;
- // We're done polling when either we see we're in progress or we see we're done.
- return l_status.getBit<TT::MCBIST_IN_PROGRESS>() == false;
- });
-
- // Pass or fail output the current address. This is useful for debugging when we can get it.
- // It's in the register FFDC for memdiags so we don't need it below
- FAPI_TRY( mss::getScom(i_target, TT::LAST_ADDR_REG, l_last_address) );
- FAPI_INF("MCBIST last address (during stop): 0x%016lx for %s",
- l_last_address, mss::c_str(i_target));
-
- // So we've either stopped or we timed out
- FAPI_ASSERT( l_poll_result == true,
- fapi2::MSS_MEMDIAGS_MCBIST_FAILED_TO_STOP()
- .set_MCBIST_TARGET(i_target)
- .set_POLL_COUNT(l_poll_parameters.iv_poll_count),
- "%s The MCBIST engine failed to stop its program",
- mss::c_str(i_target) );
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief memdiags init helper
-/// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
-/// in subclassed constructors more easily.
-/// @return FAPI2_RC_SUCCESS iff everything ok
-///
-template<>
-fapi2::ReturnCode operation<TARGET_TYPE_MCBIST>::base_init()
+fapi2::ReturnCode pre_maint_read_settings<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>&
+ i_target )
{
- FAPI_INF("memdiags base init for %s", mss::c_str(iv_target));
-
- // Check the state of the MCBIST engine to make sure its OK that we proceed.
- // Force stop the engine (per spec, as opposed to waiting our turn)
- FAPI_TRY( memdiags::stop(iv_target) );
-
- // Zero out cmd timebase - mcbist::program constructor does that for us.
- // Load pattern
- FAPI_TRY( iv_program.change_pattern(iv_const.iv_pattern) );
-
- // Load end boundaries
- iv_program.change_end_boundary(iv_const.iv_end_boundary);
-
- // Load thresholds
- iv_program.change_thresholds(iv_const.iv_stop);
-
- // Setup the requested speed
- FAPI_TRY( iv_program.change_speed(iv_target, iv_const.iv_speed) );
-
- // Enable maint addressing mode - enabled by default in the mcbist::program ctor
-
- // Apparently the MCBIST engine needs the ports selected even though the ports are specified
- // in the subtest. We can just select them all, and it adjusts when it executes the subtest
- iv_program.select_ports(0b1111);
-
- // Kick it off, don't wait for a result
- iv_program.change_async(mss::ON);
-
-fapi_try_exit:
- return fapi2::current_err;
+ return fapi2::FAPI2_RC_SUCCESS;
}
///
-/// @brief Single port initializer
-/// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
-/// in subclassed constructors more easily.
-/// @return FAPI2_RC_SUCCESS iff everything ok
+/// @brief Set up memory controller specific settings for pre-scrub
+/// @param[in] i_target the memory controller target
+/// @return FAPI2_RC_SUCCESS iff ok
+/// @note mc_type::NIMBUS specialization
///
template<>
-fapi2::ReturnCode operation<TARGET_TYPE_MCBIST>::single_port_init()
+fapi2::ReturnCode pre_scrub_settings<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target )
{
- FAPI_INF("single port init for %s", mss::c_str(iv_target));
-
- const uint64_t l_relative_port_number = iv_const.iv_start_address.get_port();
- const uint64_t l_dimm_number = iv_const.iv_start_address.get_dimm();
-
- // Make sure the specificed port is functional
- FAPI_ASSERT( mss::is_functional<TARGET_TYPE_MCA>(iv_target, l_relative_port_number),
- fapi2::MSS_MEMDIAGS_PORT_NOT_FUNCTIONAL()
- .set_RELATIVE_PORT_POSITION(l_relative_port_number)
- .set_ADDRESS( uint64_t(iv_const.iv_start_address) )
- .set_MCBIST_TARGET(iv_target),
- "Port with relative postion %d is not functional for %s",
- l_relative_port_number, mss::c_str(iv_target));
-
- // No broadcast mode for this one
- // Push on a read subtest
- {
- mss::mcbist::subtest_t<TARGET_TYPE_MCBIST> l_subtest = iv_subtest;
-
- l_subtest.enable_port(l_relative_port_number);
- l_subtest.enable_dimm(l_dimm_number);
- iv_program.iv_subtests.push_back(l_subtest);
- FAPI_INF("%s adding subtest 0x%04x for port %d, DIMM %d",
- mss::c_str(iv_target), l_subtest, l_relative_port_number, l_dimm_number);
- }
-
- // The address should have the port and DIMM noted in it. All we need to do is calculate the
- // remainder of the address
- if (iv_sim)
- {
- iv_const.iv_start_address.get_sim_end_address(iv_const.iv_end_address);
- }
- else if (iv_const.iv_end_address == mss::mcbist::address::LARGEST_ADDRESS)
- {
- // Only the DIMM range as we don't want to cross ports.
- iv_const.iv_start_address.get_range<mss::mcbist::address::DIMM>(iv_const.iv_end_address);
- }
-
- // Configure the address range
- FAPI_TRY( mss::mcbist::config_address_range0(iv_target, iv_const.iv_start_address, iv_const.iv_end_address) );
-
- // Initialize the common sections
- FAPI_TRY( base_init() );
-
-fapi_try_exit:
- return fapi2::current_err;
+ return fapi2::FAPI2_RC_SUCCESS;
}
///
@@ -215,10 +80,12 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff ok
///
template<>
-fapi2::ReturnCode operation<TARGET_TYPE_MCBIST>::multi_port_addr()
+fapi2::ReturnCode operation<DEFAULT_MC_TYPE>::multi_port_addr()
{
+ using TT = mcbistTraits<>;
+
mss::mcbist::address l_end_of_start_port;
- mss::mcbist::address l_end_of_complete_port(mss::mcbist::address::LARGEST_ADDRESS);
+ mss::mcbist::address l_end_of_complete_port(TT::LARGEST_ADDRESS);
mss::mcbist::address l_start_of_end_port;
// The last address in the start port is the start address thru the "DIMM range" (all addresses left on this DIMM)
@@ -255,8 +122,8 @@ fapi_try_exit:
/// @param[in] i_dimms a vector of DIMM targets
///
template<>
-void operation<TARGET_TYPE_MCBIST>::configure_multiport_subtests(const
- std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& i_dimms)
+void operation<DEFAULT_MC_TYPE>::configure_multiport_subtests(
+ const std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& i_dimms)
{
// Constexpr's to beautify the code
constexpr uint64_t FIRST_ADDRESS = 0;
@@ -424,37 +291,21 @@ fapi_try_exit:
}
///
-/// @brief memdiags multi-port init helper
+/// @brief memdiags multi-port init
/// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
/// in subclassed constructors more easily.
/// @return FAPI2_RC_SUCCESS iff everything ok
///
template<>
-fapi2::ReturnCode operation<TARGET_TYPE_MCBIST>::multi_port_init()
+fapi2::ReturnCode operation<DEFAULT_MC_TYPE>::multi_port_init_internal()
{
- FAPI_INF("multi-port init for %s", mss::c_str(iv_target));
-
- const auto l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(iv_target);
+ FAPI_INF("multi-port init internal for %s", mss::c_str(iv_target));
- // Make sure we have ports, if we don't then exit out
- if(l_mcas.size() == 0)
- {
- // Cronus can have no ports under an MCBIST, FW deconfigures by association
- FAPI_INF("%s has no attached MCAs skipping setup", mss::c_str(iv_target));
- return fapi2::FAPI2_RC_SUCCESS;
- }
// Let's assume we are going to send out all subtest unless we are in broadcast mode,
// where we only send up to 2 subtests under an MCA ( 1 for each DIMM) which is why no const
auto l_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(iv_target);
- if( l_dimms.size() == 0)
- {
- // Cronus can have no DIMMS under an MCBIST, FW deconfigures by association
- FAPI_INF("%s has no attached DIMMs skipping setup", mss::c_str(iv_target));
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
// Get the port/DIMM information for the addresses. This is an integral value which allows us to index
// all the DIMM across a controller.
const uint64_t l_portdimm_start_address = iv_const.iv_start_address.get_port_dimm();
@@ -478,7 +329,7 @@ fapi2::ReturnCode operation<TARGET_TYPE_MCBIST>::multi_port_init()
"Start address %d larger than end address %d for %s",
l_portdimm_start_address, l_portdimm_end_address, mss::c_str(iv_target));
- // Determine which ports are functional and whether we can broadcast to them
+// Determine which ports are functional and whether we can broadcast to them
// If we're in broadcast mode, PRD sends DIMM 0/1 of the first functional and configured port,
// and we then run all ports in parallel (ports set in subtest config)
if( mss::mcbist::is_broadcast_capable(iv_target) == mss::YES )
@@ -532,407 +383,7 @@ fapi_try_exit:
return fapi2::current_err;
}
-///
-/// @brief memdiags::continuous_scrub_operation constructor
-/// @param[in] i_target the target of the mcbist engine
-/// @param[in] i_const the contraints of the operation
-/// @param[out] o_rc the fapi2::ReturnCode of the intialization process
-///
-template<>
-continuous_scrub_operation<TARGET_TYPE_MCBIST>::continuous_scrub_operation(
- const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const constraints i_const,
- fapi2::ReturnCode& o_rc ):
- operation<TARGET_TYPE_MCBIST>(i_target, mss::mcbist::scrub_subtest<TARGET_TYPE_MCBIST>(), i_const)
-{
- mss::mcbist::address l_generic_start_address;
- mss::mcbist::address l_generic_end_address;
-
- FAPI_INF("setting up for continuous scrub for %s", mss::c_str(i_target));
-
- // Scrub operations run 128B
- iv_program.change_len64(mss::OFF);
-
- // We build a little program here which allows us to restart the loop in the event of a pause.
- // So we need to craft some of the address ranges and some of the subtests by hand.
-
- // Setup address config 0 to cover all the addresses for a port/dimm.
- // We leverage the MCBIST's ability to skip invalid addresses, and just setup
- // If we're running in the simulator, we want to only touch the addresses which training touched
- // *INDENT-OFF*
- iv_sim ?
- l_generic_start_address.get_sim_end_address(l_generic_end_address) :
- l_generic_start_address.get_range<mss::mcbist::address::DIMM>(l_generic_end_address);
- // *INDENT-ON*
-
- FAPI_TRY( mss::mcbist::config_address_range0(i_target, l_generic_start_address, l_generic_end_address) );
-
- // We push on a fake subtest 0 and subtest 1. We fix them up after we fill in the
- // rest of the subtests.
- iv_program.iv_subtests.push_back(iv_subtest);
- iv_program.iv_subtests.push_back(iv_subtest);
-
- // a generic 0 - DIMM address range.
- //
- // Subtests 2-9: One subtest per port/dimm each covering the whole range of that
- // port/dimm. scrub_subtests by default are using address config 0, so each of
- // these get their full address complement.
- for (const auto& p : iv_target.template getChildren<TARGET_TYPE_MCA>())
- {
- for (const auto& d : p.template getChildren<TARGET_TYPE_DIMM>())
- {
- // Don't destroy the subtest passed in, copy it
- auto l_subtest = iv_subtest;
-
- l_subtest.enable_port(mss::relative_pos<TARGET_TYPE_MCBIST>(p));
- l_subtest.enable_dimm(mss::index(d));
- iv_program.iv_subtests.push_back(l_subtest);
- FAPI_INF("adding scrub subtest for %s (dimm %d) ( 0x%04x)", mss::c_str(d), mss::index(d), l_subtest);
- }
- }
-
- //
- // Subtest 10: goto subtest 2. This causes us to loop back to the first port/dimm and go thru them all
- // This subtest will be marked the last when the MCBMR registers are filled in.
- //
- iv_program.iv_subtests.push_back(mss::mcbist::goto_subtest<TARGET_TYPE_MCBIST>(2));
- FAPI_INF("last goto subtest (10) is going to subtest 2 ( 0x%04x) for %s", iv_program.iv_subtests[2],
- mss::c_str(iv_target));
-
- // Ok, now we can go back in to fill in the first two subtests.
-
- {
- auto l_subtest = iv_subtest;
- auto l_port = iv_const.iv_start_address.get_port();
- auto l_dimm = iv_const.iv_start_address.get_dimm();
- size_t l_index = 2;
-
- // By default if we don't find our port/dimm in the subtests, we just go back to the beginning.
- uint64_t l_goto_subtest = 2;
-
- //
- // subtest 0
- //
-
- // load the start address given and calculate the end address. Stick this into address config 1
- // We don't need to account for the simulator here as the caller can do that when they setup the
- // start address.
- // *INDENT-OFF*
- iv_sim ?
- iv_const.iv_start_address.get_sim_end_address(iv_const.iv_end_address) :
- iv_const.iv_start_address.get_range<mss::mcbist::address::DIMM>(iv_const.iv_end_address);
- // *INDENT-ON*
-
- FAPI_TRY( mss::mcbist::config_address_range1(i_target, iv_const.iv_start_address, iv_const.iv_end_address) );
-
- // We need to use this address range. We know it's ok to write to element 0 as we pushed it on above
- l_subtest.change_addr_sel(1);
- l_subtest.enable_port(l_port);
- l_subtest.enable_dimm(l_dimm);
-
- iv_program.iv_subtests[0] = l_subtest;
- FAPI_INF("adding scrub subtest 0 for port %d dimm %d (0x%04x) for %s", l_port, l_dimm, l_subtest, mss::c_str(i_target));
-
- //
- // subtest 1
- //
-
- // From the port/dimm specified in the start address, we know what subtest should execute next. The idea
- // being that this 0'th subtest is a mechanism to allow the caller to start a scrub 'in the middle' and
- // jump to the next port/dimm which would have been scrubbed. The hard part is that we don't know where
- // in the subtest vector the 'next' port/dimm are placed. So we look for our port/dimm (skipping subtest 0
- // since we know that's us and skipping subtest 1 since it isn't there yet.)
- for (; l_index < iv_program.iv_subtests.size(); ++l_index)
- {
- auto l_my_dimm = iv_program.iv_subtests[l_index].get_dimm();
- auto l_my_port = iv_program.iv_subtests[l_index].get_port();
-
- if ((l_dimm == l_my_dimm) && (l_port == l_my_port))
- {
- l_goto_subtest = l_index + 1;
- break;
- }
- }
-
- // Since we set l_goto_subtest up with a meaningful default, we can just make a subtest with the
- // l_goto_subtest subtest specified and pop that in to index 1.
- FAPI_INF("adding scrub subtest 1 to goto subtest %d (port %d, dimm %d, test 0x%04x) for %s", l_goto_subtest,
- iv_program.iv_subtests[l_goto_subtest].get_port(),
- iv_program.iv_subtests[l_goto_subtest].get_dimm(),
- iv_program.iv_subtests[l_goto_subtest], mss::c_str(i_target) );
-
- iv_program.iv_subtests[1] = mss::mcbist::goto_subtest<TARGET_TYPE_MCBIST>(l_goto_subtest);
- }
-
- // Initialize the common sections
- FAPI_TRY( base_init() );
-
-fapi_try_exit:
- o_rc = fapi2::current_err;
- return;
-}
-
-///
-/// @brief Super Fast Read Init - used to init all memory behind a target with a given pattern
-/// @note Uses broadcast mode if possible
-/// @param[in] i_target the target behind which all memory should be initialized
-/// @param[in] i_pattern an index representing a pattern to use to initize memory (defaults to 0)
-/// @return FAPI2_RC_SUCCESS iff everything ok
-/// @note The function is asynchronous, and the caller should be looking for a done attention
-///
-template<>
-fapi2::ReturnCode sf_init( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const uint64_t i_pattern )
-{
- FAPI_INF("superfast init start for %s", mss::c_str(i_target));
-
- uint8_t l_sim = false;
- FAPI_TRY( mss::is_simulation( l_sim) );
-
- if (l_sim)
- {
- // Use some sort of pattern in sim in case the verification folks need to look for something
- // TK. Need a verification pattern. This is a not-good pattern for verification ... We don't really
- // have a good pattern for verification defined.
- FAPI_INF("running mss sim init in place of sf_init for %s", mss::c_str(i_target));
- return mss::mcbist::sim::sf_init(i_target, i_pattern);
- }
- else
- {
- fapi2::ReturnCode l_rc;
- constraints l_const(i_pattern);
- sf_init_operation<TARGET_TYPE_MCBIST> l_init_op(i_target, l_const, l_rc);
-
- FAPI_ASSERT( l_rc == FAPI2_RC_SUCCESS,
- fapi2::MSS_MEMDIAGS_SUPERFAST_INIT_FAILED_TO_INIT().set_MCBIST_TARGET(i_target),
- "Unable to initialize the MCBIST engine for a sf read %s", mss::c_str(i_target) );
-
- return l_init_op.execute();
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Super Fast Read to End of MCBIST - used to run superfast read on all memory behind the target
-/// @tparam T the fapi2::TargetType of the target
-/// @param[in] i_target the target behind which all memory should be read
-/// @param[in] i_stop stop conditions
-/// @param[in] i_address mcbist::address representing the address from which to start.
-// Defaults to the first address behind the target
-/// @param[in] i_end whether to end, and where
-/// Defaults to stop after slave rank
-/// @param[in] i_end_address mcbist::address representing the address to end.
-// Defaults to mcbist::address::LARGEST_ADDRESS
-/// @return FAPI2_RC_SUCCESS iff everything ok
-/// @note The function is asynchronous, and the caller should be looking for a done attention
-/// @note The address is often the port, dimm, rank but this is not enforced in the API.
-///
-template<>
-fapi2::ReturnCode sf_read( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const stop_conditions& i_stop,
- const mss::mcbist::address& i_address,
- const end_boundary i_end,
- const mss::mcbist::address& i_end_address )
-{
- FAPI_INF("superfast read - start for %s", mss::c_str(i_target));
-
- fapi2::ReturnCode l_rc;
- constraints l_const(i_stop, speed::LUDICROUS, i_end, i_address, i_end_address);
- sf_read_operation<TARGET_TYPE_MCBIST> l_read_op(i_target, l_const, l_rc);
-
- FAPI_ASSERT( l_rc == FAPI2_RC_SUCCESS,
- fapi2::MSS_MEMDIAGS_SUPERFAST_READ_FAILED_TO_INIT().set_MCBIST_TARGET(i_target),
- "Unable to initialize the MCBIST engine for a sf read %s", mss::c_str(i_target) );
-
- return l_read_op.execute();
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-///
-/// @brief Scrub - continuous scrub all memory behind the target
-/// @param[in] i_target the target behind which all memory should be scrubbed
-/// @param[in] i_stop stop conditions
-/// @param[in] i_speed the speed to scrub
-/// @param[in] i_address mcbist::address representing the port, dimm, rank
-/// @return FAPI2_RC_SUCCESS iff everything ok
-/// @warning The function is asynchronous, and the caller should be looking for a done attention
-/// @note The operation will fail immediately when a stop condition is encountered
-///
-template<>
-fapi2::ReturnCode background_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const stop_conditions& i_stop,
- const speed i_speed,
- const mss::mcbist::address& i_address )
-{
- FAPI_INF("continuous (background) scrub for %s", mss::c_str(i_target));
-
- fapi2::ReturnCode l_rc;
- constraints l_const(i_stop, i_speed, end_boundary::STOP_AFTER_ADDRESS, i_address);
- continuous_scrub_operation<TARGET_TYPE_MCBIST> l_op(i_target, l_const, l_rc);
+} // namespace memdiags
- FAPI_ASSERT( l_rc == FAPI2_RC_SUCCESS,
- fapi2::MSS_MEMDIAGS_CONTINUOUS_SCRUB_FAILED_TO_INIT().set_MCBIST_TARGET(i_target),
- "Unable to initialize the MCBIST engine for a continuous scrub %s", mss::c_str(i_target) );
-
- return l_op.execute();
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Scrub - targeted scrub all memory behind the target
-/// @param[in] i_target the target behind which all memory should be scrubbed
-/// @param[in] i_stop stop conditions
-/// @param[in] i_start_address mcbist::address representing the address from which to start.
-/// @param[in] i_end_address mcbist::address representing the address at which to end.
-/// @param[in] i_end whether to end, and where (defaults to not stop on error)
-/// @return FAPI2_RC_SUCCESS iff everything ok
-/// @note The function is asynchronous, and the caller should be looking for a done attention
-/// @note The caller can use the address range functions to calculate the end address as needed
-///
-template<>
-fapi2::ReturnCode targeted_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const stop_conditions& i_stop,
- const mss::mcbist::address& i_start_address,
- const mss::mcbist::address& i_end_address,
- const end_boundary i_end )
-{
- FAPI_INF("targeted scrub for %s", mss::c_str(i_target));
-
- fapi2::ReturnCode l_rc;
- constraints l_const(i_stop, speed::LUDICROUS, i_end, i_start_address, i_end_address);
- targeted_scrub_operation<TARGET_TYPE_MCBIST> l_op(i_target, l_const, l_rc);
-
- FAPI_ASSERT( l_rc == FAPI2_RC_SUCCESS,
- fapi2::MSS_MEMDIAGS_TARGETED_SCRUB_FAILED_TO_INIT().set_MCBIST_TARGET(i_target),
- "Unable to initialize the MCBIST engine for a targeted scrub %s", mss::c_str(i_target) );
-
- return l_op.execute();
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Continue current command on next address
-/// The current commaand has paused on an error, so we can record the address of the error
-/// and finish the current master or slave rank.
-/// @param[in] i_target the target
-/// @param[in] i_end whether to end, and where (default = don't stop at end of rank)
-/// @param[in] i_stop stop conditions (default - 0 meaning 'don't change conditions')
-/// @param[in] i_speed the speed to scrub (default - SAME_SPEED meaning leave speed untouched)
-/// @return FAPI2_RC_SUCCESS iff ok
-/// @note overloaded as there's no 'invalid' state for thresholds.
-///
-template<>
-fapi2::ReturnCode continue_cmd( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const end_boundary i_end,
- const stop_conditions& i_stop,
- const speed i_speed )
-{
- // Too long, make shorter
- using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>;
-
- // We can use a local mcbist::program to help with the bit processing, and then write just the registers we touch.
- mss::mcbist::program<TARGET_TYPE_MCBIST> l_program;
- fapi2::buffer<uint64_t> l_status;
-
- FAPI_INF("continue_cmd for %s", mss::c_str(i_target));
-
- // TODO RTC:155518 Check for stop or in progress before allowing continue. Not critical
- // as the caller should know and can check the in-progress bit in the event they don't
-
- if (i_end != end_boundary::DONT_CHANGE)
- {
- // Before we go too far, check to see if we're already stopped at the boundary we are asking to stop at
- bool l_stopped_at_boundary = false;
- uint64_t l_error_mode = 0;
- bool l_detect_slave = false;
-
- FAPI_TRY( mss::getScom(i_target, TT::CFGQ_REG, l_program.iv_config) );
- FAPI_TRY( mss::getScom(i_target, TT::MCBAGRAQ_REG, l_program.iv_addr_gen) );
- l_program.iv_config.extractToRight<TT::CFG_PAUSE_ON_ERROR_MODE, TT::CFG_PAUSE_ON_ERROR_MODE_LEN>(l_error_mode);
- l_detect_slave = l_program.iv_addr_gen.getBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>();
-
- switch (i_end)
- {
- case end_boundary::STOP_AFTER_ADDRESS:
- l_stopped_at_boundary =
- l_program.iv_config.getBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR>() ||
- l_error_mode == end_boundary::STOP_AFTER_ADDRESS;
- break;
-
- case end_boundary::STOP_AFTER_SLAVE_RANK:
- // Note: we really want STOP_AFTER_MASTER_RANK here even though we're in the slave
- // case because MASTER_RANK has the a 0 so that l_error_mode will check correctly
- l_stopped_at_boundary =
- l_program.iv_config.getBit<TT::MCBIST_CFG_PAUSE_AFTER_RANK>() ||
- ((l_error_mode == end_boundary::STOP_AFTER_MASTER_RANK) && (l_detect_slave == false));
- break;
-
- case end_boundary::STOP_AFTER_MASTER_RANK:
- l_stopped_at_boundary =
- l_program.iv_config.getBit<TT::MCBIST_CFG_PAUSE_AFTER_RANK>() ||
- ((l_error_mode == end_boundary::STOP_AFTER_MASTER_RANK) && (l_detect_slave == true));
- break;
-
- case end_boundary::STOP_AFTER_SUBTEST:
- l_stopped_at_boundary =
- l_program.iv_config.getBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST>() ||
- l_error_mode == end_boundary::STOP_AFTER_SUBTEST;
- break;
-
- // By default we're not stopped at a boundary we're going to continue from
- default:
- break;
- };
-
- FAPI_ASSERT( l_stopped_at_boundary == false,
- fapi2::MSS_MEMDIAGS_ALREADY_AT_BOUNDARY().set_MCBIST_TARGET(i_target).set_BOUNDARY(i_stop),
- "Asked to stop at a boundary, but we're already there" );
-
- // Ok, if we're here either we need to change the stop and boundary conditions.
- // Read-modify-write the fields in the program.
- FAPI_TRY( mss::getScom(i_target, TT::MCBAGRAQ_REG, l_program.iv_addr_gen) );
-
- // Configure broadcast mode if needed
- FAPI_TRY(mss::mcbist::configure_broadcast_mode(i_target, l_program));
-
- l_program.change_end_boundary(i_end);
-
- FAPI_TRY( mss::mcbist::load_addr_gen(i_target, l_program) );
-
- FAPI_TRY( mss::mcbist::load_config(i_target, l_program) );
- }
-
- // Thresholds
- // According to API definition, 0 means don't change conditions
- if( i_stop != stop_conditions::DONT_CHANGE)
- {
- FAPI_TRY( mss::mcbist::load_thresholds(i_target, i_stop) );
- }
-
- // Setup speed
- FAPI_TRY( l_program.change_speed(i_target, i_speed) );
-
- // Load new speed unless we aren't changing it
- if( i_speed != speed::SAME_SPEED )
- {
- FAPI_TRY( load_mcbparm(i_target, l_program) );
- }
-
- // Tickle the resume from pause
- FAPI_TRY( mss::mcbist::resume(i_target) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-}
-
-}
+} // namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.H
index 918342c6c..38ea0a8aa 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,10 +39,17 @@
#include <fapi2.H>
#include <lib/shared/mss_const.H>
+#include <lib/shared/mss_const.H>
+#include <lib/ecc/ecc_traits_nimbus.H>
#include <lib/mcbist/mcbist.H>
-#include <lib/mcbist/address.H>
-#include <lib/mcbist/patterns.H>
-#include <lib/mcbist/settings.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_memdiags.H>
+
+using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_MCA;
+using fapi2::TARGET_TYPE_DIMM;
+using fapi2::TARGET_TYPE_SYSTEM;
+using fapi2::FAPI2_RC_SUCCESS;
+using fapi2::FAPI2_RC_INVALID_PARAMETER;
namespace mss
{
@@ -50,309 +57,10 @@ namespace mss
namespace memdiags
{
-// Map some of the mcbist namespace here to make it easier for users of memdiags
-// This is an intentional using statement in a header which is typically
-// disallowed - I am intentionally pulling these into this namespace for all callers.
-using mss::mcbist::constraints;
-using mss::mcbist::speed;
-using mss::mcbist::end_boundary;
-using mss::mcbist::stop_conditions;
-using mss::mcbist::cache_line;
-using mss::mcbist::pattern;
-using mss::mcbist::patterns;
-
-// Why not mss::mcbist::address? Because the fields can't be pulled in via using,
-// and it seems even more confusing to have a memdiags address but have to use
-// mcbist fields. So, we all use mcbist address until such time that its promoted
-// to some other general namespace.
-
-using mss::mcbist::PATTERN_ZEROS;
-using mss::mcbist::PATTERN_0;
-using mss::mcbist::PATTERN_ONES;
-using mss::mcbist::PATTERN_1;
-using mss::mcbist::PATTERN_2;
-using mss::mcbist::PATTERN_3;
-using mss::mcbist::PATTERN_4;
-using mss::mcbist::PATTERN_5;
-using mss::mcbist::PATTERN_6;
-using mss::mcbist::PATTERN_7;
-using mss::mcbist::PATTERN_8;
-using mss::mcbist::PATTERN_RANDOM;
-using mss::mcbist::LAST_PATTERN;
-using mss::mcbist::NO_PATTERN;
-
-///
-/// @brief Stop the current command
-/// @tparam T the fapi2::TargetType of the target
-/// @param[in] i_target the target
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode stop( const fapi2::Target<T>& i_target );
-
-///
-/// @class Base class for memdiags operations
-/// @tparam T fapi2::TargetType of the MCBIST engine
-///
-template< fapi2::TargetType T >
-class operation
-{
- public:
- ///
- /// @brief memdiags::operation constructor
- /// @param[in] i_target the target of the mcbist engine
- /// @param[in] i_subtest the proper subtest for this operation
- /// @param[in] i_const mss::constraint structure
- ///
- operation( const fapi2::Target<T>& i_target,
- const mss::mcbist::subtest_t<T> i_subtest,
- const constraints i_const ):
- iv_target(i_target),
- iv_subtest(i_subtest),
- iv_const(i_const)
- {
- FAPI_TRY( mss::is_simulation (iv_sim) );
- return;
-
- fapi_try_exit:
- // Seems like a safe risk to take ...
- FAPI_ERR("Unable to get the attribute ATTR_IS_SIMULATION");
- return;
- }
-
- operation() = delete;
-
- ///
- /// @brief Execute the memdiags operation
- /// @return FAPI2_RC_SUCCESS iff ok
- ///
- inline fapi2::ReturnCode execute()
- {
- return mss::mcbist::execute(iv_target, iv_program);
- }
-
- ///
- /// @brief memdiags::operation destructor
- ///
- virtual ~operation() = default;
-
- ///
- /// @brief memdiags init helper
- /// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
- /// in subclassed constructores more easily.
- /// @return FAPI2_RC_SUCCESS iff everything ok
- ///
- fapi2::ReturnCode base_init();
-
- ///
- /// @brief Configures all subtests for a multiport init
- /// @param[in] i_dimms a vector of DIMM targets
- ///
- void configure_multiport_subtests(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& i_dimms);
-
- ///
- /// @brief memdiags multi-port init helper
- /// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
- /// in subclassed constructores more easily.
- /// @return FAPI2_RC_SUCCESS iff everything ok
- ///
- fapi2::ReturnCode multi_port_init();
-
- ///
- /// @brief memdiags multi-port address config helper
- /// Initializes the address configs needed for a multi port operation
- /// @return FAPI2_RC_SUCCESS iff everything ok
- ///
- fapi2::ReturnCode multi_port_addr();
-
- ///
- /// @brief Single port initializer
- /// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
- /// in subclassed constructores more easily.
- /// @return FAPI2_RC_SUCCESS iff everything ok
- ///
- fapi2::ReturnCode single_port_init();
-
- ///
- /// @brief get the protected mcbist program - useful for testing
- /// @return a reference to the iv_program member
- /// @note Intentionally not const ref; allows getter to set.
- ///
- mss::mcbist::program<T>& get_program()
- {
- return iv_program;
- }
-
- ///
- /// @brief get the protected mcbist subtest_t - useful for testing
- /// @return a reference to the iv_subtest member
- ///
- const mss::mcbist::subtest_t<T>& get_subtest() const
- {
- return iv_subtest;
- }
-
- protected:
- fapi2::Target<T> iv_target;
- mss::mcbist::subtest_t<T> iv_subtest;
- constraints iv_const;
- mss::mcbist::program<T> iv_program;
- uint8_t iv_sim;
-};
-
-///
-/// @class Class for memdiags' super-fast init
-/// @tparam T fapi2::TargetType of the MCBIST engine
-///
-template< fapi2::TargetType T >
-struct sf_init_operation : public operation<T>
-{
-
- ///
- /// @brief memdiags::sf_init_operation constructor
- /// @param[in] i_target the target of the mcbist engine
- /// @param[in] i_const mss::constraint structure
- /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
- ///
- sf_init_operation( const fapi2::Target<T>& i_target,
- const constraints i_const,
- fapi2::ReturnCode& o_rc):
- operation<T>(i_target, mss::mcbist::init_subtest<T>(), i_const)
- {
- // If sf_init was passed the random data pattern, then modify the subtest to use the true random data
- if(i_const.iv_pattern == PATTERN_RANDOM)
- {
- this->iv_subtest.change_data_mode(mss::mcbist::data_mode::RAND_FWD_MAINT);
- }
-
- // We're a multi-port operation
- o_rc = this->multi_port_init();
- }
-
- sf_init_operation() = delete;
-};
-
-///
-/// @class Class for memdiags' super-fast read
-/// @tparam T fapi2::TargetType of the MCBIST engine
///
-template< fapi2::TargetType T >
-struct sf_read_operation : public operation<T>
-{
-
- ///
- /// @brief memdiags::sf_read_operation constructor
- /// @param[in] i_target the target of the mcbist engine
- /// @param[in] i_const mss::constraint structure
- /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
- ///
- sf_read_operation( const fapi2::Target<T>& i_target,
- const constraints i_const,
- fapi2::ReturnCode& o_rc):
- operation<T>(i_target, mss::mcbist::read_subtest<T>(), i_const)
- {
- // We're a multi-port operation
- o_rc = this->multi_port_init();
- }
-
- sf_read_operation() = delete;
-};
-
-///
-/// @class Class for memdiags' super-fast read to end of port
-/// @tparam T fapi2::TargetType of the MCBIST engine
-///
-template< fapi2::TargetType T >
-struct sf_read_eop_operation : public operation<T>
-{
- ///
- /// @brief memdiags::sf_read_operation constructor
- /// @param[in] i_target the target of the mcbist engine
- /// @param[in] i_const mss::constraint structure
- /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
- ///
- sf_read_eop_operation( const fapi2::Target<T>& i_target,
- const constraints i_const,
- fapi2::ReturnCode& o_rc ):
- operation<T>(i_target, mss::mcbist::read_subtest<T>(), i_const)
- {
- // We're a single-port operation
- o_rc = this->single_port_init();
- }
-
- sf_read_eop_operation() = delete;
-};
-
-///
-/// @class Class for memdiags' continuous scrub
-/// @tparam T fapi2::TargetType of the MCBIST engine
-///
-template< fapi2::TargetType T >
-struct continuous_scrub_operation : public operation<T>
-{
-
- ///
- /// @brief memdiags::continuous_scrub_operation constructor
- /// @param[in] i_target the target of the mcbist engine
- /// @param[in] i_const the contraints of the operation
- /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
- ///
- continuous_scrub_operation( const fapi2::Target<T>& i_target,
- const constraints i_const,
- fapi2::ReturnCode& o_rc );
-
- continuous_scrub_operation() = delete;
-};
-
-///
-/// @class Class for memdiags' targeted scrub
-/// @tparam T fapi2::TargetType of the MCBIST engine
-///
-template< fapi2::TargetType T >
-struct targeted_scrub_operation : public operation<T>
-{
-
- ///
- /// @brief memdiags::targeted_scrub_operation constructor
- /// @param[in] i_target the target of the mcbist engine
- /// @param[in] i_const the contraints of the operation
- /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
- ///
- targeted_scrub_operation( const fapi2::Target<T>& i_target,
- const constraints i_const,
- fapi2::ReturnCode& o_rc ):
- operation<T>(i_target, mss::mcbist::scrub_subtest<T>(), i_const)
- {
- // Scrub operations run 128B
- this->iv_program.change_len64(mss::OFF);
-
- // We're a single-port operation
- o_rc = this->single_port_init();
-
- // Targeted scrub needs to force a pause and the end boundary. So we make sure that happens here.
- this->iv_program.change_forced_pause( i_const.iv_end_boundary );
- }
-
- targeted_scrub_operation() = delete;
-};
-
-///
-/// @brief Super Fast Init - used to init all memory behind a target with a given pattern
-/// @note Uses broadcast mode if possible
-/// @tparam T the fapi2::TargetType of the target
-/// @param[in] i_target the target behind which all memory should be initialized
-/// @param[in] i_pattern an index representing a pattern to use to init memory (defaults to 0)
-/// @return FAPI2_RC_SUCCESS iff everything ok
-/// @note The function is asynchronous, and the caller should be looking for a done attention
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode sf_init( const fapi2::Target<T>& i_target,
- const uint64_t i_pattern = PATTERN_0 );
-
-///
-/// @brief Start address port dimm check - helper for testing
+/// @brief Checks that the starting port/dimm address is in range for broadcast mode - helper for testing
/// @param[in] i_targets a vector of MCA targets
-/// @param[in] i_start_addr the starting port_dimm seelct address
+/// @param[in] i_start_addr the starting port_dimm select address
/// @return FAPI2_RC_SUCCESS iff okay
///
fapi2::ReturnCode broadcast_mode_start_address_check_helper(
@@ -370,82 +78,7 @@ fapi2::ReturnCode broadcast_mode_start_address_check(const fapi2::Target<fapi2::
const uint64_t i_start_addr,
std::vector< fapi2::Target<fapi2::TARGET_TYPE_DIMM> >& o_dimms);
-///
-/// @brief Super Fast Read - used to run superfast read on all memory behind the target
-/// Determines ability to braodcast to all ports behind a target, does so if possible.
-/// @tparam T the fapi2::TargetType of the target
-/// @param[in] i_target the target behind which all memory should be read
-/// @param[in] i_stop stop conditions
-/// @param[in] i_address mcbist::address representing the address from which to start.
-// Defaults to the first address behind the target
-/// @param[in] i_end whether to end, and where
-/// Defaults to stop after slave rank
-/// @param[in] i_end_address mcbist::address representing the address to end.
-// Defaults to mcbist::address::LARGEST_ADDRESS
-/// @return FAPI2_RC_SUCCESS iff everything ok
-/// @note The function is asynchronous, and the caller should be looking for a done attention
-/// @note The address is often the port, dimm, rank but this is not enforced in the API.
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode sf_read( const fapi2::Target<T>& i_target,
- const stop_conditions& i_stop,
- const mss::mcbist::address& i_address = mss::mcbist::address(),
- const end_boundary i_end = end_boundary::STOP_AFTER_SLAVE_RANK,
- const mss::mcbist::address& i_end_address = mss::mcbist::address(mcbist::address::LARGEST_ADDRESS) );
-
-///
-/// @brief Scrub - continuous scrub all memory behind the target
-/// @param[in] i_target the target behind which all memory should be scrubbed
-/// @param[in] i_stop stop conditions
-/// @param[in] i_speed the speed to scrub
-/// @param[in] i_address mcbist::address representing the address from which to start.
-/// @return FAPI2_RC_SUCCESS iff everything ok
-/// @note The function is asynchronous, and the caller should be looking for a done attention
-/// @note The address is often the port, dimm, rank but this is not enforced in the API.
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode background_scrub( const fapi2::Target<T>& i_target,
- const stop_conditions& i_stop,
- const speed i_speed,
- const mss::mcbist::address& i_address );
-
-///
-/// @brief Scrub - targeted scrub all memory described by the input address (rank, slave, etc.)
-/// @param[in] i_target the target behind which all memory should be scrubbed
-/// @param[in] i_stop stop conditions
-/// @param[in] i_speed the speed to scrub
-/// @param[in] i_start_address mcbist::address representing the address from which to start.
-/// @param[in] i_end_address mcbist::address representing the address at which to end.
-/// @param[in] i_end whether to end, and where
-/// @return FAPI2_RC_SUCCESS iff everything ok
-/// @note The function is asynchronous, and the caller should be looking for a done attention
-/// @note The address is often the port, dimm, rank but this is not enforced in the API.
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode targeted_scrub( const fapi2::Target<T>& i_target,
- const stop_conditions& i_stop,
- const mss::mcbist::address& i_start_address,
- const mss::mcbist::address& i_end_address,
- const end_boundary i_end );
-
-///
-/// @brief Continue current command on next address
-/// The current commaand has paused on an error, so we can record the address of the error
-/// and finish the current master or slave rank.
-/// @tparam T the fapi2::TargetType of the target
-/// @param[in] i_target the target
-/// @param[in] i_end whether to end, and where (default - don't stop at end of rank)
-/// @param[in] i_stop stop conditions (default - 0 meaning 'don't change conditions')
-/// @param[in] i_speed the speed to scrub (default - SAME_SPEED meaning leave speed untouched)
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode continue_cmd( const fapi2::Target<T>& i_target,
- const end_boundary i_end = end_boundary::DONT_CHANGE,
- const stop_conditions& i_stop = stop_conditions(stop_conditions::DONT_CHANGE),
- const speed i_speed = speed::SAME_SPEED );
-
-} // namespace
+} // ns memdiags
-} // namespace
+} // ns mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/settings.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/settings.H
index 3e89ee647..f4d822105 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/settings.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/settings.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,759 +38,11 @@
#include <fapi2.H>
-#include <p9_mc_scom_addresses.H>
-#include <p9_mc_scom_addresses_fld.H>
+#include <lib/shared/mss_const.H>
+#include <lib/ecc/ecc_traits_nimbus.H>
+#include <lib/mcbist/mcbist_traits.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H>
-#include <lib/mcbist/address.H>
-#include <lib/utils/bit_count.H>
+// This file is still necessary to put traits and generic code together
-namespace mss
-{
-
-namespace mcbist
-{
-
-/// End boundaries for MCBIST programs - where to stop when stopping or pausing
-enum end_boundary : uint64_t
-{
- // We're gonna get a little hacky here. The pause on error mode field
- // is two bits, with another bit representing slave/master. So we craft
- // the enum so that we can insertFromRight and get the proper vaules, and
- // leave one bit out of that two-bit range to represent master or slave
- NONE = 0b000,
- STOP_AFTER_ADDRESS = 0b001,
- STOP_AFTER_MASTER_RANK = 0b010,
- STOP_AFTER_SLAVE_RANK = 0b110,
- STOP_AFTER_SUBTEST = 0b011,
-
- DONT_CHANGE = 0xFF,
-};
-
-/// Speeds for performing MCBIST operations
-enum speed
-{
- /// As fast as possible, often the default
- LUDICROUS = 0,
-
- /// Background scrubbing speed.
- BG_SCRUB = 1,
-
- /// Used to indicate to the continue current command to not change the speed of the commands
- SAME_SPEED = 4,
-};
-
-///
-/// @class Memory diagnostic subsystem stop-on-error settings and thresholds
-/// @note Matches Nimbus MBSTRQ, but might be changed later for Centaur, or mapped.
-///
-class stop_conditions
-{
- public:
-
- // Many of the config fields share a disable bit pattern, so we define it here
- static constexpr uint64_t DISABLE = 0b1111;
- static constexpr uint64_t MAX_THRESHOLD = 0b1110;
- static constexpr uint64_t DONT_CHANGE = 0;
-
- private:
-
- ///
- /// @brief Little helper to convert threshold inputs to exponents
- /// @param[in] i_value, the value of the threshold (presumably)
- /// @return a value n such that 2^n <= i_value && n < 15
- ///
- uint64_t make_threshold_setting( const uint64_t i_value )
- {
- // If the user passes in DISABLE, let it past. This prevents callers from having to
- // do the conditional. Zero is none which is disable
- if ((i_value == DISABLE) || (i_value == 0))
- {
- return DISABLE;
- }
-
- // Find the first bit set. This represents the largest power of 2 this input can represent
- // The subtraction from 63 switches from a left-count to a right-count (e.g., 0 (left most
- // bit) is really bit 63 if you start on the right.)
- const uint64_t l_largest = 63 - first_bit_set(i_value);
-
- // If the first bit set is off in space and greater than 2^14, we just return 0b1110
- // Otherwise, l_largest is the droid we're looking for
- return l_largest >= MAX_THRESHOLD ? MAX_THRESHOLD : l_largest;
- }
-
- ///
- /// @brief Generic pause on threshold
- /// @tparam F, the bit field to manipulate
- /// @tparam L, the length of F
- /// @param[in] the state of the error - mss::ON or mss::OFF
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note If the input is mss::ON, this method enables the error, it's corresponding
- /// threshold defines the threshold at which the engine will stop. If no threshold is
- /// defined (the error is disabled) this method will set the threshold to 1. A previously
- /// defined threshold (i.e., not disabled) will be left intact. If the input
- /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
- ///
- template< uint64_t F, uint64_t L >
- inline stop_conditions& set_pause_on_threshold( const states i_on_or_off )
- {
- if (i_on_or_off == mss::OFF)
- {
- iv_value.insertFromRight<F, L>(DISABLE);
- return *this;
- }
-
- uint64_t l_thresh = 0;
- iv_value.extractToRight<F, L>(l_thresh);
-
- if (l_thresh == DISABLE)
- {
- // Note the threshold field is an exponent, so this is 2^0, or 1 count
- iv_value.insertFromRight<F, L>(0);
- }
-
- return *this;
- }
-
- public:
- ///
- /// @brief Stop/Thresholds class ctor
- ///
- stop_conditions():
- iv_value(0)
- {
- // By default we want to start everything in 'don't stop' mode. This means disabling
- // the errors which contain thresholds
- set_thresh_nce_int(DISABLE)
- .set_thresh_nce_soft(DISABLE)
- .set_thresh_nce_hard(DISABLE)
- .set_thresh_rce(DISABLE)
- .set_thresh_ice(DISABLE)
- .set_thresh_mce_int(DISABLE)
- .set_thresh_mce_soft(DISABLE)
- .set_thresh_mce_hard(DISABLE);
- }
-
- ///
- /// @brief Stop/Thresholds class ctor
- /// @param[in] uint64_t representing the threshold register contents
- ///
- stop_conditions(const uint64_t i_value):
- iv_value(i_value)
- {
- }
-
- ///
- /// @brief Stop/Thresholds class dtor
- ///
- ~stop_conditions() = default;
-
- ///
- /// @brief uint64_t conversion
- ///
- inline operator uint64_t() const
- {
- return uint64_t(iv_value);
- }
-
- ///
- /// @brief set_thresh_nce_int
- /// @param[in] i_value the value of the field
- /// NCE intermittent error threshold magnitude to trigger for triggering pause. If
- /// 1111, then pause will never be triggered (disabled). Else, then MCBIST will
- /// pause if it takes sees 2^[this value] number of errors of this type.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note The register field is actually an exponent. The hardware will count 2^n for the
- /// threshold. However, the input represents a count - how many. Thus we need to convert
- /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
- /// to the nearest power of 2 which is less than 2^15 before being set in the register.
- ///
- inline stop_conditions& set_thresh_nce_int( const uint64_t i_value )
- {
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @brief set_pause_on_nce_int - enable NCE intermittent error
- /// @param[in] i_on_or_off - the desired state.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note If the input is mss::ON, this method enables the error, it's corresponding
- /// threshold defines the threshold at which the engine will stop. If no threshold is
- /// defined (the error is disabled) this method will set the threshold to 1. A previously
- /// defined threshold (i.e., not disabled) will be left intact. If the input
- /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
- ///
- inline stop_conditions& set_pause_on_nce_int( const states i_on_or_off )
- {
- return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN>(i_on_or_off);
- }
-
- ///
- /// @brief set_thresh_nce_soft
- /// @param[in] i_value the value of the field
- /// NCE soft error threshold magnitude to trigger for triggering pause. If 1111,
- /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it
- /// takes sees 2^[this value] number of errors of this type.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note The register field is actually an exponent. The hardware will count 2^n for the
- /// threshold. However, the input represents a count - how many. Thus we need to convert
- /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
- /// to the nearest power of 2 which is less than 2^15 before being set in the register.
- ///
- inline stop_conditions& set_thresh_nce_soft( const uint64_t i_value )
- {
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @brief set_pause_on_nce_int - enable NCE soft error
- /// @param[in] i_on_or_off - the desired state.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note If the input is mss::ON, this method enables the error, it's corresponding
- /// threshold defines the threshold at which the engine will stop. If no threshold is
- /// defined (the error is disabled) this method will set the threshold to 1. A previously
- /// defined threshold (i.e., not disabled) will be left intact. If the input
- /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
- ///
- inline stop_conditions& set_pause_on_nce_soft( const states i_on_or_off )
- {
- return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN>(i_on_or_off);
- }
-
- ///
- /// @brief set_thresh_nce_hard
- /// @param[in] i_value the value of the field
- /// NCE hard error threshold magnitude to trigger for triggering pause. If 1111,
- /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it
- /// takes sees 2^[this value] number of errors of this type.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note The register field is actually an exponent. The hardware will count 2^n for the
- /// threshold. However, the input represents a count - how many. Thus we need to convert
- /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
- /// to the nearest power of 2 which is less than 2^15 before being set in the register.
- ///
- inline stop_conditions& set_thresh_nce_hard( const uint64_t i_value )
- {
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @brief set_pause_on_nce_hard - enable NCE hard error
- /// @param[in] i_on_or_off - the desired state.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note If the input is mss::ON, this method enables the error, it's corresponding
- /// threshold defines the threshold at which the engine will stop. If no threshold is
- /// defined (the error is disabled) this method will set the threshold to 1. A previously
- /// defined threshold (i.e., not disabled) will be left intact. If the input
- /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
- ///
- inline stop_conditions& set_pause_on_nce_hard( const states i_on_or_off )
- {
- return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN>(i_on_or_off);
- }
-
- ///
- /// @brief set_thresh_rce
- /// @param[in] i_value the value of the field
- /// RCE error threshold magnitude to trigger for triggering pause. If 1111, then
- /// pause will never be triggered (disabled). Else, then MCBIST will pause if it takes
- /// sees 2^[this value] number of errors of this type.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note The register field is actually an exponent. The hardware will count 2^n for the
- /// threshold. However, the input represents a count - how many. Thus we need to convert
- /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
- /// to the nearest power of 2 which is less than 2^15 before being set in the register.
- ///
- inline stop_conditions& set_thresh_rce( const uint64_t i_value )
- {
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE_LEN>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @brief set_pause_on_rce - enable RCE error
- /// @param[in] i_on_or_off - the desired state.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note If the input is mss::ON, this method enables the error, it's corresponding
- /// threshold defines the threshold at which the engine will stop. If no threshold is
- /// defined (the error is disabled) this method will set the threshold to 1. A previously
- /// defined threshold (i.e., not disabled) will be left intact. If the input
- /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
- ///
- inline stop_conditions& set_pause_on_rce( const states i_on_or_off )
- {
- return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE_LEN>(i_on_or_off);
- }
-
- ///
- /// @brief set_thresh_ice
- /// @param[in] i_value the value of the field
- /// ICE (IMPE) error threshold magnitude to trigger for triggering pause. If 1111,
- /// then pause will never be triggered (disabled). Else, then MCBIST will pause if
- /// it takes sees 2^[this value] number of errors of this type.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note The register field is actually an exponent. The hardware will count 2^n for the
- /// threshold. However, the input represents a count - how many. Thus we need to convert
- /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
- /// to the nearest power of 2 which is less than 2^15 before being set in the register.
- ///
- inline stop_conditions& set_thresh_ice( const uint64_t i_value )
- {
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE_LEN>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @brief set_pause_on_ice - enable ICE (IMPE) error
- /// @param[in] i_on_or_off - the desired state.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note If the input is mss::ON, this method enables the error, it's corresponding
- /// threshold defines the threshold at which the engine will stop. If no threshold is
- /// defined (the error is disabled) this method will set the threshold to 1. A previously
- /// defined threshold (i.e., not disabled) will be left intact. If the input
- /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
- ///
- inline stop_conditions& set_pause_on_ice( const states i_on_or_off )
- {
- return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE_LEN>(i_on_or_off);
- }
-
- ///
- /// @brief set_thresh_mce_int
- /// @param[in] i_value the value of the field
- /// MCE intermittent error threshold magnitude to trigger for triggering pause. If
- /// 1111, then pause will never be triggered (disabled). Else, then MCBIST will
- /// pause if it takes sees 2^[this value] number of errors of this type.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note The register field is actually an exponent. The hardware will count 2^n for the
- /// threshold. However, the input represents a count - how many. Thus we need to convert
- /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
- /// to the nearest power of 2 which is less than 2^15 before being set in the register.
- ///
- inline stop_conditions& set_thresh_mce_int( const uint64_t i_value )
- {
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @brief set_pause_on_mce_int - enable MCE intermittent error
- /// @param[in] i_on_or_off - the desired state.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note If the input is mss::ON, this method enables the error, it's corresponding
- /// threshold defines the threshold at which the engine will stop. If no threshold is
- /// defined (the error is disabled) this method will set the threshold to 1. A previously
- /// defined threshold (i.e., not disabled) will be left intact. If the input
- /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
- ///
- inline stop_conditions& set_pause_on_mce_int( const states i_on_or_off )
- {
- return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN>(i_on_or_off);
- }
-
- ///
- /// @brief set_thresh_mce_soft
- /// @param[in] i_value the value of the field
- /// MCE soft error threshold magnitude to trigger for triggering pause. If 1111,
- /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it
- /// takes sees 2^[this value] number of errors of this type.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note The register field is actually an exponent. The hardware will count 2^n for the
- /// threshold. However, the input represents a count - how many. Thus we need to convert
- /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
- /// to the nearest power of 2 which is less than 2^15 before being set in the register.
- ///
- inline stop_conditions& set_thresh_mce_soft( const uint64_t i_value )
- {
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @brief set_pause_on_mce_soft - enable MCE soft error
- /// @param[in] i_on_or_off - the desired state.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note If the input is mss::ON, this method enables the error, it's corresponding
- /// threshold defines the threshold at which the engine will stop. If no threshold is
- /// defined (the error is disabled) this method will set the threshold to 1. A previously
- /// defined threshold (i.e., not disabled) will be left intact. If the input
- /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
- ///
- inline stop_conditions& set_pause_on_mce_soft( const states i_on_or_off )
- {
- return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN>(i_on_or_off);
- }
-
- ///
- /// @brief set_thresh_mce_hard
- /// @param[in] i_value the value of the field
- /// MCE hard error threshold magnitude to trigger for triggering pause. If 1111,
- /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it
- /// takes sees 2^[this value] number of errors of this type.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note The register field is actually an exponent. The hardware will count 2^n for the
- /// threshold. However, the input represents a count - how many. Thus we need to convert
- /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
- /// to the nearest power of 2 which is less than 2^15 before being set in the register.
- ///
- inline stop_conditions& set_thresh_mce_hard( const uint64_t i_value )
- {
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @brief set_pause_on_mce_hard - enable MCE hard error
- /// @param[in] i_on_or_off - the desired state.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- /// @note If the input is mss::ON, this method enables the error, it's corresponding
- /// threshold defines the threshold at which the engine will stop. If no threshold is
- /// defined (the error is disabled) this method will set the threshold to 1. A previously
- /// defined threshold (i.e., not disabled) will be left intact. If the input
- /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
- ///
- inline stop_conditions& set_pause_on_mce_hard( const states i_on_or_off )
- {
- return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD,
- MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN>(i_on_or_off);
- }
-
- ///
- /// @brief set_pause_on_sce
- /// @param[in] i_on_or_off - the desired state.
- /// Enable pause on SCE error. When enabled, MCBIST will pause at the boundary
- /// configured if this error is seen.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_pause_on_sce( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_SCE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_on_mce
- /// @param[in] i_on_or_off - the desired state.
- /// Enable pause on MCE error. When enabled, MCBIST will pause at the boundary
- /// configured if this error is seen.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_pause_on_mce( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_MCE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_on_mpe
- /// @param[in] i_on_or_off - the desired state.
- /// Enable pause on MPE error. When enabled, MCBIST will pause at the boundary
- /// configured if this error is seen.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_pause_on_mpe( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_MPE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_on_ue
- /// @param[in] i_on_or_off - the desired state.
- /// Enable pause on UE error. When enabled, MCBIST will pause at the boundary
- /// configured if this error is seen.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_pause_on_ue( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_UE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_on_sue
- /// @param[in] i_on_or_off - the desired state.
- /// Enable pause on SUE error. When enabled, MCBIST will pause at the boundary
- /// configured if this error is seen.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_pause_on_sue( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_SUE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_on_aue
- /// @param[in] i_on_or_off - the desired state.
- /// Enable pause on AUE error. When enabled, MCBIST will pause at the boundary
- /// configured if this error is seen.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_pause_on_aue( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_AUE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_on_rcd
- /// @param[in] i_on_or_off - the desired state.
- /// Enable pause on RCD error. When enabled, MCBIST will pause at the boundary
- /// configured if this error is seen.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_pause_on_rcd( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_RCD>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_symbol_counter_mode
- /// @param[in] i_value the value of the field
- /// Selects which mode to use symbol counter latches: Mode 0) MAINT 8-bit error
- /// counters for of 72 symbols Mode 1) MCBIST 4-bit error counters for 18 nibbles x 8
- /// ranks (port agnostic) Mode 2) MCBIST 4-bit error counters for 18 nibbles x 4
- /// ports (rank agnostic) and 1-bit error rank map for 18 nibbles x 4 ports
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_symbol_counter_mode( const uint64_t i_value )
- {
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE,
- MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE_LEN>(i_value);
- return *this;
- }
-
- ///
- /// @brief set_nce_soft_symbol_count_enable
- /// @param[in] i_on_or_off - the desired state.
- /// Enables soft NCEs to trigger per symbol NCE error counting Only applies to
- /// scrub where we have different types of NCE. Non scrub counts all NCE.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_nce_soft_symbol_count_enable( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_NCE_SOFT_SYMBOL_COUNT_ENABLE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_nce_inter_symbol_count_enable
- /// @param[in] i_on_or_off - the desired state.
- /// Enables intermittent NCEs to trigger per symbol NCE error counting Only applies
- /// to scrub where we have different types of NCE. Non scrub counts all NCE.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_nce_inter_symbol_count_enable( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_NCE_INTER_SYMBOL_COUNT_ENABLE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_nce_hard_symbol_count_enable
- /// @param[in] i_on_or_off - the desired state.
- /// Enables hard NCEs to trigger per symbol NCE error counting Only applies to
- /// scrub where we have different types of NCE. Non scrub counts all NCE.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_nce_hard_symbol_count_enable( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_NCE_HARD_SYMBOL_COUNT_ENABLE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_mcb_error
- /// @param[in] i_on_or_off - the desired state.
- /// Enable pause when MCBIST error is logged. When enabled, MCBIST will pause at
- /// the boundary configured if this error is seen.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_pause_mcb_error( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_MCB_ERROR>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_mcb_log_full
- /// @param[in] i_on_or_off - the desired state.
- /// Enable pause when MCBIST log is full. When enabled, MCBIST will pause at the
- /// boundary configured if this error is seen.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_pause_mcb_log_full( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_MCB_LOG_FULL>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_maint_rce_with_ce
- /// @param[in] i_on_or_off - the desired state.
- /// cfg_maint_rce_with_ce - not implemented. Need to investigate if needed for nimbus.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_maint_rce_with_ce( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_MAINT_RCE_WITH_CE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_mce_soft_symbol_count_enable
- /// @param[in] i_on_or_off - the desired state.
- /// Enables soft MCEs to trigger per symbol MCE error counting Only applies to
- /// scrub where we have different types of MCE. Non scrub counts all MCE.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_mce_soft_symbol_count_enable( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_MCE_SOFT_SYMBOL_COUNT_ENABLE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_mce_inter_symbol_count_enable
- /// @param[in] i_on_or_off - the desired state.
- /// Enables intermittent MCEs to trigger per symbol MCE error counting Only applies
- /// to scrub where we have different types of MCE. Non scrub counts all MCE.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_mce_inter_symbol_count_enable( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_MCE_INTER_SYMBOL_COUNT_ENABLE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_mce_hard_symbol_count_enable
- /// @param[in] i_on_or_off - the desired state.
- /// Enables hard MCEs to trigger per symbol MCE error counting Only applies to
- /// scrub where we have different types of MCE. Non scrub counts all MCE.
- /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- ///
- inline stop_conditions& set_mce_hard_symbol_count_enable( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_MCE_HARD_SYMBOL_COUNT_ENABLE>(i_on_or_off);
- return *this;
- }
-
- private:
-
- fapi2::buffer<uint64_t> iv_value;
-};
-
-///
-/// @class memdiags operational constraints
-///
-struct constraints
-{
- ///
- /// @brief constraints default constructor
- ///
- constraints():
- iv_stop(),
- iv_pattern(NO_PATTERN),
- iv_end_boundary(NONE),
- iv_speed(LUDICROUS),
- iv_start_address(0),
- iv_end_address(mcbist::address::LARGEST_ADDRESS)
- {
- }
-
- ///
- /// @brief constraints constructor
- /// @param[in] i_pattern a pattern to set
- ///
- constraints( const uint64_t i_pattern ):
- constraints()
- {
- iv_pattern = i_pattern;
- FAPI_INF("setting up constraints with pattern %d", i_pattern);
- }
-
- ///
- /// @brief constraints constructor
- /// @param[in] i_stop stop conditions
- ///
- constraints( const stop_conditions& i_stop ):
- constraints()
- {
- iv_stop = i_stop;
- FAPI_INF("setting up constraints with stop 0x%016lx", uint64_t(i_stop));
- }
-
- ///
- /// @brief constraints constructor
- /// @param[in] i_stop stop conditions
- /// @param[in] i_start_address address to start from
- ///
- constraints( const stop_conditions& i_stop,
- const address& i_start_address ):
- constraints(i_stop)
- {
- iv_start_address = i_start_address;
- FAPI_INF("setting up constraints with start address 0x%016lx", uint64_t(i_start_address));
- }
-
- ///
- /// @brief constraints constructor
- /// @param[in] i_stop stop conditions
- /// @param[in] i_speed the speed at which to run
- /// @param[in] i_end_boundary the place to stop on error
- /// @param[in] i_start_address address to start from
- /// @param[in] i_end_address address to end at (optional, run to end)
- ///
- constraints( const stop_conditions& i_stop,
- const speed i_speed,
- const end_boundary i_end_boundary,
- const address& i_start_address,
- const address& i_end_address = mcbist::address(mcbist::address::LARGEST_ADDRESS) ):
- constraints(i_stop, i_start_address)
- {
- iv_end_boundary = i_end_boundary;
- iv_speed = i_speed;
- iv_end_address = i_end_address;
-
- FAPI_INF("setting up constraints with end boundary %d and speed 0x%x", i_end_boundary, i_speed);
-
- // If our end address is 'before' our start address, make the end address the same as the start.
- if (iv_start_address > iv_end_address)
- {
- iv_end_address = iv_start_address;
- }
- }
-
- // Member variable declaration
- stop_conditions iv_stop;
- uint64_t iv_pattern;
- end_boundary iv_end_boundary;
- speed iv_speed;
- mcbist::address iv_start_address;
- mcbist::address iv_end_address;
-};
-
-
-} // namespace
-} // namespace
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C
deleted file mode 100644
index 2fa88eb98..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C
+++ /dev/null
@@ -1,175 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file mcbist/sim.C
-/// @brief MCBIST/memdiags functions for when we're in simulation mode
-///
-// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#include <lib/shared/nimbus_defaults.H>
-#include <fapi2.H>
-
-#include <lib/dimm/rank.H>
-#include <lib/mcbist/address.H>
-#include <lib/mcbist/mcbist.H>
-#include <lib/mcbist/patterns.H>
-#include <lib/mcbist/sim.H>
-#include <generic/memory/lib/utils/count_dimm.H>
-#include <generic/memory/lib/utils/pos.H>
-
-using fapi2::TARGET_TYPE_MCBIST;
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_SYSTEM;
-using fapi2::FAPI2_RC_SUCCESS;
-
-namespace mss
-{
-
-namespace mcbist
-{
-
-namespace sim
-{
-
-///
-/// @brief Perform a sim version of initializing memory
-/// @param[in] i_target MCBIST
-/// @param[in] i_pattern an index representing a pattern to use to initize memory (defaults to 0)
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-template<>
-fapi2::ReturnCode sf_init( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const uint64_t i_pattern )
-{
- FAPI_INF("Start sim init");
-
- // If we're running in the simulator, we want to only touch the addresses which training touched
-
- for (const auto& p : i_target.getChildren<TARGET_TYPE_MCA>())
- {
- std::vector<uint64_t> l_pr;
- mss::mcbist::program<TARGET_TYPE_MCBIST> l_program;
-
- mss::mcbist::address l_start;
- mss::mcbist::address l_end;
-
- size_t l_rank_address_pair = 0;
-
- // No point in bothering if we don't have any DIMM
- if (mss::count_dimm(p) == 0)
- {
- FAPI_INF("No DIMM on %s, not running sf_init", mss::c_str(p));
- continue;
- }
-
- // In sim we know a few things ...
- // Get the primary ranks for this port. We know there can only be 4, and we know we only trained the primary
- // ranks. Therefore, we only need to clean up the primary ranks. And because there's 4 max, we can do it
- // all using the 4 address range registers of tne MCBIST (broadcast currently not considered.)
- // So we can write 0's to those to get their ECC fixed up.
- FAPI_TRY( mss::rank::primary_ranks(p, l_pr) );
- fapi2::Assert( l_pr.size() <= mss::MAX_RANK_PER_DIMM );
-
- for (auto r = l_pr.begin(); r != l_pr.end(); ++l_rank_address_pair, ++r)
- {
- FAPI_INF("sim init %s, rank %d", mss::c_str(p), *r);
-
- // Setup l_start to represent this rank, and then make the end address from that.
- l_start.set_master_rank(*r);
-
- // Set C3 bit to get an entire cache line
- l_start.get_sim_end_address(l_end);
-
- // By default we're in maint address mode, not address counting mode. So we give it a start and end, and ignore
- // anything invalid - that's what maint address mode is all about
- mss::mcbist::config_address_range(i_target, l_start, l_end, l_rank_address_pair);
-
- // Write
- {
- // Run in ECC mode, 64B writes (superfast mode)
-
- mss::mcbist::subtest_t<TARGET_TYPE_MCBIST> l_fw_subtest =
- mss::mcbist::write_subtest<TARGET_TYPE_MCBIST>();
-
- l_fw_subtest.enable_port(mss::relative_pos<TARGET_TYPE_MCBIST>(p));
- l_fw_subtest.change_addr_sel(l_rank_address_pair);
- l_fw_subtest.enable_dimm(mss::rank::get_dimm_from_rank(*r));
- l_program.iv_subtests.push_back(l_fw_subtest);
- FAPI_DBG("adding superfast write for %s rank %d (dimm %d)", mss::c_str(p), *r, mss::rank::get_dimm_from_rank(*r));
- }
-
- // Read - we do a read here as verification can use this as a tool as we do the write and then the read.
- // If we failed to write properly the read would thow ECC errors. Just a write (which the real hardware would
- // do) doesn't catch that. This takes longer, but it's not terribly long in any event.
- {
- // Run in ECC mode, 64B writes (superfast mode)
- mss::mcbist::subtest_t<TARGET_TYPE_MCBIST> l_fr_subtest =
- mss::mcbist::read_subtest<TARGET_TYPE_MCBIST>();
-
- l_fr_subtest.enable_port(mss::relative_pos<TARGET_TYPE_MCBIST>(p));
- l_fr_subtest.change_addr_sel(l_rank_address_pair);
- l_fr_subtest.enable_dimm(mss::rank::get_dimm_from_rank(*r));
- l_program.iv_subtests.push_back(l_fr_subtest);
- FAPI_DBG("adding superfast read for %s rank %d (dimm %d)", mss::c_str(p), *r, mss::rank::get_dimm_from_rank(*r));
- }
- }
-
- // Write pattern
- FAPI_TRY( mss::mcbist::load_pattern(i_target, i_pattern) );
-
- // Setup the sim polling based on a heuristic <cough>guess</cough>
- // Looks like ~400ck per address for a write/read program on the sim-dimm, and add a long number of polls
- // On real hardware wait 100ms and then start polling for another 5s
- l_program.iv_poll.iv_initial_sim_delay = mss::cycles_to_simcycles(((l_end - l_start) * l_pr.size()) * 800);
- l_program.iv_poll.iv_initial_delay = 100 * mss::DELAY_1MS;
- l_program.iv_poll.iv_sim_delay = 100000;
- l_program.iv_poll.iv_delay = 10 * mss::DELAY_1MS;
- l_program.iv_poll.iv_poll_count = 500;
-
- // Just one port for now. Per Shelton we need to set this in maint address mode
- // even tho we specify the port/dimm in the subtest.
- fapi2::buffer<uint8_t> l_port;
- l_port.setBit(mss::relative_pos<TARGET_TYPE_MCBIST>(p));
- l_program.select_ports(l_port >> 4);
-
- // Kick it off, wait for a result
- FAPI_TRY( mss::mcbist::execute(i_target, l_program) );
- }
-
-fapi_try_exit:
- FAPI_INF("End sim init");
- return fapi2::current_err;
-}
-
-} // namespace sim
-
-} // namespace mcbist
-
-} // namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss.mk b/src/import/chips/p9/procedures/hwp/memory/lib/mss.mk
index 2b07ee18c..878c51e37 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mss.mk
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2015,2017
+# Contributors Listed Below - COPYRIGHT 2015,2019
# [+] International Business Machines Corp.
#
#
@@ -44,6 +44,7 @@ $(call ADD_MODULE_INCDIR,$(1),$(FAPI2_PATH)/include)
$(call ADD_MODULE_INCDIR,$(1),$(GENPATH))
$(call ADD_MODULE_INCDIR,$(1),$(FAPI2_PLAT_INCLUDE))
$(call ADD_MODULE_INCDIR,$(1),$(ROOTPATH))
+$(call ADD_MODULE_INCDIR,$(1),$(ROOTPATH)/generic/memory/lib)
endef
MODULE = mss
OBJS += $(MSS_MODULE_OBJS)
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H
index c482989dd..709d3af1b 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H
@@ -14142,6 +14142,31 @@ fapi_try_exit:
///
+/// @brief ATTR_MSS_MRW_NVDIMM_SLOT_POSITION getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generateParameters (PROC_CHIP)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note The position of a dimm is based on which mca it is associated with and which
+/// drop behind that mca, with 16 dimms possible per processor socket. The formula
+/// is: [processor position with no gaps, i.e. 0,1,2,3]*16 + [mca position on this
+/// processor * 2] + [dimm location behind this
+/// mca]
+///
+inline fapi2::ReturnCode mrw_nvdimm_slot_position(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MRW_NVDIMM_SLOT_POSITION, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_MRW_NVDIMM_SLOT_POSITION: 0x%lx",
+ uint64_t(fapi2::current_err));
+ return fapi2::current_err;
+}
+
+///
/// @brief ATTR_MSS_MRW_UNSUPPORTED_RANK_CONFIG getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
/// @param[out] ref to the value uint64_t
@@ -21501,6 +21526,172 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief ATTR_MSS_MRW_OCMB_THERMAL_MEMORY_POWER_LIMIT getter
+/// @param[out] uint64_t* memory to store the value
+/// @note Generated by gen_accessors.pl generateParameters (SYSTEM A)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Machine Readable Workbook Thermal Memory Power Limit Used to calculate throttles
+/// to meet the thermal power per DIMM limit Per DIMM basis, uses first matching KEY
+/// entry KEY (0-21): In order DIMM_SIZE = bits 0-3, DIMM_GEN = 4-5, DIMM_TYPE =
+/// 6-8, DIMM_WIDTH = 9-11, DIMM_DENSITY = 12-14, DIMM_STACK_TYPE = 15-16,
+/// DRAM_MFGID = 17-19, DIMM_HEIGHT = 20-21, Bits 22-32: Not used VALUE (bits 32-47)
+/// in cW: thermal power limit DDIMM: Total OCMB+DRAM power limit per DDIMM
+/// non-DDIMM: VMEM+VPP power limit per
+/// DIMM
+///
+inline fapi2::ReturnCode mrw_ocmb_thermal_memory_power_limit(uint64_t* o_array)
+{
+ uint64_t l_value[25];
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MRW_OCMB_THERMAL_MEMORY_POWER_LIMIT, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ l_value) );
+ memcpy(o_array, &l_value, 200);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_MRW_OCMB_THERMAL_MEMORY_POWER_LIMIT: 0x%lx (system target)",
+ uint64_t(fapi2::current_err));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_MRW_OCMB_PWR_SLOPE getter
+/// @param[out] uint64_t* memory to store the value
+/// @note Generated by gen_accessors.pl generateParameters (SYSTEM A)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Machine Readable Workbook Power Curve Slope for DIMM Used to calculate thermal
+/// throttles and port power Per DIMM basis, uses first matching KEY entry KEY
+/// (0-21): In order DIMM_SIZE = bits 0-3, DIMM_GEN = 4-5, DIMM_TYPE = 6-8,
+/// DIMM_WIDTH = 9-11, DIMM_DENSITY = 12-14, DIMM_STACK_TYPE = 15-16, DRAM_MFGID =
+/// 17-19, DIMM_HEIGHT = 20-21, Bits 22-32: Not used VALUE (bits 32-47) in
+/// cW/utilization: DIMM power slope DDIMM: Total OCMB+DRAM power slope per DDIMM
+/// non-DDIMM: VMEM+VPP power slope per
+/// DIMM
+///
+inline fapi2::ReturnCode mrw_ocmb_pwr_slope(uint64_t* o_array)
+{
+ uint64_t l_value[50];
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MRW_OCMB_PWR_SLOPE, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_value) );
+ memcpy(o_array, &l_value, 400);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_MRW_OCMB_PWR_SLOPE: 0x%lx (system target)",
+ uint64_t(fapi2::current_err));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_MRW_OCMB_PWR_INTERCEPT getter
+/// @param[out] uint64_t* memory to store the value
+/// @note Generated by gen_accessors.pl generateParameters (SYSTEM A)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Machine Readable Workbook Power Curve Intercept for DIMM Used to calculate
+/// thermal throttles and port power Per DIMM basis, uses first matching KEY entry
+/// KEY (0-21): In order DIMM_SIZE = bits 0-3, DIMM_GEN = 4-5, DIMM_TYPE = 6-8,
+/// DIMM_WIDTH = 9-11, DIMM_DENSITY = 12-14, DIMM_STACK_TYPE = 15-16, DRAM_MFGID =
+/// 17-19, DIMM_HEIGHT = 20-21, Bits 22-32: Not used VALUE (bits 32-47) in
+/// cW/utilization: DIMM power intercept DDIMM: Total OCMB+DRAM power intercept per
+/// DDIMM non-DDIMM: VMEM+VPP power intercept per
+/// DIMM
+///
+inline fapi2::ReturnCode mrw_ocmb_pwr_intercept(uint64_t* o_array)
+{
+ uint64_t l_value[50];
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MRW_OCMB_PWR_INTERCEPT, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_value) );
+ memcpy(o_array, &l_value, 400);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_MRW_OCMB_PWR_INTERCEPT: 0x%lx (system target)",
+ uint64_t(fapi2::current_err));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_MRW_OCMB_CURRENT_CURVE_WITH_LIMIT getter
+/// @param[out] uint64_t* memory to store the value
+/// @note Generated by gen_accessors.pl generateParameters (SYSTEM A)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Machine Readable Workbook Current Curve Intercept and limit for DIMM Used to
+/// calculate throttles to meet regulator current per DIMM limit Per DIMM basis,
+/// uses first matching KEY entry For DDIMM, use PMIC SW output that provides worst
+/// case throttling KEY (0-21): In order DIMM_SIZE = bits 0-3, DIMM_GEN = 4-5,
+/// DIMM_TYPE = 6-8, DIMM_WIDTH = 9-11, DIMM_DENSITY = 12-14, DIMM_STACK_TYPE =
+/// 15-16, DRAM_MFGID = 17-19, DIMM_HEIGHT = 20-21, Bits 22-32: Not used VALUE (bits
+/// 32-39): Current limit (dA) DDIMM: PMIC output current limit per DDIMM non-DDIMM:
+/// VMEM regulator current limit per DIMM VALUE (bits 40-51): Current slope
+/// (cA/utilization) DDIMM: PMIC output current slope per DDIMM non-DDIMM: VMEM
+/// regulator current slope per DIMM VALUE (bits 52-63): Current intercept (cA)
+/// DDIMM: PMIC output current intercept per DDIMM non-DDIMM: VMEM regulator current
+/// intercept per
+/// DIMM
+///
+inline fapi2::ReturnCode mrw_ocmb_current_curve_with_limit(uint64_t* o_array)
+{
+ uint64_t l_value[25];
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MRW_OCMB_CURRENT_CURVE_WITH_LIMIT, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ l_value) );
+ memcpy(o_array, &l_value, 200);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_MRW_OCMB_CURRENT_CURVE_WITH_LIMIT: 0x%lx (system target)",
+ uint64_t(fapi2::current_err));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_MRW_SAFEMODE_DRAM_DATABUS_UTIL getter
+/// @param[out] uint32_t& reference to store the value
+/// @note Generated by gen_accessors.pl generateParameters (SYSTEM)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Machine Readable Workbook value for safe mode dram data bus utilization in centi
+/// percent (c%). Set to below optimum value/ rate. On a per port basis Also used
+/// for emergency mode throttle Used to thermally protect the system in all
+/// supported environmental conditions when OCC is not functional Consumer:
+/// thermal_init, initfile Default to 2500
+/// c%%
+///
+inline fapi2::ReturnCode mrw_safemode_dram_databus_util(uint32_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MRW_SAFEMODE_DRAM_DATABUS_UTIL, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_MRW_SAFEMODE_DRAM_DATABUS_UTIL: 0x%lx (system target)",
+ uint64_t(fapi2::current_err));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_PORT_POS_OF_FAIL_THROTTLE getter
+/// @param[out] uint64_t& reference to store the value
+/// @note Generated by gen_accessors.pl generateParameters (SYSTEM)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note This is the fapi position of the port that failed to calculate memory throttles
+/// given the passed in watt target and or
+/// utilization
+///
+inline fapi2::ReturnCode port_pos_of_fail_throttle(uint64_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_PORT_POS_OF_FAIL_THROTTLE, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MEM_PORT_POS_OF_FAIL_THROTTLE: 0x%lx (system target)",
+ uint64_t(fapi2::current_err));
+ return fapi2::current_err;
+}
+
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H
index 201b1ee39..cf0884182 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,7 +40,7 @@
#define MSS_ATTR_ACCESS_MANUAL_H_
#include <fapi2.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <lib/mss_attribute_accessors.H>
namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss_vpd_decoder.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss_vpd_decoder.H
index d33f69a26..fd6485d83 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mss_vpd_decoder.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss_vpd_decoder.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,7 +33,7 @@
#include <lib/shared/mss_const.H>
#include <lib/mss_utils.H>
#include <lib/mss_attribute_accessors.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <generic/memory/lib/utils/index.H>
namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.C
index f68b7dab9..c12adbab8 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,7 +37,7 @@
#include <lib/phy/adr32s.H>
#include <lib/phy/dcd.H>
#include <lib/workarounds/adr32s_workarounds.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <lib/mss_attribute_accessors_manual.H>
using fapi2::TARGET_TYPE_MCA;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.H
index 0de3f350e..ee8e54121 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,7 +42,7 @@
#include <lib/mss_attribute_accessors.H>
#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/scom.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
namespace mss
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C
index 88337c26c..82769de0f 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C
@@ -48,6 +48,7 @@
#include <lib/phy/adr.H>
#include <lib/phy/seq.H>
#include <lib/fir/check.H>
+#include <lib/ccs/ccs_nimbus.H>
#include <lib/workarounds/dp16_workarounds.H>
#include <lib/workarounds/wr_vref_workarounds.H>
#include <lib/dimm/ddr4/latch_wr_vref.H>
@@ -55,10 +56,10 @@
#include <lib/workarounds/dll_workarounds.H>
#include <lib/workarounds/dqs_align_workarounds.H>
#include <lib/phy/mss_training.H>
-#include <generic/memory/lib/utils/find_magic.H>
+#include <lib/utils/find_magic.H>
#include <generic/memory/lib/utils/bit_count.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/utils/dump_regs.H>
+#include <lib/utils/nimbus_find.H>
+#include <generic/memory/lib/utils/dump_regs.H>
#include <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <lib/dimm/rank.H>
@@ -1038,9 +1039,9 @@ fapi2::ReturnCode execute_cal_steps_helper( const fapi2::Target<TARGET_TYPE_MCA>
const uint64_t i_total_cycles)
{
const auto& l_mcbist = mss::find_target<TARGET_TYPE_MCBIST>(i_target);
- auto l_cal_inst = mss::ccs::initial_cal_command<TARGET_TYPE_MCBIST>(i_rp);
+ auto l_cal_inst = mss::ccs::initial_cal_command(i_rp);
- mss::ccs::program<TARGET_TYPE_MCBIST, TARGET_TYPE_MCA> l_program;
+ ccs::program l_program;
FAPI_DBG("%s executing training CCS instruction: 0x%016llx, 0x%016llx for cal config 0x%16x",
mss::c_str(i_target),
@@ -1303,7 +1304,7 @@ fapi2::ReturnCode override_odt_wr_config( const fapi2::Target<fapi2::TARGET_TYPE
FAPI_ASSERT( i_rank < MAX_MRANK_PER_PORT,
fapi2::MSS_INVALID_RANK()
.set_RANK(i_rank)
- .set_MCA_TARGET(i_target)
+ .set_PORT_TARGET(i_target)
.set_FUNCTION(OVERRIDE_ODT_WR_CONFIG),
"%s had invalid rank (0x%016lx) passed into override_odt_wr_config",
mss::c_str(i_target),
@@ -1337,7 +1338,7 @@ fapi_try_exit:
template<>
fapi2::ReturnCode setup_wr_level_terminations( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const uint64_t i_rp,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
// Danger: Make sure this DIMM target doesn't get used/accessed until it is populated
// by get_dimm_target_from_rank below!
@@ -1396,7 +1397,7 @@ fapi_try_exit:
template<>
fapi2::ReturnCode restore_mainline_terminations( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const uint64_t i_rp,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
// Danger: Make sure this DIMM target doesn't get used/accessed until it is populated
// by get_dimm_target_from_rank below!
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H
index 9195725ae..06a115d85 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,7 +37,10 @@
#define _MSS_DDR_PHY_H_
#include <fapi2.H>
-#include <lib/ccs/ccs.H>
+#include <lib/shared/mss_const.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
+
namespace mss
{
@@ -295,16 +298,15 @@ fapi2::ReturnCode override_odt_wr_config( const fapi2::Target<fapi2::TARGET_TYPE
///
/// @brief Setup terminations for WR_LEVEL cal for a given RP
/// @tparam T the target type of the MCA/MBA
-/// @tparam CT TargetType of the CCS instruction
/// @param[in] i_target the target associated with this cal setup
/// @param[in] i_rp selected rank pair
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
-template< fapi2::TargetType T, fapi2::TargetType CT >
+template< fapi2::TargetType T >
fapi2::ReturnCode setup_wr_level_terminations( const fapi2::Target<T>& i_target,
const uint64_t i_rp,
- std::vector< ccs::instruction_t<CT> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Setup terminations for WR_LEVEL cal for a given RP
@@ -313,24 +315,23 @@ fapi2::ReturnCode setup_wr_level_terminations( const fapi2::Target<T>& i_target,
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
-template<>
+template< >
fapi2::ReturnCode setup_wr_level_terminations( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const uint64_t i_rp,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Restore terminations after WR_LEVEL cal for a given RP
/// @tparam T the target type of the MCA/MBA
-/// @tparam CT TargetType of the CCS instruction
/// @param[in] i_target the target associated with this cal setup
/// @param[in] i_rp selected rank pair
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
-template< fapi2::TargetType T, fapi2::TargetType CT >
+template< fapi2::TargetType T >
fapi2::ReturnCode restore_mainline_terminations( const fapi2::Target<T>& i_target,
const uint64_t i_rp,
- std::vector< ccs::instruction_t<CT> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Restore terminations after WR_LEVEL cal for a given RP
@@ -339,10 +340,10 @@ fapi2::ReturnCode restore_mainline_terminations( const fapi2::Target<T>& i_targe
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
-template<>
+template< >
fapi2::ReturnCode restore_mainline_terminations( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const uint64_t i_rp,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
///
/// @brief Perform the DLL calibration
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C
index 507f95f86..81b8114ff 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C
@@ -51,7 +51,7 @@
#include <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/pos.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find_magic.H>
+#include <lib/utils/find_magic.H>
#include <lib/workarounds/dp16_workarounds.H>
#include <lib/fir/check.H>
#include <generic/memory/lib/utils/mss_math.H>
@@ -4626,7 +4626,7 @@ fapi2::ReturnCode check_rp_and_dram( const fapi2::Target<fapi2::TARGET_TYPE_MCA>
// Checks for i_rp in bounds
FAPI_ASSERT(i_rp < MAX_RANK_PAIRS,
fapi2::MSS_INVALID_RANK().
- set_MCA_TARGET(i_target).
+ set_PORT_TARGET(i_target).
set_RANK(i_rp).
set_FUNCTION(i_function),
"%s rank pair is out of bounds %lu", mss::c_str(i_target), i_rp);
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H
index 73e011b94..1f9f9714d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H
@@ -42,7 +42,7 @@
#include <p9_mc_scom_addresses_fld.H>
#include <generic/memory/lib/utils/scom.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <generic/memory/lib/utils/mss_bad_bits.H>
#include <lib/mss_attribute_accessors.H>
#include <lib/shared/mss_const.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.C
index 8994a75d0..b57aa7070 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.C
@@ -38,6 +38,7 @@
#include <lib/shared/nimbus_defaults.H>
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>
+#include <lib/shared/mss_const.H>
#include <lib/phy/mss_lrdimm_training.H>
#include <lib/phy/mss_training.H>
#include <lib/dimm/rank.H>
@@ -45,13 +46,15 @@
#include <lib/dimm/ddr4/control_word_ddr4.H>
#include <lib/dimm/ddr4/data_buffer_ddr4.H>
#include <lib/workarounds/ccs_workarounds.H>
-#include <lib/ccs/ccs.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
#include <lib/mc/port.H>
#include <lib/rosetta_map/rosetta_map.H>
#include <lib/dimm/ddr4/pba.H>
#include <lib/eff_config/timing.H>
#include <generic/memory/lib/utils/pos.H>
+
#ifdef LRDIMM_CAPABLE
#include <lib/phy/mss_lrdimm_training_helper.H>
#endif
@@ -190,7 +193,7 @@ fapi2::ReturnCode mpr_pattern_wr_rank(const fapi2::Target<fapi2::TARGET_TYPE_MCA
return fapi2::FAPI2_RC_SUCCESS;
}
- mss::ccs::program<fapi2::TARGET_TYPE_MCBIST> l_program;
+ mss::ccs::program l_program;
const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
// Gets the DIMM target
@@ -250,16 +253,17 @@ fapi_try_exit:
///
fapi2::ReturnCode execute_nttm_mode_read(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target)
{
- using TT = ccsTraits<fapi2::TARGET_TYPE_MCBIST>;
+
+ using TT = ccsTraits<mss::mc_type::NIMBUS>;
// A hardware bug requires us to increase our delay significanlty for NTTM mode reads
constexpr uint64_t SAFE_NTTM_READ_DELAY = 0x40;
- mss::ccs::program<fapi2::TARGET_TYPE_MCBIST> l_program;
+ mss::ccs::program l_program;
const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
// Note: CKE are enabled by default in the NTTM mode read command, so we should be good to go
// set the NTTM read mode
- auto l_nttm_read = mss::ccs::nttm_read_command<fapi2::TARGET_TYPE_MCBIST>();
+ auto l_nttm_read = mss::ccs::nttm_read_command();
l_nttm_read.arr1.template insertFromRight<TT::ARR1_IDLES, TT::ARR1_IDLES_LEN>(SAFE_NTTM_READ_DELAY);
l_program.iv_instructions.push_back(l_nttm_read);
@@ -439,21 +443,21 @@ fapi2::ReturnCode mrep::set_delay(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&
const uint8_t i_rank,
const uint8_t i_delay ) const
{
- mss::ccs::program<fapi2::TARGET_TYPE_MCBIST> l_program;
+ mss::ccs::program l_program;
const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
std::vector<cw_info> l_bcws =
{
- {i_rank, NIBBLE0_BCW_NUMBER, i_delay, mss::tmrc(), mss::CW8_DATA_LEN, cw_info::BCW},
- {i_rank, NIBBLE1_BCW_NUMBER, i_delay, mss::tmrc(), mss::CW8_DATA_LEN, cw_info::BCW},
+ {i_rank, NIBBLE0_BCW_NUMBER, i_delay, mss::tmrd_l2(), mss::CW8_DATA_LEN, cw_info::BCW},
+ {i_rank, NIBBLE1_BCW_NUMBER, i_delay, mss::tmrd_l2(), mss::CW8_DATA_LEN, cw_info::BCW},
};
uint8_t l_sim = 0;
FAPI_TRY(mss::is_simulation(l_sim));
// Ensure our CKE's are powered on
- l_program.iv_instructions.push_back(mss::ccs::des_command<fapi2::TARGET_TYPE_MCBIST>());
+ l_program.iv_instructions.push_back(mss::ccs::des_command());
// Inserts the function space selects
FAPI_TRY(mss::ddr4::insert_function_space_select(l_bcws));
@@ -807,9 +811,11 @@ void deconfigure_steps(const uint8_t i_dimm_type,
// If the DIMM type is an LRDIMM, configure for LRDIMM
if(i_dimm_type == fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM)
{
- FAPI_INF("LRDIMM: deconfigure WR VREF 2D");
+ FAPI_INF("LRDIMM: deconfigure WR VREF 2D and RD VREF 2D");
// We clear WRITE_CTR_2D_VREF as the HW calibration algorithm will not work with LRDIMM
- io_cal_steps.clearBit<WRITE_CTR_2D_VREF>();
+ // Same for RD VREF
+ io_cal_steps.clearBit<WRITE_CTR_2D_VREF>()
+ .clearBit<READ_CTR_2D_VREF>();
return;
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.H
index c7d92d98a..eef2c09d4 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,8 +39,10 @@
#define MSS_LRDIMM_TRAINING_H
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <lib/shared/mss_const.H>
#include <lib/phy/mss_training.H>
-#include <lib/ccs/ccs.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>
#include <lib/dimm/ddr4/control_word_ddr4.H>
#include <lib/dimm/ddr4/data_buffer_ddr4.H>
@@ -52,6 +54,7 @@
#include <lib/rosetta_map/rosetta_map.H>
#include <lib/phy/ddr_phy.H>
+
// Disables LRDIMM support for HB
#ifndef __HOSTBOOT_MODULE
#define CONFIG_LRDIMM_CAPABLE 1
@@ -86,18 +89,16 @@ fapi2::ReturnCode mpr_pattern_wr_all_ranks(const fapi2::Target<fapi2::TARGET_TYP
///
/// @brief Adds all write commands for the passed in pattern
-/// @tparam fapi2::TargetType T target type for the CCS instruction
/// @param[in] i_target DIMM target on which to operate
/// @param[in] i_rank the DIMM rank to set the MPR on
/// @param[in] i_pattern the pattern to write into the MPRS
/// @param[in,out] io_insts CCS instructions
/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
///
-template<fapi2::TargetType T>
inline fapi2::ReturnCode add_mpr_pattern_writes(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
const uint64_t i_pattern,
- std::vector<mss::ccs::instruction_t<T>>& io_insts)
+ std::vector<mss::ccs::instruction_t>& io_insts)
{
constexpr uint64_t NUM_MPR_PATTERNS = 4;
@@ -122,10 +123,10 @@ inline fapi2::ReturnCode add_mpr_pattern_writes(const fapi2::Target<fapi2::TARGE
FAPI_TRY(l_swizzled_pattern.extract(l_pattern, l_ba * PATTERN_LEN, PATTERN_LEN, ADDR_START), "%s ba%u",
mss::c_str(i_target), l_ba);
{
- auto l_wr = mss::ccs::wr_command<fapi2::TARGET_TYPE_MCBIST>( i_rank,
- l_ba,
- MPR_WR_BG,
- l_pattern);
+ auto l_wr = mss::ccs::wr_command( i_rank,
+ l_ba,
+ MPR_WR_BG,
+ l_pattern);
// Swaps the bank addresses so they're a true to the BA we tried to pass in above
swap<BA0, BA1>(l_wr.arr0);
@@ -142,14 +143,12 @@ fapi_try_exit:
///
/// @brief Helper function to disable address inversion
-/// @tparam fapi2::TargetType T target type for the CCS instruction
/// @param[in] i_target DIMM target on which to operate
/// @param[in,out] io_insts CCS instructions
/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
///
-template<fapi2::TargetType T>
inline fapi2::ReturnCode disable_address_inversion(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector<mss::ccs::instruction_t<T>>& io_insts)
+ std::vector<mss::ccs::instruction_t>& io_insts)
{
// Declares the default control word that handles address inversion
// Data of 0 as we're going to override it below
@@ -177,14 +176,12 @@ fapi_try_exit:
///
/// @brief Helper function to restore default address inversion
-/// @tparam fapi2::TargetType T target type for the CCS instruction
/// @param[in] i_target DIMM target on which to operate
/// @param[in,out] io_insts CCS instructions
/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
///
-template<fapi2::TargetType T>
inline fapi2::ReturnCode restore_address_inversion(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector<mss::ccs::instruction_t<T>>& io_insts)
+ std::vector<mss::ccs::instruction_t>& io_insts)
{
// Declares the default control word that handles address inversion
// Data of 0 as we're going to override it below
@@ -590,7 +587,7 @@ inline fapi2::ReturnCode set_buffer_training(const fapi2::Target<fapi2::TARGET_T
const mss::ddr4::training i_mode )
{
- mss::ccs::program<fapi2::TARGET_TYPE_MCBIST> l_program;
+ mss::ccs::program l_program;
const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
@@ -615,7 +612,7 @@ inline fapi2::ReturnCode mpr_load(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&
const uint8_t i_mode,
const uint64_t i_rank)
{
- mss::ccs::program<fapi2::TARGET_TYPE_MCBIST> l_program;
+ mss::ccs::program l_program;
const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
@@ -647,7 +644,7 @@ inline fapi2::ReturnCode mpr_read( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&
constexpr uint64_t SAFETY_CYCLES = 2;
constexpr uint64_t ODT_CYCLE_LEN = 5 + SAFETY_CYCLES * 2;
- mss::ccs::program<fapi2::TARGET_TYPE_MCBIST> l_program;
+ mss::ccs::program l_program;
const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
uint8_t l_cl = 0;
@@ -661,16 +658,16 @@ inline fapi2::ReturnCode mpr_read( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&
FAPI_TRY(mss::eff_odt_rd(i_target, &l_rd_odt[0]));
- FAPI_TRY( ddr4::mpr_read<fapi2::TARGET_TYPE_MCBIST>(i_target, i_mpr_loc, i_rank, l_program.iv_instructions));
+ FAPI_TRY( ddr4::mpr_read(i_target, i_mpr_loc, i_rank, l_program.iv_instructions));
l_program.iv_instructions[0].arr1.template insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES,
MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(l_delay);
// Holds the RD ODT's for 5 cycles
{
- const auto l_ccs_value = mss::ccs::convert_odt_attr_to_ccs<fapi2::TARGET_TYPE_MCBIST>(fapi2::buffer<uint8_t>
+ const auto l_ccs_value = mss::ccs::convert_odt_attr_to_ccs(fapi2::buffer<uint8_t>
(l_rd_odt[l_dimm_rank]));
- auto l_odt = mss::ccs::odt_command<fapi2::TARGET_TYPE_MCBIST>(l_ccs_value, ODT_CYCLE_LEN);
+ auto l_odt = mss::ccs::odt_command(l_ccs_value, ODT_CYCLE_LEN);
l_program.iv_instructions.push_back(l_odt);
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C
index 50574d764..d48202d17 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2019 */
+/* Contributors Listed Below - COPYRIGHT 2017,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -55,6 +55,7 @@
#include <lib/dimm/ddr4/pda.H>
#include <lib/phy/seq.H>
#include <lib/phy/read_cntrl.H>
+#include <lib/mss_attribute_accessors.H>
#ifdef LRDIMM_CAPABLE
#include <lib/phy/mss_dwl.H>
@@ -67,6 +68,19 @@
namespace mss
{
+///
+/// @brief Bad bit getter - Nimbus specialization
+/// @param[in] i_target the fapi2 target oon which training was conducted
+/// @param[out] o_array the bad bits
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+template <>
+fapi2::ReturnCode get_bad_dq_bitmap<mss::mc_type::NIMBUS>(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT])
+{
+ return mss::bad_dq_bitmap(i_target, &(o_array[0][0]));
+}
+
namespace training
{
// Below definitions are used to avoid linker errors
@@ -198,7 +212,7 @@ fapi2::ReturnCode wr_lvl::pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE
const uint64_t i_rp,
const uint8_t i_abort_on_error ) const
{
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> > l_rtt_inst;
+ std::vector< ccs::instruction_t > l_rtt_inst;
FAPI_DBG("%s Running Pre-WR_LEVEL workaround steps on RP%d", mss::c_str(i_target), i_rp);
// Setup WR_LEVEL specific terminations
@@ -208,7 +222,7 @@ fapi2::ReturnCode wr_lvl::pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE
if (!l_rtt_inst.empty())
{
const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- mss::ccs::program<fapi2::TARGET_TYPE_MCBIST, fapi2::TARGET_TYPE_MCA> l_program;
+ ccs::program l_program;
l_program.iv_instructions.insert(l_program.iv_instructions.end(), l_rtt_inst.begin(), l_rtt_inst.end() );
FAPI_TRY( mss::ccs::execute(l_mcbist, l_program, i_target) );
l_program.iv_instructions.clear();
@@ -261,7 +275,7 @@ fapi2::ReturnCode wr_lvl::post_workaround( const fapi2::Target<fapi2::TARGET_TYP
const uint64_t i_rp,
const uint8_t i_abort_on_error ) const
{
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> > l_rtt_inst;
+ std::vector< ccs::instruction_t > l_rtt_inst;
FAPI_DBG("%s Running Post-WR_LEVEL workaround steps on RP%d", mss::c_str(i_target), i_rp);
@@ -270,7 +284,7 @@ fapi2::ReturnCode wr_lvl::post_workaround( const fapi2::Target<fapi2::TARGET_TYP
if (!l_rtt_inst.empty())
{
const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- mss::ccs::program<fapi2::TARGET_TYPE_MCBIST, fapi2::TARGET_TYPE_MCA> l_program;
+ ccs::program l_program;
l_program.iv_instructions.insert(l_program.iv_instructions.end(),
l_rtt_inst.begin(),
l_rtt_inst.end() );
@@ -660,14 +674,14 @@ fapi2::ReturnCode write_ctr::post_workaround( const fapi2::Target<fapi2::TARGET_
// If the rank vector is empty log an error
FAPI_ASSERT(!l_ranks.empty(),
fapi2::MSS_INVALID_RANK().
- set_MCA_TARGET(i_target).
+ set_PORT_TARGET(i_target).
set_RANK(i_rp).
set_FUNCTION(mss::ffdc_function_codes::WR_VREF_TRAINING_WORKAROUND),
"%s rank pair is empty! %lu", mss::c_str(i_target), i_rp);
FAPI_ASSERT(l_ranks[0] != NO_RANK,
fapi2::MSS_INVALID_RANK().
- set_MCA_TARGET(i_target).
+ set_PORT_TARGET(i_target).
set_RANK(NO_RANK).
set_FUNCTION(mss::ffdc_function_codes::WR_VREF_TRAINING_WORKAROUND),
"%s rank pair has no ranks %lu", mss::c_str(i_target), i_rp);
@@ -767,7 +781,7 @@ fapi2::ReturnCode write_ctr::post_workaround( const fapi2::Target<fapi2::TARGET_
// As such, let's run the nvdimm with rank median vref value so later on we can just load
// the vref in 1 ccs sequence.
if ((l_hybrid[0] == fapi2::ENUM_ATTR_EFF_HYBRID_IS_HYBRID) &&
- (l_hybrid_type[0] == fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NVDIMM) && !iv_wr_vref)
+ (l_hybrid_type[0] == fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NVDIMM) && iv_wr_vref)
{
FAPI_TRY(mss::workarounds::wr_vref::nvdimm_workaround(i_target, i_rp, i_abort_on_error));
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/accessor_wrapper.H b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/accessor_wrapper.H
index a9cebab3a..fd0991a7a 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/accessor_wrapper.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/accessor_wrapper.H
@@ -22,3 +22,260 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file accessor_wrapper.H
+/// @brief The wrapper of new accessor API(get_/set_) to old accessor API
+///
+
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_ACCESSOR_WRAPPER_
+#define _MSS_ACCESSOR_WRAPPER_
+
+#include <fapi2.H>
+#include <lib/shared/mss_const.H>
+#include <lib/mss_attribute_accessors.H>
+
+
+namespace mss
+{
+namespace attr
+{
+///
+/// @brief ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT getter
+/// @param[in] const ref to the TARGET_TYPE_MCA
+/// @param[out] uint16_t& reference to store the value
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Runtime throttle numerator setting for cfg_nm_n_per_slot
+///
+inline fapi2::ReturnCode get_runtime_mem_throttled_n_commands_per_slot(const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
+ i_target, uint16_t& o_value)
+{
+ return mss::runtime_mem_throttled_n_commands_per_slot(i_target, o_value);
+}
+
+///
+/// @brief ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT setter
+/// @param[in] const ref to the TARGET_TYPE_MCA
+/// @param[in] uint16_t the value to set
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK
+/// @note Runtime throttle numerator setting for cfg_nm_n_per_slot
+///
+inline fapi2::ReturnCode set_runtime_mem_throttled_n_commands_per_slot(const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
+ i_target, uint16_t i_value)
+{
+ uint16_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
+ i_target.getParent<fapi2::TARGET_TYPE_MCS>(), l_value) );
+ l_value[mss::index(i_target)] = i_value;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
+ i_target.getParent<fapi2::TARGET_TYPE_MCS>(), l_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed setting ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT getter
+/// @param[in] const ref to the TARGET_TYPE_MCA
+/// @param[out] uint16_t& reference to store the value
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Runtime throttled N commands per M DRAM clocks setting for cfg_nm_n_per_port.
+///
+inline fapi2::ReturnCode get_runtime_mem_throttled_n_commands_per_port(const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
+ i_target, uint16_t& o_value)
+{
+ return mss::runtime_mem_throttled_n_commands_per_port(i_target, o_value);
+}
+
+///
+/// @brief ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT setter
+/// @param[in] const ref to the TARGET_TYPE_MCA
+/// @param[in] uint16_t the value to set
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK
+/// @note Runtime throttled N commands per M DRAM clocks setting for cfg_nm_n_per_port.
+///
+inline fapi2::ReturnCode set_runtime_mem_throttled_n_commands_per_port(const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
+ i_target, uint16_t i_value)
+{
+ uint16_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT,
+ i_target.getParent<fapi2::TARGET_TYPE_MCS>(), l_value) );
+ l_value[mss::index(i_target)] = i_value;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT,
+ i_target.getParent<fapi2::TARGET_TYPE_MCS>(), l_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed setting ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT getter
+/// @param[in] const ref to the TARGET_TYPE_MCA
+/// @param[out] uint16_t& reference to store the value
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note This is the throttle numerator setting for cfg_nm_n_per_slot
+///
+inline fapi2::ReturnCode get_mem_throttled_n_commands_per_slot(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ uint16_t& o_value)
+{
+ return mss::mem_throttled_n_commands_per_slot(i_target, o_value);
+}
+
+///
+/// @brief ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT setter
+/// @param[in] const ref to the TARGET_TYPE_MCA
+/// @param[in] uint16_t the value to set
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK
+/// @note This is the throttled N commands per window of M DRAM clocks setting for cfg_nm_n_per_port.
+///
+inline fapi2::ReturnCode set_mem_throttled_n_commands_per_port(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ uint16_t i_value)
+{
+ uint16_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, i_target.getParent<fapi2::TARGET_TYPE_MCS>(),
+ l_value) );
+ l_value[mss::index(i_target)] = i_value;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, i_target.getParent<fapi2::TARGET_TYPE_MCS>(),
+ l_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed setting ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT getter
+/// @param[in] const ref to the TARGET_TYPE_MCA
+/// @param[out] uint16_t& reference to store the value
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note This is the throttled N commands per window of M DRAM clocks setting for cfg_nm_n_per_port.
+///
+inline fapi2::ReturnCode get_mem_throttled_n_commands_per_port(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ uint16_t& o_value)
+{
+ return mss::mem_throttled_n_commands_per_port(i_target, o_value);
+}
+
+///
+/// @brief ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT setter
+/// @param[in] const ref to the TARGET_TYPE_MCA
+/// @param[in] uint16_t the value to set
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK
+/// @note This is the throttle numerator setting for cfg_nm_n_per_slot
+///
+inline fapi2::ReturnCode set_mem_throttled_n_commands_per_slot(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ uint16_t i_value)
+{
+ uint16_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, i_target.getParent<fapi2::TARGET_TYPE_MCS>(),
+ l_value) );
+ l_value[mss::index(i_target)] = i_value;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, i_target.getParent<fapi2::TARGET_TYPE_MCS>(),
+ l_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed setting ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_PORT_MAXPOWER setter
+/// @param[in] const ref to the TARGET_TYPE_MCA
+/// @param[in] uint32_t the value to set
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK
+/// @note Channel Pair Max Power output from thermal procedures
+///
+inline fapi2::ReturnCode set_port_maxpower(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, uint32_t i_value)
+{
+ uint32_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_PORT_MAXPOWER, i_target.getParent<fapi2::TARGET_TYPE_MCS>(), l_value) );
+ l_value[mss::index(i_target)] = i_value;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_PORT_MAXPOWER, i_target.getParent<fapi2::TARGET_TYPE_MCS>(), l_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed setting ATTR_MSS_PORT_MAXPOWER: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief ATTR_MSS_DIMM_THERMAL_LIMIT getter
+/// @param[in] const ref to the TARGET_TYPE_MCA
+/// @param[out] uint32_t&[] array reference to store the value
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note DIMM Max Power based on a thermal limit Decoded from ATTR_MSS_MRW_THERMAL_POWER_LIMIT
+///
+inline fapi2::ReturnCode get_dimm_thermal_limit(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ uint32_t (&o_array)[2])
+{
+ return mss::dimm_thermal_limit(i_target, o_array);
+}
+
+///
+/// @brief ATTR_MSS_TOTAL_PWR_INTERCEPT getter
+/// @param[in] const ref to the TARGET_TYPE_MCA
+/// @param[out] uint16_t&[] array reference to store the value
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note VDDR+VPP Power intercept value for dimm creator: mss_eff_config consumer: mss_bulk_pwr_throttles
+///
+inline fapi2::ReturnCode get_total_pwr_intercept(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ uint16_t (&o_array)[2])
+{
+ return total_pwr_intercept(i_target, o_array);
+}
+
+///
+/// @brief ATTR_MSS_TOTAL_PWR_SLOPE getter
+/// @param[in] const ref to the TARGET_TYPE_MCA
+/// @param[out] uint16_t&[] array reference to store the value
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note VDDR+VPP Power slope value for dimm creator: mss_eff_config consumer: mss_bulk_pwr_throttles
+///
+inline fapi2::ReturnCode get_total_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ uint16_t (&o_array)[2])
+{
+ return mss::total_pwr_slope(i_target, o_array);
+}
+
+///
+/// @brief ATTR_MSS_MEM_WATT_TARGET getter
+/// @param[in] const ref to the TARGET_TYPE_MCA
+/// @param[out] uint32_t&[] array reference to store the value
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Total memory power used to throttle for each dimm Used to compute the throttles
+/// on the channel and/or dimms for OCC OCC sets after IPL creator: mss_eff_config consumer:
+/// mss_bulk_pwr_throttle, mss_utils_to_throttle firmware notes: none.
+///
+inline fapi2::ReturnCode get_mem_watt_target(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint32_t& o_value)
+{
+ return mss::mem_watt_target(i_target, o_value);
+}
+
+}// namespace attr
+}// namespace mss
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C
index b381042a2..8855a30f7 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -32,6 +32,7 @@
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
+#include <lib/shared/nimbus_defaults.H>
// fapi2
#include <fapi2.H>
#include <vector>
@@ -41,103 +42,24 @@
#include <mss.H>
#include <lib/power_thermal/throttle.H>
#include <lib/power_thermal/decoder.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <generic/memory/lib/utils/c_str.H>
#include <generic/memory/lib/utils/count_dimm.H>
-#include <lib/dimm/kind.H>
-#include <lib/shared/mss_const.H>
+#include <generic/memory/lib/utils/power_thermal/gen_decoder.H>
+#include <lib/dimm/nimbus_kind.H>
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_MCS;
-using fapi2::TARGET_TYPE_DIMM;
-using fapi2::TARGET_TYPE_MCBIST;
namespace mss
{
namespace power_thermal
{
-///
-/// @brief generates the 32 bit encoding for the power curve attributes
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
-/// @note populates iv_gen_keys
-///
-fapi2::ReturnCode decoder::generate_encoding()
+const std::vector< std::pair<uint8_t , uint8_t> > throttle_traits<mss::mc_type::NIMBUS>::DIMM_TYPE_MAP =
{
- //DIMM_SIZE
- FAPI_TRY(( encode<DIMM_SIZE_START, DIMM_SIZE_LEN>
- (iv_kind.iv_target, iv_kind.iv_size, DIMM_SIZE_MAP, iv_gen_key)),
- "Failed to generate power thermal encoding for %s val %d on target: %s",
- "DIMM_SIZE", iv_kind.iv_size, c_str(iv_kind.iv_target) );
-
- //DRAM_GEN
- FAPI_TRY(( encode<DRAM_GEN_START, DRAM_GEN_LEN>
- (iv_kind.iv_target, iv_kind.iv_dram_generation, DRAM_GEN_MAP, iv_gen_key)),
- "Failed to generate power thermal encoding for %s val %d on target: %s",
- "DRAM_GEN", iv_kind.iv_dram_generation, c_str(iv_kind.iv_target) );
-
- //DIMM_TYPE
- FAPI_TRY(( encode<DIMM_TYPE_START, DIMM_TYPE_LEN>
- (iv_kind.iv_target, iv_kind.iv_dimm_type, DIMM_TYPE_MAP, iv_gen_key)),
- "Failed to generate power thermal encoding for %s val %d on target: %s",
- "DIMM_TYPE", iv_kind.iv_dimm_type, c_str(iv_kind.iv_target) );
-
- //DRAM WIDTH
- FAPI_TRY(( encode<DRAM_WIDTH_START, DRAM_WIDTH_LEN>
- (iv_kind.iv_target, iv_kind.iv_dram_width, DRAM_WIDTH_MAP, iv_gen_key)),
- "Failed to generate power thermal encoding for %s val %d on target: %s",
- "DRAM_WIDTH", iv_kind.iv_dram_width, c_str(iv_kind.iv_target) );
-
- //DRAM DENSITY
- FAPI_TRY(( encode<DRAM_DENSITY_START, DRAM_DENSITY_LEN>
- (iv_kind.iv_target, iv_kind.iv_dram_density, DRAM_DENSITY_MAP, iv_gen_key)),
- "Failed to generate power thermal encoding for %s val %d on target: %s",
- "DRAM_DENSITY", iv_kind.iv_dram_density, c_str(iv_kind.iv_target) );
-
- //DRAM STACK TYPE
- FAPI_TRY(( encode<DRAM_STACK_TYPE_START, DRAM_STACK_TYPE_LEN>
- (iv_kind.iv_target, iv_kind.iv_stack_type, DRAM_STACK_TYPE_MAP, iv_gen_key)),
- "Failed to generate power thermal encoding for %s val %d on target: %s",
- "DRAM_STACK_TYPE", iv_kind.iv_stack_type, c_str(iv_kind.iv_target) );
-
- //DRAM MFG ID
- FAPI_TRY(( encode<DRAM_MFGID_START, DRAM_MFGID_LEN>
- (iv_kind.iv_target, iv_kind.iv_mfgid, DRAM_MFGID_MAP, iv_gen_key)),
- "Failed to generate power thermal encoding for %s val %d on target: %s",
- "DRAM_MFG_ID", iv_kind.iv_mfgid, c_str(iv_kind.iv_target) );
-
- //NUM DROPS PER PORT
- FAPI_TRY(( encode<DIMMS_PER_PORT_START, DIMMS_PER_PORT_LEN>
- (iv_kind.iv_target, iv_dimms_per_port, DIMMS_PORT_MAP, iv_gen_key)),
- "Failed to generate power thermal encoding for %s val %d on target: %s",
- "DIMMS_PER_PORT", iv_dimms_per_port, c_str(iv_kind.iv_target) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-///
-///@brief a compare functor for the decoder::find_attr functions below
-///@note AND's the input hash with the generated hash from the DIMM to see if they match
-///@note Using an AND instead of == because not all DIMM configs have power slopes, so defaults are needed
-///
-struct is_match
-{
- ///
- ///@brief functor constructor
- ///@param[in] i_gen_key the class object's constructed hash for the installed dimm, to be compared with the attr array
- ///
- is_match(const uint32_t i_gen_key) : iv_gen_key(i_gen_key) {}
- const fapi2::buffer<uint32_t> iv_gen_key;
-
- ///
- ///@brief Boolean compare used for find_if function
- ///
- bool operator()(const uint64_t i_hash)
- {
- // l_this_hash is the first half of the i_hash's bits
- uint32_t l_this_hash = i_hash >> 32;
- return ((l_this_hash & iv_gen_key) == iv_gen_key);
- }
+ {fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_RDIMM, 0b00},
+ {fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_UDIMM, 0b01},
+ {fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_LRDIMM, 0b10},
+ {ANY_TYPE, 0b11}
};
///
@@ -146,16 +68,21 @@ struct is_match
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
/// @note populates iv_vddr_slope, iv_total_slop
///
-fapi2::ReturnCode decoder::find_slope (const std::vector<uint64_t>& i_slope)
+template<>
+fapi2::ReturnCode decoder<mss::mc_type::NIMBUS>::find_slope (
+ const std::vector< const std::vector<uint64_t>* >& i_slope)
{
+ using TT = throttle_traits<mss::mc_type::NIMBUS>;
+
+ // For nimbus only one attribute is used to get slope (i_slope[0])
// Find iterator to matching key (if it exists)
- const auto l_value_iterator = std::find_if(i_slope.begin(),
- i_slope.end(),
- is_match(iv_gen_key));
+ const auto l_value_iterator = std::find_if((*i_slope[0]).begin(),
+ (*i_slope[0]).end(),
+ is_match<>(iv_gen_key));
//Should have matched with the default ATTR value at least
//The last value should always be the default value
- FAPI_ASSERT(l_value_iterator != i_slope.end(),
+ FAPI_ASSERT(l_value_iterator != (*i_slope[0]).end(),
fapi2::MSS_NO_POWER_THERMAL_ATTR_FOUND()
.set_GENERATED_KEY(iv_gen_key)
.set_FUNCTION(SLOPE)
@@ -184,8 +111,8 @@ fapi2::ReturnCode decoder::find_slope (const std::vector<uint64_t>& i_slope)
{
const fapi2::buffer<uint64_t> l_temp(*l_value_iterator);
- l_temp.extractToRight<VDDR_START, VDDR_LENGTH>( iv_vddr_slope);
- l_temp.extractToRight<TOTAL_START, TOTAL_LENGTH>(iv_total_slope);
+ l_temp.extractToRight<TT::VDDR_START, TT::VDDR_LENGTH>( iv_vddr_slope);
+ l_temp.extractToRight<TT::TOTAL_START, TT::TOTAL_LENGTH>(iv_total_slope);
}
fapi_try_exit:
return fapi2::current_err;
@@ -197,15 +124,19 @@ fapi_try_exit:
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
/// @note populates iv_vddr_intercept, iv_total_intercept
///
-fapi2::ReturnCode decoder::find_intercept (const std::vector<uint64_t>& i_intercept)
+template<>
+fapi2::ReturnCode decoder<mss::mc_type::NIMBUS>::find_intercept (
+ const std::vector< const std::vector<uint64_t>* >& i_intercept)
{
+ using TT = throttle_traits<mss::mc_type::NIMBUS>;
+
// Find iterator to matching key (if it exists)
- const auto l_value_iterator = std::find_if(i_intercept.begin(),
- i_intercept.end(),
- is_match(iv_gen_key));
+ const auto l_value_iterator = std::find_if((*i_intercept[0]).begin(),
+ (*i_intercept[0]).end(),
+ is_match<>(iv_gen_key));
//Should have matched with the all default ATTR at least
//The last value should always be the default value
- FAPI_ASSERT(l_value_iterator != i_intercept.end(),
+ FAPI_ASSERT(l_value_iterator != (*i_intercept[0]).end(),
fapi2::MSS_NO_POWER_THERMAL_ATTR_FOUND()
.set_GENERATED_KEY(iv_gen_key)
.set_FUNCTION(INTERCEPT)
@@ -234,31 +165,36 @@ fapi2::ReturnCode decoder::find_intercept (const std::vector<uint64_t>& i_interc
{
const fapi2::buffer<uint64_t> l_temp(*l_value_iterator);
- l_temp.extractToRight<VDDR_START, VDDR_LENGTH>( iv_vddr_intercept);
- l_temp.extractToRight<TOTAL_START, TOTAL_LENGTH>(iv_total_intercept);
+ l_temp.extractToRight<TT::VDDR_START, TT::VDDR_LENGTH>( iv_vddr_intercept);
+ l_temp.extractToRight<TT::TOTAL_START, TT::TOTAL_LENGTH>(iv_total_intercept);
}
fapi_try_exit:
return fapi2::current_err;
}
+
///
/// @brief Finds a value from ATTR_MSS_MRW_THERMAL_MEMORY_POWER_LIMIT and stores in iv variable
/// @param[in] i_thermal_limits is a vector of the generated values from ATTR_MSS_MRW_THERMAL_POWER_LIMIT
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
-/// @note populates thermal_power_limit
+/// @note populates thermal_power_limit.
///
-fapi2::ReturnCode decoder::find_thermal_power_limit (const std::vector<uint64_t>& i_thermal_limits)
+template<>
+fapi2::ReturnCode decoder<mss::mc_type::NIMBUS>::find_thermal_power_limit (
+ const std::vector< const std::vector<uint64_t>* >& i_thermal_limits)
{
+ using TT = throttle_traits<mss::mc_type::NIMBUS>;
+
// Find iterator to matching key (if it exists)
- const auto l_value_iterator = std::find_if(i_thermal_limits.begin(),
- i_thermal_limits.end(),
- is_match(iv_gen_key));
+ const auto l_value_iterator = std::find_if((*i_thermal_limits[0]).begin(),
+ (*i_thermal_limits[0]).end(),
+ is_match<>(iv_gen_key));
fapi2::buffer<uint64_t> l_temp;
//Should have matched with the all default ATTR at least
//The last value should always be the default value
- FAPI_ASSERT(l_value_iterator != i_thermal_limits.end(),
+ FAPI_ASSERT(l_value_iterator != (*i_thermal_limits[0]).end(),
fapi2::MSS_NO_POWER_THERMAL_ATTR_FOUND()
.set_GENERATED_KEY(iv_gen_key)
.set_FUNCTION(POWER_LIMIT)
@@ -287,11 +223,13 @@ fapi2::ReturnCode decoder::find_thermal_power_limit (const std::vector<uint64_t>
{
const fapi2::buffer<uint64_t> l_temp(*l_value_iterator);
- l_temp.extractToRight<THERMAL_POWER_START, THERMAL_POWER_LENGTH>( iv_thermal_power_limit);
+ l_temp.extractToRight<TT::THERMAL_POWER_START, TT::THERMAL_POWER_LENGTH>( iv_thermal_power_limit);
}
fapi_try_exit:
return fapi2::current_err;
}
+
+
///
/// @brief find the power curve attributes for each dimm on an MCS target
/// @param[in] i_targets vector of MCS targets on which dimm attrs will be set
@@ -317,13 +255,15 @@ fapi2::ReturnCode get_power_attrs (const fapi2::Target<fapi2::TARGET_TYPE_MCS>&
uint16_t o_total_int [PORTS_PER_MCS][MAX_DIMM_PER_PORT],
uint32_t o_thermal_power [PORTS_PER_MCS][MAX_DIMM_PER_PORT])
{
+ using TT = throttle_traits<mss::mc_type::NIMBUS>;
+
for (const auto& l_dimm : find_targets <fapi2::TARGET_TYPE_DIMM> (i_mcs))
{
- const auto l_mca_pos = mss::index (find_target<TARGET_TYPE_MCA>(l_dimm));
+ const auto l_mca_pos = mss::index (find_target<fapi2::TARGET_TYPE_MCA>(l_dimm));
const auto l_dimm_pos = mss::index (l_dimm);
- mss::dimm::kind l_kind (l_dimm);
- mss::power_thermal::decoder l_decoder(l_kind);
+ mss::dimm::kind<> l_kind (l_dimm);
+ mss::power_thermal::decoder<> l_decoder(l_kind);
FAPI_TRY( l_decoder.generate_encoding(), "%s Error in get_power_attrs", mss::c_str(i_mcs) );
// The first entry into these arrays must be valid
@@ -331,12 +271,13 @@ fapi2::ReturnCode get_power_attrs (const fapi2::Target<fapi2::TARGET_TYPE_MCS>&
if (i_slope.empty() || i_slope[0] == 0)
{
FAPI_INF("%s ATTR_MSS_MRW_PWR_SLOPE not found!!", mss::c_str(i_mcs));
- o_vddr_slope [l_mca_pos][l_dimm_pos] = default_power::VDDR_SLOPE;
- o_total_slope [l_mca_pos][l_dimm_pos] = default_power::TOTAL_SLOPE;
+ o_vddr_slope [l_mca_pos][l_dimm_pos] = TT::VDDR_SLOPE;
+ o_total_slope [l_mca_pos][l_dimm_pos] = TT::TOTAL_SLOPE;
}
else
{
- FAPI_TRY( l_decoder.find_slope(i_slope), "%s Error in get_power_attrs", mss::c_str(i_mcs) );
+ const std::vector< const std::vector<uint64_t>* > l_slope {&i_slope};
+ FAPI_TRY( l_decoder.find_slope(l_slope), "%s Error in get_power_attrs", mss::c_str(i_mcs) );
o_vddr_slope [l_mca_pos][l_dimm_pos] = l_decoder.iv_vddr_slope;
o_total_slope [l_mca_pos][l_dimm_pos] = l_decoder.iv_total_slope;
}
@@ -344,12 +285,13 @@ fapi2::ReturnCode get_power_attrs (const fapi2::Target<fapi2::TARGET_TYPE_MCS>&
if (i_intercept.empty() || i_intercept[0] == 0)
{
FAPI_INF("%s ATTR_MSS_MRW_PWR_INTERCEPT not found!!", mss::c_str(i_mcs));
- o_total_int [l_mca_pos][l_dimm_pos] = default_power::TOTAL_INT;
- o_vddr_int [l_mca_pos][l_dimm_pos] = default_power::VDDR_INT;
+ o_total_int [l_mca_pos][l_dimm_pos] = TT::TOTAL_INT;
+ o_vddr_int [l_mca_pos][l_dimm_pos] = TT::VDDR_INT;
}
else
{
- FAPI_TRY( l_decoder.find_intercept(i_intercept), "%s Error in get_power_attrs", mss::c_str(i_mcs) );
+ std::vector< const std::vector<uint64_t>* > l_intercept {&i_intercept};
+ FAPI_TRY( l_decoder.find_intercept(l_intercept), "%s Error in get_power_attrs", mss::c_str(i_mcs) );
o_vddr_int [l_mca_pos][l_dimm_pos] = l_decoder.iv_vddr_intercept;
o_total_int [l_mca_pos][l_dimm_pos] = l_decoder.iv_total_intercept;
}
@@ -357,11 +299,12 @@ fapi2::ReturnCode get_power_attrs (const fapi2::Target<fapi2::TARGET_TYPE_MCS>&
if (i_thermal_power_limit.empty() || i_thermal_power_limit[0] == 0)
{
FAPI_INF("%s ATTR_MSS_MRW_THERMAL_MEMORY_POWER_LIMIT not found!!", mss::c_str(i_mcs));
- o_thermal_power [l_mca_pos][l_dimm_pos] = default_power::THERMAL_LIMIT;
+ o_thermal_power [l_mca_pos][l_dimm_pos] = TT::THERMAL_LIMIT;
}
else
{
- FAPI_TRY( l_decoder.find_thermal_power_limit(i_thermal_power_limit),
+ std::vector< const std::vector<uint64_t>* > l_thermal_power_limit {&i_thermal_power_limit};
+ FAPI_TRY( l_decoder.find_thermal_power_limit(l_thermal_power_limit),
"%s Error in get_power_attrs", mss::c_str(i_mcs) );
o_thermal_power [l_mca_pos][l_dimm_pos] = l_decoder.iv_thermal_power_limit;
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H
index ac1efcdbe..f6f9bf5ea 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H
@@ -36,222 +36,17 @@
#define _MSS_POWER_DECODER__
#include <fapi2.H>
-#include <lib/dimm/kind.H>
+#include <lib/shared/mss_const.H>
+#include <lib/dimm/nimbus_kind.H>
#include <generic/memory/lib/utils/count_dimm.H>
+#include <generic/memory/lib/utils/power_thermal/gen_decoder.H>
+
namespace mss
{
namespace power_thermal
{
-enum size_of_attrs : size_t
-{
- SIZE_OF_POWER_CURVES_ATTRS = 100,
- SIZE_OF_THERMAL_ATTR = 10,
-};
-
-enum default_power
-{
- //Values are the worst case defaults for power curves
- //They are the default/ catch-all values from the power curve attributes
- //Shouldn't be used if system is set up correctly and attributes are available
- //This will throttle the DIMMs to ~76% dram data bus utilization
- //(using the mrw regulator power limit of 1700 cW and thermal power limit here of 1940 cW).
- VDDR_SLOPE = 0x41A,
- VDDR_INT = 0x384,
- TOTAL_SLOPE = 0x44C,
- TOTAL_INT = 0x44C,
- THERMAL_LIMIT = 0x794,
-};
-
-//Currently needs to be in sorted order for lookup to work
-static const std::vector< std::pair<uint32_t , uint8_t> > DIMM_SIZE_MAP =
-{
- {4, 0b0000},
- {8, 0b0001},
- {16, 0b0010},
- {32, 0b0011},
- {64, 0b0100},
- {128, 0b0101},
- {256, 0b0110},
- {512, 0b0111},
-};
-
-static const std::vector< std::pair<uint8_t , uint8_t> > DIMM_TYPE_MAP =
-{
- {fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM, 0b00},
- {fapi2::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM, 0b01},
- {fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM, 0b10},
-};
-
-static const std::vector< std::pair<uint8_t , uint8_t> > DRAM_GEN_MAP =
-{
- {fapi2::ENUM_ATTR_EFF_DRAM_GEN_EMPTY, 0b00},
- {fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR3, 0b01},
- {fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4, 0b10}
-};
-
-static const std::vector <std::pair<uint8_t, uint8_t> > DRAM_WIDTH_MAP =
-{
- {fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4, 0b000},
- {fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8, 0b001},
- {fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X16, 0b010},
- {fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X32, 0b011}
-};
-
-static const std::vector< std::pair<uint8_t , uint8_t> > DRAM_DENSITY_MAP =
-{
- {4, 0b000},
- {8, 0b001},
- {16, 0b010},
- {32, 0b011},
- {64, 0b100},
-};
-
-static const std::vector <std::pair<uint8_t, uint8_t> > DRAM_STACK_TYPE_MAP =
-{
- {fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_SDP, 0b00},
- {fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_DDP_QDP, 0b01},
- {fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_3DS, 0b10}
-};
-
-//Note, the first entries of the pairs need to be in sorted order!!
-static const std::vector <std::pair<uint16_t, uint8_t> > DRAM_MFGID_MAP =
-{
- //Kingston
- {0x0198, 0b011},
- //A-data
- {0x04CB, 0b101},
- //Micron
- {0x802C, 0b000},
- //HYNIX
- {0x80AD, 0b001},
- //SAMSUNG
- {0x80CE, 0b010},
- //Innodisk
- {0x86F1, 0b100},
-};
-
-static const std::vector < std::pair< uint8_t, uint8_t> > DIMMS_PORT_MAP =
-{
- //Num dimms per MCA, only 1 or 2 possible options. 0 is no-op
- {1, 0b00},
- {2, 0b01}
-};
-
-//Bit positions for different section of the attribute
-//first 32 bits are the encoding, second are for values
-enum DECODE_BUFFER_POS
-{
- ENCODING_START = 0,
- ENCODING_LENGTH = 32,
- VDDR_START = 32,
- VDDR_LENGTH = 16,
- TOTAL_START = 48,
- TOTAL_LENGTH = 16,
- THERMAL_POWER_START = 32,
- THERMAL_POWER_LENGTH = 32,
-};
-
-//Positions and lengths of the encodings
-enum ATTR_DECODE_INFO
-{
- DIMM_SIZE_START = 0,
- DIMM_SIZE_LEN = 4,
-
- DRAM_GEN_START = 4,
- DRAM_GEN_LEN = 2,
-
- DIMM_TYPE_START = 6,
- DIMM_TYPE_LEN = 2,
-
- DRAM_WIDTH_START = 8,
- DRAM_WIDTH_LEN = 3,
-
- DRAM_DENSITY_START = 11,
- DRAM_DENSITY_LEN = 3,
-
- DRAM_STACK_TYPE_START = 14,
- DRAM_STACK_TYPE_LEN = 2,
-
- DRAM_MFGID_START = 16,
- DRAM_MFGID_LEN = 3,
-
- DIMMS_PER_PORT_START = 19,
- DIMMS_PER_PORT_LEN = 2,
-};
-
-///
-/// @class decoder
-/// @brief Decodes the power curve and thermal power limit attributes for eff_config_thermal
-///
-class decoder
-{
- public:
-
- //IVs for all of the attributes per MCS
- const mss::dimm::kind iv_kind;
-
- //Left in here rather than calculating during encode for testing
- uint8_t iv_dimms_per_port;
-
- //Power thermal attributes, both total and vddr versions will be used in eff_config_thermal
- uint16_t iv_vddr_slope;
- uint16_t iv_vddr_intercept;
- uint16_t iv_total_slope;
- uint16_t iv_total_intercept;
-
- uint32_t iv_thermal_power_limit;
- //Generated key, used to decode all three power curve attributes
- fapi2::buffer<uint32_t> iv_gen_key;
-
- ///
- /// @brief Constructor
- /// @param[in] dimm::kind to call power thermal stuff on
- ///
- decoder( mss::dimm::kind& i_kind):
- iv_kind(i_kind)
- {
- iv_dimms_per_port = mss::count_dimm (find_target<fapi2::TARGET_TYPE_MCA>(iv_kind.iv_target));
- };
-
- //
- // @brief Default destructor
- //
- ~decoder() = default;
-
- ///
- /// @brief generates the 32 bit encoding for the power curve attributes
- /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
- /// @note populates iv_gen_key
- ///
- fapi2::ReturnCode generate_encoding ();
-
- ///
- /// @brief Finds a value for the power curve slope attributes by matching the generated hashes
- /// @param[in] i_array is a vector of the attribute values
- /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
- /// @note populates iv_vddr_slope, iv_total_slope
- ///
- fapi2::ReturnCode find_slope (const std::vector<uint64_t>& i_slope);
-
- ///
- /// @brief Finds a value for power curve intercept attributes by matching the generated hashes
- /// @param[in] i_array is a vector of the attribute values
- /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
- /// @note populates iv_vddr_intercept, iv_total_intercept
- ///
- fapi2::ReturnCode find_intercept (const std::vector<uint64_t>& i_intercept);
-
- ///
- /// @brief Finds a value from ATTR_MSS_MRW_THERMAL_MEMORY_POWER_LIMIT and stores in iv variable
- /// @param[in] i_array is a vector of the attribute values
- /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
- /// @note populates iv_thermal_power_limit
- ///
- fapi2::ReturnCode find_thermal_power_limit (const std::vector<uint64_t>& i_thermal_limits);
-
-};
///
/// @brief find the power curve attributes for each dimm on an MCS target
@@ -277,70 +72,6 @@ fapi2::ReturnCode get_power_attrs (const fapi2::Target<fapi2::TARGET_TYPE_MCS>&
uint16_t o_total_slope [PORTS_PER_MCS][MAX_DIMM_PER_PORT],
uint16_t o_total_int [PORTS_PER_MCS][MAX_DIMM_PER_PORT],
uint32_t o_thermal_power [PORTS_PER_MCS][MAX_DIMM_PER_PORT]);
-///
-/// @brief Encode the attribute into a bit encoding
-/// @tparam[in] S *ATTR*_SIZE enum used for fapi2::buffer position
-/// @tparam[in] L *ATTR*_LEN enum used for fapi2::buffer position
-/// @tparam[in] OT fapi2::buffer of some integral type
-/// @tparam[in] T integral type of key
-/// @param[in] i_target the DIMM the encoding is for
-/// @param[in] i_attr the attribute key being used for the encoding
-/// @param[in] i_map a vector of pairs of the ATTR values and encodings for each value, sorted
-/// @param[out] o_buf the fapi2::buffer where the encoding is going into
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff attribute is found in map lookup
-///
-template<size_t S, size_t L, typename T, typename OT>
-inline fapi2::ReturnCode encode ( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const T& i_attr,
- const std::vector<std::pair<T, OT> >& i_map,
- fapi2::buffer<uint32_t>& o_buf)
-{
- //used to hold result from vector pair lookup
- OT l_encoding = 0;
-
- //Failing out if we don't find an encoding. All suported types should be encoded above
- FAPI_ASSERT( mss::find_value_from_key (i_map, i_attr, l_encoding),
- fapi2::MSS_POWER_THERMAL_ENCODE_ERROR()
- .set_ATTR(i_attr)
- .set_DIMM_TARGET(i_target),
- "Couldn't find encoding for power thermal encode for value: %x target: %s", i_attr, mss::c_str(i_target));
- o_buf.insertFromRight<S, L>(l_encoding);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decode the attribute into a bit encoding
-/// @tparam[in] S DRAM_GEN_SIZE enum used for fapi2::buffer position
-/// @tparam[in] L DRAM_GEN_LEN enum used for fapi2::buffer position
-/// @tparam[in] OT fapi2::buffer of some integral type
-/// @tparam[in] T integral type of key
-/// @param[in] i_target the DIMM the encoding is for
-/// @param[in] i_map a vector of pairs of the ATTR values and encodings for each value
-/// @param[in] i_buf the fapi2::buffer that has the encoding to parse
-/// @param[out] o_attr the attribute value from the encoding is going
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff attribute is found in map lookup
-///
-template<size_t S, size_t L, typename T, typename OT>
-inline fapi2::ReturnCode decode ( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<std::pair<T, OT> >& i_map,
- fapi2::buffer<uint32_t>& i_buf,
- T& o_attr )
-{
- //used to hold result from vector pair lookup
- OT l_encoding = 0;
- i_buf.extractToRight<S, L>(l_encoding);
-
- //Failing out if we don't find an decoding. All suported types should be encoded above
- FAPI_ASSERT( mss::find_key_from_value (i_map, l_encoding, o_attr),
- fapi2::MSS_POWER_THERMAL_DECODE_ERROR()
- .set_ATTR(l_encoding)
- .set_DIMM_TARGET(i_target),
- "Couldn't find encoding for power thermal decode for target: %s", mss::c_str(i_target));
-fapi_try_exit:
- return fapi2::current_err;
-}
} // power_thermal
} // mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C
index 82a5e2c6e..0ef22bddd 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C
@@ -31,6 +31,8 @@
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
+
+#include <lib/shared/nimbus_defaults.H>
//std lib
#include<algorithm>
// fapi2
@@ -41,687 +43,12 @@
#include <generic/memory/lib/utils/count_dimm.H>
#include <generic/memory/lib/utils/pos.H>
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_MCS;
-using fapi2::TARGET_TYPE_DIMM;
-using fapi2::TARGET_TYPE_MCBIST;
-
namespace mss
{
namespace power_thermal
{
///
-/// @brief Constructor
-/// @param[in] i_target MCS target to call power thermal stuff on
-/// @param[out] o_rc, a return code which determines the success of the constructor
-///
-throttle::throttle( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_mca, fapi2::ReturnCode& o_rc) :
- iv_target(i_mca),
- iv_databus_port_max(0),
- iv_runtime_n_slot(0),
- iv_runtime_n_port(0),
- iv_n_slot(0),
- iv_n_port(0),
- iv_port_power_limit(0),
- iv_calc_port_maxpower(0)
-{
- //holder for watt_target to add up for port
- uint32_t l_dimm_power_limits [MAX_DIMM_PER_PORT] = {};
-
- FAPI_TRY( mrw_max_dram_databus_util(iv_databus_port_max), "%s Error in throttle ctor", mss::c_str(i_mca) );
- FAPI_TRY( mrw_dimm_power_curve_percent_uplift(iv_power_uplift), "%s Error in throttle ctor", mss::c_str(i_mca) );
- FAPI_TRY( mrw_dimm_power_curve_percent_uplift_idle(iv_power_uplift_idle), "%s Error in throttle ctor",
- mss::c_str(i_mca) );
- FAPI_TRY( dimm_thermal_limit( iv_target, iv_dimm_thermal_limit), "%s Error in throttle ctor", mss::c_str(i_mca) );
- FAPI_TRY( total_pwr_intercept( iv_target, iv_pwr_int), "%s Error in throttle ctor", mss::c_str(i_mca) );
- FAPI_TRY( total_pwr_slope( iv_target, iv_pwr_slope), "%s Error in throttle ctor", mss::c_str(i_mca) );
- FAPI_TRY( runtime_mem_throttled_n_commands_per_slot(iv_target, iv_runtime_n_slot ), "%s Error in throttle ctor",
- mss::c_str(i_mca) );
- FAPI_TRY( runtime_mem_throttled_n_commands_per_port(iv_target, iv_runtime_n_port ), "%s Error in throttle ctor",
- mss::c_str(i_mca) );
- FAPI_TRY( mem_watt_target( iv_target, l_dimm_power_limits), "%s Error in throttle ctor", mss::c_str(i_mca) );
- FAPI_TRY( mrw_mem_m_dram_clocks(iv_m_clocks), "%s Error in throttle ctor", mss::c_str(i_mca) );
-
- //Port power limit = sum of dimm power limits
- for ( const auto& l_dimm : mss::find_targets<TARGET_TYPE_DIMM>(iv_target) )
- {
- iv_port_power_limit += l_dimm_power_limits[mss::index(l_dimm)];
- }
-
- FAPI_INF("Setting up throttle for target %s, Values are: max databus is %d, uplifts are %d %d, runtime throttles are %d %d",
- mss::c_str(iv_target),
- iv_databus_port_max,
- iv_power_uplift,
- iv_power_uplift_idle,
- iv_runtime_n_slot,
- iv_runtime_n_port);
-
- FAPI_INF("The dimm power limit for dimm0 is %d, dimm1 is %d, port power limit is %d, dram clocks are %d, dimm power curve slopes are %d %d,",
- l_dimm_power_limits[0],
- l_dimm_power_limits[1],
- iv_port_power_limit,
- iv_m_clocks,
- iv_pwr_slope[0],
- iv_pwr_slope[1]);
-
- FAPI_INF("DIMM power curve intercepts are %d %d, DIMM power thermal limits are %d %d",
- iv_pwr_int[0],
- iv_pwr_int[1],
- iv_dimm_thermal_limit[0],
- iv_dimm_thermal_limit[1]);
-
- FAPI_ASSERT( (iv_databus_port_max != 0),
- fapi2::MSS_NO_DATABUS_UTILIZATION()
- .set_PORT_DATABUS_UTIL(iv_databus_port_max)
- .set_DIMM_COUNT(mss::count_dimm(iv_target)),
- "Failed to get max databus utilization for target %s",
- mss::c_str(iv_target));
-
- FAPI_ASSERT( (iv_port_power_limit != 0),
- fapi2::MSS_NO_PORT_POWER_LIMIT()
- .set_COUNT_DIMMS( mss::count_dimm(iv_target))
- .set_PORT_POWER_LIMIT( iv_port_power_limit),
- "Error calculating port_power_limit on target %s with %d DIMMs installed",
- mss::c_str(iv_target),
- iv_port_power_limit);
-
- //Checking to make sure all of the attributes are valid
- for ( const auto& l_dimm : mss::find_targets<TARGET_TYPE_DIMM>(iv_target) )
- {
- const auto l_pos = mss::index(l_dimm);
- FAPI_ASSERT( (iv_pwr_int[l_pos] != 0),
- fapi2::MSS_POWER_INTERCEPT_NOT_SET(),
- "The attribute ATTR_MSS_TOTAL_PWR_INTERCEPT equals 0 for %s",
- mss::c_str(l_dimm));
-
- FAPI_ASSERT( (iv_pwr_slope[l_pos] != 0),
- fapi2::MSS_POWER_SLOPE_NOT_SET(),
- "The attribute ATTR_MSS_TOTAL_PWR_SLOPE equals 0 for %s",
- mss::c_str(l_dimm));
- }
-
-fapi_try_exit:
- o_rc = fapi2::current_err;
- return;
-}
-
-///
-/// @brief Set ATTR_MSS_CHANNEL_PAIR_MAXPOWER, ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT and _PER_PORT
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Called in p9_mss_bulk_pwr_throttles
-/// @note determines the throttle levels based off of the port's power curve,
-/// @note the _per_slot throttles are set to the _per_port values
-/// @note throttles are all equalized and set to the worst case value
-///
-fapi2::ReturnCode throttle::power_regulator_throttles ()
-{
- double l_port_power_calc_idle = 0;
- double l_port_power_calc_max = 0;
- uint32_t l_port_power_slope = 0;
- uint32_t l_port_power_int = 0;
- double l_calc_util_port = 0;
- double l_databus_dimm_max[MAX_DIMM_PER_PORT] = {};
- double l_calc_databus_port_idle[MAX_DIMM_PER_PORT] = {IDLE_UTIL, IDLE_UTIL};
-
- FAPI_INF("Starting power regulator throttles");
-
- //Decide utilization for each dimm based off of dimm count and power slopes
- FAPI_TRY( calc_databus(iv_databus_port_max, l_databus_dimm_max),
- "Failed to calculate each DIMMs' percentage of dram databus utilization for target %s, max port databus is %d",
- mss::c_str(iv_target),
- iv_databus_port_max);
-
- //Use the dimm utilizations and dimm power slopes to calculate port min and max power
- FAPI_TRY( calc_port_power(l_calc_databus_port_idle,
- l_databus_dimm_max,
- l_port_power_calc_idle,
- l_port_power_calc_max),
- "Failed to calculate the max and idle power for port %s",
- mss::c_str(iv_target));
-
- FAPI_INF("POWER throttles: %s max port power is %f", mss::c_str(iv_target), l_port_power_calc_max);
-
- //Calculate the power curve slope and intercept using the port's min and max power values
- FAPI_TRY(calc_power_curve(l_port_power_calc_idle,
- l_port_power_calc_max,
- l_port_power_slope,
- l_port_power_int),
- "Failed to calculate the power curve for port %s, calculated port power max is %d, idle is %d",
- mss::c_str(iv_target),
- l_port_power_calc_max,
- l_port_power_calc_idle);
-
- FAPI_INF("%s POWER Port power limit is %d", mss::c_str(iv_target), iv_port_power_limit);
- //Calculate the port's utilization to get under watt target using the port's calculated slopes
- calc_util_usage(l_port_power_slope,
- l_port_power_int,
- iv_port_power_limit,
- l_calc_util_port);
-
- FAPI_INF("%s POWER calc util port is %f", mss::c_str(iv_target), l_calc_util_port);
-
- //Calculate the new slot values and the max power value for the port
- FAPI_TRY( calc_slots_and_power( l_calc_util_port),
- "%s Error calculating the final throttles and power values for target with passed in port utilization %d",
- mss::c_str(iv_target),
- l_calc_util_port);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief set iv_n_port, iv_n_slot, iv_calc_port_maxpower
-/// @param[in] i_util_port pass in the calculated port databus utilization
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-///
-fapi2::ReturnCode throttle::calc_slots_and_power (const double i_util_port)
-{
- //Calculate the Port N throttles
- iv_n_port = power_thermal::throttled_cmds(i_util_port, iv_m_clocks);
-
- //Set iv_n_slot to the lower value between the slot runtime and iv_n_port
- iv_n_slot = (iv_runtime_n_slot != 0) ? std::min (iv_n_port, iv_runtime_n_slot) : iv_n_port;
-
- //Choose the lowest value of the runtime and the calculated
- iv_n_port = (iv_runtime_n_port != 0) ? std::min (iv_n_port, iv_runtime_n_port) : iv_n_port;
-
- //Use the throttle value to calculate the power that gets to exactly that value
- FAPI_TRY( calc_power_from_n(iv_n_slot, iv_n_port, iv_calc_port_maxpower));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Set ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT and PER_PORT
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Called in p9_mss_bulk_pwr_throttles
-/// @note Sets the throttle levels based off of the dimm's thermal limits
-/// @note both DIMM's on a port are set to the same throttle level
-///
-fapi2::ReturnCode throttle::thermal_throttles ()
-{
- double l_dimm_power_idle [MAX_DIMM_PER_PORT] = {};
- double l_dimm_power_max [MAX_DIMM_PER_PORT] = {};
- uint32_t l_dimm_power_slope [MAX_DIMM_PER_PORT] = {};
- uint32_t l_dimm_power_int [MAX_DIMM_PER_PORT] = {};
- double l_calc_util [MAX_DIMM_PER_PORT] = {};
- const auto l_count = count_dimm (iv_target);
-
- //Calculate the dimm power range for each dimm at max utilization for each
- calc_dimm_power(power_thermal::IDLE_UTIL,
- iv_databus_port_max,
- l_dimm_power_idle,
- l_dimm_power_max);
-
- //Let's calculate the N throttle for each DIMM
- for ( const auto& l_dimm : mss::find_targets<TARGET_TYPE_DIMM>(iv_target) )
- {
- uint16_t l_temp_n_slot = 0;
- uint8_t l_pos = mss::index(l_dimm);
- //Calculate the power curve taking the thermal limit into account
- FAPI_TRY( calc_power_curve(l_dimm_power_idle[l_pos],
- l_dimm_power_max[l_pos],
- l_dimm_power_slope[l_pos],
- l_dimm_power_int[l_pos]),
- "Failed to calculate the power curve for dimm %s, calculated dimm power curve slope is %d, intercept %d",
- mss::c_str(l_dimm),
- l_dimm_power_slope[l_pos],
- l_dimm_power_int[l_pos]);
-
- //Calculate the databus utilization at the calculated power curve
- calc_util_usage(l_dimm_power_slope[l_pos],
- l_dimm_power_int[l_pos],
- iv_dimm_thermal_limit[l_pos],
- l_calc_util[l_pos]);
-
- FAPI_INF("THERMAL throttles: %s dram databus utilization is %f", mss::c_str(l_dimm), l_calc_util[l_pos]);
-
- l_temp_n_slot = power_thermal::throttled_cmds (l_calc_util[l_pos], iv_m_clocks);
-
- //Set to the min between the two value
- //If iv_n_slot == 0 (so uninitialized), set it to the calculated slot value
- //The l_n_slot value can't be equal to 0 because there's a dimm installed
- if ((l_temp_n_slot < iv_n_slot) || (iv_n_slot == 0))
- {
- iv_n_slot = l_temp_n_slot;
- }
- }
-
- //Set to lowest value between calculated and runtime
- FAPI_INF("THERMAL throttles: runtime slot is %d, calc n slot is %d", iv_runtime_n_slot, iv_n_slot);
- //Taking the min of the SLOT * (# of dimms on the port) and the iv_runtime_port throttle value
- //Thermal throttling happens after the POWER calculations. the iv_runtime_n_port value shouldn't be set to 0
- iv_n_port = std::min(iv_runtime_n_port, static_cast<uint16_t>(iv_n_slot * l_count));
- iv_n_port = (iv_n_port == 0) ? MIN_THROTTLE : iv_n_port;
-
- iv_n_slot = std::min(iv_n_slot, iv_runtime_n_slot);
- iv_n_slot = (iv_n_slot == 0) ? MIN_THROTTLE : iv_n_slot;
-
- //Now time to get and set iv_calc_port_max from the calculated N throttle
- FAPI_TRY( calc_power_from_n(iv_n_slot, iv_n_port, iv_calc_port_maxpower),
- "Failed to calculate the final max port maxpower. Slot throttle value is %d, port value is %d",
- iv_n_slot,
- iv_n_port);
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- FAPI_ERR("Error calculating mss::power_thermal::thermal_throttles()");
- return fapi2::current_err;
-}
-
-///
-/// @brief Calculates the min and max power usage for a port based off of power curves and utilizations
-/// @param[in] i_idle_util the utilization of the databus in idle mode (0% most likely)
-/// @param[in] i_max_util the utilization of the dimm at maximum possible percentage (mrw or calculated)
-/// @param[out] o_port_power_idle max value of port power in cW
-/// @param[out] o_port_power_max max value of port power in cW
-/// @return fapi2::FAPI2_RC_SUCCESS iff the method was a success
-/// @note Called twice in p9_mss_bulk_pwr_throttles
-/// @note uses dimm power curves from class variables
-///
-fapi2::ReturnCode throttle::calc_port_power(const double i_idle_util [MAX_DIMM_PER_PORT],
- const double i_max_util [MAX_DIMM_PER_PORT],
- double& o_port_power_idle,
- double& o_port_power_max) const
-{
- //Playing it safe
- o_port_power_idle = 0;
- o_port_power_max = 0;
-
- //Calculate the port power curve info by summing the dimms on the port
- for ( const auto& l_dimm : mss::find_targets<TARGET_TYPE_DIMM>(iv_target) )
- {
- const auto l_pos = mss::index(l_dimm);
- //Printing as decimals because HB messes up floats
- FAPI_INF("%s max dram databus for DIMM in pos %d is %d, databus for idle is %d",
- mss::c_str(iv_target),
- l_pos,
- static_cast<uint64_t>( i_max_util[l_pos]),
- static_cast<uint64_t>( i_idle_util[l_pos]) );
- //Sum up the dim's power to calculate the port power curve
- o_port_power_idle += calc_power(i_idle_util[l_pos], l_pos);
- o_port_power_max += calc_power(i_max_util[l_pos], l_pos);
- }
-
- //Raise the powers by the uplift percent
- calc_power_uplift(iv_power_uplift_idle, o_port_power_idle);
- calc_power_uplift(iv_power_uplift, o_port_power_max);
-
- FAPI_ASSERT( (o_port_power_max > 0),
- fapi2::MSS_NO_PORT_POWER()
- .set_COUNT_DIMMS(mss::count_dimm(iv_target))
- .set_MAX_UTILIZATION_DIMM_0(i_max_util[0])
- .set_MAX_UTILIZATION_DIMM_1(i_max_util[1]),
- "No Port Power limit was calculated for %s, %d DIMMs installed, utilizations: DIMM 0 %d, DIMM 1 %d",
- mss::c_str(iv_target),
- mss::count_dimm(iv_target),
- i_max_util[0],
- i_max_util[1]);
-
- //FAPI_ASSERTs don't set the current err to good
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Calculates max and min power usages based off of DIMM power curves
-/// @param[in] i_databus_idle idle databus utilization (either calculated or mrw)
-/// @param[in] i_databus_max max databus utilization (either calculated or mrw)
-/// @param[out] o_dimm_power_idle array of dimm power in cW
-/// @param[out] o_dimm_power_max array of dimm power in cW
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
-/// @note Called in p9_mss_bulk_pwr_throttles
-/// @note used for the thermal throttles
-///
-void throttle::calc_dimm_power(const double i_databus_idle,
- const double i_databus_max,
- double o_dimm_power_idle [MAX_DIMM_PER_PORT],
- double o_dimm_power_max [MAX_DIMM_PER_PORT]) const
-{
- for ( const auto& l_dimm : mss::find_targets<TARGET_TYPE_DIMM>(iv_target) )
- {
- const uint8_t l_pos = mss::index(l_dimm);
- o_dimm_power_idle[l_pos] = calc_power(i_databus_idle, l_pos);
- o_dimm_power_max[l_pos] = calc_power(i_databus_max, l_pos);
-
- //Raise the powers by the uplift percent
-
- calc_power_uplift(iv_power_uplift_idle, o_dimm_power_idle[l_pos]);
- calc_power_uplift(iv_power_uplift, o_dimm_power_max[l_pos]);
-
- FAPI_INF("Calc_dimm_power: dimm (%d) power max is %f, %f for dimm slope of %d, intercept of %d",
- l_pos,
- o_dimm_power_max[l_pos],
- o_dimm_power_max[l_pos],
- iv_pwr_slope[l_pos],
- iv_pwr_int[l_pos]);
- }
-}
-
-///
-/// @brief Calculate the port power curve in order to calculate the port utilization
-/// @param[in] i_power_idle double of the port's power consumption at idle
-/// @param[in] i_power_max double of the port's power consumption at max utilization
-/// @param[out] o_slope
-/// @param[out] o_int
-/// @note Called in p9_mss_bulk_pwr_throttles
-/// @note Port power curve needed to calculate the port utilization
-///
-fapi2::ReturnCode throttle::calc_power_curve(const double i_power_idle,
- const double i_power_max,
- uint32_t& o_slope,
- uint32_t& o_int) const
-{
- const double l_divisor = ((static_cast<double>(iv_databus_port_max) / UTIL_CONVERSION) - IDLE_UTIL);
- FAPI_ASSERT ((l_divisor > 0),
- fapi2::MSS_CALC_POWER_CURVE_DIVIDE_BY_ZERO()
- .set_PORT_DATABUS_UTIL(iv_databus_port_max)
- .set_UTIL_CONVERSION(UTIL_CONVERSION)
- .set_IDLE_UTIL(IDLE_UTIL)
- .set_RESULT(l_divisor),
- "Calculated zero for the divisor in calc_power_curve on target %s",
- mss::c_str(iv_target) );
-
- o_slope = (i_power_max - i_power_idle) / l_divisor;
- o_int = i_power_idle - (o_slope * IDLE_UTIL);
- FAPI_INF("Calc_power_curve: power idle is %f, max is %f, slope is %d, int is %d",
- i_power_idle,
- i_power_max,
- o_slope,
- o_int);
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- FAPI_INF("Error calculating mss::power_thermal::calc_power_curve");
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Calculate the databus utilization given the power curve
-/// @param[in] i_slope
-/// @param[in] i_int
-/// @param[in] i_power_limit either the port_power_limit or the dimm thermal power limit
-/// @param[out] o_port_util the port's databus utilization
-/// @note Called in p9_mss_bulk_pwr_throttles
-/// @note Chooses worst case between the maximum allowed databus utilization and the calculated value
-///
-void throttle::calc_util_usage(const uint32_t i_slope,
- const uint32_t i_int,
- const uint32_t i_power_limit,
- double& o_util) const
-{
- o_util = ((static_cast<double>(i_power_limit) - i_int) / i_slope ) * UTIL_CONVERSION;
-
- //Cast to uint32 for edge case where it has decimals
- o_util = (static_cast<uint32_t>(o_util) < iv_databus_port_max) ? static_cast<uint32_t>(o_util) : iv_databus_port_max;
-
- // Check for the minimum threshnold and update if need be
- if(o_util < MIN_UTIL)
- {
- FAPI_INF("Calculated utilization (%lu) is less than the minimum utilization: %lu. Setting to minimum value", o_util,
- MIN_UTIL);
- o_util = MIN_UTIL;
- }
-}
-
-///
-/// @brief calculated the output power estimate from the calculated N throttle
-/// @param[in] i_n_slot the throttle per slot in terms of N commands
-/// @param[in] i_n_port the throttle per port in terms of N commands
-/// @param[out] o_power the calculated power
-/// @return fapi2::ReturnCode iff it was a success
-///
-fapi2::ReturnCode throttle::calc_power_from_n (const uint16_t i_n_slot,
- const uint16_t i_n_port,
- uint32_t& o_power) const
-{
- double l_calc_util_port = 0;
- double l_calc_util_slot = 0;
- double l_calc_databus_port_max[MAX_DIMM_PER_PORT] = {};
- double l_calc_databus_port_idle[MAX_DIMM_PER_PORT] = {};
- double l_port_power_max = 0;
- double l_port_power_idle = 0;
-
- FAPI_TRY( calc_util_from_throttles(i_n_slot, iv_m_clocks, l_calc_util_slot),
- "%s Error calculating utilization from slot throttle %d and mem clocks %d",
- mss::c_str(iv_target),
- i_n_slot,
- iv_m_clocks);
- FAPI_TRY( calc_util_from_throttles(i_n_port, iv_m_clocks, l_calc_util_port),
- "%s Error calculating utilization from port throttle %d and mem clocks %d",
- mss::c_str(iv_target),
- i_n_port,
- iv_m_clocks);
-
- //Determine the utilization for each DIMM that will maximize the port power
- FAPI_TRY( calc_split_util(l_calc_util_slot, l_calc_util_port, l_calc_databus_port_max),
- "Error splitting the utilization for target %s with slot utilizatio %d and port util %d",
- mss::c_str(iv_target),
- l_calc_util_slot,
- l_calc_util_port);
-
- FAPI_TRY( calc_port_power(l_calc_databus_port_idle,
- l_calc_databus_port_max,
- l_port_power_idle,
- l_port_power_max),
- "Error calculating the port power value for %s. Slot value is %d, port value is %d",
- mss::c_str(iv_target),
- i_n_slot,
- i_n_port);
-
- o_power = power_thermal::round_up (l_port_power_max);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Converts the port maximum databus to a dimm level based on powerslopes and dimms installed
-/// @param[in] i_databus_port_max max databus utilization for the port (either calculated or mrw)
-/// @param[out] o_databus_dimm_max array of dimm utilization values
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
-/// @note Called in p9_mss_bulk_pwr_throttles
-/// @used to calculate the port power based off of DIMM power curves
-///
-fapi2::ReturnCode throttle::calc_databus (const double i_databus_port_max,
- double o_databus_dimm_max [MAX_DIMM_PER_PORT])
-{
- uint8_t l_count_dimms = count_dimm(iv_target);
-
- //No work for no dimms
- if (l_count_dimms == 0)
- {
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
- for (const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(iv_target))
- {
- //Left early if count_dimms == 0
- o_databus_dimm_max[mss::index(l_dimm)] = i_databus_port_max / l_count_dimms;
- }
-
- //If the power slopes aren't equal, set the dimm with the highest power slope
- //Should be correct even if only one DIMM is installed
- if (iv_pwr_slope[0] != iv_pwr_slope[1])
- {
- o_databus_dimm_max[0] = (iv_pwr_slope[0] > iv_pwr_slope[1]) ? i_databus_port_max : 0;
- o_databus_dimm_max[1] = (iv_pwr_slope[1] > iv_pwr_slope[0]) ? i_databus_port_max : 0;
- }
-
- //Make sure both are not 0
- FAPI_ASSERT ( (o_databus_dimm_max[0] != 0) || (o_databus_dimm_max[1] != 0),
- fapi2::MSS_NO_DATABUS_UTILIZATION()
- .set_PORT_DATABUS_UTIL(i_databus_port_max)
- .set_DIMM_COUNT(l_count_dimms),
- "Failed to calculated databus utilization for target %s",
- mss::c_str(iv_target));
-
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Converts the port and slot util to a dimm level based on powerslopes and number of dimms installed
-/// @param[in] i_util_slot databus utilization for the slot
-/// @param[in] i_util_port databus utilization for the port
-/// @param[out] o_util_dimm_max array of dimm utilization values
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
-/// @note determines worst case utilization per dimms, takes into account port and combine slot throttles
-/// @note used in calculating the port power, not for calculating the slot and port utilization
-///
-fapi2::ReturnCode throttle::calc_split_util(
- const double i_util_slot,
- const double i_util_port,
- double o_util_dimm_max [MAX_DIMM_PER_PORT]) const
-{
- uint8_t l_count_dimms = count_dimm (iv_target);
- //The total utilization to be used is limited by either what the port can allow or what the dimms can use
- FAPI_ASSERT( (i_util_slot <= i_util_port),
- fapi2::MSS_SLOT_UTIL_EXCEEDS_PORT()
- .set_SLOT_UTIL(i_util_slot)
- .set_PORT_UTIL(i_util_port),
- "The slot utilization (%f) exceeds the port's utilization (%f)",
- i_util_slot,
- i_util_port);
-
- if (l_count_dimms == 0)
- {
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
- //assumptions slot <= port, l_count_dimms <=2
- else if (i_util_slot * l_count_dimms > i_util_port)
- {
- FAPI_INF("In mss::power_thermal::calc_split i_util_slot is %f, i_util_port is %f, l_count_dimms is %d",
- i_util_slot,
- i_util_port,
- l_count_dimms);
- const uint8_t l_high_pos = (iv_pwr_slope[0] >= iv_pwr_slope[1]) ? 0 : 1;
-
- //Highest power_slope gets the higher utilization
- o_util_dimm_max[l_high_pos] = std::min(i_util_slot, i_util_port);
- //Set the other dimm to the left over utilization (i_util_port - i_util_slot)
- o_util_dimm_max[(!l_high_pos)] = (l_count_dimms == 2) ? (i_util_port - o_util_dimm_max[l_high_pos]) : 0;
-
- FAPI_INF("Split utilization for target %s, DIMM in %d gets %f, DIMM in %d gets %f",
- mss::c_str(iv_target),
- l_high_pos,
- o_util_dimm_max[l_high_pos],
- !l_high_pos,
- o_util_dimm_max[!l_high_pos]);
- }
-
- else
- {
- //If only 1 dimm, i_util_port == i_util_slot
- //If 2 dimms, 2*i_util_slot <= i_util_pot
- //Either way, limit utilization by the slot value
- for (const auto& l_dimm : mss::find_targets<TARGET_TYPE_DIMM>(iv_target))
- {
- const size_t l_pos = mss::index(l_dimm);
- o_util_dimm_max[l_pos] = i_util_slot;
- }
- }
-
- //make sure both are not 0
- FAPI_ASSERT ( (o_util_dimm_max[0] != 0) || (o_util_dimm_max[1] != 0),
- fapi2::MSS_NO_DATABUS_UTILIZATION()
- .set_PORT_DATABUS_UTIL(i_util_port)
- .set_DIMM_COUNT(mss::count_dimm(iv_target)),
- "Failed to calculated util utilization for target %s",
- mss::c_str(iv_target));
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Perform thermal calculations as part of the effective configuration
-/// @param[in] i_target the MCS target in which the runtime throttles will be reset
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode restore_runtime_throttles( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target )
-{
- uint16_t l_run_throttles [MAX_DIMM_PER_PORT] = {};
- uint32_t l_max_databus = 0;
- uint32_t l_throttle_m_clocks = {};
-
- FAPI_TRY( mrw_mem_m_dram_clocks(l_throttle_m_clocks) );
- FAPI_TRY( mrw_max_dram_databus_util(l_max_databus) );
-
- //Set runtime throttles to unthrottled value, using max dram utilization and M throttle
- //Do I need to check to see if any DIMMS configured on the port?
- for (const auto& l_mca : mss::find_targets<TARGET_TYPE_MCA>(i_target))
- {
- const auto l_pos = mss::index(l_mca);
-
- if (mss::count_dimm (l_mca) != 0)
- {
- l_run_throttles[l_pos] = mss::power_thermal::throttled_cmds (l_max_databus, l_throttle_m_clocks);
- }
- }
-
- FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT, i_target, l_run_throttles) );
- FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT, i_target, l_run_throttles) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Update the runtime throttles to the worst case of the general throttle values and the runtime values
-/// @param[in] i_target the MCS target in which the runtime throttles will be set
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode update_runtime_throttles( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets )
-{
- for (const auto& l_mcs : i_targets)
- {
- if (mss::count_dimm(l_mcs) == 0)
- {
- continue;
- }
-
- uint16_t l_run_slot [PORTS_PER_MCS] = {};
- uint16_t l_run_port [PORTS_PER_MCS] = {};
- uint16_t l_calc_slot [PORTS_PER_MCS] = {};
- uint16_t l_calc_port [PORTS_PER_MCS] = {};
-
- FAPI_TRY(runtime_mem_throttled_n_commands_per_slot(l_mcs, l_run_slot));
- FAPI_TRY(runtime_mem_throttled_n_commands_per_port(l_mcs, l_run_port));
- FAPI_TRY(mem_throttled_n_commands_per_slot(l_mcs, l_calc_slot));
- FAPI_TRY(mem_throttled_n_commands_per_port(l_mcs, l_calc_port));
-
- for (const auto& l_mca : mss::find_targets<TARGET_TYPE_MCA>(l_mcs))
- {
- const auto l_pos = mss::index(l_mca);
- //Choose the worst case between runtime and calculated throttles
- //Have to make sure the calc_slot isn't equal to 0 though
- l_run_slot[l_pos] = (l_calc_slot[l_pos] != 0) ?
- std::min(l_run_slot[l_pos], l_calc_slot[l_pos]) : l_run_slot[l_pos];
- l_run_port[l_pos] = (l_calc_port[l_pos] != 0) ?
- std::min(l_run_port[l_pos], l_calc_port[l_pos]) : l_run_port[l_pos];
-
- FAPI_INF("New runtime throttles for %s for slot are %d, port are %d",
- mss::c_str(l_mca),
- l_run_slot[l_pos],
- l_run_port[l_pos]);
- }
-
- FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT, l_mcs, l_run_port) );
- FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT, l_mcs, l_run_slot) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief set ATTR_MSS_RUNTIME_MEM_M_DRAM_CLOCKS and ATTR_MSS_MEM_WATT_TARGET
/// @param[in] i_targets vector of mcs targets all on the same vddr domain
/// @return FAPI2_RC_SUCCESS iff it was a success
@@ -785,149 +112,5 @@ fapi_try_exit:
return fapi2::current_err;
}
-///
-/// @brief Equalize the throttles and estimated power at those throttle levels
-/// @param[in] i_targets vector of MCS targets all on the same VDDR domain
-/// @param[in] i_throttle_type denotes if this was done for POWER (VMEM) or THERMAL (VMEM+VPP) throttles
-/// @param[out] o_exceeded_power vector of MCA targets where the estimated power exceeded the maximum allowed
-/// @return FAPI2_RC_SUCCESS iff ok
-/// @note sets the throttles and power to the worst case
-/// Called by p9_mss_bulk_pwr_throttles and by p9_mss_utils_to_throttle (so by IPL or by OCC)
-///
-fapi2::ReturnCode equalize_throttles (const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets,
- const throttle_type i_throttle_type,
- std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCA> >& o_exceeded_power)
-{
- o_exceeded_power.clear();
-
- //Set to max values so every compare will change to min value
- uint16_t l_min_slot = ~(0);
- uint16_t l_min_port = ~(0);
-
- //Loop through all of the MCS targets to find the worst case throttle value (lowest) for the slot and port
- for (const auto& l_mcs : i_targets)
- {
- uint16_t l_calc_slot [mss::PORTS_PER_MCS] = {};
- uint16_t l_calc_port [mss::PORTS_PER_MCS] = {};
- uint16_t l_run_slot [mss::PORTS_PER_MCS] = {};
- uint16_t l_run_port [mss::PORTS_PER_MCS] = {};
-
- FAPI_TRY(mem_throttled_n_commands_per_slot(l_mcs, l_calc_slot));
- FAPI_TRY(mem_throttled_n_commands_per_port(l_mcs, l_calc_port));
- FAPI_TRY(runtime_mem_throttled_n_commands_per_slot(l_mcs, l_run_slot));
- FAPI_TRY(runtime_mem_throttled_n_commands_per_port(l_mcs, l_run_port));
-
- for (const auto& l_mca : mss::find_targets<TARGET_TYPE_MCA>(l_mcs))
- {
- if (mss::count_dimm(l_mca) == 0)
- {
- continue;
- }
-
- const auto l_pos = mss::index(l_mca);
- //Find the smaller of the three values (calculated slot, runtime slot, and min slot)
- l_min_slot = (l_calc_slot[l_pos] != 0) ? std::min( std::min (l_calc_slot[l_pos], l_run_slot[l_pos]),
- l_min_slot) : l_min_slot;
- l_min_port = (l_calc_port[l_pos] != 0) ? std::min( std::min( l_calc_port[l_pos], l_run_port[l_pos]),
- l_min_port) : l_min_port;
- }
- }
-
- FAPI_INF("Calculated min slot is %d, min port is %d for the system", l_min_slot, l_min_port);
-
- //Now set every port to have those values
- {
- for (const auto& l_mcs : i_targets)
- {
- uint16_t l_fin_slot [mss::PORTS_PER_MCS] = {};
- uint16_t l_fin_port [mss::PORTS_PER_MCS] = {};
- uint32_t l_fin_power [mss::PORTS_PER_MCS] = {};
-
- for (const auto& l_mca : mss::find_targets<TARGET_TYPE_MCA>(l_mcs))
- {
- if (mss::count_dimm(l_mca) == 0)
- {
- continue;
- }
-
- const auto l_pos = mss::index(l_mca);
- // Declaring above to avoid fapi2 jump
- uint64_t l_power_limit = 0;
-
- l_fin_slot[l_pos] = (mss::count_dimm(l_mca)) ? l_min_slot : 0;
- l_fin_port[l_pos] = (mss::count_dimm(l_mca)) ? l_min_port : 0;
-
- //Need to create throttle object for each mca in order to get dimm configuration and power curves
- //To calculate the slot/port utilization and total port power consumption
- fapi2::ReturnCode l_rc;
-
- const auto l_dummy = mss::power_thermal::throttle(l_mca, l_rc);
- FAPI_TRY(l_rc, "Failed creating a throttle object in equalize_throttles");
-
- FAPI_TRY( l_dummy.calc_power_from_n(l_fin_slot[l_pos], l_fin_port[l_pos], l_fin_power[l_pos]),
- "Failed calculating the power value for throttles: slot %d, port %d for target %s",
- l_fin_slot[l_pos],
- l_fin_port[l_pos],
- mss::c_str(l_mca));
-
- //Only calculate the power for ports that have dimms
- l_fin_power[l_pos] = (mss::count_dimm(l_mca) != 0 ) ? l_fin_power[l_pos] : 0;
-
- // You may ask why this is not a variable within the throttle struct
- // It's because POWER throttling is on a per port basis while the THERMAL throttle is per dimm
- // Didn't feel like adding a variable just for this check
- l_power_limit = (i_throttle_type == throttle_type::POWER) ?
- l_dummy.iv_port_power_limit : (l_dummy.iv_dimm_thermal_limit[0] + l_dummy.iv_dimm_thermal_limit[1]);
-
- FAPI_INF("Calculated power is %d, limit is %d", l_fin_power[l_pos], l_power_limit);
-
- //If there's an error with calculating port power, the wrong watt target was passed in
- //Returns an error but doesn't deconfigure anything. Calling function can log if it wants to
- //Called by OCC and by p9_mss_eff_config_thermal, thus different ways for error handling
- //Continue setting throttles to prevent a possible throttle == 0
- //The error will be the last bad port found
- if (l_fin_power[l_pos] > l_power_limit)
- {
- //Need this because of pos traits and templating stuff
- uint64_t l_fail = mss::fapi_pos(l_mca);
- //Set the failing port. OCC just needs one failing port, doesn't need all of them
- FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_MEM_PORT_POS_OF_FAIL_THROTTLE,
- fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
- l_fail) );
-
- FAPI_ASSERT_NOEXIT( false,
- fapi2::MSS_CALC_PORT_POWER_EXCEEDS_MAX()
- .set_CALCULATED_PORT_POWER(l_fin_power[l_pos])
- .set_MAX_POWER_ALLOWED(l_power_limit)
- .set_PORT_POS(mss::pos(l_mca))
- .set_MCA_TARGET(l_mca),
- "Error calculating the final port power value for target %s, calculated power is %d, max value can be %d",
- mss::c_str(l_mca),
- l_fin_power[l_pos],
- l_power_limit);
-
- o_exceeded_power.push_back(l_mca);
- }
-
- FAPI_INF("%s Final throttles values for slot %d, for port %d, power value %d",
- mss::c_str(l_mca),
- l_fin_port[l_pos],
- l_fin_slot[l_pos],
- l_fin_power[l_pos]);
- }
-
- //Even if there's an error, still calculate and set the throttles.
- //OCC will set to safemode if there's an error
- //Better to set the throttles than leave them 0, and potentially brick the memory
- FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, l_mcs, l_fin_port) );
- FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, l_mcs, l_fin_slot) );
- FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_PORT_MAXPOWER, l_mcs, l_fin_power) );
- }
- }
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- FAPI_ERR("Error equalizing memory throttles");
- return fapi2::current_err;
-}
}//namespace power_thermal
}//namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H
index 189583cfa..bfc978492 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,332 +39,24 @@
#include <fapi2.H>
#include <lib/shared/mss_const.H>
#include <lib/mss_attribute_accessors.H>
+#include <lib/power_thermal/accessor_wrapper.H>
+#include <lib/power_thermal/throttle_traits.H>
+#include <lib/dimm/nimbus_kind.H>
+#include <generic/memory/lib/utils/power_thermal/gen_throttle.H>
namespace mss
{
namespace power_thermal
{
///
-/// @brief throttle constants used in the power_thermal functions
-///
-enum throttle_const : size_t
-{
- /// Dram data bus utilization is bus utilization / 4
- DRAM_BUS_UTILS = 4,
-
- /// 10000 to convert to and from c%
- UTIL_CONVERSION = 10000,
-
- /// Conversion to percentage
- PERCENT_CONVERSION = 100,
-
- /// MIN_UTIL is in c%
- MIN_UTIL = 2500,
-
- /// IDLE_UTIL is in c%
- IDLE_UTIL = 0,
-
- /// Minimum throttle allowed for the port and or slot. If we set to 0, we brick the port
- MIN_THROTTLE = 1,
-};
-
-///
-/// @class throttle
-/// @brief Determine power_thermal throttles for memory
-///
-class throttle
-{
- private:
- ///
- /// @brief Calculate the power (cW) of inputs and the power curve
- /// @tparam T
- /// @param[in] i_util the databus utilization that the power will be based on
- /// @param[in] l_pos the dimm position for the power value being calculated.
- /// @return Integral type T
- ///
- template<typename T>
- inline T calc_power (const T i_util, const size_t i_pos) const
- {
- return ((i_util / UTIL_CONVERSION) * iv_pwr_slope[i_pos]) + iv_pwr_int[i_pos];
- }
-
- ///
- /// @brief Raise the o_value by the percent passed in
- /// @param[in] i_uplift the percent the o_Value should be raised by
- /// @param[out] o_value the value that will be modified
- ///
- inline void calc_power_uplift (const uint8_t i_uplift, double& o_value) const
- {
- o_value *= (1 + (static_cast<double>(i_uplift) / PERCENT_CONVERSION));
- }
-
- public:
- const fapi2::Target<fapi2::TARGET_TYPE_MCA>& iv_target;
-
- uint32_t iv_databus_port_max;
-
- uint8_t iv_power_uplift_idle;
- uint8_t iv_power_uplift;
-
- uint16_t iv_runtime_n_slot;
- uint16_t iv_runtime_n_port;
- uint32_t iv_m_clocks;
- uint32_t iv_dimm_thermal_limit[MAX_DIMM_PER_PORT] = {};
- uint16_t iv_pwr_slope[MAX_DIMM_PER_PORT] = {};
- uint16_t iv_pwr_int[MAX_DIMM_PER_PORT] = {};
- uint16_t iv_n_slot;
- uint16_t iv_n_port;
- uint32_t iv_port_power_limit;
- uint32_t iv_calc_port_maxpower;
-
- //default ctor deleted
- throttle() = delete;
-
- ///
- /// @brief Constructor
- /// @param[in] i_target MCA target to call power thermal stuff on
- /// @param[out] o_rc fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ctor was successful
- ///
- throttle( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_mca, fapi2::ReturnCode& o_rc);
-
- //
- // @brief Destructor
- //
- ~throttle() = default;
-
- ///
- /// @brief Calculates the min and max power usage for a port
- /// @param[in] i_idle_util the utilization of the databus in idle mode
- /// @param[in] i_max_util the utilization of the port at maximum possible (mrw or calculated)
- /// @param[out] o_port_power_idle max value of port power in cW
- /// @param[out] o_port_power_max max value of port power in cW
- /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
- /// @note Called twice in p9_mss_bulk_pwr_throttles
- ///
- fapi2::ReturnCode calc_port_power( const double i_idle_util [MAX_DIMM_PER_PORT],
- const double i_max_util [MAX_DIMM_PER_PORT],
- double& o_port_power_idle,
- double& o_port_power_max) const;
- ///
- /// @brief Calculates max and min power usages based off of DIMM power curves
- /// @param[in] i_databus_port_max max databus utilization for the port (either calculated or mrw)
- /// @param[in] i_port_power_calc_idle double of the port's power consumption at idle
- /// @param[out] o_dimm_power_idle array of dimm power in cW
- /// @param[out] o_dimm_power_max array of dimm power in cW
- /// @note Called in p9_mss_bulk_pwr_throttles
- /// @note used for the thermal throttles
- ///
- void calc_dimm_power(const double i_databus_idle,
- const double i_databus_max,
- double o_dimm_power_idle [MAX_DIMM_PER_PORT],
- double o_dimm_power_max [MAX_DIMM_PER_PORT]) const;
-
- ///
- /// @brief Calculate the power curve in order to calculate databus utilization
- /// @param[in] i_power_idle double of the port's power consumption at idle
- /// @param[in] i_power_max double of the port's power consumption at max utilization
- /// @param[out] o_power_slope
- /// @param[out] o_power_int
- /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
- /// @note Called in p9_mss_bulk_pwr_throttles
- /// @note Power curve needed to calculate the utilization
- ///
- fapi2::ReturnCode calc_power_curve(const double i_power_idle,
- const double i_power_max,
- uint32_t& o_power_slope,
- uint32_t& o_power_int) const;
- ///
- /// @brief Calculate the databus utilization given the power curve
- /// @param[in] i_slope
- /// @param[in] i_int
- /// @param[in] i_power_limit either iv_port_power_limit or thermal_power_limit depending on throttle type
- /// @param[out] o_port_util the port's databus utilization
- /// @note Called in p9_mss_bulk_pwr_throttles
- /// @note Chooses worst case between the maximum allowed databus utilization and the calculated value
- ///
- void calc_util_usage(const uint32_t i_slope,
- const uint32_t i_int,
- const uint32_t i_power_limit,
- double& o_util) const;
- ///
- /// @brief set iv_n_port, iv_n_slot, iv_calc_port_maxpower
- /// @param[in] i_util_port pass in the calculated port databus utilization
- /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
- ///
- fapi2::ReturnCode calc_slots_and_power (const double i_util_port);
-
- ///
- /// @brief calculated the output power estimate from the calculated N throttle
- /// @param[in] i_n_slot the N throttle per slot
- /// @param[in] i_n_port the N throttle per port
- /// @param[out] o_power the calculated power
- /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
- ///
- fapi2::ReturnCode calc_power_from_n (const uint16_t i_n_slot, const uint16_t i_n_port, uint32_t& o_power) const;
-
- ///
- /// @brief Converts the port maximum databus util to a dimm level based on powerslopes and dimms installed
- /// @param[in] i_databus_port_max max databus utilization for the port (either calculated or mrw)
- /// @param[out] o_databus_dimm_max array of dimm utilization values
- /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
- /// @note Called in p9_mss_bulk_pwr_throttles
- /// @used to calculate the port power based off of DIMM power curves
- ///
- fapi2::ReturnCode calc_databus( const double i_databus_port_max,
- double o_databus_dimm_max [MAX_DIMM_PER_PORT]);
- ///
- /// @brief Converts the port and slot util to a dimm level based on powerslopes and number of dimms installed
- /// @param[in] i_util_slot databus utilization for the slot
- /// @param[in] i_util_port databus utilization for the port
- /// @param[out] o_util_dimm_max array of dimm utilization values
- /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
- /// @note determines worst case utilization per dimms, takes into account port and combine slot throttles
- ///
- fapi2::ReturnCode calc_split_util(
- const double i_util_slot,
- const double i_util_port,
- double o_util_dimm_max [MAX_DIMM_PER_PORT]) const;
-
-
- ///
- /// @brief Calculate ATTR_MSS_CHANNEL_PAIR_MAXPOWER and ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
- /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
- /// @note Called in p9_mss_bulk_pwr_throttles
- /// @note determines the throttle levels based off of the port's power curve, max databus utilization,
- /// and memwat target.
- /// @note currently sets the slot and port throttles to the same value
- ///
- fapi2::ReturnCode power_regulator_throttles ();
-
- ///
- /// @brief Set ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
- /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
- /// @note Called in p9_mss_bulk_pwr_throttles
- /// @note Sets the throttle levels based off of the dimm's thermal limits
- /// @note both DIMM's on a port are set to the same throttle level
- ///
- fapi2::ReturnCode thermal_throttles ();
-};
-
-///
-/// @brief Calculate N (address operations) allowed within a window of M DRAM clocks
-/// @param[in] i_databus_util databus utilization percentage (e.g. 5% = 5)
-/// @param[in] i_num_dram_clocks window of M DRAM clocks
-/// @return number of throttled commands allowed
-/// @note Uses N/M Throttling.
-/// Equation: N = (DRAM data bus utilization * M) / (4 * 10000)
-///
-inline uint32_t throttled_cmds(const uint32_t i_databus_util, const uint32_t i_num_dram_clocks)
-{
- constexpr uint64_t l_divisor = DRAM_BUS_UTILS * UTIL_CONVERSION;
- const uint64_t l_dividend = i_databus_util * i_num_dram_clocks;
- const uint64_t l_result = l_dividend / l_divisor;
-
- //Make sure N is not equal to 0, or we brick the dram until reboot
- return ((l_result == 0) ? 1 : l_result);
-}
-
-///
-/// @brief Calculate the port databus utilization based off of N throttles and M dram clocks
-/// @tparam T output type
-/// @param[in] i_n_throttles N (address operations) allowed within a window of M DRAM clocks
-/// @param[in] i_num_dram_clocks window of M DRAM clocks
-/// @param[out] o_calc_util
-/// @return FAPI2_RC_SUCCESS iff method was a success
-/// @note Uses N/M Throttling.
-/// @note DRAM databus utilization = N * 4 * 10000 / M
-///
-template<typename T>
-fapi2::ReturnCode calc_util_from_throttles(const uint16_t i_n_throttles,
- const uint32_t i_num_dram_clocks,
- T& o_calc_util)
-{
- constexpr uint32_t l_multiplier = DRAM_BUS_UTILS * UTIL_CONVERSION;
- FAPI_ASSERT( (i_num_dram_clocks != 0),
- fapi2::MSS_M_DRAM_CLOCKS_EQUALS_ZERO(),
- "ATTR_MSS_MRW_MEM_M_DRAM_CLOCKS was not set and equals zero");
-
- o_calc_util = (static_cast<double>(i_n_throttles) * l_multiplier) / i_num_dram_clocks;
-
- // Best way to check for overflow if o_calc_util can be a double?
- // If o_calc_util overflows, the value inside will be below the expected outcome
- // So compare o_calc_util with the calculated value, but store calculated value in largest storage
- // Compare ">=" because o_calc_util can be a double, and so we can't compare just equality due to truncation
- FAPI_ASSERT( o_calc_util >= static_cast<uint64_t>((static_cast<double>(i_n_throttles) * l_multiplier) /
- i_num_dram_clocks),
- fapi2::MSS_OUTPUT_OVERFLOW_CALC_UTIL()
- .set_RESULT((static_cast<double>(i_n_throttles) * l_multiplier) / i_num_dram_clocks),
- "Overflow of output variable in calc_util_from_throttles throttles: %d, multiplier %d, dram_clocks %d",
- i_n_throttles,
- l_multiplier,
- i_num_dram_clocks);
-
- // Check for the minimum
- if(o_calc_util < MIN_UTIL)
- {
- FAPI_INF("Calculated utilization (%f) is less than the minimum utilization: %lu. Setting to minimum value",
- o_calc_util, MIN_UTIL);
- o_calc_util = MIN_UTIL;
- }
-
- FAPI_INF("In calc_util_from_throttles, calculated %f for output utilization", o_calc_util);
- return fapi2::FAPI2_RC_SUCCESS;
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines if the double has decimal digits and adds 1 and rounds if true
-/// @param[in] i_val the double to be rounded up if trialing digits
-/// @return the input value rounded up to the next whole digit
-/// @note Called in p9_mss_bulk_pwr_throttles
-///
-inline uint32_t round_up(double i_val)
-{
- //convert to uint to truncate decimals and convert back to double for comparison
- uint32_t temp = uint32_t (i_val);
-
- //if not equal, lost something from truncating, so add 1
- temp += (temp == i_val) ? 0 : 1;
-
- //Truncate final value
- return temp;
-}
-
-///
-/// @brief Perform thermal calculations as part of the effective configuration
-/// @param[in] i_target the MCS target in which the runtime throttles will be reset
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode restore_runtime_throttles( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target );
-
-///
-/// @brief Update the runtime throttles to the worst case of the general throttle values and the runtime values
-/// @param[in] i_target the MCS target in which the runtime throttles will be set
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode update_runtime_throttles(const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets);
-
-///
/// @brief set ATTR_MSS_RUNTIME_MEM_M_DRAM_CLOCKS and ATTR_MSS_MEM_WATT_TARGET
/// @param[in] i_targets vector of mcs targets all on the same vddr domain
/// @return FAPI2_RC_SUCCESS iff it was a success
///
fapi2::ReturnCode set_runtime_m_and_watt_limit( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets );
-///
-/// @brief Equalize the throttles and estimated power at those throttle levels
-/// @param[in] i_targets vector of MCS targets all on the same VDDR domain
-/// @param[in] i_throttle_type denotes if this was done for POWER (VMEM) or THERMAL (VMEM+VPP) throttles
-/// @param[out] o_exceeded_power vector of MCA targets where the estimated power exceeded the maximum allowed
-/// @return FAPI2_RC_SUCCESS iff ok
-/// @note sets the throttles and power to the worst case
-///
-fapi2::ReturnCode equalize_throttles (const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets,
- const throttle_type i_throttle_type,
- std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCA> >& o_exceeded_power);
-
}//power_thermal
+
}// mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle_traits.H b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle_traits.H
index da277d6fb..15407e3a4 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle_traits.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle_traits.H
@@ -22,3 +22,125 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_mss_utils_to_throttle.H
+/// @brief throttle API
+///
+
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_POWER_THROTTLE_TRAITS_
+#define _MSS_POWER_THROTTLE_TRAITS_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/power_thermal/gen_throttle_traits.H>
+
+namespace mss
+{
+namespace power_thermal
+{
+
+///
+/// @class Traits and policy class for throttle code - specialization for the NIMBUS mc type
+///
+template<>
+class throttle_traits<mss::mc_type::NIMBUS>
+{
+ public:
+ //////////////////////////////////////////////////////////////
+ // Target types
+ //////////////////////////////////////////////////////////////
+ static constexpr fapi2::TargetType MC_TARGET_TYPE = fapi2::TARGET_TYPE_MCS;
+ static constexpr fapi2::TargetType PORT_TARGET_TYPE = fapi2::TARGET_TYPE_MCA;
+
+ // MIN_UTIL is in c%
+ static const uint64_t MIN_UTIL = 2500;
+ // IDLE_UTIL is in c%
+ static const uint64_t IDLE_UTIL = 0;
+ // Minimum throttle allowed for the port and or slot. If we set to 0, we brick the port
+ static const uint64_t MIN_THROTTLE = 1;
+
+ enum size_of_attrs : size_t
+ {
+ SIZE_OF_POWER_CURVES_ATTRS = 100,
+ SIZE_OF_THERMAL_ATTR = 10,
+ };
+
+ enum default_power
+ {
+ //Values are the worst case defaults for power curves
+ //They are the default/ catch-all values from the power curve attributes
+ //Shouldn't be used if system is set up correctly and attributes are available
+ //This will throttle the DIMMs to ~76% dram data bus utilization
+ //(using the mrw regulator power limit of 1700 cW and thermal power limit here of 1940 cW).
+ VDDR_SLOPE = 0x41A,
+ VDDR_INT = 0x384,
+ TOTAL_SLOPE = 0x44C,
+ TOTAL_INT = 0x44C,
+ THERMAL_LIMIT = 0x794,
+ };
+
+ enum
+ {
+ PORTS_PER_MC = 2,
+ DIMMS_PER_PORT = 2,
+ };
+
+ //Bit positions for different section of the attribute
+ //first 32 bits are the encoding, second are for values
+ enum DECODE_BUFFER_POS
+ {
+ ENCODING_START = 0,
+ ENCODING_LENGTH = 32,
+ VDDR_START = 32,
+ VDDR_LENGTH = 16,
+ TOTAL_START = 48,
+ TOTAL_LENGTH = 16,
+ THERMAL_POWER_START = 32,
+ THERMAL_POWER_LENGTH = 32,
+ };
+
+ //Positions and lengths of the encodings
+ enum ATTR_DECODE_INFO
+ {
+ DIMM_SIZE_START = 0,
+ DIMM_SIZE_LEN = 4,
+
+ DRAM_GEN_START = 4,
+ DRAM_GEN_LEN = 2,
+
+ DIMM_TYPE_START = 6,
+ DIMM_TYPE_LEN = 2,
+
+ DRAM_WIDTH_START = 8,
+ DRAM_WIDTH_LEN = 3,
+
+ DRAM_DENSITY_START = 11,
+ DRAM_DENSITY_LEN = 3,
+
+ DRAM_STACK_TYPE_START = 14,
+ DRAM_STACK_TYPE_LEN = 2,
+
+ DRAM_MFGID_START = 16,
+ DRAM_MFGID_LEN = 3,
+
+ DIMMS_PER_PORT_START = 19,
+ DIMMS_PER_PORT_LEN = 2,
+
+ // Invalid for Nimbus but compile will fail without them
+ DIMM_MODULE_HEIGHT_START = 0,
+ DIMM_MODULE_HEIGHT_LEN = 1,
+ };
+
+
+ // Definition is in chip folder
+ static const std::vector< std::pair<uint8_t , uint8_t> > DIMM_TYPE_MAP;
+};
+}//power_thermal
+}// mss
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
index bf84c1662..679459d74 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
@@ -51,7 +51,6 @@ enum sizes
MC_PER_MODULE = 2,
MCBIST_PER_MC = 1,
MAX_DIMM_PER_PORT = 2,
- MAX_RANK_PER_DIMM = 4,
PORTS_PER_MODULE = MC_PER_MODULE * MCS_PER_MC * PORTS_PER_MCS,
BITS_PER_DP = 16,
NIBBLES_PER_DP = BITS_PER_DP / BITS_PER_NIBBLE,
@@ -64,7 +63,7 @@ enum sizes
RANK_MID_POINT = 4, ///< Which rank number indicates the switch to the other DIMM
MAX_NUM_IMP = 4, ///< number of impedances valid per slew type
MAX_NUM_CAL_SLEW_RATES = 4, ///< 3V/ns, 4V/ns, 5V/ns, 6V/n
- MAX_DQ_BITS = 72, /// TODO RTC:157753 This is Nimbus specific. Should be attribute/trait of processor.
+ MAX_DQ_BITS = 72,
MAX_DQ_NIBBLES = MAX_DQ_BITS / BITS_PER_NIBBLE, ///< For ISDIMMs are 18 DQ nibbles for DQ 72 bits
MAX_DRAMS_X8 = MAX_DQ_BITS / BITS_PER_BYTE, ///< For x8's there are 9 DRAM for 72 bits
MAX_DRAMS_X4 = MAX_DQ_BITS / BITS_PER_NIBBLE, ///< For x4's there are 18 DRAM for 72 bits
@@ -75,10 +74,6 @@ enum sizes
ROW_REPAIR_BYTE_COUNT = 4, ///< Elements in a ROW_REPAIR_DATA attribute array.
- BYTES_PER_GB = 1000000000, ///< Multiplier to go from GB to B
- T_PER_MT = 1000000, ///< Multiplier to go from MT/s to T/s
- CYCLES_PER_CMD = 4, ///< Best case cycles per MCBIST command
-
// All need to be attributes? - BRS
WR_LVL_BIG_STEP = 0b0111,
WR_LVL_SMALL_STEP = 0b000,
@@ -99,27 +94,11 @@ enum sizes
// Largest size a VPD keyword can be
VPD_KEYWORD_MAX = 255,
-
- // Number of double words in...
- NUM_DW_IN_128B = 16,
- NUM_DW_IN_64B = 8,
-
- // MCBIST polling constant for actual HW
- // The specific value here is not important, only that it is very large to avoid polling timeouts,
- // but not to avoid any actual hardware timeouts
- // Note: ~0 is not used as that would cause MCBIST to never timeout even if the hardware is in an infinite loop
- // You can't get greater than ~0, so you'd never timeout
- // TODO RTC:166340 - Clean up MCBIST polling
- OVERLY_LARGE_NUMBER_OF_POLLS = 5000000000000,
};
enum times
{
// Not *exactly* a time but go with i
- BG_SCRUB_IN_HOURS = 12,
-
- CMD_TIMEBASE = 8192, ///< Represents the timebase multiplier for the MCBIST inter cmd gap
- MAX_CMD_GAP = 4095, ///< Represents the maximum (non-multplied) time for MCBIST inter cmd gap
FULL_DLL_CAL_DELAY = 37382, ///< Full DLL calibration (in ddphy_nck cycles)
};
@@ -154,26 +133,9 @@ enum ffdc_function_codes
SOFT_POST_PACKAGE_REPAIR = 27,
EFF_BC07 = 28,
- // Used in fw_mark_store.H for MSS_INVALID_RANK_PASSED
- FWMS_READ = 30,
- FWMS_WRITE = 31,
-
- // Used in hw_mark_store.H for MSS_INVALID_RANK_PASSED
- HWMS_READ = 40,
- HWMS_WRITE = 41,
-
- // MSS_INVALID_INDEX_PASSED
- SYMBOL_COUNT_READ = 50,
- SYMBOL_COUNT_WRITE = 51,
-
// Used in rank.H
MAP_RP_PRIMARY_TO_INIT_CAL = 60,
- // Power thermal functions
- SLOPE = 70,
- INTERCEPT = 71,
- POWER_LIMIT = 72,
-
// PDA function codes
PDA_WR_VREF_LATCH_CONTAINER = 80,
PDA_WR_VREF_LATCH_VECTOR = 81,
@@ -198,6 +160,7 @@ enum ffdc_function_codes
DRAM_TO_RP_REG = 101,
// eff_dimm.C
+ RAW_CARD_FACTORY = 115,
PRIMARY_STACK_TYPE = 116,
// CW engine information
@@ -212,9 +175,6 @@ enum ffdc_function_codes
// LR training function
DWL_CALL_OUT = 130,
MREP_CALL_OUT = 131,
-
-
- CCS_INST_CONFIGURE_RANK = 132,
};
// Static consts describing the bits used in the cal_step_enable attribute
@@ -276,44 +236,6 @@ enum voltages : uint64_t
};
-enum port_select
-{
- // Port selects for MCBIST and CCS
- // Select for 1 port
- PORT0 = 0b1000,
- PORT1 = 0b0100,
- PORT2 = 0b0010,
- PORT3 = 0b0001,
- // Selects for 2 port combinations
- PORT01 = PORT0 | PORT1,
- PORT02 = PORT0 | PORT2,
- PORT03 = PORT0 | PORT3,
- PORT12 = PORT1 | PORT2,
- PORT13 = PORT1 | PORT3,
- PORT23 = PORT2 | PORT3,
- // Selects for 3 port combinations
- PORT012 = PORT0 | PORT1 | PORT2,
- PORT013 = PORT0 | PORT1 | PORT3,
- PORT023 = PORT0 | PORT2 | PORT3,
- PORT123 = PORT1 | PORT2 | PORT3,
- // Select all
- PORT0123 = PORT0 | PORT1 | PORT2 | PORT3,
- // Maybe a better name for disabling all
- PORT_NONE = 0b0000,
-};
-
-enum dimm_select
-{
- // Dimm selects for MCBIST and CCS
- // Select for 1 dimm
- DIMM0 = 0b10,
- DIMM1 = 0b01,
- // Selects for 2 dimm combinations
- DIMM01 = DIMM0 | DIMM1,
- // Maybe a better name for disabling all
- DIMM_NONE = 0b00,
-};
-
// Possible values for power domains in MBARPC0Q
enum min_max_domains : uint64_t
{
@@ -324,179 +246,5 @@ enum min_max_domains : uint64_t
MAX1_MIN0 = 0b100,
};
-namespace mcbist
-{
-
-enum broadcast_timebase
-{
- // Number of 1024 2:1 cycle timebases to wait starting MCBIST
- // for SRQs to get synced for broadcast mode
- TB_COUNT_2 = 0b0000001,
- TB_COUNT_4 = 0b0000011,
- TB_COUNT_8 = 0b0000111,
- TB_COUNT_16 = 0b0001111,
- TB_COUNT_32 = 0b0011111,
- TB_COUNT_64 = 0b0111111,
- TB_COUNT_128 = 0b1111111,
-};
-
-enum rmw_address
-{
- // 32B block addresses into the maint portion of the rmw buffer
- DW0 = 0b111110000,
- DW1 = 0b111110001,
- DW2 = 0b111110010,
- DW3 = 0b111110011,
- DW4 = 0b111110100,
- DW5 = 0b111110101,
- DW6 = 0b111110110,
- DW7 = 0b111110111,
- DW8 = 0b111111000,
- DW9 = 0b111111001,
- DWA = 0b111111010,
- DWB = 0b111111011,
- DWC = 0b111111100,
- DWD = 0b111111101,
- DWE = 0b111111110,
- DWF = 0b111111111,
-};
-
-enum data_rotate_mode
-{
- // MCBIST data rotate modes refer to register MCBDRCR bits 0:3
- ROTATE_0_BITS = 0b0000,
- ROTATE_1_BITS = 0b0001,
- ROTATE_2_BITS = 0b0010,
- ROTATE_3_BITS = 0b0011,
- ROTATE_4_BITS = 0b0100,
- ROTATE_5_BITS = 0b0101,
- ROTATE_6_BITS = 0b0110,
- ROTATE_7_BITS = 0b0111,
- ROTATE_8_BITS = 0b1000,
- ROTATE_9_BITS = 0b1001,
- ROTATE_10_BITS = 0b1010,
- ROTATE_11_BITS = 0b1011,
- ROTATE_12_BITS = 0b1100,
- ROTATE_13_BITS = 0b1101,
- ROTATE_14_BITS = 0b1110,
- ROTATE_15_BITS = 0b1111,
-};
-
-enum data_seed_mode
-{
- // MCBIST data seed modes refer to register MCBDRCR bits 21:22
- ALL_UNIQUE = 0b00,
- REPEAT_SEED_0 = 0b01,
- REPEAT_SEED_1 = 0b10,
- REPEAT_SEED_2 = 0b11,
-};
-
-enum data_mode
-{
- // MCBIST test data modes
- FIXED_DATA_MODE = 0b000,
- RAND_FWD_MODE = 0b001,
- RAND_REV_MODE = 0b010,
- RAND_FWD_MAINT = 0b011,
- RAND_REV_MAINT = 0b100,
- DATA_EQ_ADDR = 0b101,
- ROTATE_LEFT_MODE = 0b110,
- ROTATE_RIGHT_MODE = 0b111,
-};
-
-// 0:3 Operation Type
-enum op_type
-{
- WRITE = 0b0000, // fast, with no concurrent traffic
- READ = 0b0001, // fast, with no concurrent traffic
- READ_WRITE = 0b0010,
- WRITE_READ = 0b0011,
- READ_WRITE_READ = 0b0100,
- READ_WRITE_WRITE = 0b0101,
- RAND_SEQ = 0b0110,
- READ_READ_WRITE = 0b1000,
- SCRUB_RRWR = 0b1001,
- STEER_RW = 0b1010,
- ALTER = 0b1011, // (W)
- DISPLAY = 0b1100, // (R, slow)
- CCS_EXECUTE = 0b1111,
-
- // if bits 9:11 (Data Mode bits) = 000 (bits 4:8 used to specify which subtest to go to)
- // Refresh only cmd if bits 9:11 (Data Mode bits) /= 000
- GOTO_SUBTEST_N = 0b0111,
-};
-
-
-enum test_type
-{
- USER_MODE = 0,
- CENSHMOO = 1,
- SUREFAIL = 2,
- MEMWRITE = 3,
- MEMREAD = 4,
- CBR_REFRESH = 5,
- MCBIST_SHORT = 6,
- SHORT_SEQ = 7,
- DELTA_I = 8,
- DELTA_I_LOOP = 9,
- SHORT_RAND = 10,
- LONG1 = 11,
- BUS_TAT = 12,
- SIMPLE_FIX = 13,
- SIMPLE_RAND = 14,
- SIMPLE_RAND_2W = 15,
- SIMPLE_RAND_FIXD = 16,
- SIMPLE_RA_RD_WR = 17,
- SIMPLE_RA_RD_R = 18,
- SIMPLE_RA_FD_R = 19,
- SIMPLE_RA_FD_R_INF = 20,
- SIMPLE_SA_FD_R = 21,
- SIMPLE_RA_FD_W = 22,
- INFINITE = 23,
- WR_ONLY = 24,
- W_ONLY = 25,
- R_ONLY = 26,
- W_ONLY_RAND = 27,
- R_ONLY_RAND = 28,
- R_ONLY_MULTI = 29,
- SHORT = 30,
- SIMPLE_RAND_BARI = 31,
- W_R_INFINITE = 32,
- W_R_RAND_INFINITE = 33,
- R_INFINITE1 = 34,
- R_INFINITE_RF = 35,
- MARCH = 36,
- SIMPLE_FIX_RF = 37,
- SHMOO_STRESS = 38,
- SIMPLE_RAND_RA = 39,
- SIMPLE_FIX_RA = 40,
- SIMPLE_FIX_RF_RA = 41,
- TEST_RR = 42,
- TEST_RF = 43,
- W_ONLY_INFINITE_RAND = 44,
- MCB_2D_CUP_SEQ = 45,
- MCB_2D_CUP_RAND = 46,
- SHMOO_STRESS_INFINITE = 47,
- HYNIX_1_COL = 48,
- RMWFIX = 49,
- RMWFIX_I = 50,
- W_INFINITE = 51,
- R_INFINITE = 52,
-};
-
-
-} // namespace mcbist
-
-enum class shmoo_edge : std::size_t
-{
- LEFT,
- RIGHT
-};
-
-enum visual_max : uint64_t
-{
- MAX_VISUAL_VALUE = 9999
-};
-
} // namespace mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/shared/nimbus_defaults.H b/src/import/chips/p9/procedures/hwp/memory/lib/shared/nimbus_defaults.H
index 5863d063f..0a10d2522 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/shared/nimbus_defaults.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/shared/nimbus_defaults.H
@@ -36,12 +36,15 @@
#ifndef _MSS_NIMBUS_DEFAULTS_H_
#define _MSS_NIMBUS_DEFAULTS_H_
+#include <fapi2.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
namespace mss
{
constexpr mss::mc_type DEFAULT_MC_TYPE = mss::mc_type::NIMBUS;
+constexpr fapi2::TargetType DEFAULT_MC_TARGET = fapi2::TARGET_TYPE_MCBIST;
+constexpr fapi2::TargetType DEFAULT_MEM_PORT_TARGET = fapi2::TARGET_TYPE_MCA;
} // ns mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C b/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C
index be8343c71..2d6aef4c8 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C
@@ -53,7 +53,7 @@
#include <generic/memory/lib/spd/spd_checker.H>
#include <generic/memory/lib/spd/spd_utils.H>
#include <lib/utils/mss_nimbus_conversions.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <lib/eff_config/timing.H>
#include <lib/shared/mss_const.H>
@@ -131,7 +131,8 @@ fapi2::ReturnCode raw_card_factory(const fapi2::Target<TARGET_TYPE_DIMM>& i_targ
FAPI_ASSERT( false,
fapi2::MSS_INVALID_DIMM_TYPE()
.set_DIMM_TYPE(l_dimm_type)
- .set_DIMM_TARGET(i_target),
+ .set_DIMM_TARGET(i_target)
+ .set_FUNCTION(mss::ffdc_function_codes::RAW_CARD_FACTORY),
"Recieved invalid dimm type: %d for %s",
l_dimm_type, mss::spd::c_str(i_target) );
break;
diff --git a/src/import/generic/memory/lib/utils/find_magic.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/find_magic.H
index a67d4f2e8..3c8a385c4 100644
--- a/src/import/generic/memory/lib/utils/find_magic.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/find_magic.H
@@ -1,7 +1,7 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/generic/memory/lib/utils/find_magic.H $ */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/utils/find_magic.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
@@ -135,30 +135,6 @@ find_targets_with_magic( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_targe
return l_ports;
}
-///
-/// @brief Determine if a thing is functional
-/// @tparam I, the type of the item we want to check for
-/// @tparam P, the type of the parent which holds the things of interest
-/// @param[in] i_target the parent containing the thing we're looking for
-/// @param[in] i_rel_pos the relative position of the item of interest.
-/// @return bool true iff the thing at i_rel_pos is noted as functional
-///
-template< fapi2::TargetType I, fapi2::TargetType P >
-bool is_functional( const fapi2::Target<P>& i_target, const uint64_t i_rel_pos )
-{
- // Not sure of a good way to do this ... we get all the functional
- // children of the parent and look for our relative position ...
- for (const auto& i : i_target.template getChildren<I>(fapi2::TARGET_STATE_FUNCTIONAL))
- {
- if (mss::template relative_pos<P>(i) == i_rel_pos)
- {
- return true;
- }
- }
-
- return false;
-}
-
}// mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/hwp_wrappers_nim.C b/src/import/chips/p9/procedures/hwp/memory/lib/utils/hwp_wrappers_nim.C
new file mode 100644
index 000000000..7f5dd54e7
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/hwp_wrappers_nim.C
@@ -0,0 +1,169 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/utils/hwp_wrappers_nim.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file hwp_wrappers_nim.C
+/// @brief Main wrapper file for PRD calling Nimbus memory procedure code
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#include <fapi2.H>
+#include <lib/shared/nimbus_defaults.H>
+#include <lib/mcbist/mcbist_traits.H>
+#include <generic/memory/lib/utils/dimm/kind.H>
+#include <lib/dimm/nimbus_kind.H>
+#include <lib/dimm/rank.H>
+#include <mss.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_memdiags.H>
+
+///
+/// @brief Memdiags stop command wrapper for Nimbus
+/// @param[in] i_target the target
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode nim_stop( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target )
+{
+ return mss::memdiags::stop<mss::mc_type::NIMBUS>(i_target);
+}
+
+///
+/// @brief Memdiags Super Fast Init command wrapper for Nimbus
+/// @param[in] i_target the target behind which all memory should be initialized
+/// @param[in] i_pattern an index representing a pattern to use to init memory (defaults to 0)
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode nim_sf_init( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const uint64_t i_pattern )
+{
+ return mss::memdiags::sf_init<mss::mc_type::NIMBUS>(i_target, i_pattern);
+}
+
+///
+/// @brief Memdiags Super Fast Read command wrapper for Nimbus
+/// @param[in] i_target the target behind which all memory should be read
+/// @param[in] i_stop stop conditions
+/// @param[in] i_address mcbist::address representing the address from which to start.
+// Defaults to the first address behind the target
+/// @param[in] i_end whether to end, and where
+/// Defaults to stop after slave rank
+/// @param[in] i_end_address mcbist::address representing the address to end.
+// Defaults to TT::LARGEST_ADDRESS
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode nim_sf_read( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const mss::mcbist::stop_conditions<mss::mc_type::NIMBUS>& i_stop,
+ const mss::mcbist::address& i_address,
+ const mss::mcbist::end_boundary i_end,
+ const mss::mcbist::address& i_end_address )
+{
+ return mss::memdiags::sf_read<mss::mc_type::NIMBUS>(i_target, i_stop, i_address, i_end, i_end_address);
+}
+
+///
+/// @brief Continuous background scrub command wrapper for Nimbus
+/// @param[in] i_target the target behind which all memory should be scrubbed
+/// @param[in] i_stop stop conditions
+/// @param[in] i_speed the speed to scrub
+/// @param[in] i_address mcbist::address representing the address from which to start.
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode nim_background_scrub( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const mss::mcbist::stop_conditions<mss::mc_type::NIMBUS>& i_stop,
+ const mss::mcbist::speed i_speed,
+ const mss::mcbist::address& i_address )
+{
+ return mss::memdiags::background_scrub<mss::mc_type::NIMBUS>(i_target, i_stop, i_speed, i_address);
+}
+
+///
+/// @brief Targeted scrub command wrapper for Nimbus
+/// @param[in] i_target the target behind which all memory should be scrubbed
+/// @param[in] i_stop stop conditions
+/// @param[in] i_speed the speed to scrub
+/// @param[in] i_start_address mcbist::address representing the address from which to start.
+/// @param[in] i_end_address mcbist::address representing the address at which to end.
+/// @param[in] i_end whether to end, and where
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode nim_targeted_scrub( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const mss::mcbist::stop_conditions<mss::mc_type::NIMBUS>& i_stop,
+ const mss::mcbist::address& i_start_address,
+ const mss::mcbist::address& i_end_address,
+ const mss::mcbist::end_boundary i_end )
+{
+ return mss::memdiags::targeted_scrub<mss::mc_type::NIMBUS>(i_target, i_stop, i_start_address, i_end_address, i_end);
+}
+
+///
+/// @brief Continue current command wrapper for Nimbus
+/// @param[in] i_target the target
+/// @param[in] i_end whether to end, and where (default - don't stop at end of rank)
+/// @param[in] i_stop stop conditions (default - 0 meaning 'don't change conditions')
+/// @param[in] i_speed the speed to scrub (default - SAME_SPEED meaning leave speed untouched)
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode nim_continue_cmd( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const mss::mcbist::end_boundary i_end,
+ const mss::mcbist::stop_conditions<mss::mc_type::NIMBUS>& i_stop,
+ const mss::mcbist::speed i_speed )
+{
+ return mss::memdiags::continue_cmd<mss::mc_type::NIMBUS>(i_target, i_end, i_stop, i_speed);
+}
+
+///
+/// @brief Broadcast mode check wrapper for Nimbus
+/// @param[in] i_target the target to effect
+/// @return o_capable - yes iff these vector of targets are broadcast capable
+///
+const mss::states nim_is_broadcast_capable(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target)
+{
+ return mss::mcbist::is_broadcast_capable<mss::mc_type::NIMBUS>(i_target);
+}
+
+
+///
+/// @brief Broadcast mode check wrapper for Nimbus
+/// @param[in] i_targets the vector of targets to analyze
+/// @return o_capable - yes iff these vector of targets are broadcast capable
+///
+const mss::states nim_is_broadcast_capable(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCA>>& i_targets)
+{
+ return mss::mcbist::is_broadcast_capable<mss::mc_type::NIMBUS>(i_targets);
+}
+
+///
+/// @brief Broadcast mode check wrapper for Nimbus
+/// @param[in] i_kinds the dimms to effect
+/// @return o_capable - yes iff these vector of targets are broadcast capable
+///
+const mss::states nim_is_broadcast_capable(const std::vector<mss::dimm::kind<mss::mc_type::NIMBUS>>& i_kinds)
+{
+ return mss::mcbist::is_broadcast_capable(i_kinds);
+}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_nimbus_conversions.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_nimbus_conversions.H
index 1b7f749fd..9a560f72a 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_nimbus_conversions.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_nimbus_conversions.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,7 +36,7 @@
#define _MSS_NIMBUS_CONVERSIONS_H_
#include <generic/memory/lib/utils/conversions.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <lib/mss_attribute_accessors.H>
namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_pair.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_pair.H
index 9b2a7a1af..ddea7c7fd 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_pair.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_pair.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,7 +38,7 @@
#define _MSS_PAIR_CONST_H_
#include <fapi2.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <generic/memory/lib/utils/c_str.H>
namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/nimbus_find.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/nimbus_find.H
new file mode 100644
index 000000000..b922938d4
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/nimbus_find.H
@@ -0,0 +1,112 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/utils/nimbus_find.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file nimbus_find.H
+/// @brief Nimbus templates specialization for finding things
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_NIMBUS_FIND_H
+#define _MSS_NIMBUS_FIND_H
+
+#include <fapi2.H>
+#include <vector>
+#include <generic/memory/lib/utils/find.H>
+
+namespace mss
+{
+
+///
+/// @brief find the McBIST given a DIMM
+/// @param[in] i_target the fapi2 target DIMM
+/// @return a McBIST target.
+///
+template<>
+inline fapi2::Target<fapi2::TARGET_TYPE_MCBIST> find_target(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target)
+{
+ return i_target.getParent<fapi2::TARGET_TYPE_MCA>().getParent<fapi2::TARGET_TYPE_MCBIST>();
+}
+
+///
+/// @brief find all the dimm connected to an MCS
+/// @param[in] i_target a fapi2::Target MCS
+/// @return a vector of fapi2::TARGET_TYPE_DIMM
+///
+template<>
+inline std::vector< fapi2::Target<fapi2::TARGET_TYPE_DIMM> >
+find_targets( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
+ fapi2::TargetState i_state )
+{
+ std::vector< fapi2::Target<fapi2::TARGET_TYPE_DIMM> > l_dimms;
+
+ for (const auto& p : i_target.getChildren<fapi2::TARGET_TYPE_MCA>(i_state))
+ {
+ auto l_these_dimms( p.getChildren<fapi2::TARGET_TYPE_DIMM>(i_state) );
+ l_dimms.insert(l_dimms.end(), l_these_dimms.begin(), l_these_dimms.end());
+ }
+
+ return l_dimms;
+}
+
+///
+/// @brief find all the dimms connected to an MCBIST
+/// @param[in] i_target a fapi2::Target MCBIST
+/// @return a vector of fapi2::TARGET_TYPE_DIMM
+///
+template<>
+inline std::vector< fapi2::Target<fapi2::TARGET_TYPE_DIMM> >
+find_targets( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ fapi2::TargetState i_state )
+{
+ std::vector< fapi2::Target<fapi2::TARGET_TYPE_DIMM> > l_dimms;
+
+ for (const auto& p : i_target.getChildren<fapi2::TARGET_TYPE_MCA>(i_state))
+ {
+ auto l_these_dimms( p.getChildren<fapi2::TARGET_TYPE_DIMM>(i_state) );
+ l_dimms.insert(l_dimms.end(), l_these_dimms.begin(), l_these_dimms.end());
+ }
+
+ return l_dimms;
+}
+
+///
+/// @brief find the MCS given a DIMM
+/// @param[in] i_target the fapi2 target DIMM
+/// @return a MCS target.
+///
+template<>
+inline fapi2::Target<fapi2::TARGET_TYPE_MCS> find_target( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target)
+{
+ return i_target.getParent<fapi2::TARGET_TYPE_MCA>().getParent<fapi2::TARGET_TYPE_MCS>();
+}
+
+}// mss
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C
index cb9e22594..107cca50c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C
@@ -48,7 +48,7 @@
#include <lib/workarounds/adr32s_workarounds.H>
#include <lib/phy/ddr_phy.H>
#include <lib/phy/dcd.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_SYSTEM;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.C
index f6a8b3467..de136357f 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.C
@@ -34,13 +34,16 @@
// *HWP Consumed by: FSP:HB Memory Lab
#include <lib/shared/nimbus_defaults.H>
+#include <lib/shared/mss_const.H>
#include <lib/workarounds/ccs_workarounds.H>
#include <lib/dimm/rank.H>
#include <p9_mc_scom_addresses.H>
#include <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/pos.H>
#include <lib/eff_config/timing.H>
-#include <lib/ccs/ccs.H>
+#include <generic/memory/lib/ccs/ccs.H>
+#include <lib/mc/port.H>
+#include <lib/mc/mc.H>
namespace mss
{
@@ -105,7 +108,7 @@ fapi_try_exit:
///
fapi2::ReturnCode exit( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
- ccs::program<fapi2::TARGET_TYPE_MCBIST>& io_program )
+ ccs::program& io_program )
{
const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
// Issues A-side MRS
@@ -150,9 +153,9 @@ fapi_try_exit:
/// ccs program execution will be handled by OCC
///
fapi2::ReturnCode preload_ccs_for_epow( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- ccs::program<fapi2::TARGET_TYPE_MCBIST>& i_program)
+ ccs::program& i_program)
{
- typedef ccsTraits<fapi2::TARGET_TYPE_MCBIST> TT;
+ typedef ccsTraits<mss::mc_type::NIMBUS> TT;
// Subtract one for the idle we insert at the end
constexpr size_t CCS_INSTRUCTION_DEPTH = 32 - 1;
@@ -219,6 +222,66 @@ namespace nvdimm
{
///
+/// @brief add_refreshes() helper
+/// @param[in] i_target The MCA target where the program will be executed on
+/// @param[in,out] i_program the MCBIST ccs program to append the refreshes
+/// @return FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode add_refreshes_helper(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ mss::ccs::program& io_program)
+{
+ typedef ccsTraits<mss::mc_type::NIMBUS> TT;
+
+ uint16_t l_trefi = 0;
+
+ // 3 refreshes because the maximum number of instructions we can have is 28 for
+ // dual-rank NVDIMM (MRS)
+ constexpr size_t l_num_refreshes = 3;
+ constexpr uint64_t CS_N_ACTIVE = 0b00;
+
+ //get tREFI
+ FAPI_TRY(mss::eff_dram_trefi(i_target, l_trefi));
+
+ //load the refreshes into the program
+ for (size_t i = 0; i < l_num_refreshes; i++)
+ {
+ // We want to make sure the refresh hit all the ranks, so let's get the refresh command and change the chip select manually later
+ mss::ccs::instruction_t l_inst = mss::ccs::refresh_command(0, l_trefi);
+ l_inst.arr0.insertFromRight<TT::ARR0_DDR_CSN_0_1, TT::ARR0_DDR_CSN_0_1_LEN>(CS_N_ACTIVE);
+ l_inst.arr0.insertFromRight<TT::ARR0_DDR_CSN_2_3, TT::ARR0_DDR_CSN_2_3_LEN>(CS_N_ACTIVE);
+ l_inst.iv_update_rank = false;
+ io_program.iv_instructions.push_back(l_inst);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Adds refreshes at the beginning and end of the program
+/// @param[in] i_target The MCA target where the program will be executed on
+/// @param[in,out] io_program the MCBIST ccs program to add the refreshes
+/// @return FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode add_refreshes(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ mss::ccs::program& io_program)
+{
+ mss::ccs::program l_program;
+
+ // Add the refreshes at the beginning
+ FAPI_TRY(add_refreshes_helper(i_target, l_program));
+
+ // Append the instructions from io_program
+ l_program.iv_instructions.insert(l_program.iv_instructions.end(), io_program.iv_instructions.begin(),
+ io_program.iv_instructions.end());
+
+ io_program = l_program;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Execute the contents of the CCS array with ccs_addr_mux_sel control
/// @param[in] i_target The MCBIST containing the array
/// @param[in] i_program the MCBIST ccs program - to get the polling parameters
@@ -229,10 +292,10 @@ namespace nvdimm
/// CCS can properly drive the bus during the nvdimm post-restore sequence.
///
fapi2::ReturnCode execute_inst_array(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- mss::ccs::program<fapi2::TARGET_TYPE_MCBIST>& i_program,
+ mss::ccs::program& i_program,
const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_port)
{
- typedef ccsTraits<fapi2::TARGET_TYPE_MCBIST> TT;
+ typedef ccsTraits<mss::mc_type::NIMBUS> TT;
fapi2::buffer<uint64_t> status;
@@ -256,7 +319,7 @@ fapi2::ReturnCode execute_inst_array(const fapi2::Target<fapi2::TARGET_TYPE_MCBI
i_program.iv_probes);
// Check for done and success. DONE being the only bit set.
- if (status == STAT_QUERY_SUCCESS)
+ if (status == TT::STAT_QUERY_SUCCESS)
{
FAPI_INF("%s CCS Executed Successfully.", mss::c_str(i_port) );
goto fapi_try_exit;
@@ -280,105 +343,130 @@ fapi_try_exit:
/// @note This is a copy of execute() with minor tweaks to the namespace and single port only
///
fapi2::ReturnCode execute( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- mss::ccs::program<fapi2::TARGET_TYPE_MCBIST>& i_program,
+ mss::ccs::program& i_program,
const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_port)
{
- typedef ccsTraits<fapi2::TARGET_TYPE_MCBIST> TT;
+ typedef ccsTraits<mss::mc_type::NIMBUS> TT;
// Subtract one for the idle we insert at the end
constexpr size_t CCS_INSTRUCTION_DEPTH = 32 - 1;
constexpr uint64_t CCS_ARR0_ZERO = MCBIST_CCS_INST_ARR0_00;
constexpr uint64_t CCS_ARR1_ZERO = MCBIST_CCS_INST_ARR1_00;
+ mss::states l_str_state = mss::states::OFF;
+ fapi2::buffer<uint64_t> l_farb6q;
- mss::ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> l_des = ccs::des_command<fapi2::TARGET_TYPE_MCBIST>();
+ mss::ccs::instruction_t l_des = ccs::des_command();
FAPI_INF("loading ccs instructions (%d) for %s", i_program.iv_instructions.size(), mss::c_str(i_target));
- auto l_inst_iter = i_program.iv_instructions.begin();
+ //Check if we are in str. If we are not, throw some refreshes into the program
+ FAPI_TRY(mss::mc::read_farb6q(i_port, l_farb6q));
+ mss::mc::get_self_time_refresh_state(l_farb6q, l_str_state);
- // Stop the CCS engine just for giggles - it might be running ...
- FAPI_TRY( mss::ccs::start_stop(i_target, mss::states::STOP), "Error in ccs::execute" );
-
- FAPI_ASSERT( mss::poll(i_target, TT::STATQ_REG, poll_parameters(),
- [](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
+ if (l_str_state == mss::states::OFF)
{
- FAPI_INF("ccs statq (stop) 0x%llx, remaining: %d", stat_reg, poll_remaining);
- return stat_reg.getBit<TT::CCS_IN_PROGRESS>() != 1;
- }),
- fapi2::MSS_CCS_HUNG_TRYING_TO_STOP().set_MCBIST_TARGET(i_target) );
+ // Since we are executing the CCS program with data in the DRAMs, we need to be congnizant
+ // about the refreshes. Refresh from mc is fenced off when CCS has the bus, and by the time
+ // the control is given back to the mc, we would have violated 8*trefi refresh window.
+ // As such, let's start off each program with couple of refreshes so we don't violate the
+ // rolling 8*trefi window (verified on logic analyzer)
+ FAPI_TRY(add_refreshes(i_port, i_program));
+ }
- while (l_inst_iter != i_program.iv_instructions.end())
{
- size_t l_inst_count = 0;
+ auto l_inst_iter = i_program.iv_instructions.begin();
- uint64_t l_total_delay = 0;
- uint64_t l_delay = 0;
- uint64_t l_repeat = 0;
- uint8_t l_current_cke = 0;
+ std::vector<rank_configuration> l_rank_configs;
+ FAPI_TRY(get_rank_config(i_target, l_rank_configs));
- // Shove the instructions into the CCS engine, in 32 instruction chunks, and execute them
- for (; l_inst_iter != i_program.iv_instructions.end()
- && l_inst_count < CCS_INSTRUCTION_DEPTH; ++l_inst_count, ++l_inst_iter)
+ // Stop the CCS engine just for giggles - it might be running ...
+ FAPI_TRY( mss::ccs::start_stop(i_target, mss::states::STOP), "Error in ccs::execute" );
+
+ FAPI_ASSERT( mss::poll(i_target, TT::STATQ_REG, poll_parameters(),
+ [](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
{
- l_inst_iter->arr0.extractToRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(l_current_cke);
+ FAPI_INF("ccs statq (stop) 0x%llx, remaining: %d", stat_reg, poll_remaining);
+ return stat_reg.getBit<TT::CCS_IN_PROGRESS>() != 1;
+ }),
+ fapi2::MSS_CCS_HUNG_TRYING_TO_STOP().set_MCBIST_TARGET(i_target) );
- // Make sure this instruction leads to the next. Notice this limits this mechanism to pretty
- // simple (straight line) CCS programs. Anything with a loop or such will need another mechanism.
- l_inst_iter->arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_GOTO_CMD,
- MCBIST_CCS_INST_ARR1_00_GOTO_CMD_LEN>(l_inst_count + 1);
- FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_inst_iter->arr0), "Error in ccs::execute" );
- FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_inst_iter->arr1), "Error in ccs::execute" );
+ while (l_inst_iter != i_program.iv_instructions.end())
+ {
+ size_t l_inst_count = 0;
- // arr1 contains a specification of the delay and repeat after this instruction, as well
- // as a repeat. Total up the delays as we go so we know how long to wait before polling
- // the CCS engine for completion
- l_inst_iter->arr1.extractToRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(l_delay);
- l_inst_iter->arr1.extractToRight<MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT,
- MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT>(l_repeat);
+ uint64_t l_total_delay = 0;
+ uint64_t l_delay = 0;
+ uint64_t l_repeat = 0;
+ uint8_t l_current_cke = 0;
+ const auto l_port_index = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_port);
- l_total_delay += l_delay * (l_repeat + 1);
+ // Shove the instructions into the CCS engine, in 32 instruction chunks, and execute them
+ for (; l_inst_iter != i_program.iv_instructions.end()
+ && l_inst_count < CCS_INSTRUCTION_DEPTH; ++l_inst_count, ++l_inst_iter)
+ {
+ // First, update the current instruction's chip selects for the current port
+ FAPI_TRY(l_inst_iter->configure_rank(i_port, l_rank_configs[l_port_index]), "Error in rank config");
- FAPI_INF("css inst %d: 0x%016lX 0x%016lX (0x%lx, 0x%lx) delay: 0x%x (0x%x) %s",
- l_inst_count, l_inst_iter->arr0, l_inst_iter->arr1,
- CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count,
- l_delay, l_total_delay, mss::c_str(i_target));
- }
+ l_inst_iter->arr0.extractToRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(l_current_cke);
- // Check our program for any delays. If there isn't a iv_initial_delay configured, then
- // we use the delay we just summed from the instructions.
- if (i_program.iv_poll.iv_initial_delay == 0)
- {
- i_program.iv_poll.iv_initial_delay = cycles_to_ns(i_target, l_total_delay);
- }
+ // Make sure this instruction leads to the next. Notice this limits this mechanism to pretty
+ // simple (straight line) CCS programs. Anything with a loop or such will need another mechanism.
+ l_inst_iter->arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_GOTO_CMD,
+ MCBIST_CCS_INST_ARR1_00_GOTO_CMD_LEN>(l_inst_count + 1);
+ FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_inst_iter->arr0), "Error in ccs::execute" );
+ FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_inst_iter->arr1), "Error in ccs::execute" );
+
+ // arr1 contains a specification of the delay and repeat after this instruction, as well
+ // as a repeat. Total up the delays as we go so we know how long to wait before polling
+ // the CCS engine for completion
+ l_inst_iter->arr1.extractToRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(l_delay);
+ l_inst_iter->arr1.extractToRight<MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT,
+ MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT>(l_repeat);
+
+ l_total_delay += l_delay * (l_repeat + 1);
+
+ FAPI_INF("css inst %d: 0x%016lX 0x%016lX (0x%lx, 0x%lx) delay: 0x%x (0x%x) %s",
+ l_inst_count, l_inst_iter->arr0, l_inst_iter->arr1,
+ CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count,
+ l_delay, l_total_delay, mss::c_str(i_target));
+ }
- if (i_program.iv_poll.iv_initial_sim_delay == 0)
- {
- i_program.iv_poll.iv_initial_sim_delay = cycles_to_simcycles(l_total_delay);
- }
+ // Check our program for any delays. If there isn't a iv_initial_delay configured, then
+ // we use the delay we just summed from the instructions.
+ if (i_program.iv_poll.iv_initial_delay == 0)
+ {
+ i_program.iv_poll.iv_initial_delay = cycles_to_ns(i_target, l_total_delay);
+ }
- FAPI_INF("executing ccs instructions (%d:%d, %d) for %s",
- i_program.iv_instructions.size(), l_inst_count, i_program.iv_poll.iv_initial_delay, mss::c_str(i_target));
-
- // Deselect
- l_des.arr0.insertFromRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(l_current_cke);
-
- // Insert a DES as our last instruction. DES is idle state anyway and having this
- // here as an instruction forces the CCS engine to wait the delay specified in
- // the last instruction in this array (which it otherwise doesn't do.)
- l_des.arr1.setBit<MCBIST_CCS_INST_ARR1_00_END>();
- FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_des.arr0), "Error in ccs::execute" );
- FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_des.arr1), "Error in ccs::execute" );
-
- FAPI_INF("css inst %d fixup: 0x%016lX 0x%016lX (0x%lx, 0x%lx) %s",
- l_inst_count, l_des.arr0, l_des.arr1,
- CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count, mss::c_str(i_target));
-
- // Kick off the CCS engine - per port. No broadcast mode for CCS (per Shelton 9/23/15)
- FAPI_INF("executing CCS array for port %d (%s)", mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_port),
- mss::c_str(i_port));
- FAPI_TRY( mss::ccs::select_ports( i_target, mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_port)),
- "Error in ccs execute" );
- FAPI_TRY( execute_inst_array(i_target, i_program, i_port), "Error in ccs execute" );
+ if (i_program.iv_poll.iv_initial_sim_delay == 0)
+ {
+ i_program.iv_poll.iv_initial_sim_delay = cycles_to_simcycles(l_total_delay);
+ }
+
+ FAPI_INF("executing ccs instructions (%d:%d, %d) for %s",
+ i_program.iv_instructions.size(), l_inst_count, i_program.iv_poll.iv_initial_delay, mss::c_str(i_target));
+
+ // Deselect
+ l_des.arr0.insertFromRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(l_current_cke);
+
+ // Insert a DES as our last instruction. DES is idle state anyway and having this
+ // here as an instruction forces the CCS engine to wait the delay specified in
+ // the last instruction in this array (which it otherwise doesn't do.)
+ l_des.arr1.setBit<MCBIST_CCS_INST_ARR1_00_END>();
+ FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_des.arr0), "Error in ccs::execute" );
+ FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_des.arr1), "Error in ccs::execute" );
+
+ FAPI_INF("css inst %d fixup: 0x%016lX 0x%016lX (0x%lx, 0x%lx) %s",
+ l_inst_count, l_des.arr0, l_des.arr1,
+ CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count, mss::c_str(i_target));
+
+ // Kick off the CCS engine - per port. No broadcast mode for CCS (per Shelton 9/23/15)
+ FAPI_INF("executing CCS array for port %d (%s)", mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_port),
+ mss::c_str(i_port));
+ FAPI_TRY( mss::ccs::select_ports<mss::mc_type::NIMBUS>( i_target, mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(i_port)),
+ "Error in ccs execute" );
+ FAPI_TRY( execute_inst_array(i_target, i_program, i_port), "Error in ccs execute" );
+ }
}
fapi_try_exit:
@@ -413,7 +501,7 @@ void update_mrs(mss::ddr4::mrs01_data& io_mrs, const mss::states i_state)
fapi2::ReturnCode add_mrs(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const uint64_t i_rank,
const mss::states& i_state,
- std::vector<ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>>& io_inst)
+ std::vector<ccs::instruction_t>& io_inst)
{
// First, get the DIMM target
// Note: the target is setup below based upon the rank
@@ -555,7 +643,7 @@ fapi2::ReturnCode configure_non_calibrating_ranks(const fapi2::Target<fapi2::TAR
const mss::states& i_state)
{
// Declares variables
- mss::ccs::program<fapi2::TARGET_TYPE_MCBIST, fapi2::TARGET_TYPE_MCA> l_program;
+ ccs::program l_program;
std::vector<uint64_t> l_ranks;
const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.H
index 067f8481f..5cb57295b 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/ccs_workarounds.H
@@ -38,12 +38,15 @@
#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
+#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/ccs/ccs.H>
+#include <lib/utils/nimbus_find.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>
+
namespace mss
{
@@ -66,7 +69,7 @@ namespace workarounds
///
fapi2::ReturnCode exit( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
- ccs::program<fapi2::TARGET_TYPE_MCBIST>& io_program );
+ ccs::program& io_program );
///
/// @brief Re-enables PDA mode on a given rank in the shadow registers
@@ -83,7 +86,7 @@ fapi2::ReturnCode enable_pda_shadow_reg( const fapi2::Target<fapi2::TARGET_TYPE_
/// @param[in,out] io_inst - the CCS instruction
///
inline void hold_cke_low_helper( fapi2::buffer<uint8_t>& io_cke,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst )
+ ccs::instruction_t& io_inst )
{
fapi2::buffer<uint8_t> l_cur_cke;
io_inst.arr0.extractToRight<MCBIST_CCS_INST_ARR0_00_DDR_CKE, MCBIST_CCS_INST_ARR0_00_DDR_CKE_LEN>(l_cur_cke);
@@ -95,7 +98,7 @@ inline void hold_cke_low_helper( fapi2::buffer<uint8_t>& io_cke,
/// @brief Holds the lower order rank cke low in higher order rank instruction
/// @param[in,out] io_program - CCS program with instructions on multi-rank DIMM
///
-inline void hold_cke_low( ccs::program<fapi2::TARGET_TYPE_MCBIST>& io_program )
+inline void hold_cke_low( ccs::program& io_program )
{
fapi2::buffer<uint8_t> l_cke(CKE_HIGH);
@@ -111,7 +114,7 @@ inline void hold_cke_low( ccs::program<fapi2::TARGET_TYPE_MCBIST>& io_program )
/// @param[in,out] io_inst - the CCS instruction
///
inline void hold_cke_high_helper( fapi2::buffer<uint8_t>& io_cke,
- ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst )
+ ccs::instruction_t& io_inst )
{
fapi2::buffer<uint8_t> l_cur_cke;
io_inst.arr0.extractToRight<MCBIST_CCS_INST_ARR0_00_DDR_CKE, MCBIST_CCS_INST_ARR0_00_DDR_CKE_LEN>(l_cur_cke);
@@ -123,7 +126,7 @@ inline void hold_cke_high_helper( fapi2::buffer<uint8_t>& io_cke,
/// @brief Holds the lower order rank cke high in higher order rank instruction
/// @param[in,out] io_inst - CCS program with instructions on multi-rank DIMM
///
-inline void hold_cke_high( std::vector<ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>>& io_inst )
+inline void hold_cke_high( std::vector<ccs::instruction_t>& io_inst )
{
fapi2::buffer<uint8_t> l_cke(CKE_LOW);
@@ -137,7 +140,7 @@ inline void hold_cke_high( std::vector<ccs::instruction_t<fapi2::TARGET_TYPE_MCB
/// @brief Holds the lower order rank cke high in higher order rank instruction
/// @param[in,out] io_program - CCS program with instructions on multi-rank DIMM
///
-inline void hold_cke_high( ccs::program<fapi2::TARGET_TYPE_MCBIST>& io_program )
+inline void hold_cke_high( ccs::program& io_program )
{
fapi2::buffer<uint8_t> l_cke(CKE_LOW);
@@ -155,12 +158,30 @@ inline void hold_cke_high( ccs::program<fapi2::TARGET_TYPE_MCBIST>& io_program )
/// @note This is written specifically to support EPOW on NVDIMM
///
fapi2::ReturnCode preload_ccs_for_epow( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- ccs::program<fapi2::TARGET_TYPE_MCBIST>& i_program);
+ ccs::program& i_program);
namespace nvdimm
{
///
+/// @brief add_refreshes() helper
+/// @param[in] i_target The MCA target where the program will be executed on
+/// @param[in,out] i_program the MCBIST ccs program to append the refreshes
+/// @return FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode add_refreshes_helper(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ mss::ccs::program& io_program);
+
+///
+/// @brief Adds refreshes at the beginning and end of the program
+/// @param[in] i_target The MCA target where the program will be executed on
+/// @param[in,out] io_program the MCBIST ccs program to add the refreshes
+/// @return FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode add_refreshes(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ mss::ccs::program& io_program);
+
+///
/// @brief Execute a set of CCS instructions
/// @param[in] i_target the target to effect
/// @param[in] i_program the vector of instructions
@@ -169,7 +190,7 @@ namespace nvdimm
/// @note This is a copy of execute() with minor tweaks to the namespace and single port only
///
fapi2::ReturnCode execute( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- mss::ccs::program<fapi2::TARGET_TYPE_MCBIST>& i_program,
+ mss::ccs::program& i_program,
const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_port);
///
@@ -183,7 +204,7 @@ fapi2::ReturnCode execute( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_tar
/// CCS can properly drive the bus during the nvdimm post-restore sequence.
///
fapi2::ReturnCode execute_inst_array(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- mss::ccs::program<fapi2::TARGET_TYPE_MCBIST>& i_program,
+ mss::ccs::program& i_program,
fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_port);
}
@@ -208,7 +229,7 @@ void update_mrs(mss::ddr4::mrs01_data& io_mrs, const mss::states i_state);
fapi2::ReturnCode add_mrs(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const uint64_t i_rank,
const mss::states& i_state,
- std::vector<ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>>& io_inst);
+ std::vector<ccs::instruction_t>& io_inst);
///
/// @brief Gets a vector of ranks that are not going to be calibrated in the given rank pair
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dll_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dll_workarounds.C
index 4e73323f2..584dc36c8 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dll_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dll_workarounds.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,7 +33,7 @@
#include <fapi2.H>
#include <lib/workarounds/dll_workarounds.H>
#include <lib/fir/check.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <generic/memory/lib/utils/scom.H>
#include <lib/phy/dp16.H>
#include <lib/fir/fir.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C
index 798447c83..f9e3b08d7 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C
@@ -59,6 +59,79 @@ namespace mss
namespace workarounds
{
+// Putting the NVDIMM workarounds here as it's a bit of a hybrid case
+// Also there are issues as the nvdimm_workarounds.* files are picked up externally
+namespace nvdimm
+{
+
+///
+/// @brief Checks if the NVDIMM RD DQ delay adjust is needed
+/// @param[in] i_target the fapi2 target of the port
+/// @param[out] o_is_needed true if the workaround is needed
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+fapi2::ReturnCode is_adjust_rd_dq_delay_needed( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ bool& o_is_needed )
+{
+ uint8_t l_hybrid_type[mss::MAX_DIMM_PER_PORT] = {};
+ uint8_t l_is_hybrid[mss::MAX_DIMM_PER_PORT] = {};
+ o_is_needed = false;
+
+ FAPI_TRY(mss::eff_hybrid_memory_type(i_target, l_hybrid_type));
+ FAPI_TRY(mss::eff_hybrid(i_target, l_is_hybrid));
+
+ // This workaround is only needed if we're dealing with NVDIMM
+ // We only need DIMM0 as NVDIMM will only ever be single drop
+ o_is_needed = (l_hybrid_type[0] == fapi2::ENUM_ATTR_EFF_HYBRID_IS_HYBRID) &&
+ (l_is_hybrid[0] == fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NVDIMM);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Adjusts NVDIMM RD DQ delays
+/// @param[in] i_target the fapi2 target of the port
+/// @param[in] i_rp the rank pair on which to adjust delays
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+fapi2::ReturnCode adjust_rd_dq_delay( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_rp )
+{
+ // Constexpr's for some general beautification
+ constexpr uint64_t VALUE0_START = MCA_DDRPHY_DP16_READ_DELAY0_RANK_PAIR0_P0_0_01_RD;
+ constexpr uint64_t VALUE1_START = MCA_DDRPHY_DP16_READ_DELAY0_RANK_PAIR0_P0_0_01_RD_DELAY1;
+ typedef mss::dp16Traits<fapi2::TARGET_TYPE_MCA> TT;
+
+ bool l_is_needed = false;
+ std::vector<fapi2::buffer<uint64_t>> l_data;
+ FAPI_TRY(is_adjust_rd_dq_delay_needed(i_target, l_is_needed));
+
+ // If the adjust is not needed, exit out
+ if(!l_is_needed)
+ {
+ FAPI_INF("%s RD DQ delay adjust isn't needed. Skipping the workaround", mss::c_str(i_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Read
+ FAPI_TRY(mss::scom_suckah(i_target, TT::READ_DELAY_REG[i_rp], l_data));
+
+ // Modify
+ for(auto& l_info : l_data)
+ {
+ update_rd_dq_delay<VALUE0_START>(l_info);
+ update_rd_dq_delay<VALUE1_START>(l_info);
+ }
+
+ // Write
+ FAPI_TRY(mss::scom_blastah(i_target, TT::READ_DELAY_REG[i_rp], l_data));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // close namespace nvdimm
+
namespace dp16
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H
index daf9780d6..ddee4f42a 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -52,6 +52,48 @@ namespace mss
namespace workarounds
{
+// Putting the NVDIMM workarounds here as it's a bit of a hybrid case
+// Also there are issues as the nvdimm_workarounds.* files are picked up externally
+namespace nvdimm
+{
+
+///
+/// @brief Updates a single RD DQ value for the NVDIMM workaround
+/// @tparam P the bit position to update
+/// @param[in,out] io_data the data bufffer to update
+///
+template<uint64_t P>
+void update_rd_dq_delay(fapi2::buffer<uint64_t>& io_data)
+{
+ constexpr uint64_t MAX_VALUE = 0x7f;
+ constexpr uint64_t OFFSET = 2;
+ constexpr uint64_t LEN = MCA_DDRPHY_DP16_READ_DELAY0_RANK_PAIR0_P0_0_01_RD_LEN;
+ uint64_t l_value = 0;
+ io_data.extractToRight<P, LEN>(l_value);
+ l_value += OFFSET;
+ l_value = std::min(l_value, MAX_VALUE);
+ io_data.insertFromRight<P, LEN>(l_value);
+}
+
+///
+/// @brief Checks if the NVDIMM RD DQ delay adjust is needed
+/// @param[in] i_target the fapi2 target of the port
+/// @param[out] o_is_needed true if the workaround is needed
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+fapi2::ReturnCode is_adjust_rd_dq_delay_needed( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ bool& o_is_needed );
+
+///
+/// @brief Adjusts NVDIMM RD DQ delays
+/// @param[in] i_target the fapi2 target of the port
+/// @param[in] i_rp the rank pair on which to adjust delays
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+fapi2::ReturnCode adjust_rd_dq_delay( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_rp );
+
+} // close namespace nvdimm
+
namespace dp16
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/draminit_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/draminit_workarounds.C
index a0a375f2b..dd5275288 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/draminit_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/draminit_workarounds.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -55,7 +55,7 @@ namespace workarounds
///
fapi2::ReturnCode rcw_reset_dram( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const bool i_sim,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
+ std::vector< ccs::instruction_t >& io_inst)
{
// Note: we're always going to run this guy
FAPI_INF("%s running the DRAM RCW DRAM reset workaround", mss::c_str(i_target));
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/draminit_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/draminit_workarounds.H
index 1b43c1416..437065578 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/draminit_workarounds.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/draminit_workarounds.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -53,7 +53,7 @@ namespace workarounds
///
fapi2::ReturnCode rcw_reset_dram( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const bool i_sim,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+ std::vector< ccs::instruction_t >& io_inst);
} // namespace workarounds
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.C
new file mode 100644
index 000000000..dae18167b
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.C
@@ -0,0 +1,94 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+
+#include <fapi2.H>
+#include <lib/mss_attribute_accessors.H>
+#include <lib/workarounds/eff_config_workarounds.H>
+
+namespace mss
+{
+
+namespace workarounds
+{
+
+namespace eff_config
+{
+
+///
+/// @brief Checks if the NVDIMM RC drive strength workaround is needed
+/// @param[in] i_target DIMM target on which to operate
+/// @param[out] o_is_needed true if the workaround is needed
+/// @return SUCCESS if the code executes successfully
+///
+fapi2::ReturnCode is_nvdimm_rc_drive_strength_needed(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ bool& o_is_needed)
+{
+ o_is_needed = false;
+
+ uint8_t l_hybrid = 0;
+ uint8_t l_hybrid_type = 0;
+ uint32_t l_size = 0;
+
+ FAPI_TRY(mss::eff_hybrid(i_target, l_hybrid));
+ FAPI_TRY(mss::eff_hybrid_memory_type(i_target, l_hybrid_type));
+ FAPI_TRY(mss::eff_dimm_size(i_target, l_size));
+
+ if(l_hybrid == fapi2::ENUM_ATTR_EFF_HYBRID_IS_HYBRID &&
+ l_hybrid_type == fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NVDIMM &&
+ l_size == fapi2::ENUM_ATTR_EFF_DIMM_SIZE_32GB)
+ {
+ o_is_needed = true;
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Updates the RC drive strength if the workaround is needed
+/// @param[in] i_target DIMM target on which to operate
+/// @param[in] i_override_value the value to override if the workaround needs to be applied
+/// @param[in,out] io_rc_value Register Control word value to update
+/// @return SUCCESS if the code executes successfully
+///
+fapi2::ReturnCode nvdimm_rc_drive_strength(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint8_t i_override_value,
+ fapi2::buffer<uint8_t>& io_rc_value)
+{
+ bool l_is_needed = false;
+ FAPI_TRY(is_nvdimm_rc_drive_strength_needed(i_target, l_is_needed));
+
+ // If the workaround is needed, overwrite it to be ALL_MODERATE values
+ // Otherwise keep it as it is
+ io_rc_value = l_is_needed ? fapi2::buffer<uint8_t>(i_override_value) : io_rc_value;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // ns eff_config
+} // ns workarounds
+} // ns mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.H
index de58c465c..f41d9b89c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ecc/ecc_traits.C $ */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/workarounds/eff_config_workarounds.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -24,45 +24,52 @@
/* IBM_PROLOG_END_TAG */
///
-/// @file ecc_traits.C
-/// @brief Traits class for the MC ECC syndrome registers
+/// @file eff_config_workarounds.H
+/// @brief Workarounds for effective config
+/// Workarounds are very device specific, so there is no attempt to generalize
+/// this code in any way.
///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
+#ifndef _EFF_CONFIG_WORKAROUNDS_H_
+#define _EFF_CONFIG_WORKAROUNDS_H_
+
#include <fapi2.H>
-#include <lib/ecc/ecc_traits.H>
namespace mss
{
-// we need these declarations here in order for the linker to see the definitions
-// in the eccTraits class
-constexpr const uint64_t eccTraits<fapi2::TARGET_TYPE_MCA>::MAINLINE_NCE_REGS[];
-constexpr const uint64_t eccTraits<fapi2::TARGET_TYPE_MCA>::MAINLINE_RCE_REGS[];
-constexpr const uint64_t eccTraits<fapi2::TARGET_TYPE_MCA>::MAINLINE_MPE_REGS[];
-constexpr const uint64_t eccTraits<fapi2::TARGET_TYPE_MCA>::MAINLINE_UE_REGS[];
-constexpr const uint64_t eccTraits<fapi2::TARGET_TYPE_MCA>::MAINLINE_AUE_REGS[];
-constexpr const uint64_t eccTraits<fapi2::TARGET_TYPE_MCA>::ERROR_VECTOR_REGS[];
-
-constexpr const uint8_t eccTraits<fapi2::TARGET_TYPE_MCA>::symbol2galois[];
-constexpr const uint8_t eccTraits<fapi2::TARGET_TYPE_MCA>::symbol2dq[];
+namespace workarounds
+{
-// Definition of the symbol error count registers
-const std::vector< uint64_t > eccTraits<fapi2::TARGET_TYPE_MCBIST>::SYMBOL_COUNT_REG =
+namespace eff_config
{
- MCBIST_MBSSYMEC0Q,
- MCBIST_MBSSYMEC1Q,
- MCBIST_MBSSYMEC2Q,
- MCBIST_MBSSYMEC3Q,
- MCBIST_MBSSYMEC4Q,
- MCBIST_MBSSYMEC5Q,
- MCBIST_MBSSYMEC6Q,
- MCBIST_MBSSYMEC7Q,
- MCBIST_MBSSYMEC8Q,
-};
-} // close namespace mss
+///
+/// @brief Checks if the NVDIMM RC drive strength workaround is needed
+/// @param[in] i_target DIMM target on which to operate
+/// @param[out] o_is_needed true if the workaround is needed
+/// @return SUCCESS if the code executes successfully
+///
+fapi2::ReturnCode is_nvdimm_rc_drive_strength_needed(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ bool& o_is_needed);
+
+///
+/// @brief Updates the RC drive strength if the workaround is needed
+/// @param[in] i_target DIMM target on which to operate
+/// @param[in] i_override_value the value to override if the workaround needs to be applied
+/// @param[in,out] io_rc_value Register Control word value to update
+/// @return SUCCESS if the code executes successfully
+///
+fapi2::ReturnCode nvdimm_rc_drive_strength(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint8_t i_override_value,
+ fapi2::buffer<uint8_t>& io_rc_value);
+
+} // ns eff_config
+} // ns workarounds
+} // ns mss
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.C
index d9e8f6416..164fbe580 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mca_workarounds.C
@@ -66,6 +66,17 @@ bool check_str_non_tsv_parity_workaround(const fapi2::Target<fapi2::TARGET_TYPE_
bool l_tsv = false;
bool l_str_enabled = false;
bool l_is_nvdimm = false;
+ bool l_has_4r_dimm = false;
+ uint8_t l_master_ranks[MAX_DIMM_PER_PORT] = {};
+
+ FAPI_TRY(eff_num_master_ranks_per_dimm(i_target, l_master_ranks));
+
+ // If we have either DIMM having four ranks, we need to disable parity mode
+ if((l_master_ranks[0] == fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R) ||
+ (l_master_ranks[1] == fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R))
+ {
+ l_has_4r_dimm = true;
+ }
// Figure out if any hybrid memory is plugged
FAPI_TRY(mss::eff_hybrid(i_target, l_hybrid));
@@ -101,11 +112,13 @@ bool check_str_non_tsv_parity_workaround(const fapi2::Target<fapi2::TARGET_TYPE_
// 1) greater than or equal to DD2
// 2) self time refresh is enabled
// 3) the DIMM's are not TSV
- FAPI_INF("%s %s DD2 STR: %s DIMM %s TSV", mss::c_str(i_target),
+ // 4) a 4R DIMM is present
+ FAPI_INF("%s %s DD2 STR: %s DIMM %s TSV %s DIMM", mss::c_str(i_target),
l_less_than_dd2 ? "less than" : "greater than or equal to",
l_str_enabled ? "enabled" : "disabled",
- l_tsv ? "is" : "isn't");
- return (!l_less_than_dd2) && l_str_enabled && (!l_tsv);
+ l_tsv ? "is" : "isn't",
+ l_has_4r_dimm ? "4R" : "not 4R");
+ return ((!l_less_than_dd2) && l_str_enabled && (!l_tsv)) || (l_has_4r_dimm);
fapi_try_exit:
FAPI_ERR("failed calling check_str_non_tsv_parity_workaround: 0x%lx (target: %s)",
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C
index 9316abaa5..f87d01078 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C
@@ -43,7 +43,7 @@
#include <lib/mss_attribute_accessors.H>
#include <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/pos.H>
-#include <lib/dimm/kind.H>
+#include <lib/dimm/nimbus_kind.H>
#include <lib/workarounds/mcbist_workarounds.H>
#include <lib/mcbist/mcbist.H>
#include <lib/fir/fir.H>
@@ -66,9 +66,9 @@ namespace mcbist
/// @param[in,out] the MCBIST program to check for read/display replacement
/// @note Useful for testing
///
-void replace_read_helper(mss::mcbist::program<TARGET_TYPE_MCBIST>& io_program)
+void replace_read_helper(mss::mcbist::program<>& io_program)
{
- using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>;
+ using TT = mss::mcbistTraits<>;
io_program.change_maint_broadcast_mode(mss::OFF);
io_program.change_end_boundary(mss::mcbist::end_boundary::STOP_AFTER_ADDRESS);
@@ -99,9 +99,9 @@ void replace_read_helper(mss::mcbist::program<TARGET_TYPE_MCBIST>& io_program)
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
///
fapi2::ReturnCode end_of_rank( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- mss::mcbist::program<TARGET_TYPE_MCBIST>& io_program )
+ mss::mcbist::program<>& io_program )
{
- using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>;
+ using TT = mss::mcbistTraits<>;
// If we don't need the mcbist work-around, we're done.
if (! mss::chip_ec_feature_mcbist_end_of_rank(i_target) )
@@ -110,8 +110,9 @@ fapi2::ReturnCode end_of_rank( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target
}
// First things first - lets find out if we have an 1R DIMM on our side of the chip.
- const auto l_dimm_kinds = dimm::kind::vector( mss::find_targets<TARGET_TYPE_DIMM>(i_target) );
- const auto l_kind = std::find_if(l_dimm_kinds.begin(), l_dimm_kinds.end(), [](const dimm::kind & k) -> bool
+ const auto l_dimm_kinds = dimm::kind<>::vector( mss::find_targets<TARGET_TYPE_DIMM>(i_target) );
+ const auto l_kind = std::find_if(l_dimm_kinds.begin(),
+ l_dimm_kinds.end(), [](const dimm::kind<>& k) -> bool
{
// If total ranks are 1, we have a 1R DIMM, SDP. This is the fellow of concern
return k.iv_total_ranks == 1;
@@ -146,26 +147,6 @@ fapi2::ReturnCode end_of_rank( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target
}
///
-/// @brief WAT debug attention
-/// For Nimbus DD1 the MCBIST engine uses the WAT debug bit as a workaround
-/// For Nimbus DD2 the WAT debug bit is used for a different workaround
-/// @param[in] i_target the fapi2 target of the mcbist
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-fapi2::ReturnCode wat_debug_attention( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target )
-{
- // MCBIST attentions are already special attention
- fapi2::ReturnCode l_rc;
- fir::reg<MCBIST_MCBISTFIRQ> mcbist_fir_register(i_target, l_rc);
- FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCBIST_MCBISTFIRQ);
-
- FAPI_TRY(mcbist_fir_register.attention<MCBIST_MCBISTFIRQ_WAT_DEBUG_ATTN>().write());
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief BROADCAST OUT OF SYNC workaround
/// A UE noise window is triggered by UE/AUEs causing an out of sync error
/// @param[in] i_target the fapi2 target of the mcbist
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H
index 1e5d9662a..7a4533c6d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -55,7 +55,7 @@ namespace mcbist
/// @param[in] the MCBIST program to check for read/display replacement
/// @note Useful for testing
///
-void replace_read_helper(mss::mcbist::program<fapi2::TARGET_TYPE_MCBIST>& i_program);
+void replace_read_helper(mss::mcbist::program<>& i_program);
///
/// @brief End of rank work around
@@ -69,15 +69,7 @@ void replace_read_helper(mss::mcbist::program<fapi2::TARGET_TYPE_MCBIST>& i_prog
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
///
fapi2::ReturnCode end_of_rank( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- mss::mcbist::program<fapi2::TARGET_TYPE_MCBIST>& i_program );
-
-///
-/// @brief WAT debug attention
-/// For Nimbus DD1 the MCBIST engine uses the WAT debug bit as a workaround
-/// @param[in] i_target the fapi2 target of the mcbist
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
-///
-fapi2::ReturnCode wat_debug_attention( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target );
+ mss::mcbist::program<>& i_program );
///
/// @brief BROADCAST OUT OF SYNC workaround
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/nvdimm_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/nvdimm_workarounds.C
index 86e2cce75..f5942b528 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/nvdimm_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/nvdimm_workarounds.C
@@ -48,33 +48,8 @@ namespace workarounds
namespace nvdimm
{
-// MBASTR0Q for each MCA
// Note: Since the scoms are executed at the chip, it needs the dedicated
// address for each MCA
-constexpr const uint64_t MBASTR0Q_REG[] =
-{
- MCA_0_MBASTR0Q,
- MCA_1_MBASTR0Q,
- MCA_2_MBASTR0Q,
- MCA_3_MBASTR0Q,
- MCA_4_MBASTR0Q,
- MCA_5_MBASTR0Q,
- MCA_6_MBASTR0Q,
- MCA_7_MBASTR0Q,
-};
-
-// MBARPC0Q for each MCA
-constexpr const uint64_t MBARPC0Q_REG[] =
-{
- MCA_0_MBARPC0Q,
- MCA_1_MBARPC0Q,
- MCA_2_MBARPC0Q,
- MCA_3_MBARPC0Q,
- MCA_4_MBARPC0Q,
- MCA_5_MBARPC0Q,
- MCA_6_MBARPC0Q,
- MCA_7_MBARPC0Q,
-};
// FARB5Q for each MCA
constexpr const uint64_t FARB5Q_REG[] =
@@ -89,6 +64,15 @@ constexpr const uint64_t FARB5Q_REG[] =
MCA_7_MBA_FARB5Q,
};
+// MCFGP for each MCS
+constexpr const uint64_t MCFGP[] =
+{
+ MCS_0_MCFGP,
+ MCS_1_MCFGP,
+ MCS_2_MCFGP,
+ MCS_3_MCFGP,
+};
+
// MCB_CNTLQ
constexpr const uint64_t MCB_CNTLQ_REG[] =
{
@@ -96,89 +80,159 @@ constexpr const uint64_t MCB_CNTLQ_REG[] =
MCBIST_1_MCB_CNTLQ,
};
+// MCB_MCBAGRAQ
+constexpr const uint64_t MCB_MCBAGRAQ_REG[] =
+{
+ MCBIST_0_MCBAGRAQ,
+ MCBIST_1_MCBAGRAQ,
+};
+
+// CCS_MODEQ
+constexpr const uint64_t CCS_MODEQ_REG[] =
+{
+ MCBIST_0_CCS_MODEQ,
+ MCBIST_1_CCS_MODEQ,
+};
+
+// CCS_CNTLQ
+constexpr const uint64_t CCS_CNTLQ_REG[] =
+{
+ MCBIST_0_CCS_CNTLQ,
+ MCBIST_1_CCS_CNTLQ,
+};
+
constexpr uint8_t PORTS_PER_MODULE = 8;
+constexpr uint8_t PORTS_PER_MCBIST = 4;
+constexpr uint8_t MCBISTS_PER_PROC = 2;
///
-/// @brief Helper for trigger_csave. This subroutine puts the MCA into STR
-/// This is the same thing as mss::nvdimm::self_refresh_entry() but rewritten
-/// to support SBE
+/// @brief Program the necessary scom regs to prepare for CSAVE
/// @param[in] i_target - PROC_CHIP target
-/// @param[in] l_mca_pos - The MCA position relative to the PROC
+/// @param[in] i_mcbist - mcbist position relative to the proc
+/// @param[out] o_addresses - list of addresses that require restore
+/// @param[out] o_data - data to restore to o_addresses
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
-fapi2::ReturnCode self_refresh_entry( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
- const uint8_t l_mca_pos)
+fapi2::ReturnCode prep_for_csave( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
+ const uint8_t i_mcbist,
+ std::vector<uint64_t>& o_addresses,
+ std::vector<fapi2::buffer<uint64_t>>& o_data)
{
- FAPI_ASSERT((l_mca_pos < PORTS_PER_MODULE),
- fapi2::MSS_SRE_MCA_OUT_OF_RANGE().
- set_PROC_TARGET(i_target).
- set_MCA_POS(l_mca_pos),
- "Invalid port number %u provided", l_mca_pos);
+ fapi2::buffer<uint64_t> l_mcbcntlq_data;
+ fapi2::buffer<uint64_t> l_mcbagraq_data;
+ fapi2::buffer<uint64_t> l_ccs_modeq_data;
- FAPI_DBG("Entering STR on port %u.", l_mca_pos);
+ // Stop mcbist first otherwise it can kick the DIMM out of STR
+ FAPI_TRY(fapi2::getScom(i_target, MCB_CNTLQ_REG[i_mcbist], l_mcbcntlq_data));
+ l_mcbcntlq_data.setBit<MCBIST_CCS_CNTLQ_STOP>();
+ FAPI_TRY(fapi2::putScom(i_target, MCB_CNTLQ_REG[i_mcbist], l_mcbcntlq_data));
- {
- fapi2::buffer<uint64_t> l_mbarpc0_data, l_mbastr0_data, l_mcbcntlq_data;
- constexpr uint64_t ENABLE = 1;
- constexpr uint64_t DISABLE = 0;
- constexpr uint64_t MAXALL_MIN0 = 0b010;
- constexpr uint64_t STOP = 1;
- constexpr uint64_t PORTS_PER_MCBIST = 4;
- constexpr uint64_t TIME_0 = 0;
- const uint8_t l_mcbist = l_mca_pos < PORTS_PER_MCBIST ? 0 : 1;
-
- // Stop mcbist first otherwise it can kick the DIMM out of STR
- FAPI_TRY(fapi2::getScom(i_target, MCB_CNTLQ_REG[l_mcbist], l_mcbcntlq_data));
- l_mcbcntlq_data.writeBit<MCBIST_CCS_CNTLQ_STOP>(STOP);
- FAPI_TRY(fapi2::putScom(i_target, MCB_CNTLQ_REG[l_mcbist], l_mcbcntlq_data));
-
- // Step 1 - In MBARPC0Q, disable power domain control, set domain to MAXALL_MIN0,
- // and disable minimum domain reduction (allow immediate entry of STR)
- FAPI_TRY(fapi2::getScom(i_target, MBARPC0Q_REG[l_mca_pos], l_mbarpc0_data));
- l_mbarpc0_data.writeBit<MCA_MBARPC0Q_CFG_MIN_MAX_DOMAINS_ENABLE>(DISABLE);
- l_mbarpc0_data.insertFromRight<MCA_MBARPC0Q_CFG_MIN_MAX_DOMAINS, MCA_MBARPC0Q_CFG_MIN_MAX_DOMAINS_LEN>(MAXALL_MIN0);
- l_mbarpc0_data.writeBit<MCA_MBARPC0Q_CFG_MIN_DOMAIN_REDUCTION_ENABLE>(DISABLE);
- FAPI_TRY(fapi2::putScom(i_target, MBARPC0Q_REG[l_mca_pos], l_mbarpc0_data));
-
- // Step 2 - In MBASTR0Q, enable STR entry
- FAPI_TRY(fapi2::getScom(i_target, MBASTR0Q_REG[l_mca_pos], l_mbastr0_data));
- l_mbastr0_data.writeBit<MCA_MBASTR0Q_CFG_STR_ENABLE>(ENABLE);
- l_mbastr0_data.insertFromRight<MCA_MBASTR0Q_CFG_ENTER_STR_TIME, MCA_MBASTR0Q_CFG_ENTER_STR_TIME_LEN>(TIME_0);
- FAPI_TRY(fapi2::putScom(i_target, MBASTR0Q_REG[l_mca_pos], l_mbastr0_data));
-
- // Step 3 - In MBARPC0Q, enable power domain control.
- l_mbarpc0_data.writeBit<MCA_MBARPC0Q_CFG_MIN_MAX_DOMAINS_ENABLE>(ENABLE);
- FAPI_TRY(fapi2::putScom(i_target, MBARPC0Q_REG[l_mca_pos], l_mbarpc0_data));
- }
+ // Backup the address and data for the following scoms to restore later
+
+ // Disable maint. address mode
+ FAPI_TRY(fapi2::getScom(i_target, MCB_MCBAGRAQ_REG[i_mcbist], l_mcbagraq_data));
+ o_addresses.push_back(MCB_MCBAGRAQ_REG[i_mcbist]);
+ o_data.push_back(l_mcbagraq_data);
+ l_mcbagraq_data.clearBit<MCBIST_MCBAGRAQ_CFG_MAINT_ADDR_MODE_EN>();
+ FAPI_TRY(fapi2::putScom(i_target, MCB_MCBAGRAQ_REG[i_mcbist], l_mcbagraq_data));
+
+ // Required for CCS to drive RESETn
+ FAPI_TRY(fapi2::getScom(i_target, CCS_MODEQ_REG[i_mcbist], l_ccs_modeq_data));
+ o_addresses.push_back(CCS_MODEQ_REG[i_mcbist]);
+ o_data.push_back(l_ccs_modeq_data);
+ l_ccs_modeq_data.setBit<MCBIST_CCS_MODEQ_IDLE_PAT_BANK_2>();
+ FAPI_TRY(fapi2::putScom(i_target, CCS_MODEQ_REG[i_mcbist], l_ccs_modeq_data));
fapi_try_exit:
return fapi2::current_err;
}
///
-/// @brief Helper for trigger_csave. This subroutine assert RESET_n to trigger
-/// the backup on nvdimm
-/// @param[in] i_target - PROC_CHIP targetdefine
-/// @param[in] l_mca_pos - The MCA position relative to the PROC
+/// @brief Start or stop CCS
+/// @param[in] i_target - PROC_CHIP target
+/// @param[in] i_mcbist - mcbist position relative to the proc
+/// @param[in] i_start_stop - start or stop CCS
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
-fapi2::ReturnCode assert_resetn( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const uint8_t l_mca_pos)
+fapi2::ReturnCode start_stop_ccs( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
+ const uint8_t i_mcbist,
+ const uint8_t i_start_stop)
{
- FAPI_ASSERT((l_mca_pos < PORTS_PER_MODULE),
- fapi2::MSS_RESETN_MCA_OUT_OF_RANGE().
+ fapi2::buffer<uint64_t> l_data;
+ constexpr uint8_t START = 1;
+
+ FAPI_TRY(fapi2::getScom(i_target, CCS_CNTLQ_REG[i_mcbist], l_data));
+ FAPI_TRY(fapi2::putScom(i_target, CCS_CNTLQ_REG[i_mcbist],
+ i_start_stop == START ? l_data.setBit<MCBIST_CCS_CNTLQ_START>() : l_data.setBit<MCBIST_CCS_CNTLQ_STOP>()));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Select which port to run CCS on
+/// @param[in] i_target - PROC_CHIP target
+/// @param[in] i_mca - mca position relative to the proc
+/// @param[out] o_addresses - list of addresses that require restore
+/// @param[out] o_data - data to restore to o_addresses
+/// @return FAPI2_RC_SUCCESS iff setup was successful
+///
+fapi2::ReturnCode select_port(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
+ const uint8_t i_mca,
+ std::vector<uint64_t>& o_addresses,
+ std::vector<fapi2::buffer<uint64_t>>& o_data)
+{
+ FAPI_ASSERT((i_mca < PORTS_PER_MODULE),
+ fapi2::MSS_SELECT_PORT_MCA_OUT_OF_RANGE().
set_PROC_TARGET(i_target).
- set_MCA_POS(l_mca_pos),
- "Invalid port number %u provided", l_mca_pos);
+ set_MCA_POS(i_mca),
+ "Invalid port number %u provided", i_mca);
+ {
+ // MCB_CNTLQ[2:5]. Default to port 0 then shift right as needed
+ constexpr uint8_t PORT_0 = 0b1000;
+ const uint64_t l_port_sel = PORT_0 >> (i_mca % PORTS_PER_MCBIST);
+ const uint8_t l_mcbist = i_mca < PORTS_PER_MCBIST ? 0 : 1;
+ fapi2::buffer<uint64_t> l_data;
- FAPI_DBG("Asserting RESETn on port %d.", l_mca_pos);
+ FAPI_TRY(fapi2::getScom(i_target, MCB_CNTLQ_REG[l_mcbist], l_data));
+ l_data.insertFromRight<MCBIST_MCB_CNTLQ_MCBCNTL_PORT_SEL, MCBIST_MCB_CNTLQ_MCBCNTL_PORT_SEL_LEN>(l_port_sel);
+ FAPI_TRY(fapi2::putScom(i_target, MCB_CNTLQ_REG[l_mcbist], l_data));
+ // For each port, set the address mux to CCS and enable CCS to drive RESETn
+ FAPI_TRY(fapi2::getScom(i_target, FARB5Q_REG[i_mca], l_data));
+ o_addresses.push_back(FARB5Q_REG[i_mca]);
+ o_data.push_back(l_data);
+ l_data.setBit<MCA_MBA_FARB5Q_CFG_CCS_ADDR_MUX_SEL>();
+ l_data.setBit<MCA_MBA_FARB5Q_CFG_CCS_INST_RESET_ENABLE>();
+ FAPI_TRY(fapi2::putScom(i_target, FARB5Q_REG[i_mca], l_data));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief change the BAR valid state on MCS with NVDIMM installed
+/// @param[in] i_target - PROC_CHIP target
+/// @param[in] i_port_bitmap - port bitmap that indicates port with nvdimm
+/// @param[in] i_state - BAR state to change to
+/// @return FAPI2_RC_SUCCESS iff setup was successful
+///
+fapi2::ReturnCode change_bar_valid_state( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
+ const fapi2::buffer<uint8_t> i_port_bitmap,
+ const uint64_t i_state)
+{
+ for (uint8_t l_mca_pos = 0; l_mca_pos < PORTS_PER_MODULE; l_mca_pos++)
{
- fapi2::buffer<uint64_t> l_farb5q_data;
- constexpr uint64_t LOW = 0;
+ if (i_port_bitmap.getBit(l_mca_pos) == fapi2::ENUM_ATTR_SBE_NVDIMM_IN_PORT_YES)
+ {
+ const uint8_t l_mcs = l_mca_pos / 2;
+ fapi2::buffer<uint64_t> l_data;
- FAPI_TRY(fapi2::getScom(i_target, FARB5Q_REG[l_mca_pos], l_farb5q_data));
- l_farb5q_data.writeBit<MCA_MBA_FARB5Q_CFG_DDR_RESETN>(LOW);
- FAPI_TRY(fapi2::putScom(i_target, FARB5Q_REG[l_mca_pos], l_farb5q_data));
+ FAPI_TRY(fapi2::getScom(i_target, MCFGP[l_mcs], l_data));
+ l_data.writeBit<MCS_MCFGP_VALID>(i_state);
+ FAPI_TRY(fapi2::putScom(i_target, MCFGP[l_mcs], l_data));
+ }
}
fapi_try_exit:
@@ -195,23 +249,70 @@ fapi_try_exit:
fapi2::ReturnCode trigger_csave( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target )
{
fapi2::buffer<uint8_t> l_nvdimm_port_bitmap = 0;
+ constexpr uint64_t INVALID = 0;
+ constexpr uint64_t VALID = 1;
+ constexpr uint8_t START = 1;
+ constexpr uint8_t STOP = 0;
+ constexpr uint64_t MS_IN_NS = 1000000;
+ const uint64_t DELAY_20MS_IN_NS = 20 * MS_IN_NS;
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_SBE_NVDIMM_IN_PORT, i_target, l_nvdimm_port_bitmap) );
- for (uint8_t l_mca_pos = 0; l_mca_pos < PORTS_PER_MODULE; l_mca_pos++)
+ // Invalidate the BAR temporarily. This prevents any memory access (proc, IO, etc.) from
+ // remove the port out of STR
+ FAPI_TRY( change_bar_valid_state(i_target, l_nvdimm_port_bitmap, INVALID));
+
+ // Get all the mcbists/mcas with NVDIMM
+ for (uint8_t l_mcbist = 0; l_mcbist < MCBISTS_PER_PROC; l_mcbist++)
{
- if (l_nvdimm_port_bitmap.getBit(l_mca_pos) == fapi2::ENUM_ATTR_SBE_NVDIMM_IN_PORT_YES)
+ std::vector<uint8_t> l_mcas;
+ std::vector<uint64_t> l_addresses;
+ std::vector<fapi2::buffer<uint64_t>> l_data;
+ const uint8_t MCA_STARTING_POS = (PORTS_PER_MCBIST * l_mcbist);
+
+ // For each mcbist, gather a list of mcas with nvdimm installed
+ for (uint8_t l_mca_pos = 0 + MCA_STARTING_POS;
+ l_mca_pos < PORTS_PER_MCBIST + MCA_STARTING_POS;
+ l_mca_pos++)
{
- FAPI_DBG("NVDIMM found in port %d ", l_mca_pos);
+ if (l_nvdimm_port_bitmap.getBit(l_mca_pos) == fapi2::ENUM_ATTR_SBE_NVDIMM_IN_PORT_YES)
+ {
+ l_mcas.push_back(l_mca_pos);
+ }
+ }
- // Enter STR
- FAPI_TRY(self_refresh_entry(i_target, l_mca_pos));
+ // Nothing to do
+ if (l_mcas.empty())
+ {
+ FAPI_DBG("No mca with nvdimm detect. l_mcbist = 0x%x, l_mcas.size = %u",
+ l_mcbist, l_mcas.size());
+ continue;
+ }
+
+ // Prep mcbist/ccs for csave
+ FAPI_TRY( prep_for_csave(i_target, l_mcbist, l_addresses, l_data));
- // Assert ddr_resetn
- FAPI_TRY(assert_resetn(i_target, l_mca_pos));
+ // Start and stop CCS, one port at a time.
+ for (const auto l_mca : l_mcas)
+ {
+ FAPI_TRY( select_port(i_target, l_mca, l_addresses, l_data), "Error returned from select_port(). l_mca = %u", l_mca);
+ FAPI_TRY( start_stop_ccs(i_target, l_mcbist, START), "Error to START from start_stop_ccs()");
+ FAPI_TRY( fapi2::delay(DELAY_20MS_IN_NS, 0), "Error returned from fapi2::delay call");
+ FAPI_TRY( start_stop_ccs(i_target, l_mcbist, STOP), "Error to STOP from start_stop_ccs()");
+ }
+
+ // Restore the original value. This is a don't care for poweroff/warm reboot,
+ // needed for MPIPL
+ for (size_t index = 0; index < l_addresses.size(); index++)
+ {
+ FAPI_TRY(fapi2::putScom(i_target, l_addresses[index], l_data[index]));
}
}
+ // Set the BAR back to valid. This is a don't care for the power down but required
+ // for MPIPL.
+ FAPI_TRY( change_bar_valid_state(i_target, l_nvdimm_port_bitmap, VALID));
+
fapi_try_exit:
return fapi2::current_err;
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/nvdimm_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/nvdimm_workarounds.H
index a5d1b4a07..39952ddf8 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/nvdimm_workarounds.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/nvdimm_workarounds.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -58,27 +58,55 @@ typedef fapi2::ReturnCode (*p9_flush_nvdimm_FP_t) (const fapi2::Target<fapi2::TA
/// @param[in] i_target - PROC_CHIP target
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
-
fapi2::ReturnCode trigger_csave( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target );
///
-/// @brief Helper for trigger_csave. This subroutine assert RESET_n to trigger
-/// the backup on nvdimm
+/// @brief Program the necessary scom regs to prepare for CSAVE
/// @param[in] i_target - PROC_CHIP target
-/// @param[in] l_mca_pos - The MCA position relative to the PROC
+/// @param[in] i_mcbist - mcbist position relative to the proc
+/// @param[out] o_addresses - list of addresses that require restore
+/// @param[out] o_data - data to restore to o_addresses
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
+fapi2::ReturnCode prep_for_csave( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
+ const uint8_t i_mcbist,
+ std::vector<uint64_t>& o_addresses,
+ std::vector<fapi2::buffer<uint64_t>>& o_data);
-fapi2::ReturnCode assert_resetn( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, uint8_t l_mca_pos);
+///
+/// @brief Select which port to run CCS on
+/// @param[in] i_target - PROC_CHIP target
+/// @param[in] i_mca - mca position relative to the proc
+/// @param[out] o_addresses - list of addresses that require restore
+/// @param[out] o_data - data to restore to o_addresses
+/// @return FAPI2_RC_SUCCESS iff setup was successful
+///
+fapi2::ReturnCode select_port(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
+ const uint8_t i_mca,
+ std::vector<uint64_t>& o_addresses,
+ std::vector<fapi2::buffer<uint64_t>>& o_data);
///
-/// @brief Helper for trigger_csave. This subroutine puts the MCA into STR
+/// @brief Start or stop CCS
/// @param[in] i_target - PROC_CHIP target
-/// @param[in] l_mca_pos - The MCA position relative to the PROC
+/// @param[in] i_mcbist - mcbist position relative to the proc
+/// @param[in] i_start_stop - start or stop CCS
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
+fapi2::ReturnCode start_stop_ccs( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
+ const uint8_t i_mcbist,
+ const bool i_start_stop);
-fapi2::ReturnCode self_refresh_entry( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, uint8_t l_mca_pos);
+///
+/// @brief change the BAR valid state on MCS with NVDIMM installed
+/// @param[in] i_target - PROC_CHIP target
+/// @param[in] i_port_bitmap - port bitmap that indicates port with nvdimm
+/// @param[in] i_state - BAR state to change to
+/// @return FAPI2_RC_SUCCESS iff setup was successful
+///
+fapi2::ReturnCode change_bar_valid_state( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
+ const fapi2::buffer<uint8_t> i_port_bitmap,
+ const uint64_t i_state);
}//ns nvdimm
}//ns workarounds
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/quad_encode_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/quad_encode_workarounds.C
new file mode 100644
index 000000000..cf13e917a
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/quad_encode_workarounds.C
@@ -0,0 +1,256 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/workarounds/quad_encode_workarounds.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file quad_encode_workarounds.C
+/// @brief Contains workarounds having to do with quad-encode CS
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB Memory Lab
+
+#include <lib/shared/nimbus_defaults.H>
+#include <fapi2.H>
+#include <p9n2_mc_scom_addresses.H>
+
+#include <generic/memory/lib/utils/c_str.H>
+#include <lib/utils/nimbus_find.H>
+#include <lib/ccs/ccs_traits_nimbus.H>
+#include <generic/memory/lib/ccs/ccs.H>
+#include <lib/mss_attribute_accessors.H>
+#include <lib/dimm/ddr4/mrs_load_ddr4.H>
+#include <lib/workarounds/quad_encode_workarounds.H>
+
+namespace mss
+{
+
+namespace workarounds
+{
+
+const std::vector< uint64_t> shadow_regs_traits<0>::REGS =
+{
+ P9N2_MCA_DDRPHY_PC_MR0_RP0_P0,
+ P9N2_MCA_DDRPHY_PC_MR0_RP1_P0,
+ P9N2_MCA_DDRPHY_PC_MR0_RP2_P0,
+ P9N2_MCA_DDRPHY_PC_MR0_RP3_P0,
+};
+const std::vector< uint64_t> shadow_regs_traits<1>::REGS =
+{
+ P9N2_MCA_DDRPHY_PC_MR1_RP0_P0,
+ P9N2_MCA_DDRPHY_PC_MR1_RP1_P0,
+ P9N2_MCA_DDRPHY_PC_MR1_RP2_P0,
+ P9N2_MCA_DDRPHY_PC_MR1_RP3_P0,
+};
+const std::vector< uint64_t> shadow_regs_traits<2>::REGS =
+{
+ P9N2_MCA_DDRPHY_PC_MR2_RP0_P0,
+ P9N2_MCA_DDRPHY_PC_MR2_RP1_P0,
+ P9N2_MCA_DDRPHY_PC_MR2_RP2_P0,
+ P9N2_MCA_DDRPHY_PC_MR2_RP3_P0,
+};
+const std::vector< uint64_t> shadow_regs_traits<3>::REGS =
+{
+ P9N2_MCA_DDRPHY_PC_MR3_RP0_P0,
+ P9N2_MCA_DDRPHY_PC_MR3_RP1_P0,
+ P9N2_MCA_DDRPHY_PC_MR3_RP2_P0,
+ P9N2_MCA_DDRPHY_PC_MR3_RP3_P0,
+};
+const std::vector< uint64_t> shadow_regs_traits<4>::REGS =
+{
+ P9N2_MCA_DDRPHY_PC_MR4_RP0_P0,
+ P9N2_MCA_DDRPHY_PC_MR4_RP1_P0,
+ P9N2_MCA_DDRPHY_PC_MR4_RP2_P0,
+ P9N2_MCA_DDRPHY_PC_MR4_RP3_P0,
+};
+const std::vector< uint64_t> shadow_regs_traits<5>::REGS =
+{
+ P9N2_MCA_DDRPHY_PC_MR5_RP0_P0,
+ P9N2_MCA_DDRPHY_PC_MR5_RP1_P0,
+ P9N2_MCA_DDRPHY_PC_MR5_RP2_P0,
+ P9N2_MCA_DDRPHY_PC_MR5_RP3_P0,
+};
+const std::vector< uint64_t> shadow_regs_traits<6>::REGS =
+{
+ P9N2_MCA_DDRPHY_PC_MR6_RP0_P0,
+ P9N2_MCA_DDRPHY_PC_MR6_RP1_P0,
+ P9N2_MCA_DDRPHY_PC_MR6_RP2_P0,
+ P9N2_MCA_DDRPHY_PC_MR6_RP3_P0,
+};
+
+///
+/// @brief Returns true if an MRS command was run
+/// @param[in] i_inst instruction to check for an MRS command
+/// @return true iff the command contains an MRS command
+///
+bool is_command_mrs(const ccs::instruction_t& i_inst)
+{
+ // An MRS command is
+ // 1) at least one chip select active
+ // 2) at ACT HI, RAS/CAS/WEN low
+ // 3) not BA7
+
+ const auto l_cs_low = !i_inst.arr0.getBit<MCBIST_CCS_INST_ARR0_00_DDR_CSN_0_1>() ||
+ !i_inst.arr0.getBit < MCBIST_CCS_INST_ARR0_00_DDR_CSN_0_1 + 1 > () ||
+ !i_inst.arr0.getBit<MCBIST_CCS_INST_ARR0_00_DDR_CSN_2_3>() ||
+ !i_inst.arr0.getBit < MCBIST_CCS_INST_ARR0_00_DDR_CSN_2_3 + 1 > ();
+
+ const auto l_mrs_cmd = i_inst.arr0.getBit<MCBIST_CCS_INST_ARR0_00_DDR_ACTN>() &&
+ !i_inst.arr0.getBit<MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_16>() &&
+ !i_inst.arr0.getBit<MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_15>() &&
+ !i_inst.arr0.getBit<MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_14>();
+
+ const auto l_mrs_ba = !i_inst.arr0.getBit<MCBIST_CCS_INST_ARR0_00_DDR_BANK_0_1>() ||
+ !i_inst.arr0.getBit < MCBIST_CCS_INST_ARR0_00_DDR_BANK_0_1 + 1 > () ||
+ !i_inst.arr0.getBit<MCBIST_CCS_INST_ARR0_00_DDR_BANK_GROUP_0>();
+ return l_cs_low && l_mrs_cmd && l_mrs_ba;
+}
+///
+/// @brief Returns true if a vector of commands contains an MRS command
+/// @param[in] i_inst instruction to check for an MRS command
+/// @return true iff the command contains an MRS command
+///
+bool contains_command_mrs(const std::vector<ccs::instruction_t>& i_inst)
+{
+ bool l_contains_mrs = false;
+
+ for(const auto& l_inst : i_inst)
+ {
+ l_contains_mrs = is_command_mrs(l_inst);
+
+ if(l_contains_mrs)
+ {
+ FAPI_DBG("0x%016lx is an MRS command. Exiting", uint64_t(l_inst.arr0));
+ break;
+ }
+ }
+
+ return l_contains_mrs;
+}
+
+///
+/// @brief Fixes shadow register corruption over all ranks if needed
+/// @param[in] i_target - the DIMM target on which to operate
+/// @return fapi2::ReturnCode - SUCCESS iff everything executes successfully
+///
+fapi2::ReturnCode fix_shadow_register_corruption( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target)
+{
+ std::vector< uint64_t > l_ranks;
+ FAPI_TRY(mss::rank::primary_ranks( i_target, l_ranks ));
+
+ for(const auto l_rank : l_ranks)
+ {
+ FAPI_TRY(fix_shadow_register_corruption(i_target, l_rank));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Fixes shadow register corruption if needed
+/// @param[in] i_target - the DIMM target on which to operate
+/// @param[in] i_rank - the rank on which to operate
+/// @return fapi2::ReturnCode - SUCCESS iff everything executes successfully
+///
+fapi2::ReturnCode fix_shadow_register_corruption( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rank)
+{
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> l_dimm;
+ const auto l_dimm_rank = mss::index(i_rank);
+ uint64_t l_rp = 0;
+ bool l_fix_needed = false;
+
+ // In this case, the rank is really to get the DIMM in question
+ FAPI_TRY(mss::rank::get_dimm_target_from_rank(i_target, i_rank, l_dimm),
+ "%s failed to get DIMM from rank%u", mss::c_str(i_target), i_rank);
+
+ FAPI_TRY(check_shadow_register_corruption(l_dimm, i_rank, l_fix_needed),
+ "%s failed to check if the fix is needed", mss::c_str(i_target));
+
+ // If the fix isn't needed, exit out
+ if(!l_fix_needed)
+ {
+ FAPI_INF("%s workaround not needed. Skipping", mss::c_str(i_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Shadow registers are on a per-rank pair basis
+ FAPI_TRY(mss::rank::get_pair_from_rank(i_target, i_rank, l_rp),
+ "%s rank%u failed to get RP nominal values", mss::c_str(i_target), i_rank);
+
+ FAPI_TRY(fix_shadow_register_corruption_mr<0>(l_dimm, l_rp, l_dimm_rank),
+ "%s failed to fix shadow regs on MR0", mss::c_str(i_target));
+ FAPI_TRY(fix_shadow_register_corruption_mr<1>(l_dimm, l_rp, l_dimm_rank),
+ "%s failed to fix shadow regs on MR1", mss::c_str(i_target));
+ FAPI_TRY(fix_shadow_register_corruption_mr<2>(l_dimm, l_rp, l_dimm_rank),
+ "%s failed to fix shadow regs on MR2", mss::c_str(i_target));
+ FAPI_TRY(fix_shadow_register_corruption_mr<3>(l_dimm, l_rp, l_dimm_rank),
+ "%s failed to fix shadow regs on MR3", mss::c_str(i_target));
+ FAPI_TRY(fix_shadow_register_corruption_mr<4>(l_dimm, l_rp, l_dimm_rank),
+ "%s failed to fix shadow regs on MR4", mss::c_str(i_target));
+ FAPI_TRY(fix_shadow_register_corruption_mr<5>(l_dimm, l_rp, l_dimm_rank),
+ "%s failed to fix shadow regs on MR5", mss::c_str(i_target));
+ FAPI_TRY(fix_shadow_register_corruption_mr<6>(l_dimm, l_rp, l_dimm_rank),
+ "%s failed to fix shadow regs on MR6", mss::c_str(i_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @param[in] i_target - the DIMM target on which to operate
+/// @param[in] i_rank - the rank on which to operate
+/// @param[out] o_fix_needed - true iff the shadow register's could be corrupted (aka are we a 4R DIMM?)
+/// @return fapi2::ReturnCode - SUCCESS iff everything executes successfully
+///
+
+fapi2::ReturnCode check_shadow_register_corruption( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint64_t i_rank,
+ bool& o_fix_needed)
+{
+ // Number of master ranks for this DIMM - if we have 4, we need the workaround
+ // Also, always run the workaround if we have an LRDIMM
+ constexpr uint8_t RANKS_FOR_FIX_NEEDED = 4;
+ uint8_t l_master_ranks = 0;
+ uint8_t l_dimm_type = 0;
+ o_fix_needed = false;
+
+ FAPI_TRY(mss::eff_num_master_ranks_per_dimm(i_target, l_master_ranks), "%s failed to get master ranks",
+ mss::c_str(i_target));
+ FAPI_TRY(mss::eff_dimm_type(i_target, l_dimm_type), "%s failed to get dimm_type",
+ mss::c_str(i_target));
+ o_fix_needed = (l_master_ranks == RANKS_FOR_FIX_NEEDED) ||
+ (l_dimm_type == fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM);
+ FAPI_INF("%s workaround %s needed. num master ranks %u dimm type %u", mss::c_str(i_target), o_fix_needed ? "is" : "not",
+ l_master_ranks, l_dimm_type);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // ns workarounds
+} // ns mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/quad_encode_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/quad_encode_workarounds.H
new file mode 100644
index 000000000..1d7ea180f
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/quad_encode_workarounds.H
@@ -0,0 +1,373 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/workarounds/quad_encode_workarounds.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file quad_encode_workaround.H
+/// @brief Contains workarounds having to do with quad-encode CS
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB Memory Lab
+
+#ifndef _QUAD_ENCODE_WORKAROUND_H_
+#define _QUAD_ENCODE_WORKAROUND_H_
+
+#include <fapi2.H>
+#include <p9_mc_scom_addresses.H>
+
+#include <lib/shared/mss_const.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <lib/utils/nimbus_find.H>
+#include <generic/memory/lib/ccs/ccs.H>
+#include <lib/dimm/rank.H>
+#include <lib/dimm/ddr4/mrs_load_ddr4.H>
+#include <p9_mc_scom_addresses_fld.H>
+
+namespace mss
+{
+
+namespace workarounds
+{
+
+static constexpr uint64_t MAX_MR = 6;
+
+///
+/// @brief Fixes shadow register corruption over all ranks if needed
+/// @param[in] i_target - the DIMM target on which to operate
+/// @return fapi2::ReturnCode - SUCCESS iff everything executes successfully
+///
+fapi2::ReturnCode fix_shadow_register_corruption( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target);
+
+///
+/// @brief Fixes shadow register corruption if needed
+/// @param[in] i_target - the DIMM target on which to operate
+/// @param[in] i_rank - the rank on which to operate
+/// @return fapi2::ReturnCode - SUCCESS iff everything executes successfully
+///
+fapi2::ReturnCode fix_shadow_register_corruption( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rank);
+
+///
+/// @param[in] i_target - the DIMM target on which to operate
+/// @param[in] i_rank - the rank on which to operate
+/// @param[out] o_fix_needed - true iff the shadow register's could be corrupted (aka are we a 4R DIMM?)
+/// @return fapi2::ReturnCode - SUCCESS iff everything executes successfully
+///
+
+fapi2::ReturnCode check_shadow_register_corruption( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint64_t i_rank,
+ bool& o_fix_needed);
+
+///
+/// @brief Returns true if an MRS command was run
+/// @param[in] i_inst instruction to check for an MRS command
+/// @return true iff the command contains an MRS command
+///
+bool is_command_mrs(const ccs::instruction_t& i_inst);
+
+///
+/// @brief Returns true if a vector of commands contains an MRS command
+/// @param[in] i_inst instruction to check for an MRS command
+/// @return true iff the command contains an MRS command
+///
+bool contains_command_mrs(const std::vector<ccs::instruction_t>& i_inst);
+
+///
+/// @brief Converts the CCS instructions to the shadow register configuration
+/// @param[in] i_inst CCS instruction to convert
+/// @return the register value for the shadow register
+///
+inline fapi2::buffer<uint64_t> convert_to_shadow_reg(const ccs::instruction_t& i_inst)
+{
+ fapi2::buffer<uint64_t> l_arr0(i_inst.arr0);
+ mss::reverse(l_arr0);
+ constexpr uint64_t SHADOW_REG_START = 50;
+ l_arr0.clearBit<0, SHADOW_REG_START>();
+ return l_arr0;
+}
+
+///
+/// @class shadow_regs_traits
+/// @brief a collection of traits associated with each shadow register
+/// @tparam MR the MR number for which to fix the shadow regs
+///
+template< uint64_t MR >
+class shadow_regs_traits;
+
+///
+/// @class shadow_regs_traits
+/// @brief a collection of traits associated with each shadow register - specialization for MR0
+///
+template<>
+class shadow_regs_traits<0>
+{
+ public:
+
+ static const std::vector<uint64_t> REGS;
+
+ ///
+ /// @brief Configure the ARR0 of the CCS isntruction for mrs00
+ /// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+ /// @param[in,out] io_inst the instruction to fixup
+ /// @param[in] i_rank ths rank in question
+ /// @return FAPI2_RC_SUCCESS iff OK
+ ///
+ static inline fapi2::ReturnCode mrs_gen(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t& io_inst,
+ const uint64_t i_rank)
+ {
+ constexpr uint8_t LR_2666_MARGIN_ADJUST = 2;
+
+ // So, why is MRS0 being reset differently compared to the other mode register sets?
+ // For LRDIMM, at 2666, we're running at the edge of the PHY's capabilities to account for the read delay
+ // This means, we've started taking some fails related to not being able to wait long enough for the data to come back
+ // A handy workaround for this is to increase our CAS latency within the PHY itself by changing the value of the mode register
+ // This tricks the PHY's snooping capabilities to think that the data is coming back a bit later
+ // This allows the gate delay and RLO to account for the increased delay correctly
+ // Note: we need the DRAM to send the data back at the same time, but fake the PHY into thinking that it's coming later
+
+ uint8_t l_dimm_type = 0;
+ uint64_t l_freq = 0;
+
+ // Check to make sure our ctor worked ok
+ mss::ddr4::mrs00_data l_data( i_target, fapi2::current_err );
+ FAPI_TRY( fapi2::current_err, "%s Unable to construct MRS00 data from attributes", mss::c_str(i_target) );
+ FAPI_TRY( mss::eff_dimm_type(i_target, l_dimm_type));
+ FAPI_TRY( mss::freq(mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq));
+
+ // Apply the CAS latency offset if we have an LRDIMM at 2666
+ l_data.iv_cas_latency += ((l_dimm_type == fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM) &&
+ (l_freq == fapi2::ENUM_ATTR_MSS_FREQ_MT2666)) ?
+ LR_2666_MARGIN_ADJUST : 0;
+ FAPI_TRY( mss::ddr4::mrs00(i_target, l_data, io_inst, i_rank) );
+ fapi_try_exit:
+ return fapi2::current_err;
+ };
+};
+
+///
+/// @class shadow_regs_traits
+/// @brief a collection of traits associated with each shadow register - specialization for MR1
+///
+template<>
+class shadow_regs_traits<1>
+{
+ public:
+
+ static const std::vector<uint64_t> REGS;
+
+ ///
+ /// @brief Configure the ARR0 of the CCS isntruction for mrs00
+ /// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+ /// @param[in,out] io_inst the instruction to fixup
+ /// @param[in] i_rank ths rank in question
+ /// @return FAPI2_RC_SUCCESS iff OK
+ ///
+ static inline fapi2::ReturnCode mrs_gen(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t& io_inst,
+ const uint64_t i_rank)
+ {
+ return mss::ddr4::mrs01(i_target, io_inst, i_rank);
+ };
+};
+
+///
+/// @class shadow_regs_traits
+/// @brief a collection of traits associated with each shadow register - specialization for MR2
+///
+template<>
+class shadow_regs_traits<2>
+{
+ public:
+
+ static const std::vector<uint64_t> REGS;
+
+ ///
+ /// @brief Configure the ARR0 of the CCS isntruction for mrs00
+ /// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+ /// @param[in,out] io_inst the instruction to fixup
+ /// @param[in] i_rank ths rank in question
+ /// @return FAPI2_RC_SUCCESS iff OK
+ ///
+ static inline fapi2::ReturnCode mrs_gen(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t& io_inst,
+ const uint64_t i_rank)
+ {
+ return mss::ddr4::mrs02(i_target, io_inst, i_rank);
+ };
+};
+
+///
+/// @class shadow_regs_traits
+/// @brief a collection of traits associated with each shadow register - specialization for MR3
+///
+template<>
+class shadow_regs_traits<3>
+{
+ public:
+
+ static const std::vector<uint64_t> REGS;
+
+ ///
+ /// @brief Configure the ARR0 of the CCS isntruction for mrs00
+ /// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+ /// @param[in,out] io_inst the instruction to fixup
+ /// @param[in] i_rank ths rank in question
+ /// @return FAPI2_RC_SUCCESS iff OK
+ ///
+ static inline fapi2::ReturnCode mrs_gen(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t& io_inst,
+ const uint64_t i_rank)
+ {
+ return mss::ddr4::mrs03(i_target, io_inst, i_rank);
+ };
+};
+
+///
+/// @class shadow_regs_traits
+/// @brief a collection of traits associated with each shadow register - specialization for MR4
+///
+template<>
+class shadow_regs_traits<4>
+{
+ public:
+
+ static const std::vector<uint64_t> REGS;
+
+ ///
+ /// @brief Configure the ARR0 of the CCS isntruction for mrs00
+ /// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+ /// @param[in,out] io_inst the instruction to fixup
+ /// @param[in] i_rank ths rank in question
+ /// @return FAPI2_RC_SUCCESS iff OK
+ ///
+ static inline fapi2::ReturnCode mrs_gen(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t& io_inst,
+ const uint64_t i_rank)
+ {
+ return mss::ddr4::mrs04(i_target, io_inst, i_rank);
+ };
+};
+
+///
+/// @class shadow_regs_traits
+/// @brief a collection of traits associated with each shadow register - specialization for MR5
+///
+template<>
+class shadow_regs_traits<5>
+{
+ public:
+
+ static const std::vector<uint64_t> REGS;
+
+ ///
+ /// @brief Configure the ARR0 of the CCS isntruction for mrs00
+ /// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+ /// @param[in,out] io_inst the instruction to fixup
+ /// @param[in] i_rank ths rank in question
+ /// @return FAPI2_RC_SUCCESS iff OK
+ ///
+ static inline fapi2::ReturnCode mrs_gen(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t& io_inst,
+ const uint64_t i_rank)
+ {
+ return mss::ddr4::mrs05(i_target, io_inst, i_rank);
+ };
+};
+
+///
+/// @class shadow_regs_traits
+/// @brief a collection of traits associated with each shadow register - specialization for MR6
+///
+template<>
+class shadow_regs_traits<6>
+{
+ public:
+
+ static const std::vector<uint64_t> REGS;
+
+ ///
+ /// @brief Configure the ARR0 of the CCS isntruction for mrs00
+ /// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+ /// @param[in,out] io_inst the instruction to fixup
+ /// @param[in] i_rank ths rank in question
+ /// @return FAPI2_RC_SUCCESS iff OK
+ ///
+ static inline fapi2::ReturnCode mrs_gen(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t& io_inst,
+ const uint64_t i_rank)
+ {
+ return mss::ddr4::mrs06(i_target, io_inst, i_rank);
+ };
+};
+
+
+///
+/// @brief Fixes shadow register corruption on the associated MR
+/// @tparam MR the MR number for which to fix the shadow regs
+/// @tparam traits associated with this shadow register
+/// @param[in] i_target - the DIMM target on which to operate
+/// @param[in] i_rp - the rank pair on which to operate
+/// @param[in] i_rank - the rank on which to operate
+/// @return fapi2::ReturnCode - SUCCESS iff everything executes successfully
+///
+template< uint64_t MR, typename TT = shadow_regs_traits<MR> >
+fapi2::ReturnCode fix_shadow_register_corruption_mr( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint64_t i_rp,
+ const uint64_t i_rank)
+{
+ static_assert( MR <= MAX_MR, "MR instance out of range");
+
+ ccs::instruction_t l_inst;
+ const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
+
+ // Converts this to DIMM rank. just. in. case.
+ const auto l_dimm_rank = mss::index(i_rank);
+
+ FAPI_ASSERT( i_rp < MAX_RANK_PAIRS,
+ fapi2::MSS_INVALID_RANK_PAIR()
+ .set_RANK_PAIR(i_rp)
+ .set_FUNCTION(mss::ffdc_function_codes::FIX_SHADOW_REGISTER)
+ .set_MCA_TARGET(l_mca),
+ "%s invalid RP %u. Max is %u",
+ mss::c_str(l_mca), i_rp, MAX_RANK_PAIRS);
+
+ FAPI_TRY(TT::mrs_gen(i_target, l_inst, l_dimm_rank), "%s failed to get MRS%u nominal values", mss::c_str(i_target), MR);
+
+ // Issues the scom to the shadow regiser
+ FAPI_TRY(mss::putScom(l_mca, TT::REGS[i_rp], convert_to_shadow_reg(l_inst)),
+ "%s rank%u failed to set the shadow register", mss::c_str(i_target), l_dimm_rank);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // ns workarounds
+} // ns mss
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/mss.H b/src/import/chips/p9/procedures/hwp/memory/mss.H
index f8c5dabf9..47200a2eb 100644
--- a/src/import/chips/p9/procedures/hwp/memory/mss.H
+++ b/src/import/chips/p9/procedures/hwp/memory/mss.H
@@ -49,26 +49,26 @@
#include <lib/shared/mss_const.H>
#include <lib/shared/mss_kind.H>
+#include <lib/ccs/ccs_nimbus.H>
#include <generic/memory/lib/utils/index.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <lib/utils/num.H>
+#include <generic/memory/lib/utils/num.H>
#include <generic/memory/lib/utils/pos.H>
#include <generic/memory/lib/utils/buffer_ops.H>
#include <lib/utils/mss_nimbus_conversions.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <generic/memory/lib/utils/poll.H>
#include <lib/utils/checker.H>
-#include <lib/utils/dump_regs.H>
+#include <generic/memory/lib/utils/dump_regs.H>
-#include <lib/ccs/ccs.H>
#include <lib/mcbist/mcbist.H>
#include <lib/dimm/rcd_load.H>
#include <lib/dimm/mrs_load.H>
#include <lib/dimm/rank.H>
-#include <lib/dimm/kind.H>
+#include <lib/dimm/nimbus_kind.H>
#include <lib/phy/ddr_phy.H>
#include <lib/phy/dp16.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_background_scrub.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_background_scrub.C
index aaf7b6195..e9e4fd0d1 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_background_scrub.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_background_scrub.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,52 +40,32 @@
#include <lib/dimm/rank.H>
#include <lib/mcbist/address.H>
#include <lib/mcbist/mcbist.H>
-#include <lib/mcbist/patterns.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H>
#include <lib/mcbist/memdiags.H>
-#include <lib/mcbist/sim.H>
#include <generic/memory/lib/utils/count_dimm.H>
-#include <lib/fir/memdiags_fir.H>
+#include <lib/fir/unmask.H>
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_SYSTEM;
using fapi2::FAPI2_RC_SUCCESS;
-///
-/// @brief Begin background scrub
-/// @param[in] i_target MCBIST
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode p9_mss_background_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
-{
- FAPI_INF("Start mss background scrub on: %s", mss::c_str( i_target ));
- // If there are no DIMM we don't need to bother. In fact, we can't as we didn't setup
- // attributes for the PHY, etc.
- if (mss::count_dimm(i_target) == 0)
- {
- FAPI_INF("... skipping background scrub for %s - no DIMM ...", mss::c_str(i_target));
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
- // If we're running in the simulator, we want to only touch the addresses which training touched
- uint8_t l_sim = 0;
- FAPI_TRY( mss::is_simulation(l_sim) );
+extern "C"
+{
- // Kick off background scrub if we are not running in sim
- if (!(l_sim))
+ ///
+ /// @brief Begin background scrub
+ /// @param[in] i_target MCBIST
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode p9_mss_background_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
{
- // Start background scrub
- FAPI_TRY ( mss::memdiags::background_scrub( i_target,
- mss::mcbist::stop_conditions(),
- mss::mcbist::speed::BG_SCRUB,
- mss::mcbist::address() ) );
+ FAPI_INF("Start mss background scrub on: %s", mss::c_str( i_target ));
+ FAPI_TRY(mss::memdiags::mss_background_scrub_helper(i_target));
+ fapi_try_exit:
+ return fapi2::current_err;
}
- // Unmask firs after background scrub is started
- FAPI_TRY ( mss::unmask::after_background_scrub( i_target ) );
-
-fapi_try_exit:
- return fapi2::current_err;
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C
index 84cc1c73e..e88962861 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -32,11 +32,13 @@
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
+
+#include <lib/shared/nimbus_defaults.H>
#include <vector>
#include <fapi2.H>
#include <p9_mss_bulk_pwr_throttles.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <lib/power_thermal/throttle.H>
@@ -88,7 +90,7 @@ extern "C"
const uint8_t l_pos = mss::index(l_mca);
- mss::power_thermal::throttle l_pwr_struct(l_mca, l_rc);
+ mss::power_thermal::throttle<> l_pwr_struct(l_mca, l_rc);
FAPI_TRY(l_rc, "Error constructing mss:power_thermal::throttle object for target %s",
mss::c_str(l_mca));
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_ddr_phy_reset.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_ddr_phy_reset.C
index 27b616a72..8d439b9d8 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_ddr_phy_reset.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_ddr_phy_reset.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,6 +33,7 @@
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
+#include <lib/shared/nimbus_defaults.H>
#include <stdint.h>
#include <string.h>
@@ -198,7 +199,7 @@ extern "C"
// The algorithm is 'good path do after_phy_reset, all paths (error or not) perform the checks
// which are defined in during_phy_reset'. We won't run after_phy_reset (unmask of FIR) unless
// we're done with a success.
- FAPI_TRY( mss::unmask::after_phy_reset<mss::mc_type::NIMBUS>(i_target), "%s Error in p9_mss_ddr_phy_reset.C",
+ FAPI_TRY( mss::unmask::after_phy_reset(i_target), "%s Error in p9_mss_ddr_phy_reset.C",
mss::c_str(i_target) );
// Leave as we're all good and checked the FIR already ...
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C
index 559593111..62a9e3114 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C
@@ -60,10 +60,6 @@ extern "C"
{
fapi2::buffer<uint64_t> l_data;
- mss::ccs::instruction_t<TARGET_TYPE_MCBIST> l_des = mss::ccs::des_command<TARGET_TYPE_MCBIST>();
-
- mss::ccs::program<TARGET_TYPE_MCBIST> l_program;
-
// Up, down P down, up N. Somewhat magic numbers - came from Centaur and proven to be the
// same on Nimbus. Why these are what they are might be lost to time ...
constexpr uint64_t PCLK_INITIAL_VALUE = 0b10;
@@ -158,16 +154,10 @@ extern "C"
mss::c_str(i_target) );
}
- // Also a Deselect command must be registered as required from the Spec.
- // Register DES instruction, which pulls CKE high. Idle 400 cycles, and then begin RCD loading
- // Note: This only is sent to one of the MCA as we still have the mux_addr_sel bit set, meaning
- // we'll PDE/DES all DIMM at the same time.
- l_des.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(400);
- l_program.iv_instructions.push_back(l_des);
-
- FAPI_TRY( mss::ccs::execute(i_target, l_program, l_mcas[0]),
- "%s Failed execute in p9_mss_draminit",
- mss::c_str(i_target) );
+ // Holds our CKE high for 400 cycles - required by the JEDEC spec
+ FAPI_TRY( mss::draminit_cke_helper(l_mcas[0]),
+ "%s Failed to hold CKE high in p9_mss_draminit",
+ mss::c_str(i_target));
// Per conversation with Shelton and Steve 10/9/15, turn off addr_mux_sel after the CKE CCS but
// before the RCD/MRS CCSs
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_mc.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_mc.C
index 66892c8bd..22a6bacb4 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_mc.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_mc.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,13 +33,14 @@
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
+#include <lib/shared/nimbus_defaults.H>
#include <fapi2.H>
#include <mss.H>
#include <p9_mc_scom_addresses_fld.H>
#include <p9_mss_draminit_mc.H>
#include <lib/fir/unmask.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <lib/workarounds/mca_workarounds.H>
@@ -87,7 +88,6 @@ extern "C"
for(const auto& l_mca : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target))
{
FAPI_TRY(mss::workarounds::str_non_tsv_parity(l_mca));
- FAPI_TRY(mss::configure_cid_parity(l_mca));
}
// TODO:RTC179508 - Cleanup draminit_mc
@@ -140,14 +140,14 @@ extern "C"
FAPI_TRY( mss::enable_periodic_cal(p), "%s Failed enable_periodic_cal", mss::c_str(i_target) );
// Step Six: Setup Control Bit ECC
- FAPI_TRY( mss::enable_read_ecc(p), "%s Failed enable_read_ecc", mss::c_str(i_target) );
+ FAPI_TRY( mss::enable_read_ecc<mss::mc_type::NIMBUS>(p), "%s Failed enable_read_ecc", mss::c_str(i_target) );
// apply marks from MVPD
- FAPI_TRY( mss::apply_mark_store(p), "%s Failed enable_read_ecc", mss::c_str(i_target) );
+ FAPI_TRY( mss::apply_mark_store(p), "%s Failed apply_mark_store", mss::c_str(i_target) );
}
// At this point the DDR interface must be monitored for memory errors. Memory related FIRs should be unmasked.
- FAPI_TRY( mss::unmask::after_draminit_mc<mss::mc_type::NIMBUS>(i_target), "%s Failed after_draminit_mc",
+ FAPI_TRY( mss::unmask::after_draminit_mc(i_target), "%s Failed after_draminit_mc",
mss::c_str(i_target) );
fapi_try_exit:
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C
index e4084b461..0a13ac90c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C
@@ -33,6 +33,7 @@
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
+#include <lib/shared/nimbus_defaults.H>
#include <fapi2.H>
#include <mss.H>
#include <vector>
@@ -212,7 +213,7 @@ extern "C"
// We do it here in order to train every port
FAPI_TRY( mss::draminit_training_error_handler(l_fails) );
// Unmask FIR
- FAPI_TRY( mss::unmask::after_draminit_training<mss::mc_type::NIMBUS>(i_target), "Error in p9_mss_draminit" );
+ FAPI_TRY( mss::unmask::after_draminit_training(i_target), "Error in p9_mss_draminit" );
fapi_try_exit:
FAPI_INF("End draminit training");
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C
index 95a662883..67c3074a2 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training_adv.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -43,6 +43,7 @@
#include <lib/phy/seq.H>
#include <lib/phy/ddr_phy.H>
#include <lib/phy/mss_training.H>
+#include <lib/workarounds/dp16_workarounds.H>
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
@@ -125,6 +126,9 @@ extern "C"
{
FAPI_TRY( l_step->execute(p, rp, l_cal_abort_on_error) );
}
+
+ // Adjusts values for NVDIMM's
+ FAPI_TRY(mss::workarounds::nvdimm::adjust_rd_dq_delay(p, rp));
}// rank pairs
// Resetting current_err.
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C
index 7ce96a63d..9a8217e52 100755
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C
@@ -42,10 +42,11 @@
#include <fapi2.H>
// mss lib
+#include <lib/shared/nimbus_defaults.H>
#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
#include <generic/memory/lib/utils/pos.H>
#include <lib/utils/checker.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <lib/shared/mss_kind.H>
#include <lib/dimm/eff_dimm.H>
#include <lib/eff_config/plug_rules.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C
index bd5819fd2..b9d63f3fc 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,13 +33,13 @@
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
+#include <lib/shared/nimbus_defaults.H>
#include <fapi2.H>
#include <vector>
#include <p9_mss_eff_config_thermal.H>
#include <p9_mss_bulk_pwr_throttles.H>
#include <lib/power_thermal/throttle.H>
#include <lib/power_thermal/decoder.H>
-#include <lib/dimm/kind.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <lib/shared/mss_const.H>
#include <mss.H>
@@ -52,12 +52,14 @@ extern "C"
/// @note sets ATTR_MSS_MEM_WATT_TARGET, ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT and _PER_SLOT, and ATTR_MSS_PORT_MAXPOWER
fapi2::ReturnCode p9_mss_eff_config_thermal( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets )
{
+ using TT = mss::power_thermal::throttle_traits<mss::mc_type::NIMBUS>;
+
FAPI_INF("Start effective config thermal");
fapi2::ReturnCode l_rc;
- std::vector< uint64_t > l_slope (mss::power_thermal::SIZE_OF_POWER_CURVES_ATTRS, 0);
- std::vector< uint64_t > l_intercept (mss::power_thermal::SIZE_OF_POWER_CURVES_ATTRS, 0);
- std::vector< uint64_t > l_thermal_power_limit (mss::power_thermal::SIZE_OF_THERMAL_ATTR, 0);
+ std::vector< uint64_t > l_slope (TT::SIZE_OF_POWER_CURVES_ATTRS, 0);
+ std::vector< uint64_t > l_intercept (TT::SIZE_OF_POWER_CURVES_ATTRS, 0);
+ std::vector< uint64_t > l_thermal_power_limit (TT::SIZE_OF_THERMAL_ATTR, 0);
uint16_t l_vddr_slope [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
uint16_t l_vddr_int [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
@@ -75,19 +77,21 @@ extern "C"
// Return error if safemode throttle utilization is less than MIN_UTIL
// This section needs to be in braces otherwise the compile will fail
{
+ using TT = mss::power_thermal::throttle_traits<>;
+ const uint64_t l_min_util = TT::MIN_UTIL;
uint16_t l_throttle_per_port = 0;
uint32_t l_throttle_denominator = 0;
FAPI_TRY(mss::mrw_mem_m_dram_clocks(l_throttle_denominator), "Error in p9_mss_eff_config_thermal" );
FAPI_TRY(mss::mrw_safemode_mem_throttled_n_commands_per_port(l_throttle_per_port),
"Error in p9_mss_eff_config_thermal" );
- FAPI_ASSERT( (l_throttle_per_port >= (mss::power_thermal::MIN_UTIL * l_throttle_denominator /
+ FAPI_ASSERT( (l_throttle_per_port >= (TT::MIN_UTIL * l_throttle_denominator /
mss::power_thermal::DRAM_BUS_UTILS / mss::power_thermal::UTIL_CONVERSION)),
fapi2::MSS_MRW_SAFEMODE_THROTTLE_NOT_SUPPORTED()
.set_MRW_SAFEMODE_N_VALUE(l_throttle_per_port)
.set_MRW_DRAM_CLOCK_THROTTLE_M(l_throttle_denominator)
- .set_MIN_UTIL_VALUE(mss::power_thermal::MIN_UTIL),
+ .set_MIN_UTIL_VALUE(l_min_util),
"MRW safemode attribute (N=%d, M=%d) has less util than the min util allowed (%d centi percent)",
- l_throttle_per_port, l_throttle_denominator, mss::power_thermal::MIN_UTIL);
+ l_throttle_per_port, l_throttle_denominator, l_min_util);
}
//Restore runtime_throttles from safemode setting
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C
index 7d770fc13..6c24fd182 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C
@@ -48,7 +48,7 @@
#include <lib/freq/nimbus_freq_traits.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <generic/memory/lib/utils/freq/gen_mss_freq.H>
-#include <generic/memory/lib/data_engine/pre_data_init.H>
+#include <lib/eff_config/pre_data_init.H>
using fapi2::TARGET_TYPE_MCS;
using fapi2::TARGET_TYPE_MCA;
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq_system.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq_system.C
index cba559c16..7721c724d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq_system.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq_system.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,7 +39,7 @@
#include <mss.H>
#include <p9_mss_freq_system.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <lib/freq/sync.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.C
index 150f725a3..80b54d1ff 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.C
@@ -39,16 +39,15 @@
#include <lib/dimm/rank.H>
#include <generic/memory/lib/utils/poll.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <lib/mcbist/address.H>
-#include <lib/mcbist/patterns.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H>
#include <lib/mcbist/memdiags.H>
#include <lib/mcbist/mcbist.H>
#include <lib/mc/port.H>
-#include <lib/mcbist/sim.H>
-#include <lib/ecc/ecc.H>
-#include <lib/fir/memdiags_fir.H>
+#include <lib/fir/unmask.H>
+#include <generic/memory/lib/ecc/ecc.H>
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_SYSTEM;
@@ -181,7 +180,7 @@ extern "C"
l_probes);
FAPI_ASSERT( l_poll_results == true,
- fapi2::MSS_MEMDIAGS_SUPERFAST_INIT_FAILED_TO_INIT().set_MCBIST_TARGET(i_target),
+ fapi2::MSS_MEMDIAGS_SUPERFAST_INIT_FAILED_TO_INIT().set_MC_TARGET(i_target),
"p9_mss_memdiag (init) timedout %s", mss::c_str(i_target) );
// Unmask firs after memdiags and turn off FIFO mode
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_scominit.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_scominit.C
index 3ee15dc3b..9dc8d134c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_scominit.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_scominit.C
@@ -40,11 +40,11 @@
#include <p9n_mcbist_scom.H>
#include <p9n_ddrphy_scom.H>
#include <generic/memory/lib/utils/count_dimm.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <lib/phy/ddr_phy.H>
#include <lib/mc/mc.H>
#include <lib/fir/unmask.H>
-#include <generic/memory/lib/utils/find_magic.H>
+#include <lib/utils/find_magic.H>
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCBIST;
@@ -119,7 +119,7 @@ fapi2::ReturnCode p9_mss_scominit( const fapi2::Target<TARGET_TYPE_MCBIST>& i_ta
FAPI_TRY( mss::phy_scominit(i_target), "%s failed phy_scominit", mss::c_str(i_target) );
// Do FIRry things
- FAPI_TRY( mss::unmask::after_scominit<mss::mc_type::NIMBUS>(i_target), "%s failed after_scominit",
+ FAPI_TRY( mss::unmask::after_scominit(i_target), "%s failed after_scominit",
mss::c_str(i_target) );
fapi_try_exit:
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C
index b6845295e..caba47caf 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C
@@ -40,106 +40,34 @@
#include <lib/dimm/rank.H>
#include <lib/mcbist/address.H>
#include <lib/mcbist/mcbist.H>
-#include <lib/mcbist/patterns.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H>
#include <lib/mcbist/memdiags.H>
-#include <lib/mcbist/sim.H>
#include <generic/memory/lib/utils/count_dimm.H>
-#include <lib/fir/memdiags_fir.H>
+#include <lib/fir/unmask.H>
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_SYSTEM;
using fapi2::FAPI2_RC_SUCCESS;
-///
-/// @brief Begin background scrub
-/// @param[in] i_target MCBIST
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode p9_mss_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
+extern "C"
{
- FAPI_INF("Start mss scrub");
-
- // If there are no DIMM we don't need to bother. In fact, we can't as we didn't setup
- // attributes for the PHY, etc.
- if (mss::count_dimm(i_target) == 0)
- {
- FAPI_INF("... skipping scrub for %s - no DIMM ...", mss::c_str(i_target));
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
- // If we're running in the simulator, we want to only touch the addresses which training touched
- uint8_t l_sim = 0;
- bool l_poll_results = false;
- fapi2::buffer<uint64_t> l_status;
-
- // A small vector of addresses to poll during the polling loop
- const std::vector<mss::poll_probe<fapi2::TARGET_TYPE_MCBIST>> l_probes =
- {
- {i_target, "mcbist current address", MCBIST_MCBMCATQ},
- };
-
- // We'll fill in the initial delay below
- mss::poll_parameters l_poll_parameters(0, 200, 100 * mss::DELAY_1MS, 200, 10000);
- uint64_t l_memory_size = 0;
-
- FAPI_TRY( mss::eff_memory_size<mss::mc_type::NIMBUS>(i_target, l_memory_size) );
- l_poll_parameters.iv_initial_delay = mss::calculate_initial_delay(i_target, (l_memory_size * mss::BYTES_PER_GB));
- FAPI_TRY( mss::is_simulation( l_sim) );
-
- if (l_sim)
+ ///
+ /// @brief Begin background scrub
+ /// @param[in] i_target MCBIST
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode p9_mss_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
{
- fapi2::ReturnCode l_rc;
-
- // Use some sort of pattern in sim in case the verification folks need to look for something
- // TK. Need a verification pattern. This is a not-good pattern for verification ... We don't really
- // have a good pattern for verification defined.
- FAPI_INF("running mss sim init in place of scrub");
- l_rc = mss::mcbist::sim::sf_init(i_target, mss::mcbist::PATTERN_0);
-
- // Unmask firs and turn off FIFO mode before returning
- FAPI_TRY ( mss::unmask::after_memdiags( i_target ) );
- FAPI_TRY ( mss::unmask::after_background_scrub( i_target ) );
- FAPI_TRY ( mss::reset_reorder_queue_settings(i_target) );
-
- return l_rc;
+ FAPI_INF("Start mss scrub for %s", mss::c_str(i_target));
+ // Initialize memory and set firs accordingly
+ FAPI_TRY(mss::memdiags::mss_initialize_memory(i_target));
+ // Kickoff background scrub and unmask firs
+ FAPI_TRY(mss::memdiags::mss_background_scrub_helper(i_target));
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
- // In Cronus on hardware (which is how we got here - f/w doesn't call this) we want
- // to call sf_init (0's)
- // TK we need to check FIR given the way this is right now, we should adjust with better stop
- // conditions when we learn more about what we want to find in the lab
- FAPI_TRY( mss::memdiags::sf_init(i_target, mss::mcbist::PATTERN_0) );
-
- // Poll for completion.
- l_poll_results = mss::poll(i_target, MCBIST_MCBISTFIRQ, l_poll_parameters,
- [&l_status](const size_t poll_remaining,
- const fapi2::buffer<uint64_t>& stat_reg) -> bool
- {
- FAPI_DBG("mcbist firq 0x%llx, remaining: %d", stat_reg, poll_remaining);
- l_status = stat_reg;
- return l_status.getBit<MCBIST_MCBISTFIRQ_MCBIST_PROGRAM_COMPLETE>() == true;
- },
- l_probes);
-
- FAPI_ASSERT( l_poll_results == true,
- fapi2::MSS_MEMDIAGS_SUPERFAST_INIT_FAILED_TO_INIT().set_MCBIST_TARGET(i_target),
- "p9_mss_scrub (init) timedout %s", mss::c_str(i_target) );
-
- // Unmask firs after memdiags and turn off FIFO mode
- FAPI_TRY ( mss::unmask::after_memdiags( i_target ) );
- FAPI_TRY ( mss::reset_reorder_queue_settings(i_target) );
-
- // Start background scrub
- FAPI_TRY ( mss::memdiags::background_scrub( i_target,
- mss::mcbist::stop_conditions(),
- mss::mcbist::speed::BG_SCRUB,
- mss::mcbist::address() ) );
-
- // Unmask firs after background scrub is started
- FAPI_TRY ( mss::unmask::after_background_scrub( i_target ) );
-
-fapi_try_exit:
- return fapi2::current_err;
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_thermal_init.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_thermal_init.C
index 2523989fa..45ea4392d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_thermal_init.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_thermal_init.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -34,8 +34,9 @@
// *HWP Consumed by: FSP:HB
#include <fapi2.H>
+#include <lib/shared/nimbus_defaults.H>
#include <lib/mc/mc.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <p9_mss_thermal_init.H>
using fapi2::TARGET_TYPE_MCS;
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
index 076cd911c..01bd44749 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,6 +37,7 @@
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
+#include <lib/shared/nimbus_defaults.H>
#include <p9_mss_utils_to_throttle.H>
// fapi2
@@ -45,7 +46,7 @@
// mss lib
#include <lib/power_thermal/throttle.H>
#include <generic/memory/lib/utils/index.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <lib/utils/mss_nimbus_conversions.H>
#include <lib/power_thermal/throttle.H>
#include <lib/mss_attribute_accessors.H>
@@ -71,6 +72,8 @@ extern "C"
///
fapi2::ReturnCode p9_mss_utils_to_throttle( const std::vector< fapi2::Target<TARGET_TYPE_MCS> >& i_targets )
{
+ constexpr uint64_t l_min_util = mss::power_thermal::throttle_traits<mss::mc_type::NIMBUS>::MIN_UTIL;
+
FAPI_INF("Entering p9_mss_utils_to_throttle");
std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCA> > l_exceeded_power;
@@ -87,20 +90,24 @@ extern "C"
uint32_t l_max_databus_util = {};
uint32_t l_dram_clocks = 0;
uint16_t l_safemode_throttle_per_port = 0;
- double l_calc_util_safemode = 0;
+ uint32_t l_calc_util = 0;
uint16_t l_n_port[mss::PORTS_PER_MCS] = {};
uint16_t l_n_slot[mss::PORTS_PER_MCS] = {};
uint32_t l_max_power[mss::PORTS_PER_MCS] = {};
- FAPI_TRY( mss::mrw_mem_m_dram_clocks(l_dram_clocks) );
+ FAPI_TRY(mss::mrw_mem_m_dram_clocks(l_dram_clocks) );
//Util attribute set by OCC
- FAPI_TRY( mss::databus_util(l_mcs, l_input_databus_util) );
- FAPI_TRY( mss::mrw_max_dram_databus_util(l_max_databus_util));
+ FAPI_TRY(mss::databus_util(l_mcs, l_input_databus_util) );
+ FAPI_TRY(mss::mrw_max_dram_databus_util(l_max_databus_util));
+ FAPI_TRY(mss::mrw_safemode_mem_throttled_n_commands_per_port(l_safemode_throttle_per_port));
for( const auto& l_mca : mss::find_targets<TARGET_TYPE_MCA>(l_mcs) )
{
+ fapi2::ReturnCode l_rc;
+ bool l_safemode = false;
+
FAPI_INF("Input databus utilization for %s is %d",
mss::c_str(l_mca),
l_input_databus_util[mss::index(l_mca)]);
@@ -113,56 +120,31 @@ extern "C"
}
// If input utilization is zero, use mrw safemode throttle values for utilization
- bool l_safemode = false;
-
- if (l_input_databus_util[l_port_num] == 0)
- {
- FAPI_TRY(mss::mrw_safemode_mem_throttled_n_commands_per_port(l_safemode_throttle_per_port),
- "Error in getting safemode throttles" );
- FAPI_TRY( mss::power_thermal::calc_util_from_throttles(l_safemode_throttle_per_port, l_dram_clocks,
- l_calc_util_safemode),
- "%s Error calculating utilization from safemode throttle %d and mem clocks %d",
- mss::c_str(l_mca),
- l_safemode_throttle_per_port,
- l_dram_clocks);
- FAPI_INF( "%s Safemode throttles being used since input util is zero: Using N=%d, Utilization %f",
- mss::c_str(l_mca),
- l_safemode_throttle_per_port,
- l_calc_util_safemode);
- l_safemode = true;
- l_input_databus_util[l_port_num] = l_calc_util_safemode;
- }
-
- //Make sure MIN_UTIL <= input_utilization <= max_utilization
- const uint32_t l_databus_util = ( l_input_databus_util[l_port_num] >= mss::power_thermal::MIN_UTIL) ?
- std::min(l_input_databus_util[l_port_num], l_max_databus_util)
- : mss::power_thermal::MIN_UTIL;
+ // else make sure we're within our maximum utilization limit
+ FAPI_TRY(mss::power_thermal::calc_utilization<mss::mc_type::NIMBUS>(l_mca,
+ l_input_databus_util[l_port_num],
+ l_dram_clocks,
+ l_safemode_throttle_per_port,
+ l_max_databus_util,
+ l_calc_util,
+ l_util_error,
+ l_safemode));
// Error if utilization is less than MIN_UTIL
// Don't exit, let HWP finish and return error at end
- if (l_input_databus_util[l_port_num] < mss::power_thermal::MIN_UTIL)
- {
- FAPI_ASSERT_NOEXIT( false,
- fapi2::MSS_MIN_UTILIZATION_ERROR()
- .set_INPUT_UTIL_VALUE(l_input_databus_util[l_port_num])
- .set_MIN_UTIL_VALUE(mss::power_thermal::MIN_UTIL),
- "%s Input utilization (%d) less than minimum utilization allowed (%d)",
- mss::c_str(l_mca), l_input_databus_util[l_port_num], mss::power_thermal::MIN_UTIL);
- l_util_error = true;
- }
-
- //Make a throttle object in order to calculate the port power
- fapi2::ReturnCode l_rc;
-
- mss::power_thermal::throttle l_throttle (l_mca, l_rc);
- FAPI_TRY(l_rc, "Error calculating mss::power_thermal::throttle constructor in p9_mss_utils_to_throttles");
+ FAPI_ASSERT_NOEXIT(!l_util_error,
+ fapi2::MSS_MIN_UTILIZATION_ERROR()
+ .set_INPUT_UTIL_VALUE(l_input_databus_util[l_port_num])
+ .set_MIN_UTIL_VALUE(l_min_util),
+ "%s Input utilization (%d) less than minimum utilization allowed (%d)",
+ mss::c_str(l_mca), l_input_databus_util[l_port_num], l_min_util);
- FAPI_INF( "%s MRW dram clock window: %d, databus utilization: %d",
- mss::c_str(l_mca),
- l_dram_clocks,
- l_databus_util);
+ // Make a throttle object in order to calculate the port power
+ mss::power_thermal::throttle<mss::mc_type::NIMBUS> l_throttle (l_mca, l_rc);
+ FAPI_TRY(l_rc, "%s Error calculating mss::power_thermal::throttle constructor in p9_mss_utils_to_throttles",
+ mss::c_str(l_mca));
- FAPI_TRY( l_throttle.calc_slots_and_power(l_databus_util));
+ FAPI_TRY( l_throttle.calc_slots_and_power(l_calc_util));
FAPI_INF( "%s Calculated N commands per port %d, per slot %d, commands per dram clock window %d, maxpower is %d",
mss::c_str(l_mca),
@@ -194,7 +176,7 @@ extern "C"
// Return a failing RC code if we had any input utilization values less than MIN_UTIL
if (l_util_error)
{
- fapi2::current_err = fapi2::FAPI2_RC_FALSE;
+ fapi2::current_err = fapi2::RC_MSS_MIN_UTILIZATION_ERROR;
}
fapi_try_exit:
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9a_omi_init.C b/src/import/chips/p9/procedures/hwp/memory/p9a_omi_init.C
index b11696597..60d52d748 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9a_omi_init.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9a_omi_init.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -90,20 +90,13 @@ fapi2::ReturnCode p9a_omi_init_enable_templates(const fapi2::Target<fapi2::TARGE
l_enable_tmpl_7),
"Error from FAPI_ATTR_GET (ATTR_PROC_ENABLE_DL_TMPL_7)");
- FAPI_ASSERT(l_enable_tmpl_1 != 0,
- fapi2::PROC_DOWNSTREAM_TMPL1_REQUIRED_ERR()
- .set_TARGET(i_target),
- "Downstream template 1 is required.");
-
- FAPI_ASSERT(l_enable_tmpl_4 != 0 || l_enable_tmpl_7 != 0,
- fapi2::PROC_DOWNSTREAM_TMPL4OR7_REQUIRED_ERR()
- .set_TARGET(i_target),
- "Downstream template 4 and/or 7 is required.");
-
- //Turn off temp0_only
- FAPI_TRY(getScom(i_target, P9A_MCC_DSTLCFG, l_data));
- l_data.clearBit<P9A_MCC_DSTLCFG_TMPL0_ONLY>();
- FAPI_TRY(putScom(i_target, P9A_MCC_DSTLCFG, l_data));
+ if (l_enable_tmpl_1 || l_enable_tmpl_4 || l_enable_tmpl_7)
+ {
+ //Turn off temp0_only
+ FAPI_TRY(getScom(i_target, P9A_MCC_DSTLCFG, l_data));
+ l_data.clearBit<P9A_MCC_DSTLCFG_TMPL0_ONLY>();
+ FAPI_TRY(putScom(i_target, P9A_MCC_DSTLCFG, l_data));
+ }
fapi_try_exit:
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_fab_iovalid.C b/src/import/chips/p9/procedures/hwp/nest/p9_fab_iovalid.C
index 9f1a45f6b..58e2393cc 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_fab_iovalid.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_fab_iovalid.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -998,7 +998,7 @@ fapi2::ReturnCode p9_fab_iovalid_get_link_delay(
{
FAPI_DBG("Start");
fapi2::buffer<uint64_t> l_link_delay_reg;
- uint32_t l_sublink_delay[2];
+ uint32_t l_sublink_delay[2] = {};
// read link delay register, extract hi/lo delay values & return their average
FAPI_TRY(fapi2::getScom(i_target, i_link_ctl.tl_link_delay_addr, l_link_delay_reg),
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C b/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C
index 342e32247..0feeff44e 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C
@@ -745,7 +745,7 @@ fapi2::ReturnCode EffGroupingMccAttrs::getAttrs(
iv_dimmSize = (iv_ocmbs.size() * l_min_size);
// Display this OMI's attribute info
- FAPI_INF("EffGroupingMccAttrs::getAttrs: MCC %d, OCMBs attached %d, "
+ FAPI_INF("EffGroupingMccAttrs::getAttrs: MCC %d, OCMBs w/ memory attached %d, "
"iv_dimmSize %d GB ",
iv_unitPos, iv_ocmbs.size(), iv_dimmSize);
@@ -1553,7 +1553,8 @@ fapi2::ReturnCode EffGroupingBaseSizeData::set_HTM_OCC_base_addr(
}
// Setting NHTM & OCC base addresses
- if ( (l_nhtmSize + l_chtmSize) < i_procAttrs.iv_occSandboxSize)
+ // Set larger allocations on top (at higher addresses)
+ if ( (l_nhtmSize + l_chtmSize) >= i_procAttrs.iv_occSandboxSize)
{
iv_occ_sandbox_base = l_mem_bases[l_index] + l_mem_sizes[l_index];
iv_nhtm_bar_base = iv_occ_sandbox_base + i_procAttrs.iv_occSandboxSize;
@@ -1564,6 +1565,23 @@ fapi2::ReturnCode EffGroupingBaseSizeData::set_HTM_OCC_base_addr(
iv_occ_sandbox_base = iv_nhtm_bar_base + l_nhtmSize + l_chtmSize;
}
+ // Verify NHTM base addresses aligned with allocated size.
+ // The OCC sandbox base is just a FW scratch area and no HW
+ // functions mapped to it so we don't need to check its base alignment.
+ if ( ((l_nhtmSize + l_chtmSize) > 0) &&
+ (iv_nhtm_bar_base & ((l_nhtmSize + l_chtmSize) - 1)) )
+ {
+ FAPI_ASSERT(false,
+ fapi2::MSS_EFF_GROUPING_ADDRESS_NOT_ALIGNED()
+ .set_NHTM_BAR_BASE(iv_nhtm_bar_base)
+ .set_NHTM_SIZE(l_nhtmSize)
+ .set_CHTM_SIZE(l_chtmSize),
+ "EffGroupingBaseSizeData::set_HTM_OCC_base_addr: "
+ "NHTM BAR base address is not aligned with its size "
+ "NHTM_BAR_BASE 0x%.16llX, NHTM_SIZE 0x%.16llX, CTHM_SIZE 0x%.16llX",
+ iv_nhtm_bar_base, l_nhtmSize, l_chtmSize);
+ }
+
// Setting CHTM base addresses
for (uint8_t ii = 0; ii < NUM_OF_CHTM_REGIONS; ii++)
{
@@ -1608,7 +1626,8 @@ fapi2::ReturnCode EffGroupingBaseSizeData::set_HTM_OCC_base_addr(
}
// Update mem sizes with working array values
- if (l_numRegions == NUM_NON_MIRROR_REGIONS)
+ if (i_sysAttrs.iv_selectiveMode ==
+ fapi2::ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL)
{
memcpy(iv_memory_sizes, l_mem_sizes, sizeof(iv_memory_sizes));
}
@@ -1809,7 +1828,8 @@ fapi2::ReturnCode EffGroupingBaseSizeData::setSMFBaseSizeData(
}
// Update mem sizes with working array values
- if (l_numRegions == NUM_NON_MIRROR_REGIONS)
+ if (i_sysAttrs.iv_selectiveMode ==
+ fapi2::ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL)
{
memcpy(iv_memory_sizes, l_mem_sizes, sizeof(iv_memory_sizes));
}
@@ -1839,7 +1859,7 @@ fapi2::ReturnCode EffGroupingBaseSizeData::setSMFBaseSizeData(
ii, l_mem_bases[ii], l_mem_sizes[ii]);
}
- FAPI_INF("SMF_BASE %.16lld (%d GB)", iv_smf_bar_base, iv_smf_bar_base >> 30);
+ FAPI_INF("SMF_BASE 0x%.16llX", iv_smf_bar_base);
for (uint8_t ii = 0; ii < l_numRegions; ii++)
{
@@ -2147,7 +2167,6 @@ void grouping_group8PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
o_groupData.iv_data[g][MEMBER_IDX(5)] = MCPORTID_5;
o_groupData.iv_data[g][MEMBER_IDX(6)] = MCPORTID_3;
o_groupData.iv_data[g][MEMBER_IDX(7)] = MCPORTID_7;
- g++; // increase o_groupData.iv_numGroups
// Record which MC ports were grouped
// Check if OMI mirrorable
@@ -2163,6 +2182,8 @@ void grouping_group8PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
}
}
+ g++; // increase o_groupData.iv_numGroups
+
FAPI_INF("grouping_group8PortsPerGroup: Successfully grouped 8 "
"MC ports.");
}
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.C b/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.C
index 90e62859e..46a87c966 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.C
@@ -6,6 +6,7 @@
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* [+] Inspur Power Systems Corp. */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -44,17 +45,20 @@
#include <p9_mc_scom_addresses_fld.H>
#include <p9n2_mc_scom_addresses.H>
#include <p9n2_mc_scom_addresses_fld.H>
+#include <p9a_mc_scom_addresses.H>
+#include <p9a_mc_scom_addresses_fld.H>
#include <p9a_misc_scom_addresses.H>
#include <p9a_misc_scom_addresses_fld.H>
#include <p9a_addr_ext.H>
#include <map>
#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/memory_size.H>
-#include <exp_inband.H>
+#include <lib/inband/exp_inband.H>
///----------------------------------------------------------------------------
/// Constant definitions
///----------------------------------------------------------------------------
+const uint8_t USTL_MDI_EQUAL_ONE = 1;
const uint8_t MAX_MC_PORTS_PER_MCS = 2; // 2 MC ports per MCS
const uint8_t NO_CHANNEL_PER_GROUP = 0xFF; // Init value of channel per group
@@ -300,12 +304,12 @@ fapi2::ReturnCode getMcMemSize(
uint8_t l_mcaPos = 0;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mca, l_mcaPos),
"Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Get the amount of memory behind this MCA target
FAPI_TRY(mss::eff_memory_size<mss::mc_type::NIMBUS>(l_mca, l_mcaSize),
"Error returned from eff_memory_size - MCA, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
FAPI_INF("MCA %u: Total DIMM size %lu GB", l_mcaPos, l_mcaSize);
o_mcSize += l_mcaSize;
@@ -334,12 +338,12 @@ fapi2::ReturnCode getMcMemSize(
uint8_t l_dmiPos = 0;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_dmi, l_dmiPos),
"Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Get the amount of memory behind this DMI target
FAPI_TRY(mss::eff_memory_size<mss::mc_type::CENTAUR>(l_dmi, l_chSize),
"Error returned from eff_memory_size - DMI, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
FAPI_INF("DMI %u: Total DIMM size %lu GB", l_dmiPos, l_chSize);
o_mcSize += l_chSize;
@@ -370,19 +374,19 @@ fapi2::ReturnCode getMcMemSize(
for (auto l_omi : l_omiChiplets)
{
- const auto& l_ocmb_chiplets = l_omi.getChildren<fapi2::TARGET_TYPE_OCMB_CHIP>();
+ const auto& l_ocmb_chips = l_omi.getChildren<fapi2::TARGET_TYPE_OCMB_CHIP>();
- if (!l_ocmb_chiplets.empty())
+ if (!l_ocmb_chips.empty())
{
uint8_t l_omiPos = 0;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_omi, l_omiPos),
"Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Get the amount of memory behind this OMI
- FAPI_TRY(mss::eff_memory_size<mss::mc_type::EXPLORER>(l_ocmb_chiplets[0], l_chSize),
+ FAPI_TRY(mss::eff_memory_size<mss::mc_type::EXPLORER>(l_ocmb_chips[0], l_chSize),
"Error returned from eff_memory_size - ocmb, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
FAPI_INF("OMI %u: Total DIMM size %lu GB", l_omiPos, l_chSize);
@@ -506,14 +510,14 @@ fapi2::ReturnCode validateGroupData(
uint8_t l_mcPos = 0;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mc, l_mcPos),
"Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
FAPI_INF("validateGroupData: MC unit pos %d", l_mcPos);
// Get the memory size behind this MC
FAPI_TRY(getMcMemSize(l_mc, l_mcSize),
"Error returned from getMcMemSize, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Get this MC memsize reported in Group data
getGroupDataMcMemSize(l_mcPos, i_omi, i_groupData, l_portFound,
@@ -536,6 +540,8 @@ fapi2::ReturnCode validateGroupData(
} // MC loop
+ FAPI_INF("Total memory size= %lu GB", l_mcSize);
+
// Assert if a PORT_ID is found more than once in any group
for (uint8_t ii = 0; ii < NUM_MC_PORTS_PER_PROC; ii++)
{
@@ -590,7 +596,7 @@ fapi2::ReturnCode getGroupSizeEncodedValue(
uint8_t l_mcPos = 0;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_mcTarget, l_mcPos),
"Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Assert if can't find Group size in the table
FAPI_ASSERT( false,
fapi2::MSS_SETUP_BARS_INVALID_GROUP_SIZE()
@@ -761,7 +767,7 @@ fapi2::ReturnCode getNonMirrorBarIdSize(const fapi2::Target<T>& i_mcTarget,
FAPI_TRY(getGroupSizeEncodedValue(i_mcTarget, i_portInfo[0].groupSize,
o_mcBarData.MCFGP_group_size),
"getGroupSizeEncodedValue() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Group base address
o_mcBarData.MCFGP_groupBaseAddr = i_portInfo[0].groupBaseAddr;
@@ -774,7 +780,7 @@ fapi2::ReturnCode getNonMirrorBarIdSize(const fapi2::Target<T>& i_mcTarget,
FAPI_TRY(getGroupSizeEncodedValue(i_mcTarget, i_portInfo[1].groupSize,
o_mcBarData.MCFGPM_group_size),
"getGroupSizeEncodedValue() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Group base address
o_mcBarData.MCFGPM_groupBaseAddr = i_portInfo[1].groupBaseAddr;
@@ -873,7 +879,7 @@ fapi2::ReturnCode getNonMirrorBarIdSize(const fapi2::Target<fapi2::TARGET_TYPE_M
FAPI_TRY(getGroupSizeEncodedValue(i_mcTarget, i_portInfo.groupSize,
o_mcBarData.MCFGP_group_size),
"getGroupSizeEncodedValue() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Group base address
o_mcBarData.MCFGP_groupBaseAddr = i_portInfo.groupBaseAddr;
@@ -886,7 +892,7 @@ fapi2::ReturnCode getNonMirrorBarIdSize(const fapi2::Target<fapi2::TARGET_TYPE_M
FAPI_TRY(getGroupSizeEncodedValue(i_mcTarget, i_portInfo.groupSize,
o_mcBarData.MCFGPM_group_size),
"getGroupSizeEncodedValue() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Group base address
o_mcBarData.MCFGPM_groupBaseAddr = i_portInfo.groupBaseAddr;
@@ -1040,7 +1046,7 @@ fapi2::ReturnCode getMirrorBarData(const fapi2::Target<T>& i_mcTarget,
FAPI_TRY(getGroupSizeEncodedValue(i_mcTarget, i_portInfo[1].groupSize,
io_mcBarData.MCFGPM_group_size),
"getGroupSizeEncodedValue() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Group base address
io_mcBarData.MCFGPM_groupBaseAddr = i_portInfo[1].groupBaseAddr;
@@ -1106,7 +1112,7 @@ fapi2::ReturnCode getMirrorBarData(const fapi2::Target<fapi2::TARGET_TYPE_MCC>&
FAPI_TRY(getGroupSizeEncodedValue(i_mcTarget, i_portInfo.groupSize,
io_mcBarData.MCFGPM_group_size),
"getGroupSizeEncodedValue() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Group base address
io_mcBarData.MCFGPM_groupBaseAddr = i_portInfo.groupBaseAddr;
@@ -1462,7 +1468,7 @@ fapi2::ReturnCode buildMCBarData(
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MRW_HW_MIRRORING_ENABLE,
FAPI_SYSTEM, l_mirror_ctl),
"Error getting ATTR_MRW_HW_MIRRORING_ENABLE, "
- "l_rc 0x%.8X", (uint64_t)fapi2::current_err);
+ "l_rc 0x%.8X", uint64_t(fapi2::current_err));
for (auto l_mc : i_mcTargets)
{
@@ -1473,7 +1479,7 @@ fapi2::ReturnCode buildMCBarData(
uint8_t l_unitPos = 0;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mc, l_unitPos),
"Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
fapi2::toString(l_mc, l_targetStr, sizeof(l_targetStr));
FAPI_INF("Build BAR data for MC target: %s", l_targetStr);
@@ -1493,7 +1499,7 @@ fapi2::ReturnCode buildMCBarData(
// ---- Build MCFGP/MCFGM data based on port group info ----
FAPI_TRY(getNonMirrorBarData(l_mc, l_portInfo, l_mcBarData),
"getNonMirrorBarData() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// ---------------------------------------------------------------
// Set MC register values for mirror groups
@@ -1514,7 +1520,7 @@ fapi2::ReturnCode buildMCBarData(
// ---- Build MCFGM data based on port group info ----
FAPI_TRY(getMirrorBarData(l_mc, l_portInfoMirrored, l_mcBarData),
"getMirrorBarData() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
}
}
@@ -1563,7 +1569,7 @@ fapi2::ReturnCode buildMCBarData(
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MRW_HW_MIRRORING_ENABLE,
FAPI_SYSTEM, l_mirror_ctl),
"Error getting ATTR_MRW_HW_MIRRORING_ENABLE, "
- "l_rc 0x%.8X", (uint64_t)fapi2::current_err);
+ "l_rc 0x%.8X", uint64_t(fapi2::current_err));
for (auto l_mcc : i_mccTargets)
{
@@ -1574,7 +1580,7 @@ fapi2::ReturnCode buildMCBarData(
uint8_t l_unitPos = 0;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mcc, l_unitPos),
"Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
fapi2::toString(l_mcc, l_targetStr, sizeof(l_targetStr));
FAPI_INF("Build BAR data for MC target: %s", l_targetStr);
@@ -1593,7 +1599,7 @@ fapi2::ReturnCode buildMCBarData(
// ---- Build MCFGP/MCFGM data based on port group info ----
FAPI_TRY(getNonMirrorBarData(l_mcc, l_portInfo, l_mcBarData),
"getNonMirrorBarData() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// ---------------------------------------------------------------
// Set MC register values for mirror groups
@@ -1610,7 +1616,7 @@ fapi2::ReturnCode buildMCBarData(
// ---- Build MCFGM data based on port group info ----
FAPI_TRY(getMirrorBarData(l_mcc, l_portInfoMirrored, l_mcBarData),
"getMirrorBarData() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
}
// Add to output pair
@@ -1675,13 +1681,12 @@ fapi2::ReturnCode writeMCBarData(
FAPI_DBG("Entering");
fapi2::buffer<uint64_t> l_scomData(0);
-
fapi2::ATTR_MSS_INTERLEAVE_GRANULARITY_Type l_interleave_granule_size;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_INTERLEAVE_GRANULARITY,
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
l_interleave_granule_size),
"Error getting ATTR_MSS_INTERLEAVE_GRANULARITY, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
for (auto l_pair : i_mcBarDataPair)
{
@@ -1718,11 +1723,13 @@ fapi2::ReturnCode writeMCBarData(
MCS_MCFGP_GROUP_BASE_ADDRESS_LEN>(
(l_data.MCFGP_groupBaseAddr >> 2));
+
// configure interleave granularity if 2/4/8 MC per group only
- if ((l_data.MCFGP_chan_per_group == 0b0100) || // 2 MC/group
- (l_data.MCFGP_chan_per_group == 0b0101) ||
- (l_data.MCFGP_chan_per_group == 0b0110) || // 4 MC/group
- (l_data.MCFGP_chan_per_group == 0b1000)) // 8 MC/group
+ if ( (l_data.MCFGP_chan_per_group == 0b0100) || // 2 MC/group
+ (l_data.MCFGP_chan_per_group == 0b0101) ||
+ (l_data.MCFGP_chan_per_group == 0b0110) || // 4 MC/group
+ (l_data.MCFGP_chan_per_group == 0b1000) // 8 MC/group
+ )
{
fapi2::buffer<uint64_t> l_mcmode0_scom_data;
FAPI_TRY(fapi2::getScom(l_target, MCS_MCMODE0, l_mcmode0_scom_data),
@@ -1971,7 +1978,7 @@ fapi2::ReturnCode writeMCCInterleaveGranularity(
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
l_interleave_granule_size),
"Error getting ATTR_MSS_INTERLEAVE_GRANULARITY, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
for (auto l_pair : i_mcBarDataPair)
{
@@ -1982,33 +1989,6 @@ fapi2::ReturnCode writeMCCInterleaveGranularity(
if (l_data.MCFGP_valid == true)
{
fapi2::Target<fapi2::TARGET_TYPE_MI> l_mi_target = l_target.getParent<fapi2::TARGET_TYPE_MI>();
-
- // configure interleave granularity if 1/2/4/8 MC per group only
- if ((l_data.MCFGP_chan_per_group == 0) || // 8 MC/group
- (l_data.MCFGP_chan_per_group == 1) || // 1 MC/group
- (l_data.MCFGP_chan_per_group == 2) || // 2 MC/group
- (l_data.MCFGP_chan_per_group == 4)) // 4 MC/group
- {
- //Only set to true if the value for the target is not set yet
- if (l_granule_supported.find(l_mi_target) == l_granule_supported.end())
- {
- l_granule_supported[l_mi_target] = true;
- }
- }
- else
- {
- //Always set to false if we find one channel that cannot support it.
- l_granule_supported[l_mi_target] = false;
- }
- }
- }
-
- for ( auto l_it = l_granule_supported.begin(); l_it != l_granule_supported.end(); l_it++ )
- {
- if (l_it->second)
- {
- auto l_mi_target = l_it->first;
-
fapi2::buffer<uint64_t> l_mcmode0_scom_data;
FAPI_TRY(fapi2::getScom(l_mi_target, P9A_MI_MCMODE0, l_mcmode0_scom_data),
"Error reading from MCS_MCMODE0 reg");
@@ -2065,10 +2045,19 @@ fapi2::ReturnCode writeMCBarData(
uint8_t l_pos;
fapi2::buffer<uint64_t> l_scomData(0);
+ fapi2::buffer<uint64_t> l_scomData_mirror(0);
+ fapi2::buffer<uint64_t> l_scomData_mcmode(0);
fapi2::buffer<uint64_t> l_extAddr(0);
fapi2::buffer<uint64_t> l_norAddr;
uint64_t l_ext_mask;
+ const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
+ uint8_t mirror_policy;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEM_MIRROR_PLACEMENT_POLICY, FAPI_SYSTEM, mirror_policy),
+ "Error reading ATTR_MEM_MIRROR_PLACEMENT_POLICY, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
FAPI_TRY(p9a_get_ext_mask(l_ext_mask));
FAPI_TRY(writeMCCInterleaveGranularity(i_mcBarDataPair));
@@ -2084,7 +2073,7 @@ fapi2::ReturnCode writeMCBarData(
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_target, l_pos),
"Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// 1. ---- Set MCFGP reg -----
l_scomData = 0;
@@ -2174,55 +2163,176 @@ fapi2::ReturnCode writeMCBarData(
"Error writing to P9A_MI_MCFGPM1 reg");
}
- // 3. ---- Set MCFGPA reg -----
+ // 3. ---- Set MCFGPA/MCFGPMA regs -----
l_scomData = 0;
-
- // Assert if both HOLE1 and SMF are valid, settings will overlap
- FAPI_ASSERT((l_data.MCFGPA_HOLE_valid[1] && l_data.MCFGPA_SMF_valid) == 0,
- fapi2::MSS_SETUP_BARS_HOLE1_SMF_CONFLICT()
- .set_TARGET(l_target)
- .set_HOLE1_VALID(l_data.MCFGPA_HOLE_valid[1])
- .set_SMF_VALID(l_data.MCFGPA_SMF_valid),
- "Error: MCFGPA HOLE1 and SMF are both valid, settings will overlap");
+ l_scomData_mirror = 0;
// Hole 0
if (l_data.MCFGPA_HOLE_valid[0] == true)
{
- // MCFGPA HOLE0 valid (bit 0)
- l_scomData.setBit<P9A_MI_MCFGP0A_HOLE_VALID>();
+ if(mirror_policy ==
+ fapi2::ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL) //Non-mirrored mode, but still set up mirrored equiv addressses
+ {
+ // Non-mirrored
+ // MCFGP0A HOLE valid (bit 0)
+ l_scomData.setBit<P9A_MI_MCFGP0A_HOLE_VALID>();
+
+ // Hole lower addr
+ // Hole always extends to end of range
+ FAPI_DBG("l_data.MCFGPA_HOLE_LOWER_addr[0]: %016llx", l_data.MCFGPA_HOLE_LOWER_addr[0]);
+ FAPI_TRY(extBar(l_ext_mask, l_data.MCFGPA_HOLE_LOWER_addr[0], l_extAddr));
+ l_scomData.insert<P9A_MI_MCFGP0A_HOLE_LOWER_ADDRESS,
+ P9A_MI_MCFGP0A_HOLE_LOWER_ADDRESS_LEN>(
+ (l_extAddr << 9)); //matches 17:31 extendedBarAddress shifts left 8 (17-8) = 9
+
+ // Mirrored Address = Non-mirrored >> 1 since bit 56 is not part of the dsaddr
+ // MCFGPM0A HOLE0 valid (bit 0)
+ l_scomData_mirror.setBit<P9A_MI_MCFGPM0A_HOLE_VALID>();
+
+ // Hole lower addr
+ // Hole always extends to end of range
+ FAPI_DBG("l_data.MCFGPA_HOLE_LOWER_addr[0]: %016llx", (l_data.MCFGPA_HOLE_LOWER_addr[0] >> 1));
+ FAPI_TRY(extBar(l_ext_mask, l_data.MCFGPA_HOLE_LOWER_addr[0], l_extAddr));
+ l_scomData_mirror.insert<P9A_MI_MCFGPM0A_HOLE_LOWER_ADDRESS,
+ P9A_MI_MCFGPM0A_HOLE_LOWER_ADDRESS_LEN>(
+ (l_extAddr << 8)); //matches 17:31 extendedBarAddress shifts left 8 (17- (8 + 1)) = 8
+ }
+ else
+ {
+ // Mirrored Address
+ // MCFGPM0A HOLE0 valid (bit 0)
+ l_scomData_mirror.setBit<P9A_MI_MCFGPM0A_HOLE_VALID>();
+
+ // Hole 0 lower addr
+ // Hole 0 always extends to end of range
+ FAPI_DBG("l_data.MCFGPA_HOLE_LOWER_addr[0]: %016llx", l_data.MCFGPA_HOLE_LOWER_addr[0]);
+ FAPI_TRY(extBar(l_ext_mask, l_data.MCFGPA_HOLE_LOWER_addr[0], l_extAddr));
+ l_scomData_mirror.insert<P9A_MI_MCFGPM0A_HOLE_LOWER_ADDRESS,
+ P9A_MI_MCFGPM0A_HOLE_LOWER_ADDRESS_LEN>(
+ (l_extAddr << 9)); //matches 17:31 extendedBarAddress shifts left 8 (17- 8) = 9
+
+ // Non-mirrored Address = Mirrored Address << 1 since bit 56 is part of the dsaddr
+ // MCFGPA HOLE0 valid (bit 0)
+ l_scomData.setBit<P9A_MI_MCFGP0A_HOLE_VALID>();
+
+ // Hole 0 lower addr
+ // Hole 0 always extends to end of range
+ FAPI_DBG("l_data.MCFGPA_HOLE_LOWER_addr[0]: %016llx", (l_data.MCFGPA_HOLE_LOWER_addr[0] << 1));
+ FAPI_TRY(extBar(l_ext_mask, l_data.MCFGPA_HOLE_LOWER_addr[0], l_extAddr));
+ l_scomData.insert<P9A_MI_MCFGP0A_HOLE_LOWER_ADDRESS,
+ P9A_MI_MCFGP0A_HOLE_LOWER_ADDRESS_LEN>(
+ (l_extAddr << 10)); //matches 17:31 extendedBarAddress shifts left 8 (17- (8 - 1)) = 10
- // Hole 0 lower addr
- // Hole 0 always extends to end of range
- FAPI_DBG("l_data.MCFGPA_HOLE_LOWER_addr[0]: %016llx", l_data.MCFGPA_HOLE_LOWER_addr[0]);
- FAPI_TRY(extBar(l_ext_mask, l_data.MCFGPA_HOLE_LOWER_addr[0], l_extAddr));
- l_scomData.insert<P9A_MI_MCFGP0A_HOLE_LOWER_ADDRESS,
- P9A_MI_MCFGP0A_HOLE_LOWER_ADDRESS_LEN>(
- (l_extAddr << 9)); //matches 17:31 extendedBarAddress shifts left 8 (17-8) = 9
+ }
}
// SMF
if (l_data.MCFGPA_SMF_valid == true)
{
- // MCFGPA SMF valid (bit 0)
- l_scomData.setBit<P9A_MI_MCFGP0A_SMF_VALID>();
+ FAPI_DBG("Writing SMF bit into address extension now");
+ // Set up Extension Address for SMF
+ FAPI_TRY(fapi2::getScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCMODE2, l_scomData_mcmode),
+ "Error reading to P9A_MI_MCMODE2 reg");
+ l_scomData_mcmode.setBit<P9A_MI_MCMODE2_CHIP_ADDRESS_EXTENSION_MASK_ENABLE>();
+ FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCMODE2, l_scomData_mcmode),
+ "Error writing to P9A_MI_MCMODE2 reg");
+
+ if(mirror_policy ==
+ fapi2::ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL) //Non-mirrored mode, but still set up mirrored equiv addressses
+ {
+ //Non-mirrored
+ // MCFGPA SMF valid (bit 0)
+ l_scomData.setBit<P9A_MI_MCFGP0A_SMF_VALID>();
+
+ // MCFGPA_SMF_UPPER_ADDRESS_AT_END_OF_RANGE
+ l_scomData.setBit<P9A_MI_MCFGP0A_SMF_EXTEND_TO_END_OF_RANGE>();
+
+ // SMF lower addr
+ l_norAddr = 0;
+ l_norAddr.insertFromRight<17, 19>(l_data.MCFGPA_SMF_LOWER_addr);
+ FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
+ l_scomData.insert<P9A_MI_MCFGP0A_SMF_LOWER_ADDRESS,
+ P9A_MI_MCFGP0A_SMF_LOWER_ADDRESS_LEN>(
+ (l_extAddr << 9)); //matches 17:35 extendBarAddress shifts left 8 (17-8) = 9
+ // SMF upper addr
+ l_norAddr = 0;
+ l_norAddr.insertFromRight<17, 19>(l_data.MCFGPA_SMF_UPPER_addr);
+ FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
+ l_scomData.insert<P9A_MI_MCFGP0A_SMF_UPPER_ADDRESS,
+ P9A_MI_MCFGP0A_SMF_UPPER_ADDRESS_LEN>(
+ (l_extAddr << 9)); //matches 17:35 extendBarAddress shifts left 8 (17-8) = 9
+
+
+ //Mirrored BAR = Non-mirrored BAR >> 1 since bit 56 is not a dsaddr bit
+ // MCFGPA SMF valid (bit 0)
+ l_scomData_mirror.setBit<P9A_MI_MCFGPM0A_SMF_VALID>();
+
+ // MCFGPA_SMF_UPPER_ADDRESS_AT_END_OF_RANGE
+ l_scomData_mirror.setBit<P9A_MI_MCFGPM0A_SMF_EXTEND_TO_END_OF_RANGE>();
+
+ // SMF lower addr
+ l_norAddr = 0;
+ l_norAddr.insertFromRight<17, 19>(l_data.MCFGPA_SMF_LOWER_addr);
+ FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
+ l_scomData_mirror.insert<P9A_MI_MCFGPM0A_SMF_LOWER_ADDRESS,
+ P9A_MI_MCFGPM0A_SMF_LOWER_ADDRESS_LEN>(
+ (l_extAddr << 8)); //matches 17:35 extendBarAddress shifts left 8 (17- (8 + 1)) = 8
+ // SMF upper addr
+ l_norAddr = 0;
+ l_norAddr.insertFromRight<17, 19>(l_data.MCFGPA_SMF_UPPER_addr);
+ FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
+ l_scomData_mirror.insert<P9A_MI_MCFGPM0A_SMF_UPPER_ADDRESS,
+ P9A_MI_MCFGPM0A_SMF_UPPER_ADDRESS_LEN>(
+ (l_extAddr << 8)); //matches 17:35 extendBarAddress shifts left 8 (17- (8 + 1)) = 8
+ }
+ else
+ {
+ //Mirrored
+ // MCFGPA SMF valid (bit 0)
+ l_scomData_mirror.setBit<P9A_MI_MCFGPM0A_SMF_VALID>();
+
+ // MCFGPA_SMF_UPPER_ADDRESS_AT_END_OF_RANGE
+ l_scomData_mirror.setBit<P9A_MI_MCFGPM0A_SMF_EXTEND_TO_END_OF_RANGE>();
+
+ // SMF lower addr
+ l_norAddr = 0;
+ l_norAddr.insertFromRight<17, 19>(l_data.MCFGPA_SMF_LOWER_addr);
+ FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
+ l_scomData_mirror.insert<P9A_MI_MCFGPM0A_SMF_LOWER_ADDRESS,
+ P9A_MI_MCFGPM0A_SMF_LOWER_ADDRESS_LEN>(
+ (l_extAddr << 9)); //matches 17:35 extendBarAddress shifts left 8 (17- 8) = 9
+ // SMF upper addr
+ l_norAddr = 0;
+ l_norAddr.insertFromRight<17, 19>(l_data.MCFGPA_SMF_UPPER_addr);
+ FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
+ l_scomData_mirror.insert<P9A_MI_MCFGPM0A_SMF_UPPER_ADDRESS,
+ P9A_MI_MCFGPM0A_SMF_UPPER_ADDRESS_LEN>(
+ (l_extAddr << 9)); //matches 17:35 extendBarAddress shifts left 8 (17- 8) = 9
+
+ //Non-Mirrored BAR = Mirrored BAR << 1 since bit 56 is now a dsaddr bit
+ // MCFGPA SMF valid (bit 0)
+ l_scomData.setBit<P9A_MI_MCFGP0A_SMF_VALID>();
+
+ // MCFGPA_SMF_UPPER_ADDRESS_AT_END_OF_RANGE
+ l_scomData.setBit<P9A_MI_MCFGP0A_SMF_EXTEND_TO_END_OF_RANGE>();
+
+ // SMF lower addr
+ l_norAddr = 0;
+ l_norAddr.insertFromRight<17, 19>(l_data.MCFGPA_SMF_LOWER_addr);
+ FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
+ l_scomData.insert<P9A_MI_MCFGP0A_SMF_LOWER_ADDRESS,
+ P9A_MI_MCFGP0A_SMF_LOWER_ADDRESS_LEN>(
+ (l_extAddr << 10)); //matches 17:35 extendBarAddress shifts left 8 (17- (8 - 1)) = 10
+ // SMF upper addr
+ l_norAddr = 0;
+ l_norAddr.insertFromRight<17, 19>(l_data.MCFGPA_SMF_UPPER_addr);
+ FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
+ l_scomData.insert<P9A_MI_MCFGP0A_SMF_UPPER_ADDRESS,
+ P9A_MI_MCFGP0A_SMF_UPPER_ADDRESS_LEN>(
+ (l_extAddr << 10)); //matches 17:35 extendBarAddress shifts left 8 (17- (8 - 1)) = 10
- // MCFGPA_SMF_UPPER_ADDRESS_AT_END_OF_RANGE
- l_scomData.setBit<P9A_MI_MCFGP0A_SMF_EXTEND_TO_END_OF_RANGE>();
- // SMF lower addr
- l_norAddr = 0;
- l_norAddr.insertFromRight<22, 14>(l_data.MCFGPA_SMF_LOWER_addr);
- FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
- l_scomData.insert<P9A_MI_MCFGP0A_SMF_LOWER_ADDRESS,
- P9A_MI_MCFGP0A_SMF_LOWER_ADDRESS_LEN>(
- (l_extAddr << 14)); //matches 22:35 extendBarAddress shifts left 8 (22-8) = 14
- // SMF upper addr
- l_norAddr = 0;
- l_norAddr.insertFromRight<22, 14>(l_data.MCFGPA_SMF_UPPER_addr);
- FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
- l_scomData.insert<P9A_MI_MCFGP0A_SMF_UPPER_ADDRESS,
- P9A_MI_MCFGP0A_SMF_UPPER_ADDRESS_LEN>(
- (l_extAddr << 14)); //matches 22:35 extendBarAddress shifts left 8 (22-8) = 14
+ }
}
// Write to reg
@@ -2232,6 +2342,11 @@ fapi2::ReturnCode writeMCBarData(
P9A_MI_MCFGP0A, l_scomData);
FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGP0A, l_scomData),
"Error writing to P9A_MI_MCFGP0A reg");
+
+ FAPI_INF("Write MCFGPM0A reg 0x%.16llX, Value 0x%.16llX",
+ P9A_MI_MCFGPM0A, l_scomData_mirror);
+ FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGPM0A, l_scomData_mirror),
+ "Error writing to P9A_MI_MCFGPM0A reg");
}
else
{
@@ -2239,83 +2354,76 @@ fapi2::ReturnCode writeMCBarData(
P9A_MI_MCFGP1A, l_scomData);
FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGP1A, l_scomData),
"Error writing to P9A_MI_MCFGP1A reg");
- }
-
- // 4. ---- Set MCFGPMA reg -----
- l_scomData = 0;
- // Assert if both HOLE1 and SMF are valid, settings will overlap
- FAPI_ASSERT((l_data.MCFGPMA_HOLE_valid[1] && l_data.MCFGPMA_SMF_valid) == 0,
- fapi2::MSS_SETUP_BARS_HOLE1_SMF_CONFLICT()
- .set_TARGET(l_target)
- .set_HOLE1_VALID(l_data.MCFGPMA_HOLE_valid[1])
- .set_SMF_VALID(l_data.MCFGPMA_SMF_valid),
- "Error: MCFGPMA HOLE1 and SMF are both valid, settings will overlap");
-
- // Hole 0
- if (l_data.MCFGPMA_HOLE_valid[0] == true)
- {
- // MCFGPMA HOLE0 valid (bit 0)
- l_scomData.setBit<P9A_MI_MCFGPM0A_HOLE_VALID>();
-
- // Hole 0 lower addr
- // 0b0000000001 = 4GB
- FAPI_TRY(extBar(l_ext_mask, l_data.MCFGPMA_HOLE_LOWER_addr[0], l_extAddr));
- l_scomData.insert<P9A_MI_MCFGPM0A_HOLE_LOWER_ADDRESS,
- P9A_MI_MCFGPM0A_HOLE_LOWER_ADDRESS_LEN>(
- (l_extAddr << 9)); //matches 17:31 extendedBarAddress shifts left 8 (17-8) = 9
+ FAPI_INF("Write MCFGPM1A reg 0x%.16llX, Value 0x%.16llX",
+ P9A_MI_MCFGPM1A, l_scomData_mirror);
+ FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGPM1A, l_scomData_mirror),
+ "Error writing to P9A_MI_MCFGP1A reg");
}
+ } // Data pair loop
- // SMF
- if (l_data.MCFGPMA_SMF_valid == true)
- {
- // MCFGPMA SMF valid (bit 0)
- l_scomData.setBit<P9A_MI_MCFGPM0A_SMF_VALID>();
+fapi_try_exit:
+ FAPI_DBG("Exit");
+ return fapi2::current_err;
+}
- // MCFGPMA_SMF_UPPER_ADDRESS_AT_END_OF_RANGE
- l_scomData.setBit<P9A_MI_MCFGPM0A_SMF_EXTEND_TO_END_OF_RANGE>();
+///
+/// @brief Apply Gemini MDI bit workaround and mask Channel Timeout
+///
+/// @param[in] i_target target to set actions/mask
+///
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode applyGeminiFixes(const fapi2::Target<fapi2::TARGET_TYPE_MCC> i_target)
+{
+ FAPI_DBG("Entering fixGeminiMDI on %s", mss::c_str(i_target));
- // SMF lower addr
- l_norAddr = 0;
- l_norAddr.insertFromRight<22, 14>(l_data.MCFGPMA_SMF_LOWER_addr);
- FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
- l_scomData.insert<P9A_MI_MCFGPM0A_SMF_LOWER_ADDRESS,
- P9A_MI_MCFGPM0A_SMF_LOWER_ADDRESS_LEN>(
- (l_extAddr << 14 )); //matches 22:35 extendBarAddress shifts left 8 (22-8) = 14
- // SMF upper addr
- l_norAddr = 0;
- l_norAddr.insertFromRight<22, 14>(l_data.MCFGPMA_SMF_UPPER_addr);
- FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
- l_scomData.insert<P9A_MI_MCFGPM0A_SMF_UPPER_ADDRESS,
- P9A_MI_MCFGPM0A_SMF_UPPER_ADDRESS_LEN>(
- (l_extAddr << 14)); //matches 22:35 extendBarAddress shifts left 8 (22-8) = 14
- }
+ fapi2::buffer<uint64_t> l_scom_data;
+ uint8_t l_any_gemini = 0;
+ const auto l_omiChiplets = i_target.getChildren<fapi2::TARGET_TYPE_OMI>();
- // Write to reg
- if (l_pos % 2 == 0)
- {
- FAPI_INF("Write P9A_MI_MCFGPM0A reg 0x%.16llX, Value 0x%.16llX",
- P9A_MI_MCFGPM0A, l_scomData);
+ for (const auto& l_omi : l_omiChiplets)
+ {
+ const auto& l_ocmb_chips = l_omi.getChildren<fapi2::TARGET_TYPE_OCMB_CHIP>();
- FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGPM0A, l_scomData),
- "Error writing to P9A_MI_MCFGPM0A reg");
- }
- else
+ if (!l_ocmb_chips.empty())
{
- FAPI_INF("Write P9A_MI_MCFGPM1A reg 0x%.16llX, Value 0x%.16llX",
- P9A_MI_MCFGPM1A, l_scomData);
-
- FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGPM1A, l_scomData),
- "Error writing to P9A_MI_MCFGPM1A reg");
+ uint8_t l_workaround = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_AXONE_GEMINI_MDI_ERROR,
+ l_ocmb_chips[0],
+ l_workaround),
+ "Error from FAPI_ATTR_GET (ATTR_CHIP_EC_FEATURE_AXONE_GEMINI_MDI_ERROR)");
+ l_any_gemini |= l_workaround;
}
+ }
- } // Data pair loop
+ if(l_any_gemini)
+ {
+ // MDI Workaround
+ FAPI_TRY(fapi2::getScom(i_target, P9A_MCC_USTLCFG, l_scom_data),
+ "Error reading from MCC_USTLCFG reg");
+ l_scom_data.setBit<P9A_MCC_USTLCFG_DEFAULT_META_DATA_ENABLE>();
+ l_scom_data.insertFromRight<P9A_MC_USTLCFG_DEFAULT_META_DATA,
+ P9A_MC_USTLCFG_DEFAULT_META_DATA_LEN>(USTL_MDI_EQUAL_ONE);
+ FAPI_TRY(fapi2::putScom(i_target, P9A_MCC_USTLCFG, l_scom_data),
+ "Error writing to MCC_USTLCFG reg");
+
+
+ fapi2::Target<fapi2::TARGET_TYPE_MI> l_mi_target = i_target.getParent<fapi2::TARGET_TYPE_MI>();
+ // Channel Timeout
+ FAPI_TRY(fapi2::getScom(l_mi_target, P9A_MI_MCTO, l_scom_data),
+ "Error reading from MCC_USTLCFG reg");
+ l_scom_data.clearBit<P9A_MI_MCTO_ENABLE_CHANNEL_HANG>();
+ FAPI_TRY(fapi2::putScom(l_mi_target, P9A_MI_MCTO, l_scom_data),
+ "Error writing to MCC_USTLCFG reg");
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
fapi_try_exit:
- FAPI_DBG("Exit");
+ FAPI_DBG("Exiting fixGeminiMDI on %s", mss::c_str(i_target));
return fapi2::current_err;
}
-
///
/// @brief Unmask FIR before opening BARs
///
@@ -2462,7 +2570,7 @@ fapi2::ReturnCode p9_mss_setup_bars(
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_MCS_GROUP_32, i_target,
l_groupData),
"Error getting ATTR_MSS_MCS_GROUP_32, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Setup BAR for Nimbus
if (l_mcsChiplets.size() > 0)
@@ -2470,22 +2578,22 @@ fapi2::ReturnCode p9_mss_setup_bars(
// Validate group data from attributes
FAPI_TRY(validateGroupData(l_mcsChiplets, false, l_groupData),
"validateGroupData() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Build MC BAR data based on Group data info
FAPI_TRY(buildMCBarData(l_mcsChiplets, l_groupData, l_mcsBarDataPair),
"buildMCBarData() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Unmask MC FIRs
FAPI_TRY(unmaskMCFIR(l_mcsBarDataPair),
"unmaskMCFIR() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Write data to MCS
FAPI_TRY(writeMCBarData(l_mcsBarDataPair),
"writeMCBarData() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
}
// Setup BAR for Axone
@@ -2494,25 +2602,33 @@ fapi2::ReturnCode p9_mss_setup_bars(
// Validate group data from attributes
FAPI_TRY(validateGroupData(l_mccChiplets, true, l_groupData),
"validateGroupData() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Build MC BAR data based on Group data info
FAPI_TRY(buildMCBarData(l_mccChiplets, l_groupData, l_mccBarDataPair),
"buildMCBarData() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Unmask MC FIRs
for (auto l_target : l_miChiplets)
{
FAPI_TRY(unmaskMCFIR(l_target),
"unmaskMCFIR() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
+ }
+
+ // Apply Gemini MDI bit workaround
+ for (fapi2::Target<fapi2::TARGET_TYPE_MCC> l_target : l_mccChiplets)
+ {
+ FAPI_TRY(applyGeminiFixes(l_target),
+ "fixGeminiMDI() returns error, l_rc 0x%.8X",
+ uint64_t(fapi2::current_err));
}
// Write data to MI
FAPI_TRY(writeMCBarData(l_mccBarDataPair),
"writeMCBarData() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
}
// Setup BAR for Cumulus
@@ -2521,22 +2637,22 @@ fapi2::ReturnCode p9_mss_setup_bars(
// Validate group data from attributes
FAPI_TRY(validateGroupData(l_miChiplets, false, l_groupData),
"validateGroupData() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Build MC BAR data based on Group data info
FAPI_TRY(buildMCBarData(l_miChiplets, l_groupData, l_miBarDataPair),
"buildMCBarData() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Unmask MC FIRs
FAPI_TRY(unmaskMCFIR(l_miBarDataPair),
"unmaskMCFIR() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
// Write data to MI
FAPI_TRY(writeMCBarData(l_miBarDataPair),
"writeMCBarData() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
+ uint64_t(fapi2::current_err));
}
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_npu_scominit.C b/src/import/chips/p9/procedures/hwp/nest/p9_npu_scominit.C
index cf3edc4f4..cb2e6f175 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_npu_scominit.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_npu_scominit.C
@@ -42,6 +42,7 @@
#include <p9_misc_scom_addresses_fld.H>
#include <p9a_misc_scom_addresses.H>
#include <p9a_misc_scom_addresses_fld.H>
+#include <p9_fbc_ioo_dl_npu_scom.H>
//------------------------------------------------------------------------------
// Constant definitions
@@ -99,6 +100,30 @@ fapi2::ReturnCode p9_npu_scominit(
goto fapi_try_exit;
}
+ // Enable obus for NPU for Axone
+ if (l_axone)
+ {
+ auto l_obus_targets = i_target.getChildren<fapi2::TARGET_TYPE_OBUS>();
+
+ for (auto l_obus_target : l_obus_targets)
+ {
+ FAPI_DBG("Invoking p9.fbc.ioo_dl.npu.scom.initfile...");
+ FAPI_EXEC_HWP(l_rc,
+ p9_fbc_ioo_dl_npu_scom,
+ l_obus_target,
+ i_target,
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>());
+
+ if (l_rc)
+ {
+ FAPI_ERR("Error from p9.fbc.ioo_dl.npu.scom.initfile");
+ fapi2::current_err = l_rc;
+ goto fapi_try_exit;
+ }
+
+ }
+ }
+
// apply additional SCOM inits
l_atrmiss.setBit<PU_NPU_SM2_XTS_ATRMISS_FLAG_MAP>()
.setBit<PU_NPU_SM2_XTS_ATRMISS_ENA>();
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars.C b/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars.C
index 844899466..31a20244d 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -743,6 +743,160 @@ fapi_try_exit:
}
+/// @brief Configure an NPU instance
+///
+/// @param[in] i_target Processor chip target
+/// @param[in] i_attr_bar_enable Enable the NPU MMIO bar
+/// @param[in] i_attr_bar The BAR for the NPU instance
+/// @param[in] i_mmio_offset The MMIO offset for the chip
+/// @param[in] i_attr_pri The private reg interface settings for each NDL
+/// @param[in] i_npu_regs The registers for this NPU
+/// @param[in] i_chip_info Structure describing chip properties/base addresses
+///
+/// @return FAPI_RC_SUCCESS if all calls are successful, else error
+fapi2::ReturnCode
+p9a_setup_bars_npuX(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
+ const uint8_t& i_attr_bar_enable,
+ fapi2::buffer<uint64_t> i_attr_bar,
+ const uint64_t& i_mmio_offset,
+ const uint8_t i_attr_pri[],
+ p9_setup_bars_p9a_npu_regs& i_npu_regs,
+ p9_setup_bars_chip_info& i_chip_info)
+{
+ FAPI_DBG("Start");
+
+ if (i_attr_bar_enable)
+ {
+ p9_setup_bars_addr_range l_mmio_range;
+ FAPI_ASSERT((i_attr_bar & P9_SETUP_BARS_OFFSET_MASK_16_MB) == 0,
+ fapi2::P9_SETUP_BARS_NPU_MMIO_BAR_ATTR_ERR()
+ .set_TARGET(i_target)
+ .set_BAR_OFFSET(i_attr_bar)
+ .set_BAR_OFFSET_MASK(P9_SETUP_BARS_OFFSET_MASK_16_MB)
+ .set_BAR_OVERLAP(i_attr_bar & P9_SETUP_BARS_OFFSET_MASK_2_MB),
+ "NPU MMIO BAR offset attribute is not aligned to HW implementation");
+
+ i_attr_bar &= NPU_BAR_BASE_ADDR_MASK;
+ i_attr_bar += i_mmio_offset;
+ i_attr_bar = i_attr_bar << NPU_BAR_ADDR_SHIFT;
+ i_attr_bar = NPU_BAR_REG_MASK & i_attr_bar;
+ i_attr_bar.setBit<PU_NPU0_SM0_PHY_BAR_CONFIG_ENABLE>();
+
+ for (uint8_t ll = 0; ll < NPU_NUM_BAR_SHADOWS; ll++)
+ {
+ FAPI_TRY(fapi2::putScom(i_target, i_npu_regs.bar_regs[ll], i_attr_bar),
+ "Error from putScom (0x08X)", i_npu_regs.bar_regs[ll]);
+ }
+
+ l_mmio_range.base_addr = i_attr_bar;
+ l_mmio_range.size = P9_SETUP_BARS_SIZE_16_MB;
+ l_mmio_range.enabled = true;
+ i_chip_info.ranges.push_back(l_mmio_range);
+ i_chip_info.ranges.back().print();
+ }
+
+ for (uint8_t ll = 0; ll < NPU_NUM_BAR_SHADOWS; ll++)
+ {
+ uint64_t l_pri_val = static_cast<uint64_t>(i_attr_pri[ll]) << (64 - 8);
+ FAPI_TRY(fapi2::putScom(i_target, i_npu_regs.pri_regs[ll], l_pri_val),
+ "Error from putScom (0x08X)", i_npu_regs.pri_regs[ll]);
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+/// @brief Configure p9a NPU MMIO access
+///
+/// @param[in] i_target Processor chip target
+/// @param[in] i_target_sys System target
+/// @param[in] i_chip_info Structure describing chip properties/base addresses
+///
+/// @return FAPI_RC_SUCCESS if all calls are successful, else error
+fapi2::ReturnCode
+p9a_setup_bars_npu(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
+ const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& i_target_sys,
+ p9_setup_bars_chip_info& i_chip_info)
+
+{
+ FAPI_DBG("Start");
+
+ fapi2::buffer<uint64_t> l_mmio_bar = i_chip_info.base_address_mmio;
+
+ //NPU0
+ {
+ fapi2::ATTR_PROC_NPU0_MMIO_BAR_ENABLE_Type l_mmio_enable;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU0_MMIO_BAR_ENABLE, i_target, l_mmio_enable),
+ "Error from FAPI_ATTR_GET (ATTR_PROC_NPU0_MMIO_BAR_ENABLE)");
+
+ fapi2::ATTR_PROC_NPU0_MMIO_BAR_BASE_ADDR_OFFSET_Type l_mmio_offset;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU0_MMIO_BAR_BASE_ADDR_OFFSET, i_target_sys, l_mmio_offset),
+ "Error from FAPI_ATTR_GET (ATTR_PROC_NPU0_MMIO_BAR_BASE_ADDR_OFFSET)");
+
+ fapi2::ATTR_PROC_NPU0_PRI_CONFIG_Type l_pri_config;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU0_PRI_CONFIG, i_target, l_pri_config),
+ "Error from FAPI_ATTR_GET (ATTR_PROC_NPU0_PRI_CONFIG)");
+
+ FAPI_TRY(p9a_setup_bars_npuX(i_target,
+ l_mmio_enable,
+ l_mmio_offset,
+ l_mmio_bar,
+ l_pri_config,
+ p9_setup_bars_p9a_npu0_regs,
+ i_chip_info));
+ }
+ //NPU1
+ {
+ fapi2::ATTR_PROC_NPU1_MMIO_BAR_ENABLE_Type l_mmio_enable;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU1_MMIO_BAR_ENABLE, i_target, l_mmio_enable),
+ "Error from FAPI_ATTR_GET (ATTR_PROC_NPU1_MMIO_BAR_ENABLE)");
+
+ fapi2::ATTR_PROC_NPU1_MMIO_BAR_BASE_ADDR_OFFSET_Type l_mmio_offset;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU1_MMIO_BAR_BASE_ADDR_OFFSET, i_target_sys, l_mmio_offset),
+ "Error from FAPI_ATTR_GET (ATTR_PROC_NPU1_MMIO_BAR_BASE_ADDR_OFFSET)");
+
+ fapi2::ATTR_PROC_NPU1_PRI_CONFIG_Type l_pri_config;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU1_PRI_CONFIG, i_target, l_pri_config),
+ "Error from FAPI_ATTR_GET (ATTR_PROC_NPU1_PRI_CONFIG)");
+
+ FAPI_TRY(p9a_setup_bars_npuX(i_target,
+ l_mmio_enable,
+ l_mmio_offset,
+ l_mmio_bar,
+ l_pri_config,
+ p9_setup_bars_p9a_npu1_regs,
+ i_chip_info));
+ }
+ //NPU2
+ {
+ fapi2::ATTR_PROC_NPU2_MMIO_BAR_ENABLE_Type l_mmio_enable;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU2_MMIO_BAR_ENABLE, i_target, l_mmio_enable),
+ "Error from FAPI_ATTR_GET (ATTR_PROC_NPU2_MMIO_BAR_ENABLE)");
+
+ fapi2::ATTR_PROC_NPU2_MMIO_BAR_BASE_ADDR_OFFSET_Type l_mmio_offset;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU2_MMIO_BAR_BASE_ADDR_OFFSET, i_target_sys, l_mmio_offset),
+ "Error from FAPI_ATTR_GET (ATTR_PROC_NPU2_MMIO_BAR_BASE_ADDR_OFFSET)");
+
+ fapi2::ATTR_PROC_NPU2_PRI_CONFIG_Type l_pri_config;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU2_PRI_CONFIG, i_target, l_pri_config),
+ "Error from FAPI_ATTR_GET (ATTR_PROC_NPU2_PRI_CONFIG)");
+
+ FAPI_TRY(p9a_setup_bars_npuX(i_target,
+ l_mmio_enable,
+ l_mmio_offset,
+ l_mmio_bar,
+ l_pri_config,
+ p9_setup_bars_p9a_npu2_regs,
+ i_chip_info));
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+
/// @brief Configure NPU MMIO access
///
/// @param[in] i_target Processor chip target
@@ -1237,7 +1391,12 @@ p9_setup_bars_check_overlap(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i
.set_BASE_ADDR2(i_chip_info.ranges[jj].base_addr)
.set_END_ADDR2(i_chip_info.ranges[jj].end_addr())
.set_ENABLED2(i_chip_info.ranges[jj].enabled),
- "Overlapping address regions detected!");
+ "Overlapping address regions detected %llx->%llx %llx->%llx!",
+ i_chip_info.ranges[ii].base_addr,
+ i_chip_info.ranges[ii].end_addr(),
+ i_chip_info.ranges[jj].base_addr,
+ i_chip_info.ranges[jj].end_addr()
+ );
}
}
}
@@ -1255,6 +1414,10 @@ p9_setup_bars(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
FAPI_INF("Start");
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
p9_setup_bars_chip_info l_chip_info;
+ fapi2::ATTR_CHIP_EC_FEATURE_ONE_NPU_TOP_Type l_one_npu;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_ONE_NPU_TOP, i_target, l_one_npu),
+ "Error from FAPI_ATTR_GET (ATTR_CHIP_EC_FEATURE_ONE_NPU_TOP)");
// process chip information
FAPI_TRY(p9_setup_bars_build_chip_info(i_target,
@@ -1268,9 +1431,18 @@ p9_setup_bars(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
// PSI
FAPI_TRY(p9_setup_bars_psi(i_target, FAPI_SYSTEM, l_chip_info),
"Error from p9_setup_bars_psi");
+
// NPU
- FAPI_TRY(p9_setup_bars_npu(i_target, FAPI_SYSTEM, l_chip_info),
- "Error from p9_setup_bars_npu");
+ if (l_one_npu)
+ {
+ FAPI_TRY(p9_setup_bars_npu(i_target, FAPI_SYSTEM, l_chip_info),
+ "Error from p9_setup_bars_npu");
+ }
+ else
+ {
+ FAPI_TRY(p9a_setup_bars_npu(i_target, FAPI_SYSTEM, l_chip_info),
+ "Error from p9a_setup_bars_npu");
+ }
// MCD
if (!l_chip_info.hw423589_option1)
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars_defs.H b/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars_defs.H
index ebf4682af..19a04873e 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars_defs.H
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars_defs.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -344,6 +344,13 @@ const uint8_t NPU_NUM_BAR_SHADOWS = 4;
const uint64_t NPU_BAR_BASE_ADDR_MASK = 0x0001FFFFFFFFFFFFULL;
const uint64_t NPU_BAR_ADDR_SHIFT = 12;
+// The NPU BAR does not include the Memory Select bits.
+// This mask ensures after shifting the attribute bar value
+// we only set the relivant BAR bits.
+// 0001122233444556
+// 0482604826048260
+const uint64_t NPU_BAR_REG_MASK = 0x1FFFFFF000000000ULL;
+
const uint64_t NPU_PHY0_BAR_REGS_NDD1[NPU_NUM_BAR_SHADOWS] =
{
PU_NPU0_SM0_PHY_BAR,
@@ -360,6 +367,14 @@ const uint64_t NPU_PHY0_BAR_REGS[NPU_NUM_BAR_SHADOWS] =
0x05011496
};
+const uint64_t NPU_PHY0_BAR_REGS_ADD1[NPU_NUM_BAR_SHADOWS] =
+{
+ 0x05011406,
+ 0x05011436,
+ 0x05011466,
+ 0x05011496
+};
+
const uint64_t NPU_PHY1_BAR_REGS_NDD1[NPU_NUM_BAR_SHADOWS] =
{
PU_NPU1_SM0_PHY_BAR,
@@ -392,4 +407,29 @@ const uint64_t NPU_MMIO_BAR_REGS[NPU_NUM_BAR_SHADOWS] =
0x05011096
};
+// P9A Npu instances
+struct p9_setup_bars_p9a_npu_regs
+{
+ uint64_t bar_regs[NPU_NUM_BAR_SHADOWS];
+ uint64_t pri_regs[NPU_NUM_BAR_SHADOWS];
+};
+
+p9_setup_bars_p9a_npu_regs p9_setup_bars_p9a_npu0_regs =
+{
+ { 0x501103C, 0x501109C, 0x50110FC, 0x501115C },
+ { 0x50111F6, 0x5011216, 0x50113D6, 0x50113F6 }
+};
+
+p9_setup_bars_p9a_npu_regs p9_setup_bars_p9a_npu1_regs =
+{
+ { 0x501143C, 0x501149C, 0x50114FC, 0x501155C },
+ { 0x50115F6, 0x5011616, 0x50117D6, 0x50117F6 }
+};
+
+p9_setup_bars_p9a_npu_regs p9_setup_bars_p9a_npu2_regs =
+{
+ { 0x3011C3C, 0x3011C9C, 0x3011CFC, 0x3011D5C },
+ { 0x3011DF6, 0x3011E16, 0x3011FD6, 0x3011FF6 }
+};
+
#endif //_P9_SETUP_BARS_DEFS_H_
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_throttle_sync.C b/src/import/chips/p9/procedures/hwp/nest/p9_throttle_sync.C
index e62ff6ab1..3ed9cc44c 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_throttle_sync.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_throttle_sync.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -43,7 +43,7 @@
//------------------------------------------------------------------------------
#include <p9_throttle_sync.H>
#include <fapi2.H>
-#include <generic/memory/lib/utils/find.H>
+#include <lib/utils/nimbus_find.H>
#include <p9_perv_scom_addresses.H>
///----------------------------------------------------------------------------
@@ -79,13 +79,30 @@ template<>
uint8_t findNumDimms(const fapi2::Target<fapi2::TARGET_TYPE_MI>& i_miTarget)
{
FAPI_DBG("Entering findNumDimms");
- auto l_dmiChiplets = i_miTarget.getChildren<fapi2::TARGET_TYPE_DMI>();
uint8_t l_num_dimms = 0;
- for (auto l_dmi : l_dmiChiplets)
+ // Cumulus code
+ const auto& l_dmiChiplets = i_miTarget.getChildren<fapi2::TARGET_TYPE_DMI>();
+
+ for (const auto& l_dmi : l_dmiChiplets)
+ {
+ const auto& l_memBufs = l_dmi.getChildren<fapi2::TARGET_TYPE_MEMBUF_CHIP>();
+
+ if (l_memBufs.size() > 0)
+ {
+ l_num_dimms++;
+ }
+ }
+
+ FAPI_DBG("After number of DIMM's after cumulus targets %u", l_num_dimms);
+
+ // Axone code
+ const auto& l_omiChiplets = i_miTarget.getChildren<fapi2::TARGET_TYPE_OMI>();
+
+ for (const auto& l_omi : l_omiChiplets)
{
- auto l_memBufs = l_dmi.getChildren<fapi2::TARGET_TYPE_MEMBUF_CHIP>();
+ const auto& l_memBufs = l_omi.getChildren<fapi2::TARGET_TYPE_OCMB_CHIP>();
if (l_memBufs.size() > 0)
{
@@ -93,6 +110,8 @@ uint8_t findNumDimms(const fapi2::Target<fapi2::TARGET_TYPE_MI>& i_miTarget)
}
}
+ FAPI_DBG("After number of DIMM's after axone targets %u", l_num_dimms);
+
FAPI_DBG("Exiting findNumDimms");
return l_num_dimms;
}
@@ -374,7 +393,7 @@ fapi2::ReturnCode throttleSync(
}
// Program the MCMODE0 if HW397255 is not enabled which means we
- // should have a chip with Nimbus DD2+ or Cumulus.
+ // should have a chip with Nimbus DD2+ or Cumulus/Axone.
if (i_HW397255_enabled == 0)
{
progMCMODE0(l_mc, i_mcTargets);
@@ -442,7 +461,7 @@ extern "C"
// HW397255 requires to also program a master MCS on MC23 if
// it has DIMMs.
// This should only be enabled for Nimbus DD1, disabled for Nimbus DD2
- // and Cumulus.
+ // and Cumulus/Axone.
fapi2::ATTR_CHIP_EC_FEATURE_HW397255_Type l_HW397255_enabled;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_HW397255,
i_target, l_HW397255_enabled),
@@ -456,7 +475,7 @@ extern "C"
(uint64_t)fapi2::current_err);
}
- // Cumulus
+ // Cumulus/Axone
if (l_miChiplets.size() > 0)
{
FAPI_TRY(throttleSync(l_miChiplets, l_HW397255_enabled),
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_tod_setup.C b/src/import/chips/p9/procedures/hwp/nest/p9_tod_setup.C
index 04ce62cd9..18c0079b0 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_tod_setup.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_tod_setup.C
@@ -44,6 +44,7 @@
const uint64_t M_PATH_CTRL_REG_CLEAR_VALUE = 0x0000000000000000;
const uint64_t S_PATH_CTRL_REG_CLEAR_VALUE = 0x0000003F00000000;
+static const uint8_t P9A_PERV_ROOT_CTRL8_TP_PLL_CLKIN_SEL9_DC = 21;
/// @brief MPIPL specific steps to clear the previous topology, this should be
// called only during MPIPL
@@ -778,6 +779,18 @@ fapi2::ReturnCode configure_m_path_ctrl_reg(
const p9_tod_setup_osc_sel i_osc_sel)
{
fapi2::buffer<uint64_t> l_m_path_ctrl_reg = 0;
+ fapi2::buffer<uint64_t> l_root_ctrl8_reg = 0;
+ bool l_tod_on_lpc_clock = false;
+
+ const bool is_mdmt = (i_tod_node->i_tod_master && i_tod_node->i_drawer_master);
+
+ // Read ROOT_CTRL8 to determine TOD input clock selection
+ FAPI_TRY(fapi2::getScom(*(i_tod_node->i_target),
+ PERV_ROOT_CTRL8_SCOM,
+ l_root_ctrl8_reg),
+ "Error from getScom (PERV_ROOT_CTRL8_SCOM)!");
+
+ l_tod_on_lpc_clock = l_root_ctrl8_reg.getBit<P9A_PERV_ROOT_CTRL8_TP_PLL_CLKIN_SEL9_DC>();
// Read PERV_TOD_M_PATH_CTRL_REG to preserve any prior configuration
FAPI_TRY(fapi2::getScom(*(i_tod_node->i_target),
@@ -785,85 +798,91 @@ fapi2::ReturnCode configure_m_path_ctrl_reg(
l_m_path_ctrl_reg),
"Error from getScom (PERV_TOD_M_PATH_CTRL_REG)!");
- // Configure Master OSC0/OSC1 path
- FAPI_DBG("Configuring Master OSC path in PERV_TOD_M_PATH_CTRL_REG");
+ // Configure single or dual edge detect based on tod clock select
+ l_m_path_ctrl_reg.writeBit<PERV_TOD_M_PATH_CTRL_REG_STEP_CREATE_DUAL_EDGE_DISABLE>(l_tod_on_lpc_clock);
- if (i_osc_sel == TOD_OSC_0 ||
- i_osc_sel == TOD_OSC_0_AND_1 ||
- i_osc_sel == TOD_OSC_0_AND_1_SEL_0 ||
- i_osc_sel == TOD_OSC_0_AND_1_SEL_1)
+ if (is_mdmt)
{
- FAPI_DBG("OSC0 is valid; master path-0 will be configured.");
+ // Configure Master OSC0/OSC1 path
+ FAPI_DBG("Configuring Master OSC path in PERV_TOD_M_PATH_CTRL_REG");
- // OSC0 is connected
- l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_0_OSC_NOT_VALID>();
+ if (i_osc_sel == TOD_OSC_0 ||
+ i_osc_sel == TOD_OSC_0_AND_1 ||
+ i_osc_sel == TOD_OSC_0_AND_1_SEL_0 ||
+ i_osc_sel == TOD_OSC_0_AND_1_SEL_1)
+ {
+ FAPI_DBG("OSC0 is valid; master path-0 will be configured.");
- // OSC0 step alignment enabled
- l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_0_STEP_ALIGN_DISABLE>();
+ // OSC0 is connected
+ l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_0_OSC_NOT_VALID>();
- // Set 512 steps per sync for path 0
- l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT,
- PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT_LEN>(
- TOD_M_PATH_CTRL_REG_M_PATH_SYNC_CREATE_SPS_512);
+ // OSC0 step alignment enabled
+ l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_0_STEP_ALIGN_DISABLE>();
- // Set step check CPS deviation to 50%
- l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_CPS_DEVIATION,
- PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_CPS_DEVIATION_LEN>(
- STEP_CHECK_CPS_DEVIATION_50_00_PCENT);
+ // Set 512 steps per sync for path 0
+ l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT,
+ PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT_LEN>(
+ TOD_M_PATH_CTRL_REG_M_PATH_SYNC_CREATE_SPS_512);
- // 8 valid steps are required before step check is enabled
- l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_VALIDITY_COUNT,
- PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_VALIDITY_COUNT_LEN>(
- STEP_CHECK_VALIDITY_COUNT_8);
- }
- else
- {
- FAPI_DBG("OSC0 is not connected.");
+ // Set step check CPS deviation to 50%
+ l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_CPS_DEVIATION,
+ PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_CPS_DEVIATION_LEN>(
+ STEP_CHECK_CPS_DEVIATION_50_00_PCENT);
- // OSC0 is not connected; any previous path-0 settings will be ignored
- l_m_path_ctrl_reg.setBit<PERV_TOD_M_PATH_CTRL_REG_0_OSC_NOT_VALID>();
- }
+ // 8 valid steps are required before step check is enabled
+ l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_VALIDITY_COUNT,
+ PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_VALIDITY_COUNT_LEN>(
+ STEP_CHECK_VALIDITY_COUNT_8);
+ }
+ else
+ {
+ FAPI_DBG("OSC0 is not connected.");
- if (i_osc_sel == TOD_OSC_1 ||
- i_osc_sel == TOD_OSC_0_AND_1 ||
- i_osc_sel == TOD_OSC_0_AND_1_SEL_0 ||
- i_osc_sel == TOD_OSC_0_AND_1_SEL_1)
- {
- FAPI_DBG("OSC1 is valid; master path-1 will be configured.");
+ // OSC0 is not connected; any previous path-0 settings will be ignored
+ l_m_path_ctrl_reg.setBit<PERV_TOD_M_PATH_CTRL_REG_0_OSC_NOT_VALID>();
+ }
- // OSC1 is connected
- l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_1_OSC_NOT_VALID>();
+ if (i_osc_sel == TOD_OSC_1 ||
+ i_osc_sel == TOD_OSC_0_AND_1 ||
+ i_osc_sel == TOD_OSC_0_AND_1_SEL_0 ||
+ i_osc_sel == TOD_OSC_0_AND_1_SEL_1)
+ {
+ FAPI_DBG("OSC1 is valid; master path-1 will be configured.");
- // OSC1 step alignment enabled
- l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_1_STEP_ALIGN_DISABLE>();
+ // OSC1 is connected
+ l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_1_OSC_NOT_VALID>();
- // Set 512 steps per sync for path 1
- l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT,
- PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT_LEN>(
- TOD_M_PATH_CTRL_REG_M_PATH_SYNC_CREATE_SPS_512);
+ // OSC1 step alignment enabled
+ l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_1_STEP_ALIGN_DISABLE>();
- // Set step check CPS deviation to 50%
- l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_CPS_DEVIATION,
- PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_CPS_DEVIATION_LEN>(
- STEP_CHECK_CPS_DEVIATION_50_00_PCENT);
+ // Set 512 steps per sync for path 1
+ l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT,
+ PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT_LEN>(
+ TOD_M_PATH_CTRL_REG_M_PATH_SYNC_CREATE_SPS_512);
- // 8 valid steps are required before step check is enabled
- l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_VALIDITY_COUNT,
- PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_VALIDITY_COUNT_LEN>(
- STEP_CHECK_VALIDITY_COUNT_8);
- }
- else
- {
- FAPI_DBG("OSC1 is not connected.");
+ // Set step check CPS deviation to 50%
+ l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_CPS_DEVIATION,
+ PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_CPS_DEVIATION_LEN>(
+ STEP_CHECK_CPS_DEVIATION_50_00_PCENT);
- // OSC1 is not connected; any previous path-1 settings will be ignored
- l_m_path_ctrl_reg.setBit<PERV_TOD_M_PATH_CTRL_REG_1_OSC_NOT_VALID>();
- }
+ // 8 valid steps are required before step check is enabled
+ l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_VALIDITY_COUNT,
+ PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_VALIDITY_COUNT_LEN>(
+ STEP_CHECK_VALIDITY_COUNT_8);
+ }
+ else
+ {
+ FAPI_DBG("OSC1 is not connected.");
- // CPS deviation factor configures both path-0 and path-1
- l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_STEP_CHECK_CPS_DEVIATION_FACTOR,
- PERV_TOD_M_PATH_CTRL_REG_STEP_CHECK_CPS_DEVIATION_FACTOR_LEN>(
- STEP_CHECK_CPS_DEVIATION_FACTOR_1);
+ // OSC1 is not connected; any previous path-1 settings will be ignored
+ l_m_path_ctrl_reg.setBit<PERV_TOD_M_PATH_CTRL_REG_1_OSC_NOT_VALID>();
+ }
+
+ // CPS deviation factor configures both path-0 and path-1
+ l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_STEP_CHECK_CPS_DEVIATION_FACTOR,
+ PERV_TOD_M_PATH_CTRL_REG_STEP_CHECK_CPS_DEVIATION_FACTOR_LEN>(
+ STEP_CHECK_CPS_DEVIATION_FACTOR_1);
+ }
FAPI_TRY(fapi2::putScom(*(i_tod_node->i_target),
PERV_TOD_M_PATH_CTRL_REG,
@@ -1058,13 +1077,10 @@ fapi2::ReturnCode configure_tod_node(
i_osc_sel),
"Error from configure_port_ctrl_regs!");
- if (is_mdmt)
- {
- FAPI_TRY(configure_m_path_ctrl_reg(i_tod_node,
- i_tod_sel,
- i_osc_sel),
- "Error from configure_m_path_ctrl_reg!");
- }
+ FAPI_TRY(configure_m_path_ctrl_reg(i_tod_node,
+ i_tod_sel,
+ i_osc_sel),
+ "Error from configure_m_path_ctrl_reg!");
FAPI_TRY(configure_i_path_ctrl_reg(i_tod_node,
i_tod_sel,
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.C b/src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.C
index 4f6aeeb07..31f826501 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.C
@@ -69,7 +69,8 @@ fapi_try_exit:
/*
- * As documented
+ * As documented (TYPO in BAR Bits)
+ * They should be naturally ordered.
* BAR Bits 6 8 9 7 10 11 12 13
* 0x00 15 16 17 18 21 20 19 14
* 0x04 15 16 17 18 21 20 14 19
@@ -92,29 +93,6 @@ fapi_try_exit:
* 0xF6 15 21 14 20 19 18 17 16
* 0xF7 15 14 21 20 19 18 17 16
*
- * Ordered bar bits
- * BAR Bits 5 6 7 8 9 10 11 12 13 14 ...
- * 0x00 13 15 18 16 17 21 20 19 14 22 ...
- * 0x04 13 15 18 16 17 21 20 14 19 22 ...
- * 0x06 13 15 18 16 17 21 14 20 19 22 ...
- * 0x07 13 15 18 16 17 14 21 20 19 22 ...
- * 0x80 13 15 18 16 17 21 20 19 14 22 ...
- * 0x84 13 15 18 16 17 21 20 14 19 22 ...
- * 0x86 13 15 18 16 17 21 14 20 19 22 ...
- * 0x87 13 15 18 16 17 14 21 20 19 22 ...
- * 0xC0 13 15 21 17 18 20 19 14 16 22 ...
- * 0xC4 13 15 21 17 18 20 14 19 16 22 ...
- * 0xC6 13 15 21 17 18 14 20 19 16 22 ...
- * 0xC7 13 15 14 17 18 21 20 19 16 22 ...
- * 0xE0 13 15 20 18 21 19 14 17 16 22 ...
- * 0xE4 13 15 20 18 21 14 19 17 16 22 ...
- * 0xE6 13 15 14 18 21 20 19 17 16 22 ...
- * 0xE7 13 15 21 18 14 20 19 17 16 22 ...
- * 0xF0 13 15 19 21 20 14 18 17 16 22 ...
- * 0xF4 13 15 14 21 20 19 18 17 16 22 ...
- * 0xF6 13 15 20 21 14 19 18 17 16 22 ...
- * 0xF7 13 15 20 14 21 19 18 17 16 22 ...
- *
*
*/
fapi2::ReturnCode extendBarAddress(const uint64_t& i_ext_mask, const fapi2::buffer<uint64_t>& i_bar_addr,
@@ -127,27 +105,27 @@ fapi2::ReturnCode extendBarAddress(const uint64_t& i_ext_mask, const fapi2::buff
static const int NUM_EXT_MASKS = 20; // 20 different extension masks are supported
static const uint64_t EXT_MASK_REORDER[][9] = // Workbook table 7
{
- // B 6 7 8 9 10 11 12 13
- { 0x00, 15, 18, 16, 17, 21, 20, 19, 14 },
- { 0x04, 15, 18, 16, 17, 21, 20, 14, 19 },
- { 0x06, 15, 18, 16, 17, 21, 14, 20, 19 },
- { 0x07, 15, 18, 16, 17, 14, 21, 20, 19 },
- { 0x80, 15, 18, 16, 17, 21, 20, 19, 14 },
- { 0x84, 15, 18, 16, 17, 21, 20, 14, 19 },
- { 0x86, 15, 18, 16, 17, 21, 14, 20, 19 },
- { 0x87, 15, 18, 16, 17, 14, 21, 20, 19 },
- { 0xC0, 15, 21, 17, 18, 20, 19, 14, 16 },
- { 0xC4, 15, 21, 17, 18, 20, 14, 19, 16 },
- { 0xC6, 15, 21, 17, 18, 14, 20, 19, 16 },
- { 0xC7, 15, 14, 17, 18, 21, 20, 19, 16 },
- { 0xE0, 15, 20, 18, 21, 19, 14, 17, 16 },
- { 0xE4, 15, 20, 18, 21, 14, 19, 17, 16 },
- { 0xE6, 15, 14, 18, 21, 20, 19, 17, 16 },
- { 0xE7, 15, 21, 18, 14, 20, 19, 17, 16 },
- { 0xF0, 15, 19, 21, 20, 14, 18, 17, 16 },
- { 0xF4, 15, 14, 21, 20, 19, 18, 17, 16 },
- { 0xF6, 15, 20, 21, 14, 19, 18, 17, 16 },
- { 0xF7, 15, 20, 14, 21, 19, 18, 17, 16 }
+ // B 6 7 8 9 10 11 12 13
+ { 0x00, 15, 16, 17, 18, 21, 20, 19, 14 },
+ { 0x04, 15, 16, 17, 18, 21, 20, 14, 19 },
+ { 0x06, 15, 16, 17, 18, 21, 14, 20, 19 },
+ { 0x07, 15, 16, 17, 18, 14, 21, 20, 19 },
+ { 0x80, 15, 16, 17, 18, 21, 20, 19, 14 },
+ { 0x84, 15, 16, 17, 18, 21, 20, 14, 19 },
+ { 0x86, 15, 16, 17, 18, 21, 14, 20, 19 },
+ { 0x87, 15, 16, 17, 18, 14, 21, 20, 19 },
+ { 0xC0, 15, 17, 18, 21, 20, 19, 14, 16 },
+ { 0xC4, 15, 17, 18, 21, 20, 14, 19, 16 },
+ { 0xC6, 15, 17, 18, 21, 14, 20, 19, 16 },
+ { 0xC7, 15, 17, 18, 14, 21, 20, 19, 16 },
+ { 0xE0, 15, 18, 21, 20, 19, 14, 17, 16 },
+ { 0xE4, 15, 18, 21, 20, 14, 19, 17, 16 },
+ { 0xE6, 15, 18, 21, 14, 20, 19, 17, 16 },
+ { 0xE7, 15, 18, 14, 21, 20, 19, 17, 16 },
+ { 0xF0, 15, 21, 20, 19, 14, 18, 17, 16 },
+ { 0xF4, 15, 21, 20, 14, 19, 18, 17, 16 },
+ { 0xF6, 15, 21, 14, 20, 19, 18, 17, 16 },
+ { 0xF7, 15, 14, 21, 20, 19, 18, 17, 16 }
};
uint64_t l_bar = i_bar_addr;
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_get_mmio.C b/src/import/chips/p9/procedures/hwp/nest/p9a_get_mmio.C
index c2cb8d8ef..836d63057 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9a_get_mmio.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9a_get_mmio.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -55,8 +55,8 @@ fapi2::ReturnCode p9a_get_mmio(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
std::vector<uint8_t>& o_data)
{
uint8_t data[8];
- uint8_t l_idx;
- uint8_t l_data_idx;
+ uint32_t l_idx;
+ uint32_t l_data_idx;
uint32_t l_max_grans;
uint32_t l_grans;
p9_ADU_oper_flag l_myAduFlag;
@@ -82,7 +82,7 @@ fapi2::ReturnCode p9a_get_mmio(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
}
FAPI_TRY(addOMIBase(i_target, l_addr));
- FAPI_INF("Read address: 0x%lX transaction size: %d", l_addr, l_tsize);
+ FAPI_DBG("Read address: 0x%lX transaction size: %d", l_addr, l_tsize);
l_proc_target = i_target.getParent<fapi2::TARGET_TYPE_OMI>().getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
@@ -120,7 +120,7 @@ fapi2::ReturnCode p9a_get_mmio(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
sprintf(&l_hexdata[l_i * 2], "%02X", o_data[l_i]);
}
- FAPI_INF("Read data: 0x%s", l_hexdata);
+ FAPI_DBG("Read data: 0x%s", l_hexdata);
fapi_try_exit:
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.C b/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.C
index e5efc07c5..9801e8f30 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.C
@@ -45,7 +45,7 @@
#include <p9_mc_scom_addresses.H>
#include <p9a_misc_scom_addresses.H>
#include <p9a_misc_scom_addresses_fld.H>
-#include <chips/ocmb/explorer/procedures/hwp/memory/exp_inband.H>
+#include <lib/inband/exp_inband.H>
//-----------------------------------------------------------------------------------
// Function definitions
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.mk b/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.mk
index d24e4e5f0..b7428fc57 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.mk
+++ b/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2017,2019
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -25,5 +25,6 @@
PROCEDURE=p9a_omi_setup_bars
OBJS+=p9_fbc_utils.o
OBJS+=p9a_addr_ext.o
+$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/ocmb/explorer/procedures/hwp/memory/)
$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH))
$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_put_mmio.C b/src/import/chips/p9/procedures/hwp/nest/p9a_put_mmio.C
index adebd16da..fb1a2c13b 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9a_put_mmio.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9a_put_mmio.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -55,8 +55,8 @@ fapi2::ReturnCode p9a_put_mmio(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
const std::vector<uint8_t>& i_data)
{
uint8_t data[8];
- uint8_t l_idx;
- uint8_t l_data_idx;
+ uint32_t l_idx;
+ uint32_t l_data_idx;
uint32_t l_max_grans;
uint32_t l_grans;
p9_ADU_oper_flag l_myAduFlag;
@@ -87,8 +87,8 @@ fapi2::ReturnCode p9a_put_mmio(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
}
FAPI_TRY(addOMIBase(i_target, l_addr));
- FAPI_INF("Write address: %lX", l_addr);
- FAPI_INF("Write data: %s", l_hexdata);
+ FAPI_DBG("Write address: %lX", l_addr);
+ FAPI_DBG("Write data: %s", l_hexdata);
l_proc_target = i_target.getParent<fapi2::TARGET_TYPE_OMI>().getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.C b/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.C
new file mode 100644
index 000000000..c288c1fb2
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.C
@@ -0,0 +1,346 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/// ----------------------------------------------------------------------------
+/// @file p9_throttle_sync.C
+///
+/// @brief Perform p9_throttle_sync HWP
+///
+/// The purpose of this procedure is to triggers sync command from a 'master'
+/// MC to other MCs that have attached memory in a processor.
+///
+/// ----------------------------------------------------------------------------
+/// *HWP HWP Owner : Joe McGill <jmcgill@us.ibm.com>
+/// *HWP HWP Backup : Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+/// *HWP FW Owner : Thi Tran <thi@us.ibm.com>
+/// *HWP Team : Nest
+/// *HWP Level : 3
+/// *HWP Consumed by : HB
+/// ----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <p9a_throttle_sync.H>
+#include <fapi2.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <lib/shared/axone_consts.H>
+
+///
+/// @brief Program MCMODE0 based on the functional targets
+///
+/// @param[in] i_mi_target The MC target to be programmed
+/// @param[in] i_mi_targets Other MC targets.
+///
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode prog_MCMODE0(
+ const fapi2::Target<fapi2::TARGET_TYPE_MI>& i_mc_target,
+ const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MI> >& i_mc_targets)
+{
+ FAPI_DBG("Entering prog_MCMODE0 on target %s", mss::c_str(i_mc_target));
+ // --------------------------------------------------------------
+ // Setup MCMODE0 for disabling MC SYNC to other-side and same-side
+ // partner unit.
+ // BIT27: set if other-side MC is non-functional, 0<->2, 1<->3
+ // BIT28: set if same-side MC is non-functional, 0<->1, 2<->3
+ // --------------------------------------------------------------
+ fapi2::buffer<uint64_t> l_scomData(0);
+ fapi2::buffer<uint64_t> l_scomMask(0);
+ bool l_other_side_functional = false;
+ bool l_same_side_functional = false;
+ uint8_t l_current_pos = 0;
+ uint8_t l_other_side_pos = 0;
+ uint8_t l_same_side_pos = 0;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_mc_target, l_current_pos),
+ "Error getting ATTR_CHIP_UNIT_POS on %s", mss::c_str(i_mc_target));
+
+ // Calculate the peer MC in the other side and in the same side.
+ l_other_side_pos = (l_current_pos + MAX_MC_PER_SIDE) % MAX_MC_PER_PROC;
+ l_same_side_pos = ((l_current_pos / MAX_MC_SIDES_PER_PROC) * MAX_MC_PER_SIDE)
+ + ((l_current_pos % MAX_MC_PER_SIDE) + 1) % MAX_MC_PER_SIDE;
+
+ FAPI_DBG("Current pos: %i, other side pos: %i, same side pos: %i",
+ l_current_pos, l_other_side_pos, l_same_side_pos);
+
+ // Determine side functionality
+ for (const auto& l_mc : i_mc_targets)
+ {
+ uint8_t l_tmp_pos = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mc, l_tmp_pos),
+ "Error getting ATTR_CHIP_UNIT_POS on %s", mss::c_str(l_mc));
+
+ // The other side
+ if (l_tmp_pos == l_other_side_pos)
+ {
+ l_other_side_functional = true;
+ }
+
+ // The same side
+ if (l_tmp_pos == l_same_side_pos)
+ {
+ l_same_side_functional = true;
+ }
+ }
+
+ l_scomData.flush<0>();
+ l_scomMask.flush<0>();
+
+ if (!l_other_side_functional)
+ {
+ l_scomData.setBit<P9A_MI_MCMODE0_DISABLE_MC_SYNC>();
+ l_scomMask.setBit<P9A_MI_MCMODE0_DISABLE_MC_SYNC>();
+ }
+ else
+ {
+ l_scomData.clearBit<P9A_MI_MCMODE0_DISABLE_MC_SYNC>();
+ l_scomMask.setBit<P9A_MI_MCMODE0_DISABLE_MC_SYNC>();
+ }
+
+ if (!l_same_side_functional)
+ {
+ l_scomData.setBit<P9A_MI_MCMODE0_DISABLE_MC_PAIR_SYNC>();
+ l_scomMask.setBit<P9A_MI_MCMODE0_DISABLE_MC_PAIR_SYNC>();
+ }
+ else
+ {
+ l_scomData.clearBit<P9A_MI_MCMODE0_DISABLE_MC_PAIR_SYNC>();
+ l_scomMask.setBit<P9A_MI_MCMODE0_DISABLE_MC_PAIR_SYNC>();
+ }
+
+ FAPI_DBG("Writing MCS_MCMODE0 reg 0x%016llX: Mask 0x%016llX , Data 0x%016llX",
+ P9A_MI_MCMODE0, l_scomMask, l_scomData);
+
+ FAPI_TRY(fapi2::putScomUnderMask(i_mc_target, P9A_MI_MCMODE0, l_scomData, l_scomMask),
+ "putScomUnderMask() returns an error, P9A_MI_MCMODE0 reg 0x%016llX", P9A_MI_MCMODE0);
+
+fapi_try_exit:
+ FAPI_DBG("Exiting prog_MCMODE0");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Programming master MCS
+/// Writes P9A_MI_MCSYNC reg to set the input MCS as the master.
+///
+/// @param[in] i_mcsTarget The MCS target to be programmed as master.
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode prog_master(const fapi2::Target<fapi2::TARGET_TYPE_MI>& i_mc_target)
+{
+ FAPI_DBG("Entering progMaster with target %s", mss::c_str(i_mc_target));
+ fapi2::buffer<uint64_t> l_scomData(0);
+ fapi2::buffer<uint64_t> l_scomMask(0);
+
+ // -------------------------------------------------------------------
+ // 1. Reset sync command
+ // -------------------------------------------------------------------
+
+ // Clear GO bit
+ l_scomMask.flush<0>().setBit<P9A_MI_MCSYNC_SYNC_GO>();
+ l_scomData.flush<0>();
+ FAPI_TRY(fapi2::putScomUnderMask(i_mc_target, P9A_MI_MCSYNC, l_scomData, l_scomMask),
+ "putScomUnderMask() returns an error (Reset), P9A_MI_MCSYNC reg 0x%016llX", P9A_MI_MCSYNC);
+
+ // --------------------------------------------------------------
+ // 2. Setup MC Sync Command Register data for master MCS or MI
+ // --------------------------------------------------------------
+
+ // Clear buffers
+ l_scomData.flush<0>();
+ l_scomMask.flush<0>();
+
+ // Force bit set in case cleared from last procedure run
+ l_scomData.setBit<EXPLR_SRQ_MBA_SYNCCNTLQ_SYNC_REF_EN>();
+ l_scomMask.setBit<EXPLR_SRQ_MBA_SYNCCNTLQ_SYNC_REF_EN>();
+
+ // Iterate through OCMBs to make sure refresh SYNC bit is set
+ for (const auto& l_ocmb : mss::find_targets<fapi2::TARGET_TYPE_OCMB_CHIP>(i_mc_target))
+ {
+ FAPI_DBG("Writing EXPLR_SRQ_MBA_SYNCCNTLQ reg 0x%016llX: Data 0x%016llX Mask 0x%016llX",
+ EXPLR_SRQ_MBA_SYNCCNTLQ, l_scomData, l_scomMask);
+
+ FAPI_TRY(fapi2::putScomUnderMask(l_ocmb, EXPLR_SRQ_MBA_SYNCCNTLQ, l_scomData, l_scomMask),
+ "Error writing to REG 0x%016llX of %s", EXPLR_SRQ_MBA_SYNCCNTLQ, mss::c_str(l_ocmb));
+ }
+
+ // Clear buffers
+ l_scomData.flush<0>();
+ l_scomMask.flush<0>();
+
+ // Setup MCSYNC_CHANNEL_SELECT
+ // Set ALL channels with or without DIMMs (bits 0:7)
+ l_scomData.setBit<P9A_MI_MCSYNC_CHANNEL_SELECT,
+ P9A_MI_MCSYNC_CHANNEL_SELECT_LEN>();
+ l_scomMask.setBit<P9A_MI_MCSYNC_CHANNEL_SELECT,
+ P9A_MI_MCSYNC_CHANNEL_SELECT_LEN>();
+
+ // Setup MCSYNC_SYNC_TYPE for SYNC ALL
+ l_scomData.setBit<P9A_MI_MCSYNC_SYNC_TYPE>();
+ l_scomMask.setBit<P9A_MI_MCSYNC_SYNC_TYPE>();
+
+ // Setup SYNC_GO (bit 16 is now used for both channels)
+ l_scomMask.setBit<P9A_MI_MCSYNC_SYNC_GO>();
+ l_scomData.setBit<P9A_MI_MCSYNC_SYNC_GO>();
+
+ // --------------------------------------------------------------
+ // 3. Write to MC Sync Command Register of master MCS or MI
+ // --------------------------------------------------------------
+ // Write to MCSYNC reg
+ FAPI_DBG("Writing P9A_MI_MCSYNC reg 0x%016llX: Mask 0x%016llX , Data 0x%016llX",
+ P9A_MI_MCSYNC, l_scomMask, l_scomData);
+
+ FAPI_TRY(fapi2::putScomUnderMask(i_mc_target, P9A_MI_MCSYNC, l_scomData, l_scomMask),
+ "putScomUnderMask() returns an error (Sync), P9A_MI_MCSYNC reg 0x%016llX", P9A_MI_MCSYNC);
+
+ // Note: No need to read Sync replay count and retry in P9.
+
+ // --------------------------------------------------------------
+ // 4. Clear refresh sync bit
+ // --------------------------------------------------------------
+ l_scomData.flush<0>();
+ l_scomMask.flush<0>().setBit<EXPLR_SRQ_MBA_SYNCCNTLQ_SYNC_REF_EN>();
+
+ // Iterate through OCMBs to clear refresh sync bit
+ for (const auto& l_ocmb : mss::find_targets<fapi2::TARGET_TYPE_OCMB_CHIP>(i_mc_target))
+ {
+ FAPI_DBG("Writing EXPLR_SRQ_MBA_SYNCCNTLQ reg 0x%016llX: Mask 0x%016llX , Data 0x%016llX on %s",
+ EXPLR_SRQ_MBA_SYNCCNTLQ, l_scomMask, l_scomData, mss::c_str(l_ocmb));
+
+ FAPI_TRY(fapi2::putScomUnderMask(l_ocmb, EXPLR_SRQ_MBA_SYNCCNTLQ, l_scomData, l_scomMask),
+ "putScomUnderMask() returns an error (Sync), EXPLR_SRQ_MBA_SYNCCNTLQ reg 0x%016llX",
+ EXPLR_SRQ_MBA_SYNCCNTLQ);
+ }
+
+fapi_try_exit:
+ FAPI_DBG("Exiting progMaster");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Perform throttle sync on the Memory Controllers
+///
+/// @param[in] i_mc_targets vector of reference of MC targets (MCS or MI)
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode throttle_sync(
+ const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MI> >& i_mc_targets)
+{
+ mc_side_info_t l_mcSide[MAX_MC_SIDES_PER_PROC];
+ uint8_t l_sideNum = 0;
+ uint8_t l_pos = 0;
+ uint8_t l_numMasterProgrammed = 0;
+
+ // Initialization
+ for (l_sideNum = 0; l_sideNum < MAX_MC_SIDES_PER_PROC; l_sideNum++)
+ {
+ l_mcSide[l_sideNum].master_mc_found = false;
+ }
+
+ // ---------------------------------------------------------------------
+ // 1. Pick the first MCS/MI with DIMMS as potential master
+ // for both MC sides (MC01/MC23)
+ // ---------------------------------------------------------------------
+ for (const auto& l_mc : i_mc_targets)
+ {
+ uint8_t l_num_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(l_mc).size();
+
+ if (l_num_dimms > 0)
+ {
+ // This MCS or MI has DIMMs attached, find out which MC side it
+ // belongs to:
+ // l_sideNum = 0 --> MC01
+ // 1 --> MC23
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mc, l_pos),
+ "Error getting ATTR_CHIP_UNIT_POS on %s", mss::c_str(l_mc));
+ l_sideNum = l_pos / MAX_MC_SIDES_PER_PROC;
+
+ FAPI_INF("MCS %u has DIMMs", l_pos);
+
+ // If there's no master MCS or MI marked for this side yet, mark
+ // this MCS as master
+ if (l_mcSide[l_sideNum].master_mc_found == false)
+ {
+ FAPI_INF("Mark MCS %u as master for MC side %u",
+ l_pos, l_sideNum);
+ l_mcSide[l_sideNum].master_mc_found = true;
+ l_mcSide[l_sideNum].master_mc = l_mc;
+ }
+ }
+
+ prog_MCMODE0(l_mc, i_mc_targets);
+ }
+
+ // --------------------------------------------------------------
+ // 2. Program the master MI
+ // --------------------------------------------------------------
+ for (l_sideNum = 0; l_sideNum < MAX_MC_SIDES_PER_PROC; l_sideNum++)
+ {
+ // If there is a potential master MI found for this side
+ if (l_mcSide[l_sideNum].master_mc_found == true)
+ {
+ // No master MI programmed for either side yet,
+ // go ahead and program this MI as master.
+ if (l_numMasterProgrammed == 0)
+ {
+ FAPI_TRY(prog_master(l_mcSide[l_sideNum].master_mc),
+ "programMaster() returns error on %s", mss::c_str(l_mcSide[l_sideNum].master_mc));
+ l_numMasterProgrammed++;
+ }
+ }
+ }
+
+fapi_try_exit:
+ FAPI_DBG("Exiting");
+ return fapi2::current_err;
+}
+
+extern "C"
+{
+ ///
+ /// @brief p9a_throttle_sync procedure
+ ///
+ /// @param[in] i_target TARGET_TYPE_PROC_CHIP target
+ /// @return FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ fapi2::ReturnCode p9a_throttle_sync(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
+ {
+ FAPI_DBG("Executing p9a_throttle_sync on %s", mss::c_str(i_target));
+
+ const auto l_miChiplets = i_target.getChildren<fapi2::TARGET_TYPE_MI>();
+
+ if (l_miChiplets.size() > 0)
+ {
+ FAPI_TRY(throttle_sync(l_miChiplets), "Error calling throttle_sync() with vector of MI Chiplets");
+ }
+
+ fapi_try_exit:
+ FAPI_DBG("Exiting");
+ return fapi2::current_err;
+ }
+
+} // extern "C"
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.H b/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.H
new file mode 100644
index 000000000..c87312b23
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.H
@@ -0,0 +1,78 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/// ----------------------------------------------------------------------------
+/// @file p9a_throttle_sync.H
+///
+/// @brief p9a_throttle_sync HWP
+///
+/// The purpose of this procedure is to triggers sync command from a 'master'
+/// MC to other MCs that have attached memory in a processor.
+///
+/// ----------------------------------------------------------------------------
+/// *HWP HWP Owner : Joe McGill <jmcgill@us.ibm.com>
+/// *HWP HWP Backup : Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+/// *HWP FW Owner : Thi Tran <thi@us.ibm.com>
+/// *HWP Team : Nest
+/// *HWP Level : 3
+/// *HWP Consumed by : HB
+/// ----------------------------------------------------------------------------
+#ifndef _P9A_THROTTLE_SYNC_H_
+#define _P9A_THROTTLE_SYNC_H_
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+#include <p9a_mc_scom_addresses_fld.H>
+#include <p9a_misc_scom_addresses_fld.H>
+#include <p9a_misc_scom_addresses.H>
+#include <explorer_scom_addresses.H>
+#include <explorer_scom_addresses_fld.H>
+
+// Function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9a_throttle_sync_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);
+
+///
+/// @brief Structure that holds the potential master MI for a MC side (MC01/MC23)
+///
+struct mc_side_info_t
+{
+ bool master_mc_found = false;
+ fapi2::Target<fapi2::TARGET_TYPE_MI> master_mc; // Master MC for this MC side
+};
+
+extern "C"
+{
+ ///
+ /// @brief p9a_throttle_sync procedure
+ ///
+ /// @param[in] i_target TARGET_TYPE_PROC_CHIP target
+ /// @return FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ fapi2::ReturnCode p9a_throttle_sync(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);
+
+} // extern "C"
+
+#endif // _P9A_THROTTLE_SYNC_H_
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.mk b/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.mk
new file mode 100644
index 000000000..cf235b53d
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.mk
@@ -0,0 +1,30 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+PROCEDURE=p9a_throttle_sync
+$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/p9a/procedures/hwp/memory/)
+
+$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH))
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9/procedures/hwp/perv/p9_nv_ref_clk_enable.C b/src/import/chips/p9/procedures/hwp/perv/p9_nv_ref_clk_enable.C
index 43e396486..8c64aa78a 100644
--- a/src/import/chips/p9/procedures/hwp/perv/p9_nv_ref_clk_enable.C
+++ b/src/import/chips/p9/procedures/hwp/perv/p9_nv_ref_clk_enable.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -43,12 +43,16 @@
#include <p9_nv_ref_clk_enable.H>
#include <p9_perv_scom_addresses.H>
#include <p9_perv_scom_addresses_fld.H>
+#include <p9a_perv_scom_addresses.H>
+#include <p9a_perv_scom_addresses_fld.H>
//------------------------------------------------------------------------------
// Constant definitions
//------------------------------------------------------------------------------
const uint16_t TPFSI_OFFCHIP_REFCLK_EN_NV = 0xF;
+// P9A_PERV_ROOT_CTRL7_TP_TPIO_NV_REFCLK_EN_DC_LEN == 6
+const uint16_t P9A_NV_REFCLK_BIT_LEN = 4;
//------------------------------------------------------------------------------
// Function definitions
@@ -58,13 +62,27 @@ fapi2::ReturnCode
p9_nv_ref_clk_enable(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
FAPI_INF("Start");
- fapi2::buffer<uint64_t> l_root_ctrl6;
- FAPI_TRY(fapi2::getScom(i_target, PERV_ROOT_CTRL6_SCOM, l_root_ctrl6),
- "Error from getScom (PERV_ROOT_CTRL6_SCOM)");
- l_root_ctrl6.insertFromRight<PERV_ROOT_CTRL6_TSFSI_NV_REFCLK_EN_DC,
- PERV_ROOT_CTRL6_TSFSI_NV_REFCLK_EN_DC_LEN>(TPFSI_OFFCHIP_REFCLK_EN_NV);
- FAPI_TRY(fapi2::putScom(i_target, PERV_ROOT_CTRL6_SCOM, l_root_ctrl6),
- "Error from putScom (PERV_ROOT_CTRL6_SCOM)");
+ fapi2::buffer<uint64_t> l_root_ctrl;
+ fapi2::ATTR_CHIP_EC_FEATURE_ONE_NPU_TOP_Type l_one_npu;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_ONE_NPU_TOP, i_target, l_one_npu));
+
+ if (l_one_npu)
+ {
+ FAPI_TRY(fapi2::getScom(i_target, PERV_ROOT_CTRL6_SCOM, l_root_ctrl),
+ "Error from getScom (PERV_ROOT_CTRL6_SCOM)");
+ l_root_ctrl.insertFromRight<PERV_ROOT_CTRL6_TSFSI_NV_REFCLK_EN_DC,
+ PERV_ROOT_CTRL6_TSFSI_NV_REFCLK_EN_DC_LEN>(TPFSI_OFFCHIP_REFCLK_EN_NV);
+ FAPI_TRY(fapi2::putScom(i_target, PERV_ROOT_CTRL6_SCOM, l_root_ctrl),
+ "Error from putScom (PERV_ROOT_CTRL6_SCOM)");
+ }
+ else
+ {
+ FAPI_TRY(fapi2::getScom(i_target, P9A_PERV_ROOT_CTRL7_SCOM, l_root_ctrl),
+ "Error from getScom (P9A_PERV_ROOT_CTRL7_SCOM)");
+ l_root_ctrl.setBit<P9A_PERV_ROOT_CTRL7_TP_TPIO_NV_REFCLK_EN_DC, P9A_NV_REFCLK_BIT_LEN>();
+ FAPI_TRY(fapi2::putScom(i_target, P9A_PERV_ROOT_CTRL7_SCOM, l_root_ctrl),
+ "Error from putScom (P9A_PERV_ROOT_CTRL7_SCOM)");
+ }
fapi_try_exit:
FAPI_INF("End");
diff --git a/src/import/chips/p9/procedures/hwp/perv/p9_proc_gettracearray.H b/src/import/chips/p9/procedures/hwp/perv/p9_proc_gettracearray.H
index 9390108ed..5b39fc2a9 100644
--- a/src/import/chips/p9/procedures/hwp/perv/p9_proc_gettracearray.H
+++ b/src/import/chips/p9/procedures/hwp/perv/p9_proc_gettracearray.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -63,6 +63,7 @@ static const fapi2::TargetType PROC_GETTRACEARRAY_TARGET_TYPES =
fapi2::TARGET_TYPE_PROC_CHIP |
fapi2::TARGET_TYPE_OBUS |
fapi2::TARGET_TYPE_MCBIST |
+ fapi2::TARGET_TYPE_MC |
fapi2::TARGET_TYPE_EX |
fapi2::TARGET_TYPE_CORE;
@@ -98,10 +99,22 @@ extern "C"
{
return fapi2::TARGET_TYPE_EX;
}
- else
+ else if (i_trace_bus <= _PROC_TB_LAST_CORE_TARGET)
{
return fapi2::TARGET_TYPE_CORE;
}
+ else if (i_trace_bus <= _PROC_TB_LAST_AXONE_CHIP_TARGET)
+ {
+ return fapi2::TARGET_TYPE_PROC_CHIP;
+ }
+ else if (i_trace_bus <= _PROC_TB_LAST_AXONE_MC_TARGET)
+ {
+ return fapi2::TARGET_TYPE_MC;
+ }
+ else
+ {
+ return fapi2::TARGET_TYPE_EX;
+ }
}
/**
diff --git a/src/import/chips/p9/procedures/hwp/perv/p9_ram_core.C b/src/import/chips/p9/procedures/hwp/perv/p9_ram_core.C
index 24d789f02..87e1d5b70 100644
--- a/src/import/chips/p9/procedures/hwp/perv/p9_ram_core.C
+++ b/src/import/chips/p9/procedures/hwp/perv/p9_ram_core.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -49,6 +49,8 @@ const uint32_t RAM_REG_MSR = 2001;
const uint32_t RAM_REG_CR = 2002;
const uint32_t RAM_REG_FPSCR = 2003;
const uint32_t RAM_REG_VSCR = 2004;
+const uint32_t RAM_REG_SLBE = 2005;
+const uint32_t RAM_REG_SLBV = 2006;
// opcode for ramming
const uint32_t OPCODE_MTSPR_FROM_GPR0_TO_SPRD = 0x7C1543A6;
@@ -602,6 +604,16 @@ fapi2::ReturnCode RamCore::get_reg(const Enum_RegType i_type,
opcodes[8] = {&l_backup_vr0_dw0, OPCODE_MFSPR_FROM_SPRD_TO_GPR0 + (1 << 21), NULL};
opcodes[9] = {NULL, OPCODE_MTVSRDD_FROM_GPR1_0_TO_VSR32, NULL};
}
+ else if(i_reg_num == RAM_REG_SLBE)
+ {
+ opcodes[0] = {NULL, OPCODE_SLBMFEE, NULL};
+ opcodes[1] = {NULL, OPCODE_MTSPR_FROM_GPR0_TO_SPRD, &o_buffer[0]};
+ }
+ else if(i_reg_num == RAM_REG_SLBV)
+ {
+ opcodes[0] = {NULL, OPCODE_SLBMFEV, NULL};
+ opcodes[1] = {NULL, OPCODE_MTSPR_FROM_GPR0_TO_SPRD, &o_buffer[0]};
+ }
else
{
//1.create mfspr<gpr0, i_reg_num> opcode, ram into thread
diff --git a/src/import/chips/p9/procedures/hwp/perv/p9_sbe_hreset.C b/src/import/chips/p9/procedures/hwp/perv/p9_sbe_hreset.C
index 64153812f..fa51f80f9 100644
--- a/src/import/chips/p9/procedures/hwp/perv/p9_sbe_hreset.C
+++ b/src/import/chips/p9/procedures/hwp/perv/p9_sbe_hreset.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -55,6 +55,7 @@ fapi2::ReturnCode p9_sbe_i2c_bit_rate_divisor_setting(
{
uint8_t l_attr_nest_pll_bucket = 0;
const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
+ fapi2::ATTR_CHIP_EC_FEATURE_I2CM_INTERNAL_CLK_DIV2_Type l_i2cm_internal_clk_div2 = 0;
fapi2::buffer<uint16_t> l_mb_bit_rate_divisor;
fapi2::buffer<uint64_t> l_data64;
fapi2::buffer<uint32_t> l_data32;
@@ -63,7 +64,12 @@ fapi2::ReturnCode p9_sbe_i2c_bit_rate_divisor_setting(
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_NEST_PLL_BUCKET, FAPI_SYSTEM,
l_attr_nest_pll_bucket));
FAPI_INF("ATTR_NEST_PLL_BUCKET value: %d", l_attr_nest_pll_bucket);
- l_mb_bit_rate_divisor = NEST_PLL_FREQ_I2CDIV_LIST[l_attr_nest_pll_bucket - 1];
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_I2CM_INTERNAL_CLK_DIV2, i_target_chip, l_i2cm_internal_clk_div2));
+
+ l_mb_bit_rate_divisor = NEST_PLL_FREQ_I2CDIV_LIST[l_attr_nest_pll_bucket - 1] *
+ ((l_i2cm_internal_clk_div2) ? (2) : (1));
+
FAPI_INF("Bit_rate_divisor value: %d", l_mb_bit_rate_divisor);
FAPI_DBG("Adjust I2C bit rate divisor setting in I2CM B Mode Reg");
diff --git a/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.C b/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.C
index fdb602e74..640347186 100644
--- a/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.C
+++ b/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -103,14 +103,15 @@ enum chip_type_and_ec
{
NIMBUS = 1,
CUMULUS = 2,
- OTHER = 4,
+ AXONE = 4,
+ OTHER = 128,
ANY_CHIP = 0xFF,
};
struct ta_def
{
/* One entry per mux setting; value of 0 means N/A */
- p9_tracearray_bus_id bus_ids[TRACE_MUX_POSITIONS];
+ uint8_t bus_ids[TRACE_MUX_POSITIONS];
const uint8_t ex_odd_scom_offset: 2;
const uint8_t chiplet: 6;
const uint8_t base_multiplier;
@@ -133,12 +134,15 @@ struct ta_def
{ { PROC_TB_PB9 }, 0x00, 0x03, 0x03, ANY_CHIP },
{ { PROC_TB_PB10 }, 0x00, 0x03, 0x04, ANY_CHIP },
{ { PROC_TB_PB11 }, 0x00, 0x03, 0x05, ANY_CHIP },
- { { PROC_TB_MCD0, PROC_TB_MCD1, PROC_TB_VAS }, 0x00, 0x03, 0x06, ANY_CHIP },
- { { PROC_TB_MCS2, PROC_TB_MCS3, PROC_TB_PB13 }, 0x00, 0x03, 0x07, ANY_CHIP },
+ { { PROC_TB_MCD0, PROC_TB_MCD1, PROC_TB_VAS }, 0x00, 0x03, 0x06, NIMBUS | CUMULUS },
+ { { PROC_TB_MCS2, PROC_TB_MCS3, PROC_TB_PB13 }, 0x00, 0x03, 0x07, NIMBUS | CUMULUS },
+ { { PROC_TB_MCD0, PROC_TB_MCD1, PROC_TB_VAS, PROC_TB_NPU20 }, 0x00, 0x03, 0x06, AXONE },
+ { { PROC_TB_MCS2, PROC_TB_MCS3, PROC_TB_PB13, PROC_TB_NPU21 }, 0x00, 0x03, 0x07, AXONE },
{ { PROC_TB_PBIO0 }, 0x00, 0x03, 0x08, ANY_CHIP },
{ { PROC_TB_PBIO1 }, 0x00, 0x03, 0x09, ANY_CHIP },
/* N2 */
- { { PROC_TB_CXA1, PROC_TB_IOPSI }, 0x00, 0x04, 0x00, ANY_CHIP },
+ { { PROC_TB_CXA1, PROC_TB_IOPSI }, 0x00, 0x04, 0x00, NIMBUS | CUMULUS },
+ { { NO_TB, PROC_TB_IOPSI }, 0x00, 0x04, 0x00, AXONE },
{ { PROC_TB_PCIS0, PROC_TB_PCIS1, PROC_TB_PCIS2 }, 0x00, 0x04, 0x01, ANY_CHIP },
/* N3 */
{ { PROC_TB_PB0 }, 0x00, 0x05, 0x00, ANY_CHIP },
@@ -147,10 +151,13 @@ struct ta_def
{ { PROC_TB_PB3 }, 0x00, 0x05, 0x03, ANY_CHIP },
{ { PROC_TB_PB4 }, 0x00, 0x05, 0x04, ANY_CHIP },
{ { PROC_TB_PB5 }, 0x00, 0x05, 0x05, ANY_CHIP },
- { { PROC_TB_INT, PROC_TB_NPU1, PROC_TB_NMMU1 }, 0x00, 0x05, 0x06, ANY_CHIP },
- { { PROC_TB_MCS0, PROC_TB_MCS1, PROC_TB_PB12 }, 0x00, 0x05, 0x07, ANY_CHIP },
+ { { PROC_TB_INT, PROC_TB_NPU1, PROC_TB_NMMU1 }, 0x00, 0x05, 0x06, NIMBUS | CUMULUS },
+ { { PROC_TB_MCS0, PROC_TB_MCS1, PROC_TB_PB12 }, 0x00, 0x05, 0x07, NIMBUS | CUMULUS },
+ { { PROC_TB_NPU10, PROC_TB_INT, PROC_TB_NMMU1, PROC_TB_NPU01 }, 0x00, 0x05, 0x06, AXONE },
+ { { PROC_TB_MCS0, PROC_TB_MCS1, PROC_TB_PB12, PROC_TB_NPU11 }, 0x00, 0x05, 0x07, AXONE },
{ { PROC_TB_BRIDGE }, 0x00, 0x05, 0x08, ANY_CHIP },
- { { PROC_TB_NPU0 }, 0x00, 0x05, 0x0A, ANY_CHIP },
+ { { PROC_TB_NPU0 }, 0x00, 0x05, 0x0A, NIMBUS | CUMULUS },
+ { { PROC_TB_NPU00 }, 0x00, 0x05, 0x0A, AXONE },
{ { PROC_TB_NMMU0 }, 0x00, 0x05, 0x0B, ANY_CHIP },
/* XBUS */
{ { PROC_TB_PBIOX0, PROC_TB_IOX0 }, 0x00, 0x06, 0x00, ANY_CHIP },
@@ -166,12 +173,13 @@ struct ta_def
{ { PROC_TB_MCA0 }, 0x00, 0x07, 0x20, NIMBUS },
{ { PROC_TB_MCA1 }, 0x00, 0x07, 0x21, NIMBUS },
{ { PROC_TB_IOMC0, PROC_TB_IOMC1, PROC_TB_IOMC2, PROC_TB_IOMC3 }, 0x00, 0x07, 0x00, NIMBUS },
- { { PROC_TB_MCA0 }, 0x00, 0x07, 0x00, (uint8_t)~NIMBUS },
- { { PROC_TB_MCA1 }, 0x00, 0x07, 0x01, (uint8_t)~NIMBUS },
- { { PROC_TB_IOMC0, PROC_TB_IOMC1, PROC_TB_IOMC2, PROC_TB_IOMC3 }, 0x00, 0x07, 0x02, (uint8_t)~NIMBUS },
+ { { PROC_TB_MCA0 }, 0x00, 0x07, 0x00, CUMULUS | AXONE },
+ { { PROC_TB_MCA1 }, 0x00, 0x07, 0x01, CUMULUS | AXONE },
+ { { PROC_TB_IOMC0, PROC_TB_IOMC1, PROC_TB_IOMC2, PROC_TB_IOMC3 }, 0x00, 0x07, 0x02, CUMULUS },
+ { { PROC_TB_OMI0, PROC_TB_OMI1, PROC_TB_OMI2 }, 0x00, 0x07, 0x02, AXONE },
/* EX */
- { { PROC_TB_L20, NO_TB, NO_TB, PROC_TB_SKIT10 }, 0x01, 0x10, 0x94, ANY_CHIP },
- { { PROC_TB_L21, NO_TB, NO_TB, PROC_TB_SKIT11 }, 0x01, 0x10, 0x95, ANY_CHIP },
+ { { PROC_TB_L20, NO_TB, PROC_TB_SKIT00, PROC_TB_SKIT10 }, 0x01, 0x10, 0x94, ANY_CHIP },
+ { { PROC_TB_L21, NO_TB, PROC_TB_SKIT01, PROC_TB_SKIT11 }, 0x01, 0x10, 0x95, ANY_CHIP },
{ { PROC_TB_L30, PROC_TB_NCU0, PROC_TB_CME, PROC_TB_EQPB }, 0x02, 0x10, 0x00, ANY_CHIP },
{ { PROC_TB_L31, PROC_TB_NCU1, PROC_TB_IVRM, PROC_TB_SKEWADJ }, 0x02, 0x10, 0x01, ANY_CHIP },
/* CORE */
@@ -349,6 +357,9 @@ static chip_type_and_ec map_chip_type_and_ec(fapi2::ATTR_NAME_Type i_name, fapi2
case fapi2::ENUM_ATTR_NAME_CUMULUS:
return CUMULUS;
+ case fapi2::ENUM_ATTR_NAME_AXONE:
+ return AXONE;
+
default:
return OTHER;
}
@@ -412,24 +423,11 @@ fapi2::ReturnCode p9_sbe_tracearray(
}
}
- /* check that core trace arrays can be logged out, based on EC feature attribute */
- if (ta_type == fapi2::TARGET_TYPE_CORE)
- {
- uint8_t l_core_trace_not_scomable = 0;
-
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> proc_target =
- i_target.getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_CORE_TRACE_NOT_SCOMABLE,
- proc_target, l_core_trace_not_scomable),
- "Failed to query chip EC feature "
- "ATTR_CHIP_EC_FEATURE_CORE_TRACE_NOT_SCOMABLE");
-
- FAPI_ASSERT(!l_core_trace_not_scomable ||
- !i_args.collect_dump,
- fapi2::PROC_GETTRACEARRAY_CORE_NOT_DUMPABLE()
- .set_TARGET(i_target).set_TRACE_BUS(i_args.trace_bus),
- "Core arrays cannot be dumped in this chip EC; please use fastarray instead.");
- }
+ /* we cannot dump core trace arrays on any chip - permanent erratum. */
+ FAPI_ASSERT(!(i_args.collect_dump && ta_type == fapi2::TARGET_TYPE_CORE),
+ fapi2::PROC_GETTRACEARRAY_CORE_NOT_DUMPABLE()
+ .set_TARGET(i_target).set_TRACE_BUS(i_args.trace_bus),
+ "Core arrays cannot be dumped; please use fastarray instead.");
/* For convenience, we link Cache trace arrays to the virtual EX chiplets.
* Transform back to EQ chiplet. */
diff --git a/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.H b/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.H
index c587924b9..ecaf785f7 100644
--- a/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.H
+++ b/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -120,10 +120,22 @@ extern "C" {
{
return fapi2::TARGET_TYPE_EX;
}
- else
+ else if (i_trace_bus <= _PROC_TB_LAST_CORE_TARGET)
{
return fapi2::TARGET_TYPE_CORE;
}
+ else if (i_trace_bus <= _PROC_TB_LAST_AXONE_CHIP_TARGET)
+ {
+ return fapi2::TARGET_TYPE_PROC_CHIP;
+ }
+ else if (i_trace_bus <= _PROC_TB_LAST_AXONE_MC_TARGET)
+ {
+ return fapi2::TARGET_TYPE_PERV;
+ }
+ else
+ {
+ return fapi2::TARGET_TYPE_EX;
+ }
}
/* TODO via RTC:164528 - Look at optimization to improve performance
diff --git a/src/import/chips/p9/procedures/hwp/perv/p9_spr_name_map.H b/src/import/chips/p9/procedures/hwp/perv/p9_spr_name_map.H
index 6bf4ac961..abfc2effe 100644
--- a/src/import/chips/p9/procedures/hwp/perv/p9_spr_name_map.H
+++ b/src/import/chips/p9/procedures/hwp/perv/p9_spr_name_map.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -234,7 +234,9 @@ typedef std::map<std::string, SPRMapEntry>::iterator SPR_MAP_IT;
_op_(MSR ,2001, ECP.SD.T<??T>_MSR ,FLAG_READ_WRITE ,SPR_PER_PT ,64)\
_op_(CR ,2002, N/A ,FLAG_READ_WRITE ,SPR_PER_PT ,32)\
_op_(FPSCR ,2003, N/A ,FLAG_READ_WRITE ,SPR_PER_PT ,64)\
- _op_(VSCR ,2004, N/A ,FLAG_READ_WRITE ,SPR_PER_PT ,32)
+ _op_(VSCR ,2004, N/A ,FLAG_READ_WRITE ,SPR_PER_PT ,32)\
+ _op_(SLBE ,2005, N/A ,FLAG_READ_ONLY ,SPR_PER_PT ,64)\
+ _op_(SLBV ,2006, N/A ,FLAG_READ_ONLY ,SPR_PER_PT ,64)
#define DO_SPR_MAP(in_name, in_number, in_spy_name, in_flag, in_share_type, in_bit_length)\
SPRMapEntry entry##in_name; \
diff --git a/src/import/chips/p9/procedures/hwp/perv/p9_start_cbs.C b/src/import/chips/p9/procedures/hwp/perv/p9_start_cbs.C
index 914a78072..13990c15e 100644
--- a/src/import/chips/p9/procedures/hwp/perv/p9_start_cbs.C
+++ b/src/import/chips/p9/procedures/hwp/perv/p9_start_cbs.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -71,7 +71,6 @@ fapi2::ReturnCode p9_start_cbs(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
fapi2::buffer<uint8_t> l_read_attr;
fapi2::buffer<uint8_t> l_fifo_reset_skip;
const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
- fapi2::buffer<uint8_t> l_is_axone;
FAPI_INF("p9_start_cbs: Entering ...");
@@ -81,8 +80,6 @@ fapi2::ReturnCode p9_start_cbs(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_START_CBS_FIFO_RESET_SKIP,
FAPI_SYSTEM, l_fifo_reset_skip));
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_P9A_SBE_REGION, i_target_chip, l_is_axone));
-
FAPI_DBG("Clearing Selfboot message register before every boot ");
// buffer is init value is 0
FAPI_TRY(fapi2::putCfamRegister(i_target_chip, PERV_SB_MSG_FSI, l_data32));
@@ -203,70 +200,9 @@ fapi2::ReturnCode p9_start_cbs(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
.set_FSI2PIB_STATUS_READ(l_data32),
"ERROR:VDD OFF, FSI2PIB BIT 16 NOT SET");
- if (l_is_axone)
- {
- FAPI_DBG("Switching to PIB2PCB mux sel to 1 [till pcbnet clocks are started]");
- FAPI_TRY(p9_start_cbs_switch_to_pib2pcb_path_cfam(i_target_chip));
- }
-
FAPI_INF("p9_start_cbs: Exiting ...");
fapi_try_exit:
return fapi2::current_err;
}
-
-/// @brief Switching to PIB2PCB Path via cfam
-///
-/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP
-/// @return FAPI2_RC_SUCCESS if success, else error code.
-fapi2::ReturnCode p9_start_cbs_switch_to_pib2pcb_path_cfam(const
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target_chip)
-{
- fapi2::buffer<uint32_t> l_read_reg;
- FAPI_INF("p9_start_cbs_switch_to_pib2pcb_path_cfam: Entering ...");
-
- FAPI_DBG("Reading ROOT_CTRL0_REG");
- FAPI_TRY(fapi2::getCfamRegister(i_target_chip, PERV_ROOT_CTRL0_FSI, l_read_reg));
-
- if (!l_read_reg.getBit<PERV_ROOT_CTRL0_SET_PCB_RESET_DC>())
- {
- FAPI_DBG("Setting PCB RESET bit in ROOT_CTRL0_REG");
- l_read_reg.setBit<PERV_ROOT_CTRL0_SET_PCB_RESET_DC>();
- FAPI_TRY(fapi2::putCfamRegister(i_target_chip, PERV_ROOT_CTRL0_FSI, l_read_reg));
- }
-
- if (!l_read_reg.getBit<PERV_ROOT_CTRL0_18_SPARE_MUX_CONTROL>())
- {
- FAPI_DBG("Setting PIB2PCB bit in ROOT_CTRL0_REG");
- l_read_reg.setBit<PERV_ROOT_CTRL0_18_SPARE_MUX_CONTROL>();
- FAPI_TRY(fapi2::putCfamRegister(i_target_chip, PERV_ROOT_CTRL0_FSI, l_read_reg));
- }
-
- if (l_read_reg.getBit<PERV_ROOT_CTRL0_PIB2PCB_DC>())
- {
- FAPI_DBG("Clearing FSI2PCB bit in ROOT_CTRL0_REG");
- l_read_reg.clearBit<PERV_ROOT_CTRL0_PIB2PCB_DC>();
- FAPI_TRY(fapi2::putCfamRegister(i_target_chip, PERV_ROOT_CTRL0_FSI, l_read_reg));
- }
-
- if (l_read_reg.getBit<PERV_ROOT_CTRL0_19_SPARE_MUX_CONTROL>())
- {
- FAPI_DBG("Clearing PCB2PCB bit in ROOT_CTRL0_REG");
- l_read_reg.clearBit<PERV_ROOT_CTRL0_19_SPARE_MUX_CONTROL>();
- FAPI_TRY(fapi2::putCfamRegister(i_target_chip, PERV_ROOT_CTRL0_FSI, l_read_reg));
- }
-
- if (l_read_reg.getBit<PERV_ROOT_CTRL0_SET_PCB_RESET_DC>())
- {
- FAPI_DBG("Clearing PCB RESET bit in ROOT_CTRL0_REG");
- l_read_reg.clearBit<PERV_ROOT_CTRL0_SET_PCB_RESET_DC>();
- FAPI_TRY(fapi2::putCfamRegister(i_target_chip, PERV_ROOT_CTRL0_FSI, l_read_reg));
- }
-
- FAPI_INF("p9_start_cbs_switch_to_pib2pcb_path_cfam: Exiting ...");
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
diff --git a/src/import/chips/p9/procedures/hwp/perv/p9_tracearray_defs.H b/src/import/chips/p9/procedures/hwp/perv/p9_tracearray_defs.H
index 7cf13bdf9..c0f8d8e32 100644
--- a/src/import/chips/p9/procedures/hwp/perv/p9_tracearray_defs.H
+++ b/src/import/chips/p9/procedures/hwp/perv/p9_tracearray_defs.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -166,6 +166,27 @@ enum p9_tracearray_bus_id
/* Core chiplets - TARGET_TYPE_CORE */
PROC_TB_CORE0,
PROC_TB_CORE1,
+
+ _PROC_TB_LAST_CORE_TARGET = PROC_TB_CORE1,
+
+ /* New Axone trace buses */
+ PROC_TB_NPU00,
+ PROC_TB_NPU01,
+ PROC_TB_NPU10,
+ PROC_TB_NPU11,
+ PROC_TB_NPU20,
+ PROC_TB_NPU21,
+
+ _PROC_TB_LAST_AXONE_CHIP_TARGET = PROC_TB_NPU21,
+
+ PROC_TB_OMI0,
+ PROC_TB_OMI1,
+ PROC_TB_OMI2,
+
+ _PROC_TB_LAST_AXONE_MC_TARGET = PROC_TB_OMI2,
+
+ PROC_TB_SKIT00,
+ PROC_TB_SKIT01,
};
#endif //_P9_TRACEARRAY_DEFS_H
diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.C b/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.C
index 347bd3545..c40cf595c 100644
--- a/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.C
+++ b/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.C
@@ -97,10 +97,10 @@ extern "C"
*/
#define ROUND_OFF_32B( ROUND_SIZE) \
{ \
- uint32_t tempSize = ROUND_SIZE; \
- if( tempSize ) \
+ uint32_t temp = ROUND_SIZE; \
+ if( temp ) \
{ \
- ROUND_SIZE = (( ( tempSize + 31 )/32 ) * 32 ); \
+ ROUND_SIZE = (( ( temp + 31 )/32 ) * 32 ); \
} \
}
namespace p9_hcodeImageBuild
@@ -146,6 +146,7 @@ enum
SMF_BIT_CHECK = 0x0001000000000000ull,
INST_VALUE_SC2 = 0x44000042,
SRESET_WORD_POS = 0x40,
+ CPMR_VDM_PER_QUAD = 0x43504d525f322e30ull, //supports VDM per quad
};
/**
@@ -894,6 +895,8 @@ fapi2::ReturnCode updateImageFlags( Homerlayout_t* i_pChipHomer, CONST_FAPI2_PRO
uint16_t qmFlags = 0;
const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
+ cpmrHeader_t* pCpmrHdr =
+ (cpmrHeader_t*) & (i_pChipHomer->cpmrRegion.selfRestoreRegion.CPMR_SR.elements.CPMRHeader);
cmeHeader_t* pCmeHdr = (cmeHeader_t*) & i_pChipHomer->cpmrRegion.cmeSramRegion[CME_INT_VECTOR_SIZE];
sgpeHeader_t* pSgpeHdr = (sgpeHeader_t*)& i_pChipHomer->qpmrRegion.sgpeRegion.sgpeSramImage[SGPE_INT_VECTOR_SIZE];
PgpeHeader_t* pPgpeHdr = (PgpeHeader_t*)& i_pChipHomer->ppmrRegion.pgpeSramImage[PGPE_INT_VECTOR_SIZE];
@@ -1295,7 +1298,12 @@ fapi2::ReturnCode updateImageFlags( Homerlayout_t* i_pChipHomer, CONST_FAPI2_PRO
FAPI_DBG("WOF Enabled : %s", attrVal ? "TRUE" : "FALSE" );
+ if( SWIZZLE_8_BYTE(pCpmrHdr->magic_number) >= CPMR_VDM_PER_QUAD )
+ {
+ qmFlags |= CME_QM_FLAG_PER_QUAD_VDM_ENABLE;
+ }
+ FAPI_DBG("Quad VDM Enable : Yes" );
// Updating flag fields in the headers
pCmeHdr->g_cme_mode_flags = SWIZZLE_4_BYTE(cmeFlag);
@@ -1304,7 +1312,7 @@ fapi2::ReturnCode updateImageFlags( Homerlayout_t* i_pChipHomer, CONST_FAPI2_PRO
pPgpeHdr->g_pgpe_flags = SWIZZLE_2_BYTE(pgpeFlag);
FAPI_INF("CME Flag Value : 0x%08x", SWIZZLE_4_BYTE(pCmeHdr->g_cme_mode_flags));
- FAPI_INF("CME QM Flag Value : 0x%08x", SWIZZLE_2_BYTE(pCmeHdr->g_cme_qm_mode_flags));
+ FAPI_INF("CME QM Flag Value : 0x%04x", SWIZZLE_2_BYTE(pCmeHdr->g_cme_qm_mode_flags));
FAPI_INF("SGPE Flag Value : 0x%08x", SWIZZLE_4_BYTE(pSgpeHdr->g_sgpe_reserve_flags));
FAPI_INF("SGPE Chtm Config : 0x%016llx", SWIZZLE_8_BYTE(pSgpeHdr->g_sgpe_chtm_mem_cfg));
FAPI_INF("PGPE Flag Value : 0x%08x", SWIZZLE_2_BYTE(pPgpeHdr->g_pgpe_flags));
@@ -1321,12 +1329,18 @@ fapi_try_exit:
* @brief updates various CPMR fields which are associated with scan rings.
* @param[in] i_pChipHomer points to start of P9 HOMER.
*/
-void updateCpmrCmeRegion( Homerlayout_t* i_pChipHomer )
+fapi2::ReturnCode updateCpmrCmeRegion( Homerlayout_t* i_pChipHomer, CONST_FAPI2_PROC& i_procTgt )
{
FAPI_INF(">> updateCpmrCmeRegion");
- cpmrHeader_t* pCpmrHdr =
+ cpmrHeader_t* pCpmrHdr =
(cpmrHeader_t*) & (i_pChipHomer->cpmrRegion.selfRestoreRegion.CPMR_SR.elements.CPMRHeader);
- cmeHeader_t* pCmeHdr = (cmeHeader_t*) & i_pChipHomer->cpmrRegion.cmeSramRegion[CME_INT_VECTOR_SIZE];
+ cmeHeader_t* pCmeHdr = (cmeHeader_t*) & i_pChipHomer->cpmrRegion.cmeSramRegion[CME_INT_VECTOR_SIZE];
+ uint32_t l_pstateSize = sizeof(LocalPstateParmBlock);
+ ROUND_OFF_32B(l_pstateSize);
+ uint8_t l_cmePos = 0;
+ auto cmeList = i_procTgt.getChildren<fapi2::TARGET_TYPE_EX>(fapi2::TARGET_STATE_FUNCTIONAL);
+ uint32_t l_cmeCustSize = SWIZZLE_4_BYTE(pCmeHdr->g_cme_custom_length);
+ uint64_t l_cpmrMagic = SWIZZLE_8_BYTE(pCpmrHdr->magic_number);
//Updating CPMR Header using info from CME Header
pCpmrHdr->cmeImgOffset = SWIZZLE_4_BYTE((CME_IMAGE_CPMR_OFFSET >> CME_BLK_SIZE_SHIFT));
@@ -1338,6 +1352,7 @@ void updateCpmrCmeRegion( Homerlayout_t* i_pChipHomer )
pCpmrHdr->coreScomLength = SWIZZLE_4_BYTE(CORE_SCOM_RESTORE_SIZE_TOTAL);
pCpmrHdr->coreMaxScomEntry = SWIZZLE_4_BYTE(MAX_CORE_SCOM_ENTRIES);
+
if( pCmeHdr->g_cme_common_ring_length )
{
pCpmrHdr->cmeCommonRingOffset = CME_IMAGE_CPMR_OFFSET + SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_offset);
@@ -1356,21 +1371,54 @@ void updateCpmrCmeRegion( Homerlayout_t* i_pChipHomer )
pCpmrHdr->coreSpecRingLength = pCmeHdr->g_cme_max_spec_ring_length; // already swizzled
}
+ FAPI_INF( "Custom Len 0x%08x", l_cmeCustSize );
+ for( auto cme : cmeList )
+ {
+ uint32_t *pPstateOffset = (uint32_t *)&pCpmrHdr->quad0PstateOffset;
+ FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS, cme, l_cmePos),
+ "fapiGetAttribute of ATTR_CHIP_UNIT_POS");
+
+ //Populating CPMR fields for CME PState field
+
+ pPstateOffset = pPstateOffset + (l_cmePos >> 1);
+
+ if( l_cpmrMagic >= CPMR_VDM_PER_QUAD )
+ {
+ *pPstateOffset = SWIZZLE_4_BYTE(pCpmrHdr->coreSpecRingOffset) +
+ SWIZZLE_4_BYTE(pCpmrHdr->coreSpecRingLength) + ( (l_cmePos) * l_cmeCustSize );
+ *pPstateOffset = SWIZZLE_4_BYTE(*pPstateOffset);
+ }
+ else
+ {
+ *pPstateOffset = 0; //ensures compatibility with quad common LPSPB
+ }
+ }
+
//Updating CME Image header
- pCmeHdr->g_cme_scom_offset = SWIZZLE_4_BYTE(pCmeHdr->g_cme_hcode_length) +
- SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_region_length) +
- SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_length);
- pCmeHdr->g_cme_scom_offset =
- ((pCmeHdr->g_cme_scom_offset + CME_BLOCK_READ_LEN - 1 ) >> CME_BLK_SIZE_SHIFT);
+ if( l_cpmrMagic >= CPMR_VDM_PER_QUAD )
+ {
+ pCmeHdr->g_cme_scom_offset = SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_offset) +
+ (l_pstateSize >> CME_BLK_SIZE_SHIFT);
+ }
+ else //ensures compatibility with quad common LPSPB
+ {
+ pCmeHdr->g_cme_scom_offset = SWIZZLE_4_BYTE(pCmeHdr->g_cme_hcode_length) +
+ SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_region_length) +
+ SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_length);
+ pCmeHdr->g_cme_scom_offset =
+ ((pCmeHdr->g_cme_scom_offset + CME_BLOCK_READ_LEN - 1 ) >> CME_BLK_SIZE_SHIFT);
+ //Adding to it instance ring length which is already a multiple of 32B
+ pCmeHdr->g_cme_scom_offset += SWIZZLE_4_BYTE(pCmeHdr->g_cme_max_spec_ring_length);
+ }
+
+ pCmeHdr->g_cme_scom_offset = SWIZZLE_4_BYTE(pCmeHdr->g_cme_scom_offset);
//Adding to it instance ring length which is already a multiple of 32B
- pCmeHdr->g_cme_scom_offset += SWIZZLE_4_BYTE(pCmeHdr->g_cme_max_spec_ring_length);
- pCmeHdr->g_cme_scom_offset = SWIZZLE_4_BYTE(pCmeHdr->g_cme_scom_offset);
- pCmeHdr->g_cme_scom_length = SWIZZLE_4_BYTE(CORE_SCOM_RESTORE_SIZE_PER_CME);
+ pCmeHdr->g_cme_scom_length = SWIZZLE_4_BYTE(CORE_SCOM_RESTORE_SIZE_PER_CME);
// Timebase frequency
uint32_t l_ppe_timebase_hz;
calcPPETimebase(&l_ppe_timebase_hz);
- pCmeHdr->g_cme_timebase_hz = SWIZZLE_4_BYTE(l_ppe_timebase_hz);
+ pCmeHdr->g_cme_timebase_hz = SWIZZLE_4_BYTE(l_ppe_timebase_hz);
FAPI_INF("========================= CME Header Start ==================================");
FAPI_INF(" HC Offset : 0x%08X", SWIZZLE_4_BYTE(pCmeHdr->g_cme_hcode_offset));
@@ -1382,6 +1430,7 @@ void updateCpmrCmeRegion( Homerlayout_t* i_pChipHomer )
FAPI_INF(" CR Size : 0x%08X", SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_length));
FAPI_INF(" CSR Offset : 0x%08X (Real offset / 32) ", SWIZZLE_4_BYTE(pCmeHdr->g_cme_core_spec_ring_offset));
FAPI_INF(" CSR Length : 0x%08X (Real length / 32)", SWIZZLE_4_BYTE(pCmeHdr->g_cme_max_spec_ring_length) );
+ FAPI_INF(" CME PS Offset : 0x%08X", SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_offset));
FAPI_INF(" SCOM Offset : 0x%08X (Real offset / 32)", SWIZZLE_4_BYTE(pCmeHdr->g_cme_scom_offset));
FAPI_INF(" SCOM Area Len : 0x%08X", SWIZZLE_4_BYTE(pCmeHdr->g_cme_scom_length));
FAPI_INF(" CPMR Phy Add : 0x%016lx", SWIZZLE_8_BYTE(pCmeHdr->g_cme_cpmr_PhyAddr));
@@ -1391,6 +1440,7 @@ void updateCpmrCmeRegion( Homerlayout_t* i_pChipHomer )
FAPI_INF("========================= CME Header End ==================================");
FAPI_INF("==========================CPMR Header===========================================");
+ FAPI_INF(" CPMR Ver : 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->cpmrVersion));
FAPI_INF(" CME HC Offset : 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->cmeImgOffset));
FAPI_INF(" CME HC Length : 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->cmeImgLength));
FAPI_INF(" PS Offset : 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->cmePstateOffset));
@@ -1402,9 +1452,18 @@ void updateCpmrCmeRegion( Homerlayout_t* i_pChipHomer )
FAPI_INF(" Core SCOM Offset : 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->coreScomOffset));
FAPI_INF(" Core SCOM Length : 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->coreScomLength ));
FAPI_INF(" Max SCOM Entries : 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->coreMaxScomEntry));
+ FAPI_INF(" Quad0 P-State : 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->quad0PstateOffset));
+ FAPI_INF(" Quad1 P-State : 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->quad1PstateOffset));
+ FAPI_INF(" Quad2 P-State : 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->quad2PstateOffset));
+ FAPI_INF(" Quad3 P-State : 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->quad3PstateOffset));
+ FAPI_INF(" Quad4 P-State : 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->quad4PstateOffset));
+ FAPI_INF(" Quad5 P-State : 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->quad5PstateOffset));
+
FAPI_INF("==================================CPMR Ends=====================================");
FAPI_INF("<< updateCpmrCmeRegion");
+fapi_try_exit:
+ return fapi2::current_err;
}
//------------------------------------------------------------------------------
@@ -1432,8 +1491,8 @@ void updateCpmrHeaderSR( Homerlayout_t* i_pChipHomer, uint8_t i_fusedState, uint
if( SMF_SELF_SIGNATURE == i_smfSign )
{
- pCpmrHdr->selfRestoreVer = 0x01;
- pCpmrHdr->stopApiVer = 0x01;
+ pCpmrHdr->selfRestoreVer = SELF_SAVE_RESTORE_VER;
+ pCpmrHdr->stopApiVer = STOP_API_CPU_SAVE_VER;
}
else
{
@@ -1839,6 +1898,7 @@ fapi2::ReturnCode buildCoreRestoreImage( void* const i_pImageIn,
FAPI_TRY( initSmfDisabledSelfRestore( i_pChipHomer ),
"Failed To Initialize Self-Restore Region In Non SMF Mode" );
}
+
}
updateCpmrHeaderSR( i_pChipHomer, i_fusedState, i_procFuncModel.isSmfEnabled(), l_pSmfSignature );
@@ -1915,14 +1975,18 @@ fapi2::ReturnCode buildCmeImage( void* const i_pImageIn, Homerlayout_t* i_pChipH
// Names have g_ prefix as these global variables for CME Hcode
// Note: Only the *memory* addresses are updated
cmeHeader_t* pImgHdr = (cmeHeader_t*) & i_pChipHomer->cpmrRegion.cmeSramRegion[CME_INT_VECTOR_SIZE];
- pImgHdr->g_cme_hcode_offset = CME_SRAM_HCODE_OFFSET;
- pImgHdr->g_cme_hcode_length = ppeSection.iv_size;
+ pImgHdr->g_cme_hcode_offset = CME_SRAM_HCODE_OFFSET;
+ pImgHdr->g_cme_hcode_length = ppeSection.iv_size;
//Populating common ring offset here. So, that other scan ring related field can be updated.
- pImgHdr->g_cme_cpmr_PhyAddr = (i_cpmrPhyAdd | CPMR_HOMER_OFFSET);
- pImgHdr->g_cme_pstate_region_offset = pImgHdr->g_cme_hcode_offset + pImgHdr->g_cme_hcode_length;
pImgHdr->g_cme_pstate_region_length = 0;
- pImgHdr->g_cme_common_ring_offset = pImgHdr->g_cme_pstate_region_offset + pImgHdr->g_cme_pstate_region_length;
+ pImgHdr->g_cme_pstate_region_offset = 0;
+ pImgHdr->g_cme_cpmr_PhyAddr = (i_cpmrPhyAdd | CPMR_HOMER_OFFSET);
+
+
+ pImgHdr->g_cme_common_ring_offset = pImgHdr->g_cme_hcode_offset +
+ pImgHdr->g_cme_hcode_length;
+
pImgHdr->g_cme_common_ring_length = 0;
pImgHdr->g_cme_scom_offset = 0;
pImgHdr->g_cme_scom_length = CORE_SCOM_RESTORE_SIZE_PER_CME;
@@ -1931,7 +1995,6 @@ fapi2::ReturnCode buildCmeImage( void* const i_pImageIn, Homerlayout_t* i_pChipH
//Let us handle the endianess at the end
pImgHdr->g_cme_pstate_region_offset = SWIZZLE_4_BYTE(pImgHdr->g_cme_pstate_region_offset);
- pImgHdr->g_cme_common_ring_offset = SWIZZLE_4_BYTE(pImgHdr->g_cme_common_ring_offset);
pImgHdr->g_cme_hcode_offset = SWIZZLE_4_BYTE(pImgHdr->g_cme_hcode_offset);
pImgHdr->g_cme_hcode_length = SWIZZLE_4_BYTE(pImgHdr->g_cme_hcode_length);
pImgHdr->g_cme_scom_length = SWIZZLE_4_BYTE(pImgHdr->g_cme_scom_length);
@@ -2419,6 +2482,7 @@ fapi2::ReturnCode updatePgpeHeader( void* const i_pHomer, CONST_FAPI2_PROC& i_pr
pPgpeHdr->g_pgpe_beacon_addr = 0;
pPgpeHdr->g_quad_status_addr = 0;
pPgpeHdr->g_pgpe_wof_state_address = 0;
+ pPgpeHdr->g_pgpe_wof_values_address = 0;
pPgpeHdr->g_pgpe_req_active_quad_address = 0;
pPgpeHdr->g_wof_table_addr = SWIZZLE_4_BYTE(pPpmrHdr->g_ppmr_wof_table_offset);
pPgpeHdr->g_wof_table_length = SWIZZLE_4_BYTE(pPpmrHdr->g_ppmr_wof_table_length);
@@ -2526,6 +2590,46 @@ fapi_try_exit:
//---------------------------------------------------------------------------
+fapi2::ReturnCode buildCmePstateInfo( Homerlayout_t * i_pHomer, CONST_FAPI2_PROC& i_procTgt,
+ ImageType_t i_imgType, PstateSuperStructure * i_pSuperStruct )
+{
+ FAPI_DBG(">> buildCmePstateInfo");
+ uint8_t l_cmePos = 0;
+ cmeHeader_t* pCmeHdr = (cmeHeader_t*) &i_pHomer->cpmrRegion.cmeSramRegion[CME_INT_VECTOR_SIZE];
+ auto cmeList = i_procTgt.getChildren<fapi2::TARGET_TYPE_EX>(fapi2::TARGET_STATE_FUNCTIONAL);
+ uint8_t * l_pCmePstate = NULL;
+ uint32_t l_pstateSize = sizeof(LocalPstateParmBlock);
+ ROUND_OFF_32B(l_pstateSize);
+ uint32_t l_ringSize = (SWIZZLE_4_BYTE(pCmeHdr->g_cme_max_spec_ring_length) << CME_BLK_SIZE_SHIFT );
+ uint32_t l_cmeCustSize = l_ringSize + l_pstateSize;
+
+ uint32_t l_cmeCurIndex = ( SWIZZLE_4_BYTE(pCmeHdr->g_cme_core_spec_ring_offset) << CME_BLK_SIZE_SHIFT );
+ l_cmeCurIndex += l_ringSize;
+
+ for( auto cme : cmeList )
+ {
+ FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS, cme, l_cmePos),
+ "fapiGetAttribute of ATTR_CHIP_UNIT_POS");
+ //copying CME specific LPSPB info into HOMER
+ l_pCmePstate =
+ (uint8_t *) &i_pHomer->cpmrRegion.cmeSramRegion[ (l_cmeCustSize * l_cmePos ) + l_cmeCurIndex ];
+ memcpy( l_pCmePstate, &i_pSuperStruct->localppb[(l_cmePos >> 1)], sizeof(LocalPstateParmBlock) );
+
+ //Populating CPMR fields for CME PState field
+ }
+
+ pCmeHdr->g_cme_pstate_offset = ( l_cmeCurIndex >> CME_BLK_SIZE_SHIFT );
+ pCmeHdr->g_cme_pstate_offset = SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_offset);
+ pCmeHdr->g_cme_custom_length = SWIZZLE_4_BYTE(l_cmeCustSize >> CME_BLK_SIZE_SHIFT);
+
+ FAPI_INF( "CME PS Offset 0x%08x x32= 0x%08x", SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_offset), l_cmeCurIndex );
+
+fapi_try_exit:
+ FAPI_DBG("<< buildCmePstateInfo");
+ return fapi2::current_err;
+}
+//---------------------------------------------------------------------------
+
/**
* @brief updates the PState parameter block info in CPMR and PPMR region
* @param[in] i_pHomer points to start of of chip's HOMER
@@ -2542,32 +2646,31 @@ fapi2::ReturnCode buildParameterBlock( void* const i_pHomer, CONST_FAPI2_PROC& i
{
FAPI_INF(">> buildParameterBlock");
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ PstateSuperStructure stateSupStruct;
+
+ FAPI_IMP("Size of sup-struct 0x%08x", sizeof(PstateSuperStructure));
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ uint32_t pgpeRunningOffset = 0;
+ uint32_t sizePStateBlock = 0;
+ uint32_t wofTableSize = i_sizeBuf1;
+ uint32_t localPStateBlock = 0;
+ uint32_t sizeAligned = 0;
+ fapi2::ReturnCode retCode;
if( i_imgType.pgpePstateParmBlockBuild )
{
-
- fapi2::ReturnCode retCode;
Homerlayout_t* pHomerLayout = (Homerlayout_t*)i_pHomer;
PPMRLayout_t* pPpmr = (PPMRLayout_t*) &pHomerLayout->ppmrRegion;
cmeHeader_t* pCmeHdr = (cmeHeader_t*) &pHomerLayout->cpmrRegion.cmeSramRegion[CME_INT_VECTOR_SIZE];
+ cpmrHeader_t* pCpmrHdr =
+ (cpmrHeader_t*) & (pHomerLayout->cpmrRegion.selfRestoreRegion.CPMR_SR.elements.CPMRHeader);
+ uint32_t localPspbStartIndex = SWIZZLE_4_BYTE(pCmeHdr->g_cme_hcode_length);
+
fapi2::ATTR_WOF_ENABLED_Type l_wof_enabled;
uint32_t ppmrRunningOffset = SWIZZLE_4_BYTE(io_ppmrHdr.g_ppmr_hcode_offset) +
SWIZZLE_4_BYTE(io_ppmrHdr.g_ppmr_hcode_length);
- FAPI_DBG("Hcode ppmrRunningOffset 0x%08x", ppmrRunningOffset );
-
- uint32_t pgpeRunningOffset = SWIZZLE_4_BYTE(io_ppmrHdr.g_ppmr_hcode_length);
-
- FAPI_DBG(" PGPE Hcode End 0x%08x", pgpeRunningOffset );
-
- uint32_t sizeAligned = 0;
- uint32_t sizePStateBlock = 0;
- uint32_t wofTableSize = i_sizeBuf1;
-
- // Allocate struct onto stack
- PstateSuperStructure stateSupStruct;
// Clearing i_pBuf1
memset(i_pBuf1,0x00,i_sizeBuf1);
@@ -2580,39 +2683,45 @@ fapi2::ReturnCode buildParameterBlock( void* const i_pHomer, CONST_FAPI2_PROC& i
//Check if WOF Table is copied properly even if WOF is disabled.
//As this is memory range check, we don't want memory corruption
//issues to go unnoticed as this should not EVER happen.
+
FAPI_ASSERT( ( wofTableSize <= OCC_WOF_TABLES_SIZE ),
fapi2::PARAM_WOF_TABLE_SIZE_ERR()
.set_ACTUAL_WOF_TABLE_SIZE(wofTableSize)
.set_MAX_SIZE_ALLOCATED(OCC_WOF_TABLES_SIZE),
"Size of WOF Table Exceeds Max Size Allowed" );
-
//-------------------------- Local P-State Parameter Block ------------------------------
- uint32_t localPspbStartIndex = SWIZZLE_4_BYTE(pCmeHdr->g_cme_hcode_length);
- uint8_t* pLocalPState = &pHomerLayout->cpmrRegion.cmeSramRegion[localPspbStartIndex];
-
- sizePStateBlock = sizeof(LocalPstateParmBlock);
-
- //Note: Not checking size here. Once entire CME Image layout is complete, there is a
- //size check at last. WE are safe as long as everthing put together doesn't exceed
- //maximum SRAM image size allowed(32KB). No need to check size of Local P-State
- //parameter block individually.
-
- FAPI_DBG("Copying Local P-State Parameter Block into CPMR" );
- memcpy( pLocalPState, &(stateSupStruct.localppb), sizePStateBlock );
-
- ALIGN_DBWORD( sizeAligned, sizePStateBlock )
- uint32_t localPStateBlock = sizeAligned;
- FAPI_DBG("LPSPB Actual size 0x%08x After Alignment 0x%08x", sizePStateBlock, sizeAligned );
-
- pCmeHdr->g_cme_pstate_region_length = localPStateBlock;
- pCmeHdr->g_cme_common_ring_offset = SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_offset) + localPStateBlock;
+ FAPI_INF( "Magic Word 0x%016lx Copy Start Index 0x%08x", SWIZZLE_8_BYTE(pCpmrHdr->magic_number), localPspbStartIndex );
+ if( SWIZZLE_8_BYTE(pCpmrHdr->magic_number) >= CPMR_VDM_PER_QUAD )
+ {
+ FAPI_TRY( buildCmePstateInfo( pHomerLayout, i_procTgt, i_imgType, &stateSupStruct ),
+ "Failed to copy quad P-State info in CME SRAM image region" );
+ }
+ else
+ {
+ uint8_t* pLocalPState = &pHomerLayout->cpmrRegion.cmeSramRegion[localPspbStartIndex];
+ sizePStateBlock = sizeof(LocalPstateParmBlock);
+ //Note: Not checking size here. Once entire CME Image layout is complete, there is a
+ //size check at last. WE are safe as long as everthing put together doesn't exceed
+ //maximum SRAM image size allowed(32KB). No need to check size of Local P-State
+ //parameter block individually.
+
+ FAPI_DBG("Copying Local P-State Parameter Block into CPMR" );
+ memcpy( pLocalPState, &(stateSupStruct.localppb), sizePStateBlock );
+ ALIGN_DBWORD( sizeAligned, sizePStateBlock )
+ localPStateBlock = sizeAligned;
+ FAPI_DBG("LPSPB Actual size 0x%08x After Alignment 0x%08x", sizePStateBlock, sizeAligned );
+ pCmeHdr->g_cme_pstate_region_length = localPStateBlock;
+ pCmeHdr->g_cme_pstate_region_offset = SWIZZLE_4_BYTE(pCmeHdr->g_cme_hcode_offset) +
+ SWIZZLE_4_BYTE(pCmeHdr->g_cme_hcode_length);
+ pCmeHdr->g_cme_common_ring_offset = pCmeHdr->g_cme_pstate_region_offset + localPStateBlock;
+ }
//-------------------------- Local P-State Parameter Block Ends --------------------------
//-------------------------- Global P-State Parameter Block ------------------------------
- FAPI_DBG("Copying Global P-State Parameter Block" );
+ pgpeRunningOffset = SWIZZLE_4_BYTE(io_ppmrHdr.g_ppmr_hcode_length);
sizePStateBlock = sizeof(GlobalPstateParmBlock);
FAPI_ASSERT( ( sizePStateBlock <= PGPE_GLOBAL_PSTATE_PARAM_BLOCK_SIZE),
@@ -2622,7 +2731,7 @@ fapi2::ReturnCode buildParameterBlock( void* const i_pHomer, CONST_FAPI2_PROC& i
.set_ACTUAL_SIZE( sizePStateBlock ),
"Size of Global Parameter Block Exceeds Max Size Allowed" );
- FAPI_DBG("GPPBB pgpeRunningOffset 0x%08x", pgpeRunningOffset );
+ FAPI_DBG("Copying Global P-State Parameter Block" );
memcpy( &pPpmr->pgpeSramImage[pgpeRunningOffset],
&(stateSupStruct.globalppb), sizePStateBlock );
@@ -2666,10 +2775,18 @@ fapi2::ReturnCode buildParameterBlock( void* const i_pHomer, CONST_FAPI2_PROC& i
sizePStateBlock );
//-------------------------- OCC P-State Parameter Block Ends ------------------------------
+ //Not relevant any longer. Kept for legacy reason. Now we have field per quad.
- io_ppmrHdr.g_ppmr_lppb_offset = CPMR_HOMER_OFFSET + CME_IMAGE_CPMR_OFFSET + localPspbStartIndex;
- io_ppmrHdr.g_ppmr_lppb_length = localPStateBlock;
-
+ if( SWIZZLE_8_BYTE(pCpmrHdr->magic_number) >= CPMR_VDM_PER_QUAD )
+ {
+ io_ppmrHdr.g_ppmr_lppb_offset = 0;
+ io_ppmrHdr.g_ppmr_lppb_length = 0;
+ }
+ else
+ {
+ io_ppmrHdr.g_ppmr_lppb_offset = CPMR_HOMER_OFFSET + CME_IMAGE_CPMR_OFFSET + localPspbStartIndex;
+ io_ppmrHdr.g_ppmr_lppb_length = localPStateBlock;
+ }
//------------------------------ OCC P-State Table Allocation ------------------------------
// The PPMR offset is from the begining --- which is the ppmrHeader
@@ -2683,6 +2800,7 @@ fapi2::ReturnCode buildParameterBlock( void* const i_pHomer, CONST_FAPI2_PROC& i
io_ppmrHdr.g_ppmr_wof_table_length = OCC_WOF_TABLES_SIZE;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_WOF_ENABLED, i_procTgt, l_wof_enabled));
+
if (l_wof_enabled)
{
memcpy( &pPpmr->wofTableSize, i_pBuf1, wofTableSize );
@@ -2697,10 +2815,11 @@ fapi2::ReturnCode buildParameterBlock( void* const i_pHomer, CONST_FAPI2_PROC& i
FAPI_DBG("OPPB pgpeRunningOffset 0x%08x io_ppmrHdr.g_ppmr_pgpe_sram_img_size 0x%08x",
pgpeRunningOffset, io_ppmrHdr.g_ppmr_pgpe_sram_img_size );
- //Finally let us handle endianess
+ //let us handle endianess
//CME Header
pCmeHdr->g_cme_pstate_region_length = SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_region_length);
pCmeHdr->g_cme_common_ring_offset = SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_offset);
+ pCmeHdr->g_cme_pstate_region_offset = SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_region_offset);
//PPMR Header
io_ppmrHdr.g_ppmr_gppb_offset = SWIZZLE_4_BYTE(io_ppmrHdr.g_ppmr_gppb_offset);
@@ -2860,13 +2979,22 @@ fapi2::ReturnCode layoutInstRingsForCme( Homerlayout_t* i_pHomer,
{
FAPI_DBG( ">> layoutInstRingsForCme");
uint32_t rc = IMG_BUILD_SUCCESS;
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ cpmrHeader_t* pCpmrHdr =
+ (cpmrHeader_t*) & (i_pHomer->cpmrRegion.selfRestoreRegion.CPMR_SR.elements.CPMRHeader);
// Let us find out ring-pair which is biggest in list of 12 ring pairs
- uint32_t maxCoreSpecRingLength = 0;
- uint32_t ringLength = 0;
- uint32_t tempSize = 0;
- uint32_t tempRepairLength = 0;
- uint32_t ringStartToHdrOffset = ( TOR_VER_ONE == tor_version() ) ? RING_START_TO_RS4_OFFSET : 0;
+ uint32_t maxCoreSpecRingLength = 0;
+ uint32_t ringLength = 0;
+ uint32_t tempSize = 0;
+ uint32_t tempRepairLength = 0;
+ uint32_t ringStartToHdrOffset = ( TOR_VER_ONE == tor_version() ) ? RING_START_TO_RS4_OFFSET : 0;
+ uint32_t cmePstateSize = 0;
+
+ if( SWIZZLE_8_BYTE(pCpmrHdr->magic_number) >= CPMR_VDM_PER_QUAD )
+ {
+ cmePstateSize = sizeof(LocalPstateParmBlock);
+ ROUND_OFF_32B(cmePstateSize);
+ }
if( i_imgType.cmeHcodeBuild )
{
@@ -2926,7 +3054,7 @@ fapi2::ReturnCode layoutInstRingsForCme( Homerlayout_t* i_pHomer,
ROUND_OFF_32B(maxCoreSpecRingLength);
}
- FAPI_DBG("Max Instance Spec Ring 0x%08X", maxCoreSpecRingLength);
+ FAPI_DBG("Max Instance Spec Ring 0x%08X Pstate Size Considered 0x%08x", maxCoreSpecRingLength, cmePstateSize );
// Let us copy the rings now.
uint8_t* pRingStart = NULL;
@@ -2935,7 +3063,8 @@ fapi2::ReturnCode layoutInstRingsForCme( Homerlayout_t* i_pHomer,
for( uint32_t exId = 0; exId < MAX_CMES_PER_CHIP; exId++ )
{
- pRingStart = (uint8_t*)&i_pHomer->cpmrRegion.cmeSramRegion[io_ringLength + ( exId * maxCoreSpecRingLength ) ];
+ pRingStart = (uint8_t*)&i_pHomer->cpmrRegion.cmeSramRegion[io_ringLength +
+ ( exId * ( maxCoreSpecRingLength + cmePstateSize ) ) ];
pRingPayload = pRingStart + sizeof(CoreSpecRingList_t);
pScanRingIndex = (uint16_t*)pRingStart;
@@ -3151,6 +3280,8 @@ fapi2::ReturnCode layoutRingsForCME( Homerlayout_t* i_pHomer,
uint32_t ringLength = 0;
uint32_t tempLength = 0;
RingVariant_t l_ringVariant = RV_BASE;
+ cpmrHeader_t* pCpmrHdr =
+ (cpmrHeader_t*) & (i_pHomer->cpmrRegion.selfRestoreRegion.CPMR_SR.elements.CPMRHeader);
cmeHeader_t* pCmeHdr = (cmeHeader_t*) &i_pHomer->cpmrRegion.cmeSramRegion[CME_INT_VECTOR_SIZE];
RingBucket cmeRings( PLAT_CME,
(uint8_t*)&i_pHomer->cpmrRegion,
@@ -3179,10 +3310,16 @@ fapi2::ReturnCode layoutRingsForCME( Homerlayout_t* i_pHomer,
break;
}
- ringLength = SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_region_offset) + SWIZZLE_4_BYTE(
- pCmeHdr->g_cme_pstate_region_length);
+ ringLength = SWIZZLE_4_BYTE(pCmeHdr->g_cme_hcode_offset) + SWIZZLE_4_BYTE(
+ pCmeHdr->g_cme_hcode_length);
+
+ if( SWIZZLE_8_BYTE(pCpmrHdr->magic_number) < CPMR_VDM_PER_QUAD )
+ {
+ ringLength += sizeof(LocalPstateParmBlock);
+ }
+
//save the length where hcode ends
- tempLength = ringLength;
+ tempLength = ringLength;
FAPI_TRY( layoutCmnRingsForCme( i_pHomer, i_chipState, i_ringData,
i_debugMode, l_ringVariant,
@@ -3383,7 +3520,6 @@ fapi2::ReturnCode layoutCmnRingsForSgpe( Homerlayout_t* i_pHomer,
RingBucket& io_sgpeRings )
{
FAPI_INF(">> layoutCmnRingsForSgpe");
-
uint32_t rc = IMG_BUILD_SUCCESS;
uint32_t sgpeHcodeSize = SWIZZLE_4_BYTE(io_qpmrHdr.sgpeImgLength);
uint8_t* pCmnRingPayload = &i_pHomer->qpmrRegion.sgpeRegion.sgpeSramImage[sgpeHcodeSize +
@@ -3462,7 +3598,7 @@ fapi2::ReturnCode layoutCmnRingsForSgpe( Homerlayout_t* i_pHomer,
.set_RING_ID( torRingId )
.set_EC_LEVEL( i_chipState.getChipLevel() )
.set_CHIP_TYPE( i_chipState.getChipName() ),
- "Failed To Complete Quad Common Ring Layout" );
+ "Failed To Complete Quad Common Ring Layout 0x%08x ring id 0x%08x variant %d", rc, torRingId, l_ringVariant );
memcpy( pCmnRingPayload, i_ringData.iv_pWorkBuf1, tempBufSize);
io_sgpeRings.setRingOffset( pCmnRingPayload, io_sgpeRings.getCommonRingId( ringIndex ) );
@@ -3663,12 +3799,10 @@ fapi2::ReturnCode layoutRingsForSGPE( Homerlayout_t* i_pHomer,
}
//Manage the Quad Common rings in HOMER
-
FAPI_TRY( layoutCmnRingsForSgpe( i_pHomer, i_chipState, i_ringData,
i_debugMode, l_ringVariant, io_qpmrHdr,
i_imgType, sgpeRings),
"Quad Common Ring Layout Failed");
-
//Manage the Quad Override rings in HOMER
FAPI_TRY( layoutSgpeScanOverride( i_pHomer, i_pOverride, i_chipState,
@@ -4822,12 +4956,10 @@ fapi2::ReturnCode populateUnsecureHomerAddress( CONST_FAPI2_PROC& i_procTgt, Hom
pCmeHdr->g_cme_unsec_cpmr_PhyAddr = pCmeHdr->g_cme_cpmr_PhyAddr;
goto fapi_try_exit;
}
-
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_UNSECURE_HOMER_ADDRESS,
i_procTgt,
l_unsecureHomerAdd),
"Error from FAPI_ATTR_GET for attribute ATTR_UNSECURE_HOMER_ADDRESS");
-
FAPI_INF( "Atrribute ATTR_UNSECURE_HOMER_ADDRESS 0x%016lx", l_unsecureHomerAdd );
if( l_unsecureHomerAdd & 0x1fffff )
@@ -4902,7 +5034,6 @@ fapi2::ReturnCode initUnsecureHomer( void* const i_pBuf2, const uint32_t i_s
}
//--------------------------------------------------------------------------------------------------------
-
fapi2::ReturnCode p9_hcode_image_build( CONST_FAPI2_PROC& i_procTgt,
void* const i_pImageIn,
void* i_pHomerImage,
@@ -5018,10 +5149,6 @@ fapi2::ReturnCode p9_hcode_image_build( CONST_FAPI2_PROC& i_procTgt,
FAPI_TRY( buildPgpeAux( pChipHomer ),
"Failed to build auxiliary function in PPMR" );
- //Update P State parameter block info in HOMER
- FAPI_TRY( buildParameterBlock( pChipHomer, i_procTgt, l_ppmrHdr, i_imgType, i_pBuf1, i_sizeBuf1 ),
- "Failed to Add Parameter Block" );
-
FAPI_INF("PGPE built");
//Let us add Scan Rings to the image.
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RING_DBG_MODE,
@@ -5082,8 +5209,13 @@ fapi2::ReturnCode p9_hcode_image_build( CONST_FAPI2_PROC& i_procTgt,
FAPI_TRY( populateUnsecureHomerAddress( i_procTgt, pChipHomer, l_chipFuncModel.isSmfEnabled() ),
"Failed To Populate Unsecure HOMER Region with sc2 instruction" );
+ //Update P State parameter block info in HOMER
+ FAPI_TRY( buildParameterBlock( pChipHomer, i_procTgt, l_ppmrHdr, i_imgType, i_pBuf1, i_sizeBuf1 ),
+ "Failed to Add Parameter Block" );
+
//Update CPMR Header with Scan Ring details
- updateCpmrCmeRegion( pChipHomer );
+ FAPI_TRY( updateCpmrCmeRegion( pChipHomer, i_procTgt ),
+ "Failed to update CPMR CME region" );
//Update QPMR Header area in HOMER
@@ -5139,7 +5271,6 @@ fapi2::ReturnCode p9_hcode_image_build( CONST_FAPI2_PROC& i_procTgt,
FAPI_TRY( initUnsecureHomer( i_pBuf2, i_sizeBuf2 ),
"Failed to initialize unsecure HOMER" );
-
fapi_try_exit:
FAPI_IMP("<< p9_hcode_image_build" );
return fapi2::current_err;
diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pm_corequad_init.C b/src/import/chips/p9/procedures/hwp/pm/p9_pm_corequad_init.C
index 77cd232e8..db22f670e 100644
--- a/src/import/chips/p9/procedures/hwp/pm/p9_pm_corequad_init.C
+++ b/src/import/chips/p9/procedures/hwp/pm/p9_pm_corequad_init.C
@@ -684,14 +684,14 @@ fapi2::ReturnCode pm_disable_resclk(
uint16_t l_quad_table_value;
uint8_t l_caccr_bit_13_14_value = 0;
- uint32_t attr_freq_proc_refclock_khz = 0;
+ uint32_t attr_freq_dpll_refclock_khz = 0;
uint32_t attr_proc_dpll_divider = 8;
const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
auto l_exChiplets = i_target.getChildren<fapi2::TARGET_TYPE_EX>
(fapi2::TARGET_STATE_FUNCTIONAL);
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FREQ_PROC_REFCLOCK_KHZ, FAPI_SYSTEM, attr_freq_proc_refclock_khz)
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FREQ_DPLL_REFCLOCK_KHZ, FAPI_SYSTEM, attr_freq_dpll_refclock_khz)
, "Attribute read failed");
//Read the frequency of the quad
l_address = EQ_QPPM_DPLL_FREQ;
@@ -701,10 +701,10 @@ fapi2::ReturnCode pm_disable_resclk(
l_data64.extractToRight<EQ_QPPM_DPLL_FREQ_FMULT,
EQ_QPPM_DPLL_FREQ_FMULT_LEN>(l_fmult);
- FAPI_INF("EQ_QPPM_DPLL_FREQ_FMULT %04x, attr_freq_proc_refclock_khz %08x, attr_proc_dpll_divider %x",
- l_fmult, attr_freq_proc_refclock_khz, attr_proc_dpll_divider);
+ FAPI_INF("EQ_QPPM_DPLL_FREQ_FMULT %04x, attr_freq_dpll_refclock_khz %08x, attr_proc_dpll_divider %x",
+ l_fmult, attr_freq_dpll_refclock_khz, attr_proc_dpll_divider);
- l_fmult = ((l_fmult * attr_freq_proc_refclock_khz ) / attr_proc_dpll_divider) / 1000;
+ l_fmult = ((l_fmult * attr_freq_dpll_refclock_khz ) / attr_proc_dpll_divider) / 1000;
FAPI_INF("EQ_QPPM_DPLL_FREQ FMULT value %08x", l_fmult);
diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket.C b/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket.C
index 9a13c51a2..7e31dbf78 100644
--- a/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket.C
+++ b/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -44,6 +44,34 @@
#include <p9_pm_get_poundw_bucket.H>
#include <attribute_ids.H>
+#ifdef __VDM_TEST
+
+uint8_t dummy_attr[] =
+{
+ 0x30, 0x05,
+ 0x2F, 0x6A, 0x04, 0x68, 0x05, 0xC0, 0x23, 0x12, 0x41, 0x42,
+ 0x42, 0x42, 0x42, 0x43, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73,
+ 0x02, 0x53, 0xA1, 0x04, 0x6A, 0x00, 0x00,
+
+ 0x1B, 0xF0, 0x07, 0x95, 0x07, 0x40, 0x23, 0x12, 0x23, 0x24,
+ 0x24, 0x24, 0x24, 0x25, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73,
+ 0x02, 0x53, 0xA1, 0x04, 0x6A, 0x00, 0x00,
+
+ 0x40, 0x42, 0x04, 0x2C, 0x04, 0xD0, 0x23, 0x12, 0x5A, 0x5A,
+ 0x5A, 0x5B, 0x5B, 0x5B, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73,
+ 0x02, 0x53, 0xA1, 0x04, 0x6A, 0x00, 0x00,
+
+ 0x60, 0x85, 0x0E, 0xD1, 0x0C, 0xF0, 0x23, 0x12, 0x80, 0x80,
+ 0x80, 0x80, 0x81, 0x81, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73,
+ 0x02, 0x53, 0xA1, 0x04, 0x6A, 0x00, 0x00,
+
+ 0x9C, 0x40, 0x14, 0xEE, 0x09, 0x98, 0x4E, 0x20, 0x27, 0x10,
+ 0x01, 0x02, 0x03, 0xFF, 0x03, 0x7F, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+#endif
+
// See doxygen in header file
fapi2::ReturnCode p9_pm_get_poundw_bucket(
const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target,
@@ -59,7 +87,15 @@ fapi2::ReturnCode p9_pm_get_poundw_bucket(
i_target,
l_bucketAttr));
- memcpy(&o_data, l_bucketAttr, sizeof(o_data));
+ memcpy(&o_data, l_bucketAttr, sizeof(o_data));
+
+#ifdef __VDM_TEST
+
+ memcpy( &o_data, dummy_attr, sizeof(o_data) );
+
+#endif
+
+ FAPI_INF( "COPYING from ATTR_POUNDW_BUCKET_DATA" );
fapi_try_exit:
FAPI_DBG("Exiting p9_pm_get_poundw_bucket ....");
diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket.H b/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket.H
index 47f72c091..1ca6b36f9 100644
--- a/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket.H
+++ b/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -59,7 +59,7 @@ typedef struct __attribute__((__packed__)) vdmData
// bucket Id
uint8_t bucketId;
// VDM data
- uint8_t vdmData[PW_VER_2_VDMDATA_SIZE];
+ uint8_t vdmData[PW_VER_30_VDMDATA_SIZE];
} vdmData_t;
}
diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket_attr.C b/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket_attr.C
index 40a2b03de..331c4c22f 100644
--- a/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket_attr.C
+++ b/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket_attr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -51,7 +51,7 @@ fapi2::ReturnCode p9_pm_get_poundw_bucket_attr(
uint8_t* l_fullVpdData = nullptr;
uint32_t l_vpdSize = 0;
uint8_t l_bucketId;
- uint8_t l_bucketSize = 0;
+ uint8_t l_bucketSize = PW_VER_30_VDMDATA_SIZE;
//To read MVPD we will need the proc parent of the inputted EQ target
fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_procParent =
@@ -116,6 +116,10 @@ fapi2::ReturnCode p9_pm_get_poundw_bucket_attr(
//Set the size of the bucket
l_bucketSize = POUNDW_BUCKETID_SIZE + PW_VER_2_VDMDATA_SIZE;
}
+ else if ( ( *l_fullVpdData ) >= POUNDW_VERSION_30 )
+ {
+ l_bucketSize = POUNDW_BUCKETID_SIZE + PW_VER_30_VDMDATA_SIZE;
+ }
else
{
FAPI_ASSERT( false,
diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket_attr.H b/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket_attr.H
index 6e425ba3b..edf2eb011 100644
--- a/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket_attr.H
+++ b/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundw_bucket_attr.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -44,13 +44,15 @@
enum poundwBucketParms
{
- POUNDW_VERSION_1 = 0x01,
- POUNDW_VERSION_2 = 0x02,
- POUNDW_VERSION_F = 0x0F,
- POUNDW_VERSION_SIZE = 0x01, // version is uint8_t
- POUNDW_BUCKETID_SIZE = 0x01, // bucket ID is uint8_t
- PW_VER_1_VDMDATA_SIZE = 0x28,
- PW_VER_2_VDMDATA_SIZE = 0x3C,
+ POUNDW_VERSION_1 = 0x01,
+ POUNDW_VERSION_2 = 0x02,
+ POUNDW_VERSION_F = 0x0F,
+ POUNDW_VERSION_30 = 0x30,
+ POUNDW_VERSION_SIZE = 0x01, // version is uint8_t
+ POUNDW_BUCKETID_SIZE = 0x01, // bucket ID is uint8_t
+ PW_VER_1_VDMDATA_SIZE = 0x28,
+ PW_VER_2_VDMDATA_SIZE = 0x3C,
+ PW_VER_30_VDMDATA_SIZE = 0x87,
};
diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pm_pstate_gpe_init.C b/src/import/chips/p9/procedures/hwp/pm/p9_pm_pstate_gpe_init.C
index 8483b9308..01e27f604 100644
--- a/src/import/chips/p9/procedures/hwp/pm/p9_pm_pstate_gpe_init.C
+++ b/src/import/chips/p9/procedures/hwp/pm/p9_pm_pstate_gpe_init.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -263,10 +263,10 @@ fapi2::ReturnCode pstate_gpe_init(
auto l_eqChiplets = i_target.getChildren<fapi2::TARGET_TYPE_EQ>
(fapi2::TARGET_STATE_FUNCTIONAL);
fapi2::ATTR_SAFE_MODE_FREQUENCY_MHZ_Type l_attr_safe_mode_freq_mhz;
- fapi2::ATTR_FREQ_PROC_REFCLOCK_KHZ_Type l_ref_clock_freq_khz;
+ fapi2::ATTR_FREQ_DPLL_REFCLOCK_KHZ_Type l_ref_clock_freq_khz;
fapi2::ATTR_PROC_DPLL_DIVIDER_Type l_proc_dpll_divider;
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_FREQUENCY_MHZ, i_target, l_attr_safe_mode_freq_mhz));
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FREQ_PROC_REFCLOCK_KHZ, FAPI_SYSTEM, l_ref_clock_freq_khz));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FREQ_DPLL_REFCLOCK_KHZ, FAPI_SYSTEM, l_ref_clock_freq_khz));
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_DPLL_DIVIDER, i_target, l_proc_dpll_divider));
// Convert frequency value to a format that needs to be written to the
// register
diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pm_reset.C b/src/import/chips/p9/procedures/hwp/pm/p9_pm_reset.C
index f3b28a9b4..04c14d2a1 100644
--- a/src/import/chips/p9/procedures/hwp/pm/p9_pm_reset.C
+++ b/src/import/chips/p9/procedures/hwp/pm/p9_pm_reset.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -500,7 +500,7 @@ p9_pm_reset_psafe_update(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_ta
fapi2::ATTR_VDD_AVSBUS_BUSNUM_Type l_vdd_bus_num;
fapi2::ATTR_VDD_AVSBUS_RAIL_Type l_vdd_bus_rail;
fapi2::ATTR_VDD_BOOT_VOLTAGE_Type l_vdd_voltage_mv;
- fapi2::ATTR_FREQ_PROC_REFCLOCK_KHZ_Type l_freq_proc_refclock_khz;
+ fapi2::ATTR_FREQ_DPLL_REFCLOCK_KHZ_Type l_freq_proc_refclock_khz;
fapi2::ATTR_PROC_DPLL_DIVIDER_Type l_proc_dpll_divider;
fapi2::ATTR_SAFE_MODE_NOVDM_UPLIFT_MV_Type l_uplift_mv;
fapi2::ATTR_EXTERNAL_VRM_STEPSIZE_Type l_ext_vrm_step_size_mv;
@@ -511,7 +511,7 @@ p9_pm_reset_psafe_update(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_ta
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_VDD_AVSBUS_RAIL, i_target, l_vdd_bus_rail));
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_VDD_BOOT_VOLTAGE, i_target, l_vdd_voltage_mv));
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_DPLL_DIVIDER, i_target, l_proc_dpll_divider));
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FREQ_PROC_REFCLOCK_KHZ, FAPI_SYSTEM, l_freq_proc_refclock_khz));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FREQ_DPLL_REFCLOCK_KHZ, FAPI_SYSTEM, l_freq_proc_refclock_khz));
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_NOVDM_UPLIFT_MV, i_target, l_uplift_mv));
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_EXTERNAL_VRM_STEPSIZE, FAPI_SYSTEM, l_ext_vrm_step_size_mv));
l_attr_safe_mode_mv += l_uplift_mv;
diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.C b/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.C
index cedb6d1eb..413c340b0 100644
--- a/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.C
+++ b/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.C
@@ -198,19 +198,19 @@ const uint8_t g_sysvfrtData[] =
VDN_PERCENT_KEY, // vdn percentage(1B),
0x05, // vdd percentage(1B)
QID_KEY, // quad id(1B)
- 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
- 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
- 0xA8, 0xA5, 0xA5, 0xA1, 0x9D, 0x9A, 0xA8, 0xA8, 0xA8,
- 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
- 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA5, 0xA5,
- 0xA1, 0x9D, 0x9A, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
- 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
+ 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
+ 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
+ 0xA8, 0xA5, 0xA5, 0xA1, 0x9D, 0x9A, 0xA8, 0xA8, 0xA8,
+ 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
+ 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA5, 0xA5,
+ 0xA1, 0x9D, 0x9A, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
+ 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
0xA8, 0xA8, 0xA8, 0xA8, 0xA5, 0xA5, 0xA1, 0x9D, 0x9A,
- 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
- 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
- 0xA8, 0xA5, 0xA5, 0xA1, 0x9D, 0x9A, 0xA8, 0xA8, 0xA8,
- 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
- 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA5, 0xA5,
+ 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
+ 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
+ 0xA8, 0xA5, 0xA5, 0xA1, 0x9D, 0x9A, 0xA8, 0xA8, 0xA8,
+ 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
+ 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA5, 0xA5,
0xA1, 0x9D, 0x9A
};
@@ -223,6 +223,8 @@ char const* region_names[] = { "REGION_POWERSAVE_NOMINAL",
};
char const* prt_region_names[] = VPD_OP_SLOPES_REGION_ORDER_STR;
+const uint32_t LEGACY_RESISTANCE_ENTRY_SIZE = 10;
+
//the value in this table are in Index format
uint8_t g_GreyCodeIndexMapping [] =
{
@@ -254,7 +256,7 @@ p9_pstate_parameter_block( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_
uint8_t* o_buf,
uint32_t& io_size)
{
- FAPI_DBG("> p9_pstate_parameter_block");
+ FAPI_IMP("> p9_pstate_parameter_block");
const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
fapi2::ReturnCode l_rc = 0;
io_size = 0;
@@ -278,8 +280,8 @@ p9_pstate_parameter_block( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_
memset (&l_globalppb, 0, sizeof(GlobalPstateParmBlock));
// CME content
- LocalPstateParmBlock l_localppb;
- memset (&l_localppb, 0, sizeof(LocalPstateParmBlock));
+ LocalPstateParmBlock l_localppb[MAX_QUADS_PER_CHIP];
+ memset ( &l_localppb, 0, ( MAX_QUADS_PER_CHIP * sizeof(LocalPstateParmBlock) ) );
// OCC content
OCCPstateParmBlock l_occppb;
@@ -333,7 +335,7 @@ p9_pstate_parameter_block( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_
// ----------------
// Initialize VDM data
// ----------------
- l_pmPPB.vdm_init();
+ FAPI_TRY(l_pmPPB.vdm_init());
// ----------------
// get Resonant clocking attributes
@@ -348,7 +350,7 @@ p9_pstate_parameter_block( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_
// ----------------
// Initialize LPPB structure
// ----------------
- FAPI_TRY(l_pmPPB.lppb_init(&l_localppb));
+ FAPI_TRY(l_pmPPB.lppb_init(&l_localppb[0]));
// ----------------
// WOF initialization
@@ -371,25 +373,26 @@ p9_pstate_parameter_block( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_
// Put out the Parmater Blocks to the trace
- gppb_print(&(l_globalppb));
+ FAPI_TRY(gppb_print(&(l_globalppb), i_target));
oppb_print(&(l_occppb));
// Populate Global,local and OCC parameter blocks into Pstate super structure
- (*io_pss).globalppb = l_globalppb;
- (*io_pss).localppb = l_localppb;
- (*io_pss).occppb = l_occppb;
+ (*io_pss).globalppb = l_globalppb;
+ (*io_pss).occppb = l_occppb;
+
+ memcpy( &((*io_pss).localppb), &l_localppb, ( MAX_QUADS_PER_CHIP * sizeof(LocalPstateParmBlock) ) );
}
while(0);
fapi_try_exit:
- FAPI_DBG("< p9_pstate_parameter_block");
+ FAPI_IMP("< p9_pstate_parameter_block");
return fapi2::current_err;
}
// END OF PSTATE PARAMETER BLOCK function
///////////////////////////////////////////////////////////
-//////// freq2pState
+//////// freq2pState
///////////////////////////////////////////////////////////
int PlatPmPPB::freq2pState (const uint32_t i_freq_khz,
Pstate* o_pstate,
@@ -477,22 +480,22 @@ fapi2::ReturnCode PlatPmPPB::set_global_feature_attributes()
(fapi2::ATTR_WOV_OVERV_ENABLED_Type)fapi2::ENUM_ATTR_WOV_OVERV_ENABLED_FALSE;
- iv_wov_underv_enabled = false;
- iv_wov_overv_enabled = false;
//Check whether to enable WOV Undervolting. WOV can
//only be enabled if VDMs are enabled
- if (is_wov_underv_enabled() &&
- is_vdm_enabled())
+ if (!is_wov_underv_enabled() ||
+ !is_vdm_enabled())
{
- iv_wov_underv_enabled = true;
+ FAPI_DBG("UNDERV_DISABLED")
+ iv_wov_underv_enabled = false;
}
//Check whether to enable WOV Overvolting. WOV can
//only be enabled if VDMs are enabled
- if (is_wov_overv_enabled() &&
- is_vdm_enabled())
+ if (!is_wov_overv_enabled() ||
+ !is_vdm_enabled())
{
- iv_wov_overv_enabled = true;
+ FAPI_DBG("OVERV_DISABLED")
+ iv_wov_overv_enabled = false;
}
if (iv_pstates_enabled)
@@ -546,7 +549,7 @@ fapi_try_exit:
} //end of set_global_feature_attributes
///////////////////////////////////////////////////////////
-//////// oppb_init
+//////// oppb_init
///////////////////////////////////////////////////////////
fapi2::ReturnCode PlatPmPPB::oppb_init(
OCCPstateParmBlock *i_occppb )
@@ -620,7 +623,7 @@ fapi2::ReturnCode PlatPmPPB::oppb_init(
revle16(iv_poundW_data.poundw[TURBO].ivdd_tdp_ac_current_10ma);
i_occppb->lac_tdp_vdd_nominal_10ma =
revle16(iv_poundW_data.poundw[NOMINAL].ivdd_tdp_ac_current_10ma);
- FAPI_INF("l_occppb.lac_tdp_vdd_turbo_10ma 0x%x (%d)",
+ FAPI_INF("l_occppb.lac_tdp_vdd_turbo_10ma 0x%x (%d)",
i_occppb->lac_tdp_vdd_turbo_10ma, i_occppb->lac_tdp_vdd_turbo_10ma);
FAPI_INF("l_occppb.lac_tdp_vdd_nominal_10ma 0x%x (%d)",
i_occppb->lac_tdp_vdd_nominal_10ma, i_occppb->lac_tdp_vdd_nominal_10ma);
@@ -676,7 +679,7 @@ fapi2::ReturnCode PlatPmPPB::oppb_init(
///////////////////////////////////////////////////////////
-//////// lppb_init
+//////// lppb_init
///////////////////////////////////////////////////////////
fapi2::ReturnCode PlatPmPPB::lppb_init(
LocalPstateParmBlock *i_localppb)
@@ -684,79 +687,91 @@ fapi2::ReturnCode PlatPmPPB::lppb_init(
FAPI_INF(">>>>>>>> lppb_init");
do
{
- // -----------------------------------------------
- // Local parameter block
- // -----------------------------------------------
- i_localppb->magic = revle64(LOCAL_PARMSBLOCK_MAGIC);
+ uint8_t l_eqPos = 0;
+ auto l_eqChiplets = iv_procChip.getChildren<fapi2::TARGET_TYPE_EQ>(fapi2::TARGET_STATE_FUNCTIONAL);
+ LocalPstateParmBlock *l_pLocalPspbTemp = NULL;
- // VpdBias External and Internal Biases for Global and Local parameter
- // block
- for (uint8_t i = 0; i < NUM_OP_POINTS; i++)
+ for( auto eq : l_eqChiplets )
{
- i_localppb->ext_biases[i] = iv_bias[i];
- i_localppb->int_biases[i] = iv_bias[i];
- }
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, eq, l_eqPos ));
+ l_pLocalPspbTemp = i_localppb + l_eqPos;
- //load vpd operating points
- for (uint32_t i = 0; i < NUM_OP_POINTS; i++)
- {
- i_localppb->operating_points[i].frequency_mhz = revle32(iv_biased_vpd_pts[i].frequency_mhz);
- i_localppb->operating_points[i].vdd_mv = revle32(iv_biased_vpd_pts[i].vdd_mv);
- i_localppb->operating_points[i].idd_100ma = revle32(iv_biased_vpd_pts[i].idd_100ma);
- i_localppb->operating_points[i].vcs_mv = revle32(iv_biased_vpd_pts[i].vcs_mv);
- i_localppb->operating_points[i].ics_100ma = revle32(iv_biased_vpd_pts[i].ics_100ma);
- i_localppb->operating_points[i].pstate = iv_biased_vpd_pts[i].pstate;
- }
+ // -----------------------------------------------
+ // Local parameter block
+ // -----------------------------------------------
+ l_pLocalPspbTemp->magic = revle64(LOCAL_PARMSBLOCK_MAGIC);
+
+ // VpdBias External and Internal Biases for Global and Local parameter
+ // block
+ for (uint8_t i = 0; i < NUM_OP_POINTS; i++)
+ {
+ l_pLocalPspbTemp->ext_biases[i] = iv_bias[i];
+ l_pLocalPspbTemp->int_biases[i] = iv_bias[i];
+ }
- i_localppb->vdd_sysparm = iv_vdd_sysparam;
+ //load vpd operating points
+ for (uint32_t i = 0; i < NUM_OP_POINTS; i++)
+ {
+ l_pLocalPspbTemp->operating_points[i].frequency_mhz = revle32(iv_biased_vpd_pts[i].frequency_mhz);
+ l_pLocalPspbTemp->operating_points[i].vdd_mv = revle32(iv_biased_vpd_pts[i].vdd_mv);
+ l_pLocalPspbTemp->operating_points[i].idd_100ma = revle32(iv_biased_vpd_pts[i].idd_100ma);
+ l_pLocalPspbTemp->operating_points[i].vcs_mv = revle32(iv_biased_vpd_pts[i].vcs_mv);
+ l_pLocalPspbTemp->operating_points[i].ics_100ma = revle32(iv_biased_vpd_pts[i].ics_100ma);
+ l_pLocalPspbTemp->operating_points[i].pstate = iv_biased_vpd_pts[i].pstate;
+ }
- // IvrmParmBlock
- i_localppb->ivrm = iv_ivrmpb;
+ l_pLocalPspbTemp->vdd_sysparm = iv_vdd_sysparam;
- // VDMParmBlock
- memset (&(i_localppb->vdm),0,sizeof(i_localppb->vdm));
+ // IvrmParmBlock
+ l_pLocalPspbTemp->ivrm = iv_ivrmpb;
- i_localppb->dpll_pstate0_value =
- ((iv_reference_frequency_khz) /
- (iv_frequency_step_khz));
- i_localppb->dpll_pstate0_value = revle32(i_localppb->dpll_pstate0_value);
+ // VDMParmBlock
+ memset (&(l_pLocalPspbTemp->vdm), 0, sizeof(l_pLocalPspbTemp->vdm));
- FAPI_INF("l_localppb.dpll_pstate0_value %X (%d)",
- revle32(i_localppb->dpll_pstate0_value),
- revle32(i_localppb->dpll_pstate0_value));
+ l_pLocalPspbTemp->dpll_pstate0_value =
+ ((iv_reference_frequency_khz) /
+ (iv_frequency_step_khz));
+ l_pLocalPspbTemp->dpll_pstate0_value = revle32(l_pLocalPspbTemp->dpll_pstate0_value);
- i_localppb->resclk = iv_resclk_setup;
+ FAPI_INF("l_localppb.dpll_pstate0_value %X (%d)",
+ revle32(l_pLocalPspbTemp->dpll_pstate0_value),
+ revle32(l_pLocalPspbTemp->dpll_pstate0_value));
- if (iv_attrs.attr_system_vdm_disable == fapi2::ENUM_ATTR_SYSTEM_VDM_DISABLE_OFF)
- {
+ l_pLocalPspbTemp->resclk = iv_resclk_setup;
+
+ if (iv_attrs.attr_system_vdm_disable == fapi2::ENUM_ATTR_SYSTEM_VDM_DISABLE_OFF)
+ {
- //Initializing threshold and jump values for LPPB
- memcpy ( i_localppb->vid_point_set,
- iv_vid_point_set,
- sizeof(i_localppb->vid_point_set));
+ //Initializing threshold and jump values for LPPB
+ memcpy ( l_pLocalPspbTemp->vid_point_set,
+ iv_vid_point_set,
+ sizeof(l_pLocalPspbTemp->vid_point_set));
- memcpy ( i_localppb->threshold_set,
- iv_threshold_set,
- sizeof(i_localppb->threshold_set));
+ memcpy ( l_pLocalPspbTemp->threshold_set,
+ iv_threshold_set,
+ sizeof(l_pLocalPspbTemp->threshold_set));
- memcpy ( i_localppb->jump_value_set,
- iv_jump_value_set,
- sizeof(i_localppb->jump_value_set));
+ memcpy ( l_pLocalPspbTemp->jump_value_set,
+ iv_jump_value_set,
+ sizeof(l_pLocalPspbTemp->jump_value_set));
- memcpy ( i_localppb->PsVIDCompSlopes,
- iv_PsVIDCompSlopes,
- sizeof(i_localppb->PsVIDCompSlopes));
+ memcpy ( l_pLocalPspbTemp->PsVIDCompSlopes,
+ iv_PsVIDCompSlopes,
+ sizeof(l_pLocalPspbTemp->PsVIDCompSlopes));
- memcpy ( i_localppb->PsVDMThreshSlopes,
- iv_PsVDMThreshSlopes,
- sizeof(i_localppb->PsVDMThreshSlopes));
+ memcpy ( l_pLocalPspbTemp->PsVDMThreshSlopes,
+ iv_PsVDMThreshSlopes,
+ sizeof(l_pLocalPspbTemp->PsVDMThreshSlopes));
- memcpy ( i_localppb->PsVDMJumpSlopes,
- iv_PsVDMJumpSlopes,
- sizeof(i_localppb->PsVDMJumpSlopes));
- }
+ memcpy ( l_pLocalPspbTemp->PsVDMJumpSlopes,
+ iv_PsVDMJumpSlopes,
+ sizeof(l_pLocalPspbTemp->PsVDMJumpSlopes));
+ }
+
+ }// for eq
}while(0);
+fapi_try_exit:
FAPI_INF("<<<<<<<< lppb_init");
return fapi2::current_err;
@@ -764,7 +779,7 @@ fapi2::ReturnCode PlatPmPPB::lppb_init(
///////////////////////////////////////////////////////////
-//////// gppb_init
+//////// gppb_init
///////////////////////////////////////////////////////////
fapi2::ReturnCode PlatPmPPB::gppb_init(
GlobalPstateParmBlock *io_globalppb)
@@ -878,9 +893,9 @@ fapi2::ReturnCode PlatPmPPB::gppb_init(
if (iv_attrs.attr_system_vdm_disable == fapi2::ENUM_ATTR_SYSTEM_VDM_DISABLE_OFF)
{
//Initializing threshold and jump values for GPPB
- memcpy ( io_globalppb->vid_point_set,
- iv_vid_point_set,
- sizeof(io_globalppb->vid_point_set));
+ for (uint8_t p = 0; p < NUM_OP_POINTS; p++) {
+ io_globalppb->vid_point_set[p] = iv_vid_point_set[0][p];
+ }
memcpy ( io_globalppb->threshold_set,
iv_threshold_set,
@@ -890,9 +905,9 @@ fapi2::ReturnCode PlatPmPPB::gppb_init(
iv_jump_value_set,
sizeof(io_globalppb->jump_value_set));
- memcpy ( io_globalppb->PsVIDCompSlopes,
- iv_PsVIDCompSlopes,
- sizeof(io_globalppb->PsVIDCompSlopes));
+ for (uint32_t r = 0; r < VPD_NUM_SLOPES_REGION; r++) {
+ io_globalppb->PsVIDCompSlopes[r] = iv_PsVIDCompSlopes[0][r];
+ }
memcpy ( io_globalppb->PsVDMThreshSlopes,
iv_PsVDMThreshSlopes,
@@ -937,6 +952,13 @@ fapi2::ReturnCode PlatPmPPB::gppb_init(
FAPI_INF("SafeVoltage=%u",revle32(io_globalppb->safe_voltage_mv));
}
+ //Avs Bus topplogy
+ io_globalppb->avs_bus_topology.vdd_avsbus_num = iv_attrs.vdd_bus_num;
+ io_globalppb->avs_bus_topology.vdd_avsbus_rail = iv_attrs.vdd_rail_select;
+ io_globalppb->avs_bus_topology.vdn_avsbus_num = iv_attrs.vdn_bus_num;
+ io_globalppb->avs_bus_topology.vdn_avsbus_rail = iv_attrs.vdn_rail_select;
+ io_globalppb->avs_bus_topology.vcs_avsbus_num = iv_attrs.vcs_bus_num;
+ io_globalppb->avs_bus_topology.vcs_avsbus_rail = iv_attrs.vcs_rail_select;
} while (0);
@@ -960,7 +982,7 @@ fapi2::ReturnCode PlatPmPPB::gppb_init(
// Inflection Point 0 is POWERSAVE
//
///////////////////////////////////////////////////////////
-//////// compute_PStateV_slope
+//////// compute_PStateV_slope
///////////////////////////////////////////////////////////
void PlatPmPPB::compute_PStateV_slope(
GlobalPstateParmBlock* o_gppb)
@@ -1018,7 +1040,7 @@ void PlatPmPPB::compute_PStateV_slope(
///////////////////////////////////////////////////////////
-//////// wof_init
+//////// wof_init
///////////////////////////////////////////////////////////
fapi2::ReturnCode PlatPmPPB::wof_init(
uint8_t* o_buf,
@@ -1220,7 +1242,7 @@ fapi_try_exit:
///////////////////////////////////////////////////////////
-//////// update_vfrt
+//////// update_vfrt
///////////////////////////////////////////////////////////
fapi2::ReturnCode PlatPmPPB::update_vfrt(
uint8_t* i_pBuffer,
@@ -1422,14 +1444,14 @@ fapi_try_exit:
///////////////////////////////////////////////////////////
-//////// safe_mode_init
+//////// safe_mode_init
///////////////////////////////////////////////////////////
fapi2::ReturnCode PlatPmPPB::safe_mode_init( void )
{
FAPI_INF(">>>>>>>>>> safe_mode_init");
uint8_t l_ps_pstate = 0;
Safe_mode_parameters l_safe_mode_values;
- uint32_t l_ps_freq_khz =
+ uint32_t l_ps_freq_khz =
iv_operating_points[VPD_PT_SET_BIASED][POWERSAVE].frequency_mhz * 1000;
do
@@ -1462,18 +1484,18 @@ fapi_try_exit:
///////////////////////////////////////////////////////////
//////// vdm_init
///////////////////////////////////////////////////////////
-void PlatPmPPB::vdm_init( void )
+fapi2::ReturnCode PlatPmPPB::vdm_init( void )
{
FAPI_INF(">>>>>>>> vdm_init");
do
{
uint8_t l_biased_pstate[NUM_OP_POINTS];
- memset(&iv_vid_point_set,0, sizeof(iv_vid_point_set));
- memset(iv_threshold_set,0,sizeof(iv_threshold_set));
- memset(&iv_PsVIDCompSlopes,0,sizeof(iv_PsVIDCompSlopes));
- memset(iv_PsVDMThreshSlopes,0,sizeof(iv_PsVDMThreshSlopes));
- memset(iv_jump_value_set,0,sizeof(iv_jump_value_set));
- memset(iv_PsVDMJumpSlopes,0,sizeof(iv_PsVDMJumpSlopes));
+ memset( &iv_vid_point_set[0], 0, sizeof(iv_vid_point_set) );
+ memset(iv_threshold_set, 0, sizeof(iv_threshold_set));
+ memset( &iv_PsVIDCompSlopes[0], 0, sizeof(iv_PsVIDCompSlopes) );
+ memset(iv_PsVDMThreshSlopes, 0, sizeof(iv_PsVDMThreshSlopes));
+ memset(iv_jump_value_set, 0, sizeof(iv_jump_value_set));
+ memset(iv_PsVDMJumpSlopes, 0, sizeof(iv_PsVDMJumpSlopes));
for (uint8_t i = 0; i < NUM_OP_POINTS; ++i)
{
@@ -1483,27 +1505,29 @@ void PlatPmPPB::vdm_init( void )
if (iv_attrs.attr_system_vdm_disable == fapi2::ENUM_ATTR_SYSTEM_VDM_DISABLE_OFF)
{
- compute_vdm_threshold_pts();
+ //loop thru the quad list
+ FAPI_TRY(compute_vdm_threshold_pts());
// VID slope calculation
- compute_PsVIDCompSlopes_slopes(l_biased_pstate);
+ FAPI_TRY(compute_PsVIDCompSlopes_slopes(l_biased_pstate));
// VDM threshold slope calculation
compute_PsVDMThreshSlopes(l_biased_pstate);
// VDM Jump slope calculation
compute_PsVDMJumpSlopes (l_biased_pstate);
-
}
}while(0);
FAPI_INF("<<<<<<<< vdm_init");
+fapi_try_exit:
+ return fapi2::current_err;
} //end of vdm_init
///////////////////////////////////////////////////////////
-//////// compute_PsVDMJumpSlopes
+//////// compute_PsVDMJumpSlopes
///////////////////////////////////////////////////////////
void PlatPmPPB::compute_PsVDMJumpSlopes(
uint8_t* i_pstate)
@@ -1528,10 +1552,10 @@ void PlatPmPPB::compute_PsVDMJumpSlopes(
{
iv_PsVDMJumpSlopes[region][i] =
revle16(
- compute_slope_thresh(iv_jump_value_set[region+1][i],
+ compute_slope_thresh(iv_jump_value_set[region + 1][i],
iv_jump_value_set[region][i],
i_pstate[region],
- i_pstate[region+1])
+ i_pstate[region + 1])
);
FAPI_INF("PsVDMJumpSlopes %s %x N_S %d N_L %d L_S %d S_N %d",
@@ -1549,7 +1573,7 @@ void PlatPmPPB::compute_PsVDMJumpSlopes(
///////////////////////////////////////////////////////////
-//////// compute_PsVDMThreshSlopes
+//////// compute_PsVDMThreshSlopes
///////////////////////////////////////////////////////////
void PlatPmPPB::compute_PsVDMThreshSlopes(
uint8_t* i_pstate)
@@ -1572,7 +1596,7 @@ void PlatPmPPB::compute_PsVDMThreshSlopes(
{
iv_PsVDMThreshSlopes[region][i] =
revle16(
- compute_slope_thresh(iv_threshold_set[region+1][i],
+ compute_slope_thresh(iv_threshold_set[region + 1][i],
iv_threshold_set[region][i],
i_pstate[region],
i_pstate[region+1])
@@ -1593,9 +1617,9 @@ void PlatPmPPB::compute_PsVDMThreshSlopes(
///////////////////////////////////////////////////////////
-//////// compute_PsVIDCompSlopes_slopes
+//////// compute_PsVIDCompSlopes_slopes
///////////////////////////////////////////////////////////
-void PlatPmPPB::compute_PsVIDCompSlopes_slopes(
+fapi2::ReturnCode PlatPmPPB::compute_PsVIDCompSlopes_slopes(
uint8_t* i_pstate)
{
do
@@ -1604,6 +1628,8 @@ void PlatPmPPB::compute_PsVIDCompSlopes_slopes(
"REGION_NOMINAL_TURBO",
"REGION_TURBO_ULTRA"
};
+ uint8_t l_eqPos = 0;
+ auto l_eqChiplets = iv_procChip.getChildren<fapi2::TARGET_TYPE_EQ>(fapi2::TARGET_STATE_FUNCTIONAL);
// ULTRA TURBO pstate check is not required..because its pstate will be
// 0
@@ -1615,37 +1641,53 @@ void PlatPmPPB::compute_PsVIDCompSlopes_slopes(
break;
}
- for(auto region(REGION_POWERSAVE_NOMINAL); region <= REGION_TURBO_ULTRA; ++region)
+ for( auto eq : l_eqChiplets )
{
- iv_PsVIDCompSlopes[region] =
- revle16(
- compute_slope_4_12( iv_vid_point_set[region + 1],
- iv_vid_point_set[region],
- i_pstate[region],
- i_pstate[region + 1])
- );
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, eq, l_eqPos ));
+
+ for(auto region(REGION_POWERSAVE_NOMINAL); region <= REGION_TURBO_ULTRA; ++region)
+ {
+ iv_PsVIDCompSlopes[l_eqPos][region] =
+ revle16(
+ compute_slope_4_12( iv_vid_point_set[l_eqPos][region + 1],
+ iv_vid_point_set[l_eqPos][region],
+ i_pstate[region],
+ i_pstate[region + 1])
+ );
- FAPI_DBG("PsVIDCompSlopes[%s] 0x%04x %d", region_names[region],
- revle16(iv_PsVIDCompSlopes[region]),
- revle16(iv_PsVIDCompSlopes[region]));
+ FAPI_DBG( "PsVIDCompSlopes[%s] 0x%04x %d", region_names[region],
+ revle16(iv_PsVIDCompSlopes[l_eqPos][region]),
+ revle16(iv_PsVIDCompSlopes[l_eqPos][region]) );
+ }
}
}
while(0);
-} // end of compute_PsVIDCompSlopes_slopes
+
+fapi_try_exit:
+return fapi2::current_err;
+
+} // end of compute_PsVIDCompSlopes_slopes
///////////////////////////////////////////////////////////
//////// compute_vdm_threshold_pts
///////////////////////////////////////////////////////////
-void PlatPmPPB::compute_vdm_threshold_pts()
+fapi2::ReturnCode PlatPmPPB::compute_vdm_threshold_pts()
{
int p = 0;
+ uint8_t l_eqPos = 0;
+ auto l_eqChiplets = iv_procChip.getChildren<fapi2::TARGET_TYPE_EQ>(fapi2::TARGET_STATE_FUNCTIONAL);
- //VID POINTS
- for (p = 0; p < NUM_OP_POINTS; p++)
+ for( auto eq : l_eqChiplets )
{
- iv_vid_point_set[p] = iv_poundW_data.poundw[p].vdm_vid_compare_ivid;
- FAPI_INF("Bi:VID=%x", iv_vid_point_set[p]);
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, eq, l_eqPos ));
+
+ //VID POINTS
+ for (p = 0; p < NUM_OP_POINTS; p++)
+ {
+ iv_vid_point_set[l_eqPos][p] = iv_poundW_data.poundw[p].vdm_vid_compare_per_quad[l_eqPos];
+ FAPI_INF("Bi:VID=%x", iv_vid_point_set[l_eqPos][p]);
+ }
}
// Threshold points
@@ -1689,10 +1731,13 @@ void PlatPmPPB::compute_vdm_threshold_pts()
FAPI_INF("Bi: S_L =%d", iv_jump_value_set[p][3]);
}
+
+fapi_try_exit:
+return fapi2::current_err;
} //end of compute_vdm_threshold_pts
///////////////////////////////////////////////////////////
-//////// ps2v_mv
+//////// ps2v_mv
///////////////////////////////////////////////////////////
uint32_t PlatPmPPB::ps2v_mv(const Pstate i_pstate)
{
@@ -1817,11 +1862,11 @@ fapi2::ReturnCode PlatPmPPB::safe_mode_computation(
"Core floor freqency is greater than UltraTurbo frequency");
}
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_FREQUENCY_MHZ,
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_FREQUENCY_MHZ,
iv_procChip, l_safe_mode_freq_mhz));
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_VOLTAGE_MV,
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_VOLTAGE_MV,
iv_procChip, l_safe_mode_mv));
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_VDD_BOOT_VOLTAGE,
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_VDD_BOOT_VOLTAGE,
iv_procChip, l_boot_mv));
FAPI_DBG ("l_safe_mode_freq_mhz 0%08x (%d)",
@@ -1866,7 +1911,7 @@ fapi2::ReturnCode PlatPmPPB::safe_mode_computation(
(float)(l_safe_mode_values.safe_op_freq_mhz * 1000)) /
(float)iv_frequency_step_khz;
- l_safe_mode_op_ps2freq_mhz = (iv_reference_frequency_khz -
+ l_safe_mode_op_ps2freq_mhz = (iv_reference_frequency_khz -
(l_safe_mode_values.safe_op_ps * iv_frequency_step_khz)) / 1000;
while (l_safe_mode_op_ps2freq_mhz < l_safe_mode_values.safe_op_freq_mhz)
@@ -1980,7 +2025,7 @@ fapi_try_exit:
///////////////////////////////////////////////////////////
-//////// attr_init
+//////// attr_init
///////////////////////////////////////////////////////////
void PlatPmPPB::attr_init( void )
{
@@ -2043,7 +2088,7 @@ FAPI_INF("%-60s = 0x%08x %d", #attr_name, iv_attrs.attr_assign, iv_attrs.attr_as
DATABLOCK_GET_ATTR(ATTR_VOLTAGE_INT_VDD_BIAS_POWERSAVE, iv_procChip, attr_voltage_int_vdd_bias_powersave);
// Frequency attributes
- DATABLOCK_GET_ATTR(ATTR_FREQ_PROC_REFCLOCK_KHZ, FAPI_SYSTEM, attr_freq_proc_refclock_khz);
+ DATABLOCK_GET_ATTR(ATTR_FREQ_DPLL_REFCLOCK_KHZ, FAPI_SYSTEM, attr_freq_dpll_refclock_khz);
DATABLOCK_GET_ATTR(ATTR_FREQ_PB_MHZ, FAPI_SYSTEM, attr_nest_frequency_mhz);
DATABLOCK_GET_ATTR(ATTR_FREQ_CORE_CEILING_MHZ, FAPI_SYSTEM, attr_freq_core_ceiling_mhz);
DATABLOCK_GET_ATTR(ATTR_SAFE_MODE_FREQUENCY_MHZ,iv_procChip, attr_pm_safe_frequency_mhz);
@@ -2074,13 +2119,13 @@ FAPI_INF("%-60s = 0x%08x %d", #attr_name, iv_attrs.attr_assign, iv_attrs.attr_as
DATABLOCK_GET_ATTR(ATTR_TDP_RDP_CURRENT_FACTOR, iv_procChip, attr_tdp_rdp_current_factor);
- DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_START_NS,
+ DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_START_NS,
FAPI_SYSTEM, attr_ext_vrm_transition_start_ns);
- DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_RATE_INC_UV_PER_US,
+ DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_RATE_INC_UV_PER_US,
FAPI_SYSTEM, attr_ext_vrm_transition_rate_inc_uv_per_us);
- DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_RATE_DEC_UV_PER_US,
+ DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_RATE_DEC_UV_PER_US,
FAPI_SYSTEM, attr_ext_vrm_transition_rate_dec_uv_per_us);
- DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_STABILIZATION_TIME_NS,
+ DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_STABILIZATION_TIME_NS,
FAPI_SYSTEM, attr_ext_vrm_stabilization_time_us);
DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_STEPSIZE, FAPI_SYSTEM, attr_ext_vrm_step_size_mv);
DATABLOCK_GET_ATTR(ATTR_NEST_LEAKAGE_PERCENT, FAPI_SYSTEM, attr_nest_leakage_percent);
@@ -2105,12 +2150,12 @@ FAPI_INF("%-60s = 0x%08x %d", #attr_name, iv_attrs.attr_assign, iv_attrs.attr_as
DATABLOCK_GET_ATTR(ATTR_PROC_R_LOADLINE_VCS_UOHM, iv_procChip, r_loadline_vcs_uohm);
DATABLOCK_GET_ATTR(ATTR_PROC_R_DISTLOSS_VCS_UOHM, iv_procChip, r_distloss_vcs_uohm);
DATABLOCK_GET_ATTR(ATTR_PROC_VRM_VOFFSET_VCS_UV, iv_procChip, vrm_voffset_vcs_uv);
- DATABLOCK_GET_ATTR(ATTR_FREQ_PROC_REFCLOCK_KHZ, FAPI_SYSTEM, freq_proc_refclock_khz);
+ DATABLOCK_GET_ATTR(ATTR_FREQ_DPLL_REFCLOCK_KHZ, FAPI_SYSTEM, freq_proc_refclock_khz);
DATABLOCK_GET_ATTR(ATTR_PROC_DPLL_DIVIDER, iv_procChip, proc_dpll_divider);
// AVSBus ... needed by p9_setup_evid
//Get WOV attributes
- DATABLOCK_GET_ATTR(ATTR_SYSTEM_WOV_OVERV_DISABLE, FAPI_SYSTEM,attr_wov_overv_enable);
- DATABLOCK_GET_ATTR(ATTR_SYSTEM_WOV_UNDERV_DISABLE, FAPI_SYSTEM,attr_wov_underv_enable);
+ DATABLOCK_GET_ATTR(ATTR_SYSTEM_WOV_OVERV_DISABLE, FAPI_SYSTEM,attr_wov_overv_disable);
+ DATABLOCK_GET_ATTR(ATTR_SYSTEM_WOV_UNDERV_DISABLE, FAPI_SYSTEM,attr_wov_underv_disable);
DATABLOCK_GET_ATTR(ATTR_WOV_UNDERV_FORCE, iv_procChip,attr_wov_underv_force);
DATABLOCK_GET_ATTR(ATTR_WOV_SAMPLE_125US, iv_procChip,attr_wov_sample_125us);
DATABLOCK_GET_ATTR(ATTR_WOV_MAX_DROOP_10THPCT, iv_procChip,attr_wov_max_droop_pct);
@@ -2135,7 +2180,7 @@ FAPI_INF("%-60s = 0x%08x %d", #attr_name, iv_attrs.attr_assign, iv_attrs.attr_as
#_attr_name, iv_attrs._attr_name, iv_attrs._attr_name); \
}
- SET_DEFAULT(attr_freq_proc_refclock_khz, 133333);
+ SET_DEFAULT(attr_freq_dpll_refclock_khz, 133333);
SET_DEFAULT(freq_proc_refclock_khz, 133333); // Future: collapse this out
SET_DEFAULT(attr_ext_vrm_transition_start_ns, EXT_VRM_TRANSITION_START_NS)
SET_DEFAULT(attr_ext_vrm_transition_rate_inc_uv_per_us, EXT_VRM_TRANSITION_RATE_INC_UV_PER_US)
@@ -2268,7 +2313,7 @@ FAPI_INF("%-60s = 0x%08x %d", #attr_name, iv_attrs.attr_assign, iv_attrs.attr_as
iv_wov_overv_enabled = true;
//Calculate nest & frequency_step_khz
- iv_frequency_step_khz = (iv_attrs.attr_freq_proc_refclock_khz /
+ iv_frequency_step_khz = (iv_attrs.attr_freq_dpll_refclock_khz /
iv_attrs.attr_proc_dpll_divider);
iv_nest_freq_mhz = iv_attrs.attr_nest_frequency_mhz;
@@ -2362,9 +2407,9 @@ void PlatPmPPB::compute_vpd_pts()
//BIASED POINTS
for (p = 0; p < NUM_OP_POINTS; p++)
{
- uint32_t l_frequency_mhz = (iv_biased_vpd_pts[p].frequency_mhz);
- uint32_t l_vdd_mv = (iv_biased_vpd_pts[p].vdd_mv);
- uint32_t l_vcs_mv = (iv_biased_vpd_pts[p].vcs_mv);
+ uint32_t l_frequency_mhz = (iv_raw_vpd_pts[p].frequency_mhz);
+ uint32_t l_vdd_mv = (iv_raw_vpd_pts[p].vdd_mv);
+ uint32_t l_vcs_mv = (iv_raw_vpd_pts[p].vcs_mv);
iv_operating_points[VPD_PT_SET_BIASED][p].vdd_mv =
bias_adjust_mv(l_vdd_mv, iv_bias[p].vdd_ext_hp);
@@ -2457,7 +2502,7 @@ void PlatPmPPB::compute_vpd_pts()
///////////////////////////////////////////////////////////
-//////// resclk_init
+//////// resclk_init
///////////////////////////////////////////////////////////
fapi2::ReturnCode PlatPmPPB::resclk_init( void )
{
@@ -2485,7 +2530,7 @@ fapi_try_exit:
///////////////////////////////////////////////////////////
-//////// res_clock_setup
+//////// res_clock_setup
///////////////////////////////////////////////////////////
fapi2::ReturnCode PlatPmPPB::res_clock_setup (void)
{
@@ -2696,7 +2741,7 @@ fapi_try_exit:
///////////////////////////////////////////////////////////
-//////// get_ivrm_parms
+//////// get_ivrm_parms
///////////////////////////////////////////////////////////
fapi2::ReturnCode PlatPmPPB::get_ivrm_parms ()
{
@@ -2752,7 +2797,7 @@ fapi_try_exit:
///////////////////////////////////////////////////////////
-//////// chk_valid_poundv
+//////// chk_valid_poundv
///////////////////////////////////////////////////////////
fapi2::ReturnCode PlatPmPPB::chk_valid_poundv(
const bool i_biased_state)
@@ -2805,7 +2850,7 @@ fapi2::ReturnCode PlatPmPPB::chk_valid_poundv(
(l_attr_mvpd_data[pv_op_order[i]].vcs_mv),
(l_attr_mvpd_data[pv_op_order[i]].ics_100ma));
- if (is_wof_enabled() &&
+ if (is_wof_enabled() &&
(strcmp(pv_op_str[pv_op_order[i]], "UltraTurbo") == 0))
{
if (l_attr_mvpd_data[pv_op_order[i]].frequency_mhz == 0 ||
@@ -2979,25 +3024,25 @@ fapi2::ReturnCode PlatPmPPB::chk_valid_poundv(
// Only skip checkinug for WOF not enabled and UltraTurbo.
if ( is_wof_enabled() ||
- (!( !is_wof_enabled() &&
+ (!( !is_wof_enabled() &&
(strcmp(pv_op_str[pv_op_order[i]], "UltraTurbo") == 0))))
{
- if (l_attr_mvpd_data[pv_op_order[i - 1]].frequency_mhz >
+ if (l_attr_mvpd_data[pv_op_order[i - 1]].frequency_mhz >
l_attr_mvpd_data[pv_op_order[i]].frequency_mhz ||
- l_attr_mvpd_data[pv_op_order[i - 1]].vdd_mv >
+ l_attr_mvpd_data[pv_op_order[i - 1]].vdd_mv >
l_attr_mvpd_data[pv_op_order[i]].vdd_mv ||
- l_attr_mvpd_data[pv_op_order[i - 1]].idd_100ma >
+ l_attr_mvpd_data[pv_op_order[i - 1]].idd_100ma >
l_attr_mvpd_data[pv_op_order[i]].idd_100ma ||
- l_attr_mvpd_data[pv_op_order[i - 1]].vcs_mv >
+ l_attr_mvpd_data[pv_op_order[i - 1]].vcs_mv >
l_attr_mvpd_data[pv_op_order[i]].vcs_mv ||
- l_attr_mvpd_data[pv_op_order[i - 1]].ics_100ma >
+ l_attr_mvpd_data[pv_op_order[i - 1]].ics_100ma >
l_attr_mvpd_data[pv_op_order[i]].ics_100ma )
{
iv_pstates_enabled = false;
if (attr_poundv_validity_halt_disable)
{
- FAPI_IMP("**** WARNING : halt on #V validity checking has been "
+ FAPI_IMP("**** WARNING : halt on #V validity checking has been "
"disabled and relationship errors were found");
FAPI_IMP("**** WARNING : Relationship error between #V operating point "
"(%s > %s)(power save <= nominal <= turbo <= ultraturbo) (chiplet = %u bucket id = %u op point = %u)",
@@ -3014,7 +3059,7 @@ fapi2::ReturnCode PlatPmPPB::chk_valid_poundv(
FAPI_INF("%s Frequency value %u is %s %s Frequency value %u",
pv_op_str[pv_op_order[i - 1]], l_attr_mvpd_data[pv_op_order[i - 1]].frequency_mhz,
- POUNDV_SLOPE_CHECK(l_attr_mvpd_data[pv_op_order[i - 1]].frequency_mhz,
+ POUNDV_SLOPE_CHECK(l_attr_mvpd_data[pv_op_order[i - 1]].frequency_mhz,
l_attr_mvpd_data[pv_op_order[i]].frequency_mhz),pv_op_str[pv_op_order[i]], l_attr_mvpd_data[pv_op_order[i]].frequency_mhz);
FAPI_INF("%s VDD voltage value %u is %s %s Frequency value %u",
@@ -3143,7 +3188,7 @@ fapi_try_exit:
///////////////////////////////////////////////////////////
-//////// get_mvpd_poundV
+//////// get_mvpd_poundV
///////////////////////////////////////////////////////////
fapi2::ReturnCode PlatPmPPB::get_mvpd_poundV()
{
@@ -3153,7 +3198,7 @@ fapi2::ReturnCode PlatPmPPB::get_mvpd_poundV()
uint8_t j = 0;
uint8_t first_chplt = 1;
uint8_t bucket_id = 0;
- uint8_t* l_buffer =
+ uint8_t* l_buffer =
reinterpret_cast<uint8_t*>(malloc(sizeof(voltageBucketData_t)) );
uint8_t* l_buffer_inc = NULL;
@@ -3421,11 +3466,11 @@ fapi_try_exit:
FAPI_INF("<<<<<<<<<<<< apply_biased_values");
return fapi2::current_err;
-} // end of apply_biased_values
+} // end of apply_biased_values
///////////////////////////////////////////////////////////
-//////// large_jump_defaults
+//////// large_jump_defaults
///////////////////////////////////////////////////////////
void PlatPmPPB::large_jump_defaults()
{
@@ -3452,7 +3497,7 @@ void PlatPmPPB::large_jump_defaults()
///////////////////////////////////////////////////////////
-//////// get_mvpd_poundW
+//////// get_mvpd_poundW
///////////////////////////////////////////////////////////
fapi2::ReturnCode PlatPmPPB::get_mvpd_poundW (void)
{
@@ -3461,11 +3506,6 @@ fapi2::ReturnCode PlatPmPPB::get_mvpd_poundW (void)
uint8_t selected_eq = 0;
uint8_t bucket_id = 0;
uint8_t version_id = 0;
- const uint16_t VDM_VOLTAGE_IN_MV = 512;
- const uint16_t MIN_VDM_VOLTAGE_IN_MV = 576;
- const uint16_t VDM_GRANULARITY = 4;
- uint32_t l_vdm_compare_raw_mv[NUM_OP_POINTS];
- uint32_t l_vdm_compare_biased_mv[NUM_OP_POINTS];
const char* pv_op_str[NUM_OP_POINTS] = PV_OP_ORDER_STR;
@@ -3512,10 +3552,41 @@ fapi2::ReturnCode PlatPmPPB::get_mvpd_poundW (void)
FAPI_TRY(p9_pm_get_poundw_bucket(l_eqChiplets[selected_eq], l_vdmBuf));
- bucket_id = l_vdmBuf.bucketId;
- version_id = l_vdmBuf.version;
+ bucket_id = l_vdmBuf.bucketId;
+ version_id = l_vdmBuf.version;
- FAPI_INF("#W chiplet = %u bucket id = %u", l_chipletNum, bucket_id, version_id);
+ FAPI_INF( "#W chiplet = %u bucket id = %u", l_chipletNum, bucket_id );
+
+ if( version_id < POUNDW_VERSION_30 )
+ {
+ PoundW_data_per_quad l_poundwPerQuad;
+ PoundW_data l_poundw;
+ memcpy( &l_poundw, l_vdmBuf.vdmData, sizeof( PoundW_data ) );
+ memset( &l_poundwPerQuad, 0, sizeof(PoundW_data_per_quad) );
+
+ for( size_t op = 0; op <= ULTRA; op++ )
+ {
+ //structure mapping
+ l_poundwPerQuad.poundw[op].ivdd_tdp_ac_current_10ma = l_poundw.poundw[op].ivdd_tdp_ac_current_10ma;
+
+ l_poundwPerQuad.poundw[op].ivdd_tdp_dc_current_10ma = l_poundw.poundw[op].ivdd_tdp_dc_current_10ma;
+ l_poundwPerQuad.poundw[op].vdm_overvolt_small_thresholds = l_poundw.poundw[op].vdm_overvolt_small_thresholds;
+ l_poundwPerQuad.poundw[op].vdm_large_extreme_thresholds = l_poundw.poundw[op].vdm_large_extreme_thresholds;
+ l_poundwPerQuad.poundw[op].vdm_normal_freq_drop = l_poundw.poundw[op].vdm_normal_freq_drop;
+ l_poundwPerQuad.poundw[op].vdm_normal_freq_return = l_poundw.poundw[op].vdm_normal_freq_return;
+ l_poundwPerQuad.poundw[op].vdm_vid_compare_per_quad[0] = l_poundw.poundw[op].vdm_vid_compare_ivid;
+ l_poundwPerQuad.poundw[op].vdm_vid_compare_per_quad[1] = l_poundw.poundw[op].vdm_vid_compare_ivid;
+ l_poundwPerQuad.poundw[op].vdm_vid_compare_per_quad[2] = l_poundw.poundw[op].vdm_vid_compare_ivid;
+ l_poundwPerQuad.poundw[op].vdm_vid_compare_per_quad[3] = l_poundw.poundw[op].vdm_vid_compare_ivid;
+ l_poundwPerQuad.poundw[op].vdm_vid_compare_per_quad[4] = l_poundw.poundw[op].vdm_vid_compare_ivid;
+ l_poundwPerQuad.poundw[op].vdm_vid_compare_per_quad[5] = l_poundw.poundw[op].vdm_vid_compare_ivid;
+ }
+
+ memcpy( &l_poundwPerQuad.resistance_data, &l_poundw.resistance_data , LEGACY_RESISTANCE_ENTRY_SIZE );
+ l_poundwPerQuad.resistance_data.r_undervolt_allowed = l_poundw.undervolt_tested;
+ memset(&l_vdmBuf.vdmData, 0, sizeof(l_vdmBuf));
+ memcpy(&l_vdmBuf.vdmData, &l_poundwPerQuad, sizeof( PoundW_data_per_quad ) );
+ }
//if we match with the bucket id, then we don't need to continue
if (iv_poundV_bucket_id == bucket_id)
@@ -3548,18 +3619,19 @@ fapi2::ReturnCode PlatPmPPB::get_mvpd_poundW (void)
// When we read the data from VPD image the order will be N,PS,T,UT.
// But we need the order PS,N,T,UT.. hence we are swapping the data
// between PS and Nominal.
- poundw_entry_t l_tmp_data;
+ poundw_entry_per_quad_t l_tmp_data;
+ memset( &l_tmp_data ,0, sizeof(poundw_entry_per_quad_t));
memcpy (&l_tmp_data,
&(iv_poundW_data.poundw[VPD_PV_NOMINAL]),
- sizeof (poundw_entry_t));
+ sizeof (poundw_entry_per_quad_t));
memcpy (&(iv_poundW_data.poundw[VPD_PV_NOMINAL]),
&(iv_poundW_data.poundw[VPD_PV_POWERSAVE]),
- sizeof(poundw_entry_t));
+ sizeof(poundw_entry_per_quad_t));
memcpy (&(iv_poundW_data.poundw[VPD_PV_POWERSAVE]),
&l_tmp_data,
- sizeof(poundw_entry_t));
+ sizeof(poundw_entry_per_quad_t));
// If the #W version is less than 3, validate Turbo VDM large threshold
// not larger than -32mV. This filters out parts that have bad VPD. If
@@ -3661,83 +3733,16 @@ fapi2::ReturnCode PlatPmPPB::get_mvpd_poundW (void)
// within #W. If VDMs are not enabled (or supported), skip all of it
if (!is_vdm_enabled())
{
- FAPI_INF(" get_mvpd_poundW: VDM is disabled. Skipping remaining checks");
- iv_vdm_enabled = false;
- break;
- }
-
- for (int i = 0; i < NUM_OP_POINTS; ++i)
- {
- l_vdm_compare_raw_mv[i] = VDM_VOLTAGE_IN_MV + (iv_poundW_data.poundw[i].vdm_vid_compare_ivid << 2);
- FAPI_INF("%10s vdm_vid_compare_ivid %3d => %d mv",
- pv_op_str[i],
- iv_poundW_data.poundw[i].vdm_vid_compare_ivid,
- l_vdm_compare_raw_mv[i]);
- }
-
- //Validation of VPD Data
- //If all VID compares are zero then use #V VDD voltage to populate local
- //data structure..So that we make progress in lab with early hardware
- if ( !(iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_ivid) &&
- !(iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_ivid) &&
- !(iv_poundW_data.poundw[TURBO].vdm_vid_compare_ivid) &&
- !(iv_poundW_data.poundw[ULTRA].vdm_vid_compare_ivid))
- {
- //vdm_vid_compare_ivid will be in ivid units (eg HEX((Compare
- //Voltage (mv) - 512mV)/4mV).
- iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_ivid =
- (iv_poundV_raw_data.VddNomVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY;
- iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_ivid =
- (iv_poundV_raw_data.VddPSVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY;
- iv_poundW_data.poundw[TURBO].vdm_vid_compare_ivid =
- (iv_poundV_raw_data.VddTurboVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY;
- iv_poundW_data.poundw[ULTRA].vdm_vid_compare_ivid =
- (iv_poundV_raw_data.VddUTurboVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY;
- }//if any one of the VID compares are zero, then need to fail because of BAD VPD image.
- else if ( !(iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_ivid) ||
- !(iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_ivid) ||
- !(iv_poundW_data.poundw[TURBO].vdm_vid_compare_ivid) ||
- !(iv_poundW_data.poundw[ULTRA].vdm_vid_compare_ivid))
- {
- iv_vdm_enabled = false;
- FAPI_ASSERT_NOEXIT(false,
- fapi2::PSTATE_PB_POUND_W_INVALID_VID_VALUE(fapi2::FAPI2_ERRL_SEV_RECOVERED)
- .set_CHIP_TARGET(iv_procChip)
- .set_EQ_TARGET(l_eqChiplets[selected_eq])
- .set_NOMINAL_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_ivid)
- .set_POWERSAVE_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_ivid)
- .set_TURBO_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[TURBO].vdm_vid_compare_ivid)
- .set_ULTRA_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[ULTRA].vdm_vid_compare_ivid),
- "Pstate Parameter Block #W : one of the VID compare value is zero");
- break;
- }
-
- // validate vid values
- bool l_compare_vid_value_state = 1;
- VALIDATE_VID_VALUES (iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_ivid,
- iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_ivid,
- iv_poundW_data.poundw[TURBO].vdm_vid_compare_ivid,
- iv_poundW_data.poundw[ULTRA].vdm_vid_compare_ivid,
- l_compare_vid_value_state);
-
- if (!l_compare_vid_value_state)
- {
+ FAPI_INF( "get_mvpd_poundW: VDM is disabled. Skipping remaining checks" );
iv_vdm_enabled = false;
- FAPI_ASSERT_NOEXIT(false,
- fapi2::PSTATE_PB_POUND_W_INVALID_VID_ORDER(fapi2::FAPI2_ERRL_SEV_RECOVERED)
- .set_CHIP_TARGET(iv_procChip)
- .set_EQ_TARGET(l_eqChiplets[selected_eq])
- .set_NOMINAL_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_ivid)
- .set_POWERSAVE_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_ivid)
- .set_TURBO_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[TURBO].vdm_vid_compare_ivid)
- .set_ULTRA_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[ULTRA].vdm_vid_compare_ivid),
- "Pstate Parameter Block #W VID compare data are not in increasing order");
break;
}
// validate threshold values
bool l_threshold_value_state = 1;
+ validate_quad_spec_data( );
+
for (uint8_t p = 0; p < NUM_OP_POINTS; ++p)
{
FAPI_INF("iv_poundW_data.poundw[%d].vdm_overvolt_thresholds 0x%X",
@@ -3749,9 +3754,9 @@ fapi2::ReturnCode PlatPmPPB::get_mvpd_poundW (void)
FAPI_INF("iv_poundW_data.poundw[%d].vdm_extreme_thresholds 0x%X",
p,(iv_poundW_data.poundw[p].vdm_large_extreme_thresholds) & 0x0F);
VALIDATE_THRESHOLD_VALUES(((iv_poundW_data.poundw[p].vdm_overvolt_small_thresholds >> 4) & 0x0F), // overvolt
- ((iv_poundW_data.poundw[p].vdm_overvolt_small_thresholds) & 0x0F), //small
- ((iv_poundW_data.poundw[p].vdm_large_extreme_thresholds >> 4) & 0x0F), //large
- ((iv_poundW_data.poundw[p].vdm_large_extreme_thresholds) & 0x0F), //extreme
+ ((iv_poundW_data.poundw[p].vdm_overvolt_small_thresholds) & 0x0F), // small
+ ((iv_poundW_data.poundw[p].vdm_large_extreme_thresholds >> 4) & 0x0F), // large
+ ((iv_poundW_data.poundw[p].vdm_large_extreme_thresholds) & 0x0F), // extreme
l_threshold_value_state);
if (!l_threshold_value_state)
@@ -3777,7 +3782,7 @@ fapi2::ReturnCode PlatPmPPB::get_mvpd_poundW (void)
{
// These fields are 4 bits wide, and stored in a uint8, hence the shifting
// N_S, N_L, L_S, S_N
- FAPI_INF("iv_poundW_data.poundw[%d] VDM_FREQ_DROP N_S = %d",
+ FAPI_INF("iv_poundW_data.poundw[%d] VDM_FREQ_DROP N_S = %d",
p, ((iv_poundW_data.poundw[p].vdm_normal_freq_drop >> 4) & 0x0F));
FAPI_INF("iv_poundW_data.poundw[%d] VDM_FREQ_DROP N_L = %d",
p, ((iv_poundW_data.poundw[p].vdm_normal_freq_drop) & 0x0F));
@@ -3809,44 +3814,16 @@ fapi2::ReturnCode PlatPmPPB::get_mvpd_poundW (void)
}
}
- //Biased compare vid data
- fapi2::ATTR_VDM_VID_COMPARE_BIAS_0P5PCT_Type l_bias_value;
-
-
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_VDM_VID_COMPARE_BIAS_0P5PCT,
- iv_procChip,
- l_bias_value),
- "Error from FAPI_ATTR_GET for attribute ATTR_VDM_VID_COMPARE_BIAS_0P5PCT");
-
- float l_pound_w_points[NUM_OP_POINTS];
-
- for (uint8_t i = 0; i < NUM_OP_POINTS; i++)
- {
- l_pound_w_points[i] = calc_bias(l_bias_value[i]);
- l_vdm_compare_biased_mv[i] = internal_ceil( (l_vdm_compare_raw_mv[i] * l_pound_w_points[i]));
-
- if (l_vdm_compare_biased_mv[i] < MIN_VDM_VOLTAGE_IN_MV)
- {
- l_vdm_compare_biased_mv[i] = MIN_VDM_VOLTAGE_IN_MV;
- }
-
- iv_poundW_data.poundw[i].vdm_vid_compare_ivid =
- (l_vdm_compare_biased_mv[i] - VDM_VOLTAGE_IN_MV) >> 2;
-
- FAPI_INF("vdm_vid_compare_ivid %x %x, %x",
- iv_poundW_data.poundw[i].vdm_vid_compare_ivid,
- iv_poundW_data.poundw[i].vdm_vid_compare_ivid,
- l_pound_w_points[i]);
- }
//If we have reached this point, that means VDM is ok to be enabled. Only then we try to
//enable wov undervolting
- if ( ((iv_poundW_data.undervolt_tested == 1) || (iv_attrs.attr_wov_underv_force == 1)) &&
- is_wov_underv_enabled() == 1) {
+ if ( ((iv_poundW_data.resistance_data.r_undervolt_allowed == 1) || (iv_attrs.attr_wov_underv_force == 1)) &&
+ is_wov_underv_enabled() == 1 )
+ {
iv_wov_underv_enabled = true;
- FAPI_INF("UNDERV_TESTED or UNDERV_FORCE set to 1");
- } else{
+ FAPI_DBG("UNDERV_TESTED or UNDERV_FORCE set to 1");
+ } else {
iv_wov_underv_enabled = false;
- FAPI_INF("UNDERV_TESTED and UNDERV_FORCE set to 0");
+ FAPI_DBG("UNDERV_TESTED and UNDERV_FORCE set to 0");
}
@@ -3879,10 +3856,129 @@ fapi_try_exit:
} // end of get_mvpd_poundW
+fapi2::ReturnCode PlatPmPPB::validate_quad_spec_data( )
+{
+ auto l_eqChiplets = iv_procChip.getChildren<fapi2::TARGET_TYPE_EQ>(fapi2::TARGET_STATE_FUNCTIONAL);
+ uint8_t eqNum = 0;
+ const uint16_t VDM_VOLTAGE_IN_MV = 512;
+ const uint16_t VDM_GRANULARITY = 4;
+ const uint16_t MIN_VDM_VOLTAGE_IN_MV = 576;
+ const char* pv_op_str[NUM_OP_POINTS] = VPD_PV_ORDER_STR;
+ uint32_t l_vdm_compare_raw_mv[NUM_OP_POINTS];
+ uint32_t l_vdm_compare_biased_mv[NUM_OP_POINTS];
+
+ for( auto eq : l_eqChiplets )
+ {
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, eq, eqNum ));
+
+ for (int i = 0; i < NUM_OP_POINTS; ++i)
+ {
+ l_vdm_compare_raw_mv[i] = VDM_VOLTAGE_IN_MV + (iv_poundW_data.poundw[i].vdm_vid_compare_per_quad[eqNum] << 2);
+
+ FAPI_INF( "%10s Op Point [%d] vdm_vid_compare_per_quad[%d] %3d => %d mv",
+ pv_op_str[i], i, eqNum, iv_poundW_data.poundw[i].vdm_vid_compare_per_quad[eqNum],
+ l_vdm_compare_raw_mv[i] );
+ }
+
+ //Validation of VPD Data
+ //If all VID compares are zero then use #V VDD voltage to populate local
+ //data structure..So that we make progress in lab with early hardware
+ if ( !(iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_per_quad[eqNum]) &&
+ !(iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_per_quad[eqNum]) &&
+ !(iv_poundW_data.poundw[TURBO].vdm_vid_compare_per_quad[eqNum]) &&
+ !(iv_poundW_data.poundw[ULTRA].vdm_vid_compare_per_quad[eqNum]))
+ {
+ //vdm_vid_compare_per_quad[eqNum] will be in ivid units (eg HEX((Compare
+ //Voltage (mv) - 512mV)/4mV).
+ iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_per_quad[eqNum] =
+ (iv_poundV_raw_data.VddNomVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY;
+ iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_per_quad[eqNum] =
+ (iv_poundV_raw_data.VddPSVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY;
+ iv_poundW_data.poundw[TURBO].vdm_vid_compare_per_quad[eqNum] =
+ (iv_poundV_raw_data.VddTurboVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY;
+ iv_poundW_data.poundw[ULTRA].vdm_vid_compare_per_quad[eqNum] =
+ (iv_poundV_raw_data.VddUTurboVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY;
+ }//if any one of the VID compares are zero, then need to fail because of BAD VPD image.
+ else if ( !(iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_per_quad[eqNum]) ||
+ !(iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_per_quad[eqNum]) ||
+ !(iv_poundW_data.poundw[TURBO].vdm_vid_compare_per_quad[eqNum]) ||
+ !(iv_poundW_data.poundw[ULTRA].vdm_vid_compare_per_quad[eqNum]))
+ {
+ iv_vdm_enabled = false;
+ FAPI_ASSERT_NOEXIT(false,
+ fapi2::PSTATE_PB_POUND_W_INVALID_VID_VALUE(fapi2::FAPI2_ERRL_SEV_RECOVERED)
+ .set_CHIP_TARGET(iv_procChip)
+ .set_EQ_TARGET(eq)
+ .set_NOMINAL_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_per_quad[eqNum])
+ .set_POWERSAVE_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_per_quad[eqNum])
+ .set_TURBO_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[TURBO].vdm_vid_compare_per_quad[eqNum])
+ .set_ULTRA_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[ULTRA].vdm_vid_compare_per_quad[eqNum]),
+ "Pstate Parameter Block #W : one of the VID compare value is zero");
+ break;
+ }
+
+ // validate vid values
+ bool l_compare_vid_value_state = 1;
+ VALIDATE_VID_VALUES (iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_per_quad[eqNum],
+ iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_per_quad[eqNum],
+ iv_poundW_data.poundw[TURBO].vdm_vid_compare_per_quad[eqNum],
+ iv_poundW_data.poundw[ULTRA].vdm_vid_compare_per_quad[eqNum],
+ l_compare_vid_value_state);
+
+ if (!l_compare_vid_value_state)
+ {
+ iv_vdm_enabled = false;
+ FAPI_ASSERT_NOEXIT(false,
+ fapi2::PSTATE_PB_POUND_W_INVALID_VID_ORDER(fapi2::FAPI2_ERRL_SEV_RECOVERED)
+ .set_CHIP_TARGET(iv_procChip)
+ .set_EQ_TARGET(eq)
+ .set_NOMINAL_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_per_quad[eqNum])
+ .set_POWERSAVE_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_per_quad[eqNum])
+ .set_TURBO_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[TURBO].vdm_vid_compare_per_quad[eqNum])
+ .set_ULTRA_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[ULTRA].vdm_vid_compare_per_quad[eqNum]),
+ "Pstate Parameter Block #W VID compare data are not in increasing order");
+ break;
+ }
+
+ //Biased compare vid data
+ fapi2::ATTR_VDM_VID_COMPARE_BIAS_0P5PCT_Type l_bias_value;
+
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_VDM_VID_COMPARE_BIAS_0P5PCT,
+ iv_procChip,
+ l_bias_value),
+ "Error from FAPI_ATTR_GET for attribute ATTR_VDM_VID_COMPARE_BIAS_0P5PCT");
+
+ float l_pound_w_points[NUM_OP_POINTS];
+
+ for (uint8_t i = 0; i < NUM_OP_POINTS; i++)
+ {
+ l_pound_w_points[i] = calc_bias(l_bias_value[i]);
+ l_vdm_compare_biased_mv[i] = internal_ceil( (l_vdm_compare_raw_mv[i] * l_pound_w_points[i]));
+
+ if (l_vdm_compare_biased_mv[i] < MIN_VDM_VOLTAGE_IN_MV)
+ {
+ l_vdm_compare_biased_mv[i] = MIN_VDM_VOLTAGE_IN_MV;
+ }
+
+ iv_poundW_data.poundw[i].vdm_vid_compare_per_quad[eqNum] =
+ (l_vdm_compare_biased_mv[i] - VDM_VOLTAGE_IN_MV) >> 2;
+
+ FAPI_INF("vdm_vid_compare_per_quad[eqNum] %x %x, %x",
+ iv_poundW_data.poundw[i].vdm_vid_compare_per_quad[eqNum],
+ iv_poundW_data.poundw[i].vdm_vid_compare_per_quad[eqNum],
+ l_pound_w_points[i]);
+ }
+ }//for eq
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
///////////////////////////////////////////////////////////
-//////// iddq_print
+//////// iddq_print
///////////////////////////////////////////////////////////
void iddq_print(IddqTable* i_iddqt)
{
@@ -4192,7 +4288,7 @@ void PlatPmPPB::load_mvpd_operating_point (vpd_type i_type)
iv_raw_vpd_pts[i].idd_100ma = (iv_attr_mvpd_poundV_raw[pv_op_order[i]].idd_100ma);
iv_raw_vpd_pts[i].vcs_mv = (iv_attr_mvpd_poundV_raw[pv_op_order[i]].vcs_mv);
iv_raw_vpd_pts[i].ics_100ma = (iv_attr_mvpd_poundV_raw[pv_op_order[i]].ics_100ma);
- iv_raw_vpd_pts[i].pstate = (iv_attr_mvpd_poundV_raw[ULTRA].frequency_mhz -
+ iv_raw_vpd_pts[i].pstate = (iv_attr_mvpd_poundV_raw[ULTRA].frequency_mhz -
iv_attr_mvpd_poundV_raw[pv_op_order[i]].frequency_mhz) * 1000 / (iv_frequency_step_khz);
FAPI_INF("PSTATE %x %x %d",iv_attr_mvpd_poundV_raw[ULTRA].frequency_mhz,iv_attr_mvpd_poundV_raw[pv_op_order[i]].frequency_mhz,iv_raw_vpd_pts[i].pstate);
}
@@ -4206,7 +4302,7 @@ void PlatPmPPB::load_mvpd_operating_point (vpd_type i_type)
iv_biased_vpd_pts[i].idd_100ma = (iv_attr_mvpd_poundV_biased[pv_op_order[i]].idd_100ma);
iv_biased_vpd_pts[i].vcs_mv = (iv_attr_mvpd_poundV_biased[pv_op_order[i]].vcs_mv);
iv_biased_vpd_pts[i].ics_100ma = (iv_attr_mvpd_poundV_biased[pv_op_order[i]].ics_100ma);
- iv_biased_vpd_pts[i].pstate = (iv_attr_mvpd_poundV_biased[ULTRA].frequency_mhz -
+ iv_biased_vpd_pts[i].pstate = (iv_attr_mvpd_poundV_biased[ULTRA].frequency_mhz -
iv_attr_mvpd_poundV_biased[pv_op_order[i]].frequency_mhz) * 1000 / (iv_frequency_step_khz);
}
}
@@ -4216,7 +4312,7 @@ void PlatPmPPB::load_mvpd_operating_point (vpd_type i_type)
///////////////////////////////////////////////////////////
-//////// vpd_init
+//////// vpd_init
///////////////////////////////////////////////////////////
fapi2::ReturnCode PlatPmPPB::vpd_init( void )
{
@@ -4308,22 +4404,22 @@ fapi_try_exit:
} // end of vpd_init
///////////////////////////////////////////////////////////
-//////// is_wov_underv_enabled
+//////// is_wov_underv_enabled
///////////////////////////////////////////////////////////
bool PlatPmPPB::is_wov_underv_enabled()
{
- return(!(iv_attrs.attr_wov_underv_enable) &&
+ return(!(iv_attrs.attr_wov_underv_disable) &&
iv_wov_underv_enabled)
? true : false;
}
///--------------------------------------
///////////////////////////////////////////////////////////
-//////// is_wov_overv_enabled
+//////// is_wov_overv_enabled
///////////////////////////////////////////////////////////
bool PlatPmPPB::is_wov_overv_enabled()
{
- return (!(iv_attrs.attr_wov_overv_enable) &&
+ return (!(iv_attrs.attr_wov_overv_disable) &&
iv_wov_overv_enabled)
? true : false;
}
@@ -4367,7 +4463,7 @@ bool PlatPmPPB::is_vdm_enabled()
///////////////////////////////////////////////////////////
-//////// isPstateModeEnabled
+//////// isPstateModeEnabled
///////////////////////////////////////////////////////////
bool PlatPmPPB::isPstateModeEnabled()
{
@@ -4377,7 +4473,7 @@ bool PlatPmPPB::isPstateModeEnabled()
///////////////////////////////////////////////////////////
-//////// isEqChipletPresent
+//////// isEqChipletPresent
///////////////////////////////////////////////////////////
bool PlatPmPPB::isEqChipletPresent ()
{
@@ -4386,7 +4482,7 @@ bool PlatPmPPB::isEqChipletPresent ()
///////////////////////////////////////////////////////////
-//////// large_jump_interpolate
+//////// large_jump_interpolate
///////////////////////////////////////////////////////////
uint32_t PlatPmPPB::large_jump_interpolate(const Pstate i_pstate,
const Pstate i_ps_pstate)
@@ -4607,15 +4703,18 @@ fapi_try_exit:
///////////////////////////////////////////////////////////
//////// gppb_print
///////////////////////////////////////////////////////////
-void gppb_print(GlobalPstateParmBlock* i_gppb)
+fapi2::ReturnCode gppb_print(GlobalPstateParmBlock* i_gppb, const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target )
{
- static const uint32_t BUFFSIZE = 256;
+ static const uint32_t BUFFSIZE = 512;
char l_buffer[BUFFSIZE];
char l_temp_buffer[BUFFSIZE];
char l_temp_buffer1[BUFFSIZE];
const char* pv_op_str[NUM_OP_POINTS] = PV_OP_ORDER_STR;
const char* thresh_op_str[NUM_THRESHOLD_POINTS] = VPD_THRESHOLD_ORDER_STR;
const char* slope_region_str[VPD_NUM_SLOPES_REGION] = VPD_OP_SLOPES_REGION_ORDER_STR;
+ auto l_eqChiplets = i_target.getChildren<fapi2::TARGET_TYPE_EQ>(fapi2::TARGET_STATE_FUNCTIONAL);
+ uint8_t eqPos = 0;
+ int l_len = strlen(l_buffer);
// Put out the endian-corrected scalars
FAPI_INF("---------------------------------------------------------------------------------------");
FAPI_INF("Global Pstate Parameter Block @ %p", i_gppb);
@@ -4803,10 +4902,29 @@ void gppb_print(GlobalPstateParmBlock* i_gppb)
}
FAPI_INF ("VID Operating Points");
- for (auto i = 0; i < NUM_OP_POINTS; ++i)
+ for( auto eq : l_eqChiplets )
{
- sprintf (l_buffer, " %-16s : %02X ",pv_op_str[i], i_gppb->vid_point_set[i]);
- FAPI_INF("%s", l_buffer);
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, eq, eqPos ));
+ strcpy(l_buffer,"");
+ strcpy(l_temp_buffer, "");
+
+ //FIXME avoiding changes in GPSPB to address compatibility issues between
+ //hardware image and HWP
+ for (auto i = 0; i < NUM_OP_POINTS; ++i)
+ {
+ //sprintf (l_buffer, "Q[%d] %-16s : %02X ", eqPos, pv_op_str[i], i_gppb->vid_point_set[eqPos][i]);
+ //FAPI_INF("%s", l_buffer);
+ }
+
+ for (auto j = 0; j < VPD_NUM_SLOPES_REGION; ++j)
+ {
+ //sprintf(l_temp_buffer1, "%04X",
+ // revle16(i_gppb->PsVIDCompSlopes[eqPos][j]));
+ //CENTER_STR(l_temp_buffer, l_temp_buffer1, 8);
+ //strcat(l_buffer, l_temp_buffer);
+ }
+
+ //FAPI_INF("%s", l_buffer);
}
sprintf(l_buffer, "%-25s", "Thrshod Op Points: ");
@@ -4832,7 +4950,6 @@ void gppb_print(GlobalPstateParmBlock* i_gppb)
}
sprintf(l_buffer, "VID Compare Slopes:");
- int l_len = strlen(l_buffer);
for (auto j = 0; j < VPD_NUM_SLOPES_REGION; ++j)
{
sprintf(l_temp_buffer1, "%s", prt_region_names[j]);
@@ -4842,14 +4959,6 @@ void gppb_print(GlobalPstateParmBlock* i_gppb)
FAPI_INF("%s", l_buffer);
sprintf( l_buffer, "%*s", l_len+6," ");
- for (auto j = 0; j < VPD_NUM_SLOPES_REGION; ++j)
- {
- sprintf(l_temp_buffer1, "%04X",
- revle16(i_gppb->PsVIDCompSlopes[j]));
- CENTER_STR(l_temp_buffer, l_temp_buffer1, 8);
- strcat(l_buffer, l_temp_buffer);
- }
- FAPI_INF("%s", l_buffer);
sprintf(l_buffer, "%-18s", "VDM Thrshld Slopes:");
for (auto j = 0; j < VPD_NUM_SLOPES_REGION; ++j)
@@ -4936,6 +5045,8 @@ void gppb_print(GlobalPstateParmBlock* i_gppb)
}
FAPI_INF("---------------------------------------------------------------------------------------");
+fapi_try_exit:
+ return fapi2::current_err;
} // end of gppb_print
@@ -5095,5 +5206,4 @@ void oppb_print(OCCPstateParmBlock* i_oppb)
FAPI_INF("---------------------------------------------------------------------------------------");
} // end of oppb_print
-
// *INDENT-ON*
diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.H b/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.H
index 971a7be99..3d140464f 100644
--- a/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.H
+++ b/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.H
@@ -42,7 +42,7 @@
#include <p9_pstates_occ.h>
#include "p9_pm_get_poundv_bucket.H"
#include "p9_pm_get_poundw_bucket.H"
-
+#include <p9_hcd_memmap_base.H>
//Pstate SuperStructure
typedef struct
@@ -54,7 +54,7 @@ typedef struct
GlobalPstateParmBlock globalppb;
// CME content
- LocalPstateParmBlock localppb;
+ LocalPstateParmBlock localppb[MAX_QUADS_PER_CHIP];
// OCC content
OCCPstateParmBlock occppb;
@@ -119,7 +119,7 @@ typedef struct
uint32_t attr_proc_r_distloss_vcs_uohm;
uint32_t attr_proc_vrm_voffset_vcs_uv;
- uint32_t attr_freq_proc_refclock_khz;
+ uint32_t attr_freq_dpll_refclock_khz;
uint32_t attr_proc_dpll_divider;
uint32_t attr_nest_frequency_mhz;
@@ -205,8 +205,8 @@ typedef struct
uint32_t proc_dpll_divider;
///Undervolt and Overvolt Attributes
- uint8_t attr_wov_underv_enable;
- uint8_t attr_wov_overv_enable;
+ uint8_t attr_wov_underv_disable;
+ uint8_t attr_wov_overv_disable;
uint8_t attr_wov_underv_force;
uint32_t attr_wov_sample_125us;
uint32_t attr_wov_max_droop_pct;
@@ -247,21 +247,21 @@ class PlatPmPPB
/// -----------------------------------------------------------------------
/// @brief Initialize VPD data
- // @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ // @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode vpd_init();
/// -----------------------------------------------------------------------
/// @brief Initialize resclk data
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode resclk_init();
/// -----------------------------------------------------------------------
/// @brief Initialize WOF data
/// @param[out] o_buf points to WOF data
- /// @param[inout] io_size size of the wof table
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @param[inout] io_size size of the wof table
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode wof_init(
uint8_t* o_buf,
@@ -269,19 +269,19 @@ class PlatPmPPB
/// -----------------------------------------------------------------------
/// @brief Initialize global pstate parameter block
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode gppb_init( GlobalPstateParmBlock* i_globalppb);
/// -----------------------------------------------------------------------
/// @brief Initialize local pstate parameter block
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode lppb_init(LocalPstateParmBlock* i_localppb);
/// -----------------------------------------------------------------------
/// @brief Initialize occ pstate parameter block
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode oppb_init(OCCPstateParmBlock* i_occppb);
@@ -289,11 +289,11 @@ class PlatPmPPB
/// @brief VDM initializtion based on #W data
/// @return none
/// -----------------------------------------------------------------------
- void vdm_init( void );
+ fapi2::ReturnCode vdm_init( void );
/// -----------------------------------------------------------------------
/// @brief Safe mode frquency and voltage init
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode safe_mode_init( void );
@@ -301,7 +301,7 @@ class PlatPmPPB
/// @brief VFRT data initialization from WOF data
/// @param[in] i_pBuffer WOF data buffer
/// @param[inout] o_vfrt_data vfrt data
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode update_vfrt(
uint8_t* i_pBuffer,
@@ -309,43 +309,43 @@ class PlatPmPPB
/// -----------------------------------------------------------------------
/// @brief Compute and apply biased values
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode get_extint_bias();
/// -----------------------------------------------------------------------
/// @brief apply biased values for #V data
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode apply_biased_values();
/// -----------------------------------------------------------------------
/// @brief Read IQ vpd data
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode get_mvpd_iddq( void );
/// -----------------------------------------------------------------------
/// @brief Read #W(VDM) vpd data
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode get_mvpd_poundW (void);
/// -----------------------------------------------------------------------
/// @brief Read IVRM data from attributes
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode get_ivrm_parms ();
/// -----------------------------------------------------------------------
/// @brief Set resclk attribute values
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode set_resclk_table_attrs();
/// -----------------------------------------------------------------------
/// @brief Compute and setup resclk values
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode res_clock_setup (void);
@@ -358,7 +358,7 @@ class PlatPmPPB
/// -----------------------------------------------------------------------
/// @brief Compute safe mode values
/// @param[in] i_action voltage config action (Compute/set)
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode compute_boot_safe(
const VoltageConfigActions_t i_action);
@@ -373,7 +373,7 @@ class PlatPmPPB
/// -----------------------------------------------------------------------
/// @brief This will set the pstate feature attrbutes(VDM,RESCLK,VRM,WOF)
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode set_global_feature_attributes();
@@ -410,14 +410,14 @@ class PlatPmPPB
/// -----------------------------------------------------------------------
/// @brief Read #V data form module vpd
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode get_mvpd_poundV();
/// -----------------------------------------------------------------------
/// @brief Validate #V data
/// @param[in] i_biased_state present/nonpresent
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode chk_valid_poundv(
const bool i_biased_state);
@@ -431,8 +431,9 @@ class PlatPmPPB
/// -----------------------------------------------------------------------
/// @brief Converts frequency value to pstate number
/// @param[in] i_freq_khz input frequency
- /// @param[out] o_pstate pstate output for a given inut frequency
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @param[out] pstate pstate output for a given inut frequency
+ /// @param[in] i_round p-state rounding strategy
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
int freq2pState (const uint32_t freq_khz,
Pstate* pstate,
@@ -440,9 +441,9 @@ class PlatPmPPB
/// -----------------------------------------------------------------------
/// @brief Compute safe mode values
- /// @param[in] i_pstate pstate value
+ /// @param[in] i_ps_state pstate value
/// @param[out] o_safe_mode_values safe mode freq/voltage values
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
fapi2::ReturnCode safe_mode_computation(
const Pstate i_ps_pstate,
@@ -451,7 +452,7 @@ class PlatPmPPB
/// -----------------------------------------------------------------------
/// @brief Convert pstate to voltage
/// @param[in] i_pstate pstate value that needs to be converted
- /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
uint32_t ps2v_mv(const Pstate i_pstate);
@@ -474,16 +475,16 @@ class PlatPmPPB
/// -----------------------------------------------------------------------
/// @brief Compute VID compare slope values for a given pstate
/// @param[in] i_pstate pstate value
- /// @return none
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
- void compute_PsVIDCompSlopes_slopes(
+ fapi2::ReturnCode compute_PsVIDCompSlopes_slopes(
uint8_t* i_pstate);
/// -----------------------------------------------------------------------
/// @brief Compute VDM threshold points for different regions
- /// @return none
+ /// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -----------------------------------------------------------------------
- void compute_vdm_threshold_pts();
+ fapi2::ReturnCode compute_vdm_threshold_pts();
/// -----------------------------------------------------------------------
/// @brief Compute bias value for pre-defined percentage unit
@@ -685,8 +686,10 @@ class PlatPmPPB
}
#endif
+ private: //function
+ fapi2::ReturnCode validate_quad_spec_data( );
- private:
+ private: //data
fapi2::Target< fapi2::TARGET_TYPE_PROC_CHIP > iv_procChip; // processor chip target
AttributeList iv_attrs; // Pstate attributes list
VpdOperatingPoint iv_raw_vpd_pts[NUM_OP_POINTS]; // Raw vpd operating points
@@ -718,14 +721,14 @@ class PlatPmPPB
VpdPoint iv_attr_mvpd_poundV_raw[5];
VpdPoint iv_attr_mvpd_poundV_biased[5];
- PoundW_data iv_poundW_data;
+ PoundW_data_per_quad iv_poundW_data;
IddqTable iv_iddqt;
GP_VDMParmBlock iv_vdmpb;
IvrmParmBlock iv_ivrmpb;
ResonantClockingSetup iv_resclk_setup;
- CompareVIDPoints iv_vid_point_set[NUM_OP_POINTS];
+ CompareVIDPoints iv_vid_point_set[MAX_QUADS_PER_CHIP][NUM_OP_POINTS];
uint8_t iv_threshold_set[NUM_OP_POINTS][NUM_THRESHOLD_POINTS];
- int16_t iv_PsVIDCompSlopes[VPD_NUM_SLOPES_REGION];
+ int16_t iv_PsVIDCompSlopes[MAX_QUADS_PER_CHIP][VPD_NUM_SLOPES_REGION];
int16_t iv_PsVDMThreshSlopes[VPD_NUM_SLOPES_REGION][NUM_THRESHOLD_POINTS];
uint8_t iv_jump_value_set[NUM_OP_POINTS][NUM_JUMP_VALUES];
int16_t iv_PsVDMJumpSlopes[VPD_NUM_SLOPES_REGION][NUM_JUMP_VALUES];
@@ -747,10 +750,10 @@ extern "C"
/// -------------------------------------------------------------------
/// @brief Print a GlobalPstateParameterBlock structure on a given stream
/// @param[in] i_gppb The Global Pstate Parameter Block to print
-/// @return void
+/// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -------------------------------------------------------------------
- void
- gppb_print(GlobalPstateParmBlock* i_gppb);
+ fapi2::ReturnCode gppb_print(GlobalPstateParmBlock* i_gppb,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target );
/// -------------------------------------------------------------------
@@ -778,7 +781,7 @@ extern "C"
/// @param[inout] *io_pss => pointer to pstate superstructure
/// @param[out] *o_buf => wof table data
/// @param[inout] &io_size => wof table data size
-/// @return FAPI2::SUCCESS
+/// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// -------------------------------------------------------------------
fapi2::ReturnCode
p9_pstate_parameter_block( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
diff --git a/src/import/chips/p9/procedures/utils/stopreg/p9_cpu_reg_restore_instruction.H b/src/import/chips/p9/procedures/utils/stopreg/p9_cpu_reg_restore_instruction.H
index 27603b23f..b92d439bb 100755
--- a/src/import/chips/p9/procedures/utils/stopreg/p9_cpu_reg_restore_instruction.H
+++ b/src/import/chips/p9/procedures/utils/stopreg/p9_cpu_reg_restore_instruction.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -76,7 +76,8 @@ enum
SKIP_SPR_REST_INST = 0x4800001c, //b . +0x01c
MFLR_R30 = 0x7fc802a6,
SKIP_SPR_SELF_SAVE = 0x3bff0020, //addi r31 r31, 0x20
- MTLR_INST = 0x7fc803a6 //mtlr r30
+ MTLR_INST = 0x7fc803a6, //mtlr r30
+ BRANCH_BE_INST = 0x48000020,
};
#ifdef __cplusplus
diff --git a/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.C b/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.C
index f41086b44..d3e11e8ab 100755
--- a/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.C
+++ b/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -80,7 +80,7 @@ const uint32_t LEGACY_QUAD_SCOM_SUPPORTED = 63;
//-----------------------------------------------------------------------------
/**
- * @brief vaildated input arguments passed to p9_stop_save_cpureg_control.
+ * @brief validated input arguments passed to p9_stop_save_cpureg_control.
* @param[in] i_pImage point to start of HOMER
* @param[in] i_coreId id of the core
* @param[in] i_threadId id of the thread
@@ -651,138 +651,9 @@ StopReturnCode_t p9_stop_save_cpureg( void* const i_pImage,
const uint64_t i_regData,
const uint64_t i_pir )
{
- StopReturnCode_t l_rc = STOP_SAVE_SUCCESS; // procedure return code
- HomerSection_t* chipHomer = NULL;
- SmfHomerSection_t* smfChipHomer = NULL;
-
- do
- {
- uint32_t threadId = 0;
- uint32_t coreId = 0;
- uint32_t lookUpKey = 0;
- void* pSprEntryLocation = NULL; // an offset w.r.t. to start of image
- void* pThreadLocation = NULL;
- bool threadScopeReg = false;
- uint8_t l_urmorFix = false;
- uint64_t l_sprValue = 0;
- uint8_t l_selfRestVer = 0;
-
- MY_INF(">> p9_stop_save_cpureg" );
-
- l_rc = getCoreAndThread( i_pImage, i_pir, &coreId, &threadId );
-
- if( l_rc )
- {
- MY_ERR("Failed to determine Core Id and Thread Id from PIR 0x%016llx",
- i_pir);
- break;
- }
-
- MY_INF( " PIR 0x%016llx coreId %d threadid %d "
- " registerId %d", i_pir, coreId,
- threadId, i_regId );
-
- // First of all let us validate all input arguments.
- l_rc = validateSprImageInputs( i_pImage,
- i_regId,
- coreId,
- &threadId,
- &threadScopeReg );
-
- if( l_rc )
- {
- // Error: bad argument traces out error code
- MY_ERR("Bad input argument rc %d", l_rc );
-
- break;
- }
-
- l_urmorFix = *(uint8_t*)((uint8_t*)i_pImage + CPMR_HOMER_OFFSET + CPMR_URMOR_FIX_BYTE);
- l_selfRestVer = *(uint8_t *)((uint8_t *)i_pImage + CPMR_HOMER_OFFSET + CPMR_SELF_RESTORE_VER_BYTE );
-
- if( l_selfRestVer )
- {
- smfChipHomer = ( SmfHomerSection_t*)i_pImage;
-
- if( threadScopeReg )
- {
- pThreadLocation =
- &(smfChipHomer->iv_coreThreadRestore[coreId].iv_threadRestoreArea[threadId][0]);
- }
- else
- {
- pThreadLocation =
- &(smfChipHomer->iv_coreThreadRestore[coreId].iv_coreRestoreArea[0]);
- }
- }
- else //Old fips or OPAL release that doesn't support SMF
- {
- chipHomer = (HomerSection_t*)i_pImage;
-
- if( threadScopeReg )
- {
- pThreadLocation =
- &(chipHomer->iv_coreThreadRestore[coreId][threadId].iv_threadArea[0]);
- }
- else
- {
- pThreadLocation =
- &(chipHomer->iv_coreThreadRestore[coreId][threadId].iv_coreArea[0]);
- }
- }
-
- if( ( SWIZZLE_4_BYTE(BLR_INST) == *(uint32_t*)pThreadLocation ) ||
- ( SWIZZLE_4_BYTE(ATTN_OPCODE) == *(uint32_t*) pThreadLocation ) )
- {
- // table for given core id doesn't exit. It needs to be
- // defined.
- pSprEntryLocation = pThreadLocation;
- }
- else
- {
- // an SPR restore section for given core already exists
- lookUpKey = genKeyForSprLookup( i_regId );
- l_rc = lookUpSprInImage( (uint32_t*)pThreadLocation,
- lookUpKey,
- threadScopeReg,
- &pSprEntryLocation,
- l_selfRestVer );
- }
-
- if( l_rc )
- {
- MY_ERR("Invalid or corrupt SPR entry. CoreId 0x%08x threadId ",
- "0x%08x regId 0x%08x lookUpKey 0x%08x pThreadLocation 0x%08x"
- , coreId, threadId, i_regId, lookUpKey, pThreadLocation );
- break;
- }
-
- if( ( P9_STOP_SPR_URMOR == i_regId ) && ( l_urmorFix ) )
- {
- l_sprValue = i_regData - URMOR_CORRECTION;
- }
- else
- {
- l_sprValue = i_regData;
- }
-
- l_rc = updateSprEntryInImage( (uint32_t*) pSprEntryLocation,
- i_regId,
- l_sprValue,
- UPDATE_SPR_ENTRY );
-
- if( l_rc )
- {
- MY_ERR( " Failed to update the SPR entry of PIR 0x%08x reg"
- "0x%08x", i_pir, i_regId );
- break;
- }
-
- }
- while(0);
+ MY_INF(">> p9_stop_save_cpureg" );
- MY_INF("<< p9_stop_save_cpureg" );
- return l_rc;
+ return proc_stop_save_cpureg( i_pImage, i_regId, i_regData, i_pir );
}
//-----------------------------------------------------------------------------
@@ -1008,6 +879,239 @@ StopReturnCode_t p9_stop_save_scom( void* const i_pImage,
const ScomOperation_t i_operation,
const ScomSection_t i_section )
{
+ MY_INF(">> p9_stop_save_scom");
+
+ return proc_stop_save_scom( i_pImage, i_scomAddress,
+ i_scomData, i_operation, i_section );
+}
+
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief searches a self save entry of an SPR in self-save segment.
+ * @param[in] i_sprBitPos bit position associated with SPR in save mask vector.
+ * @param[in] l_pSprSaveStart start location of SPR save segment
+ * @param[in] i_searchLength length of SPR save segment
+ * @param[in] i_pSaveSprLoc start location of save entry for a given SPR.
+ * @return STOP_SAVE_SUCCESS if look up succeeds, error code otherwise.
+ */
+STATIC StopReturnCode_t lookUpSelfSaveSpr( uint32_t i_sprBitPos, uint32_t* l_pSprSaveStart,
+ uint32_t i_searchLength, uint32_t** i_pSaveSprLoc )
+{
+ int32_t l_saveWordLength = (int32_t)(i_searchLength >> 2);
+ uint32_t l_oriInst = getOriInstruction( 0, 0, i_sprBitPos );
+ StopReturnCode_t l_rc = STOP_SAVE_FAIL;
+
+ while( l_saveWordLength > 0 )
+ {
+ if( l_oriInst == *l_pSprSaveStart )
+ {
+ *i_pSaveSprLoc = l_pSprSaveStart;
+ l_rc = STOP_SAVE_SUCCESS;
+ break;
+ }
+
+ l_pSprSaveStart++;
+ l_saveWordLength--;
+ }
+
+ return l_rc;
+}
+
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief searches a self save entry of an SPR in self-save segment.
+ * @param[in] i_pSaveReg start of editable location of a SPR save entry.
+ * @param[in] i_sprNum Id of the SPR for which entry needs to be edited.
+ * @return STOP_SAVE_SUCCESS if look up succeeds, error code otherwise.
+ */
+STATIC StopReturnCode_t updateSelfSaveEntry( uint32_t* i_pSaveReg, uint16_t i_sprNum )
+{
+ StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;
+
+ do
+ {
+ if( !i_pSaveReg )
+ {
+ l_rc = STOP_SAVE_FAIL;
+ MY_ERR( "Failed to update self save area for SPR 0x%04x", i_sprNum );
+ break;
+ }
+
+ if( P9_STOP_SPR_MSR == i_sprNum )
+ {
+ *i_pSaveReg = getMfmsrInstruction( 1 );
+ }
+ else
+ {
+ *i_pSaveReg = getMfsprInstruction( 1, i_sprNum );
+ }
+
+ i_pSaveReg++;
+
+ *i_pSaveReg = getBranchLinkRegInstruction( );
+ }
+ while(0);
+
+ return l_rc;
+}
+
+//-----------------------------------------------------------------------------
+
+StopReturnCode_t p9_stop_save_cpureg_control( void* i_pImage,
+ const uint64_t i_pir,
+ const uint32_t i_saveRegVector )
+{
+ MY_INF( ">> p9_stop_save_cpureg_control" );
+
+ return proc_stop_save_cpureg_control( i_pImage, i_pir, i_saveRegVector );
+}
+
+//-----------------------------------------------------------------------------------------------------
+
+StopReturnCode_t p9_stop_init_cpureg( void* const i_pImage, const uint32_t i_corePos )
+{
+ MY_INF( ">> p9_stop_init_cpureg" );
+
+ return proc_stop_init_cpureg( i_pImage, i_corePos );
+}
+
+//-----------------------------------------------------------------------------------------------------
+
+StopReturnCode_t p9_stop_init_self_save( void* const i_pImage, const uint32_t i_corePos )
+{
+ MY_INF( ">> p9_stop_init_self_save" );
+
+ return proc_stop_init_self_save( i_pImage, i_corePos );
+}
+
+//-----------------------------------------------------------------------------------------------------
+
+StopReturnCode_t proc_stop_init_cpureg( void* const i_pImage, const uint32_t i_corePos )
+{
+
+ StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;
+ uint32_t* l_pRestoreStart = NULL;
+ void* l_pTempLoc = NULL;
+ SmfHomerSection_t* l_pHomer = NULL;
+ uint32_t l_threadPos = 0;
+ uint32_t l_lookUpKey = 0;
+ uint32_t l_sprIndex = 0;
+ uint8_t l_selfRestVer = 0;
+
+ MY_INF( ">> proc_stop_init_cpureg" );
+
+ do
+ {
+ if( !i_pImage )
+ {
+ l_rc = STOP_SAVE_ARG_INVALID_IMG;
+ break;
+ }
+
+ if( i_corePos > MAX_CORE_ID_SUPPORTED )
+ {
+ l_rc = STOP_SAVE_ARG_INVALID_CORE;
+ break;
+ }
+
+ l_pHomer = ( SmfHomerSection_t * ) i_pImage;
+ l_selfRestVer = *(uint8_t *)((uint8_t *)i_pImage + CPMR_HOMER_OFFSET + CPMR_SELF_RESTORE_VER_BYTE );
+
+ for( l_sprIndex = 0; l_sprIndex < MAX_SPR_SUPPORTED; l_sprIndex++ )
+ {
+ //Check if a given SPR needs to be self-saved each time on STOP entry
+
+ l_lookUpKey = genKeyForSprLookup( ( CpuReg_t )g_sprRegister[l_sprIndex].iv_sprId );
+
+ if( g_sprRegister[l_sprIndex].iv_isThreadScope )
+ {
+ for( l_threadPos = 0; l_threadPos < MAX_THREADS_PER_CORE; l_threadPos++ )
+ {
+ l_pRestoreStart =
+ (uint32_t*)&l_pHomer->iv_coreThreadRestore[i_corePos].iv_threadRestoreArea[l_threadPos][0];
+
+ l_rc = lookUpSprInImage( (uint32_t*)l_pRestoreStart, l_lookUpKey,
+ g_sprRegister[l_sprIndex].iv_isThreadScope,
+ &l_pTempLoc,
+ l_selfRestVer );
+
+ if( l_rc )
+ {
+ MY_ERR( "Thread SPR lookup failed in p9_stop_init_cpureg SPR %d Core %d Thread %d Index %d",
+ g_sprRegister[l_sprIndex].iv_sprId, i_corePos, l_threadPos, l_sprIndex );
+ break;
+ }
+
+ l_rc = updateSprEntryInImage( (uint32_t*) l_pTempLoc,
+ ( CpuReg_t )g_sprRegister[l_sprIndex].iv_sprId,
+ 0x00,
+ INIT_SPR_REGION );
+
+ if( l_rc )
+ {
+ MY_ERR( "Thread SPR region init failed. Core %d SPR Id %d",
+ i_corePos, g_sprRegister[l_sprIndex].iv_sprId );
+ break;
+ }
+
+ }//end for thread
+
+ if( l_rc )
+ {
+ break;
+ }
+
+ }//end if SPR threadscope
+ else
+ {
+ l_pRestoreStart = (uint32_t*)&l_pHomer->iv_coreThreadRestore[i_corePos].iv_coreRestoreArea[0];
+
+ l_rc = lookUpSprInImage( (uint32_t*)l_pRestoreStart, l_lookUpKey,
+ g_sprRegister[l_sprIndex].iv_isThreadScope,
+ &l_pTempLoc, l_selfRestVer );
+
+ if( l_rc )
+ {
+ MY_ERR( "Core SPR lookup failed in p9_stop_init_cpureg" );
+ break;
+ }
+
+ l_rc = updateSprEntryInImage( (uint32_t*) l_pTempLoc,
+ ( CpuReg_t )g_sprRegister[l_sprIndex].iv_sprId,
+ 0x00,
+ INIT_SPR_REGION );
+
+ if( l_rc )
+ {
+ MY_ERR( "Core SPR region init failed. Core %d SPR Id %d SPR Index %d",
+ i_corePos, g_sprRegister[l_sprIndex].iv_sprId, l_sprIndex );
+ break;
+ }
+
+ }// end else
+
+ }// end for l_sprIndex
+
+ }
+ while(0);
+
+ MY_INF( "<< proc_stop_init_cpureg" );
+
+ return l_rc;
+}
+
+//-----------------------------------------------------------------------------------------------------
+
+StopReturnCode_t proc_stop_save_scom( void* const i_pImage,
+ const uint32_t i_scomAddress,
+ const uint64_t i_scomData,
+ const ScomOperation_t i_operation,
+ const ScomSection_t i_section )
+{
+ MY_INF( ">> proc_stop_save_scom" );
+
StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;
uint32_t entryLimit = 0;
uint8_t chipletId = 0;
@@ -1028,7 +1132,6 @@ StopReturnCode_t p9_stop_save_scom( void* const i_pImage,
uint32_t swizzleBlr = SWIZZLE_4_BYTE(BLR_INST);
bool cacheEntry = true;
- MY_INF(">> p9_stop_save_scom");
//Reads SGPE image version info from QPMR Header in HOMER
//For backward compatibility, for base version of SGPE Hcode,
@@ -1323,87 +1426,16 @@ StopReturnCode_t p9_stop_save_scom( void* const i_pImage,
updateEntryHeader( pEditScomHeader, imageVer, l_maxScomRestoreEntry );
}
- MY_INF("<< p9_stop_save_scom");
- return l_rc;
-}
-
-//-----------------------------------------------------------------------------
-
-/**
- * @brief searches a self save entry of an SPR in self-save segment.
- * @param[in] i_sprBitPos bit position associated with SPR in save mask vector.
- * @param[in] l_pSprSaveStart start location of SPR save segment
- * @param[in] i_searchLength length of SPR save segment
- * @param[in] i_pSaveSprLoc start location of save entry for a given SPR.
- * @return STOP_SAVE_SUCCESS if look up succeeds, error code otherwise.
- */
-STATIC StopReturnCode_t lookUpSelfSaveSpr( uint32_t i_sprBitPos, uint32_t* l_pSprSaveStart,
- uint32_t i_searchLength, uint32_t** i_pSaveSprLoc )
-{
- int32_t l_saveWordLength = (int32_t)(i_searchLength >> 2);
- uint32_t l_oriInst = getOriInstruction( 0, 0, i_sprBitPos );
- StopReturnCode_t l_rc = STOP_SAVE_FAIL;
-
- while( l_saveWordLength > 0 )
- {
- if( l_oriInst == *l_pSprSaveStart )
- {
- *i_pSaveSprLoc = l_pSprSaveStart;
- l_rc = STOP_SAVE_SUCCESS;
- break;
- }
-
- l_pSprSaveStart++;
- l_saveWordLength--;
- }
-
- return l_rc;
-}
-
-//-----------------------------------------------------------------------------
-
-/**
- * @brief searches a self save entry of an SPR in self-save segment.
- * @param[in] i_pSaveReg start of editable location of a SPR save entry.
- * @param[in] i_sprNum Id of the SPR for which entry needs to be edited.
- * @return STOP_SAVE_SUCCESS if look up succeeds, error code otherwise.
- */
-STATIC StopReturnCode_t updateSelfSaveEntry( uint32_t* i_pSaveReg, uint16_t i_sprNum )
-{
- StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;
-
- do
- {
- if( !i_pSaveReg )
- {
- l_rc = STOP_SAVE_FAIL;
- MY_ERR( "Failed to update self save area for SPR 0x%04x", i_sprNum );
- break;
- }
-
- if( P9_STOP_SPR_MSR == i_sprNum )
- {
- *i_pSaveReg = getMfmsrInstruction( 1 );
- }
- else
- {
- *i_pSaveReg = getMfsprInstruction( 1, i_sprNum );
- }
-
- i_pSaveReg++;
-
- *i_pSaveReg = getBranchLinkRegInstruction( );
- }
- while(0);
+ MY_INF( "<< proc_stop_save_scom" );
return l_rc;
}
-//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------------------------
-StopReturnCode_t p9_stop_save_cpureg_control( void* i_pImage,
- const uint64_t i_pir,
- const uint32_t i_saveRegVector )
+StopReturnCode_t proc_stop_save_cpureg_control( void* i_pImage,
+ const uint64_t i_pir,
+ const uint32_t i_saveRegVector )
{
StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;
uint32_t l_coreId = 0;
@@ -1419,6 +1451,7 @@ StopReturnCode_t p9_stop_save_cpureg_control( void* i_pImage,
uint32_t * l_pTempWord = NULL;
SmfHomerSection_t* l_pHomer = NULL;
uint8_t l_selfRestVer = 0;
+ MY_INF(">> proc_stop_save_cpureg_control" );
do
{
@@ -1522,134 +1555,168 @@ StopReturnCode_t p9_stop_save_cpureg_control( void* i_pImage,
}
while(0);
+ MY_INF("<< proc_stop_save_cpureg_control" );
+
return l_rc;
+
}
//-----------------------------------------------------------------------------------------------------
-StopReturnCode_t p9_stop_init_cpureg( void* const i_pImage, const uint32_t i_corePos )
+StopReturnCode_t proc_stop_save_cpureg( void* const i_pImage,
+ const CpuReg_t i_regId,
+ const uint64_t i_regData,
+ const uint64_t i_pir )
{
- StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;
- uint32_t* l_pRestoreStart = NULL;
- void* l_pTempLoc = NULL;
- SmfHomerSection_t* l_pHomer = NULL;
- uint32_t l_threadPos = 0;
- uint32_t l_lookUpKey = 0;
- uint32_t l_sprIndex = 0;
- uint8_t l_selfRestVer = 0;
+ MY_INF(">> proc_stop_save_cpureg" );
- MY_INF( ">> p9_stop_init_cpureg" );
+ StopReturnCode_t l_rc = STOP_SAVE_SUCCESS; // procedure return code
+ HomerSection_t* chipHomer = NULL;
+ SmfHomerSection_t* smfChipHomer = NULL;
do
{
- if( !i_pImage )
+ uint32_t threadId = 0;
+ uint32_t coreId = 0;
+ uint32_t lookUpKey = 0;
+ void* pSprEntryLocation = NULL; // an offset w.r.t. to start of image
+ void* pThreadLocation = NULL;
+ bool threadScopeReg = false;
+ uint8_t l_urmorFix = false;
+ uint64_t l_sprValue = 0;
+ uint8_t l_selfRestVer = 0;
+
+
+ l_rc = getCoreAndThread( i_pImage, i_pir, &coreId, &threadId );
+
+ if( l_rc )
{
- l_rc = STOP_SAVE_ARG_INVALID_IMG;
+ MY_ERR("Failed to determine Core Id and Thread Id from PIR 0x%016llx",
+ i_pir);
break;
}
- if( i_corePos > MAX_CORE_ID_SUPPORTED )
+ MY_INF( " PIR 0x%016llx coreId %d threadid %d "
+ " registerId %d", i_pir, coreId,
+ threadId, i_regId );
+
+ // First of all let us validate all input arguments.
+ l_rc = validateSprImageInputs( i_pImage,
+ i_regId,
+ coreId,
+ &threadId,
+ &threadScopeReg );
+
+ if( l_rc )
{
- l_rc = STOP_SAVE_ARG_INVALID_CORE;
+ // Error: bad argument traces out error code
+ MY_ERR("Bad input argument rc %d", l_rc );
+
break;
}
- l_pHomer = ( SmfHomerSection_t * ) i_pImage;
+ l_urmorFix = *(uint8_t*)((uint8_t*)i_pImage + CPMR_HOMER_OFFSET + CPMR_URMOR_FIX_BYTE);
l_selfRestVer = *(uint8_t *)((uint8_t *)i_pImage + CPMR_HOMER_OFFSET + CPMR_SELF_RESTORE_VER_BYTE );
- for( l_sprIndex = 0; l_sprIndex < MAX_SPR_SUPPORTED; l_sprIndex++ )
+ if( l_selfRestVer )
{
- //Check if a given SPR needs to be self-saved each time on STOP entry
-
- l_lookUpKey = genKeyForSprLookup( ( CpuReg_t )g_sprRegister[l_sprIndex].iv_sprId );
+ smfChipHomer = ( SmfHomerSection_t*)i_pImage;
- if( g_sprRegister[l_sprIndex].iv_isThreadScope )
+ if( threadScopeReg )
{
- for( l_threadPos = 0; l_threadPos < MAX_THREADS_PER_CORE; l_threadPos++ )
- {
- l_pRestoreStart =
- (uint32_t*)&l_pHomer->iv_coreThreadRestore[i_corePos].iv_threadRestoreArea[l_threadPos][0];
-
- l_rc = lookUpSprInImage( (uint32_t*)l_pRestoreStart, l_lookUpKey,
- g_sprRegister[l_sprIndex].iv_isThreadScope,
- &l_pTempLoc,
- l_selfRestVer );
-
- if( l_rc )
- {
- MY_ERR( "Thread SPR lookup failed in p9_stop_init_cpureg SPR %d Core %d Thread %d Index %d",
- g_sprRegister[l_sprIndex].iv_sprId, i_corePos, l_threadPos, l_sprIndex );
- break;
- }
-
- l_rc = updateSprEntryInImage( (uint32_t*) l_pTempLoc,
- ( CpuReg_t )g_sprRegister[l_sprIndex].iv_sprId,
- 0x00,
- INIT_SPR_REGION );
-
- if( l_rc )
- {
- MY_ERR( "Thread SPR region init failed. Core %d SPR Id %d",
- i_corePos, g_sprRegister[l_sprIndex].iv_sprId );
- break;
- }
-
- }//end for thread
-
- if( l_rc )
- {
- break;
- }
-
- }//end if SPR threadscope
+ pThreadLocation =
+ &(smfChipHomer->iv_coreThreadRestore[coreId].iv_threadRestoreArea[threadId][0]);
+ }
else
{
- l_pRestoreStart = (uint32_t*)&l_pHomer->iv_coreThreadRestore[i_corePos].iv_coreRestoreArea[0];
+ pThreadLocation =
+ &(smfChipHomer->iv_coreThreadRestore[coreId].iv_coreRestoreArea[0]);
+ }
+ }
+ else //Old fips or OPAL release that doesn't support SMF
+ {
+ chipHomer = (HomerSection_t*)i_pImage;
- l_rc = lookUpSprInImage( (uint32_t*)l_pRestoreStart, l_lookUpKey,
- g_sprRegister[l_sprIndex].iv_isThreadScope,
- &l_pTempLoc, l_selfRestVer );
+ if( threadScopeReg )
+ {
+ pThreadLocation =
+ &(chipHomer->iv_coreThreadRestore[coreId][threadId].iv_threadArea[0]);
+ }
+ else
+ {
+ pThreadLocation =
+ &(chipHomer->iv_coreThreadRestore[coreId][threadId].iv_coreArea[0]);
+ }
+ }
- if( l_rc )
- {
- MY_ERR( "Core SPR lookup failed in p9_stop_init_cpureg" );
- break;
- }
+ if( ( SWIZZLE_4_BYTE(BLR_INST) == *(uint32_t*)pThreadLocation ) ||
+ ( SWIZZLE_4_BYTE(ATTN_OPCODE) == *(uint32_t*) pThreadLocation ) )
+ {
+ // table for given core id doesn't exit. It needs to be
+ // defined.
+ pSprEntryLocation = pThreadLocation;
+ }
+ else
+ {
+ // an SPR restore section for given core already exists
+ lookUpKey = genKeyForSprLookup( i_regId );
+ l_rc = lookUpSprInImage( (uint32_t*)pThreadLocation,
+ lookUpKey,
+ threadScopeReg,
+ &pSprEntryLocation,
+ l_selfRestVer );
+ }
- l_rc = updateSprEntryInImage( (uint32_t*) l_pTempLoc,
- ( CpuReg_t )g_sprRegister[l_sprIndex].iv_sprId,
- 0x00,
- INIT_SPR_REGION );
+ if( l_rc )
+ {
+ MY_ERR("Invalid or corrupt SPR entry. CoreId 0x%08x threadId ",
+ "0x%08x regId 0x%08x lookUpKey 0x%08x pThreadLocation 0x%08x"
+ , coreId, threadId, i_regId, lookUpKey, pThreadLocation );
+ break;
+ }
- if( l_rc )
- {
- MY_ERR( "Core SPR region init failed. Core %d SPR Id %d SPR Index %d",
- i_corePos, g_sprRegister[l_sprIndex].iv_sprId, l_sprIndex );
- break;
- }
+ if( ( P9_STOP_SPR_URMOR == i_regId ) && ( l_urmorFix ) )
+ {
+ l_sprValue = i_regData - URMOR_CORRECTION;
+ }
+ else
+ {
+ l_sprValue = i_regData;
+ }
- }// end else
+ l_rc = updateSprEntryInImage( (uint32_t*) pSprEntryLocation,
+ i_regId,
+ l_sprValue,
+ UPDATE_SPR_ENTRY );
- }// end for l_sprIndex
+ if( l_rc )
+ {
+ MY_ERR( " Failed to update the SPR entry of PIR 0x%08x reg"
+ "0x%08x", i_pir, i_regId );
+ break;
+ }
}
while(0);
- MY_INF( "<< p9_stop_init_cpureg" );
+ MY_INF("<< proc_stop_save_cpureg" );
+
return l_rc;
}
//-----------------------------------------------------------------------------------------------------
-StopReturnCode_t p9_stop_init_self_save( void* const i_pImage, const uint32_t i_corePos )
+StopReturnCode_t proc_stop_init_self_save( void* const i_pImage, const uint32_t i_corePos )
{
+
StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;
uint32_t* l_pSaveStart = NULL;
SmfHomerSection_t * l_pHomer = NULL;
uint32_t l_threadPos = 0;
uint32_t l_sprBitPos = 0;
uint32_t l_sprIndexAdj = 0;
- MY_INF( ">> p9_stop_init_self_save" );
+
+ MY_INF(">> proc_stop_init_self_save" );
do
{
@@ -1756,12 +1823,74 @@ StopReturnCode_t p9_stop_init_self_save( void* const i_pImage, const uint32_t i
}
while(0);
- MY_INF( "<< p9_stop_init_self_save" );
+ MY_INF("<< proc_stop_init_self_save" );
+
return l_rc;
}
+//-----------------------------------------------------------------------------------------------------
+
+StopReturnCode_t proc_stop_api_discover_capability( void* const i_pImage, uint64_t * o_inCompVector )
+{
+ StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;
+ uint64_t l_incompVector = 0;
+ uint32_t l_tempWord = 0;
+ *o_inCompVector = 0;
+
+ do
+ {
+ if( !i_pImage )
+ {
+ l_rc = STOP_SAVE_ARG_INVALID_IMG;
+ break;
+ }
+
+ l_tempWord =
+ *(uint32_t*)((uint8_t*)i_pImage + CPMR_HOMER_OFFSET + SMF_SUPPORT_SIGNATURE_OFFSET);
+
+ if( l_tempWord != SWIZZLE_4_BYTE(SMF_SELF_SIGNATURE) )
+ {
+ l_incompVector |= SMF_SUPPORT_MISSING_IN_HOMER;
+ }
+
+ l_tempWord = *(uint32_t *)((uint8_t *)i_pImage + CPMR_HOMER_OFFSET + CPMR_HEADER_SIZE );
+
+ if( l_tempWord != SWIZZLE_4_BYTE(BRANCH_BE_INST) )
+ {
+ l_incompVector |= SELF_SUPPORT_MISSING_FOR_LE_HYP;
+ }
+
+ l_tempWord = *(uint8_t *)((uint8_t *)i_pImage + CPMR_HOMER_OFFSET + CPMR_SELF_RESTORE_VER_BYTE );
+
+ if( l_tempWord < SELF_SAVE_RESTORE_VER )
+ {
+ l_incompVector |= SELF_RESTORE_VER_MISMATCH;
+ }
+
+ l_tempWord = *(uint8_t *)((uint8_t *)i_pImage + CPMR_HOMER_OFFSET + CPMR_STOP_API_VER_BYTE );
+
+ if( l_tempWord < STOP_API_CPU_SAVE_VER )
+ {
+ l_incompVector |= IPL_RUNTIME_CPU_SAVE_VER_MISMATCH;
+ }
+
+ *o_inCompVector = l_incompVector;
+
+ if( l_incompVector )
+ {
+ l_rc = STOP_SAVE_API_IMG_INCOMPATIBLE;
+ }
+
+ }while(0);
+
+ return l_rc;
+}
+
+} //extern "C"
+
#ifdef __cplusplus
} //namespace stopImageSection ends
-} //extern "C"
+//-----------------------------------------------------------------------------------------------------
+
#endif
diff --git a/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.H b/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.H
index ef0d9d1ec..983a3845d 100755
--- a/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.H
+++ b/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -70,6 +70,26 @@ typedef enum
P9_STOP_SPR_PMCR = 884, // core register
P9_STOP_SPR_HID = 1008, // core register
P9_STOP_SPR_MSR = 2000, // thread register
+
+ //enum members which are project agnostic
+ PROC_STOP_SPR_DAWR = 180, // thread register
+ PROC_STOP_SPR_CIABR = 187, // thread register
+ PROC_STOP_SPR_DAWRX = 188, // thread register
+ PROC_STOP_SPR_HSPRG0 = 304, // thread register
+ PROC_STOP_SPR_HRMOR = 313, // core register
+ PROC_STOP_SPR_LPCR = 318, // thread register
+ PROC_STOP_SPR_HMEER = 337, // core register
+ PROC_STOP_SPR_PTCR = 464, // core register
+ PROC_STOP_SPR_USPRG0 = 496, // thread register
+ PROC_STOP_SPR_USPRG1 = 497, // thread register
+ PROC_STOP_SPR_URMOR = 505, // core register
+ PROC_STOP_SPR_SMFCTRL = 511, // thread register
+ PROC_STOP_SPR_LDBAR = 850, // thread register
+ PROC_STOP_SPR_PSSCR = 855, // thread register
+ PROC_STOP_SPR_PMCR = 884, // core register
+ PROC_STOP_SPR_HID = 1008, // core register
+ PROC_STOP_SPR_MSR = 2000, // thread register
+
} CpuReg_t;
/**
@@ -94,6 +114,7 @@ typedef enum
STOP_SAVE_FAIL = 14, // for internal failure within firmware.
STOP_SAVE_SPR_ENTRY_MISSING = 15,
STOP_SAVE_SPR_BIT_POS_RESERVE = 16,
+ STOP_SAVE_API_IMG_INCOMPATIBLE = 18,
} StopReturnCode_t;
/**
@@ -110,7 +131,20 @@ typedef enum
P9_STOP_SCOM_RESET = 6,
P9_STOP_SCOM_OR_APPEND = 7,
P9_STOP_SCOM_AND_APPEND = 8,
- P9_STOP_SCOM_OP_MAX = 9
+ P9_STOP_SCOM_OP_MAX = 9,
+
+ //enum members which are project agnostic
+ PROC_STOP_SCOM_OP_MIN = 0,
+ PROC_STOP_SCOM_APPEND = 1,
+ PROC_STOP_SCOM_REPLACE = 2,
+ PROC_STOP_SCOM_OR = 3,
+ PROC_STOP_SCOM_AND = 4,
+ PROC_STOP_SCOM_NOOP = 5,
+ PROC_STOP_SCOM_RESET = 6,
+ PROC_STOP_SCOM_OR_APPEND = 7,
+ PROC_STOP_SCOM_AND_APPEND = 8,
+ PROC_STOP_SCOM_OP_MAX = 9,
+
} ScomOperation_t;
/**
@@ -123,7 +157,15 @@ typedef enum
P9_STOP_SECTION_EQ_SCOM = 2,
P9_STOP_SECTION_L2 = 3,
P9_STOP_SECTION_L3 = 4,
- P9_STOP_SECTION_MAX = 5
+ P9_STOP_SECTION_MAX = 5,
+
+ //enum members which are project agnostic
+ PROC_STOP_SECTION_MIN = 0,
+ PROC_STOP_SECTION_CORE_SCOM = 1,
+ PROC_STOP_SECTION_EQ_SCOM = 2,
+ PROC_STOP_SECTION_L2 = 3,
+ PROC_STOP_SECTION_L3 = 4,
+ PROC_STOP_SECTION_MAX = 5,
} ScomSection_t;
/**
@@ -157,6 +199,21 @@ typedef enum
BIT_POS_USPRG1 = 30,
} SprBitPositionList_t;
+/**
+ * @brief List of major incompatibilities between API version.
+ * @note STOP APIs assumes a specific HOMER layout, certain
+ * level of CME-SGPE hcode and certain version of self-save restore
+ * binary. A mismatch can break STOP function.
+ */
+
+typedef enum
+{
+ SMF_SUPPORT_MISSING_IN_HOMER = 0x01,
+ SELF_SUPPORT_MISSING_FOR_LE_HYP = 0x02,
+ IPL_RUNTIME_CPU_SAVE_VER_MISMATCH = 0x04,
+ SELF_RESTORE_VER_MISMATCH = 0x08,
+} VersionIncompList_t;
+
#ifdef __cplusplus
extern "C" {
@@ -227,13 +284,87 @@ p9_stop_save_cpureg_control( void* i_pImage, const uint64_t i_pir,
* @brief initializes self-save region with specific instruction.
* @param[in] i_pImage start address of homer image of P9 chip.
* @param[in] i_corePos physical core's relative position within processor chip.
- * @return STOP_SAVE_SUCCESS SUCCESS if self-save is initialized successfully,
+ * @return STOP_SAVE_SUCCESS if self-save is initialized successfully,
* error code otherwise.
* @note API is intended only for use case of HOMER build. There is no explicit
* effort to support any other use case.
*/
StopReturnCode_t p9_stop_init_self_save( void* const i_pImage, const uint32_t i_corePos );
+/**
+ * @brief creates SCOM restore entry for a given scom adress in HOMER.
+ * @param i_pImage points to start address of HOMER image.
+ * @param i_scomAddress address associated with SCOM restore entry.
+ * @param i_scomData data associated with SCOM restore entry.
+ * @param i_operation operation type requested for API.
+ * @param i_section section of HOMER in which restore entry needs to be created.
+ * @return STOP_SAVE_SUCCESS if API succeeds, error code otherwise.
+ * @note It is an API for creating SCOM restore entry in HOMER. It is agnostic to
+ * generation of POWER processor.
+ */
+
+StopReturnCode_t proc_stop_save_scom( void* const i_pImage,
+ const uint32_t i_scomAddress,
+ const uint64_t i_scomData,
+ const ScomOperation_t i_operation,
+ const ScomSection_t i_section );
+
+/**
+ * @brief initializes self save restore region of HOMER.
+ * @param[in] i_pImage points to base of HOMER image.
+ * @param[in] i_corePos position of the physical core.
+ * @return STOP_SAVE_SUCCESS if API succeeds, error code otherwise.
+ * @note It is an API for initializing self restore region in HOMER. It is agnostic to
+ * generation of POWER processor.
+ */
+StopReturnCode_t proc_stop_init_cpureg( void* const i_pImage, const uint32_t i_corePos );
+
+/**
+ * @brief enables self save for a given set of SPRs
+ * @param[in] i_pImage points to start address of HOMER image.
+ * @param[in] i_pir PIR value associated with core and thread.
+ * @param[in] i_saveRegVector bit vector representing the SPRs that needs to be self saved.
+ * @return STOP_SAVE_SUCCESS if API succeeds, error code otherwise.
+ * @note It is an API for enabling self save of SPRs and it is agnostic to
+ * generation of POWER processor.
+ */
+StopReturnCode_t proc_stop_save_cpureg_control( void* i_pImage,
+ const uint64_t i_pir,
+ const uint32_t i_saveRegVector );
+
+/**
+ * @brief creates an SPR restore entry in HOMER
+ * @param[in] i_pImage points to start address of HOMER image.
+ * @param[in] i_pir PIR value associated with core and thread.
+ * @param[in] i_saveRegVector bit vector representing the SPRs that needs to be self saved.
+ * @return STOP_SAVE_SUCCESS if API succeeds, error code otherwise.
+ * @note It is an API for enabling self save of SPRs and it is agnostic to
+ * generation of POWER processor.
+ */
+StopReturnCode_t proc_stop_save_cpureg( void* const i_pImage,
+ const CpuReg_t i_regId,
+ const uint64_t i_regData,
+ const uint64_t i_pir );
+
+/**
+ * @brief initializes self-save region with specific instruction.
+ * @param[in] i_pImage start address of homer image.
+ * @param[in] i_corePos physical core's relative position within processor chip.
+ * @return STOP_SAVE_SUCCESS if self-save is initialized successfully,
+ * error code otherwise.
+ * @note API is project agnostic and is intended only for use case of HOMER build.
+ * There is no explicit effort to support any other use case.
+ */
+StopReturnCode_t proc_stop_init_self_save( void* const i_pImage, const uint32_t i_corePos );
+
+/**
+ * @brief verifies if API is compatible of current HOMER image.
+ * @param[in] i_pImage points to the start of HOMER image of P9 chip.
+ * @param[out] o_inCompVector list of incompatibilities found.
+ * @return STOP_SAVE_SUCCESS if if API succeeds, error code otherwise.
+ */
+StopReturnCode_t proc_stop_api_discover_capability( void* const i_pImage, uint64_t* o_inCompVector );
+
#ifdef __cplusplus
} // extern "C"
}; // namespace stopImageSection ends
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/chip_ec_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/chip_ec_attributes.xml
index 1c2df1354..1a9b27e47 100644
--- a/src/import/chips/p9/procedures/xml/attribute_info/chip_ec_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/chip_ec_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2016,2019 -->
+<!-- Contributors Listed Below - COPYRIGHT 2016,2020 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -116,6 +116,40 @@
</attribute>
<!-- ********************************************************************* -->
<attribute>
+ <id>ATTR_CHIP_EC_FEATURE_CP_FILTER_100MHZ</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ True where CP refclock is expected to be 100 MHz
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_AXONE</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
+ <!-- ********************************************************************* -->
+ <attribute>
+ <id>ATTR_CHIP_EC_FEATURE_I2CM_INTERNAL_CLK_DIV2</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ I2CM internal clock divider is div2 , not div4
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_AXONE</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
+ <!-- ********************************************************************* -->
+ <attribute>
<id>ATTR_CHIP_EC_FEATURE_NOT_DD1_FBC_AND_ALINK</id>
<targetType>TARGET_TYPE_PROC_CHIP, TARGET_TYPE_PROC_CHIP</targetType>
<description>
@@ -149,6 +183,25 @@
</attribute>
<!-- ********************************************************************* -->
<attribute>
+ <id>ATTR_CHIP_EC_FEATURE_XBUS_COMPRESSION_WORKAROUND</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ Modifies calibration gain targets and moves common mode to improve
+ DAC linearity and compression.
+ Enable only for Axone.
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_AXONE</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
+ <!-- ********************************************************************* -->
+ <attribute>
<id>ATTR_CHIP_EC_FEATURE_NO_NPU2_FIR</id>
<targetType>TARGET_TYPE_PROC_CHIP, TARGET_TYPE_PROC_CHIP</targetType>
<description>
@@ -1212,13 +1265,6 @@
<test>GREATER_THAN_OR_EQUAL</test>
</ec>
</chip>
- <chip>
- <name>ENUM_ATTR_NAME_AXONE</name>
- <ec>
- <value>0x10</value>
- <test>GREATER_THAN_OR_EQUAL</test>
- </ec>
- </chip>
</chipEcFeature>
</attribute>
<!-- ******************************************************************** -->
@@ -3118,6 +3164,23 @@
</chip>
</chipEcFeature>
</attribute>
+ <!-- ********************************************************************* -->
+<attribute>
+ <id>ATTR_CHIP_EC_FEATURE_NMMU_AX1_ISS768_FIX_DIS</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ NMMU disables seg fault generation for radix access to DR=1, HV=1 with lpid !=0.
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_AXONE</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
<!-- ******************************************************************** -->
<attribute>
<id>ATTR_CHIP_EC_FEATURE_NMMU_PWC_DIS_DD2</id>
@@ -3311,10 +3374,11 @@
<!-- ******************************************************************** -->
<attribute>
<id>ATTR_CHIP_EC_FEATURE_HW438727</id>
- <targetType>TARGET_TYPE_PROC_CHIP,TARGET_TYPE_PROC_CHIP</targetType>
+ <targetType>TARGET_TYPE_PROC_CHIP,TARGET_TYPE_PROC_CHIP,TARGET_TYPE_PROC_CHIP</targetType>
<description>
- Anything NDD20+,CDD10+: Disable clockgating to allow correct
- errors to be reported in ODL c_err_rpt and other error capture
+ Anything NDD20+,CDD10+,ADD10+: Disable clockgating to allow correct
+ errors to be reported in ODL c_err_rpt and other error capture.
+ Axone see: HW481539
</description>
<chipEcFeature>
<chip>
@@ -3331,6 +3395,13 @@
<test>GREATER_THAN_OR_EQUAL</test>
</ec>
</chip>
+ <chip>
+ <name>ENUM_ATTR_NAME_AXONE</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
</chipEcFeature>
</attribute>
<!-- ******************************************************************** -->
@@ -5055,6 +5126,37 @@
</attribute>
<!-- ******************************************************************** -->
<attribute>
+ <id>ATTR_CHIP_EC_FEATURE_HW499047</id>
+ <targetType>TARGET_TYPE_PROC_CHIP, TARGET_TYPE_PROC_CHIP, TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ HW499047 - SMT2 prefetch issue
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_NIMBUS</name>
+ <ec>
+ <value>0x22</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ <chip>
+ <name>ENUM_ATTR_NAME_CUMULUS</name>
+ <ec>
+ <value>0x11</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ <chip>
+ <name>ENUM_ATTR_NAME_AXONE</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
+ <!-- ******************************************************************** -->
+ <attribute>
<id>ATTR_CHIP_EC_FEATURE_HW420860</id>
<targetType>TARGET_TYPE_PROC_CHIP, TARGET_TYPE_PROC_CHIP</targetType>
<description>
@@ -5329,7 +5431,7 @@
<!-- ******************************************************************** -->
<attribute>
<id>ATTR_CHIP_EC_FEATURE_CORE_SMF_SETUP</id>
- <targetType>TARGET_TYPE_PROC_CHIP, TARGET_TYPE_PROC_CHIP</targetType>
+ <targetType>TARGET_TYPE_PROC_CHIP, TARGET_TYPE_PROC_CHIP, TARGET_TYPE_PROC_CHIP</targetType>
<description>
Core inits for enabling secure memory facility
</description>
@@ -6926,6 +7028,13 @@
<test>GREATER_THAN_OR_EQUAL</test>
</ec>
</chip>
+ <chip>
+ <name>ENUM_ATTR_NAME_AXONE</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
</chipEcFeature>
</attribute>
@@ -7749,7 +7858,24 @@
</chip>
</chipEcFeature>
</attribute>
-
+ <!-- ******************************************************************** -->
+ <attribute>
+ <id>ATTR_CHIP_EC_FEATURE_AXONE_FBC_SETTINGS</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ Fabric settings that are in Axone only
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_AXONE</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
+ <!-- ******************************************************************** -->
<attribute>
<id>ATTR_CHIP_EC_FEATURE_HW412371</id>
<targetType>TARGET_TYPE_PROC_CHIP, TARGET_TYPE_PROC_CHIP</targetType>
@@ -8011,6 +8137,7 @@
</chip>
</chipEcFeature>
</attribute>
+
<!-- ******************************************************************** -->
<attribute>
<id>ATTR_CHIP_EC_FEATURE_HW426816</id>>
@@ -8042,6 +8169,30 @@
</chip>
</chipEcFeature>
</attribute>
+ <!-- ******************************************************************** -->
+ <attribute>
+ <id>ATTR_CHIP_EC_FEATURE_HW515286</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ Mask Particular type of NPU OTL UE to prevent unwanted xstops and/or fences.
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_NIMBUS</name>
+ <ec>
+ <value>0x20</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ <chip>
+ <name>ENUM_ATTR_NAME_CUMULUS</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
<!-- ******************************************************************** -->
<!-- NOTE: This attribute is used in an initfile to qualify the contents
of a GPTR ring. There is special processing in place to move the
@@ -8848,4 +8999,156 @@
</chipEcFeature>
</attribute>
<!-- ******************************************************************** -->
+ <attribute>
+ <id>ATTR_CHIP_EC_FEATURE_HW476692</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ HW476692
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_AXONE</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
+ <!-- ******************************************************************** -->
+ <attribute>
+ <id>ATTR_CHIP_EC_FEATURE_AXONE_GEMINI_OVERRUN</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ Setup Memory controller to hold back too many operations from being passed to Gemini
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_AXONE</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
+ <!-- ******************************************************************** -->
+ <attribute>
+ <id>ATTR_CHIP_EC_FEATURE_AXONE_MMU</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ Bumpy Toothpaste fix not enabled in Axone
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_AXONE</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
+ <!-- ******************************************************************** -->
+ <attribute>
+ <id>ATTR_CHIP_EC_FEATURE_AXONE_HW441771</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ Bumpy Toothpaste fix not enabled in Axone
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_AXONE</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
+ <!-- ******************************************************************** -->
+ <attribute>
+ <id>ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE</id>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ <description>
+ The DL half width backoff enable bit in DL_CONFIG0_CFG (bit 47)
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_EXPLORER</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
+ <!-- ******************************************************************** -->
+ <attribute>
+ <id>ATTR_CHIP_EC_FEATURE_GEMINI_MENTERP_WORKAROUND</id>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ <description>
+ Bypass MENTERP register read/writes on gemini due to FW bug
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_GEMINI</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
+ <!-- ******************************************************************** -->
+ <attribute>
+ <id>ATTR_CHIP_EC_FEATURE_AXONE_GEMINI_MDI_ERROR</id>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ <description>
+ Setup Memory controller to always deliver MDI=1 by default due to Gemini bug
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_GEMINI</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
+ <!-- ******************************************************************** -->
+ <attribute>
+ <id>ATTR_CHIP_EC_FEATURE_GEMINI_OMI_SETUP_CONFIG_WORKAROUND</id>
+ <targetType>TARGET_TYPE_OCMB_CHIP</targetType>
+ <description>
+ Setup config registers for gemini in exp_omi_setup
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_GEMINI</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
+ <!-- ******************************************************************** -->
+ <attribute>
+ <id>ATTR_CHIP_EC_FEATURE_AXONE_HW476620</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ Sim fail defect number HW476620
+ </description>
+ <chipEcFeature>
+ <chip>
+ <name>ENUM_ATTR_NAME_AXONE</name>
+ <ec>
+ <value>0x10</value>
+ <test>GREATER_THAN_OR_EQUAL</test>
+ </ec>
+ </chip>
+ </chipEcFeature>
+ </attribute>
</attributes>
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/freq_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/freq_attributes.xml
index 6f8b366f1..a64167bb3 100644
--- a/src/import/chips/p9/procedures/xml/attribute_info/freq_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/freq_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2015,2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -39,6 +39,17 @@
</attribute>
<!-- ********************************************************************* -->
<attribute>
+ <id>ATTR_FREQ_DPLL_REFCLOCK_KHZ</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ The frequency of the processor DPLL refclock in kHz.
+ </description>
+ <valueType>uint32</valueType>
+ <platInit/>
+ <default>133333</default>
+ </attribute>
+ <!-- ********************************************************************* -->
+ <attribute>
<id>ATTR_FREQ_MEM_REFCLOCK</id>
<targetType>TARGET_TYPE_SYSTEM</targetType>
<description>
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml
index 0a3c2e2b4..fd10554ce 100644
--- a/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml
@@ -1178,18 +1178,6 @@
</attribute>
<attribute>
- <id>ATTR_MSS_MEM_PORT_POS_OF_FAIL_THROTTLE</id>
- <targetType>TARGET_TYPE_SYSTEM</targetType>
- <description>
- This is the fapi position of the port that failed to calculate
- memory throttles given the passed in watt target and or utilization
- </description>
- <initToZero></initToZero>
- <valueType>uint64</valueType>
- <writeable/>
- </attribute>
-
- <attribute>
<id>ATTR_MSS_MEM_M_DRAM_CLOCKS</id>
<targetType>TARGET_TYPE_MCS</targetType>
<description>
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
index 078f79284..ae6bbb47e 100755
--- a/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
@@ -24,6 +24,22 @@
<!-- IBM_PROLOG_END_TAG -->
<attributes>
+ <attribute>
+ <id>ATTR_MSS_MRW_NVDIMM_SLOT_POSITION</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ The position of a dimm is based on which mca it is
+ associated with and which drop behind that mca, with
+ 16 dimms possible per processor socket. The formula is:
+ [processor position with no gaps, i.e. 0,1,2,3]*16 +
+ [mca position on this processor * 2] + [dimm location behind this mca]
+ </description>
+ <valueType>uint8</valueType>
+ <default>0xFF</default>
+ <platInit/>
+ <mrwHide/>
+ <mssAccessorName>mrw_nvdimm_slot_position</mssAccessorName>
+ </attribute>
<attribute>
<id>ATTR_MSS_MRW_UNSUPPORTED_RANK_CONFIG</id>
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/nest_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/nest_attributes.xml
index 2967e614a..7a2c4aa95 100644
--- a/src/import/chips/p9/procedures/xml/attribute_info/nest_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/nest_attributes.xml
@@ -50,15 +50,20 @@
<id>ATTR_FREQ_MCA_MHZ</id>
<targetType>TARGET_TYPE_SYSTEM</targetType>
<description>
- The frequency of the memory controller channel. In synchronous mode,
- this is equivalent to ATTR_FREQ_PB_MHZ. This may be independently set
- per pair of memory channels if operating in asynchronous mode,
- but this configuration is not anticipated. This clock drives the MCU queues,
- and all the associated logic that drives the inputs to the DMI and reads
- its outputs.
+ The frequency of the memory controller channel.
+ NIMBUS: In synchronous mode, this is equivalent to ATTR_FREQ_PB_MHZ. This
+ may be independently set per pair of memory channels if operating in
+ asynchronous mode, but this configuration is not anticipated.
+ CUMULUS: This clock drives the MCU queues, and all the associated logic
+ that drives the inputs to the DMI and reads its outputs.
+ AXONE: This is tied to the OMI frequency (MCAx16=OMI).
</description>
<valueType>uint32</valueType>
<enum>
+ 1200 = 1200,
+ 1333 = 1333,
+ 1466 = 1466,
+ 1600 = 1600,
2000 = 2000,
2400 = 2400
</enum>
@@ -66,6 +71,38 @@
</attribute>
<!-- ********************************************************************** -->
<attribute>
+ <id>ATTR_FREQ_OMI_MHZ</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ The frequency of the OMI channel.
+ </description>
+ <valueType>uint32</valueType>
+ <enum>
+ 19200 = 19200,
+ 21330 = 21330,
+ 23460 = 23460,
+ 25600 = 25600
+ </enum>
+ <platInit/>
+ <writeable/>
+</attribute>
+<!-- ********************************************************************** -->
+<attribute>
+ <id>ATTR_OMI_PLL_VCO</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ Should the 20GHz or the 26GHz OMI PLL VCO be used.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>
+ 20G = 0,
+ 26G = 1
+ </enum>
+ <platInit/>
+ <writeable/>
+</attribute>
+<!-- ********************************************************************** -->
+<attribute>
<id>ATTR_FREQ_O_MHZ</id>
<targetType>TARGET_TYPE_PROC_CHIP</targetType>
<description>
@@ -312,6 +349,7 @@
1 = CAPI 2.0
2 = NV 2.0
3 = OPENCAPI
+ 4 = Not Wired
Provided by the MRW.
</description>
<valueType>uint8</valueType>
@@ -319,7 +357,8 @@
SMP = 0x0,
CAPI = 0x1,
NV = 0x2,
- OCAPI = 0x3
+ OCAPI = 0x3,
+ NOT_WIRED=0x4
</enum>
<platInit/>
</attribute>
@@ -349,12 +388,16 @@
0 = default = SMP
1 = CAPI 2.0
2 = NV 2.0
+ 3 = OPENCAPI
+ 4 = Not Wired
</description>
<valueType>uint8</valueType>
<enum>
SMP = 0x0,
CAPI = 0x1,
- NV = 0x2
+ NV = 0x2,
+ OCAPI = 0x3,
+ NOT_WIRED=0x4
</enum>
<array>4</array>
<writeable/>
@@ -1069,11 +1112,11 @@
An 8 bit vector that would be a designation of which MC (Nimbus MCA or
Cumulus MI) are involved in the group.
So the bits would represent
- Nimbus Cumulus
- Bit 0 MCA0 MI0
- Bit 1 MCA1 MI1
+ Nimbus Cumulus Axone
+ Bit 0 MCA0 MI0 MCC0
+ Bit 1 MCA1 MI1 MCC1
.....
- Bit 7 MCA7 MI7
+ Bit 7 MCA7 MI7 MCC7
Set by p9_mss_eff_grouping
</description>
<valueType>uint8</valueType>
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/p9_io_obus_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/p9_io_obus_attributes.xml
index fc9efabf5..849270429 100644
--- a/src/import/chips/p9/procedures/xml/attribute_info/p9_io_obus_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/p9_io_obus_attributes.xml
@@ -93,6 +93,22 @@
</attribute>
<!-- ********************************************************************** -->
<attribute>
+ <id>ATTR_IO_OBUS_LINK_SPARE_MARK</id>
+ <targetType>TARGET_TYPE_OBUS</targetType>
+ <description>
+ Used to save indication that a spare lane has been deployed during
+ runtime link recovery retrain sequence. This sparing will be posted
+ into the DL FIR after all other FIR clearing/unmasking has been
+ performed in the link recovery sequence. Index 0 tracks the even half
+ link, index 1 the odd half link.
+ </description>
+ <array>2</array>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <initToZero/>
+</attribute>
+<!-- ********************************************************************** -->
+<attribute>
<id>ATTR_IO_OBUS_LANE_PDWN</id>
<targetType>TARGET_TYPE_OBUS</targetType>
<description>
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/p9_setup_bars_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/p9_setup_bars_attributes.xml
index 920e0dcf1..88bd4192b 100644
--- a/src/import/chips/p9/procedures/xml/attribute_info/p9_setup_bars_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/p9_setup_bars_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2015,2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -167,6 +167,20 @@
<mrwHide/>
</attribute>
<!-- ********************************************************************* -->
+ <attribute>
+ <id>ATTR_PROC_NPU_MMIO_BAR_ENABLE</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>NPU MMIO (stack2) BAR enable
+ creator: platform
+ consumer: p9_setup_bars
+ firmware notes: none
+ </description>
+ <valueType>uint8</valueType>
+ <enum>DISABLE = 0x0, ENABLE = 0x1</enum>
+ <platInit/>
+ <mrwHide/>
+ </attribute>
+ <!-- ********************************************************************* -->
<attribute>
<id>ATTR_PROC_NPU_MMIO_BAR_BASE_ADDR_OFFSET</id>
<targetType>TARGET_TYPE_SYSTEM</targetType>
@@ -185,9 +199,71 @@
</attribute>
<!-- ********************************************************************* -->
<attribute>
- <id>ATTR_PROC_NPU_MMIO_BAR_ENABLE</id>
+ <id>ATTR_PROC_NPU0_MMIO_BAR_ENABLE</id>
<targetType>TARGET_TYPE_PROC_CHIP</targetType>
- <description>NPU MMIO (stack2) BAR enable
+ <description>NPU0 MMIO BAR enable
+ creator: platform
+ consumer: p9_setup_bars
+ firmware notes: none
+ </description>
+ <valueType>uint8</valueType>
+ <enum>DISABLE = 0x0, ENABLE = 0x1</enum>
+ <platInit/>
+ <mrwHide/>
+ </attribute>
+ <!-- ********************************************************************* -->
+ <attribute>
+ <id>ATTR_PROC_NPU0_MMIO_BAR_BASE_ADDR_OFFSET</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>NPU MMIO BAR
+ creator: platform
+ consumer: p9_setup_bars
+ firmware notes:
+ Defines 16MB range mapped to NPU0 registers
+ Attribute holds offset (relative to chip MMIO origin) to program into
+ chip address range field of BAR -- Bits 15:39 of the RA
+ (excludes system/memory select/group/chip fields)
+ </description>
+ <valueType>uint64</valueType>
+ <platInit/>
+ <mrwHide/>
+ </attribute>
+ <!-- ********************************************************************* -->
+ <attribute>
+ <id>ATTR_PROC_NPU1_MMIO_BAR_ENABLE</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>NPU1 MMIO BAR enable
+ creator: platform
+ consumer: p9_setup_bars
+ firmware notes: none
+ </description>
+ <valueType>uint8</valueType>
+ <enum>DISABLE = 0x0, ENABLE = 0x1</enum>
+ <platInit/>
+ <mrwHide/>
+ </attribute>
+ <!-- ********************************************************************* -->
+ <attribute>
+ <id>ATTR_PROC_NPU1_MMIO_BAR_BASE_ADDR_OFFSET</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>NPU1 MMIO BAR
+ creator: platform
+ consumer: p9_setup_bars
+ firmware notes:
+ Defines 16MB range mapped to NPU1 registers
+ Attribute holds offset (relative to chip MMIO origin) to program into
+ chip address range field of BAR -- Bits 15:39 of the RA
+ (excludes system/memory select/group/chip fields)
+ </description>
+ <valueType>uint64</valueType>
+ <platInit/>
+ <mrwHide/>
+ </attribute>
+ <!-- ********************************************************************* -->
+ <attribute>
+ <id>ATTR_PROC_NPU2_MMIO_BAR_ENABLE</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>NPU2 MMIO BAR enable
creator: platform
consumer: p9_setup_bars
firmware notes: none
@@ -199,6 +275,104 @@
</attribute>
<!-- ********************************************************************* -->
<attribute>
+ <id>ATTR_PROC_NPU2_MMIO_BAR_BASE_ADDR_OFFSET</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>NPU2 MMIO BAR
+ creator: platform
+ consumer: p9_setup_bars
+ firmware notes:
+ Defines 16MB range mapped to NPU2 registers
+ Attribute holds offset (relative to chip MMIO origin) to program into
+ chip address range field of BAR -- Bits 15:39 of the RA
+ (excludes system/memory select/group/chip fields)
+ </description>
+ <valueType>uint64</valueType>
+ <platInit/>
+ <mrwHide/>
+ </attribute>
+ <!-- ********************************************************************** -->
+ <attribute>
+ <id>ATTR_PROC_NPU0_PRI_CONFIG</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ NPU0 NTL Private Register Interface (PRI) Configuration register settings
+ Array 0 = SM0 value
+ 1 = SM1 value
+ 2 = SM2 value
+ 3 = SM3 value
+ Bits of values:
+ 0 PRI_CONFIG_DISABLE: Disable
+ 1 Disable (this will disable NTL from decoding the NDL register space)
+ 1:2 PRI_CONFIG_NDL: NDL indication sent in the PRI Read/Write access
+ 00 = NDL 0
+ 01 = NDL 1
+ 10 = NDL 2
+ 11 = NDL 3
+ 3:4 PRI_CONFIG_PHY: Indicates if NTL should decode a PHY register space
+ 00 = Decode PHY0 register space
+ 01 = Decode PHY1 register space
+ 1- = Do not decode any PHY register space
+ </description>
+ <valueType>uint8</valueType>
+ <array>4</array>
+ <platInit/>
+ </attribute>
+ <!-- ********************************************************************** -->
+ <attribute>
+ <id>ATTR_PROC_NPU1_PRI_CONFIG</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ NPU1 NTL Private Register Interface (PRI) Configuration register settings
+ Array 0 = SM0 value
+ 1 = SM1 value
+ 2 = SM2 value
+ 3 = SM3 value
+ Bits of values:
+ 0 PRI_CONFIG_DISABLE: Disable
+ 1 Disable (this will disable NTL from decoding the NDL register space)
+ 1:2 PRI_CONFIG_NDL: NDL indication sent in the PRI Read/Write access
+ 00 = NDL 0
+ 01 = NDL 1
+ 10 = NDL 2
+ 11 = NDL 3
+ 3:4 PRI_CONFIG_PHY: Indicates if NTL should decode a PHY register space
+ 00 = Decode PHY0 register space
+ 01 = Decode PHY1 register space
+ 1- = Do not decode any PHY register space
+ </description>
+ <valueType>uint8</valueType>
+ <array>4</array>
+ <platInit/>
+ </attribute>
+ <!-- ********************************************************************** -->
+ <attribute>
+ <id>ATTR_PROC_NPU2_PRI_CONFIG</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ NPU2 NTL Private Register Interface (PRI) Configuration register settings
+ Array 0 = SM0 value
+ 1 = SM1 value
+ 2 = SM2 value
+ 3 = SM3 value
+ Bits of values:
+ 0 PRI_CONFIG_DISABLE: Disable
+ 1 Disable (this will disable NTL from decoding the NDL register space)
+ 1:2 PRI_CONFIG_NDL: NDL indication sent in the PRI Read/Write access
+ 00 = NDL 0
+ 01 = NDL 1
+ 10 = NDL 2
+ 11 = NDL 3
+ 3:4 PRI_CONFIG_PHY: Indicates if NTL should decode a PHY register space
+ 00 = Decode PHY0 register space
+ 01 = Decode PHY1 register space
+ 1- = Do not decode any PHY register space
+ </description>
+ <valueType>uint8</valueType>
+ <array>4</array>
+ <platInit/>
+ </attribute>
+ <!-- ********************************************************************* -->
+ <attribute>
<id>ATTR_PROC_PSI_BRIDGE_BAR_ENABLE</id>
<targetType>TARGET_TYPE_PROC_CHIP</targetType>
<description>PSI Bridge BAR enable
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/p9a_io_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/p9a_io_attributes.xml
index 70ba79239..dd982c93f 100644
--- a/src/import/chips/p9/procedures/xml/attribute_info/p9a_io_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/p9a_io_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2018,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -31,7 +31,7 @@
</targetType>
<description>
An OMI target's relative logical postion to its OMIC parent target.
-
+
pos | DL_GROUP_POS
-----+--------------
4 | 0
@@ -48,7 +48,7 @@
15 | 0
10 | 1
11 | 2
- 8 | 0
+ 8 | 0
9 | 1
</description>
@@ -63,7 +63,7 @@
TARGET_TYPE_OMI
</targetType>
<description>
- An OMI target's logical DL number
+ An OMI target's logical DL number
pos | DL_NUM
-----+--------------
@@ -90,4 +90,17 @@
<default>0xFF</default><!-- Ensures platform explicitly puts a valid number in here -->
</attribute>
<!-- ******************************************************************************** -->
+ <attribute>
+ <id>ATTR_OCMB_COUNTER</id>
+ <targetType>
+ TARGET_TYPE_OCMB_CHIP
+ </targetType>
+ <description>
+ Tracks the sequence id for OCMB command transactions. The platform is
+ expected to guarantee a unique value on each read.
+ </description>
+ <valueType>uint32</valueType>
+ <platInit/>
+ <default>0</default>
+ </attribute>
</attributes>
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/p9a_omi_train.xml b/src/import/chips/p9/procedures/xml/attribute_info/p9a_omi_train.xml
new file mode 100644
index 000000000..b1eafcf0a
--- /dev/null
+++ b/src/import/chips/p9/procedures/xml/attribute_info/p9a_omi_train.xml
@@ -0,0 +1,55 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/import/chips/p9/procedures/xml/attribute_info/p9a_omi_train.xml $ -->
+<!-- -->
+<!-- OpenPOWER HostBoot Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2019 -->
+<!-- [+] International Business Machines Corp. -->
+<!-- -->
+<!-- -->
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); -->
+<!-- you may not use this file except in compliance with the License. -->
+<!-- You may obtain a copy of the License at -->
+<!-- -->
+<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
+<!-- -->
+<!-- Unless required by applicable law or agreed to in writing, software -->
+<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
+<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -->
+<!-- implied. See the License for the specific language governing -->
+<!-- permissions and limitations under the License. -->
+<!-- -->
+<!-- IBM_PROLOG_END_TAG -->
+<!-- -->
+<!-- @file p9a_omi_train.xml -->
+<!-- @brief Attribute xml for p9a_omi_train -->
+<!-- -->
+<!-- *HWP HWP Owner: Devon Baughen <devon.baughen1@ibm.com> -->
+<!-- *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> -->
+<!-- *HWP FW Owner: Daniel Crowell <dcrowell@us.ibm.com> -->
+<!-- *HWP Team: Memory -->
+<!-- *HWP Level: 2 -->
+<!-- *HWP Consumed by: FSP:HB -->
+<!-- -->
+
+<attributes>
+
+ <attribute>
+ <id>ATTR_OMI_DL_LN_REV_ENABLE</id>
+ <targetType>TARGET_TYPE_OMI</targetType>
+ <description>
+ The DL lane reversible enable bit in DL_CONFIG0_CFG (bit 38)
+ </description>
+ <valueType>uint8</valueType>
+ <enum>
+ ENABLED = 0x01,
+ DISABLED = 0x00
+ </enum>
+ <default>0x01</default>
+ <platInit/>
+ <mssAccessorName>omi_dl_ln_rev_enable</mssAccessorName>
+ </attribute>
+
+</attributes>
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/pervasive_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/pervasive_attributes.xml
index 92286ce9a..c77fbcb99 100755
--- a/src/import/chips/p9/procedures/xml/attribute_info/pervasive_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/pervasive_attributes.xml
@@ -753,7 +753,10 @@
<attribute>
<id>ATTR_MC_PLL_BUCKET</id>
<targetType>TARGET_TYPE_SYSTEM</targetType>
- <description>MC pll bucket selection in async mode for Cumulus</description>
+ <description>MC pll bucket selection.
+ See MEM_PLL_FREQ_LIST for Cumulus.
+ See OMI_PLL_FREQ_LIST for Axone.
+ </description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/pm_plat_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/pm_plat_attributes.xml
index ef8672bf3..a8d4a08f6 100644
--- a/src/import/chips/p9/procedures/xml/attribute_info/pm_plat_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/pm_plat_attributes.xml
@@ -1515,7 +1515,7 @@
</description>
<valueType>uint8</valueType>
<initToZero/>
- <array>61</array>
+ <array>135</array>
<platInit/>
</attribute>
<!-- ********************************************************************* -->
@@ -2265,6 +2265,7 @@
</enum>
<platInit/>
<initToZero/>
+ <mrwHide/>
</attribute>
<!-- ********************************************************************* -->
<attribute>
@@ -2286,6 +2287,7 @@
</enum>
<platInit/>
<initToZero/>
+ <mrwHide/>
</attribute>
<!-- ********************************************************************* -->
<attribute>
@@ -2303,6 +2305,7 @@
<valueType>uint64</valueType>
<platInit/>
<initToZero/>
+ <mrwHide/>
</attribute>
<!-- ********************************************************************* -->
<attribute>
diff --git a/src/import/chips/p9/procedures/xml/error_info/ddimm_get_efd.xml b/src/import/chips/p9/procedures/xml/error_info/ddimm_get_efd.xml
index f4c7862fb..cb2a65d7f 100644..100755
--- a/src/import/chips/p9/procedures/xml/error_info/ddimm_get_efd.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/ddimm_get_efd.xml
@@ -159,7 +159,6 @@
<description>DMB manufacturer ID is not the expected ID and
therefore not supported.</description>
<ffdc>DMB_MFG_ID</ffdc>
- <ffdc>EXPECTED</ffdc>
<ffdc>OCMB_CHIP_TARGET</ffdc>
<ffdc>VPD_TYPE</ffdc>
<ffdc>DDR_TYPE</ffdc>
@@ -192,7 +191,6 @@
<description>DMB revision is not the expected revision and
therefore not supported.</description>
<ffdc>DMB_REVISION</ffdc>
- <ffdc>EXPECTED</ffdc>
<ffdc>OCMB_CHIP_TARGET</ffdc>
<ffdc>VPD_TYPE</ffdc>
<ffdc>DDR_TYPE</ffdc>
@@ -221,6 +219,29 @@
</hwpError>
<!-- ********************************************************************* -->
<hwpError>
+ <rc>RC_DDIMM_UNSUPPORTED_FREQUENCY</rc>
+ <description>Chosen frequency not supported by this DDIMM</description>
+ <ffdc>UNSUPPORTED_FREQ</ffdc>
+ <ffdc>SUPPORTED_FREQS</ffdc>
+ <ffdc>OCMB_CHIP_TARGET</ffdc>
+ <ffdc>VPD_TYPE</ffdc>
+ <ffdc>DDR_TYPE</ffdc>
+ <!-- This is always a code bug. -->
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <!-- It could also be bogus SPD content -->
+ <callout>
+ <hw>
+ <hwid>VPD_PART</hwid>
+ <refTarget>OCMB_CHIP_TARGET</refTarget>
+ </hw>
+ <priority>LOW</priority>
+ </callout>
+ </hwpError>
+ <!-- ********************************************************************* -->
+ <hwpError>
<rc>RC_DDIMM_GET_EFD_UNSUPPORTED_FREQUENCY</rc>
<description>Invalid Frequency. Valid values are 12800, 14930, 17060,
19200, 21330, 23460 and 25600.</description>
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_get_mem_vpd_keyword.xml b/src/import/chips/p9/procedures/xml/error_info/p9_get_mem_vpd_keyword.xml
index 48be558fe..a9372ceda 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_get_mem_vpd_keyword.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_get_mem_vpd_keyword.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2016,2017 -->
+<!-- Contributors Listed Below - COPYRIGHT 2016,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -128,15 +128,22 @@
<ffdc>MAPROW8</ffdc>
<ffdc>MAPROW9</ffdc>
<!-- Should use a variable ffdc for the rows but that isn't supported -->
+ <!-- Most likely scenario is some bad configs -->
<callout>
- <hw>
- <hwid>VPD_PART</hwid>
- <refTarget>MCS_TARGET</refTarget>
- </hw>
+ <procedure>MEMORY_PLUGGING_ERROR</procedure>
<priority>HIGH</priority>
</callout>
+ <!-- Next would be a code issue since we have a copy of MEMD in FW -->
<callout>
<procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <!-- Finally it could be downlevel MEMD VPD in the backplane -->
+ <callout>
+ <hw>
+ <hwid>VPD_PART</hwid>
+ <refTarget>MCS_TARGET</refTarget>
+ </hw>
<priority>LOW</priority>
</callout>
</hwpError>
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_draminit_training.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_draminit_training.xml
index d7bb833cd..b177f8d18 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_draminit_training.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_draminit_training.xml
@@ -658,20 +658,6 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_INVALID_RANK</rc>
- <description>
- Invalid rank passed into function
- </description>
- <ffdc>FUNCTION</ffdc>
- <ffdc>RANK</ffdc>
- <ffdc>MCA_TARGET</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
-</hwpError>
-
-<hwpError>
<rc>RC_MSS_INVALID_RANK_PAIR</rc>
<description>
Invalid rank pair passed into function
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
index 9d9aea174..8569812a9 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2016,2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2016,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -37,18 +37,6 @@
<hwpErrors>
<hwpError>
- <rc>RC_MSS_INVALID_FINE_REFRESH_MODE</rc>
- <description>
- Invalid fine refresh mode received from the mrw
- </description>
- <ffdc>FINE_REF_MODE</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
<rc>RC_MSS_INVALID_FINE_REFRESH_MODE_WITH_TEMP_REFRESH_MODE_ENABLED</rc>
<description>
Invalid fine refresh mode received due to temperature refresh mode being enabled
@@ -109,18 +97,6 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_INVALID_CAST_CALC_NCK</rc>
- <description>Invalid cast or calculation for calc_nck</description>
- <ffdc>TIMING_PS</ffdc>
- <ffdc>NCK_NS</ffdc>
- <ffdc>CORRECTION_FACTOR</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
<rc>RC_MSS_INVALID_SPD_SLAVE_RANKS</rc>
<description>
Seems logical ranks are not master ranks* slave ranks.
@@ -270,20 +246,6 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_INVALID_FREQ_PASSED_IN</rc>
- <description>
- An invalid Freq value has been set
- </description>
- <ffdc>FREQ</ffdc>
- <ffdc>FUNCTION</ffdc>
- <ffdc>DIMM_TARGET</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
<rc>RC_MSS_ERROR_CREATING_EFF_CONFIG_DIMM_OBJECT</rc>
<description>
Failed to create a dimm object, probably due to bad data from SPD (ie code doesn't support)
@@ -395,19 +357,6 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_INVALID_REFRESH_RATE_REQUEST</rc>
- <description>
- Invalid refresh request rate received.
- Possibly due to bad MRW setting for ATTR_MSS_MRW_REFRESH_RATE_REQUEST.
- </description>
- <ffdc>REFRESH_RATE_REQUEST</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
<rc>RC_MSS_INVALID_FINE_REFRESH</rc>
<description>
Incorrect FINE Refresh Mode received
@@ -420,72 +369,6 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_FAILED_TO_FIND_TRFC</rc>
- <description>
- Unable to find tRFC (ps) from map with SDRAM density key
- </description>
- <ffdc>SDRAM_DENSITY</ffdc>
- <ffdc>REFRESH_MODE</ffdc>
- <callout>
- <target>DIMM_TARGET</target>
- <priority>MEDIUM</priority>
- </callout>
- <deconfigure>
- <target>DIMM_TARGET</target>
- </deconfigure>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_INVALID_PAGE_SIZE</rc>
- <description>
- Invalid page size
- </description>
- <ffdc>DRAM_WIDTH</ffdc>
- <callout>
- <procedure>MEMORY_PLUGGING_ERROR</procedure>
- <priority>HIGH</priority>
- </callout>
- <callout>
- <target>DIMM_TARGET</target>
- <priority>MEDIUM</priority>
- </callout>
- <deconfigure>
- <target>DIMM_TARGET</target>
- </deconfigure>
- <callout>
- <procedure>CODE</procedure>
- <priority>MEDIUM</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_INVALID_DRAM_WIDTH</rc>
- <description>
- Code only supports x4 and x8 drams at this time
- </description>
- <ffdc>DRAM_WIDTH</ffdc>
- <callout>
- <procedure>MEMORY_PLUGGING_ERROR</procedure>
- <priority>HIGH</priority>
- </callout>
- <callout>
- <target>DIMM_TARGET</target>
- <priority>MEDIUM</priority>
- </callout>
- <deconfigure>
- <target>DIMM_TARGET</target>
- </deconfigure>
- <callout>
- <procedure>CODE</procedure>
- <priority>MEDIUM</priority>
- </callout>
- </hwpError>
-
- <hwpError>
<rc>RC_MSS_INVALID_RTT_PARK_CALCULATIONS</rc>
<description>
Calculated the rtt_park_index into the VPD attribute incorrectly
@@ -522,23 +405,6 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_INVALID_VPD_KEYWORD_MAX</rc>
- <description>
- VPD keyword is too big for space allocated for it.
- </description>
- <ffdc>MAX</ffdc>
- <ffdc>ACTUAL</ffdc>
- <ffdc>KEYWORD</ffdc>
- <callout>
- <hw>
- <hwid>VPD_PART</hwid>
- <refTarget>MCS_TARGET</refTarget>
- </hw>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
<rc>RC_MSS_OFFSET_WR_VREF_OUT_OF_RANGE</rc>
<description>
The offset composite range is out of range
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config_thermal.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config_thermal.xml
index 5de51418f..a156088c2 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config_thermal.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config_thermal.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2015,2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -34,182 +34,6 @@
<!-- -->
<hwpErrors>
- <hwpError>
- <rc>RC_MSS_NO_POWER_THERMAL_ATTR_FOUND</rc>
- <description>
- There was no match or value found in decoding the power thermal attributes
- </description>
- <ffdc>GENERATED_KEY</ffdc>
- <ffdc>FUNCTION</ffdc>
- <ffdc>DIMM_TARGET</ffdc>
- <ffdc>SIZE</ffdc>
- <ffdc>DRAM_GEN</ffdc>
- <ffdc>DIMM_TYPE</ffdc>
- <ffdc>DRAM_WIDTH</ffdc>
- <ffdc>DRAM_DENSITY</ffdc>
- <ffdc>STACK_TYPE</ffdc>
- <ffdc>MFGID</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_POWER_THERMAL_ENCODE_ERROR</rc>
- <description>
- There was no match or value found in encoding the power thermal attributes
- </description>
- <ffdc>DIMM_TARGET</ffdc>
- <ffdc>ATTR</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_POWER_THERMAL_DECODE_ERROR</rc>
- <description>
- There was no match or value found in decoding the power thermal attributes
- </description>
- <ffdc>DIMM_TARGET</ffdc>
- <ffdc>ATTR</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_POWER_INTERCEPT_NOT_SET</rc>
- <description>
- The attribute ATTR_MSS_TOTAL_POWER_INTERCEPT was not set and equals 0
- </description>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_POWER_SLOPE_NOT_SET</rc>
- <description>
- The attribute ATTR_MSS_TOTAL_POWER_INTERCEPT was not set and equals 0
- </description>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_NO_DATABUS_UTILIZATION</rc>
- <description>
- There are 2 DIMMS on the port but both have 0 databus utilization
- </description>
- <ffdc>PORT_DATABUS_UTIL</ffdc>
- <ffdc>DIMM_COUNT</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_CALC_POWER_CURVE_DIVIDE_BY_ZERO</rc>
- <description>
- Denominator equals 0
- </description>
- <ffdc>PORT_DATABUS_UTIL</ffdc>
- <ffdc>UTIL_CONVERSION</ffdc>
- <ffdc>IDLE_UTIL</ffdc>
- <ffdc>RESULT</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_NO_PORT_POWER_LIMIT</rc>
- <description>
- Got 0 when calculating port power limit.
- Either no dimms or attribute MEM_WATT_TARGET wasn't set
- </description>
- <ffdc>COUNT_DIMMS</ffdc>
- <ffdc>PORT_POWER_LIMIT</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_NO_PORT_POWER</rc>
- <description>
- Got 0 when calculating port power limits using the DIMMs databus utilization
- </description>
- <ffdc>COUNT_DIMMS</ffdc>
- <ffdc>MAX_UTILIZATION_DIMM_0</ffdc>
- <ffdc>MAX_UTILIZATION_DIMM_1</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_M_DRAM_CLOCKS_EQUALS_ZERO</rc>
- <description>
- ATTR_MSS_MRW_MEM_M_DRAM_CLOCKS was not set and equals zero
- </description>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_CALC_PORT_POWER_EXCEEDS_MAX</rc>
- <description>
- The calculated port power from equalizing throttles exceeds the maximum allowed power
- </description>
- <ffdc>CALCULATED_PORT_POWER</ffdc>
- <ffdc>MAX_POWER_ALLOWED</ffdc>
- <ffdc>PORT_POS</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- <callout>
- <childTargets>
- <parent>MCA_TARGET</parent>
- <childType>TARGET_TYPE_DIMM</childType>
- </childTargets>
- <priority>MEDIUM</priority>
- </callout>
- <deconfigure>
- <childTargets>
- <parent>MCA_TARGET</parent>
- <childType>TARGET_TYPE_DIMM</childType>
- </childTargets>
- </deconfigure>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_SLOT_UTIL_EXCEEDS_PORT</rc>
- <description>
- The memory throttle per slot (DIMM) exceeds the allowed throttle for the port
- </description>
- <ffdc>SLOT_UTIL</ffdc>
- <ffdc>PORT_UTIL</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
<hwpError>
<rc>RC_MSS_SPLIT_UTIL_CALC_ERROR</rc>
<description>
@@ -225,17 +49,6 @@
</callout>
</hwpError>
- <hwpError>
- <rc>RC_MSS_OUTPUT_OVERFLOW_CALC_UTIL</rc>
- <description>
- Type of output variable is not large enough for the calculations
- </description>
- <ffdc>RESULT</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
<hwpError>
<rc>RC_MSS_DIMM_COUNT_EXCEEDS_VMEM_REGULATOR_LIMIT</rc>
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_freq.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_freq.xml
index 4a1b6f51f..e2a9bf1ab 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_freq.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_freq.xml
@@ -127,32 +127,6 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_INVALID_VPD_FREQ_LIST_PASSED</rc>
- <description>
- Wrong size vector passed into limit_freq_by_vpd function
- </description>
- <ffdc>SIZE</ffdc>
- <ffdc>EXPECTED</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_INVALID_FREQ_LIST_PASSED</rc>
- <description>
- Wrong size vector passed into frequency scoreboard function
- </description>
- <ffdc>SIZE</ffdc>
- <ffdc>EXPECTED</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
<rc>RC_MSS_ERROR_FINDING_DIMM_SPEED_MAP</rc>
<description>
Empty MCBIST target vector found when constructing dimm speed mapping
@@ -204,22 +178,6 @@
</callout>
</hwpError>
-
- <hwpError>
- <rc>RC_MSS_MAX_FREQ_ATTR_SIZE_CHANGED</rc>
- <description>
- Number of entries for MSS_MRW_MAX_FREQ attribute from VPD has changed without updating the code
- Asserted because direct accesses to array
- </description>
- <ffdc>ACTUAL_SIZE</ffdc>
- <ffdc>SUPPOSED_SIZE</ffdc>
- <ffdc>MCA_TARGET</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
<hwpError>
<rc>RC_MSS_MRW_FREQ_MAX_FREQ_EMPTY_SET</rc>
<description>
@@ -286,50 +244,6 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_TOO_MANY_DIMMS_ON_PORT</rc>
- <description>There seem to be too many dimms on the port</description>
- <ffdc>DIMM_COUNT</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- <callout>
- <childTargets>
- <parent>PORT_TARGET</parent>
- <childType>TARGET_TYPE_DIMM</childType>
- </childTargets>
- <priority>MEDIUM</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_TOO_MANY_PRIMARY_RANKS_ON_DIMM</rc>
- <description>There seem to be too many primary ranks seen on the dimm</description>
- <ffdc>RANK_COUNT</ffdc>
- <callout>
- <target>DIMM_TARGET</target>
- <priority>HIGH</priority>
- </callout>
- <deconfigure>
- <target>DIMM_TARGET</target>
- </deconfigure>
- <gard>
- <target>DIMM_TARGET</target>
- </gard>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_FREQ_INDEX_TOO_LARGE</rc>
- <description>Error calculating the index into max_freq array</description>
- <ffdc>INDEX</ffdc>
- <ffdc>NUM_MAX_FREQS</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
<rc>RC_MSS_FREQ_TO_NEST_FREQ_RATIO_TOO_LARGE</rc>
<description>
Case when mss_freq to nest freq is above the maximum allowed.
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml
index 0d7d6c791..1625e16f0 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml
@@ -163,7 +163,7 @@
</registerFfdc>
<hwpError>
- <rc>RC_MSS_CCS_READ_MISCOMPARE</rc>
+ <rc>RC_MSS_NIMBUS_CCS_READ_MISCOMPARE</rc>
<description>
CCS reports a read miscompare.
</description>
@@ -186,7 +186,7 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_CCS_UE_SUE</rc>
+ <rc>RC_MSS_NIMBUS_CCS_UE_SUE</rc>
<description>
CCS reports a UE or SUE in the CCS program array
Chould be an indicator of corruption in the CCS program
@@ -210,7 +210,7 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_CCS_CAL_TIMEOUT</rc>
+ <rc>RC_MSS_NIMBUS_CCS_CAL_TIMEOUT</rc>
<description>
CCS reports never getting a response back from the PHY on a calibration command
</description>
@@ -233,7 +233,7 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_CCS_HUNG</rc>
+ <rc>RC_MSS_NIMBUS_CCS_HUNG</rc>
<description>
Software reported that the machine is not seeing the CCS finish in the alloted time
</description>
@@ -282,83 +282,6 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_MCBIST_TIMEOUT</rc>
- <description>
- MCBIST program failed to return in the time allowed
- Software timer, MCBIST has not finished in the time allowed
- </description>
- <collectRegisterFfdc>
- <id>REG_FFDC_MSS_CCS_FAILURE</id>
- <target>MCBIST_TARGET</target>
- <targetType>TARGET_TYPE_MCBIST</targetType>
- </collectRegisterFfdc>
- <callout>
- <target>MCBIST_TARGET</target>
- <priority>HIGH</priority>
- </callout>
- <deconfigure>
- <target>MCBIST_TARGET</target>
- </deconfigure>
- <gard>
- <target>MCBIST_TARGET</target>
- </gard>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_MCBIST_DATA_FAIL</rc>
- <description>
- MCBIST program appeared to have failed, but set conflicting bits in the status register
- </description>
- <ffdc>STATUS_REGISTER</ffdc>
- <collectRegisterFfdc>
- <id>REG_FFDC_MSS_CCS_FAILURE</id>
- <target>MCBIST_TARGET</target>
- <targetType>TARGET_TYPE_MCBIST</targetType>
- </collectRegisterFfdc>
- <callout>
- <target>MCBIST_TARGET</target>
- <priority>HIGH</priority>
- </callout>
- <deconfigure>
- <target>MCBIST_TARGET</target>
- </deconfigure>
- <gard>
- <target>MCBIST_TARGET</target>
- </gard>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_MCBIST_UNKNOWN_FAILURE</rc>
- <description>MCBIST program reported a failure but no error status was found</description>
- <ffdc>STATUS_REGISTER</ffdc>
- <collectRegisterFfdc>
- <id>REG_FFDC_MSS_CCS_FAILURE</id>
- <target>MCBIST_TARGET</target>
- <targetType>TARGET_TYPE_MCBIST</targetType>
- </collectRegisterFfdc>
- <callout>
- <target>MCBIST_TARGET</target>
- <priority>HIGH</priority>
- </callout>
- <deconfigure>
- <target>MCBIST_TARGET</target>
- </deconfigure>
- <gard>
- <target>MCBIST_TARGET</target>
- </gard>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_MCBIST_PROGRAM_TOO_BIG</rc>
- <description>MCBIST program larger than currently supported size</description>
- <ffdc>PROGRAM_LENGTH</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
<rc>RC_MSS_APB_INVALID_ADDRESS</rc>
<description>PHY APB interface is reporting an invalid address was read or written</description>
<ffdc>PORT_POSITION</ffdc>
@@ -566,19 +489,8 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_SRE_MCA_OUT_OF_RANGE</rc>
- <description>Indicates a MCA passed to the NVDIMM sre code is out of range</description>
- <ffdc>PROC_TARGET</ffdc>
- <ffdc>MCA_POS</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_RESETN_MCA_OUT_OF_RANGE</rc>
- <description>Indicates a MCA passed to the NVDIMM resetn code is out of range</description>
+ <rc>RC_MSS_SELECT_PORT_MCA_OUT_OF_RANGE</rc>
+ <description>Indicates a MCA is out of range</description>
<ffdc>PROC_TARGET</ffdc>
<ffdc>MCA_POS</ffdc>
<callout>
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_memdiags.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_memdiags.xml
index b18d42520..09c2bc180 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_memdiags.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_memdiags.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2016,2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2016,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -84,117 +84,112 @@
</registerFfdc>
<hwpError>
- <rc>RC_MSS_MEMDIAGS_ERROR_IN_LAST_PATTERN</rc>
- <description>An error was caused by the last MCBIST pattern</description>
- <ffdc>STATUS0</ffdc>
- <ffdc>STATUS1</ffdc>
+ <rc>RC_MSS_MCBIST_TIMEOUT</rc>
+ <description>
+ MCBIST program failed to return in the time allowed
+ Software timer, MCBIST has not finished in the time allowed
+ </description>
<collectRegisterFfdc>
<id>REG_FFDC_MSS_MEMDIAGS_FAILURE</id>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<targetType>TARGET_TYPE_MCBIST</targetType>
</collectRegisterFfdc>
<callout>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<priority>HIGH</priority>
</callout>
+ <deconfigure>
+ <target>MC_TARGET</target>
+ </deconfigure>
+ <gard>
+ <target>MC_TARGET</target>
+ </gard>
</hwpError>
<hwpError>
- <rc>RC_MSS_MEMDIAGS_COMPARE_ERROR_IN_LAST_PATTERN</rc>
- <description>A miscompare error was caused by the last MCBIST pattern</description>
- <ffdc>PORT</ffdc>
- <ffdc>SUBTEST</ffdc>
+ <rc>RC_MSS_MCBIST_DATA_FAIL</rc>
+ <description>
+ MCBIST program appeared to have failed, but set conflicting bits in the status register
+ </description>
+ <ffdc>STATUS_REGISTER</ffdc>
<collectRegisterFfdc>
- <id>REG_FFDC_MSS_MEMDIAGS_FAILURE</id>
- <target>MCBIST_TARGET</target>
+ <id>REG_FFDC_MSS_CCS_FAILURE</id>
+ <target>MC_TARGET</target>
<targetType>TARGET_TYPE_MCBIST</targetType>
</collectRegisterFfdc>
<callout>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<priority>HIGH</priority>
</callout>
+ <deconfigure>
+ <target>MC_TARGET</target>
+ </deconfigure>
+ <gard>
+ <target>MC_TARGET</target>
+ </gard>
</hwpError>
<hwpError>
- <rc>RC_MSS_MEMDIAGS_INVALID_PATTERN_INDEX</rc>
- <description>An invalid pattern index was passed to the pattern loader</description>
- <ffdc>INDEX</ffdc>
+ <rc>RC_MSS_MCBIST_UNKNOWN_FAILURE</rc>
+ <description>MCBIST program reported a failure but no error status was found</description>
+ <ffdc>STATUS_REGISTER</ffdc>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_MSS_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_MCBIST</targetType>
+ </collectRegisterFfdc>
<callout>
- <procedure>CODE</procedure>
+ <target>MC_TARGET</target>
<priority>HIGH</priority>
</callout>
+ <deconfigure>
+ <target>MC_TARGET</target>
+ </deconfigure>
+ <gard>
+ <target>MC_TARGET</target>
+ </gard>
</hwpError>
<hwpError>
- <rc>RC_MSS_MEMDIAGS_ERROR_CHANGING_RANDOM_SEED</rc>
- <description>Attempting to change to a 24b random data seed which does not exist</description>
- <ffdc>RANDOM_SEED</ffdc>
+ <rc>RC_MSS_MEMDIAGS_ERROR_IN_LAST_PATTERN</rc>
+ <description>An error was caused by the last MCBIST pattern</description>
+ <ffdc>STATUS0</ffdc>
+ <ffdc>STATUS1</ffdc>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_MSS_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_MCBIST</targetType>
+ </collectRegisterFfdc>
<callout>
- <procedure>CODE</procedure>
+ <target>MC_TARGET</target>
<priority>HIGH</priority>
</callout>
</hwpError>
<hwpError>
- <rc>RC_MSS_INVALID_GALOIS_TO_SYMBOL</rc>
- <description> An invalid galois code was found</description>
- <ffdc>GALOIS</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_INVALID_SYMBOL_FOR_GALOIS</rc>
- <description> An invalid symbol was passed to symbol_to_galois</description>
- <ffdc>SYMBOL</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_INVALID_DQ_TO_SYMBOL</rc>
- <description> An invalid DQ bit index received to map to Galois symbol</description>
- <ffdc>DQ</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_INVALID_SYMBOL_TO_DQ</rc>
- <description> An invalid symbol received to map to DQ bit index</description>
- <ffdc>SYMBOL</ffdc>
+ <rc>RC_MSS_MEMDIAGS_COMPARE_ERROR_IN_LAST_PATTERN</rc>
+ <description>A miscompare error was caused by the last MCBIST pattern</description>
+ <ffdc>PORT</ffdc>
+ <ffdc>SUBTEST</ffdc>
+ <collectRegisterFfdc>
+ <id>REG_FFDC_MSS_MEMDIAGS_FAILURE</id>
+ <target>MC_TARGET</target>
+ <targetType>TARGET_TYPE_MCBIST</targetType>
+ </collectRegisterFfdc>
<callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
+ <target>MC_TARGET</target>
+ <priority>HIGH</priority>
</callout>
</hwpError>
- <hwpError>
- <rc>RC_MSS_INVALID_RANK_PASSED</rc>
- <description> An invalid rank was passed to ecc::read function</description>
- <ffdc>RANK</ffdc>
- <ffdc>FUNCTION</ffdc>
- <ffdc>TARGET</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
<hwpError>
- <rc>RC_MSS_INVALID_INDEX_PASSED</rc>
- <description> An invalid index was passed to MODAL_SYMBOL_COUNT function</description>
- <ffdc>INDEX</ffdc>
- <ffdc>FUNCTION</ffdc>
+ <rc>RC_MSS_MEMDIAGS_ERROR_CHANGING_RANDOM_SEED</rc>
+ <description>Attempting to change to a 24b random data seed which does not exist</description>
+ <ffdc>RANDOM_SEED</ffdc>
<callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
</callout>
</hwpError>
@@ -218,11 +213,11 @@
<description>The MCBIST engine failed to start its program</description>
<collectRegisterFfdc>
<id>REG_FFDC_MSS_MEMDIAGS_FAILURE</id>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<targetType>TARGET_TYPE_MCBIST</targetType>
</collectRegisterFfdc>
<callout>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<priority>HIGH</priority>
</callout>
</hwpError>
@@ -232,12 +227,12 @@
<description>The MCBIST engine failed to stop its program</description>
<collectRegisterFfdc>
<id>REG_FFDC_MSS_MEMDIAGS_FAILURE</id>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<targetType>TARGET_TYPE_MCBIST</targetType>
</collectRegisterFfdc>
<ffdc>POLL_COUNT</ffdc>
<callout>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<priority>HIGH</priority>
</callout>
</hwpError>
@@ -247,10 +242,10 @@
<description>The port used in an MCBIST program is not functional</description>
<ffdc>RELATIVE_PORT_POSITION</ffdc>
<ffdc>ADDRESS</ffdc>
- <ffdc>MCBIST_TARGET</ffdc>
+ <ffdc>MC_TARGET</ffdc>
<collectRegisterFfdc>
<id>REG_FFDC_MSS_MEMDIAGS_FAILURE</id>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<targetType>TARGET_TYPE_MCBIST</targetType>
</collectRegisterFfdc>
<callout>
@@ -264,11 +259,11 @@
<description>A superfast read operation failed initialization</description>
<collectRegisterFfdc>
<id>REG_FFDC_MSS_MEMDIAGS_FAILURE</id>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<targetType>TARGET_TYPE_MCBIST</targetType>
</collectRegisterFfdc>
<callout>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<priority>HIGH</priority>
</callout>
</hwpError>
@@ -278,11 +273,11 @@
<description>A superfast init operation failed initialization</description>
<collectRegisterFfdc>
<id>REG_FFDC_MSS_MEMDIAGS_FAILURE</id>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<targetType>TARGET_TYPE_MCBIST</targetType>
</collectRegisterFfdc>
<callout>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<priority>HIGH</priority>
</callout>
</hwpError>
@@ -292,11 +287,11 @@
<description>A continuous scrub operation failed initialization</description>
<collectRegisterFfdc>
<id>REG_FFDC_MSS_MEMDIAGS_FAILURE</id>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<targetType>TARGET_TYPE_MCBIST</targetType>
</collectRegisterFfdc>
<callout>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<priority>HIGH</priority>
</callout>
</hwpError>
@@ -306,11 +301,11 @@
<description>A continuous scrub operation failed initialization</description>
<collectRegisterFfdc>
<id>REG_FFDC_MSS_MEMDIAGS_FAILURE</id>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<targetType>TARGET_TYPE_MCBIST</targetType>
</collectRegisterFfdc>
<callout>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<priority>HIGH</priority>
</callout>
</hwpError>
@@ -318,11 +313,11 @@
<hwpError>
<rc>RC_MSS_MEMDIAGS_ALREADY_AT_BOUNDARY</rc>
<description>A continue request asked to stop at a boundary, but we are there already</description>
- <ffdc>MCBIST_TARGET</ffdc>
+ <ffdc>MC_TARGET</ffdc>
<ffdc>BOUNDARY</ffdc>
<collectRegisterFfdc>
<id>REG_FFDC_MSS_MEMDIAGS_FAILURE</id>
- <target>MCBIST_TARGET</target>
+ <target>MC_TARGET</target>
<targetType>TARGET_TYPE_MCBIST</targetType>
</collectRegisterFfdc>
<callout>
@@ -332,16 +327,6 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_MEMDIAGS_NO_MCBIST_SUBTESTS</rc>
- <description>Attempt to run an MCBIST program with no subtests</description>
- <ffdc>MCBIST_TARGET</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
<rc>RC_MSS_MEMDIAGS_REPAIRS_EXCEEDED</rc>
<description>A mark repair operation failed to repair enough bad bits</description>
<collectRegisterFfdc>
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_spd_decode.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_spd_decode.xml
index a1310dec2..eec228380 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_spd_decode.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_spd_decode.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2015,2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -37,140 +37,6 @@
<hwpErrors>
<hwpError>
- <rc>RC_MSS_INVALID_SPD_RESERVED_BITS</rc>
- <description>
- Invalid SPD reserved bits received.
- This could be code problem (decoding) or bad SPD.
- </description>
- <ffdc>FUNCTION_CODE</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>MEDIUM</priority>
- </callout>
- <callout>
- <target>TARGET</target>
- <priority>HIGH</priority>
- </callout>
- <deconfigure>
- <target>TARGET</target>
- </deconfigure>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_INVALID_DIMM_SPEED</rc>
- <description>
- Invalid DIMM speed received. Possibly a programming error.
- </description>
- <ffdc>DIMM_SPEED</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>MEDIUM</priority>
- </callout>
- <callout>
- <target>TARGET</target>
- <priority>HIGH</priority>
- </callout>
- <deconfigure>
- <target>TARGET</target>
- </deconfigure>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_INVALID_DB_MDQ_DRIVE_STRENGTH</rc>
- <description>
- Bad SPD data for bytes 145 - 147.
- Reserved settings for data buffer MDQ drive strength received.
- This could be code problem (decoding) or bad SPD.
- </description>
- <ffdc>DATA_RATE</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>MEDIUM</priority>
- </callout>
- <callout>
- <target>TARGET</target>
- <priority>HIGH</priority>
- </callout>
- <deconfigure>
- <target>TARGET</target>
- </deconfigure>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_INVALID_DRAM_GEN</rc>
- <description>
- Received a DRAM gen unsupported by the SPD decoder factory
- </description>
- <ffdc>DRAM_GEN</ffdc>
- <ffdc>FUNCTION</ffdc>
- <callout>
- <procedure>MEMORY_PLUGGING_ERROR</procedure>
- <priority>HIGH</priority>
- </callout>
- <callout>
- <target>DIMM_TARGET</target>
- <priority>LOW</priority>
- </callout>
- <deconfigure>
- <target>DIMM_TARGET</target>
- </deconfigure>
- <callout>
- <procedure>CODE</procedure>
- <priority>MEDIUM</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_INVALID_HYBRID_MODULE</rc>
- <description>
- Received an invalid or unsupported hybrid media (SPD byte 3, bits [6:4])
- for a specified hybrid modue (SPD byte 3, bit [7])
- </description>
- <ffdc>HYBRID</ffdc>
- <ffdc>HYBRID_MEDIA</ffdc>
- <ffdc>FUNCTION</ffdc>
- <callout>
- <procedure>MEMORY_PLUGGING_ERROR</procedure>
- <priority>HIGH</priority>
- </callout>
- <callout>
- <target>TARGET</target>
- <priority>LOW</priority>
- </callout>
- <deconfigure>
- <target>TARGET</target>
- </deconfigure>
- <callout>
- <procedure>CODE</procedure>
- <priority>MEDIUM</priority>
- </callout>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_INVALID_DIMM_TYPE</rc>
- <description>
- Received a DIMM type unsupported by the SPD decoder factory
- </description>
- <ffdc>DIMM_TYPE</ffdc>
- <ffdc>FUNCTION</ffdc>
- <callout>
- <procedure>MEMORY_PLUGGING_ERROR</procedure>
- <priority>HIGH</priority>
- </callout>
- <callout>
- <target>DIMM_TARGET</target>
- <priority>LOW</priority>
- </callout>
- <deconfigure>
- <target>DIMM_TARGET</target>
- </deconfigure>
- <callout>
- <procedure>CODE</procedure>
- <priority>MEDIUM</priority>
- </callout>
- </hwpError>
-
- <hwpError>
<rc>RC_MSS_INVALID_RAW_CARD</rc>
<description>
Received a raw card that isn't currently supported in code
@@ -194,89 +60,4 @@
</deconfigure>
</hwpError>
- <hwpError>
- <rc>RC_MSS_FAILED_SPD_REVISION_FALLBACK</rc>
- <description>
- Unable to fall back SPD decoder to the highest decoded
- revision. Most likely a programming error.
- </description>
- <ffdc>FAILED_REVISION</ffdc>
- <ffdc>FUNCTION_CODE</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>MEDIUM</priority>
- </callout>
- <callout>
- <target>TARGET</target>
- <priority>MEDIUM</priority>
- </callout>
- <deconfigure>
- <target>TARGET</target>
- </deconfigure>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_SPD_TIMING_FAIL</rc>
- <description>
- Timing SPD parameter failed to meet JEDEC SPD timing
- bounds. FUNCTION_CODE ffdc field encodes which timing param.
- </description>
- <ffdc>FAILED_REVISION</ffdc>
- <ffdc>FUNCTION_CODE</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>MEDIUM</priority>
- </callout>
- <callout>
- <target>TARGET</target>
- <priority>MEDIUM</priority>
- </callout>
- <deconfigure>
- <target>TARGET</target>
- </deconfigure>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_INVALID_SPD_PARAMETER_RECEIVED</rc>
- <description>
- Unable to fall back SPD decoder to the highest decoded
- revision. Most likely a programming error.
- </description>
- <ffdc>SPD_PARAM</ffdc>
- <ffdc>FUNCTION_CODE</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>MEDIUM</priority>
- </callout>
- <callout>
- <target>TARGET</target>
- <priority>MEDIUM</priority>
- </callout>
- <deconfigure>
- <target>TARGET</target>
- </deconfigure>
- </hwpError>
-
- <hwpError>
- <rc>RC_MSS_SPD_REV_ENCODING_LEVEL_NOT_SUPPORTED</rc>
- <description>
- SPD revision on byte 1 (bits 7~4) has a unsupported encoding level
- that is greater than the largest decoded SPD decoder. There is
- no backward compatible revision to fallback to. This could be
- bad SPD or a programming error.
- </description>
- <ffdc>ENCODING_LEVEL</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>MEDIUM</priority>
- </callout>
- <callout>
- <target>TARGET</target>
- <priority>MEDIUM</priority>
- </callout>
- <deconfigure>
- <target>TARGET</target>
- </deconfigure>
- </hwpError>
-
</hwpErrors>
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_mss_eff_grouping_errors.xml b/src/import/chips/p9/procedures/xml/error_info/p9_mss_eff_grouping_errors.xml
index 5147e960f..5a5764e97 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_mss_eff_grouping_errors.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_mss_eff_grouping_errors.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2015,2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -239,4 +239,18 @@
</callout>
</hwpError>
+<hwpError>
+ <rc>RC_MSS_EFF_GROUPING_ADDRESS_NOT_ALIGNED</rc>
+ <description>
+ NHTM BAR address is not aligned with requested size.
+ </description>
+ <ffdc>NHTM_BAR_BASE</ffdc>
+ <ffdc>NHTM_SIZE</ffdc>
+ <ffdc>CHTM_SIZE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+</hwpError>
+
</hwpErrors>
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_sbe_check_master_stop15_errors.xml b/src/import/chips/p9/procedures/xml/error_info/p9_sbe_check_master_stop15_errors.xml
index 4dee999b7..e2c010a53 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_sbe_check_master_stop15_errors.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_sbe_check_master_stop15_errors.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2015,2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -34,6 +34,8 @@
for a completed transition.
</description>
+ <ffdc>EX</ffdc>
+
<collectFfdc>p9_eq_clear_atomic_lock,EQ</collectFfdc>
<collectRegisterFfdc>
@@ -47,11 +49,6 @@
<targetType>TARGET_TYPE_EQ</targetType>
</collectRegisterFfdc>
<collectRegisterFfdc>
- <id>CHECK_MASTER_STOP15_FFDC_REGS_EX</id>
- <target>EX</target>
- <targetType>TARGET_TYPE_EX</targetType>
- </collectRegisterFfdc>
- <collectRegisterFfdc>
<id>CHECK_MASTER_STOP15_FFDC_REGS_EC</id>
<target>EC</target>
<targetType>TARGET_TYPE_CORE</targetType>
@@ -77,6 +74,8 @@
but the achieved level is not appropriate.
</description>
+ <ffdc>EX</ffdc>
+
<collectFfdc>p9_eq_clear_atomic_lock,EQ</collectFfdc>
<collectRegisterFfdc>
@@ -90,11 +89,6 @@
<targetType>TARGET_TYPE_EQ</targetType>
</collectRegisterFfdc>
<collectRegisterFfdc>
- <id>CHECK_MASTER_STOP15_FFDC_REGS_EX</id>
- <target>EX</target>
- <targetType>TARGET_TYPE_EX</targetType>
- </collectRegisterFfdc>
- <collectRegisterFfdc>
<id>CHECK_MASTER_STOP15_FFDC_REGS_EC</id>
<target>EC</target>
<targetType>TARGET_TYPE_CORE</targetType>
diff --git a/src/import/chips/p9/xip/p9_xip_image.h b/src/import/chips/p9/xip/p9_xip_image.h
index 76bc2bad1..7821ca642 100644
--- a/src/import/chips/p9/xip/p9_xip_image.h
+++ b/src/import/chips/p9/xip/p9_xip_image.h
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -1619,6 +1619,7 @@ p9_xip_decode_toc_dump(void* i_image, void* i_dump,
.macro .xip_toc, index:req, type:req, address:req, elements=1
.if (((\type) < 1) || ((\type) > P9_XIP_MAX_TYPE_INDEX))
+ // cppcheck-suppress syntaxError
.error ".xip_toc : Illegal type index"
.endif
diff --git a/src/import/generic/memory/lib/data_engine/p9a/p9a_data_init_traits.H b/src/import/chips/p9a/procedures/hwp/memory/lib/eff_config/p9a_data_init_traits.H
index d0f00d6f0..509795f47 100644
--- a/src/import/generic/memory/lib/data_engine/p9a/p9a_data_init_traits.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/eff_config/p9a_data_init_traits.H
@@ -1,7 +1,7 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/generic/memory/lib/data_engine/p9a/p9a_data_init_traits.H $ */
+/* $Source: src/import/chips/p9a/procedures/hwp/memory/lib/eff_config/p9a_data_init_traits.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
@@ -46,72 +46,12 @@ namespace mss
{
///
-/// @brief Helper function to get dimm_type from SPD
-/// @param[in] i_spd_data SPD data
-/// @param[in] i_setting value we want to set attr with
-/// @return FAPI2_RC_SUCCESS iff okay
-///
-static fapi2::ReturnCode get_dimm_type(const spd::facade& i_spd_data,
- uint8_t& o_setting)
-{
- // =========================================================
- // DDR4 SPD Document Release 4
- // Byte 3 (0x003): Key Byte / Module Type
- // =========================================================
- static const std::vector< std::pair<uint8_t, uint8_t> > BASE_MODULE_TYPE_MAP =
- {
- //{key byte, dimm type}
- {1, fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_RDIMM},
- {2, fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_UDIMM},
- {10, fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_DDIMM},
- // All others reserved or not supported
- };
-
- const auto l_dimm = i_spd_data.get_dimm_target();
- uint8_t l_base_module_type = 0;
- FAPI_TRY(i_spd_data.base_module(l_base_module_type));
- FAPI_TRY(lookup_table_check(l_dimm, BASE_MODULE_TYPE_MAP, SET_ATTR_DIMM_TYPE, l_base_module_type, o_setting));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Helper function to get dram_gen from SPD
-/// @param[in] i_spd_data SPD data
-/// @param[in] i_setting value we want to set attr with
-/// @return FAPI2_RC_SUCCESS iff okay
-///
-static fapi2::ReturnCode get_dram_gen(const spd::facade& i_spd_data,
- uint8_t& o_setting)
-{
- // =========================================================
- // DDR4 SPD Document Release 4
- // Byte 2 (0x002): Key Byte / DRAM Device Type
- // =========================================================
- static const std::vector< std::pair<uint8_t, uint8_t> > DRAM_GEN_MAP =
- {
- //{key value, dram gen}
- {0x0C, fapi2::ENUM_ATTR_MEM_EFF_DRAM_GEN_DDR4}
- // Other key bytes reserved or not supported
- };
-
- const auto l_dimm = i_spd_data.get_dimm_target();
- uint8_t l_device_type = 0;
- FAPI_TRY(i_spd_data.device_type(l_device_type));
- FAPI_TRY(lookup_table_check(l_dimm, DRAM_GEN_MAP, SET_ATTR_DRAM_GEN, l_device_type, o_setting));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief Traits for pre_data_engine
/// @class attrEngineTraits
/// @note pre_data_init_fields, DIMM_TYPE specialization
///
template<>
-struct attrEngineTraits<pre_data_init_fields, DIMM_TYPE>
+struct attrEngineTraits<proc_type::AXONE, pre_data_init_fields, pre_data_init_fields::DIMM_TYPE>
{
using attr_type = fapi2::ATTR_MEM_EFF_DIMM_TYPE_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -145,13 +85,36 @@ struct attrEngineTraits<pre_data_init_fields, DIMM_TYPE>
///
/// @brief Computes setting for attribute
/// @param[in] i_spd_data SPD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
attr_integral_type& o_setting)
{
- return get_dimm_type(i_spd_data, o_setting);
+ // =========================================================
+ // DDR4 SPD Document Release 4
+ // Byte 3 (0x003): Key Byte / Module Type
+ // =========================================================
+ static const std::vector< std::pair<uint8_t, uint8_t> > BASE_MODULE_TYPE_MAP =
+ {
+ //{key byte, dimm type}
+ {1, fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_RDIMM},
+ {2, fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_UDIMM},
+ {10, fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_DDIMM},
+ // All others reserved or not supported
+ };
+
+ const auto l_dimm = i_spd_data.get_dimm_target();
+
+ attr_integral_type l_base_module_type = 0;
+ FAPI_TRY( i_spd_data.base_module(l_base_module_type),
+ "%s failed to get base module from SPD", spd::c_str(l_dimm) );
+
+ FAPI_TRY( lookup_table_check(l_dimm, BASE_MODULE_TYPE_MAP, FFDC_CODE, l_base_module_type, o_setting),
+ "%s failed DIMM_TYPE lookup check", spd::c_str(l_dimm) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
@@ -161,7 +124,7 @@ struct attrEngineTraits<pre_data_init_fields, DIMM_TYPE>
/// @note pre_data_init_fields, DRAM_GEN specialization
///
template<>
-struct attrEngineTraits<pre_data_init_fields, DRAM_GEN>
+struct attrEngineTraits<proc_type::AXONE, pre_data_init_fields, pre_data_init_fields::DRAM_GEN>
{
using attr_type = fapi2::ATTR_MEM_EFF_DRAM_GEN_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -195,13 +158,34 @@ struct attrEngineTraits<pre_data_init_fields, DRAM_GEN>
///
/// @brief Computes setting for attribute
/// @param[in] i_spd_data SPD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
attr_integral_type& o_setting)
{
- return get_dram_gen(i_spd_data, o_setting);
+ // =========================================================
+ // DDR4 SPD Document Release 4
+ // Byte 2 (0x002): Key Byte / DRAM Device Type
+ // =========================================================
+ static const std::vector< std::pair<uint8_t, uint8_t> > DRAM_GEN_MAP =
+ {
+ //{key value, dram gen}
+ {0x0C, fapi2::ENUM_ATTR_MEM_EFF_DRAM_GEN_DDR4}
+ // Other key bytes reserved or not supported
+ };
+
+ const auto l_dimm = i_spd_data.get_dimm_target();
+
+ attr_integral_type l_device_type = 0;
+ FAPI_TRY( i_spd_data.device_type(l_device_type),
+ "%s failed to get device type from SPD", spd::c_str(l_dimm) );
+
+ FAPI_TRY( lookup_table_check(l_dimm, DRAM_GEN_MAP, FFDC_CODE, l_device_type, o_setting),
+ "%s failed DRAM_GEN lookup check", spd::c_str(l_dimm) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
@@ -211,7 +195,7 @@ struct attrEngineTraits<pre_data_init_fields, DRAM_GEN>
/// @note pre_data_init_fields, HOST_TO_DDR_SPEED_RATIO specialization
///
template<>
-struct attrEngineTraits<pre_data_init_fields, HOST_TO_DDR_SPEED_RATIO>
+struct attrEngineTraits<proc_type::AXONE, pre_data_init_fields, pre_data_init_fields::HOST_TO_DDR_SPEED_RATIO>
{
using attr_type = fapi2::ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -245,7 +229,7 @@ struct attrEngineTraits<pre_data_init_fields, HOST_TO_DDR_SPEED_RATIO>
///
/// @brief Computes setting for attribute
/// @param[in] i_spd_data SPD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
@@ -289,7 +273,7 @@ struct attrEngineTraits<pre_data_init_fields, HOST_TO_DDR_SPEED_RATIO>
/// @note pre_data_init_fields, HYBRID specialization
///
template<>
-struct attrEngineTraits<pre_data_init_fields, HYBRID>
+struct attrEngineTraits<proc_type::AXONE, pre_data_init_fields, pre_data_init_fields::HYBRID>
{
using attr_type = fapi2::ATTR_MEM_EFF_HYBRID_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -323,7 +307,7 @@ struct attrEngineTraits<pre_data_init_fields, HYBRID>
///
/// @brief Computes setting for attribute
/// @param[in] i_spd_data SPD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
@@ -341,9 +325,14 @@ struct attrEngineTraits<pre_data_init_fields, HYBRID>
// All others reserved or not supported
};
- uint8_t l_spd_hybrid_type = 0;
- FAPI_TRY(i_spd_data.hybrid(l_spd_hybrid_type));
- FAPI_TRY(lookup_table_check(i_spd_data.get_dimm_target(), HYBRID_MAP, SET_ATTR_HYBRID, l_spd_hybrid_type, o_setting));
+ const auto l_dimm = i_spd_data.get_dimm_target();
+
+ attr_integral_type l_spd_hybrid_type = 0;
+ FAPI_TRY(i_spd_data.hybrid(l_spd_hybrid_type),
+ "%s failed to get hybrid from SPD", spd::c_str(l_dimm) );
+
+ FAPI_TRY(lookup_table_check(l_dimm, HYBRID_MAP, FFDC_CODE, l_spd_hybrid_type, o_setting),
+ "%s failed HYBRID lookup check", spd::c_str(l_dimm) );
fapi_try_exit:
return fapi2::current_err;
@@ -356,7 +345,7 @@ struct attrEngineTraits<pre_data_init_fields, HYBRID>
/// @note pre_data_init_fields, HYBRID_MEDIA specialization
///
template<>
-struct attrEngineTraits<pre_data_init_fields, HYBRID_MEDIA>
+struct attrEngineTraits<proc_type::AXONE, pre_data_init_fields, pre_data_init_fields::HYBRID_MEDIA>
{
using attr_type = fapi2::ATTR_MEM_EFF_HYBRID_MEMORY_TYPE_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -390,7 +379,7 @@ struct attrEngineTraits<pre_data_init_fields, HYBRID_MEDIA>
///
/// @brief Computes setting for attribute
/// @param[in] i_spd_data SPD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
@@ -408,11 +397,14 @@ struct attrEngineTraits<pre_data_init_fields, HYBRID_MEDIA>
{1, fapi2::ENUM_ATTR_MEM_EFF_HYBRID_MEMORY_TYPE_NVDIMM},
// All others reserved or not supported
};
+ const auto l_dimm = i_spd_data.get_dimm_target();
+ attr_integral_type l_spd_hybrid_media = 0;
+
+ FAPI_TRY( i_spd_data.hybrid_media(l_spd_hybrid_media),
+ "%s failed to get hybrid media from SPD", spd::c_str(l_dimm) );
- uint8_t l_spd_hybrid_media = 0;
- FAPI_TRY(i_spd_data.hybrid_media(l_spd_hybrid_media));
- FAPI_TRY(lookup_table_check(i_spd_data.get_dimm_target(), HYBRID_MEMORY_TYPE_MAP, SET_ATTR_HYBRID_MEDIA,
- l_spd_hybrid_media, o_setting));
+ FAPI_TRY( lookup_table_check(l_dimm, HYBRID_MEMORY_TYPE_MAP, FFDC_CODE, l_spd_hybrid_media, o_setting),
+ "%s failed HYBRID_MEMORY_TYPE lookup check", spd::c_str(l_dimm) );
fapi_try_exit:
return fapi2::current_err;
@@ -420,45 +412,12 @@ struct attrEngineTraits<pre_data_init_fields, HYBRID_MEDIA>
};
///
-/// @brief Gets master ranks from SPD
-/// @param[out] o_output num package ranks per DIMM
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-static fapi2::ReturnCode get_master_ranks(const spd::facade& i_spd_data,
- const generic_ffdc_codes i_ffdc,
- uint8_t& o_output)
-{
- // =========================================================
- // DDR4 SPD Document Release 4
- // Byte 12 (0x00C): Module Organization
- // =========================================================
- static const std::vector< std::pair<uint8_t, uint8_t> > NUM_PACKAGE_RANKS_MAP =
- {
- // {key byte, num of package ranks per DIMM (package ranks)}
- {0, fapi2::ENUM_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM_1R},
- {1, fapi2::ENUM_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM_2R},
- {3, fapi2::ENUM_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM_4R},
- };
-
- const auto l_dimm = i_spd_data.get_dimm_target();
- uint8_t l_master_ranks_spd = 0;
- FAPI_TRY(i_spd_data.num_package_ranks_per_dimm(l_master_ranks_spd),
- "%s failed to get number of package ranks from SPD", spd::c_str(l_dimm));
-
- FAPI_TRY(lookup_table_check(l_dimm, NUM_PACKAGE_RANKS_MAP, i_ffdc, l_master_ranks_spd,
- o_output), "%s failed MASTER_RANKS lookup check", spd::c_str(l_dimm));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief Traits for pre_data_engine
/// @class attrEngineTraits
/// @note pre_data_init_fields, MRANKS specialization
///
template<>
-struct attrEngineTraits<pre_data_init_fields, MRANKS>
+struct attrEngineTraits<proc_type::AXONE, pre_data_init_fields, pre_data_init_fields::MRANKS>
{
using attr_type = fapi2::ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -467,7 +426,7 @@ struct attrEngineTraits<pre_data_init_fields, MRANKS>
///
/// @brief attribute getter
- /// @param[in] i_target the attr target
+ /// @param[in] i_target the attribute associated target
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
@@ -479,7 +438,7 @@ struct attrEngineTraits<pre_data_init_fields, MRANKS>
///
/// @brief attribute setter
- /// @param[in] i_target the attr target
+ /// @param[in] i_target the attribute associated target
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
@@ -492,13 +451,32 @@ struct attrEngineTraits<pre_data_init_fields, MRANKS>
///
/// @brief Computes setting for attribute
/// @param[in] i_spd_data SPD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
attr_integral_type& o_setting)
{
- FAPI_TRY( get_master_ranks(i_spd_data, SET_ATTR_MASTER_RANKS, o_setting) );
+ // =========================================================
+ // DDR4 SPD Document Release 4
+ // Byte 12 (0x00C): Module Organization
+ // =========================================================
+ static const std::vector< std::pair<uint8_t, uint8_t> > NUM_PACKAGE_RANKS_MAP =
+ {
+ // {key byte, num of package ranks per DIMM (package ranks)}
+ {0, fapi2::ENUM_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM_1R},
+ {1, fapi2::ENUM_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM_2R},
+ {3, fapi2::ENUM_ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM_4R},
+ };
+
+ const auto l_dimm = i_spd_data.get_dimm_target();
+
+ attr_integral_type l_master_ranks_spd = 0;
+ FAPI_TRY( i_spd_data.num_package_ranks_per_dimm(l_master_ranks_spd),
+ "%s failed to get number of package ranks from SPD", spd::c_str(l_dimm) );
+
+ FAPI_TRY( lookup_table_check(l_dimm, NUM_PACKAGE_RANKS_MAP, FFDC_CODE, l_master_ranks_spd, o_setting),
+ "%s failed MASTER_RANKS lookup check", spd::c_str(l_dimm) );
fapi_try_exit:
return fapi2::current_err;
@@ -508,36 +486,37 @@ struct attrEngineTraits<pre_data_init_fields, MRANKS>
///
/// @brief Traits for pre_data_engine
/// @class attrEngineTraits
-/// @note pre_data_init_fields, DIMM_RANKS_CNFG specialization
+/// @note DIMM_RANKS_CNFG specialization
///
template<>
-struct attrEngineTraits<pre_data_init_fields, DIMM_RANKS_CNFG>
+struct attrEngineTraits<proc_type::AXONE, pre_data_init_fields, pre_data_init_fields::DIMM_RANKS_CNFG>
{
+
using attr_type = fapi2::ATTR_MEM_EFF_DIMM_RANKS_CONFIGED_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
- static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DIMM_RANKS_CONFIGED_TargetType;
+ static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DIMM_RANKS_CONFIGED_TargetType;
static constexpr generic_ffdc_codes FFDC_CODE = SET_DIMM_RANKS_CNFG;
///
/// @brief attribute getter
- /// @param[in] i_target the attr target
+ /// @param[in] i_target the fapi2 target
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_dimm_ranks_configed(i_target, o_setting);
}
///
/// @brief attribute setter
- /// @param[in] i_target the attr target
+ /// @param[in] i_target the fapi2 target
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_dimm_ranks_configed(i_target, i_setting);
}
@@ -545,9 +524,9 @@ struct attrEngineTraits<pre_data_init_fields, DIMM_RANKS_CNFG>
///
/// @brief Computes setting for attribute
/// @param[in] i_spd_data SPD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
- ///
+
static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
attr_integral_type& o_setting)
{
@@ -555,8 +534,11 @@ struct attrEngineTraits<pre_data_init_fields, DIMM_RANKS_CNFG>
// a 4R DIMM would be 0b11110000 (0xF0). This is used by PRD.
fapi2::buffer<uint8_t> l_ranks_configed;
+ // Make sure the number of master ranks is setup
uint8_t l_master_ranks = 0;
- FAPI_TRY( get_master_ranks(i_spd_data, SET_ATTR_RANKS_CONFIGED, l_master_ranks) );
+ FAPI_TRY( (attrEngineTraits<proc_type::AXONE, pre_data_init_fields, pre_data_init_fields::MRANKS>::get_value_to_set(
+ i_spd_data,
+ l_master_ranks)) );
FAPI_TRY( l_ranks_configed.setBit(0, l_master_ranks),
"%s. Failed to setBit", spd::c_str(i_spd_data.get_dimm_target()) );
diff --git a/src/import/generic/memory/lib/utils/mcbist/address.H b/src/import/chips/p9a/procedures/hwp/memory/lib/fir/p9a_fir.H
index af12f7144..045c8b5f9 100644
--- a/src/import/generic/memory/lib/utils/mcbist/address.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/fir/p9a_fir.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/generic/memory/lib/utils/mcbist/address.H $ */
+/* $Source: src/import/chips/p9a/procedures/hwp/memory/lib/fir/p9a_fir.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/nimbus_kind.C b/src/import/chips/p9a/procedures/hwp/memory/lib/fir/p9a_fir_traits.H
index fa45be920..19e7f4fa9 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/nimbus_kind.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/fir/p9a_fir_traits.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/nimbus_kind.C $ */
+/* $Source: src/import/chips/p9a/procedures/hwp/memory/lib/fir/p9a_fir_traits.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_scrub.C b/src/import/chips/p9a/procedures/hwp/memory/lib/fir/p9a_unmask.C
index 6e745ea5c..497d5c685 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_scrub.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/fir/p9a_unmask.C
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9a/procedures/hwp/memory/p9a_mss_scrub.C $ */
+/* $Source: src/import/chips/p9a/procedures/hwp/memory/lib/fir/p9a_unmask.C $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_freq_traits.H b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_freq_traits.H
index 1b4f96d0c..3c21636fc 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_freq_traits.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_freq_traits.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -56,14 +56,15 @@ class frequency_traits<mss::proc_type::AXONE>
//////////////////////////////////////////////////////////////
static constexpr fapi2::TargetType PORT_TARGET_TYPE = fapi2::TARGET_TYPE_MEM_PORT;
static constexpr fapi2::TargetType FREQ_TARGET_TYPE = fapi2::TARGET_TYPE_MEM_PORT;
+ static constexpr fapi2::TargetType FREQ_DOMAIN_TARGET_TYPE = fapi2::TARGET_TYPE_PROC_CHIP;
static constexpr fapi2::TargetType VPD_TARGET_TYPE = fapi2::TARGET_TYPE_OCMB_CHIP;
//////////////////////////////////////////////////////////////
// Traits values
//////////////////////////////////////////////////////////////
static const std::vector<uint64_t> SUPPORTED_FREQS;
- // MEM_PORT is our frequency domain. So 1 port per domain
- static constexpr uint64_t PORTS_PER_FREQ_DOMAIN = 1;
+ // PROC_CHIP is our frequency domain
+ static constexpr uint64_t PORTS_PER_FREQ_DOMAIN = 16;
// Max DIMM's per port
static constexpr uint64_t MAX_DIMM_PER_PORT = 2;
// Maxium number of primary ranks on a DIMM
diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_mss_freq.C b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_mss_freq.C
index 08317cb8a..db6556af3 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_mss_freq.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_mss_freq.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,6 +37,10 @@
#include <vpd_access.H>
#include <vector>
+// Explorer rank API
+#include <lib/shared/exp_defaults.H>
+#include <lib/dimm/exp_rank.H>
+
// Memory libraries
#include <lib/freq/axone_freq_traits.H>
#include <lib/shared/axone_consts.H>
@@ -100,10 +104,13 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode set_freq<mss::proc_type::AXONE>(
- const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
const uint64_t i_freq)
{
- FAPI_TRY( mss::attr::set_freq(i_target, i_freq) );
+ for (const auto& l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
+ {
+ FAPI_TRY( mss::attr::set_freq(l_port, i_freq) );
+ }
fapi_try_exit:
return fapi2::current_err;
@@ -130,7 +137,7 @@ fapi_try_exit:
return fapi2::current_err;
}
///
-/// @brief Gets the DIMM type for a specific DIMM - specialization for the NIMBUS processor type
+/// @brief Gets the DIMM type for a specific DIMM - specialization for the AXONE processor type
/// @param[in] i_target DIMM target
/// @param[out] o_dimm_type DIMM type on the DIMM target
/// @return FAPI2_RC_SUCCESS iff ok
@@ -187,7 +194,7 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode callout_bad_freq_calculated<mss::proc_type::AXONE>(
- const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
const uint64_t i_final_freq)
{
using TT = mss::frequency_traits<mss::proc_type::AXONE>;
@@ -218,55 +225,18 @@ fapi_try_exit:
}
///
-/// @brief Return a list of configured ranks on a MEM_PORT
-/// @param[in] i_target the port target
-/// @param[out] o_ranks list of valid ranks on the port
-/// @return FAPI2_RC_SUCCESS iff ok
+/// @brief Determines if rank info object is that of an LR dimm
///
-// TK this function should get replaced by our rank API when available
-fapi2::ReturnCode get_ranks_for_vpd(
- const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
- std::vector<uint64_t>& o_ranks)
+/// @param[in] i_rank_info rank info object
+/// @param[out] l_lr_dimm true if LRDIMM, else false
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if success
+///
+inline fapi2::ReturnCode rank_is_lr_dimm(const mss::rank::info<> i_rank_info, bool& o_lr_dimm)
{
- using TT = mss::frequency_traits<mss::proc_type::AXONE>;
-
- uint8_t l_rank_count_dimm[TT::MAX_DIMM_PER_PORT] = {};
- uint8_t l_dimm_type[TT::MAX_DIMM_PER_PORT] = {};
+ uint8_t l_dimm_type = 0;
+ FAPI_TRY(mss::attr::get_dimm_type(i_rank_info.get_dimm_target(), l_dimm_type));
- o_ranks.clear();
-
- FAPI_TRY( get_master_rank_per_dimm<mss::proc_type::AXONE>(i_target, &(l_rank_count_dimm[0])) );
- FAPI_TRY( get_dimm_type<mss::proc_type::AXONE>(i_target, &(l_dimm_type[0])) );
-
- // So for LRDIMM, our SI works a bit differently than for non-LRDIMM
- // LRDIMM's have buffers that operate on a per-DIMM basis across multiple ranks
- // As such, they act as a single load, similar to a 1R DIMM would
- // per the IBM signal integrity team, the 1R DIMM settings should be used for LRDIMM's
- // So, if we are LRDIMM's and have ranks, we want to only note it as a 1R DIMM for purposes of querying the VPD
- FAPI_DBG("%s for DIMM 0 rank count %u dimm type %u %s",
- mss::c_str(i_target), l_rank_count_dimm[0], l_dimm_type[0], l_dimm_type[0] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
- FAPI_DBG("%s for DIMM 1 rank count %u dimm type %u %s",
- mss::c_str(i_target), l_rank_count_dimm[1], l_dimm_type[1], l_dimm_type[1] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
-
- l_rank_count_dimm[0] = ((l_dimm_type[0] == TT::LRDIMM_TYPE) && (l_rank_count_dimm[0] > 0)) ? 1 : l_rank_count_dimm[0];
- l_rank_count_dimm[1] = ((l_dimm_type[1] == TT::LRDIMM_TYPE) && (l_rank_count_dimm[1] > 0)) ? 1 : l_rank_count_dimm[1];
-
- FAPI_DBG("after LR modification %s for DIMM 0 rank count %u dimm type %u %s",
- mss::c_str(i_target), l_rank_count_dimm[0], l_dimm_type[0], l_dimm_type[0] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
- FAPI_DBG("after LR modification %s for DIMM 1 rank count %u dimm type %u %s",
- mss::c_str(i_target), l_rank_count_dimm[1], l_dimm_type[1], l_dimm_type[1] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
-
- // Add DIMM0's ranks
- for (uint64_t l_rank = 0; l_rank < l_rank_count_dimm[0]; ++l_rank)
- {
- o_ranks.push_back(l_rank);
- }
-
- // Add DIMM1's ranks
- for (uint64_t l_rank = 0; l_rank < l_rank_count_dimm[1]; ++l_rank)
- {
- o_ranks.push_back(l_rank + TT::MAX_PRIMARY_RANK_PER_DIMM);
- }
+ o_lr_dimm = (l_dimm_type == fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_LRDIMM);
fapi_try_exit:
return fapi2::current_err;
@@ -288,37 +258,45 @@ fapi2::ReturnCode check_freq_support_vpd<mss::proc_type::AXONE>( const fapi2::Ta
using TT = mss::frequency_traits<mss::proc_type::AXONE>;
o_supported = false;
- std::vector<uint64_t> l_ranks;
+ std::vector<mss::rank::info<>> l_ranks;
fapi2::VPDInfo<TT::VPD_TARGET_TYPE> l_vpd_info(TT::VPD_BLOB);
const auto& l_vpd_target = mss::find_target<TT::VPD_TARGET_TYPE>(i_target);
+ uint32_t l_omi_freq = 0;
l_vpd_info.iv_is_config_ffdc_enabled = false;
- FAPI_TRY(convert_ddr_freq_to_omi_freq(i_target, i_proposed_freq, l_vpd_info.iv_omi_freq_mhz));
- FAPI_INF("Setting VPD info OMI frequency: %d Gbps, for DDR frequency %d MT/s",
- l_vpd_info.iv_omi_freq_mhz, i_proposed_freq);
+ FAPI_TRY(convert_ddr_freq_to_omi_freq(i_target, i_proposed_freq, l_omi_freq));
+ l_vpd_info.iv_omi_freq_mhz = l_omi_freq;
// DDIMM SPD can contain different SI settings for each master rank.
// To determine which frequencies are supported, we have to check for each valid
// master rank on the port's DIMMs
- FAPI_TRY(get_ranks_for_vpd(i_target, l_ranks));
+ FAPI_TRY(mss::rank::ranks_on_port(i_target, l_ranks));
- for (const auto l_rank : l_ranks)
+ for (const auto& l_rank : l_ranks)
{
- l_vpd_info.iv_rank = l_rank;
- FAPI_INF("%s. VPD info - checking rank: %d",
- mss::c_str(i_target), l_rank);
+ // We will skip LRDIMMs with ranks > 0
+ bool l_is_lr_dimm = false;
+ FAPI_TRY(rank_is_lr_dimm(l_rank, l_is_lr_dimm));
+
+ if (rank_not_supported_in_vpd_config(l_is_lr_dimm, l_rank.get_dimm_rank()))
+ {
+ FAPI_DBG("LRDIMM ranks > 0 are not supported for check_freq_support_vpd. Skipping this rank. Target: %s",
+ mss::c_str(i_target));
+ continue;
+ }
+
+ l_vpd_info.iv_rank = l_rank.get_dimm_rank();
// Check if this VPD configuration is supported
FAPI_TRY(is_vpd_config_supported<mss::proc_type::AXONE>(l_vpd_target, i_proposed_freq, l_vpd_info, o_supported),
- "%s failed to determine if %u freq is supported", mss::c_str(i_target), i_proposed_freq);
-
+ "%s failed to determine if %u freq is supported on rank %d", mss::c_str(i_target), i_proposed_freq, l_vpd_info.iv_rank);
// If we fail any of the ranks, then this VPD configuration is not supported
if(o_supported == false)
{
- FAPI_INF("%s is not supported on rank%u exiting...", mss::c_str(i_target), l_rank);
+ FAPI_INF("%s is not supported on rank %u exiting...", mss::c_str(i_target), l_rank.get_port_rank());
break;
}
}
@@ -328,29 +306,34 @@ fapi_try_exit:
}
///
-/// @brief Update supported frequency scoreboard according to processor limits - specialization for Axone and MEM_PORT
+/// @brief Update supported frequency scoreboard according to processor limits - specialization for Axone and PROC_CHIP
/// @param[in] i_target processor frequency domain
/// @param[in,out] io_scoreboard scoreboard of port targets supporting each frequency
/// @return FAPI2_RC_SUCCESS iff ok
///
template<>
fapi2::ReturnCode limit_freq_by_processor<mss::proc_type::AXONE>(
- const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
freq_scoreboard& io_scoreboard)
{
- std::vector<uint64_t> l_converted_omi_freqs;
-
// OCMB always needs to be in sync between OMI and DDR, by the given ratio
// so we convert the supported OMI freqs and remove every other DDR freq
// from the scoreboard
- for (const auto l_omi_freq : AXONE_OMI_FREQS)
+ for (const auto& l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
{
- uint64_t l_ddr_freq = 0;
- FAPI_TRY(convert_omi_freq_to_ddr_freq(i_target, l_omi_freq, l_ddr_freq));
- l_converted_omi_freqs.push_back(l_ddr_freq);
- }
+ const auto l_port_pos = mss::relative_pos<fapi2::TARGET_TYPE_PROC_CHIP>(l_port);
- FAPI_TRY(io_scoreboard.remove_freqs_not_on_list(0, l_converted_omi_freqs));
+ std::vector<uint64_t> l_converted_omi_freqs;
+
+ for (const auto l_omi_freq : AXONE_OMI_FREQS)
+ {
+ uint64_t l_ddr_freq = 0;
+ FAPI_TRY(convert_omi_freq_to_ddr_freq(l_port, l_omi_freq, l_ddr_freq));
+ l_converted_omi_freqs.push_back(l_ddr_freq);
+ }
+
+ FAPI_TRY(io_scoreboard.remove_freqs_not_on_list(l_port_pos, l_converted_omi_freqs));
+ }
fapi_try_exit:
return fapi2::current_err;
@@ -374,12 +357,12 @@ fapi2::ReturnCode num_master_ranks_per_dimm<mss::proc_type::AXONE>(
/// @brief Calls out the target if no DIMM frequencies are supported - specialization for Axone and MEM_PORT
/// @param[in] i_target target on which to operate
/// @param[in] i_supported_freq true if any FREQ's are supported
-/// @param[in,out] i_num_ports number of configured ports (always 1 for Axone)
+/// @param[in,out] i_num_ports number of configured ports
/// @return FAPI2_RC_SUCCESS iff ok
///
template<>
fapi2::ReturnCode callout_no_common_freq<mss::proc_type::AXONE>(
- const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
const bool i_supported_freq,
const uint64_t i_num_ports)
{
@@ -408,7 +391,7 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode callout_max_freq_empty_set<mss::proc_type::AXONE>(
- const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
const std::vector<std::vector<uint32_t>>& i_vpd_supported_freqs)
{
@@ -423,21 +406,26 @@ fapi2::ReturnCode callout_max_freq_empty_set<mss::proc_type::AXONE>(
uint32_t l_max_mrw_freqs[NUM_MAX_FREQS] = {0};
FAPI_TRY( mss::attr::get_max_allowed_dimm_freq(l_max_mrw_freqs) );
- FAPI_ASSERT(false,
- fapi2::P9A_MSS_MRW_FREQ_MAX_FREQ_EMPTY_SET()
- .set_MSS_VPD_FREQ_0(l_port_vpd_max_freq[0])
- .set_MSS_VPD_FREQ_1(l_port_vpd_max_freq[1])
- .set_MSS_VPD_FREQ_2(l_port_vpd_max_freq[2])
- .set_MSS_MAX_FREQ_0(l_max_mrw_freqs[0])
- .set_MSS_MAX_FREQ_1(l_max_mrw_freqs[1])
- .set_MSS_MAX_FREQ_2(l_max_mrw_freqs[2])
- .set_MSS_MAX_FREQ_3(l_max_mrw_freqs[3])
- .set_MSS_MAX_FREQ_4(l_max_mrw_freqs[4])
- .set_OMI_FREQ_0(fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_21_33GBPS)
- .set_OMI_FREQ_1(fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_23_46GBPS)
- .set_OMI_FREQ_2(fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_25_60GBPS)
- .set_PORT_TARGET(i_target),
- "%s didn't find a supported frequency for the port", mss::c_str(i_target));
+ for (const auto& l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
+ {
+ FAPI_ASSERT_NOEXIT(false,
+ fapi2::P9A_MSS_MRW_FREQ_MAX_FREQ_EMPTY_SET()
+ .set_MSS_VPD_FREQ_0(l_port_vpd_max_freq[0])
+ .set_MSS_VPD_FREQ_1(l_port_vpd_max_freq[1])
+ .set_MSS_VPD_FREQ_2(l_port_vpd_max_freq[2])
+ .set_MSS_MAX_FREQ_0(l_max_mrw_freqs[0])
+ .set_MSS_MAX_FREQ_1(l_max_mrw_freqs[1])
+ .set_MSS_MAX_FREQ_2(l_max_mrw_freqs[2])
+ .set_MSS_MAX_FREQ_3(l_max_mrw_freqs[3])
+ .set_MSS_MAX_FREQ_4(l_max_mrw_freqs[4])
+ .set_OMI_FREQ_0(fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_21_33GBPS)
+ .set_OMI_FREQ_1(fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_23_46GBPS)
+ .set_OMI_FREQ_2(fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_25_60GBPS)
+ .set_TARGET(l_port),
+ "%s didn't find a supported frequency for any ports in this domain", mss::c_str(l_port));
+ }
+
+ return fapi2::RC_P9A_MSS_MRW_FREQ_MAX_FREQ_EMPTY_SET;
fapi_try_exit:
return fapi2::current_err;
@@ -446,14 +434,14 @@ namespace check
{
///
-/// @brief Checks the final frequency for the system type - Axone and MEM_PORT specialization
+/// @brief Checks the final frequency for the system type - Axone and PROC_CHIP specialization
/// @param[in] i_target the target on which to operate
/// @return FAPI2_RC_SUCCESS iff okay
/// @note This function was needed in Nimbus to enforce a frequency limit due to a hardware limitation
/// and is not needed here.
///
template<>
-fapi2::ReturnCode final_freq<mss::proc_type::AXONE>(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target)
+fapi2::ReturnCode final_freq<mss::proc_type::AXONE>(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
return fapi2::FAPI2_RC_SUCCESS;
}
diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.C b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.C
index 8fd3c679b..1e3aea1a5 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -156,7 +156,7 @@ fapi_try_exit:
///
bool deconfigure(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
const uint64_t i_dimm_speed,
- const uint32_t i_max_freq)
+ const uint64_t i_max_freq)
{
bool l_is_hw_deconfigured = (i_dimm_speed != i_max_freq);
@@ -174,44 +174,42 @@ bool deconfigure(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
}
///
-/// @brief Selects synchronous mode and performs requirements enforced by selected port frequency
+/// @brief Selects OMI frequency based on selected port frequencies
/// @param[in] i_freq_map dimm speed mapping
/// @param[in] i_equal_dimm_speed tracks whether map has equal dimm speeds
/// @param[in] i_omi_freq OMI frequency
-/// @param[out] o_selected_sync_mode final synchronous mode
-/// @param[out] o_selected_omi_freq final freq selected, only valid if final sync mode is in-sync
+/// @param[out] o_selected_omi_freq final freq selected
/// @return FAPI2_RC_SUCCESS iff successful
///
-fapi2::ReturnCode select_sync_mode(const std::map< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>, uint64_t >& i_freq_map,
- const speed_equality i_equal_dimm_speed,
- const uint32_t i_omi_freq,
- uint8_t& o_selected_sync_mode,
- uint64_t& o_selected_omi_freq)
+fapi2::ReturnCode select_omi_freq(const std::map< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>, uint64_t >& i_freq_map,
+ const speed_equality i_equal_dimm_speed,
+ const uint32_t i_omi_freq,
+ uint32_t& o_selected_omi_freq)
{
- FAPI_INF("---- In select_sync_mode ----");
-
switch(i_equal_dimm_speed)
{
- // If we have a port which has resolved to equal speeds ...
+ // If we resolved to equal speeds ...
case speed_equality::EQUAL_DIMM_SPEEDS:
{
// Return back the resulting speed. It doesn't matter which we select from the map as they're all equal
// If we end up not in sync in the conditional below, thats ok - this parameter is ignored by the
// caller if we're not in sync mode
const auto l_ddr_freq = i_freq_map.begin()->second;
- FAPI_TRY(convert_ddr_freq_to_omi_freq(i_freq_map.begin()->first, l_ddr_freq, o_selected_omi_freq));
+ FAPI_TRY(convert_ddr_freq_to_omi_freq(i_freq_map.begin()->first,
+ l_ddr_freq,
+ o_selected_omi_freq));
// When we selected ATTR_MSS_FREQ, we made sure that we didn't
// select a DIMM freq the OMI couldn't support.
- o_selected_sync_mode = fapi2::ENUM_ATTR_MC_SYNC_MODE_IN_SYNC;
+
+#ifndef __HOSTBOOT_MODULE
// On Cronus if the o_selected_omi_freq != i_omi_freq we've got a mismatch. Note that p9a_mss_freq ensures
// we don't select an invalid freq, but doesn't ensure we select the current OMI freq.
-#ifndef __HOSTBOOT_MODULE
FAPI_ASSERT(o_selected_omi_freq == i_omi_freq,
fapi2::P9A_MSS_FAILED_SYNC_MODE()
.set_OMI_FREQ(i_omi_freq)
.set_MEM_FREQ(o_selected_omi_freq),
- "The DIMM freq (%d) and the OMI freq (%d) don't align",
+ "The OMI freq selected by DIMM speed (%d) and the currently selected OMI freq (%d) don't align",
o_selected_omi_freq, i_omi_freq);
#endif
return fapi2::FAPI2_RC_SUCCESS;
@@ -223,13 +221,14 @@ fapi2::ReturnCode select_sync_mode(const std::map< fapi2::Target<fapi2::TARGET_T
// When we selected ATTR_MSS_FREQ, we made sure that we didn't
// select a DIMM freq the OMI couldn't support. That means that the fastest of the ports
// is the one that rules the roost (the OMI can support it too.) So find that, and set it to
- // the selected frequency. Then deconfigure the slower port (unless we're in Cronus in which
+ // the selected frequency. Then deconfigure the slower ports (unless we're in Cronus in which
// case we just bomb out.)
#ifdef __HOSTBOOT_MODULE
uint64_t l_max_dimm_speed = 0;
fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> l_fastest_port_target = i_freq_map.begin()->first;
std::for_each(i_freq_map.begin(), i_freq_map.end(),
- [&l_max_dimm_speed, &l_fastest_port_target](const std::pair<fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>, uint64_t>& m)
+ [&l_max_dimm_speed, &l_fastest_port_target]
+ (const std::pair<fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>, uint64_t>& m)
{
l_max_dimm_speed = std::max(l_max_dimm_speed, m.second);
l_fastest_port_target = m.first;
@@ -241,15 +240,16 @@ fapi2::ReturnCode select_sync_mode(const std::map< fapi2::Target<fapi2::TARGET_T
deconfigure(m.first, m.second, l_max_dimm_speed);
});
- o_selected_sync_mode = fapi2::ENUM_ATTR_MC_SYNC_MODE_IN_SYNC;
- FAPI_TRY(convert_ddr_freq_to_omi_freq(l_fastest_port_target, l_max_dimm_speed, o_selected_omi_freq));
+ FAPI_TRY(convert_ddr_freq_to_omi_freq(l_fastest_port_target,
+ l_max_dimm_speed,
+ o_selected_omi_freq));
return fapi2::FAPI2_RC_SUCCESS;
#else
// Cronus only
FAPI_ASSERT(false,
fapi2::P9A_MSS_FAILED_SYNC_MODE()
.set_OMI_FREQ(i_omi_freq),
- "DIMM speeds differ from OMI speed %d", i_omi_freq);
+ "Some DIMM speeds are incompatible with OMI speed %d", i_omi_freq);
#endif
break;
}
diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H
index 06345713c..29436db00 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H
@@ -43,6 +43,7 @@
#include <mss_generic_attribute_getters.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <lib/shared/axone_consts.H>
+#include <lib/freq/axone_freq_traits.H>
#include <generic/memory/lib/utils/freq/mss_freq_scoreboard.H>
#include <generic/memory/lib/utils/c_str.H>
#include <generic/memory/lib/utils/mss_math.H>
@@ -60,6 +61,18 @@ static const std::vector<uint64_t> AXONE_OMI_FREQS =
};
///
+/// @brief determines if rank is not supported in VPD config, will be skipped in check_freq_support_vpd()
+///
+/// @param[in] i_is_lr_dimm is LR
+/// @param[in] i_dimm_rank DIMM rank
+/// @return true if LR & rank > 0, else false
+///
+inline bool rank_not_supported_in_vpd_config(const bool i_is_lr_dimm, const uint8_t i_dimm_rank)
+{
+ return (i_is_lr_dimm && i_dimm_rank > 0);
+}
+
+///
/// @brief Converts an OMI frequency attribute enum to the corresponding OMI frequency
/// @param[in] i_omi_enum a frequency enum value that is to be converted
/// @return the corresponding OMI frequency
@@ -99,18 +112,19 @@ fapi_try_exit:
///
inline fapi2::ReturnCode convert_ddr_freq_to_omi_freq(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
const uint64_t i_ddr_freq,
- uint64_t& o_omi_freq)
+ uint32_t& o_omi_freq)
{
using TT = mss::frequency_traits<mss::proc_type::AXONE>;
constexpr uint64_t ROUND_UNITS = 10;
+ uint64_t l_omi_freq = 0;
// Get the OMI to DDR freq ratio
uint8_t l_ratio[TT::MAX_DIMM_PER_PORT] = {0};
FAPI_TRY(mss::attr::get_host_to_ddr_speed_ratio(i_target, l_ratio));
// Multiply by the ratio and round to the nearest 10GBPS
- FAPI_TRY(mss::divide_and_round((i_ddr_freq * l_ratio[0]), ROUND_UNITS, o_omi_freq));
- o_omi_freq *= ROUND_UNITS;
+ FAPI_TRY(mss::divide_and_round((i_ddr_freq * l_ratio[0]), ROUND_UNITS, l_omi_freq));
+ o_omi_freq = ROUND_UNITS * l_omi_freq;
FAPI_DBG("For ratio %d and DDR freq %d, corresponding OMI freq is %d", l_ratio[0], i_ddr_freq, o_omi_freq);
fapi_try_exit:
@@ -125,7 +139,7 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff successful
///
inline fapi2::ReturnCode convert_omi_freq_to_ddr_freq(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
- const uint64_t i_omi_freq,
+ const uint32_t i_omi_freq,
uint64_t& o_ddr_freq)
{
using TT = mss::frequency_traits<mss::proc_type::AXONE>;
@@ -134,7 +148,7 @@ inline fapi2::ReturnCode convert_omi_freq_to_ddr_freq(const fapi2::Target<fapi2:
uint8_t l_ratio[TT::MAX_DIMM_PER_PORT] = {0};
FAPI_TRY(mss::attr::get_host_to_ddr_speed_ratio(i_target, l_ratio));
- FAPI_TRY(mss::divide_and_round(i_omi_freq, static_cast<uint64_t>(l_ratio[0]), o_ddr_freq),
+ FAPI_TRY(mss::divide_and_round(static_cast<uint64_t>(i_omi_freq), static_cast<uint64_t>(l_ratio[0]), o_ddr_freq),
"%s freq system saw a zero Host (OMI) to DDR frequency ratio", mss::c_str(i_target));
FAPI_DBG( "For ratio %d and OMI freq %d, corresponding DDR freq is %d", l_ratio[0], i_omi_freq, o_ddr_freq);
@@ -143,26 +157,6 @@ fapi_try_exit:
}
///
-/// @brief Checks to see if a passed in value could be a valid OMI frequency
-/// @param[in] i_target the port target
-/// @param[in] i_proposed_freq a frequency value that is to be checked
-/// @param[out] o_valid boolean whether the value is a valid OMI frequency
-/// @return FAPI2_RC_SUCCESS iff successful
-///
-inline fapi2::ReturnCode is_omi_freq_valid (const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
- const uint64_t i_proposed_freq,
- uint64_t& o_valid)
-{
- uint64_t l_proposed_omi_freq = 0;
- FAPI_TRY(convert_ddr_freq_to_omi_freq(i_target, i_proposed_freq, l_proposed_omi_freq));
-
- o_valid = std::binary_search(AXONE_OMI_FREQS.begin(), AXONE_OMI_FREQS.end(), l_proposed_omi_freq);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief Retrieves a mapping of MSS frequency values per port target
/// @param[in] i_targets vector of port targets
/// @param[out] o_freq_map dimm speed map <key, value> = (port target, frequency)
@@ -182,22 +176,20 @@ fapi2::ReturnCode dimm_speed_map(const std::vector< fapi2::Target<fapi2::TARGET_
///
bool deconfigure(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
const uint64_t i_dimm_speed,
- const uint32_t i_omi_freq);
+ const uint64_t i_omi_freq);
///
-/// @brief Selects synchronous mode and performs requirements enforced by selected port frequency
+/// @brief Selects OMI frequency based on selected port frequencies
/// @param[in] i_freq_map dimm speed mapping
/// @param[in] i_equal_dimm_speed tracks whether map has equal dimm speeds
/// @param[in] i_omi_freq OMI frequency
-/// @param[out] o_selected_sync_mode final synchronous mode
-/// @param[out] o_selected_omi_freq final freq selected, only valid if final sync mode is in-sync
+/// @param[out] o_selected_omi_freq final freq selected
/// @return FAPI2_RC_SUCCESS iff successful
///
-fapi2::ReturnCode select_sync_mode(const std::map< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>, uint64_t >& i_freq_map,
- const speed_equality i_equal_dimm_speed,
- const uint32_t i_omi_freq,
- uint8_t& o_selected_sync_mode,
- uint64_t& o_selected_omi_freq);
+fapi2::ReturnCode select_omi_freq(const std::map< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>, uint64_t >& i_freq_map,
+ const speed_equality i_equal_dimm_speed,
+ const uint32_t i_omi_freq,
+ uint32_t& o_selected_omi_freq);
}// mss
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_scrub.H b/src/import/chips/p9a/procedures/hwp/memory/lib/mc/host_mc_traits.H
index a71466b4a..e849eafea 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_scrub.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/mc/host_mc_traits.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9a/procedures/hwp/memory/p9a_mss_scrub.H $ */
+/* $Source: src/import/chips/p9a/procedures/hwp/memory/lib/mc/host_mc_traits.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/mc/omi.H b/src/import/chips/p9a/procedures/hwp/memory/lib/mc/omi.H
index 1298699b5..48f5cb222 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/lib/mc/omi.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/mc/omi.H
@@ -46,7 +46,10 @@
#include <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/buffer_ops.H>
#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <generic/memory/lib/mss_generic_system_attribute_getters.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
+#include <mss_p9a_attribute_getters.H>
namespace mss
{
@@ -54,327 +57,8 @@ namespace mss
namespace mc
{
-
-///
-/// @brief These values are the number of clock cycles and the times specified assume a 625ps period.
-/// This timer value must be greater than the di/dt timer
-///
-enum rx_cdr_timer
-{
- CDR_TIMER_DISABLED = 0b0001,
- CDR_TIMER_60NS = 0b0001,
- CDR_TIMER_125NS = 0b0010,
- CDR_TIMER_185NS = 0b0011,
- CDR_TIMER_250NS = 0b0100,
- CDR_TIMER_375NS = 0b0101,
- CDR_TIMER_500NS = 0b0110,
- CDR_TIMER_750NS = 0b0111,
- CDR_TIMER_1US = 0b1000,
- CDR_TIMER_2US = 0b1001,
- CDR_TIMER_4US = 0b1010,
- CDR_TIMER_8US = 0b1011,
- CDR_TIMER_16US = 0b1100,
- CDR_TIMER_32US = 0b1101,
- CDR_TIMER_64US = 0b1110,
- CDR_TIMER_128US = 0b1111
-};
-
-///
-/// @brief Amount of time to wait after lane is turned on/off before another lane can be turned on/off
-///
-enum didt_timer
-{
- DIDT_TIMER_DISABLED = 0b0000,
- DIDT_TIMER_5NS = 0b0001,
- DIDT_TIMER_10NS = 0b0010,
- DIDT_TIMER_15NS = 0b0011,
- DIDT_TIMER_20NS = 0b0100,
- DIDT_TIMER_30NS = 0b0101,
- DIDT_TIMER_45NS = 0b0110,
- DIDT_TIMER_60NS = 0b0111,
- DIDT_TIMER_90NS = 0b1000,
- DIDT_TIMER_125NS = 0b1001,
- DIDT_TIMER_185NS = 0b1010,
- DIDT_TIMER_250NS = 0b1011,
- DIDT_TIMER_375NS = 0b1100,
- DIDT_TIMER_500NS = 0b1101,
- DIDT_TIMER_768NS = 0b1110,
- DIDT_TIMER_1US = 0b1111
-};
-
-///
-/// @brief Calibration timer - amount of time betweem re-calibration for a given lane
-///
-enum recal_timer
-{
- RECAL_TIMER_DISABLED = 0b000,
- RECAL_TIMER_25MS = 0b001,
- RECAL_TIMER_50MS = 0b010,
- RECAL_TIMER_100MS = 0b011,
- RECAL_TIMER_200MS = 0b100,
- RECAL_TIMER_400MS = 0b101,
- RECAL_TIMER_800MS = 0b110,
- RECAL_TIMER_1600MS = 0b111
-};
-
-///
-/// @brief PMU prescalar value
-///
-enum pmu_prescalar
-{
- PRESCALAR_16BIT = 0b000,
- PRESCALAR_8BIT = 0b001,
- PRESCALAR_20BIT = 0b100,
-};
-
-
-///
-/// @brief PMU cntrx pair selector
-///
-enum cntrl_pair_selector
-{
- SEL_ODD = 0b00,
- SEL_EVEN = 0b01,
- SEL_BOTH_AND = 0b10,
- SEL_BOTH_XOR = 0b11
-};
-
-///
-/// @brief PMU cntrx event selector
///
-enum cntrl_event_selector
-{
- SIG_7_6 = 0b00,
- SIG_5_4 = 0b01,
- SIG_3_2 = 0b10,
- SIG_1_0 = 0b11
-};
-
-///
-/// @brief dl0 no forward progress timer
-///
-enum no_forward_progress_timer
-{
- NO_FORWARD_TIMER_1US = 0b0000,
- NO_FORWARD_TIMER_2US = 0b0001,
- NO_FORWARD_TIMER_4US = 0b0010,
- NO_FORWARD_TIMER_8US = 0b0011,
- NO_FORWARD_TIMER_16US = 0b0100,
- NO_FORWARD_TIMER_32US = 0b0101,
- NO_FORWARD_TIMER_64US = 0b0110,
- NO_FORWARD_TIMER_128US = 0b0111,
- NO_FORWARD_TIMER_256US = 0b1000,
- NO_FORWARD_TIMER_512US = 0b1001,
- NO_FORWARD_TIMER_1MS = 0b1010,
- NO_FORWARD_TIMER_2MS = 0b1011,
- NO_FORWARD_TIMER_4MS = 0b1100,
- NO_FORWARD_TIMER_8MS = 0b1101,
- NO_FORWARD_TIMER_16MS = 0b1110,
- NO_FORWARD_TIMER_DISABLED = 0b1111
-};
-
-///
-/// @brief dl0 PHY control mode - determines the amount of time needed to receive pattern A or pattern B
-///
-enum phy_ctr_mode
-{
- PHY_CTR_MODE_1US = 0b0000,
- PHY_CTR_MODE_50US = 0b0001,
- PHY_CTR_MODE_100US = 0b0010,
- PHY_CTR_MODE_200US = 0b0011,
- PHY_CTR_MODE_500US = 0b0100,
- PHY_CTR_MODE_1MS = 0b0101,
- PHY_CTR_MODE_2MS = 0b0110,
- PHY_CTR_MODE_3MS = 0b0111,
- PHY_CTR_MODE_4MS = 0b1000,
- PHY_CTR_MODE_5MS = 0b1001,
- PHY_CTR_MODE_6MS = 0b1010,
- PHY_CTR_MODE_8MS = 0b1011,
- PHY_CTR_MODE_10MS = 0b1100,
- PHY_CTR_MODE_15MS = 0b1101,
- PHY_CTR_MODE_30MS = 0b1110,
- PHY_CTR_MODE_60MS = 0b1111
-};
-
-///
-/// @brief dl0 supported link widths
-///
-enum link_widths
-{
- LINK_WIDTHS_X4PLUS1 = 0b1000,
- LINK_WIDTHS_X16 = 0b0100,
- LINK_WIDTHS_X8 = 0b0010,
- LINK_WIDTHS_X4 = 0b0001
-};
-
-///
-/// @brief dl0 train mode
-///
-enum train_mode
-{
- TX_ZEROS = 0b0000,
- TX_PATTERN_A = 0b0001,
- TX_PATTERN_B = 0b0010,
- TX_SYNC_PATTERN = 0b0011,
- TX_TRAINING_STATE1 = 0b0100,
- TX_TRAINING_STATE2 = 0b0101,
- TX_TRAINING_STATE3 = 0b0110,
- TX_TRAINING_STATE0 = 0b0111,
- ENABLE_AUTO_TRAINING = 0b1000
-};
-
-///
-/// @brief Configuration override to select lane width for dynamic lane power down modes.
-///
-enum lan_width_override
-{
- TL_CTR_BY_SIDEBAND = 0b00,
- DL_OVERRIDE_X2 = 0b01,
- DL_OVERRIDE_X4 = 0b10,
- DL_OVERRIDE_X8 = 0b11
-};
-
-///
-/// @brief Number of consecutive pattern B seen before indicating received pattern B
-///
-enum b_hysteresis
-{
- B_HYSTERESIS_16 = 0b0000,
- B_HYSTERESIS_24 = 0b0001,
- B_HYSTERESIS_32 = 0b0010,
- B_HYSTERESIS_40 = 0b0011,
- B_HYSTERESIS_48 = 0b0100,
- B_HYSTERESIS_56 = 0b0101,
- B_HYSTERESIS_64 = 0b0110,
- B_HYSTERESIS_72 = 0b0111,
- B_HYSTERESIS_80 = 0b1000,
- B_HYSTERESIS_96 = 0b1001,
- B_HYSTERESIS_128 = 0b1010,
- B_HYSTERESIS_256 = 0b1011,
- B_HYSTERESIS_512 = 0b1100,
- B_HYSTERESIS_1K = 0b1101,
- B_HYSTERESIS_2K = 0b1110,
- B_HYSTERESIS_4K = 0b1111
-};
-
-///
-/// @brief Number of consecutive pattern A seen before indicating received pattern A.
-///
-enum a_hysteresis
-{
- A_HYSTERESIS_16 = 0b0000,
- A_HYSTERESIS_24 = 0b0001,
- A_HYSTERESIS_32 = 0b0010,
- A_HYSTERESIS_48 = 0b0011,
- A_HYSTERESIS_64 = 0b0100,
- A_HYSTERESIS_96 = 0b0101,
- A_HYSTERESIS_128 = 0b0110,
- A_HYSTERESIS_256 = 0b0111,
- A_HYSTERESIS_512 = 0b1000,
- A_HYSTERESIS_1024 = 0b1001,
- A_HYSTERESIS_2K = 0b1010,
- A_HYSTERESIS_4K = 0b1011,
- A_HYSTERESIS_8K = 0b1100,
- A_HYSTERESIS_16K = 0b1101,
- A_HYSTERESIS_32K = 0b1110,
- A_HYSTERESIS_64K = 0b1111
-};
-
-///
-/// @brief Lanes disabled
-///
-enum
-{
- LANE_DISABLED_NONE = 0b00000000,
- LANE_DISABLED_7 = 0b00000001,
- LANE_DISABLED_6 = 0b00000010,
- LANE_DISABLED_5 = 0b00000100,
- LANE_DISABLED_4 = 0b00001000,
- LANE_DISABLED_3 = 0b00010000,
- LANE_DISABLED_2 = 0b00100000,
- LANE_DISABLED_1 = 0b01000000,
- LANE_DISABLED_0 = 0b10000000
-};
-
-///
-/// @brief dl0 inject crc direction
-///
-enum crc_inject_dir
-{
- CRC_DIR_RX = 0,
- CRC_DIR_TX = 1
-};
-
-///
-/// @brief dl0 crc injection rate
-///
-enum crc_inject_rate
-{
- CRC_INJ_RATE_1US = 0b0000,
- CRC_INJ_RATE_8US = 0b0001,
- CRC_INJ_RATE_64US = 0b0010,
- CRC_INJ_RATE_512US = 0b0011,
- CRC_INJ_RATE_4MS = 0b0100,
- CRC_INJ_RATE_32MS = 0b0101,
- CRC_INJ_RATE_256MS = 0b0110,
- CRC_INJ_RATE_2S = 0b0111
-};
-
-///
-/// @brief CFG_DL0_EDPL_TIME: dl0 edpl time window
-///
-enum edpl_time_win
-{
- EDPL_TIME_WIN_NO = 0b0000,
- EDPL_TIME_WIN_4US = 0b0001,
- EDPL_TIME_WIN_32US = 0b0010,
- EDPL_TIME_WIN_256US = 0b0011,
- EDPL_TIME_WIN_2MS = 0b0100,
- EDPL_TIME_WIN_16MS = 0b0101,
- EDPL_TIME_WIN_128MS = 0b0110,
- EDPL_TIME_WIN_1S = 0b0111,
- EDPL_TIME_WIN_8S = 0b1000,
- EDPL_TIME_WIN_64S = 0b1001,
- EDPL_TIME_WIN_512S = 0b1010,
- EDPL_TIME_WIN_4KS = 0b1011,
- EDPL_TIME_WIN_32KS = 0b1100,
- EDPL_TIME_WIN_256KS = 0b1101,
- EDPL_TIME_WIN_2MILLIONS = 0b1110,
- EDPL_TIME_WIN_16MILLIONS = 0b1111
-};
-
-///
-/// @brief CFG_DL0_EDPL_THRESHOLD: dl0 edpl threshold
-///
-enum edpl_err_thres
-{
- EDPL_ERR_THRES_DISABLED = 0b000,
- EDPL_ERR_THRES_2 = 0b001,
- EDPL_ERR_THRES_4 = 0b010,
- EDPL_ERR_THRES_8 = 0b011,
- EDPL_ERR_THRES_16 = 0b100,
- EDPL_ERR_THRES_32 = 0b101,
- EDPL_ERR_THRES_64 = 0b110,
- EDPL_ERR_THRES_128 = 0b111
-};
-
-///
-/// @brief CONFIG1_CFG_PREIPL_PRBS_TIME: config1 pre-ipl prbs time
-///
-enum preipl_prbs_time
-{
- PREIPL_PRBS_256US = 0b000,
- PREIPL_PRBS_1US = 0b001,
- PREIPL_PRBS_4MS = 0b010,
- PREIPL_PRBS_16MS = 0b011,
- PREIPL_PRBS_64MS = 0b100,
- PREIPL_PRBS_256MS = 0b101,
- PREIPL_PRBS_1S = 0b110,
- PREIPL_PRBS_4S = 0b111
-};
-
-///
-/// @brief Helper function to setup the CMN_CONFIG
+/// @brief Function to setup the CMN_CONFIG
/// @tparam PROC the proc type
/// @tparam T the fapi2 target type of the target
/// @tparam TT the class traits for the omi
@@ -382,31 +66,31 @@ enum preipl_prbs_time
/// @return FAPI2_RC_SUCCESS iff ok
///
template< mss::proc_type PROC = DEFAULT_PROC_TYPE, fapi2::TargetType T, typename TT = omiTraits<T, PROC>>
-fapi2::ReturnCode setup_mc_mcn_config_helper(const fapi2::Target<T>& i_target)
+fapi2::ReturnCode setup_mc_mcn_config(const fapi2::Target<T>& i_target)
{
// The value is 0x042364008874630F
fapi2::buffer<uint64_t> l_val;
// CFG_CMN_SPARE: Spare
- l_val.template insertFromRight< TT::MC_REG0_CMN_CONFIG_SPARE, TT::MC_REG0_CMN_CONFIG_SPARE_LEN>(0);
+ l_val.insertFromRight< TT::MC_REG0_CMN_CONFIG_SPARE, TT::MC_REG0_CMN_CONFIG_SPARE_LEN>(0);
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_PM_CDR_TIMER, TT::MC_REG0_CMN_CONFIG_PM_CDR_TIMER_LEN>
- (CDR_TIMER_250NS);
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_PM_CDR_TIMER, TT::MC_REG0_CMN_CONFIG_PM_CDR_TIMER_LEN>
+ (mss::omi::rx_cdr_timer::CDR_TIMER_250NS);
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_PM_DIDT_TIMER, TT::MC_REG0_CMN_CONFIG_PM_DIDT_TIMER_LEN>
- (DIDT_TIMER_10NS);
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_PM_DIDT_TIMER, TT::MC_REG0_CMN_CONFIG_PM_DIDT_TIMER_LEN>
+ (mss::omi::didt_timer::DIDT_TIMER_10NS);
- l_val.template writeBit<TT::MC_REG0_CMN_CONFIG_PSAV_STS_ENABLE>(0);
+ l_val.writeBit<TT::MC_REG0_CMN_CONFIG_PSAV_STS_ENABLE>(0);
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_RECAL_TIMER, TT::MC_REG0_CMN_CONFIG_RECAL_TIMER_LEN>
- (RECAL_TIMER_100MS);
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_RECAL_TIMER, TT::MC_REG0_CMN_CONFIG_RECAL_TIMER_LEN>
+ (mss::omi::recal_timer::RECAL_TIMER_100MS);
// CFG_CMN_1US_TMR: Number of cycles in 1us. Needs to be changed based on clock frequency
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_CFG_CMN_1US_TMR, TT::MC_REG0_CMN_CONFIG_CFG_CMN_1US_TMR_LEN>
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_CFG_CMN_1US_TMR, TT::MC_REG0_CMN_CONFIG_CFG_CMN_1US_TMR_LEN>
(1600);
// CFG_CMN_DBG_EN: Enable the debug logic
- l_val.template writeBit<TT::MC_REG0_CMN_CONFIG_CFG_CMN_DBG_EN>(0);
+ l_val.writeBit<TT::MC_REG0_CMN_CONFIG_CFG_CMN_DBG_EN>(0);
// CFG_CMN_DBG_SEL: Debug select
// 000 - zeros
@@ -419,40 +103,48 @@ fapi2::ReturnCode setup_mc_mcn_config_helper(const fapi2::Target<T>& i_target)
// 11 bits from all 3 DLs plus
// 33 bits from common macro 2
// 111 - zeros
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_DBG_SEL, TT::MC_REG0_CMN_CONFIG_DBG_SEL_LEN>(0);
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_DBG_SEL, TT::MC_REG0_CMN_CONFIG_DBG_SEL_LEN>(0);
// CFG_CMN_RD_RST: Reset the PMU counters when the PMU counters are read
- l_val.template writeBit<TT::MC_REG0_CMN_CONFIG_RD_RST>(1);
+ l_val.writeBit<TT::MC_REG0_CMN_CONFIG_RD_RST>(1);
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_PRE_SCALAR, TT::MC_REG0_CMN_CONFIG_PRE_SCALAR_LEN>
- (PRESCALAR_16BIT);
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_PRE_SCALAR, TT::MC_REG0_CMN_CONFIG_PRE_SCALAR_LEN>
+ (mss::omi::pmu_prescalar::PRESCALAR_16BIT);
// CFG_CMN_FREEZE: PMU freeze mode - when set, the PMU will stop all counters when 1 of the counters wraps.
- l_val.template writeBit<TT::MC_REG0_CMN_CONFIG_CFG_CMN_FREEZE>(1);
+ l_val.writeBit<TT::MC_REG0_CMN_CONFIG_CFG_CMN_FREEZE>(1);
// CFG_CMN_PORT_SEL: PMU port select - select which of the 8 groups of inputs will be used by the PMU.
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_PORT_SEL, TT::MC_REG0_CMN_CONFIG_PORT_SEL_LEN>(0);
-
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR3_PS, TT::MC_REG0_CMN_CONFIG_CNTR3_PS_LEN>(SEL_EVEN);
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR3_ES, TT::MC_REG0_CMN_CONFIG_CNTR3_ES_LEN>(SIG_1_0);
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR2_PS, TT::MC_REG0_CMN_CONFIG_CNTR2_PS_LEN>(SEL_EVEN);
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR2_ES, TT::MC_REG0_CMN_CONFIG_CNTR2_ES_LEN>(SIG_7_6);
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR1_PS, TT::MC_REG0_CMN_CONFIG_CNTR1_PS_LEN>(SEL_EVEN);
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR1_ES, TT::MC_REG0_CMN_CONFIG_CNTR1_ES_LEN>(SIG_3_2);
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR0_PS, TT::MC_REG0_CMN_CONFIG_CNTR0_PS_LEN>(SEL_ODD);
- l_val.template insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR0_ES, TT::MC_REG0_CMN_CONFIG_CNTR0_ES_LEN>(SIG_1_0);
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_PORT_SEL, TT::MC_REG0_CMN_CONFIG_PORT_SEL_LEN>(0);
+
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR3_PS, TT::MC_REG0_CMN_CONFIG_CNTR3_PS_LEN>(
+ mss::omi::cntrl_pair_selector::SEL_EVEN);
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR3_ES, TT::MC_REG0_CMN_CONFIG_CNTR3_ES_LEN>(
+ mss::omi::cntrl_event_selector::SIG_1_0);
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR2_PS, TT::MC_REG0_CMN_CONFIG_CNTR2_PS_LEN>(
+ mss::omi::cntrl_pair_selector::SEL_EVEN);
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR2_ES, TT::MC_REG0_CMN_CONFIG_CNTR2_ES_LEN>(
+ mss::omi::cntrl_event_selector::SIG_7_6);
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR1_PS, TT::MC_REG0_CMN_CONFIG_CNTR1_PS_LEN>(
+ mss::omi::cntrl_pair_selector::SEL_EVEN);
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR1_ES, TT::MC_REG0_CMN_CONFIG_CNTR1_ES_LEN>(
+ mss::omi::cntrl_event_selector::SIG_3_2);
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR0_PS, TT::MC_REG0_CMN_CONFIG_CNTR0_PS_LEN>(
+ mss::omi::cntrl_pair_selector::SEL_ODD);
+ l_val.insertFromRight<TT::MC_REG0_CMN_CONFIG_CNTR0_ES, TT::MC_REG0_CMN_CONFIG_CNTR0_ES_LEN>(
+ mss::omi::cntrl_event_selector::SIG_1_0);
// CFG_CMN_CNTRx_PE: PMU cntrx positive edge select
- l_val.template writeBit<TT::MC_REG0_CMN_CONFIG_CNTR3_PE>(0);
- l_val.template writeBit<TT::MC_REG0_CMN_CONFIG_CNTR2_PE>(0);
- l_val.template writeBit<TT::MC_REG0_CMN_CONFIG_CNTR1_PE>(0);
- l_val.template writeBit<TT::MC_REG0_CMN_CONFIG_CNTR0_PE>(0);
+ l_val.writeBit<TT::MC_REG0_CMN_CONFIG_CNTR3_PE>(0);
+ l_val.writeBit<TT::MC_REG0_CMN_CONFIG_CNTR2_PE>(0);
+ l_val.writeBit<TT::MC_REG0_CMN_CONFIG_CNTR1_PE>(0);
+ l_val.writeBit<TT::MC_REG0_CMN_CONFIG_CNTR0_PE>(0);
// CFG_CMN_CNTRx_EN: PMU cntrx enable
- l_val.template writeBit<TT::MC_REG0_CMN_CONFIG_CNTR3_EN>(1);
- l_val.template writeBit<TT::MC_REG0_CMN_CONFIG_CNTR2_EN>(1);
- l_val.template writeBit<TT::MC_REG0_CMN_CONFIG_CNTR1_EN>(1);
- l_val.template writeBit<TT::MC_REG0_CMN_CONFIG_CNTR0_EN>(1);
+ l_val.writeBit<TT::MC_REG0_CMN_CONFIG_CNTR3_EN>(1);
+ l_val.writeBit<TT::MC_REG0_CMN_CONFIG_CNTR2_EN>(1);
+ l_val.writeBit<TT::MC_REG0_CMN_CONFIG_CNTR1_EN>(1);
+ l_val.writeBit<TT::MC_REG0_CMN_CONFIG_CNTR0_EN>(1);
FAPI_TRY( mss::putScom(i_target, TT::MC_REG0_CMN_CONFIG, l_val) );
FAPI_TRY( mss::putScom(i_target, TT::MC_REG1_CMN_CONFIG, l_val) );
@@ -463,24 +155,30 @@ fapi_try_exit:
}
///
-/// @brief Helper function to set the CONFIG0
+/// @brief Function to set the CONFIG0 for the given train mode and backoff_en bit
/// @tparam PROC the proc type
/// @tparam T the fapi2 target type of the target
/// @tparam TT the class traits for the omi
/// @param[in] i_target the OMI target to operate on
+/// @param[in] i_train_mode training step to enable
+/// @param[in] i_dl_x4_backoff_en backoff enable mode
/// @return FAPI2_RC_SUCCESS iff ok
///
template< mss::proc_type PROC = DEFAULT_PROC_TYPE, fapi2::TargetType T, typename TT = omiTraits<T, PROC>>
-fapi2::ReturnCode setup_mc_config0_helper(const fapi2::Target<T>& i_target)
+fapi2::ReturnCode setup_mc_config0(
+ const fapi2::Target<T>& i_target,
+ const uint8_t i_train_mode,
+ const uint8_t i_dl_x4_backoff_en)
{
// The value is 0x8200040000152824
fapi2::buffer<uint64_t> l_val;
+ uint8_t l_dl_tx_ln_rev_en = 1;
// CFG_DL0_ENABLE: dl0 enabled
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_ENABLE>(1);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_ENABLE>(1);
// CFG_DL0_CFG_SPARE: dl0 Spare
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_CFG_SPARE, TT::MC_REG2_DL0_CONFIG0_CFG_CFG_SPARE_LEN>(0);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_CFG_SPARE, TT::MC_REG2_DL0_CONFIG0_CFG_CFG_SPARE_LEN>(0);
// CFG_DL0_CFG_TL_CREDITS: dl0 TL credits - Maximum number of credits that can be sent to the TL
l_val.template
@@ -491,23 +189,25 @@ fapi2::ReturnCode setup_mc_config0_helper(const fapi2::Target<T>& i_target)
// Bit 1 = Freeze afu, leave TL and DL running
// Bit 2 = Trigger Internal Logic Analyzers
// Bit 3 = Bring down the link
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_TL_EVENT_ACTIONS,
- TT::MC_REG2_DL0_CONFIG0_CFG_TL_EVENT_ACTIONS_LEN>(0);
+ l_val.template
+ insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_TL_EVENT_ACTIONS, TT::MC_REG2_DL0_CONFIG0_CFG_TL_EVENT_ACTIONS_LEN>(0);
// CFG_DL0_TL_ERROR_ACTIONS: dl0 TL error actions
// Bit 0 = Freeze all
// Bit 1 = Freeze afu, leave TL and DL running
// Bit 2 = Trigger Internal Logic Analyzers
// Bit 3 = Bring down the link
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_TL_ERROR_ACTIONS,
- TT::MC_REG2_DL0_CONFIG0_CFG_TL_ERROR_ACTIONS_LEN>(0);
+ l_val.template
+ insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_TL_ERROR_ACTIONS, TT::MC_REG2_DL0_CONFIG0_CFG_TL_ERROR_ACTIONS_LEN>(0);
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_FWD_PROGRESS_TIMER,
- TT::MC_REG2_DL0_CONFIG0_CFG_FWD_PROGRESS_TIMER_LEN>(NO_FORWARD_TIMER_16US);
+ l_val.template
+ insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_FWD_PROGRESS_TIMER, TT::MC_REG2_DL0_CONFIG0_CFG_FWD_PROGRESS_TIMER_LEN>(
+ mss::omi::no_forward_progress_timer::NO_FORWARD_TIMER_16US);
// CFG_DL0_REPLAY_RSVD_ENTRIES: dl0 replay buffers reserved - times 16 is the number of replay buffers reserved
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_REPLAY_RSVD_ENTRIES,
- TT::MC_REG2_DL0_CONFIG0_CFG_REPLAY_RSVD_ENTRIES_LEN>(0);
+ l_val.template
+ insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_REPLAY_RSVD_ENTRIES, TT::MC_REG2_DL0_CONFIG0_CFG_REPLAY_RSVD_ENTRIES_LEN>
+ (0);
// CFG_DL0_DEBUG_SELECT: dl0 trace mux select
// "000" = zeros
@@ -518,66 +218,73 @@ fapi2::ReturnCode setup_mc_config0_helper(const fapi2::Target<T>& i_target)
// "101" = 11 bits of TX flit information
// "110" = 11 bits of Tx training information
// "111" = zeros
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_DEBUG_SELECT, TT::MC_REG2_DL0_CONFIG0_CFG_DEBUG_SELECT_LEN>
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_DEBUG_SELECT, TT::MC_REG2_DL0_CONFIG0_CFG_DEBUG_SELECT_LEN>
(0);
// CFG_DL0_DEBUG_ENABLE: dl0 trace enable
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_DEBUG_ENABLE>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_DEBUG_ENABLE>(0);
// CFG_DL0_DL2TL_DATA_PARITY_INJECT: dl0 inject a data parity error
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_DL2TL_DATA_PARITY_INJECT>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_DL2TL_DATA_PARITY_INJECT>(0);
// CFG_DL0_DL2TL_CONTROL_PARITY_INJECT: dl0 inject a control parity error
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_DL2TL_CONTROL_PARITY_INJECT>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_DL2TL_CONTROL_PARITY_INJECT>(0);
// CFG_DL0_ECC_UE_INJECTION: dl0 inject a ECC UE error
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_ECC_UE_INJECTION>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_ECC_UE_INJECTION>(0);
// CFG_DL0_ECC_CE_INJECTION: dl0 inject a ECC CE error
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_ECC_CE_INJECTION>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_ECC_CE_INJECTION>(0);
// CFG_DL0_FP_DISABLE: dl0 fastpath disabled
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_FP_DISABLE>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_FP_DISABLE>(0);
// CFG_DL0_UNUSED2: dl0 Spare
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_UNUSED2>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_UNUSED2>(0);
// CFG_DL0_TX_LN_REV_ENA: When set will allow dl0 to perform tx lane reversals.
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_TX_LN_REV_ENA>(0);
+ FAPI_TRY(mss::attr::get_omi_dl_ln_rev_enable(i_target, l_dl_tx_ln_rev_en),
+ "Error from FAPI_ATTR_GET (ATTR_OMI_DL_LN_REV_ENABLE)");
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_TX_LN_REV_ENA>(l_dl_tx_ln_rev_en);
// CFG_DL0_128_130_ENCODING_ENABLED: dl0 128/130 encoding enabled
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_128_130_ENCODING_ENABLED>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_128_130_ENCODING_ENABLED>(0);
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_PHY_CNTR_LIMIT,
- TT::MC_REG2_DL0_CONFIG0_CFG_PHY_CNTR_LIMIT_LEN>(PHY_CTR_MODE_50US);
+ l_val.template
+ insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_PHY_CNTR_LIMIT, TT::MC_REG2_DL0_CONFIG0_CFG_PHY_CNTR_LIMIT_LEN>(
+ mss::omi::phy_ctr_mode::PHY_CTR_MODE_60MS);
// CFG_DL0_RUNLANE_OVRD_ENABLE: When enabled, the dl0 will drive run lane to the PHY for all training states.
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_TX_EP_MODE>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_TX_EP_MODE>(0);
// CFG_DL0_PWRMGT_ENABLE: dl0 power management enabled
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_PWRMGT_ENABLE>(1);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_PWRMGT_ENABLE>(0);
// CFG_DL0_QUARTER_WIDTH_BACKOFF_ENABLE: dl0 x1 backoff enabled
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_X1_BACKOFF_ENABLE>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_X1_BACKOFF_ENABLE>(0);
// CFG_DL0_HALF_WIDTH_BACKOFF_ENABLE: dl0 x4 backoff enabled
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_X4_BACKOFF_ENABLE>(1);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_X4_BACKOFF_ENABLE>(i_dl_x4_backoff_en);
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_SUPPORTED_MODES,
- TT::MC_REG2_DL0_CONFIG0_CFG_SUPPORTED_MODES_LEN>(LINK_WIDTHS_X8);
+ l_val.template
+ insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_SUPPORTED_MODES, TT::MC_REG2_DL0_CONFIG0_CFG_SUPPORTED_MODES_LEN>(
+ mss::omi::link_widths::LINK_WIDTHS_X8);
// CFG_DL0_TRAIN_MODE: dl0 train mode
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_TRAIN_MODE, TT::MC_REG2_DL0_CONFIG0_CFG_TRAIN_MODE_LEN>
- (ENABLE_AUTO_TRAINING);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_TRAIN_MODE, TT::MC_REG2_DL0_CONFIG0_CFG_TRAIN_MODE_LEN>(
+ i_train_mode);
// CFG_DL0_VERSION: dl0 version number
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_VERSION, TT::MC_REG2_DL0_CONFIG0_CFG_VERSION_LEN>(9);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG0_CFG_VERSION, TT::MC_REG2_DL0_CONFIG0_CFG_VERSION_LEN>(9);
// CFG_DL0_RETRAIN: dl0 retrain - Reset dl0 back to training state 4
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_RETRAIN>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_RETRAIN>(0);
// CFG_DL0_RESET: dl0 reset - Reset dl0 back to traning state 0
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_RESET>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG0_CFG_RESET>(0);
+
+ FAPI_DBG("Writing 0x%16llx to MC_REG2_DL0_CONFIG0 (0x%16llx) of %s",
+ l_val, TT::MC_REG2_DL0_CONFIG0, mss::c_str(i_target));
FAPI_TRY( mss::putScom(i_target, TT::MC_REG2_DL0_CONFIG0, l_val) );
@@ -586,7 +293,7 @@ fapi_try_exit:
}
///
-/// @brief Helper function to set the CONFIG1
+/// @brief Function to setup the CONFIG1
/// @tparam PROC the proc type
/// @tparam T the fapi2 target type of the target
/// @tparam TT the class traits for the omi
@@ -594,28 +301,30 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff ok
///
template< mss::proc_type PROC = DEFAULT_PROC_TYPE, fapi2::TargetType T, typename TT = omiTraits<T, PROC>>
-fapi2::ReturnCode setup_mc_config1_helper(const fapi2::Target<T>& i_target)
+fapi2::ReturnCode setup_mc_config1(const fapi2::Target<T>& i_target)
{
// The value is 0x0C00050000000059;
fapi2::buffer<uint64_t> l_val;
uint8_t l_sim = 0;
+ uint8_t l_edpl_disable = 0;
FAPI_TRY( mss::attr::get_is_simulation( l_sim) );
// CFG_DL0_CFG1_PREIPL_PRBS
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_PREIPL_PRBS_TIME,
- TT::MC_REG2_DL0_CONFIG1_CFG_PREIPL_PRBS_TIME_LEN>(l_sim ? PREIPL_PRBS_1US : PREIPL_PRBS_64MS);
-
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_PREIPL_PRBS_ENA, 1>(1); // Enable
+ l_val.template
+ insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_PREIPL_PRBS_TIME, TT::MC_REG2_DL0_CONFIG1_CFG_PREIPL_PRBS_TIME_LEN>(
+ l_sim ? mss::omi::preipl_prbs_time::PREIPL_PRBS_1US : mss::omi::preipl_prbs_time::PREIPL_PRBS_256MS);
+ // PRE-IPL PRBS Timing is not functional in Axone, so set to disable
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_PREIPL_PRBS_ENA, 1>(0); // Disable
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_LANE_WIDTH,
- TT::MC_REG2_DL0_CONFIG1_CFG_LANE_WIDTH_LEN>(TL_CTR_BY_SIDEBAND);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_LANE_WIDTH, TT::MC_REG2_DL0_CONFIG1_CFG_LANE_WIDTH_LEN>(
+ mss::omi::lan_width_override::TL_CTR_BY_SIDEBAND);
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_B_HYSTERESIS,
- TT::MC_REG2_DL0_CONFIG1_CFG_B_HYSTERESIS_LEN>(B_HYSTERESIS_16);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_B_HYSTERESIS, TT::MC_REG2_DL0_CONFIG1_CFG_B_HYSTERESIS_LEN>(
+ mss::omi::b_hysteresis::B_HYSTERESIS_16);
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_A_HYSTERESIS,
- TT::MC_REG2_DL0_CONFIG1_CFG_A_HYSTERESIS_LEN>(A_HYSTERESIS_16);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_A_HYSTERESIS, TT::MC_REG2_DL0_CONFIG1_CFG_A_HYSTERESIS_LEN>(
+ mss::omi::a_hysteresis::A_HYSTERESIS_16);
// CFG_DL0_B_PATTERN_LENGTH: Number of consecutive 1s and 0s needed to represent training Pattern
// B=> "11111111111111110000000000000000"
@@ -623,8 +332,8 @@ fapi2::ReturnCode setup_mc_config1_helper(const fapi2::Target<T>& i_target)
// "10" = four Xs => "111111111111XXXX000000000000XXXX"
// "01" = one Xs => "111111111111111X000000000000000X"
// "11" = same as "10"
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_B_PATTERN_LENGTH,
- TT::MC_REG2_DL0_CONFIG1_CFG_B_PATTERN_LENGTH_LEN>(0);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_B_PATTERN_LENGTH,
+ TT::MC_REG2_DL0_CONFIG1_CFG_B_PATTERN_LENGTH_LEN>(0);
// CFG_DL0_A_PATTERN_LENGTH: Number of consecutive 1s and 0s needed to represent training Pattern
// A => "1111111100000000"
@@ -632,62 +341,63 @@ fapi2::ReturnCode setup_mc_config1_helper(const fapi2::Target<T>& i_target)
// "10" = four Xs => "1111XXXX0000XXXX"
// "01" = one Xs => "1111111X0000000X"
// "11" = same as "10"
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_A_PATTERN_LENGTH,
- TT::MC_REG2_DL0_CONFIG1_CFG_A_PATTERN_LENGTH_LEN>(0);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_A_PATTERN_LENGTH,
+ TT::MC_REG2_DL0_CONFIG1_CFG_A_PATTERN_LENGTH_LEN>(0);
// CFG_DL0_TX_PERF_DEGRADED: "00" = if tx perf is degraded by 1% set error bit 25
// "01" = if tx perf is degraded by 2% set error bit 25
// "10" = if tx perf is degraded by 3% set error bit 25
// "11" = if tx perf is degraded by 4% set error bit 25
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_TX_PERF_DEGRADED,
- TT::MC_REG2_DL0_CONFIG1_CFG_TX_PERF_DEGRADED_LEN>(1);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_TX_PERF_DEGRADED,
+ TT::MC_REG2_DL0_CONFIG1_CFG_TX_PERF_DEGRADED_LEN>(1);
// CFG_DL0_RX_PERF_DEGRADED: "00" = if rx performance is degraded by 1% set error bit 26
// "01" = if rx perf is degraded by 2% set error bit 26
// "10" = if rx perf is degraded by 3% set error bit 26
// "11" = if rx perf is degraded by 4% set error bit 26
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_RX_PERF_DEGRADED,
- TT::MC_REG2_DL0_CONFIG1_CFG_RX_PERF_DEGRADED_LEN>(1);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_RX_PERF_DEGRADED,
+ TT::MC_REG2_DL0_CONFIG1_CFG_RX_PERF_DEGRADED_LEN>(1);
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_TX_LANES_DISABLE,
- TT::MC_REG2_DL0_CONFIG1_CFG_TX_LANES_DISABLE_LEN>(LANE_DISABLED_NONE);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_TX_LANES_DISABLE,
+ TT::MC_REG2_DL0_CONFIG1_CFG_TX_LANES_DISABLE_LEN>(mss::omi::LANE_DISABLED_NONE);
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_RX_LANES_DISABLE,
- TT::MC_REG2_DL0_CONFIG1_CFG_RX_LANES_DISABLE_LEN>(LANE_DISABLED_NONE);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_RX_LANES_DISABLE,
+ TT::MC_REG2_DL0_CONFIG1_CFG_RX_LANES_DISABLE_LEN>(mss::omi::LANE_DISABLED_NONE);
// CFG_DL0_RESET_ERR_HLD: dl0 reset the error hold register when it is read
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_RESET_ERR_HLD>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_RESET_ERR_HLD>(0);
// CFG_DL0_RESET_ERR_CAP: dl0 reset the error capture register when it is read
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_RESET_ERR_CAP>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_RESET_ERR_CAP>(0);
// CFG_DL0_RESET_TSHD_REG: dl0 reset the edpl threshold register when it is read
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_RESET_TSHD_REG>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_RESET_TSHD_REG>(0);
// CFG_DL0_RESET_RMT_MSG: dl0 reset the remote register when it is read
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_RESET_RMT_MSG>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_RESET_RMT_MSG>(0);
// CFG_DL0_INJECT_CRC_DIRECTION: dl0 inject crc direction
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_INJECT_CRC_DIRECTION>(CRC_DIR_RX);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_INJECT_CRC_DIRECTION>(mss::omi::crc_inject_dir::CRC_DIR_RX);
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_INJECT_CRC_RATE,
- TT::MC_REG2_DL0_CONFIG1_CFG_INJECT_CRC_RATE_LEN>(CRC_INJ_RATE_1US);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_INJECT_CRC_RATE,
+ TT::MC_REG2_DL0_CONFIG1_CFG_INJECT_CRC_RATE_LEN>(mss::omi::crc_inject_rate::CRC_INJ_RATE_1US);
// CFG_DL0_INJECT_CRC_LANE: dl0 inject crc error on lane number
l_val.template
insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_INJECT_CRC_LANE, TT::MC_REG2_DL0_CONFIG1_CFG_INJECT_CRC_LANE_LEN>(0);
// CFG_DL0_INJECT_CRC_ERROR: dl0 inject crc error enable
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_INJECT_CRC_ERROR>(0);
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_INJECT_CRC_ERROR>(0);
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_EDPL_TIME,
- TT::MC_REG2_DL0_CONFIG1_CFG_EDPL_TIME_LEN>(EDPL_TIME_WIN_16MS);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_EDPL_TIME,
+ TT::MC_REG2_DL0_CONFIG1_CFG_EDPL_TIME_LEN>(mss::omi::edpl_time_win::EDPL_TIME_WIN_16MS);
- l_val.template insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_EDPL_THRESHOLD,
- TT::MC_REG2_DL0_CONFIG1_CFG_EDPL_THRESHOLD_LEN>(EDPL_ERR_THRES_16);
+ l_val.insertFromRight<TT::MC_REG2_DL0_CONFIG1_CFG_EDPL_THRESHOLD,
+ TT::MC_REG2_DL0_CONFIG1_CFG_EDPL_THRESHOLD_LEN>(mss::omi::edpl_err_thres::EDPL_ERR_THRES_16);
// CFG_DL0_EDPL_ENA: dl0 error detection per lane "edpl" enable
- l_val.template writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_EDPL_ENA>(1);
+ FAPI_TRY(mss::attr::get_mss_omi_edpl_disable(l_edpl_disable));
+ l_val.writeBit<TT::MC_REG2_DL0_CONFIG1_CFG_EDPL_ENA>(l_edpl_disable ? 0 : 1);
FAPI_TRY( mss::putScom(i_target, TT::MC_REG2_DL0_CONFIG1, l_val) );
@@ -696,7 +406,7 @@ fapi_try_exit:
}
///
-/// @brief Helper function to set the DL0_CYA_BITS
+/// @brief Function to set the DL0_CYA_BITS
/// @tparam PROC the proc type
/// @tparam T the fapi2 target type of the target
/// @tparam TT the class traits for the omi
@@ -704,7 +414,7 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff ok
///
template< mss::proc_type PROC = DEFAULT_PROC_TYPE, fapi2::TargetType T, typename TT = omiTraits<T, PROC>>
-fapi2::ReturnCode setup_mc_cya_bits_helper(const fapi2::Target<T>& i_target)
+fapi2::ReturnCode setup_mc_cya_bits(const fapi2::Target<T>& i_target)
{
fapi2::buffer<uint64_t> l_val;
@@ -719,7 +429,7 @@ fapi_try_exit:
}
///
-/// @brief Helper function to set the DL0_ERROR_ACTION
+/// @brief Function to set the DL0_ERROR_ACTION
/// @tparam PROC the memory controller type
/// @tparam T the fapi2 target type of the target
/// @tparam TT the class traits for the omi
@@ -727,7 +437,7 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff ok
///
template< mss::proc_type PROC = DEFAULT_PROC_TYPE, fapi2::TargetType T, typename TT = omiTraits<T, PROC>>
-fapi2::ReturnCode setup_mc_error_action_helper(const fapi2::Target<T>& i_target)
+fapi2::ReturnCode setup_mc_error_action(const fapi2::Target<T>& i_target)
{
fapi2::buffer<uint64_t> l_val;
@@ -753,7 +463,7 @@ fapi_try_exit:
///
-/// @brief Helper function to set the DL0_RMT_CONFIG
+/// @brief Function to set the DL0_RMT_CONFIG
/// @tparam PROC the proc type
/// @tparam T the fapi2 target type of the target
/// @tparam TT the class traits for the omi
@@ -761,7 +471,7 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff ok
///
template< mss::proc_type PROC = DEFAULT_PROC_TYPE, fapi2::TargetType T, typename TT = omiTraits<T, PROC>>
-fapi2::ReturnCode setup_mc_rmt_config_helper(const fapi2::Target<T>& i_target)
+fapi2::ReturnCode setup_mc_rmt_config(const fapi2::Target<T>& i_target)
{
fapi2::buffer<uint64_t> l_val;
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_config_thermal.H b/src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.C
index 76f5cd416..e27f6cef5 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_config_thermal.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.C
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_config_thermal.H $ */
+/* $Source: src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.C $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/ecc_traits.H b/src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.H
index 86f274e54..8ccc4ab9c 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/ecc_traits.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/ecc/ecc_traits.H $ */
+/* $Source: src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/shared/axone_consts.H b/src/import/chips/p9a/procedures/hwp/memory/lib/shared/axone_consts.H
index c2ef9aee8..dcca78fa0 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/lib/shared/axone_consts.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/shared/axone_consts.H
@@ -39,4 +39,8 @@
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+const uint8_t MAX_MC_SIDES_PER_PROC = 2; // MC01, MC23
+const uint8_t MAX_MC_PER_PROC = 4; // MC0, MC1, MC2, MC3
+const uint8_t MAX_MC_PER_SIDE = 2; // MC0, MC1 or MC2, MC3
+
#endif
diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.C b/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.C
new file mode 100644
index 000000000..783091c62
--- /dev/null
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.C
@@ -0,0 +1,212 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file p9a_omi_workarounds.C
+/// @brief Workarounds for p9a_omi_* procedures
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: Memory
+
+#include <fapi2.H>
+#include <lib/shared/axone_defaults.H>
+#include <p9a_mc_scom_addresses.H>
+#include <p9a_mc_scom_addresses_fld.H>
+#include <p9a_mc_scom_addresses_fixes.H>
+#include <p9a_mc_scom_addresses_fld_fixes.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/mss_generic_system_attribute_getters.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
+#include <lib/mc/omi.H>
+#include <lib/mc/omi_traits.H>
+#include <lib/workarounds/p9a_omi_workarounds.H>
+
+namespace mss
+{
+namespace workarounds
+{
+namespace mc
+{
+///
+/// @brief Helper function to determine whether PRBS OMI workaround will be performed, that can be unit tested
+///
+/// @param[in] i_ocmb_type OCMB type/name
+/// @param[in] i_proc_type PROC type/name
+/// @return true/false perform workaround
+///
+bool is_prbs_omi_required(const uint8_t i_ocmb_type, const uint8_t i_proc_type)
+{
+ // OMI Workaround Logic:
+ // Explorer+Axone: OMI/PROC-side workaround off
+ // Gemini+Axone: OMI/PROC-side workaround on
+ // Any+apollo: OMI/PROC-side workaround on
+ // P10: No workarounds required. Enums don't exist yet, so this must be revisited later
+ return ((i_proc_type != fapi2::ENUM_ATTR_NAME_AXONE) || (i_ocmb_type == fapi2::ENUM_ATTR_NAME_GEMINI)); // Gem && axone
+}
+
+///
+/// @brief Helper function to determine whether PRBS axone OMI workarounds will be performed, that can be unit tested
+///
+/// @param[in] i_ocmb_type OCMB type/name
+/// @param[in] i_proc_type PROC type/name
+/// @return true/false perform workaround
+///
+bool is_prbs_omi_axone_required(const uint8_t i_ocmb_type, const uint8_t i_proc_type)
+{
+ // OMI Workaround Logic:
+ // Explorer+Axone: Workaround on.
+ // Else: None
+ return ((i_proc_type == fapi2::ENUM_ATTR_NAME_AXONE)
+ && (i_ocmb_type == fapi2::ENUM_ATTR_NAME_EXPLORER)); // Explorer && axone
+}
+
+///
+/// @brief Perform PRBS delay from prbs time and sim attributes
+///
+/// @param[in] i_omi OMI target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode prbs_delay(const fapi2::Target<fapi2::TARGET_TYPE_OMI>& i_omi)
+{
+ uint8_t l_sim = 0;
+ uint32_t l_prbs_time = 0;
+ uint64_t l_prbs_time_scaled = 0;
+
+ FAPI_TRY( mss::attr::get_is_simulation( l_sim) );
+
+ FAPI_TRY(mss::attr::get_omi_dl_preipl_prbs_time(i_omi, l_prbs_time),
+ "Error from FAPI_ATTR_GET (ATTR_OMI_DL_PREIPL_PRBS_TIME)");
+ l_prbs_time_scaled = l_prbs_time * mss::common_timings::DELAY_1MS;
+
+ FAPI_TRY(fapi2::delay(l_prbs_time_scaled, mss::common_timings::DELAY_1US));
+ FAPI_DBG("OMI Training Pre-ipl PRBS Time = %dns",
+ (l_sim ? mss::common_timings::DELAY_1US : l_prbs_time_scaled));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get PROC and OCMB types
+///
+/// @param[in] i_ocmb_chip OCMB chip
+/// @param[in] i_proc_chip PROC chip
+/// @param[out] o_required workaround required
+/// @return FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode get_ocmb_proc_types(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> i_ocmb_chip,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> i_proc_chip,
+ uint8_t& o_ocmb_type,
+ uint8_t& o_proc_type)
+{
+ FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, i_ocmb_chip, o_ocmb_type),
+ "Error getting ATTR_NAME of %s", mss::c_str(i_ocmb_chip));
+
+ FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, i_proc_chip, o_proc_type),
+ "Error getting ATTR_NAME of %s", mss::c_str(i_proc_chip));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Perform the PRBS OMI workaround for gemini configurations
+///
+/// @param[in] i_omi OMI
+/// @param[in] i_dl_x4_backoff_en backoff enable bit
+/// @return fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode omi_training_prbs_gem(
+ const fapi2::Target<fapi2::TARGET_TYPE_OMI> i_omi,
+ const uint8_t i_dl_x4_backoff_en)
+{
+ FAPI_DBG("Performing PRBS OMI workaround on %s", mss::c_str(i_omi));
+
+ // *_CONFIG0 should be the last one written, since it starts the training.
+ // We are not using the pre-ipl PRBS auto training mode because it doesn't function properly in Axone
+
+ // Enable training state 6 to send TS3
+ FAPI_TRY(mss::mc::setup_mc_config0(i_omi, mss::omi::train_mode::TX_TRAINING_STATE3, i_dl_x4_backoff_en));
+
+ FAPI_TRY(prbs_delay(i_omi));
+
+ // Enable training state 1 to send Pattern A
+ FAPI_TRY(mss::mc::setup_mc_config0(i_omi, mss::omi::train_mode::TX_PATTERN_A, i_dl_x4_backoff_en));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Perform p9a_omi_train workaround for Axone+Explorer
+///
+/// @param[in] i_omi OMI target
+/// @param[in] i_dl_x4_backoff_en backoff enable field
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode omi_training_prbs(
+ const fapi2::Target<fapi2::TARGET_TYPE_OMI> i_omi,
+ const uint8_t i_dl_x4_backoff_en)
+{
+ FAPI_DBG("Performing OMI Train axone workaround on %s", mss::c_str(i_omi));
+
+ // Training mode 1: send Pattern A
+ FAPI_TRY(mss::mc::setup_mc_config0(i_omi, mss::omi::train_mode::TX_PATTERN_A, i_dl_x4_backoff_en));
+
+ FAPI_TRY(fapi2::delay(100 * mss::common_timings::DELAY_1MS, mss::common_timings::DELAY_1MS));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Perform p9a_omi_setup (pre-training) workaround for Axone+Explorer
+///
+/// @param[in] i_omi OMI target
+/// @param[in] i_dl_x4_backoff_en backoff enable field
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode pre_omi_training_prbs(
+ const fapi2::Target<fapi2::TARGET_TYPE_OMI> i_omi,
+ const uint8_t i_dl_x4_backoff_en)
+{
+ FAPI_DBG("Performing OMI Setup axone workaround on %s", mss::c_str(i_omi));
+
+ // Training mode 4: send State 1
+ FAPI_TRY(mss::mc::setup_mc_config0(i_omi, mss::omi::train_mode::TX_TRAINING_STATE1, i_dl_x4_backoff_en));
+
+ FAPI_TRY(prbs_delay(i_omi));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // mc
+} // workarounds
+} // mss
diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.H b/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.H
new file mode 100644
index 000000000..4491a91e3
--- /dev/null
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.H
@@ -0,0 +1,124 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9a/procedures/hwp/memory/lib/workarounds/p9a_omi_workarounds.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file p9a_omi_workarounds.H
+/// @brief Workarounds for p9a_omi_* procedures
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: Memory
+
+#ifndef P9A_OMI_WORKAROUNDS_H_
+#define P9A_OMI_WORKAROUNDS_H_
+
+#include <fapi2.H>
+
+namespace mss
+{
+namespace workarounds
+{
+namespace mc
+{
+///
+/// @brief Helper function to determine whether PRBS OMI workaround will be performed, that can be unit tested
+///
+/// @param[in] i_ocmb_type OCMB type/name
+/// @param[in] i_proc_type PROC type/name
+/// @return true/false perform workaround
+///
+bool is_prbs_omi_required(const uint8_t i_ocmb_type, const uint8_t i_proc_type);
+
+///
+/// @brief Helper function to determine whether PRBS axone OMI workarounds will be performed, that can be unit tested
+///
+/// @param[in] i_ocmb_type OCMB type/name
+/// @param[in] i_proc_type PROC type/name
+/// @return true/false perform workaround
+///
+bool is_prbs_omi_axone_required(const uint8_t i_ocmb_type, const uint8_t i_proc_type);
+
+///
+/// @brief Perform PRBS delay from prbs time and sim attributes
+///
+/// @param[in] i_omi OMI target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+fapi2::ReturnCode prbs_delay(const fapi2::Target<fapi2::TARGET_TYPE_OMI>& i_omi);
+
+///
+/// @brief Get PROC and OCMB types
+///
+/// @param[in] i_ocmb_chip OCMB chip
+/// @param[in] i_proc_chip PROC chip
+/// @param[out] o_required workaround required
+/// @return FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode get_ocmb_proc_types(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> i_ocmb_chip,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> i_proc_chip,
+ uint8_t& o_ocmb_type,
+ uint8_t& o_proc_type);
+
+///
+/// @brief Perform the PRBS OMI workaround for gemini configurations
+///
+/// @param[in] i_omi OMI
+/// @param[in] i_dl_x4_backoff_en backoff enable bit
+/// @return fapi2::FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode omi_training_prbs_gem(
+ const fapi2::Target<fapi2::TARGET_TYPE_OMI> i_omi,
+ const uint8_t i_dl_x4_backoff_en);
+
+///
+/// @brief Perform p9a_omi_train workaround for Axone+Explorer
+///
+/// @param[in] i_omi OMI target
+/// @param[in] i_dl_x4_backoff_en backoff enable field
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode omi_training_prbs(
+ const fapi2::Target<fapi2::TARGET_TYPE_OMI> i_omi,
+ const uint8_t i_dl_x4_backoff_en);
+
+///
+/// @brief Perform p9a_omi_setup (pre-training) workaround for Axone+Explorer
+///
+/// @param[in] i_omi OMI target
+/// @param[in] i_dl_x4_backoff_en backoff enable field
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+fapi2::ReturnCode pre_omi_training_prbs(
+ const fapi2::Target<fapi2::TARGET_TYPE_OMI> i_omi,
+ const uint8_t i_dl_x4_backoff_en);
+
+} // namespace mc
+} // namespace workarounds
+} // namespace mss
+
+#endif
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_bulk_pwr_throttles.mk b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_bulk_pwr_throttles.mk
index aff426ea7..8c936264d 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_bulk_pwr_throttles.mk
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_bulk_pwr_throttles.mk
@@ -25,5 +25,5 @@
-include 00p9a_common.mk
PROCEDURE=p9a_mss_bulk_pwr_throttles
-$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
+$(eval $(call ADD_P9A_MEMORY_INCDIRS,$(PROCEDURE)))
$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.C
index 75d23c6af..7a62e36a0 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.C
@@ -33,17 +33,24 @@
// *HWP Level: 1
// *HWP Consumed by: FSP:HB
-// fapi2
#include <fapi2.H>
#include <p9a_mss_eff_config.H>
+#include <lib/shared/exp_defaults.H>
+#include <lib/dimm/exp_rank.H>
+#include <generic/memory/lib/utils/mss_rank.H>
#include <generic/memory/lib/data_engine/data_engine.H>
#include <generic/memory/lib/utils/find.H>
#include <generic/memory/lib/spd/ddimm/efd_factory.H>
#include <vpd_access.H>
#include <mss_generic_attribute_getters.H>
+#include <generic/memory/lib/data_engine/attr_engine_traits.H>
#include <lib/eff_config/explorer_attr_engine_traits.H>
+#include <lib/eff_config/pmic_attr_engine_traits.H>
+#include <lib/eff_config/explorer_efd_processing.H>
+#include <lib/eff_config/pmic_efd_processing.H>
#include <lib/freq/axone_freq_traits.H>
#include <lib/freq/axone_sync.H>
+#include <generic/memory/mss_git_data_helper.H>
///
/// @brief Configure the attributes for each controller
@@ -52,23 +59,22 @@
///
fapi2::ReturnCode p9a_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target )
{
- // Workaround until DIMM level attrs work
- uint8_t l_ranks[mss::exp::MAX_DIMM_PER_PORT] = {};
+ using mss::DEFAULT_MC_TYPE;
- FAPI_TRY( mss::attr::get_num_master_ranks_per_dimm(i_target, l_ranks) );
+ mss::display_git_commit_info("p9a_mss_eff_config");
for(const auto& dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target))
{
- uint8_t l_dimm_index = 0;
uint64_t l_freq = 0;
- uint64_t l_omi_freq = 0;
- FAPI_TRY( mss::attr::get_freq(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(dimm), l_freq) );
- FAPI_TRY( mss::convert_ddr_freq_to_omi_freq(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(dimm), l_freq, l_omi_freq));
+ uint32_t l_omi_freq = 0;
+ FAPI_TRY( mss::attr::get_freq(i_target, l_freq) );
+ FAPI_TRY( mss::convert_ddr_freq_to_omi_freq(i_target, l_freq, l_omi_freq));
- // Quick hack to get the index until DIMM level attrs work
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_REL_POS, dimm, l_dimm_index) );
+ // Get ranks via rank API
+ std::vector<mss::rank::info<>> l_ranks;
+ mss::rank::ranks_on_dimm(dimm, l_ranks);
- for( auto rank = 0; rank < l_ranks[l_dimm_index]; ++rank )
+ for (const auto& l_rank : l_ranks)
{
std::shared_ptr<mss::efd::base_decoder> l_efd_data;
@@ -76,7 +82,7 @@ fapi2::ReturnCode p9a_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MEM
const auto l_ocmb = mss::find_target<fapi2::TARGET_TYPE_OCMB_CHIP>(i_target);
fapi2::MemVpdData_t l_vpd_type(fapi2::MemVpdData::EFD);
fapi2::VPDInfo<fapi2::TARGET_TYPE_OCMB_CHIP> l_vpd_info(l_vpd_type);
- l_vpd_info.iv_rank = rank;
+ l_vpd_info.iv_rank = l_rank.get_dimm_rank();
l_vpd_info.iv_omi_freq_mhz = l_omi_freq;
FAPI_TRY( fapi2::getVPD(l_ocmb, l_vpd_info, nullptr), "failed getting VPD size from getVPD" );
@@ -88,7 +94,13 @@ fapi2::ReturnCode p9a_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MEM
FAPI_TRY( mss::efd::factory(l_ocmb, l_vpd_raw, l_vpd_info.iv_rank, l_efd_data) );
// Set up SI ATTRS
- FAPI_TRY( mss::attr_si_engine<mss::attr_si_engine_fields>::set(l_efd_data) );
+ FAPI_TRY( (mss::gen::attr_engine<mss::proc_type::AXONE, mss::attr_si_engine_fields>::set(l_efd_data)) );
+
+ // Explorer EFD
+ FAPI_TRY( mss::exp::efd::process(dimm, l_efd_data));
+
+ // PMIC EFD
+ FAPI_TRY(mss::pmic::efd::process(dimm, l_efd_data));
}
{
@@ -103,12 +115,19 @@ fapi2::ReturnCode p9a_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MEM
FAPI_TRY( l_rc, "Failed to initialize SPD facade for %s", mss::spd::c_str(dimm) );
// Set up generic SPD ATTRS
- FAPI_TRY( mss::attr_eff_engine<mss::attr_eff_engine_fields>::set(l_spd_decoder) );
+ FAPI_TRY( (mss::gen::attr_engine<mss::proc_type::AXONE, mss::attr_eff_engine_fields>::set(l_spd_decoder)) );
// Set up explorer SPD ATTRS
- FAPI_TRY( mss::attr_eff_engine<mss::exp::attr_eff_engine_fields>::set(l_spd_decoder) );
+ FAPI_TRY( (mss::gen::attr_engine<mss::proc_type::AXONE, mss::exp::attr_eff_engine_fields>::set(l_spd_decoder)) );
+
+ // Set up pmic SPD ATTRS
+ FAPI_TRY( (mss::gen::attr_engine<mss::proc_type::AXONE, mss::pmic::attr_eff_engine_fields>::set(l_spd_decoder)) );
}
}
+
+ // Set up derived ATTRS
+ FAPI_TRY( (mss::gen::attr_engine<mss::proc_type::AXONE, mss::attr_engine_derived_fields>::set(dimm)) );
+
}// dimm
fapi_try_exit:
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.mk b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.mk
index 65e376f98..a01aeb9ee 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.mk
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.C
index 342523d5a..4e8db7142 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,43 +40,56 @@
#include <p9a_mss_freq.H>
#include <lib/freq/axone_freq_traits.H>
-#include <generic/memory/lib/data_engine/p9a/p9a_data_init_traits.H>
+#include <lib/eff_config/p9a_data_init_traits.H>
#include <lib/eff_config/explorer_attr_engine_traits.H>
#include <generic/memory/lib/data_engine/data_engine.H>
#include <generic/memory/lib/utils/find.H>
#include <generic/memory/lib/spd/spd_facade.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <generic/memory/lib/utils/freq/gen_mss_freq.H>
+#include <generic/memory/mss_git_data_helper.H>
///
/// @brief Calculate and save off DIMM frequencies
/// @param[in] i_target port target
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode p9a_mss_freq( const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target )
+fapi2::ReturnCode p9a_mss_freq( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target )
{
+ mss::display_git_commit_info("p9a_mss_freq");
+
// If there are no DIMM, we can just get out.
- if (mss::count_dimm(i_target) == 0)
+ if (mss::count_dimm(mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target)) == 0)
{
FAPI_INF("Seeing no DIMM on %s, no freq to set", mss::c_str(i_target));
return fapi2::FAPI2_RC_SUCCESS;
}
// We will first set pre-eff_config attribes
- for(const auto& d : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target))
+ // Note that we have to go through the MEM_PORT to get to the DIMM targets because of the
+ // target hierarchy in Axone
+ for(const auto& p : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
{
- std::vector<uint8_t> l_raw_spd;
- FAPI_TRY(mss::spd::get_raw_data(d, l_raw_spd));
+ for(const auto& d : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(p))
{
- // Gets the SPD facade
- fapi2::ReturnCode l_rc(fapi2::FAPI2_RC_SUCCESS);
- mss::spd::facade l_spd_decoder(d, l_raw_spd, l_rc);
+ std::vector<uint8_t> l_raw_spd;
+ FAPI_TRY(mss::spd::get_raw_data(d, l_raw_spd));
+ {
+ // Gets the SPD facade
+ fapi2::ReturnCode l_rc(fapi2::FAPI2_RC_SUCCESS);
+ mss::spd::facade l_spd_decoder(d, l_raw_spd, l_rc);
+
+ // Checks that the facade was setup correctly
+ FAPI_TRY( l_rc, "Failed to initialize SPD facade for %s", mss::spd::c_str(d) );
- // Checks that the facade was setup correctly
- FAPI_TRY( l_rc, "Failed to initialize SPD facade for %s", mss::spd::c_str(d) );
+ // Set pre-eff_config SPD driven attributes
+ FAPI_TRY( (mss::gen::attr_engine<mss::proc_type::AXONE, mss::pre_data_init_fields>::set(l_spd_decoder)),
+ "Failed gen::attr_engine<mss::proc_type::AXONE, mss::pre_data_init_fields>::set on %s", mss::spd::c_str(d) );
- FAPI_TRY( mss::attr_eff_engine<mss::pre_data_init_fields>::set(l_spd_decoder) );
- FAPI_TRY( mss::attr_derived_engine<mss::generic_metadata_fields>::set(d) );
+ // Set pre_eff_config attributes derived from other attributes
+ FAPI_TRY( (mss::gen::attr_engine<mss::proc_type::AXONE, mss::generic_metadata_fields>::set(d)),
+ "Failed gen::attr_engine<mss::proc_type::AXONE, mss::generic_metadata_fields>::set on %s", mss::spd::c_str(d) );
+ }
}
}
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.H b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.H
index e4e20b050..ef3b57188 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,7 +38,7 @@
#include <fapi2.H>
-typedef fapi2::ReturnCode (*p9a_mss_freq_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>&);
+typedef fapi2::ReturnCode (*p9a_mss_freq_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);
extern "C"
{
@@ -48,7 +48,7 @@ extern "C"
/// @param[in] i_target port target
/// @return FAPI2_RC_SUCCESS iff ok
///
- fapi2::ReturnCode p9a_mss_freq( const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target );
+ fapi2::ReturnCode p9a_mss_freq( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target );
}
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.C
index cc23976d8..9088840f4 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -35,13 +35,57 @@
// fapi2
#include <p9a_mss_freq_system.H>
+#include <lib/freq/axone_sync.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+extern "C"
+{
///
/// @brief Matches OMI freq with DDR freq
-/// @param[in] i_target controller (e.g. MC)
+/// @param[in] i_target PROC_CHIP target
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode p9a_mss_freq_system( const fapi2::Target<fapi2::TARGET_TYPE_MC>& i_target )
-{
- return fapi2::FAPI2_RC_SUCCESS;
-}
+ fapi2::ReturnCode p9a_mss_freq_system( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target )
+ {
+ const auto& l_ports = mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target);
+
+ // If there are no DIMM we don't need to bother. In fact, we can't as we didn't setup
+ // attributes for the PHY, etc. If there is even one DIMM on this proc,
+ // we do the right thing.
+ if (mss::count_dimm(l_ports) == 0)
+ {
+ FAPI_INF("... skipping freq_system - no DIMM ...");
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ std::map< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>, uint64_t > l_freq_map;
+ uint32_t l_omi_freq = 0;
+ uint32_t l_selected_omi_freq = 0;
+ mss::speed_equality l_equal_dimm_speed;
+
+ // Get OMI freq
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_FREQ_OMI_MHZ, i_target, l_omi_freq) );
+
+ // Populate dimm speed map
+ FAPI_TRY( mss::dimm_speed_map(l_ports, l_freq_map, l_equal_dimm_speed),
+ "Failed to get dimm speed mapping" );
+
+ FAPI_INF("Dimm speed for all OCMBs are the same : %s",
+ uint8_t(l_equal_dimm_speed) ? "true" : "false");
+
+ // Select OMI freq, or check in the case of Cronus
+ FAPI_TRY( mss::select_omi_freq(l_freq_map,
+ l_equal_dimm_speed,
+ l_omi_freq,
+ l_selected_omi_freq) );
+
+ // Set attributes.
+ FAPI_INF("%s: Setting recommended OMI frequency in ATTR_FREQ_OMI_MHZ to %d", mss::c_str(i_target), l_selected_omi_freq);
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_FREQ_OMI_MHZ, i_target, l_selected_omi_freq) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+} //extern "C"
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.H b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.H
index cbf2d718c..31389feff 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,17 +39,17 @@
#include <fapi2.H>
#include <vector>
-typedef fapi2::ReturnCode (*p9a_mss_freq_system_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_MC>&);
+typedef fapi2::ReturnCode (*p9a_mss_freq_system_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);
extern "C"
{
///
/// @brief Matches OMI freq with DDR freq
- /// @param[in] i_target controller (e.g. MC)
+ /// @param[in] i_target PROC_CHIP target
/// @return FAPI2_RC_SUCCESS iff ok
///
- fapi2::ReturnCode p9a_mss_freq_system(const fapi2::Target<fapi2::TARGET_TYPE_MC>& i_target);
+ fapi2::ReturnCode p9a_mss_freq_system(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);
}
#endif
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.mk b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.mk
index 2e399418e..baacd38d6 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.mk
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq_system.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -27,5 +27,5 @@
-include 00p9a_common.mk
PROCEDURE=p9a_mss_freq_system
-$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
+$(eval $(call ADD_P9A_MEMORY_INCDIRS,$(PROCEDURE)))
$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.C
index 0666a8772..7d8afb81f 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,10 +38,16 @@
// *HWP Consumed by: FSP:HB
#include <p9a_mss_utils_to_throttle.H>
+#include <lib/shared/exp_defaults.H>
+#include <lib/shared/exp_consts.H>
+#include <mss_explorer_attribute_getters.H>
+#include <lib/power_thermal/exp_throttle.H>
// fapi2
#include <fapi2.H>
+extern "C"
+{
///
/// @brief Determines throttle and power values for a given port databus utilization.
/// @param[in] i_targets vector of OCMB_CHIPs to set throttle and power attributes on
@@ -49,11 +55,106 @@
/// @note ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT will be set to worst case of all slots passed in
/// @note input ATTR_MSS_DATABUS_UTIL and ATTR_MSS_MEM_WATT_TARGET
/// @note output ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, and ATTR_MSS_PORT_MAXPOWER
-/// @note Does not set runtime throttles or set registers to throttle values`
+/// @note Does not set runtime throttles or set registers to throttle values
///
-fapi2::ReturnCode p9a_mss_utils_to_throttle( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> >&
- i_targets )
-{
- FAPI_INF("Entering p9a_mss_utils_to_throttle");
- return fapi2::FAPI2_RC_SUCCESS;
-}
+ fapi2::ReturnCode p9a_mss_utils_to_throttle(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>>& i_targets)
+ {
+ constexpr uint64_t l_min_util = mss::power_thermal::throttle_traits<mss::mc_type::EXPLORER>::MIN_UTIL;
+
+ FAPI_INF("Entering p9a_mss_utils_to_throttle");
+
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>> l_exceeded_power;
+ bool l_util_error = false;
+
+ for (const auto& l_ocmb : i_targets)
+ {
+ if (mss::count_dimm(l_ocmb) == 0)
+ {
+ FAPI_INF("Skipping %s because it has no DIMM targets", mss::c_str(l_ocmb));
+ continue;
+ }
+
+ uint32_t l_max_databus_util = 0;
+ uint32_t l_dram_clocks = 0;
+ uint32_t l_safemode_util = 0;
+ uint32_t l_safemode_throttle_per_port = 0;
+ uint32_t l_calc_util = 0;
+
+ FAPI_TRY(mss::attr::get_mrw_mem_m_dram_clocks(l_dram_clocks));
+ FAPI_TRY(mss::attr::get_mrw_max_dram_databus_util(l_max_databus_util));
+ FAPI_TRY(mss::attr::get_mrw_safemode_dram_databus_util(l_safemode_util));
+
+ l_safemode_throttle_per_port = mss::power_thermal::calc_n_from_dram_util(
+ (l_safemode_util / mss::power_thermal::throttle_const::PERCENT_CONVERSION),
+ l_dram_clocks);
+
+ for(const auto& l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(l_ocmb))
+ {
+ fapi2::ReturnCode l_rc;
+ uint32_t l_input_databus_util = 0;
+ bool l_safemode = false;
+
+ // Util attribute set by OCC
+ FAPI_TRY( mss::attr::get_databus_util(l_port, l_input_databus_util) );
+
+ FAPI_INF("Input databus utilization for %s is %d",
+ mss::c_str(l_port),
+ l_input_databus_util);
+
+ // If input utilization is zero, use mrw safemode throttle values for utilization
+ // else make sure we're within our maximum utilization limit
+ FAPI_TRY(mss::power_thermal::calc_utilization<mss::mc_type::EXPLORER>(l_port,
+ l_input_databus_util,
+ l_dram_clocks,
+ l_safemode_throttle_per_port,
+ l_max_databus_util,
+ l_calc_util,
+ l_util_error,
+ l_safemode));
+
+ // Error if utilization is less than MIN_UTIL
+ // Don't exit, let HWP finish and return error at end
+ FAPI_ASSERT_NOEXIT( !l_util_error,
+ fapi2::MSS_MIN_UTILIZATION_ERROR()
+ .set_INPUT_UTIL_VALUE(l_input_databus_util)
+ .set_MIN_UTIL_VALUE(l_min_util),
+ "%s Input utilization (%d) less than minimum utilization allowed (%d)",
+ mss::c_str(l_port), l_input_databus_util, l_min_util);
+
+ // Make a throttle object in order to calculate the port power
+ mss::power_thermal::throttle<mss::mc_type::EXPLORER> l_throttle(l_port, l_rc);
+ FAPI_TRY(l_rc, "%s Error calculating mss::power_thermal::throttle constructor in p9a_mss_utils_to_throttles",
+ mss::c_str(l_port));
+
+ FAPI_TRY(l_throttle.calc_slots_and_power(l_calc_util));
+
+ FAPI_INF( "%s Calculated N commands per port %d, per slot %d, commands per dram clock window %d, maxpower is %d",
+ mss::c_str(l_port),
+ l_throttle.iv_n_port,
+ l_throttle.iv_n_slot,
+ l_dram_clocks,
+ l_throttle.iv_calc_port_maxpower);
+
+ FAPI_TRY(mss::attr::set_port_maxpower(l_port, l_throttle.iv_calc_port_maxpower));
+ FAPI_TRY(mss::attr::set_mem_throttled_n_commands_per_slot(l_port,
+ (l_safemode) ? l_safemode_throttle_per_port : l_throttle.iv_n_slot));
+ FAPI_TRY(mss::attr::set_mem_throttled_n_commands_per_port(l_port,
+ (l_safemode) ? l_safemode_throttle_per_port : l_throttle.iv_n_port));
+ } // ports
+ } // ocmbs
+
+ // Equalize throttles to prevent variable performance
+ // Note that we don't do anything with any port that exceed the power limit here, as we don't have an input power limit to go from
+ FAPI_TRY(mss::power_thermal::equalize_throttles<mss::mc_type::EXPLORER>(i_targets, mss::throttle_type::POWER,
+ l_exceeded_power));
+
+ // Return a failing RC code if we had any input utilization values less than MIN_UTIL
+ if (l_util_error)
+ {
+ fapi2::current_err = fapi2::RC_MSS_MIN_UTILIZATION_ERROR;
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+}// extern C
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.mk b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.mk
index a60770713..95a11aab6 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.mk
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.mk
@@ -25,5 +25,5 @@
-include 00p9a_common.mk
PROCEDURE=p9a_mss_utils_to_throttle
-$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
+$(eval $(call ADD_P9A_MEMORY_INCDIRS,$(PROCEDURE)))
$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_volt.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_volt.C
index a7b1d4b38..090f8f455 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_volt.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_volt.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -44,6 +44,7 @@
// mss lib
#include <generic/memory/lib/utils/c_str.H>
#include <generic/memory/lib/utils/voltage/gen_mss_volt.H>
+#include <generic/memory/mss_git_data_helper.H>
///
/// @brief Calculate and save off rail voltages
@@ -52,6 +53,8 @@
///
fapi2::ReturnCode p9a_mss_volt( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> >& i_targets )
{
+ mss::display_git_commit_info("p9a_mss_volt");
+
for (const auto& l_port : i_targets)
{
FAPI_TRY( (mss::setup_voltage_rail_values<mss::mc_type::EXPLORER, mss::spd::device_type::DDR4>(l_port)),
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_volt.mk b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_volt.mk
index 045691c45..70f0fe675 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_volt.mk
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_volt.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -27,5 +27,5 @@
-include 00p9a_common.mk
PROCEDURE=p9a_mss_volt
-$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
+$(eval $(call ADD_P9A_MEMORY_INCDIRS,$(PROCEDURE)))
$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_ocmb_thermal_init.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_ocmb_thermal_init.C
deleted file mode 100644
index c7f904572..000000000
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_ocmb_thermal_init.C
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9a/procedures/hwp/memory/p9a_ocmb_thermal_init.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_ocmb_thermal_init.H b/src/import/chips/p9a/procedures/hwp/memory/p9a_ocmb_thermal_init.H
deleted file mode 100644
index 5f2edfc82..000000000
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_ocmb_thermal_init.H
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9a/procedures/hwp/memory/p9a_ocmb_thermal_init.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.C
new file mode 100644
index 000000000..eaccc18c9
--- /dev/null
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.C
@@ -0,0 +1,98 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file p9a_omi_setup.C
+/// @brief Setup the OMI
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+#include <lib/shared/axone_defaults.H>
+#include <p9a_omi_setup.H>
+#include <lib/mc/omi.H>
+#include <generic/memory/mss_git_data_helper.H>
+#include <lib/workarounds/p9a_omi_workarounds.H>
+
+///
+/// @brief Setup OMI for axone
+/// @param[in] i_target the axone OMI target to operate on
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode p9a_omi_setup( const fapi2::Target<fapi2::TARGET_TYPE_OMI>& i_target )
+{
+ mss::display_git_commit_info("p9a_omi_setup");
+
+ FAPI_INF("%s Start p9a_omi_setup", mss::c_str(i_target));
+
+ const auto& l_mc = mss::find_target<fapi2::TARGET_TYPE_MC>(i_target);
+ const auto& l_ocmbs = mss::find_targets<fapi2::TARGET_TYPE_OCMB_CHIP>(i_target);
+
+ FAPI_TRY(mss::mc::setup_mc_mcn_config(l_mc));
+ FAPI_TRY(mss::mc::setup_mc_config1(i_target));
+ FAPI_TRY(mss::mc::setup_mc_cya_bits(i_target));
+ FAPI_TRY(mss::mc::setup_mc_error_action(i_target));
+ FAPI_TRY(mss::mc::setup_mc_rmt_config(i_target));
+
+ if(l_ocmbs.empty())
+ {
+ // No ocmbs, no training needed
+ // Ensuring we don't try to access an empty vector
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ {
+ // Only one OCMB per OMI for axone
+ const auto& l_ocmb = l_ocmbs[0];
+ const auto& l_proc = mss::find_target<fapi2::TARGET_TYPE_PROC_CHIP>(i_target);
+ uint8_t l_dl_x4_backoff_en = 0;
+ bool l_axone_workarounds_required = false;
+ uint8_t l_proc_type = 0;
+ uint8_t l_ocmb_type = 0;
+
+ // Get BACKOFF_ENABLE CHIP_EC attribute
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, l_ocmb, l_dl_x4_backoff_en),
+ "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE");
+
+ // Determine if workaround will be performed, if so, perform it
+ FAPI_TRY(mss::workarounds::mc::get_ocmb_proc_types(l_ocmb, l_proc, l_ocmb_type, l_proc_type));
+ l_axone_workarounds_required = mss::workarounds::mc::is_prbs_omi_axone_required(l_ocmb_type, l_proc_type);
+
+ if (l_axone_workarounds_required)
+ {
+ // TX_TRAINING_STATE1
+ FAPI_TRY(mss::workarounds::mc::pre_omi_training_prbs(i_target, l_dl_x4_backoff_en));
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.H b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.H
new file mode 100644
index 000000000..cf364294b
--- /dev/null
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.H
@@ -0,0 +1,53 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file p9a_omi_setup.H
+/// @brief Setup the OMI
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#ifndef P9A_OMI_SETUP_H_
+#define P9A_OMI_SETUP_H_
+
+#include <fapi2.H>
+
+typedef fapi2::ReturnCode (*p9a_omi_setup_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_OMI>&);
+
+extern "C"
+{
+ ///
+ /// @brief Setup OMI for axone
+ /// @param[in] i_target the axone OMI target to operate on
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode p9a_omi_setup( const fapi2::Target<fapi2::TARGET_TYPE_OMI>& i_target );
+}
+
+#endif
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.mk b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.mk
new file mode 100644
index 000000000..1edeebce8
--- /dev/null
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.mk
@@ -0,0 +1,29 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/import/chips/p9a/procedures/hwp/memory/p9a_omi_setup.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+-include 00p9a_common.mk
+
+PROCEDURE=p9a_omi_setup
+$(eval $(call ADD_P9A_MEMORY_INCDIRS,$(PROCEDURE)))
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.C
index 70202d95f..2075dfc5a 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -47,6 +47,8 @@
#include <generic/memory/lib/utils/find.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <lib/mc/omi.H>
+#include <lib/workarounds/p9a_omi_workarounds.H>
+#include <generic/memory/mss_git_data_helper.H>
///
@@ -56,19 +58,56 @@
///
fapi2::ReturnCode p9a_omi_train( const fapi2::Target<fapi2::TARGET_TYPE_OMI>& i_target)
{
+ mss::display_git_commit_info("p9a_omi_train");
+
FAPI_INF("%s Start p9a_omi_train", mss::c_str(i_target));
- const auto l_mc = mss::find_target<fapi2::TARGET_TYPE_MC>(i_target);
+ const auto& l_ocmbs = mss::find_targets<fapi2::TARGET_TYPE_OCMB_CHIP>(i_target);
+
+ if(l_ocmbs.empty())
+ {
+ // No ocmbs, no training needed
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ {
+ // Only one OCMB per OMI for axone
+ const auto& l_ocmb = l_ocmbs[0];
+ const auto& l_proc = mss::find_target<fapi2::TARGET_TYPE_PROC_CHIP>(l_ocmb);
+ uint8_t l_dl_x4_backoff_en = 0;
+ bool l_gem_or_non_axone_workaround = false;
+ bool l_axone_workarounds_required = false;
+ uint8_t l_proc_type = 0;
+ uint8_t l_ocmb_type = 0;
+
+ // Get BACKOFF_ENABLE CHIP_EC attribute
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, l_ocmb, l_dl_x4_backoff_en),
+ "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE");
+
+ // Determine if workarounds will be performed, if so, perform them
+ FAPI_TRY(mss::workarounds::mc::get_ocmb_proc_types(l_ocmb, l_proc, l_ocmb_type, l_proc_type));
+ l_gem_or_non_axone_workaround = mss::workarounds::mc::is_prbs_omi_required(l_ocmb_type, l_proc_type);
+ l_axone_workarounds_required = mss::workarounds::mc::is_prbs_omi_axone_required(l_ocmb_type, l_proc_type);
+
+ if (l_axone_workarounds_required)
+ {
+ // TX_PATTERN_A
+ FAPI_TRY(mss::workarounds::mc::omi_training_prbs(i_target, l_dl_x4_backoff_en));
+ }
+ else if (l_gem_or_non_axone_workaround)
+ {
+ // TX_TRAINING_STATE_3, TX_PATTERN_A
+ FAPI_TRY(mss::workarounds::mc::omi_training_prbs_gem(i_target, l_dl_x4_backoff_en));
- FAPI_TRY(mss::mc::setup_mc_mcn_config_helper(l_mc));
- FAPI_TRY(mss::mc::setup_mc_config1_helper(i_target));
- FAPI_TRY(mss::mc::setup_mc_cya_bits_helper(i_target));
- FAPI_TRY(mss::mc::setup_mc_error_action_helper(i_target));
- FAPI_TRY(mss::mc::setup_mc_rmt_config_helper(i_target));
+ // 2 second delay for gemini
+ FAPI_TRY(fapi2::delay(2 * mss::common_timings::DELAY_1S, mss::common_timings::DELAY_1MS));
+ }
- // *_CONFIG0 should be the last one written, since it starts the training.
- FAPI_TRY(mss::mc::setup_mc_config0_helper(i_target));
+ // Enable auto training
+ FAPI_TRY(mss::mc::setup_mc_config0(i_target, mss::omi::train_mode::ENABLE_AUTO_TRAINING, l_dl_x4_backoff_en));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.mk b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.mk
index f2deb6d74..83c2d899f 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.mk
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train.mk
@@ -27,5 +27,5 @@
-include 00p9a_common.mk
PROCEDURE=p9a_omi_train
-$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
+$(eval $(call ADD_P9A_MEMORY_INCDIRS,$(PROCEDURE)))
$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train_check.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train_check.C
index 50119a44d..f708f9ba1 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train_check.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train_check.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -44,6 +44,7 @@
#include <generic/memory/lib/utils/buffer_ops.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <lib/mc/omi.H>
+#include <generic/memory/mss_git_data_helper.H>
///
/// @brief Check the omi status in Axone side
@@ -52,52 +53,102 @@
///
fapi2::ReturnCode p9a_omi_train_check( const fapi2::Target<fapi2::TARGET_TYPE_OMI>& i_target)
{
+ mss::display_git_commit_info("p9a_omi_train_check");
+
FAPI_INF("%s Start p9a_omi_train_check", mss::c_str(i_target));
// Const
constexpr uint8_t STATE_MACHINE_SUCCESS = 0b111; // This value is from Lonny Lambrecht
- constexpr uint8_t MAX_LOOP_COUNT = 20; // Retry times
+ constexpr uint8_t MAX_LOOP_COUNT = 10; // Retry times
// Declares variables
fapi2::buffer<uint64_t> l_omi_status;
fapi2::buffer<uint64_t> l_omi_training_status;
+ fapi2::buffer<uint64_t> l_dl0_error_hold;
+ fapi2::buffer<uint64_t> l_expected_dl0_error_hold;
+ fapi2::buffer<uint64_t> l_dl0_config1;
uint8_t l_state_machine_state = 0;
uint8_t l_tries = 0;
+ uint32_t l_omi_freq = 0;
+
+ const auto& l_ocmbs = mss::find_targets<fapi2::TARGET_TYPE_OCMB_CHIP>(i_target);
+
+ // Sanity check for no empty vector
+ if (l_ocmbs.empty())
+ {
+ // No training could have occurred
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ const auto& l_proc = mss::find_target<fapi2::TARGET_TYPE_PROC_CHIP>(l_ocmbs[0]);
FAPI_TRY(mss::mc::omi_train_status(i_target, l_state_machine_state, l_omi_status));
- while (l_tries < MAX_LOOP_COUNT && l_state_machine_state != STATE_MACHINE_SUCCESS)
+ do
{
// Delay
- fapi2::delay(mss::DELAY_100US, 10 * mss::DELAY_1MS);
+ fapi2::delay(500 * mss::DELAY_1MS, 10 * mss::DELAY_1MS);
// Check OMI training status
FAPI_TRY(mss::mc::omi_train_status(i_target, l_state_machine_state, l_omi_status));
- // Note: this is very useful debug information while trying to debug training during polling
- FAPI_TRY(mss::getScom(i_target, P9A_MC_REG2_DL0_TRAINING_STATUS, l_omi_training_status));
l_tries++;
+
}
+ while (l_tries < MAX_LOOP_COUNT && l_state_machine_state != STATE_MACHINE_SUCCESS);
+ // Note: this is very useful debug information while trying to debug training during polling
FAPI_TRY(mss::getScom(i_target, P9A_MC_REG2_DL0_TRAINING_STATUS, l_omi_training_status));
+ FAPI_TRY(fapi2::getScom(i_target, P9A_MC_REG2_DL0_CONFIG1, l_dl0_config1));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FREQ_OMI_MHZ, l_proc, l_omi_freq));
+
FAPI_ASSERT(l_state_machine_state == STATE_MACHINE_SUCCESS,
fapi2::P9A_OMI_TRAIN_ERR()
- .set_TARGET(i_target)
+ .set_OMI_TARGET(i_target)
+ .set_OCMB_TARGET(l_ocmbs[0])
.set_EXPECTED_SM_STATE(STATE_MACHINE_SUCCESS)
.set_ACTUAL_SM_STATE(l_state_machine_state)
.set_DL0_STATUS(l_omi_status)
- .set_DL0_TRAINING_STATUS(l_omi_training_status),
- "%s OMI Training Failure, expected state:%d/actual state:%d",
+ .set_DL0_TRAINING_STATUS(l_omi_training_status)
+ .set_DL0_CONFIG1(l_dl0_config1)
+ .set_OMI_FREQ(l_omi_freq),
+ "%s P9A OMI Training Failure, expected state:%d/actual state:%d, DL0_STATUS:0x%016llx, DL0_TRAINING_STATUS:0x%016llx",
mss::c_str(i_target),
STATE_MACHINE_SUCCESS,
- l_state_machine_state
+ l_state_machine_state,
+ l_omi_status,
+ l_omi_training_status
);
- FAPI_INF("%s End p9a_omi_train_check, expected state:%d/actual state:%d, DL0_STATUS:0x%016llx, DL0_TRAINING_STATUS:0x%016llx",
+ // Check errors in ERROR_HOLD until we get a proper FIR API setup
+ FAPI_TRY(mss::getScom(i_target, P9A_MC_REG2_DL0_ERROR_HOLD, l_dl0_error_hold));
+
+ // Training completion bit set
+ l_expected_dl0_error_hold.setBit<P9A_OMI_REG0_DL0_ERROR_HOLD_CERR_39>();
+
+ // Lost block bit set: this results in p9a only, from the
+ // necessary pre-training workarounds, and is expected to be set
+ // TK - We will need to the proper FIR unmasking later
+ l_expected_dl0_error_hold.setBit<P9A_OMI_REG0_DL0_ERROR_HOLD_CERR_33>();
+
+ if (l_dl0_error_hold != l_expected_dl0_error_hold)
+ {
+ // To get to this point, we had to have completed training, so these errors are not catastrophic
+ // We don't need to assert out, but let's make sure we print them out
+ FAPI_INF("%s P9A_MC_REG2_DL0_ERROR_HOLD REG 0x%016llx "
+ "did not match expected value. REG contents: 0x%016llx Expected: 0x%016llx",
+ mss::c_str(i_target),
+ P9A_MC_REG2_DL0_ERROR_HOLD,
+ l_dl0_error_hold,
+ l_expected_dl0_error_hold);
+ }
+
+ FAPI_DBG("%s End p9a_omi_train_check, expected state:%d/actual state:%d, DL0_STATUS:0x%016llx, DL0_TRAINING_STATUS:0x%016llx",
mss::c_str(i_target),
STATE_MACHINE_SUCCESS,
l_state_machine_state,
l_omi_status,
l_omi_training_status);
+
return fapi2::FAPI2_RC_SUCCESS;
fapi_try_exit:
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train_check.mk b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train_check.mk
index 9f148de86..b976082cb 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train_check.mk
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_omi_train_check.mk
@@ -27,5 +27,5 @@
-include 00p9a_common.mk
PROCEDURE=p9a_omi_train_check
-$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
+$(eval $(call ADD_P9A_MEMORY_INCDIRS,$(PROCEDURE)))
$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9a/procedures/xml/error_info/p9a_freq_errors.xml b/src/import/chips/p9a/procedures/xml/error_info/p9a_freq_errors.xml
index 37909deb2..c20e29b05 100644
--- a/src/import/chips/p9a/procedures/xml/error_info/p9a_freq_errors.xml
+++ b/src/import/chips/p9a/procedures/xml/error_info/p9a_freq_errors.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2018,2019 -->
+<!-- Contributors Listed Below - COPYRIGHT 2018,2020 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -80,7 +80,7 @@
</callout>
<callout>
<childTargets>
- <parent>PORT_TARGET</parent>
+ <parent>TARGET</parent>
<childType>TARGET_TYPE_DIMM</childType>
</childTargets>
<priority>MEDIUM</priority>
diff --git a/src/import/chips/p9a/procedures/xml/error_info/p9a_omi_train_errors.xml b/src/import/chips/p9a/procedures/xml/error_info/p9a_omi_train_errors.xml
index 555c491c5..48f8f2ea2 100644
--- a/src/import/chips/p9a/procedures/xml/error_info/p9a_omi_train_errors.xml
+++ b/src/import/chips/p9a/procedures/xml/error_info/p9a_omi_train_errors.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2018,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -28,22 +28,28 @@
<hwpError>
<rc>RC_P9A_OMI_TRAIN_ERR</rc>
<description>
- Procedure: p9a_omi_train failure
+ p9a_omi_train_check did not see expected trained status from OMI DL0 status register
</description>
- <ffdc>TARGET</ffdc>
+ <ffdc>OMI_TARGET</ffdc>
<ffdc>EXPECTED_SM_STATE</ffdc>
<ffdc>ACTUAL_SM_STATE</ffdc>
<ffdc>DL0_STATUS</ffdc>
<ffdc>DL0_TRAINING_STATUS</ffdc>
+ <ffdc>DL0_CONFIG1</ffdc>
+ <ffdc>OMI_FREQ</ffdc>
<callout>
- <target>TARGET</target>
+ <target>OMI_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <bus>OMI_TARGET, OCMB_TARGET</bus>
<priority>HIGH</priority>
</callout>
<deconfigure>
- <target>TARGET</target>
+ <target>OMI_TARGET</target>
</deconfigure>
<gard>
- <target>TARGET</target>
+ <target>OMI_TARGET</target>
</gard>
</hwpError>
<!-- ******************************************************************** -->
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H b/src/import/generic/memory/lib/ccs/ccs.H
index 923b84052..f97c1f885 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H
+++ b/src/import/generic/memory/lib/ccs/ccs.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H $ */
+/* $Source: src/import/generic/memory/lib/ccs/ccs.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* Contributors Listed Below - COPYRIGHT 2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,7 +27,7 @@
/// @file ccs.H
/// @brief Run and manage the CCS engine
///
-// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
@@ -38,154 +38,13 @@
#include <fapi2.H>
-#include <p9_mc_scom_addresses.H>
-#include <p9_mc_scom_addresses_fld.H>
-
#include <generic/memory/lib/utils/poll.H>
#include <generic/memory/lib/utils/buffer_ops.H>
-#include <lib/mc/port.H>
-#include <lib/shared/mss_const.H>
-#include <lib/eff_config/timing.H>
-
-// I have a dream that the CCS engine code can be shared among controllers. So, I drive the
-// engine from a set of traits. This might be folly. Allow me to dream. BRS
-///
-/// @class ccsTraits
-/// @brief Nimbus CCS Engine traits
-///
-template< fapi2::TargetType T >
-class ccsTraits;
-
-template<>
-class ccsTraits<fapi2::TARGET_TYPE_MEMBUF_CHIP>
-{
- public:
-};
-
-template<>
-class ccsTraits<fapi2::TARGET_TYPE_MCBIST>
-{
- public:
- static constexpr uint64_t MODEQ_REG = MCBIST_CCS_MODEQ;
- static constexpr uint64_t MCB_CNTL_REG = MCBIST_MCB_CNTLQ;
- static constexpr uint64_t CNTLQ_REG = MCBIST_CCS_CNTLQ;
- static constexpr uint64_t STATQ_REG = MCBIST_CCS_STATQ;
- static constexpr fapi2::TargetType PORT_TARGET_TYPE = fapi2::TARGET_TYPE_MCA;
-
- enum
- {
- // Non address values that are needed for helper functions
-
- // ODT values used for beautification
- // Attribute locations
- ATTR_ODT_DIMM0_R0 = 0,
- ATTR_ODT_DIMM0_R1 = 1,
- ATTR_ODT_DIMM1_R0 = 4,
- ATTR_ODT_DIMM1_R1 = 5,
-
- // Right justified output - makes it so we can use insertFromRight
- CCS_ODT_DIMM0_R0 = 4,
- CCS_ODT_DIMM0_R1 = 5,
- CCS_ODT_DIMM1_R0 = 6,
- CCS_ODT_DIMM1_R1 = 7,
-
- // Default ODT cycle length is 5 - one for the preamble and 4 for the data
- DEFAULT_ODT_CYCLE_LEN = 5,
-
- // CCS MODEQ
- STOP_ON_ERR = MCBIST_CCS_MODEQ_STOP_ON_ERR,
- UE_DISABLE = MCBIST_CCS_MODEQ_UE_DISABLE,
- DATA_COMPARE_BURST_SEL = MCBIST_CCS_MODEQ_DATA_COMPARE_BURST_SEL,
- DATA_COMPARE_BURST_SEL_LEN = MCBIST_CCS_MODEQ_DATA_COMPARE_BURST_SEL_LEN,
- DDR_CAL_TIMEOUT_CNT = MCBIST_CCS_MODEQ_DDR_CAL_TIMEOUT_CNT,
- DDR_CAL_TIMEOUT_CNT_LEN = MCBIST_CCS_MODEQ_DDR_CAL_TIMEOUT_CNT_LEN,
- CFG_PARITY_AFTER_CMD = MCBIST_CCS_MODEQ_CFG_PARITY_AFTER_CMD,
- COPY_CKE_TO_SPARE_CKE = MCBIST_CCS_MODEQ_COPY_CKE_TO_SPARE_CKE,
- DISABLE_ECC_ARRAY_CHK = MCBIST_CCS_MODEQ_DISABLE_ECC_ARRAY_CHK,
- DISABLE_ECC_ARRAY_CORRECTION = MCBIST_CCS_MODEQ_DISABLE_ECC_ARRAY_CORRECTION,
- CFG_DGEN_FIXED_MODE = MCBIST_CCS_MODEQ_CFG_DGEN_FIXED_MODE,
- DDR_CAL_TIMEOUT_CNT_MULT = MCBIST_CCS_MODEQ_DDR_CAL_TIMEOUT_CNT_MULT,
- DDR_CAL_TIMEOUT_CNT_MULT_LEN = MCBIST_CCS_MODEQ_DDR_CAL_TIMEOUT_CNT_MULT_LEN,
- IDLE_PAT_ADDRESS_0_13 = MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_0_13,
- IDLE_PAT_ADDRESS_0_13_LEN = MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_0_13_LEN,
- IDLE_PAT_ADDRESS_17 = MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_17,
- IDLE_PAT_BANK_GROUP_1 = MCBIST_CCS_MODEQ_IDLE_PAT_BANK_GROUP_1,
- IDLE_PAT_BANK_0_1 = MCBIST_CCS_MODEQ_IDLE_PAT_BANK_0_1,
- IDLE_PAT_BANK_0_1_LEN = MCBIST_CCS_MODEQ_IDLE_PAT_BANK_0_1_LEN,
- IDLE_PAT_BANK_GROUP_0 = MCBIST_CCS_MODEQ_IDLE_PAT_BANK_GROUP_0,
- IDLE_PAT_ACTN = MCBIST_CCS_MODEQ_IDLE_PAT_ACTN,
- IDLE_PAT_ADDRESS_16 = MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_16,
- IDLE_PAT_ADDRESS_15 = MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_15,
- IDLE_PAT_ADDRESS_14 = MCBIST_CCS_MODEQ_IDLE_PAT_ADDRESS_14,
- NTTM_MODE = MCBIST_CCS_MODEQ_NTTM_MODE,
- NTTM_RW_DATA_DLY = MCBIST_CCS_MODEQ_NTTM_RW_DATA_DLY,
- NTTM_RW_DATA_DLY_LEN = MCBIST_CCS_MODEQ_NTTM_RW_DATA_DLY_LEN,
- IDLE_PAT_BANK_2 = MCBIST_CCS_MODEQ_IDLE_PAT_BANK_2,
- DDR_PARITY_ENABLE = MCBIST_CCS_MODEQ_DDR_PARITY_ENABLE,
- IDLE_PAT_PARITY = MCBIST_CCS_MODEQ_IDLE_PAT_PARITY,
-
- // MCB_CNTRL
- MCB_CNTL_PORT_SEL = MCBIST_MCB_CNTLQ_MCBCNTL_PORT_SEL,
- MCB_CNTL_PORT_SEL_LEN = MCBIST_MCB_CNTLQ_MCBCNTL_PORT_SEL_LEN,
-
- // CCS CNTL
- CCS_START = MCBIST_CCS_CNTLQ_START,
- CCS_STOP = MCBIST_CCS_CNTLQ_STOP,
-
- // CCS STATQ
- CCS_IN_PROGRESS = MCBIST_CCS_STATQ_IP,
-
- // ARR0
- ARR0_DDR_ADDRESS_0_13 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13,
- ARR0_DDR_ADDRESS_0_13_LEN = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13_LEN,
- ARR0_DDR_ADDRESS_0_9 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13, // Useful for rd/wr cmds
- ARR0_DDR_ADDRESS_0_9_LEN = 10, // CA bits are 9:0, total length of 10
- ARR0_DDR_ADDRESS_10 = 10, // ADR10 is the 10th bit from the left in Nimbus ARR0
- ARR0_DDR_ADDRESS_17 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_17,
- ARR0_DDR_BANK_GROUP_1 = MCBIST_CCS_INST_ARR0_00_DDR_BANK_GROUP_1,
- ARR0_DDR_RESETN = MCBIST_CCS_INST_ARR0_00_DDR_RESETN,
- ARR0_DDR_BANK_0_1 = MCBIST_CCS_INST_ARR0_00_DDR_BANK_0_1,
- ARR0_DDR_BANK_0_1_LEN = MCBIST_CCS_INST_ARR0_00_DDR_BANK_0_1_LEN,
- ARR0_DDR_BANK_GROUP_0 = MCBIST_CCS_INST_ARR0_00_DDR_BANK_GROUP_0,
- ARR0_DDR_ACTN = MCBIST_CCS_INST_ARR0_00_DDR_ACTN,
- ARR0_DDR_ADDRESS_16 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_16,
- ARR0_DDR_ADDRESS_15 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_15,
- ARR0_DDR_ADDRESS_14 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_14,
- ARR0_DDR_CKE = MCBIST_CCS_INST_ARR0_00_DDR_CKE,
- ARR0_DDR_CKE_LEN = MCBIST_CCS_INST_ARR0_00_DDR_CKE_LEN,
- ARR0_DDR_CSN_0_1 = MCBIST_CCS_INST_ARR0_00_DDR_CSN_0_1,
- ARR0_DDR_CSN_0_1_LEN = MCBIST_CCS_INST_ARR0_00_DDR_CSN_0_1_LEN,
- ARR0_DDR_CID_0_1 = MCBIST_CCS_INST_ARR0_00_DDR_CID_0_1,
- ARR0_DDR_CID_0_1_LEN = MCBIST_CCS_INST_ARR0_00_DDR_CID_0_1_LEN,
- ARR0_DDR_CSN_2_3 = MCBIST_CCS_INST_ARR0_00_DDR_CSN_2_3,
- ARR0_DDR_CSN_2_3_LEN = MCBIST_CCS_INST_ARR0_00_DDR_CSN_2_3_LEN,
- ARR0_DDR_CID_2 = MCBIST_CCS_INST_ARR0_00_DDR_CID_2,
- ARR0_DDR_ODT = MCBIST_CCS_INST_ARR0_00_DDR_ODT,
- ARR0_DDR_ODT_LEN = MCBIST_CCS_INST_ARR0_00_DDR_ODT_LEN,
- ARR0_DDR_CAL_TYPE = MCBIST_CCS_INST_ARR0_00_DDR_CAL_TYPE,
- ARR0_DDR_CAL_TYPE_LEN = MCBIST_CCS_INST_ARR0_00_DDR_CAL_TYPE_LEN,
- ARR0_DDR_PARITY = MCBIST_CCS_INST_ARR0_00_DDR_PARITY,
- ARR0_DDR_BANK_2 = MCBIST_CCS_INST_ARR0_00_DDR_BANK_2,
- ARR0_LOOP_BREAK_MODE = MCBIST_CCS_INST_ARR0_00_LOOP_BREAK_MODE,
- ARR0_LOOP_BREAK_MODE_LEN = MCBIST_CCS_INST_ARR0_00_LOOP_BREAK_MODE_LEN,
-
- // ARR1
- ARR1_IDLES = MCBIST_CCS_INST_ARR1_00_IDLES,
- ARR1_IDLES_LEN = MCBIST_CCS_INST_ARR1_00_IDLES_LEN,
- ARR1_REPEAT_CMD_CNT = MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT,
- ARR1_REPEAT_CMD_CNT_LEN = MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT_LEN,
- ARR1_READ_OR_WRITE_DATA = MCBIST_CCS_INST_ARR1_00_READ_OR_WRITE_DATA,
- ARR1_READ_OR_WRITE_DATA_LEN = MCBIST_CCS_INST_ARR1_00_READ_OR_WRITE_DATA_LEN,
- ARR1_READ_COMPARE_REQUIRED = MCBIST_CCS_INST_ARR1_00_READ_COMPARE_REQUIRED,
- ARR1_DDR_CAL_RANK = MCBIST_CCS_INST_ARR1_00_DDR_CAL_RANK,
- ARR1_DDR_CAL_RANK_LEN = MCBIST_CCS_INST_ARR1_00_DDR_CAL_RANK_LEN,
- ARR1_DDR_CALIBRATION_ENABLE = MCBIST_CCS_INST_ARR1_00_DDR_CALIBRATION_ENABLE,
- ARR1_END = MCBIST_CCS_INST_ARR1_00_END,
- ARR1_GOTO_CMD = MCBIST_CCS_INST_ARR1_00_GOTO_CMD,
- ARR1_GOTO_CMD_LEN = MCBIST_CCS_INST_ARR1_00_GOTO_CMD_LEN,
-
- };
-};
+#include <generic/memory/lib/utils/index.H>
+#include <generic/memory/lib/utils/pos.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/ccs/ccs_traits.H>
namespace mss
{
@@ -227,31 +86,16 @@ enum rank_configuration
};
///
-/// @brief Enums for CCS return codes
-///
-enum
-{
- // Success is defined as done-bit set, no others.
- STAT_QUERY_SUCCESS = 0x4000000000000000,
-
- // Bit positions 3:5
- STAT_READ_MISCOMPARE = 0x1000000000000000,
- STAT_UE_SUE = 0x0800000000000000,
- STAT_CAL_TIMEOUT = 0x0400000000000000,
-
- // If the fail type isn't one of these, we're hung
- STAT_HUNG = 0x0ull,
-};
-
-///
/// @class instruction_t
/// @brief Class for ccs instructions
/// @tparam T fapi2::TargetType representing the target of the CCS instructions
/// @note A ccs instruction is data (array 0) and some control information (array 1)cc
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
class instruction_t
{
+ private:
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
public:
fapi2::buffer<uint64_t> arr0;
fapi2::buffer<uint64_t> arr1;
@@ -269,7 +113,7 @@ class instruction_t
/// @param[in] i_arr1 the initial value for arr1, defaults to 0
/// @param[in] i_update_rank true if the rank should be updated before being sent, defaults to true
///
- instruction_t( uint64_t i_rank = NO_CHIP_SELECT_ACTIVE,
+ instruction_t( const uint64_t i_rank = NO_CHIP_SELECT_ACTIVE,
const fapi2::buffer<uint64_t> i_arr0 = 0,
const fapi2::buffer<uint64_t> i_arr1 = 0,
const bool i_update_rank = true):
@@ -278,7 +122,7 @@ class instruction_t
iv_rank(i_rank),
iv_update_rank(i_update_rank)
{
- // Skip setting up the rank if hte user doesn't want us to
+ // Skip setting up the rank if the user doesn't want us to
if(iv_update_rank)
{
// Set the chip selects to be 1's (not active)
@@ -314,11 +158,11 @@ class instruction_t
}
// First, check rank - we need to make sure that we have a valid rank
- FAPI_ASSERT(iv_rank < MAX_MRANK_PER_PORT,
+ FAPI_ASSERT(iv_rank < TT::CCS_MAX_MRANK_PER_PORT,
fapi2::MSS_INVALID_RANK()
- .set_MCA_TARGET(i_target)
+ .set_PORT_TARGET(i_target)
.set_RANK(iv_rank)
- .set_FUNCTION(ffdc_function_codes::CCS_INST_CONFIGURE_RANK),
+ .set_FUNCTION(generic_ffdc_codes::CCS_INST_CONFIGURE_RANK),
"%s rank out of bounds rank%u", mss::c_str(i_target), iv_rank);
// Now the fun happens and we can deal with the actual encoding
@@ -333,36 +177,13 @@ class instruction_t
// CS0 will select rank 0/1
// CS1 will select rank 2/3
- // Note: this is to workaround a Nimbus CCS bug
- // 1) Nimbus thinks that CID0 is a CID not part of the CS for encoded mode
- // 2) CID1 doesn't matter for quad encode
- // 3) we only access ranks 2,3 in encoded mode
- // 4) we can fake out parity by adding in another 1, so let's do that with CID1
- // This is easier than calculating our own parity
- // CS0 H, CS1 L, CID0-> L => Rank 2
-
- static const std::pair<uint64_t, uint64_t> CS_N[mss::MAX_RANK_PER_DIMM] =
- {
- // CS0 L, CS1 H, CID0-> L => Rank 0
- { 0b01, 0b00 },
-
- // CS0 L, CS1 H, CID0-> H => Rank 1
- { 0b01, 0b11 },
-
- // CS0 H, CS1 L, CID0-> L => Rank 2
- { 0b10, 0b00 },
-
- // CS0 H, CS1 L, CID0-> H => Rank 3
- { 0b10, 0b11 },
- };
-
const auto l_dimm_rank = mss::index(iv_rank);
- const bool l_is_dimm0 = iv_rank < MAX_RANK_PER_DIMM;
+ const bool l_is_dimm0 = iv_rank < TT::CCS_MAX_RANK_PER_DIMM;
constexpr uint64_t NON_DIMM_CS = 0b11;
// Assigns the CS based upon which DIMM we're at
- const auto CS01 = l_is_dimm0 ? CS_N[l_dimm_rank].first : NON_DIMM_CS;
- const auto CS23 = l_is_dimm0 ? NON_DIMM_CS : CS_N[l_dimm_rank].first;
+ const auto CS01 = l_is_dimm0 ? TT::CS_N[l_dimm_rank].first : NON_DIMM_CS;
+ const auto CS23 = l_is_dimm0 ? NON_DIMM_CS : TT::CS_N[l_dimm_rank].first;
// Setup that rank
arr0.insertFromRight<TT::ARR0_DDR_CSN_0_1,
@@ -370,35 +191,18 @@ class instruction_t
arr0.insertFromRight<TT::ARR0_DDR_CSN_2_3,
TT::ARR0_DDR_CSN_2_3_LEN>(CS23);
arr0.insertFromRight<TT::ARR0_DDR_CID_0_1,
- TT::ARR0_DDR_CID_0_1_LEN>(CS_N[l_dimm_rank].second);
+ TT::ARR0_DDR_CID_0_1_LEN>(TT::CS_N[l_dimm_rank].second);
}
// Otherwise, setup for dual-direct mode (our only other supported mode at the moment)
else
{
- // For DIMM0 .first is the CSN_0_1 setting, .second is the CSN_2_3 setting.
- // For DIMM1 .first is the CSN_2_3 setting, .second is the CSN_0_1 setting.
- static const std::pair<uint64_t, uint64_t> CS_N[mss::MAX_RANK_PER_DIMM] =
- {
- // CS0 L CS1 H => CS2 => H CS3 => H Rank 0
- { 0b01, 0b11 },
-
- // CS0 H CS1 L => CS2 => H CS3 => H Rank 1
- { 0b10, 0b11 },
-
- // CS0 H CS1 H => CS2 => L CS3 => H Rank 2
- { 0b11, 0b01 },
-
- // CS0 H CS1 H => CS2 => H CS3 => L Rank 3
- { 0b11, 0b10 },
- };
-
const auto l_dimm_rank = mss::index(iv_rank);
- const bool l_is_dimm0 = iv_rank < MAX_RANK_PER_DIMM;
+ const bool l_is_dimm0 = iv_rank < TT::CCS_MAX_RANK_PER_DIMM;
// Assigns the CS based upon which DIMM we're at
- const auto CS01 = l_is_dimm0 ? CS_N[l_dimm_rank].first : CS_N[l_dimm_rank].second;
- const auto CS23 = l_is_dimm0 ? CS_N[l_dimm_rank].second : CS_N[l_dimm_rank].first;
+ const auto CS01 = l_is_dimm0 ? TT::CS_ND[l_dimm_rank].first : TT::CS_ND[l_dimm_rank].second;
+ const auto CS23 = l_is_dimm0 ? TT::CS_ND[l_dimm_rank].second : TT::CS_ND[l_dimm_rank].first;
// Setup that rank
arr0.insertFromRight<TT::ARR0_DDR_CSN_0_1,
@@ -411,11 +215,11 @@ class instruction_t
// 1) we are DIMM1
// 2) our DIMM rank is greater than the maximum allowed number of ranks on DIMM1
// So, we pass always if we're DIMM0, or if our DIMM rank is less than the maximum number of DIMM's on rank 1
- FAPI_ASSERT(l_dimm_rank < MAX_RANKS_DIMM1 || l_is_dimm0,
+ FAPI_ASSERT(l_dimm_rank < TT::CCS_MAX_RANKS_DIMM1 || l_is_dimm0,
fapi2::MSS_INVALID_RANK()
- .set_MCA_TARGET(i_target)
+ .set_PORT_TARGET(i_target)
.set_RANK(iv_rank)
- .set_FUNCTION(ffdc_function_codes::CCS_INST_CONFIGURE_RANK),
+ .set_FUNCTION(generic_ffdc_codes::CCS_INST_CONFIGURE_RANK),
"%s rank out of bounds rank%u", mss::c_str(i_target), iv_rank);
}
@@ -429,7 +233,7 @@ class instruction_t
/// @param[in] i_rhs - the instruction to compare to
/// @return True if both instructions are equal
///
- inline bool operator==( const instruction_t<T>& i_rhs ) const
+ inline bool operator==( const instruction_t& i_rhs ) const
{
return arr0 == i_rhs.arr0 &&
arr1 == i_rhs.arr1 &&
@@ -439,32 +243,70 @@ class instruction_t
};
///
-/// @brief Determines our rank configuration type across all ports
+/// @brief Determines our rank configuration type
/// @param[in] i_target the MCA target on which to operate
/// @param[out] o_rank_config the rank configuration
/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS if ok
///
-fapi2::ReturnCode get_rank_config(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- std::vector<rank_configuration>& o_rank_config);
+inline fapi2::ReturnCode get_rank_config(const fapi2::Target<DEFAULT_MEM_PORT_TARGET>& i_target,
+ rank_configuration& o_rank_config)
+{
+ typedef ccsTraits<DEFAULT_MC_TYPE> TT;
+ constexpr uint8_t QUAD_RANK_ENABLE = 4;
+ o_rank_config = rank_configuration::DUAL_DIRECT;
+
+ uint8_t l_num_master_ranks[TT::CCS_MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY(TT::get_rank_config_attr(i_target, l_num_master_ranks));
+
+ // We only need to check DIMM0
+ // Our number of ranks should be the same between DIMM's 0/1
+ // Check if we have the right number for encoded mode
+ o_rank_config = l_num_master_ranks[0] == QUAD_RANK_ENABLE ?
+ rank_configuration::QUAD_ENCODED :
+ rank_configuration::DUAL_DIRECT;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
///
-/// @brief Determines our rank configuration type
+/// @brief Determines our rank configuration type across all ports
/// @param[in] i_target the MCA target on which to operate
/// @param[out] o_rank_config the rank configuration
/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS if ok
///
-fapi2::ReturnCode get_rank_config(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- rank_configuration& o_rank_config);
+inline fapi2::ReturnCode get_rank_config(const fapi2::Target<DEFAULT_MC_TARGET>& i_target,
+ std::vector<rank_configuration>& o_rank_config)
+{
+ typedef ccsTraits<DEFAULT_MC_TYPE> TT;
+
+ o_rank_config.clear();
+ // Create one per port, we then use relative indexing to get us the number we need
+ o_rank_config = std::vector<rank_configuration>(TT::PORTS_PER_MC_TARGET);
+
+ for(const auto& l_port : mss::find_targets<DEFAULT_MEM_PORT_TARGET>(i_target))
+ {
+ rank_configuration l_config;
+ FAPI_TRY(get_rank_config(l_port, l_config));
+ o_rank_config[mss::relative_pos<DEFAULT_MC_TARGET>(l_port)] = l_config;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
///
/// @brief A class representing a series of CCS instructions, and the
/// CCS engine parameters associated with running the instructions
/// @tparam T fapi2::TargetType representing the fapi2 target which
/// @tparam P fapi2::TargetType representing the port
-/// contains the CCS engine (e.g., fapi2::TARGET_TYPE_MCBIST)
-template< fapi2::TargetType T, fapi2::TargetType P = fapi2::TARGET_TYPE_MCA >
+/// contains the CCS engine
class program
{
+ private:
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
public:
// Setup our poll parameters so the CCS executer can see
// whether to use the delays in the instruction stream or not
@@ -472,22 +314,22 @@ class program
{}
// Vector of instructions
- std::vector< instruction_t<T> > iv_instructions;
+ std::vector< instruction_t > iv_instructions;
poll_parameters iv_poll;
// Vector of polling probes
- std::vector< poll_probe<P> > iv_probes;
+ std::vector< poll_probe<TT::PORT_TARGET_TYPE> > iv_probes;
};
///
/// @brief Common setup for all MRS/RCD instructions
-/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in,out] i_arr0 fapi2::buffer<uint64_t> representing the ARR0 of the instruction
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
static void mrs_rcd_helper( fapi2::buffer<uint64_t>& i_arr0 )
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
//
// Generic DDR4 MRS setup (RCD is an MRS)
//
@@ -505,13 +347,14 @@ static void mrs_rcd_helper( fapi2::buffer<uint64_t>& i_arr0 )
///
/// @brief Setup activate command instruction
-/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
+/// @param[in] i_target the DIMM this instruction is headed for
/// @param[in] i_rank the rank on this dimm
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> act_command( const uint64_t i_rank)
+inline instruction_t act_command( const uint64_t i_rank )
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
fapi2::buffer<uint64_t> l_boilerplate_arr0;
fapi2::buffer<uint64_t> l_boilerplate_arr1;
@@ -535,12 +378,11 @@ inline instruction_t<T> act_command( const uint64_t i_rank)
l_boilerplate_arr0.clearBit<TT::ARR0_DDR_BANK_0_1, TT::ARR0_DDR_BANK_0_1_LEN>();
l_boilerplate_arr0.clearBit<TT::ARR0_DDR_BANK_2>();
- return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
///
/// @brief Create, initialize an RCD (RCW - JEDEC) CCS command
-/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] i_target the DIMM this instruction is headed for
/// @param[in] i_turn_on_cke flag that states whether we want CKE on for this RCW (defaulted to true)
@@ -549,18 +391,19 @@ inline instruction_t<T> act_command( const uint64_t i_rank)
/// for the controller (Nimbus v Centaur) and then correct for DRAM generation (not included
/// in this template definition)
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> rcd_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const bool i_sim,
- const bool i_turn_on_cke = true)
+inline instruction_t rcd_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const bool i_sim,
+ const bool i_turn_on_cke = true)
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
fapi2::buffer<uint64_t> rcd_boilerplate_arr0;
fapi2::buffer<uint64_t> rcd_boilerplate_arr1;
//
// Generic DDR4 MRS setup (RCD is an MRS)
//
- mrs_rcd_helper<fapi2::TARGET_TYPE_MCBIST>(rcd_boilerplate_arr0);
+ mrs_rcd_helper(rcd_boilerplate_arr0);
// Not adding i_turn_on_cke in the mrs_rcd helper because we only need this
// for RCWs and there is no need to complicate/change the MRS cmd API with
@@ -581,13 +424,13 @@ inline instruction_t<T> rcd_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM
.template setBit<TT::ARR0_DDR_BANK_GROUP_0>();
// RCD always goes to the 0th rank on the DIMM; either 0 or 4.
- return instruction_t<T>((mss::index(i_target) == 0) ? 0 : 4, rcd_boilerplate_arr0, rcd_boilerplate_arr1);
+ return instruction_t((mss::index(i_target) == 0) ? 0 : 4, rcd_boilerplate_arr0, rcd_boilerplate_arr1);
}
///
/// @brief Create, initialize an MRS CCS command
-/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
+/// @param[in] i_target the DIMM this instruction is headed for
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_mrs the specific MRS
/// @return the MRS CCS instruction
@@ -595,10 +438,11 @@ inline instruction_t<T> rcd_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM
/// for the controller (Nimbus v Centaur) and then correct for DRAM generation (not included
/// in this template definition)
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> mrs_command (const uint64_t i_rank,
- const uint64_t i_mrs )
+inline instruction_t mrs_command ( const uint64_t i_rank,
+ const uint64_t i_mrs )
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
fapi2::buffer<uint64_t> rcd_boilerplate_arr0;
fapi2::buffer<uint64_t> rcd_boilerplate_arr1;
fapi2::buffer<uint8_t> mrs(i_mrs);
@@ -606,7 +450,7 @@ inline instruction_t<T> mrs_command (const uint64_t i_rank,
//
// Generic DDR4 MRS setup (RCD is an MRS)
//
- mrs_rcd_helper<fapi2::TARGET_TYPE_MCBIST>(rcd_boilerplate_arr0);
+ mrs_rcd_helper(rcd_boilerplate_arr0);
//
// MRS setup
@@ -614,23 +458,22 @@ inline instruction_t<T> mrs_command (const uint64_t i_rank,
// DDR4: Set BG1 to 0. BG0, BA1:BA0 to i_mrs
rcd_boilerplate_arr0.clearBit<TT::ARR0_DDR_BANK_GROUP_1>();
mss::swizzle<TT::ARR0_DDR_BANK_0_1, 3, 7>(mrs, rcd_boilerplate_arr0);
- FAPI_DBG("mrs rcd boiler 0x%llx 0x%llx", uint8_t(mrs), uint64_t(rcd_boilerplate_arr0));
- return instruction_t<T>(i_rank, rcd_boilerplate_arr0, rcd_boilerplate_arr1);
+ FAPI_DBG("mrs rcd boiler 0x%016lx 0x%llx", uint8_t(mrs), uint64_t(rcd_boilerplate_arr0));
+ return instruction_t(i_rank, rcd_boilerplate_arr0, rcd_boilerplate_arr1);
}
///
/// @brief Create, initialize a JEDEC Device Deselect CCS command
-/// @tparam T the target type of the chiplet which executes the CCS instruction
-/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] i_idle the idle time to the next command (default to 0)
/// @return the Device Deselect CCS instruction
/// @note THIS IS DDR4 ONLY RIGHT NOW. We can (and possibly should) specialize this
/// for the controller (Nimbus v Centaur) and then correct for DRAM generation (not included
/// in this template definition)
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> des_command(const uint16_t i_idle = 0)
+inline instruction_t des_command(const uint16_t i_idle = 0)
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
fapi2::buffer<uint64_t> rcd_boilerplate_arr0;
fapi2::buffer<uint64_t> rcd_boilerplate_arr1;
@@ -648,21 +491,21 @@ inline instruction_t<T> des_command(const uint16_t i_idle = 0)
// RAS, CAS, WE no-care
// Device Deslect wants CS_n always high (select nothing using rank NO_CHIP_SELECT_ACTIVE)
- return instruction_t<T>( NO_CHIP_SELECT_ACTIVE,
- rcd_boilerplate_arr0,
- rcd_boilerplate_arr1);
+ return instruction_t( NO_CHIP_SELECT_ACTIVE,
+ rcd_boilerplate_arr0,
+ rcd_boilerplate_arr1);
}
///
/// @brief Converts an ODT attribute to CCS array input
-/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] i_attr_value ODT attribute value
/// @return CCS value for the ODT's
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
inline uint8_t convert_odt_attr_to_ccs(const fapi2::buffer<uint8_t>& i_attr_value)
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
// ODT value buffer
fapi2::buffer<uint8_t> l_ccs_value;
l_ccs_value.template writeBit<TT::CCS_ODT_DIMM0_R0>(i_attr_value.template getBit<TT::ATTR_ODT_DIMM0_R0>())
@@ -675,8 +518,7 @@ inline uint8_t convert_odt_attr_to_ccs(const fapi2::buffer<uint8_t>& i_attr_valu
}
///
-/// @brief Create, initialize a JEDEC Device Deselect CCS command
-/// @tparam T the target type of the chiplet which executes the CCS instruction
+/// @brief Create, initialize an ODT CCS command
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] i_odt_values CCS defined ODT values
/// @param[in] i_cycles the number of cycles to hold the ODT for - defaults to DEFAULT_ODT_CYCLE_LEN
@@ -686,10 +528,10 @@ inline uint8_t convert_odt_attr_to_ccs(const fapi2::buffer<uint8_t>& i_attr_valu
/// As such, it's up to the programmers to hold the ODT's appropriately
/// This "command" will greatly help us do that
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> odt_command(const uint8_t i_odt_values, const uint64_t i_cycles = TT::DEFAULT_ODT_CYCLE_LEN)
+template< typename TT = ccsTraits<DEFAULT_MC_TYPE> >
+inline instruction_t odt_command(const uint8_t i_odt_values, const uint64_t i_cycles = TT::DEFAULT_ODT_CYCLE_LEN)
{
- auto l_odt_cmd = des_command<T>();
+ auto l_odt_cmd = des_command();
l_odt_cmd.arr0.template insertFromRight<TT::ARR0_DDR_ODT, TT::ARR0_DDR_ODT_LEN>(i_odt_values);
l_odt_cmd.arr1.template insertFromRight<TT::ARR1_REPEAT_CMD_CNT, TT::ARR1_REPEAT_CMD_CNT_LEN>(i_cycles);
@@ -699,91 +541,51 @@ inline instruction_t<T> odt_command(const uint8_t i_odt_values, const uint64_t i
///
/// @brief Create, initialize a NTTM read CCS command
-/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @return the Device Deselect CCS instruction
/// @note need to setup 4 cycles delay
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> nttm_read_command()
+inline instruction_t nttm_read_command()
{
- // setup 4 cycles delay
- constexpr uint64_t NTTM_READ_DELAY = 4;
- // No.. there's no field for this one. it's an undocumented bit
- constexpr uint64_t NTTM_MODE_FORCE_READ = 33;
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
// get the des_command
- auto l_command = des_command<T>();
+ auto l_command = des_command();
// set to CCS_INST_ARR1 register
- l_command.arr1.template setBit<NTTM_MODE_FORCE_READ>();
- l_command.arr1.template insertFromRight<TT::ARR1_IDLES, TT::ARR1_IDLES_LEN>(NTTM_READ_DELAY);
+ l_command.arr1.template setBit<TT::NTTM_MODE_FORCE_READ>();
+ l_command.arr1.template insertFromRight<TT::ARR1_IDLES, TT::ARR1_IDLES_LEN>(TT::NTTM_READ_DELAY);
return l_command;
}
///
/// @brief Create, initialize a JEDEC Device Power Down Entry CCS command
-/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @return the Device Deselect CCS instruction
/// @note THIS IS DDR4 ONLY RIGHT NOW. We can (and possibly should) specialize this
/// for the controller (Nimbus v Centaur) and then correct for DRAM generation (not included
/// in this template definition)
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> pde_command()
+inline instruction_t pde_command()
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
fapi2::buffer<uint64_t> rcd_boilerplate_arr0;
fapi2::buffer<uint64_t> rcd_boilerplate_arr1;
// Power Down Entry just like a DES, but we set CKE low
- instruction_t<T> l_inst = des_command<T>();
+ instruction_t l_inst = des_command();
// CKE is low. Note: P8 set all 4 of these low - not sure if that's correct.
l_inst.arr0.template insertFromRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(CKE_LOW);
- l_inst.arr1.template insertFromRight<TT::ARR1_IDLES, TT::ARR1_IDLES_LEN>( mss::tcpded() );
-
- return l_inst;
-}
-
-///
-/// @brief Create, initialize an instruction which indicates an initial cal
-/// @tparam T the target type of the chiplet which executes the CCS instruction
-/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
-/// @param[in] i_rp the rank-pair (rank) to cal
-/// @return the initial cal instruction
-///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> initial_cal_command(const uint64_t i_rp)
-{
- // An initial cal arr0 looks just like a DES, but we set the initial cal bits
- instruction_t<T> l_inst = des_command<T>();
-
- // ACT is low - per Centaur spec (Shelton to confirm for Nimbus) BRS
- l_inst.arr0.template clearBit<TT::ARR0_DDR_ACTN>();
-
- l_inst.arr0.template insertFromRight<TT::ARR0_DDR_CAL_TYPE, TT::ARR0_DDR_CAL_TYPE_LEN>(0b1100);
- l_inst.arr1.template setBit<TT::ARR1_DDR_CALIBRATION_ENABLE>();
-
-#ifdef USE_LOTS_OF_IDLES
- // Idles is 0xFFFF - per Centaur spec (Shelton to confirm for Nimbus) BRS
- l_inst.arr1.template insertFromRight<TT::ARR1_IDLES, TT::ARR1_IDLES_LEN>(0xFFFF);
-#else
- l_inst.arr1.template insertFromRight<TT::ARR1_IDLES, TT::ARR1_IDLES_LEN>(0x0);
-#endif
-
- // The rank we're calibrating is enacoded - it's an int. So rank 3 is 0011 not 0001
- l_inst.arr1.template insertFromRight<TT::ARR1_DDR_CAL_RANK, TT::ARR1_DDR_CAL_RANK_LEN>(i_rp);
+ l_inst.arr1.template insertFromRight<TT::ARR1_IDLES, TT::ARR1_IDLES_LEN>( TT::TIMING_TCPDED );
return l_inst;
}
///
/// @brief Setup ZQ Long instruction
-/// @tparam T the target type of the chiplet which executes the CCS instruction
-/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
-/// @param[in] i_target the DIMM this instruction is headed for
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_idle the idle time to the next command (default to 0)
/// @return the MRS CCS instruction
@@ -791,10 +593,11 @@ inline instruction_t<T> initial_cal_command(const uint64_t i_rp)
/// for the controller (Nimbus v Centaur) and then correct for DRAM generation (not included
/// in this template definition)
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> zqcl_command( const uint64_t i_rank,
- const uint16_t i_idle = 0 )
+inline instruction_t zqcl_command( const uint64_t i_rank,
+ const uint16_t i_idle = 0 )
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
fapi2::buffer<uint64_t> l_boilerplate_arr0;
fapi2::buffer<uint64_t> l_boilerplate_arr1;
@@ -815,13 +618,11 @@ inline instruction_t<T> zqcl_command( const uint64_t i_rank,
// Insert idle
l_boilerplate_arr1.template insertFromRight<TT::ARR1_IDLES, TT::ARR1_IDLES_LEN>( i_idle );
- return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
///
/// @brief Setup read command helper function
-/// @tparam T the target type of the chiplet which executes the CCS instruction
-/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_bank_addr bank address bits [BG0:BG1] = [62:63] (right aligned)
/// @param[in] i_bank_group_addr bank group address bits [BA0:BA1] = [62:63] (right aligned)
@@ -831,12 +632,13 @@ inline instruction_t<T> zqcl_command( const uint64_t i_rank,
/// for the controller (Nimbus v Centaur) and then correct for DRAM generation (not included
/// in this template definition)
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
static fapi2::buffer<uint64_t> read_cmd_boilerplate( const uint64_t i_rank,
const fapi2::buffer<uint64_t>& i_bank_addr = 0,
const fapi2::buffer<uint64_t>& i_bank_group_addr = 0,
const fapi2::buffer<uint64_t>& i_column_addr = 0)
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
// TODO - RTC 166175 Encapsulate command truth table in a subclass for ccs.H
fapi2::buffer<uint64_t> l_boilerplate_arr0;
@@ -871,7 +673,6 @@ static fapi2::buffer<uint64_t> read_cmd_boilerplate( const uint64_t i_rank,
///
/// @brief Setup write command (Fixed BL8 or BC4) instruction
-/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_bank_addr bank address bits [BA0:BA1] = [62:63] (right aligned)
@@ -882,14 +683,15 @@ static fapi2::buffer<uint64_t> read_cmd_boilerplate( const uint64_t i_rank,
/// for the controller (Nimbus v Centaur) and then correct for DRAM generation (not included
/// in this template definition)
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> wr_command( const uint64_t i_rank,
- const fapi2::buffer<uint64_t>& i_bank_addr = 0,
- const fapi2::buffer<uint64_t>& i_bank_group_addr = 0,
- const fapi2::buffer<uint64_t>& i_column_addr = 0)
+inline instruction_t wr_command( const uint64_t i_rank,
+ const fapi2::buffer<uint64_t>& i_bank_addr = 0,
+ const fapi2::buffer<uint64_t>& i_bank_group_addr = 0,
+ const fapi2::buffer<uint64_t>& i_column_addr = 0)
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
// WR's and RD's are very similar, so we just use the RD command boiler plate and modify the command to a WR
- fapi2::buffer<uint64_t> l_boilerplate_arr0 = read_cmd_boilerplate<T>(i_rank,
+ fapi2::buffer<uint64_t> l_boilerplate_arr0 = read_cmd_boilerplate(i_rank,
i_bank_addr,
i_bank_group_addr,
i_column_addr);
@@ -900,12 +702,11 @@ inline instruction_t<T> wr_command( const uint64_t i_rank,
.template clearBit<TT::ARR0_DDR_ADDRESS_15>()
.template clearBit<TT::ARR0_DDR_ADDRESS_14>();
- return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
///
/// @brief Setup read command (Fixed BL8 or BC4) instruction
-/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_bank_addr bank address bits [BA0:BA1] = [62:63] (right aligned)
@@ -916,16 +717,17 @@ inline instruction_t<T> wr_command( const uint64_t i_rank,
/// for the controller (Nimbus v Centaur) and then correct for DRAM generation (not included
/// in this template definition)
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> rd_command( const uint64_t i_rank,
- const fapi2::buffer<uint64_t>& i_bank_addr = 0,
- const fapi2::buffer<uint64_t>& i_bank_group_addr = 0,
- const fapi2::buffer<uint64_t>& i_column_addr = 0)
+inline instruction_t rd_command( const uint64_t i_rank,
+ const fapi2::buffer<uint64_t>& i_bank_addr = 0,
+ const fapi2::buffer<uint64_t>& i_bank_group_addr = 0,
+ const fapi2::buffer<uint64_t>& i_column_addr = 0)
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
fapi2::buffer<uint64_t> l_boilerplate_arr0;
fapi2::buffer<uint64_t> l_boilerplate_arr1;
- l_boilerplate_arr0 = read_cmd_boilerplate<fapi2::TARGET_TYPE_MCBIST>(i_rank,
+ l_boilerplate_arr0 = read_cmd_boilerplate(i_rank,
i_bank_addr,
i_bank_group_addr,
i_column_addr);
@@ -933,12 +735,11 @@ inline instruction_t<T> rd_command( const uint64_t i_rank,
// Setup ADDR10/AP based on read type
l_boilerplate_arr0.clearBit<TT::ARR0_DDR_ADDRESS_10>();
- return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
///
/// @brief Setup read w/auto precharge command (Fixed BL8 or BC4) instruction
-/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_bank_addr bank address bits [BG0:BG1] = [62:63] (right aligned)
@@ -949,16 +750,17 @@ inline instruction_t<T> rd_command( const uint64_t i_rank,
/// for the controller (Nimbus v Centaur) and then correct for DRAM generation (not included
/// in this template definition)
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> rda_command( const uint64_t i_rank,
- const fapi2::buffer<uint64_t>& i_bank_addr = 0,
- const fapi2::buffer<uint64_t>& i_bank_group_addr = 0,
- const fapi2::buffer<uint64_t>& i_column_addr = 0)
+inline instruction_t rda_command( const uint64_t i_rank,
+ const fapi2::buffer<uint64_t>& i_bank_addr = 0,
+ const fapi2::buffer<uint64_t>& i_bank_group_addr = 0,
+ const fapi2::buffer<uint64_t>& i_column_addr = 0)
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
fapi2::buffer<uint64_t> l_boilerplate_arr0;
fapi2::buffer<uint64_t> l_boilerplate_arr1;
- l_boilerplate_arr0 = read_cmd_boilerplate<fapi2::TARGET_TYPE_MCBIST>(i_rank,
+ l_boilerplate_arr0 = read_cmd_boilerplate(i_rank,
i_bank_addr,
i_bank_group_addr,
i_column_addr);
@@ -966,12 +768,11 @@ inline instruction_t<T> rda_command( const uint64_t i_rank,
// Setup ADDR10/AP based on read type
l_boilerplate_arr0.setBit<TT::ARR0_DDR_ADDRESS_10>();
- return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
///
/// @brief Setup precharge all banks command instruction
-/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_idle the idle time to the next command (default to 0)
@@ -980,10 +781,11 @@ inline instruction_t<T> rda_command( const uint64_t i_rank,
/// for the controller (Nimbus v Centaur) and then correct for DRAM generation (not included
/// in this template definition)
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> precharge_all_command( const uint64_t i_rank,
+inline instruction_t precharge_all_command( const uint64_t i_rank,
const uint16_t i_idle = 0 )
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
fapi2::buffer<uint64_t> l_boilerplate_arr0;
fapi2::buffer<uint64_t> l_boilerplate_arr1;
@@ -1007,21 +809,21 @@ inline instruction_t<T> precharge_all_command( const uint64_t i_rank,
// From DDR4 Spec table 17:
// All other bits from the command truth table or 'V', for valid (1 or 0)
- return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
///
/// @brief Setup self-refresh entry command instruction
-/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_idle the idle time to the next command (default to 0)
/// @return the self-refresh entry command CCS instruction
/// @note THIS IS FOR DDR4 NON-LRDIMM ONLY RIGHT NOW
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> self_refresh_entry_command( const uint64_t i_rank, const uint16_t i_idle = 0 )
+inline instruction_t self_refresh_entry_command( const uint64_t i_rank, const uint16_t i_idle = 0 )
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
fapi2::buffer<uint64_t> l_boilerplate_arr0;
fapi2::buffer<uint64_t> l_boilerplate_arr1;
@@ -1042,12 +844,11 @@ inline instruction_t<T> self_refresh_entry_command( const uint64_t i_rank, const
// From DDR4 Spec table 17:
// All other bits from the command truth table are 'V', for valid (1 or 0)
- return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
///
/// @brief Setup self-refresh exit using NOP command instruction
-/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_idle the idle time to the next command (default to 0)
@@ -1055,9 +856,10 @@ inline instruction_t<T> self_refresh_entry_command( const uint64_t i_rank, const
/// @note Using NOP in case SDRAM is in gear down mode and max power saving mode exit
/// @note THIS IS FOR DDR4 NON-LRDIMM ONLY RIGHT NOW
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> self_refresh_exit_command( const uint64_t i_rank, const uint16_t i_idle = 0 )
+inline instruction_t self_refresh_exit_command( const uint64_t i_rank, const uint16_t i_idle = 0 )
{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
fapi2::buffer<uint64_t> l_boilerplate_arr0;
fapi2::buffer<uint64_t> l_boilerplate_arr1;
@@ -1078,7 +880,30 @@ inline instruction_t<T> self_refresh_exit_command( const uint64_t i_rank, const
// From DDR4 Spec table 17:
// All other bits from the command truth table are 'V', for valid (1 or 0)
- return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+}
+
+///
+/// @brief Setup refresh command instruction
+/// @tparam T the target type of the chiplet which executes the CCS instruction
+/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
+/// @param[in] i_target the DIMM this instruction is headed for
+/// @param[in] i_rank the rank on this dimm
+/// @param[in] i_idle the idle time to the next command (default to 0)
+/// @return the self-refresh entry command CCS instruction
+/// @note THIS IS FOR DDR4 NON-LRDIMM ONLY RIGHT NOW
+///
+inline instruction_t refresh_command( const uint64_t i_rank, const uint16_t i_idle = 0 )
+{
+ using TT = ccsTraits<DEFAULT_MC_TYPE>;
+
+ // Refresh is self-refresh entry with CKE high
+ auto l_refresh_template = self_refresh_entry_command(i_rank, i_idle);
+
+ // CKE is high
+ l_refresh_template.arr0.template insertFromRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(CKE_HIGH);
+
+ return l_refresh_template;
}
//
@@ -1088,27 +913,14 @@ inline instruction_t<T> self_refresh_exit_command( const uint64_t i_rank, const
///
/// @brief Select the port(s) to be used by the CCS
+/// @tparam MC the memory controller type which executes the CCS instruction
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] i_target the target to effect
/// @param[in] i_ports the buffer representing the ports
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline fapi2::ReturnCode select_ports( const fapi2::Target<T>& i_target, uint64_t i_ports)
-{
- fapi2::buffer<uint64_t> l_data;
- fapi2::buffer<uint64_t> l_ports;
-
- // Not handling multiple ports here, can't do that for CCS. BRS
- FAPI_TRY( l_ports.setBit(i_ports) );
-
- FAPI_TRY( mss::getScom(i_target, TT::MCB_CNTL_REG, l_data) );
- l_data.insert<TT::MCB_CNTL_PORT_SEL, TT::MCB_CNTL_PORT_SEL_LEN>(l_ports);
- FAPI_TRY( mss::putScom(i_target, TT::MCB_CNTL_REG, l_data) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
+template< mss::mc_type MC, fapi2::TargetType T, typename TT = ccsTraits<MC> >
+fapi2::ReturnCode select_ports( const fapi2::Target<T>& i_target, uint64_t i_ports);
///
/// @brief User sets to a '1'b to tell the Hdw to stop CCS whenever failure occurs. When a
@@ -1119,7 +931,7 @@ fapi_try_exit:
/// @param[in,out] io_buffer the buffer representing the mode register
/// @param[in] i_value true iff stop whenever failure occurs.
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
+template< fapi2::TargetType T, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
inline void stop_on_err( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const states i_value)
{
io_buffer.writeBit<TT::STOP_ON_ERR>(i_value);
@@ -1132,7 +944,7 @@ inline void stop_on_err( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_bu
/// @param[in] the target to effect
/// @param[in,out] io_buffer the buffer representing the mode register
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
+template< fapi2::TargetType T, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
inline void disable_ecc( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer)
{
io_buffer.setBit<TT::DISABLE_ECC_ARRAY_CHK>()
@@ -1148,7 +960,7 @@ inline void disable_ecc( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_bu
/// @param[in,out] io_buffer the buffer representing the mode register
/// @param[in] i_value true iff ignore any array ue or sue errors.
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
+template< fapi2::TargetType T, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
inline void ue_disable( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const states i_value)
{
io_buffer.writeBit<TT::UE_DISABLE>(i_value);
@@ -1162,7 +974,7 @@ inline void ue_disable( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buf
/// @param[in,out] io_buffer the buffer representing the mode register
/// @param[in] i_value mss::ON iff delay parity a cycle
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
+template< fapi2::TargetType T, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
inline void parity_after_cmd( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const states i_value)
{
io_buffer.writeBit<TT::CFG_PARITY_AFTER_CMD>(i_value);
@@ -1177,7 +989,7 @@ inline void parity_after_cmd( const fapi2::Target<T>&, fapi2::buffer<uint64_t>&
/// @param[in] i_count the count to wait for DDR cal to complete.
/// @param[in] i_mult the DDR calibration time multiplaction factor
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
+template< fapi2::TargetType T, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
inline void cal_count( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer,
const uint64_t i_count, const uint64_t i_mult)
{
@@ -1198,7 +1010,7 @@ inline void cal_count( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buff
/// @param[in] i_value mss::ON iff Copy CKE signals to CKE Spare on both ports
/// @note no-op for p9n
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
+template< fapi2::TargetType T, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
void copy_cke_to_spare_cke( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const states i_value);
///
@@ -1209,10 +1021,9 @@ void copy_cke_to_spare_cke( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io
/// @param[in,out] io_buffer the buffer representing the mode register
/// @return FAPI2_RC_SUCCSS iff ok
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
+template< fapi2::TargetType T, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
inline fapi2::ReturnCode read_mode( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& io_buffer)
{
- FAPI_DBG("read mode 0x%llx", TT::MODEQ_REG);
return mss::getScom(i_target, TT::MODEQ_REG, io_buffer);
}
@@ -1224,7 +1035,7 @@ inline fapi2::ReturnCode read_mode( const fapi2::Target<T>& i_target, fapi2::buf
/// @param[in] i_buffer the buffer representing the mode register
/// @return FAPI2_RC_SUCCSS iff ok
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
+template< fapi2::TargetType T, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
inline fapi2::ReturnCode write_mode( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_buffer)
{
return mss::putScom(i_target, TT::MODEQ_REG, i_buffer);
@@ -1238,7 +1049,7 @@ inline fapi2::ReturnCode write_mode( const fapi2::Target<T>& i_target, const fap
/// @param[in] i_nttm_mode NTTM we need to turn on or off (i.e. ON, OFF)
/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS if ok
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
+template< fapi2::TargetType T, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
inline fapi2::ReturnCode configure_nttm( const fapi2::Target<T>& i_target,
const mss::states i_nttm_mode)
{
@@ -1256,39 +1067,56 @@ fapi_try_exit:
///
/// @brief Execute a set of CCS instructions - multiple ports
-/// @tparam T the target type of the chiplet which executes the CCS instruction
-/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
-/// @param[in] i_target the target to effect
+/// @tparam P the port type for this CCS engine
+/// @tparam MC the MC type on which to operate
/// @param[in] i_program the vector of instructions
/// @param[in] i_ports the vector of ports
/// @return FAPI2_RC_SUCCSS iff ok
///
-template< fapi2::TargetType T, fapi2::TargetType P, typename TT = ccsTraits<T> >
-fapi2::ReturnCode execute( const fapi2::Target<T>& i_target,
- ccs::program<T>& i_program,
- const std::vector< fapi2::Target<P> >& i_ports);
+template< fapi2::TargetType P, mss::mc_type MC>
+fapi2::ReturnCode cleanup_from_execute(const ccs::program& i_program,
+ const std::vector< fapi2::Target<P> >& i_ports);
///
-/// @brief Execute a set of CCS instructions - single port
+/// @brief Start or stop the CCS engine
/// @tparam T the target type of the chiplet which executes the CCS instruction
-/// @tparam P the target of the CCS instruction (the port)
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the vector of instructions
-/// @param[in] i_port The target that's being programmed by the array
-/// @return FAPI2_RC_SUCCSS iff ok
+/// @param[in] i_target The MCBIST containing the CCS engine
+/// @param[in] i_start_stop bool MSS_CCS_START for starting MSS_CCS_STOP otherwise
+/// @return FAPI2_RC_SUCCESS iff success
///
-template< fapi2::TargetType T, fapi2::TargetType P, typename TT = ccsTraits<T> >
-fapi2::ReturnCode execute( const fapi2::Target<T>& i_target,
- ccs::program<T>& i_program,
- const fapi2::Target<P>& i_port)
+template< fapi2::TargetType T, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
+fapi2::ReturnCode start_stop( const fapi2::Target<T>& i_target, const bool i_start_stop )
{
- // Mmm. Might want to find a better way to do this - seems expensive. BRS
- std::vector< fapi2::Target<P> > l_ports{ i_port };
- return execute(i_target, i_program, l_ports);
+ fapi2::buffer<uint64_t> l_buf;
+
+ // Do we need to read this? We are setting the only bit defined in the scomdef? BRS
+ FAPI_TRY(mss::getScom(i_target, TT::CNTLQ_REG, l_buf));
+
+ FAPI_TRY( mss::putScom(i_target, TT::CNTLQ_REG,
+ i_start_stop ? l_buf.setBit<TT::CCS_START>() : l_buf.setBit<TT::CCS_STOP>()) );
+
+fapi_try_exit:
+ return fapi2::current_err;
}
///
+/// @brief Determine the CCS failure type
+/// @tparam T the target type of the chiplet which executes the CCS instruction
+/// @tparam P the target of the CCS instruction (the port)
+/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
+/// @param[in] i_target MC target
+/// @param[in] i_type the failure type
+/// @param[in] i_port The port the CCS instruction is training
+/// @return ReturnCode associated with the fail.
+/// @note FFDC is handled here, caller doesn't need to do it
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, fapi2::TargetType P = DEFAULT_MEM_PORT_TARGET, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
+fapi2::ReturnCode fail_type( const fapi2::Target<T>& i_target,
+ const uint64_t i_type,
+ const fapi2::Target<P>& i_port );
+
+///
/// @brief Execute a CCS array already loaded in to the engine
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam P the target of the CCS instruction (the port)
@@ -1298,21 +1126,189 @@ fapi2::ReturnCode execute( const fapi2::Target<T>& i_target,
/// @param[in] i_port the port associated with the MCBIST array
/// @return FAPI2_RC_SUCCSS iff ok
///
-template< fapi2::TargetType T, fapi2::TargetType P, typename TT = ccsTraits<T> >
+template< fapi2::TargetType T, fapi2::TargetType P, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
fapi2::ReturnCode execute_inst_array(const fapi2::Target<T>& i_target,
- ccs::program<T>& i_program,
- const fapi2::Target<P>& i_port);
+ ccs::program& i_program,
+ const fapi2::Target<P>& i_port)
+{
+ fapi2::buffer<uint64_t> status;
+
+ FAPI_TRY(start_stop(i_target, mss::START), "%s Error in execute_inst_array", mss::c_str(i_port) );
+
+ mss::poll(i_target, TT::STATQ_REG, i_program.iv_poll,
+ [&status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
+ {
+ FAPI_DBG("ccs statq 0x%016lx, remaining: %d", stat_reg, poll_remaining);
+ status = stat_reg;
+ return status.getBit<TT::CCS_IN_PROGRESS>() != 1;
+ },
+ i_program.iv_probes);
+
+ // Check for done and success. DONE being the only bit set.
+ if (status == TT::STAT_QUERY_SUCCESS)
+ {
+ FAPI_INF("%s CCS Executed Successfully.", mss::c_str(i_port) );
+ goto fapi_try_exit;
+ }
+
+ // So we failed or we're still in progress. Mask off the fail bits
+ // and run this through the FFDC generator.
+ FAPI_TRY(fail_type(i_target, status & TT::STAT_ERR_MASK, i_port), "Error in execute_inst_array" );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
///
-/// @brief Start or stop the CCS engine
+/// @brief Updates the initial delays based upon the total delays passed in
+/// @tparam fapi2::TargetType T the type of the target running CCS
+/// @tparam MC the memory controller type running CCS
+/// @param[in] i_target the target type on which to operate
+/// @param[in] i_delay the calculated delays from CCS
+/// @param[in,out] io_program the program for which to update the delays
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< fapi2::TargetType T, mss::mc_type MC = DEFAULT_MC_TYPE >
+fapi2::ReturnCode update_initial_delays( const fapi2::Target<T>& i_target,
+ const uint64_t i_delay,
+ ccs::program& io_program);
+
+///
+/// @brief Execute a set of CCS instructions - multiple ports
/// @tparam T the target type of the chiplet which executes the CCS instruction
+/// @tparam P the port type for this CCS engine
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
-/// @param[in] i_target The MCBIST containing the CCS engine
-/// @param[in] i_start_stop bool MSS_CCS_START for starting MSS_CCS_STOP otherwise
-/// @return FAPI2_RC_SUCCESS iff success
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the vector of instructions
+/// @param[in] i_ports the vector of ports
+/// @return FAPI2_RC_SUCCSS iff ok
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-fapi2::ReturnCode start_stop( const fapi2::Target<T>& i_target, const bool i_start_stop );
+template< fapi2::TargetType T, fapi2::TargetType P, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
+fapi2::ReturnCode execute( const fapi2::Target<T>& i_target,
+ ccs::program& i_program,
+ const std::vector< fapi2::Target<P> >& i_ports)
+{
+ // Subtract one for the idle we insert at the end
+ constexpr size_t CCS_INSTRUCTION_DEPTH = TT::CCS_ARRAY_LEN - 1;
+ constexpr uint64_t CCS_ARR0_ZERO = TT::CCS_ARR0_START;
+ constexpr uint64_t CCS_ARR1_ZERO = TT::CCS_ARR1_START;
+
+ ccs::instruction_t l_des = ccs::des_command();
+
+ FAPI_INF("loading ccs instructions (%d) for %s", i_program.iv_instructions.size(), mss::c_str(i_target));
+
+ auto l_inst_iter = i_program.iv_instructions.begin();
+
+ std::vector<rank_configuration> l_rank_configs;
+ FAPI_TRY(get_rank_config(i_target, l_rank_configs));
+
+ // Stop the CCS engine just for giggles - it might be running ...
+ FAPI_TRY( start_stop(i_target, mss::states::STOP), "Error in ccs::execute" );
+
+ FAPI_ASSERT( mss::poll(i_target, TT::STATQ_REG, poll_parameters(),
+ [](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
+ {
+ FAPI_INF("ccs statq (stop) 0x%llx, remaining: %d", stat_reg, poll_remaining);
+ return stat_reg.getBit<TT::CCS_IN_PROGRESS>() != 1;
+ }),
+ TT::setup_trying_to_stop_err(i_target) );
+
+ while (l_inst_iter != i_program.iv_instructions.end())
+ {
+ // Kick off the CCS engine - per port. No broadcast mode for CCS (per Shelton 9/23/15)
+ for (const auto& p : i_ports)
+ {
+ const auto l_port_index = mss::relative_pos<T>(p);
+ size_t l_inst_count = 0;
+
+ uint64_t l_total_delay = 0;
+ uint64_t l_delay = 0;
+ uint64_t l_repeat = 0;
+ uint8_t l_current_cke = 0;
+
+ // Shove the instructions into the CCS engine, in 32 instruction chunks, and execute them
+ for (; l_inst_iter != i_program.iv_instructions.end()
+ && l_inst_count < CCS_INSTRUCTION_DEPTH; ++l_inst_count, ++l_inst_iter)
+ {
+ // First, update the current instruction's chip selects for the current port
+ FAPI_TRY(l_inst_iter->configure_rank(p, l_rank_configs[l_port_index]), "Error in rank config");
+
+ l_inst_iter->arr0.extractToRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(l_current_cke);
+
+ // Make sure this instruction leads to the next. Notice this limits this mechanism to pretty
+ // simple (straight line) CCS programs. Anything with a loop or such will need another mechanism.
+ l_inst_iter->arr1.insertFromRight<TT::ARR1_GOTO_CMD, TT::ARR1_GOTO_CMD_LEN>(l_inst_count + 1);
+ FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_inst_iter->arr0), "Error in ccs::execute" );
+ FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_inst_iter->arr1), "Error in ccs::execute" );
+
+ // arr1 contains a specification of the delay and repeat after this instruction, as well
+ // as a repeat. Total up the delays as we go so we know how long to wait before polling
+ // the CCS engine for completion
+ l_inst_iter->arr1.extractToRight<TT::ARR1_IDLES, TT::ARR1_IDLES_LEN>(l_delay);
+ l_inst_iter->arr1.extractToRight<TT::ARR1_REPEAT_CMD_CNT, TT::ARR1_REPEAT_CMD_CNT_LEN>(l_repeat);
+
+ l_total_delay += l_delay * (l_repeat + 1);
+
+ FAPI_INF("css inst %d: 0x%016lX 0x%016lX (0x%lx, 0x%lx) delay: 0x%x (0x%x) %s",
+ l_inst_count, l_inst_iter->arr0, l_inst_iter->arr1,
+ CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count,
+ l_delay, l_total_delay, mss::c_str(i_target));
+ }
+
+ // Updates the initial delays
+ FAPI_TRY(update_initial_delays(i_target, l_total_delay, i_program), "Error in ccs::execute");
+
+ FAPI_INF("executing ccs instructions (%d:%d, %d) for %s",
+ i_program.iv_instructions.size(), l_inst_count, i_program.iv_poll.iv_initial_delay, mss::c_str(i_target));
+
+ // Deselect
+ l_des.arr0.insertFromRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(l_current_cke);
+
+ // Insert a DES as our last instruction. DES is idle state anyway and having this
+ // here as an instruction forces the CCS engine to wait the delay specified in
+ // the last instruction in this array (which it otherwise doesn't do.)
+ l_des.arr1.setBit<TT::ARR1_END>();
+ FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_des.arr0), "Error in ccs::execute" );
+ FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_des.arr1), "Error in ccs::execute" );
+
+ FAPI_INF("css inst %d fixup: 0x%016lX 0x%016lX (0x%lx, 0x%lx) %s",
+ l_inst_count, l_des.arr0, l_des.arr1,
+ CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count, mss::c_str(i_target));
+
+
+ FAPI_INF("executing CCS array for port %d (%s)", l_port_index, mss::c_str(p));
+ FAPI_TRY( select_ports<DEFAULT_MC_TYPE>( i_target, l_port_index), "Error in ccs execute" );
+ FAPI_TRY( execute_inst_array(i_target, i_program, p), "Error in ccs execute" );
+ }
+ }
+
+ // Cleans up after executing the CCS program (runs workarounds if needed)
+ FAPI_TRY((cleanup_from_execute<P, DEFAULT_MC_TYPE>(i_program, i_ports)));
+
+fapi_try_exit:
+ i_program.iv_instructions.clear();
+ return fapi2::current_err;
+}
+
+///
+/// @brief Execute a set of CCS instructions - single port
+/// @tparam T the target type of the chiplet which executes the CCS instruction
+/// @tparam P the target of the CCS instruction (the port)
+/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the vector of instructions
+/// @param[in] i_port The target that's being programmed by the array
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< fapi2::TargetType T, fapi2::TargetType P, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
+fapi2::ReturnCode execute( const fapi2::Target<T>& i_target,
+ ccs::program& i_program,
+ const fapi2::Target<P>& i_port)
+{
+ // Mmm. Might want to find a better way to do this - seems expensive. BRS
+ std::vector< fapi2::Target<P> > l_ports{ i_port };
+ return execute(i_target, i_program, l_ports);
+}
///
/// @brief Query the status of the CCS engine
@@ -1322,22 +1318,10 @@ fapi2::ReturnCode start_stop( const fapi2::Target<T>& i_target, const bool i_sta
/// @param[out] io_status The query result first being the result, second the type
/// @return FAPI2_RC_SUCCESS iff success
///
-template< fapi2::TargetType T, typename TT = ccsTraits<T> >
+template< fapi2::TargetType T, typename TT = ccsTraits<DEFAULT_MC_TYPE> >
fapi2::ReturnCode status_query( const fapi2::Target<T>& i_target, std::pair<uint64_t, uint64_t>& io_status );
-///
-/// @brief Determine the CCS failure type
-/// @param[in] i_target MCBIST target
-/// @param[in] i_type the failure type
-/// @param[in] i_mca The port the CCS instruction is training
-/// @return ReturnCode associated with the fail.
-/// @note FFDC is handled here, caller doesn't need to do it
-///
-fapi2::ReturnCode fail_type( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- const uint64_t& i_type,
- const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_mca );
-
} // ends namespace ccs
-}
+} // ends namespace mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/dump_regs.H b/src/import/generic/memory/lib/ccs/ccs_traits.H
index 1154694e9..5bfcbd064 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/dump_regs.H
+++ b/src/import/generic/memory/lib/ccs/ccs_traits.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/utils/dump_regs.H $ */
+/* $Source: src/import/generic/memory/lib/ccs/ccs_traits.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -24,31 +24,27 @@
/* IBM_PROLOG_END_TAG */
///
-/// @file dump_regs.H
-/// @brief Dump registers
+/// @file ccs_traits.H
+/// @brief Run and manage the CCS engine
///
-// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: HB:FSP
-#ifndef _MSS_DUMP_REGS_H_
-#define _MSS_DUMP_REGS_H_
+#ifndef _MSS_CCS_TRAITS_H_
+#define _MSS_CCS_TRAITS_H_
#include <fapi2.H>
-
-namespace mss
-{
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
///
-/// @brief Dump the registers of a target
-/// @tparam T, the fapi2::TargetType
-/// @param[in] i_target the target in question
-/// @return fapi2::FAPI2_RC_SUCCESS if ok
+/// @class ccsTraits
+/// @brief CCS Engine traits and addresses
+/// @tparam MC The memory controller type of the traits
///
-template< fapi2::TargetType T >
-fapi2::ReturnCode dump_regs( const fapi2::Target<T>& i_target );
+template< mss::mc_type MC >
+class ccsTraits;
-}
#endif
diff --git a/src/import/generic/memory/lib/data_engine/attr_engine_traits.H b/src/import/generic/memory/lib/data_engine/attr_engine_traits.H
index 1d7388f65..ebcd02c8c 100644
--- a/src/import/generic/memory/lib/data_engine/attr_engine_traits.H
+++ b/src/import/generic/memory/lib/data_engine/attr_engine_traits.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,24 +37,449 @@
#define _MSS_ATTR_ENGINE_TRAITS_H_
#include <fapi2.H>
+#include <generic/memory/lib/spd/spd_facade.H>
#include <generic/memory/lib/data_engine/data_engine_traits_def.H>
+#include <generic/memory/lib/data_engine/data_engine.H>
#include <generic/memory/lib/data_engine/data_engine_utils.H>
#include <generic/memory/lib/mss_generic_attribute_getters.H>
#include <generic/memory/lib/mss_generic_attribute_setters.H>
+#include <generic/memory/lib/mss_generic_system_attribute_getters.H>
#include <generic/memory/lib/spd/ddimm/efd_decoder.H>
-#include <generic/memory/lib/spd/spd_facade.H>
-#include <generic/memory/lib/utils/buffer_ops.H>
+#include <generic/memory/lib/utils/dimm/mss_timing.H>
+#include <generic/memory/lib/spd/spd_utils.H>
namespace mss
{
///
+/// @brief Forward declartion of traits for setTimingTraits
+/// @class setTimingTraits
+/// @note attr_eff_engine_fields, DRAM_TCCD_L
+///
+template< >
+struct setTimingTraits< attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TCCD_L >
+{
+ static constexpr const char* TIMING_NAME = "TCCD_L";
+
+ static constexpr spd_facade_fptr get_timing_in_mtb = &spd::facade::min_tccd_l;
+ static constexpr spd_facade_fptr get_timing_in_ftb = &spd::facade::fine_offset_min_tccd_l;
+};
+
+///
+/// @brief Forward declartion of traits for setTimingTraits
+/// @class setTimingTraits
+/// @note attr_eff_engine_fields, DRAM_TWTR_L
+///
+template< >
+struct setTimingTraits< attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TWTR_L >
+{
+ static constexpr const char* TIMING_NAME = "tWTR_L";
+
+ static constexpr spd_facade_fptr get_timing_in_mtb = &spd::facade::min_twtr_l;
+ static constexpr spd_facade_fptr get_timing_in_ftb = &spd::facade::fine_offset_min_twtr_l;
+};
+
+///
+/// @brief Forward declartion of traits for setTimingTraits
+/// @class setTimingTraits
+/// @note attr_eff_engine_fields, DRAM_TWTR_S
+///
+template< >
+struct setTimingTraits< attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TWTR_S >
+{
+ static constexpr const char* TIMING_NAME = "tWTR_S";
+
+ static constexpr spd_facade_fptr get_timing_in_mtb = &spd::facade::min_twtr_s;
+ static constexpr spd_facade_fptr get_timing_in_ftb = &spd::facade::fine_offset_min_twtr_s;
+};
+
+///
+/// @brief Forward declartion of traits for setTimingTraits
+/// @class setTimingTraits
+/// @note attr_eff_engine_fields, DRAM_TFAW
+///
+template< >
+struct setTimingTraits< attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TFAW >
+{
+ static constexpr const char* TIMING_NAME = "tFAW";
+
+ static constexpr spd_facade_fptr get_timing_in_mtb = &spd::facade::min_tfaw;
+ static constexpr spd_facade_fptr get_timing_in_ftb = &spd::facade::fine_offset_min_tfaw;
+};
+
+///
+/// @brief Forward declartion of traits for setTimingTraits
+/// @class setTimingTraits
+/// @note attr_eff_engine_fields, DRAM_TRCD
+///
+template< >
+struct setTimingTraits< attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TRCD >
+{
+ static constexpr const char* TIMING_NAME = "trcd";
+
+ static constexpr spd_facade_fptr get_timing_in_mtb = &spd::facade::min_trcd;
+ static constexpr spd_facade_fptr get_timing_in_ftb = &spd::facade::fine_offset_min_trcd;
+};
+
+///
+/// @brief Forward declartion of traits for setTimingTraits
+/// @class setTimingTraits
+/// @note attr_eff_engine_fields, DRAM_TRP
+///
+template< >
+struct setTimingTraits< attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TRP >
+{
+ static constexpr const char* TIMING_NAME = "tRP";
+
+ static constexpr spd_facade_fptr get_timing_in_mtb = &spd::facade::min_trp;
+ static constexpr spd_facade_fptr get_timing_in_ftb = &spd::facade::fine_offset_min_trp;
+};
+
+///
+/// @brief Forward declartion of traits for setTimingTraits
+/// @class setTimingTraits
+/// @note attr_eff_engine_fields, DRAM_TRAS
+///
+template< >
+struct setTimingTraits< attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TRAS >
+{
+ static constexpr const char* TIMING_NAME = "tRAS";
+
+ static constexpr spd_facade_fptr get_timing_in_mtb = &spd::facade::min_tras;
+ static constexpr spd_facade_fptr get_timing_in_ftb = &spd::facade::fine_offset_min_tras;
+};
+
+///
+/// @brief Forward declartion of traits for setTimingTraits
+/// @class setTimingTraits
+/// @note attr_eff_engine_fields, DRAM_TWR
+///
+template< >
+struct setTimingTraits< attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TWR >
+{
+ static constexpr const char* TIMING_NAME = "tWR";
+
+ static constexpr spd_facade_fptr get_timing_in_mtb = &spd::facade::min_twr;
+ static constexpr spd_facade_fptr get_timing_in_ftb = &spd::facade::fine_offset_min_twr;
+};
+
+///
+/// @brief Forward declartion of traits for setTimingTraits
+/// @class setTimingTraits
+/// @note attr_eff_engine_fields, DRAM_TRRD_S
+///
+template< >
+struct setTimingTraits< attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TRRD_S >
+{
+ static constexpr const char* TIMING_NAME = "tRRD_S";
+
+ static constexpr spd_facade_fptr get_timing_in_mtb = &spd::facade::min_trrd_s;
+ static constexpr spd_facade_fptr get_timing_in_ftb = &spd::facade::fine_offset_min_trrd_s;
+};
+
+///
+/// @brief Forward declartion of traits for setTimingTraits
+/// @class setTimingTraits
+/// @note attr_eff_engine_fields, DRAM_TRRD_L
+///
+template< >
+struct setTimingTraits< attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TRRD_L >
+{
+ static constexpr const char* TIMING_NAME = "tRRD_L";
+
+ static constexpr spd_facade_fptr get_timing_in_mtb = &spd::facade::min_trrd_l;
+ static constexpr spd_facade_fptr get_timing_in_ftb = &spd::facade::fine_offset_min_trrd_l;
+};
+
+///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attr_eff_engine_fields, PRIM_STACK_TYPE specialization
+///
+template< proc_type P >
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::PRIM_STACK_TYPE>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PRIM_STACK_TYPE_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PRIM_STACK_TYPE_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_PRIM_STACK_TYPE;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_prim_stack_type(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_prim_stack_type(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_efd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.prim_sdram_signal_loading(o_setting);
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attr_eff_engine_fields, PRIM_DIE_COUNT specialization
+///
+template< proc_type P >
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::PRIMARY_DIE_COUNT>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PRIM_DIE_COUNT_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PRIM_DIE_COUNT_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_PRIM_DIE_COUNT;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_prim_die_count(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_prim_die_count(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_efd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ // =========================================================
+ // Byte 6 maps
+ // Item JC-45-2220.01x
+ // Page 19
+ // DDR4 SPD Document Release 3
+ // Byte 6 (0x006): Primary SDRAM Package Type
+ // =========================================================
+ static const std::vector<std::pair<uint8_t, uint8_t> > PRIM_DIE_COUNT_MAP =
+ {
+ // {key byte, number of die}
+ {0, fapi2::ENUM_ATTR_MEM_EFF_PRIM_DIE_COUNT_D1},
+ {1, fapi2::ENUM_ATTR_MEM_EFF_PRIM_DIE_COUNT_D2},
+ {2, fapi2::ENUM_ATTR_MEM_EFF_PRIM_DIE_COUNT_D3},
+ {3, fapi2::ENUM_ATTR_MEM_EFF_PRIM_DIE_COUNT_D4},
+ {4, fapi2::ENUM_ATTR_MEM_EFF_PRIM_DIE_COUNT_D5},
+ {5, fapi2::ENUM_ATTR_MEM_EFF_PRIM_DIE_COUNT_D6},
+ {6, fapi2::ENUM_ATTR_MEM_EFF_PRIM_DIE_COUNT_D7},
+ {7, fapi2::ENUM_ATTR_MEM_EFF_PRIM_DIE_COUNT_D8}
+ };
+
+ const auto l_dimm = i_spd_data.get_dimm_target();
+
+ attr_integral_type l_decoder_val = 0;
+ FAPI_TRY( i_spd_data.prim_sdram_die_count(l_decoder_val) );
+
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(l_dimm, PRIM_DIE_COUNT_MAP, FFDC_CODE, l_decoder_val, o_setting));
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for pre_data_engine
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attr_eff_engine_fields, DRAM_DENSITY specialization
+///
+template< proc_type P >
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_DENSITY>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_DENSITY_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_DENSITY_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_DENSITY;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_density(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_density(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[in] i_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ // =========================================================
+ // DDR4 SPD Document Release 4
+ // Byte 2 (0x002): Key Byte / DRAM Device Type
+ // =========================================================
+ static const std::vector< std::pair<uint8_t, uint8_t> > DRAM_DENSITY_MAP =
+ {
+ // {key byte, capacity in GBs}
+ {4, fapi2::ENUM_ATTR_MEM_EFF_DRAM_DENSITY_4G},
+ {5, fapi2::ENUM_ATTR_MEM_EFF_DRAM_DENSITY_8G},
+ {6, fapi2::ENUM_ATTR_MEM_EFF_DRAM_DENSITY_16G},
+ };
+
+ const auto l_dimm = i_spd_data.get_dimm_target();
+
+ attr_integral_type l_sdram_density = 0;
+ FAPI_TRY( i_spd_data.sdram_density(l_sdram_density),
+ "%s failed to get device type from SPD", spd::c_str(l_dimm) );
+
+ FAPI_TRY( lookup_table_check(l_dimm, DRAM_DENSITY_MAP, FFDC_CODE, l_sdram_density, o_setting),
+ "%s failed DRAM_DENSITY lookup check", spd::c_str(l_dimm) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attr_engine_derived_fields, BUS_WIDTH specialization
+///
+template< proc_type P >
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::PRIM_BUS_WIDTH>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_PRIM_BUS_WIDTH_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_PRIM_BUS_WIDTH_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_PRIM_BUS_WIDTH;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_prim_bus_width(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_prim_bus_width(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_efd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+
+ static inline fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ // =========================================================
+ // Byte 13 maps
+ // Item JC-45-2220.01x
+ // Page 27
+ // DDR4 SPD Document Release 3
+ // Byte 13 (0x00D): Module Memory Bus Width
+ // =========================================================
+ const std::vector<std::pair<uint8_t, uint8_t> > BUS_WIDTH_MAP =
+ {
+ // {key byte, bus width (in bits)
+ {0, fapi2::ENUM_ATTR_MEM_EFF_PRIM_BUS_WIDTH_8_BITS},
+ {1, fapi2::ENUM_ATTR_MEM_EFF_PRIM_BUS_WIDTH_16_BITS},
+ {2, fapi2::ENUM_ATTR_MEM_EFF_PRIM_BUS_WIDTH_32_BITS},
+ {3, fapi2::ENUM_ATTR_MEM_EFF_PRIM_BUS_WIDTH_64_BITS}
+ // All others reserved
+ };
+
+ const auto l_dimm = i_spd_data.get_dimm_target();
+
+ attr_integral_type l_spd_bus_width = 0;
+ FAPI_TRY( i_spd_data.prim_bus_width(l_spd_bus_width) );
+
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(l_dimm, BUS_WIDTH_MAP, FFDC_CODE, l_spd_bus_width, o_setting));
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_eff_engine_fields, DRAM_WIDTH specialization
///
-template<>
-struct attrEngineTraits<attr_eff_engine_fields, DRAM_WIDTH>
+template< proc_type P >
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_WIDTH>
{
using attr_type = fapi2::ATTR_MEM_EFF_DRAM_WIDTH_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -67,8 +492,8 @@ struct attrEngineTraits<attr_eff_engine_fields, DRAM_WIDTH>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_dram_width(i_target, o_setting);
}
@@ -79,8 +504,8 @@ struct attrEngineTraits<attr_eff_engine_fields, DRAM_WIDTH>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_dram_width(i_target, i_setting);
}
@@ -88,13 +513,12 @@ struct attrEngineTraits<attr_eff_engine_fields, DRAM_WIDTH>
///
/// @brief Computes setting for attribute
/// @param[in] i_efd_data EFD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
attr_integral_type& o_setting)
{
-
// =========================================================
// Byte 12 maps
// Item JC-45-2220.01x
@@ -113,11 +537,147 @@ struct attrEngineTraits<attr_eff_engine_fields, DRAM_WIDTH>
};
// Read SPD value
+ const auto l_dimm = i_spd_data.get_dimm_target();
+
attr_integral_type l_value = 0;
FAPI_TRY( i_spd_data.device_width(l_value) );
// Map SPD value to desired setting
- FAPI_TRY(lookup_table_check(i_spd_data.get_dimm_target(), DRAM_WIDTH_MAP, SET_DRAM_WIDTH, l_value, o_setting));
+ FAPI_TRY(lookup_table_check(l_dimm, DRAM_WIDTH_MAP, SET_DRAM_WIDTH, l_value, o_setting));
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attr_si_engine_fields, COLUMN_ADDR_BITS specialization
+///
+template< proc_type P >
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::COLUMN_ADDR_BITS>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_COLUMN_BITS_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_COLUMN_BITS_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_COL_ADDR_BITS;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_column_bits(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_column_bits(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_efd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ static const std::vector< std::pair<uint8_t, uint8_t> > DRAM_ADDR_COL_MAP =
+ {
+ {0b001, fapi2::ENUM_ATTR_MEM_EFF_DRAM_COLUMN_BITS_NUM10},
+ };
+
+ const auto l_dimm = i_spd_data.get_dimm_target();
+
+ attr_integral_type l_value = 0;
+ FAPI_TRY(i_spd_data.column_address_bits(l_value))
+
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(l_dimm, DRAM_ADDR_COL_MAP, SET_COL_ADDR_BITS, l_value, o_setting));
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attr_si_engine_fields, ROW_ADDR_BITS specialization
+///
+template< proc_type P >
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::ROW_ADDR_BITS>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_ROW_BITS_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_ROW_BITS_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_ROW_ADDR_BITS;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_row_bits(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_row_bits(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_efd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ static const std::vector< std::pair<uint8_t, uint8_t> > DRAM_ADDR_ROW_MAP =
+ {
+ {0b010, fapi2::ENUM_ATTR_MEM_EFF_DRAM_ROW_BITS_NUM14},
+ {0b011, fapi2::ENUM_ATTR_MEM_EFF_DRAM_ROW_BITS_NUM15},
+ {0b100, fapi2::ENUM_ATTR_MEM_EFF_DRAM_ROW_BITS_NUM16},
+ {0b101, fapi2::ENUM_ATTR_MEM_EFF_DRAM_ROW_BITS_NUM17},
+ {0b110, fapi2::ENUM_ATTR_MEM_EFF_DRAM_ROW_BITS_NUM18},
+ };
+
+ const auto l_dimm = i_spd_data.get_dimm_target();
+
+ attr_integral_type l_value = 0;
+ FAPI_TRY(i_spd_data.row_address_bits(l_value))
+
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(l_dimm, DRAM_ADDR_ROW_MAP, SET_ROW_ADDR_BITS, l_value, o_setting));
fapi_try_exit:
return fapi2::current_err;
@@ -130,19 +690,21 @@ struct attrEngineTraits<attr_eff_engine_fields, DRAM_WIDTH>
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, ATTR_SI_BASE_CASE specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, ATTR_SI_BASE_CASE> {};
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::ATTR_SI_BASE_CASE> {};
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_MC_RCV_IMP_DQ_DQS specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_MC_RCV_IMP_DQ_DQS>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_MC_RCV_IMP_DQ_DQS>
{
using attr_type = fapi2::ATTR_MEM_SI_MC_RCV_IMP_DQ_DQS_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -155,8 +717,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_RCV_IMP_DQ_DQS>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_mc_rcv_imp_dq_dqs(i_target, o_setting);
}
@@ -167,8 +729,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_RCV_IMP_DQ_DQS>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_mc_rcv_imp_dq_dqs(i_target, i_setting);
}
@@ -176,23 +738,45 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_RCV_IMP_DQ_DQS>
///
/// @brief Computes setting for attribute
/// @param[in] i_efd_data EFD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
- return i_efd_data->phy_odt_impedance(o_setting);
+ uint8_t l_odt_impedance = 0;
+
+ static const std::vector< std::pair<uint8_t, uint8_t> > ODT_IMP_MAP =
+ {
+ // {key byte, PHY ODT IMP (ohms)}
+ {0b00000, fapi2::ENUM_ATTR_MEM_SI_MC_RCV_IMP_DQ_DQS_DISABLE},
+ {0b00001, fapi2::ENUM_ATTR_MEM_SI_MC_RCV_IMP_DQ_DQS_OHM_40},
+ {0b00010, fapi2::ENUM_ATTR_MEM_SI_MC_RCV_IMP_DQ_DQS_OHM_60},
+ {0b00011, fapi2::ENUM_ATTR_MEM_SI_MC_RCV_IMP_DQ_DQS_OHM_80},
+ {0b00100, fapi2::ENUM_ATTR_MEM_SI_MC_RCV_IMP_DQ_DQS_OHM_120},
+ {0b00101, fapi2::ENUM_ATTR_MEM_SI_MC_RCV_IMP_DQ_DQS_OHM_240},
+
+ // All others reserved
+ };
+ const auto l_ocmb = i_efd_data->get_ocmb_target();
+
+ FAPI_TRY(i_efd_data->phy_odt_impedance(l_odt_impedance));
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(l_ocmb, ODT_IMP_MAP, mss::SET_SI_MC_RCV_IMP_DQ_DQS, l_odt_impedance, o_setting));
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_MC_DRV_IMP_DQ_DQS_PULL_UP specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_DQ_DQS_PULL_UP>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_MC_DRV_IMP_DQ_DQS_PULL_UP>
{
using attr_type = fapi2::ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -205,8 +789,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_DQ_DQS_PULL_UP>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_mc_drv_imp_dq_dqs_pull_up(i_target, o_setting);
}
@@ -217,8 +801,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_DQ_DQS_PULL_UP>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_mc_drv_imp_dq_dqs_pull_up(i_target, i_setting);
}
@@ -226,23 +810,58 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_DQ_DQS_PULL_UP>
///
/// @brief Computes setting for attribute
/// @param[in] i_efd_data EFD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
- return i_efd_data->phy_drive_impedance_pull_up(o_setting);
+ uint8_t l_phy_drv_imp_pu;
+
+ static const std::vector< std::pair<uint16_t, uint16_t> > PHY_DRV_IMP_PU_MAP =
+ {
+ // {key byte, DRV IMP PU (ohms)}
+ {0b000000, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_DISABLE},
+ {0b000001, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_28},
+ {0b000010, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_30},
+ {0b000011, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_32},
+ {0b000100, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_34},
+ {0b000101, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_36},
+ {0b000110, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_40},
+ {0b000111, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_43},
+ {0b001000, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_48},
+ {0b001001, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_53},
+ {0b001010, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_60},
+ {0b001011, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_68},
+ {0b001100, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_80},
+ {0b001101, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_96},
+ {0b001110, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_120},
+ {0b001111, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_160},
+ {0b010000, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_240},
+ {0b010001, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP_OHM_480},
+
+ // All others reserved
+ };
+ const auto l_ocmb = i_efd_data->get_ocmb_target();
+
+ FAPI_TRY(i_efd_data->phy_drive_impedance_pull_up(l_phy_drv_imp_pu));
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(l_ocmb, PHY_DRV_IMP_PU_MAP, mss::SET_SI_MC_DRV_IMP_DQ_DQS_PULL_UP,
+ static_cast<uint16_t>(l_phy_drv_imp_pu), o_setting));
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN>
{
using attr_type = fapi2::ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -255,8 +874,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_mc_drv_imp_dq_dqs_pull_down(i_target, o_setting);
}
@@ -267,8 +886,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_mc_drv_imp_dq_dqs_pull_down(i_target, i_setting);
}
@@ -276,24 +895,59 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN>
///
/// @brief Computes setting for attribute
/// @param[in] i_efd_data EFD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
- return i_efd_data->phy_drive_impedance_pull_down(o_setting);
+ uint8_t l_phy_drv_imp_pd = 0;
+
+ static const std::vector< std::pair<uint16_t, uint16_t> > PHY_DRV_IMP_PD_MAP =
+ {
+ // {key byte, DRV IMP PD (ohms)}
+ {0b000000, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_DISABLE},
+ {0b000001, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_28},
+ {0b000010, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_30},
+ {0b000011, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_32},
+ {0b000100, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_34},
+ {0b000101, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_36},
+ {0b000110, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_40},
+ {0b000111, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_43},
+ {0b001000, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_48},
+ {0b001001, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_53},
+ {0b001010, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_60},
+ {0b001011, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_68},
+ {0b001100, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_80},
+ {0b001101, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_96},
+ {0b001110, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_120},
+ {0b001111, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_160},
+ {0b010000, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_240},
+ {0b010001, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN_OHM_480},
+
+ // All others reserved
+ };
+ const auto l_ocmb = i_efd_data->get_ocmb_target();
+
+ FAPI_TRY(i_efd_data->phy_drive_impedance_pull_down(l_phy_drv_imp_pd));
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(l_ocmb, PHY_DRV_IMP_PD_MAP, mss::SET_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN,
+ static_cast<uint16_t>(l_phy_drv_imp_pd), o_setting));
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_DQ_DQS specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_DQ_DQS>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_MC_DRV_SLEW_RATE_DQ_DQS>
{
using attr_type = fapi2::ATTR_MEM_SI_MC_DRV_SLEW_RATE_DQ_DQS_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -306,8 +960,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_DQ_DQS>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_mc_drv_slew_rate_dq_dqs(i_target, o_setting);
}
@@ -318,8 +972,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_DQ_DQS>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_mc_drv_slew_rate_dq_dqs(i_target, i_setting);
}
@@ -327,10 +981,10 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_DQ_DQS>
///
/// @brief Computes setting for attribute
/// @param[in] i_efd_data EFD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
return i_efd_data->phy_slew_rate_dq_dqs(o_setting);
@@ -339,11 +993,12 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_DQ_DQS>
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_MC_DRV_IMP_CMD_ADDR specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_CMD_ADDR>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_MC_DRV_IMP_CMD_ADDR>
{
using attr_type = fapi2::ATTR_MEM_SI_MC_DRV_IMP_CMD_ADDR_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -356,8 +1011,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_CMD_ADDR>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_mc_drv_imp_cmd_addr(i_target, o_setting);
}
@@ -368,8 +1023,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_CMD_ADDR>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_mc_drv_imp_cmd_addr(i_target, i_setting);
}
@@ -377,23 +1032,46 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_CMD_ADDR>
///
/// @brief Computes setting for attribute
/// @param[in] i_efd_data EFD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
- return i_efd_data->atx_impedance(o_setting);
+ uint8_t l_atx_impedance = 0;
+
+ static const std::vector< std::pair<uint8_t, uint8_t> > ATX_IMP_MAP =
+ {
+ // {key byte, ATX IMP (ohm)}
+ {0b0000, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_CMD_ADDR_DISABLE},
+ {0b0001, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_CMD_ADDR_OHM_20},
+ {0b0010, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_CMD_ADDR_OHM_24},
+ {0b0011, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_CMD_ADDR_OHM_30},
+ {0b0100, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_CMD_ADDR_OHM_40},
+ {0b0101, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_CMD_ADDR_OHM_60},
+ {0b0110, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_CMD_ADDR_OHM_120},
+
+ // All others reserved
+ };
+ const auto l_ocmb = i_efd_data->get_ocmb_target();
+
+ FAPI_TRY(i_efd_data->atx_impedance(l_atx_impedance));
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(l_ocmb, ATX_IMP_MAP, mss::SET_SI_MC_DRV_IMP_CMD_ADDR, l_atx_impedance, o_setting));
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_CMD_ADDR specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_CMD_ADDR>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_MC_DRV_SLEW_RATE_CMD_ADDR>
{
using attr_type = fapi2::ATTR_MEM_SI_MC_DRV_SLEW_RATE_CMD_ADDR_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -406,8 +1084,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_CMD_ADDR>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_mc_drv_slew_rate_cmd_addr(i_target, o_setting);
}
@@ -418,8 +1096,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_CMD_ADDR>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_mc_drv_slew_rate_cmd_addr(i_target, i_setting);
}
@@ -427,10 +1105,10 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_CMD_ADDR>
///
/// @brief Computes setting for attribute
/// @param[in] i_efd_data EFD data
- /// @param[in] i_setting value we want to set attr with
+ /// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
return i_efd_data->atx_slew_rate(o_setting);
@@ -439,11 +1117,12 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_CMD_ADDR>
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_MC_DRV_IMP_CLK specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_CLK>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_MC_DRV_IMP_CLK>
{
using attr_type = fapi2::ATTR_MEM_SI_MC_DRV_IMP_CLK_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -456,8 +1135,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_CLK>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_mc_drv_imp_clk(i_target, o_setting);
}
@@ -468,8 +1147,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_CLK>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_mc_drv_imp_clk(i_target, i_setting);
}
@@ -480,20 +1159,43 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_IMP_CLK>
/// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
- return i_efd_data->ck_impedance(o_setting);
+ uint8_t l_ck_impedance = 0;
+
+ static const std::vector< std::pair<uint8_t, uint8_t> > CK_IMP_MAP =
+ {
+ // {key byte, CK IMP (ohm)}
+ {0b0000, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_CLK_DISABLE},
+ {0b0001, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_CLK_OHM_20},
+ {0b0010, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_CLK_OHM_24},
+ {0b0011, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_CLK_OHM_30},
+ {0b0100, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_CLK_OHM_40},
+ {0b0101, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_CLK_OHM_60},
+ {0b0110, fapi2::ENUM_ATTR_MEM_SI_MC_DRV_IMP_CLK_OHM_120},
+
+ // All others reserved
+ };
+ const auto l_ocmb = i_efd_data->get_ocmb_target();
+
+ FAPI_TRY(i_efd_data->ck_impedance(l_ck_impedance));
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(l_ocmb, CK_IMP_MAP, mss::SET_SI_MC_DRV_IMP_CLK, l_ck_impedance, o_setting));
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_CLK specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_CLK>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_MC_DRV_SLEW_RATE_CLK>
{
using attr_type = fapi2::ATTR_MEM_SI_MC_DRV_SLEW_RATE_CLK_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -506,8 +1208,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_CLK>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_mc_drv_slew_rate_clk(i_target, o_setting);
}
@@ -518,8 +1220,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_CLK>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_mc_drv_slew_rate_clk(i_target, i_setting);
}
@@ -530,7 +1232,7 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_CLK>
/// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
return i_efd_data->ck_slew_rate(o_setting);
@@ -539,11 +1241,12 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_SLEW_RATE_CLK>
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_MC_RCV_IMP_ALERT_N specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_MC_RCV_IMP_ALERT_N>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_MC_RCV_IMP_ALERT_N>
{
using attr_type = fapi2::ATTR_MEM_SI_MC_RCV_IMP_ALERT_N_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -556,8 +1259,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_RCV_IMP_ALERT_N>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_mc_rcv_imp_alert_n(i_target, o_setting);
}
@@ -568,8 +1271,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_RCV_IMP_ALERT_N>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_mc_rcv_imp_alert_n(i_target, i_setting);
}
@@ -580,20 +1283,43 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_RCV_IMP_ALERT_N>
/// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
- return i_efd_data->alert_odt_impedance(o_setting);
+ uint8_t l_alert_odt_imp = 0;
+
+ static const std::vector< std::pair<uint8_t, uint8_t> > ALERT_ODT_IMP_MAP =
+ {
+ // {key byte, ALERT ODT IMP (ohms)}
+ {0b0000, fapi2::ENUM_ATTR_MEM_SI_MC_RCV_IMP_ALERT_N_DISABLE},
+ {0b0001, fapi2::ENUM_ATTR_MEM_SI_MC_RCV_IMP_ALERT_N_OHM_40},
+ {0b0010, fapi2::ENUM_ATTR_MEM_SI_MC_RCV_IMP_ALERT_N_OHM_48},
+ {0b0011, fapi2::ENUM_ATTR_MEM_SI_MC_RCV_IMP_ALERT_N_OHM_60},
+ {0b0100, fapi2::ENUM_ATTR_MEM_SI_MC_RCV_IMP_ALERT_N_OHM_80},
+ {0b0101, fapi2::ENUM_ATTR_MEM_SI_MC_RCV_IMP_ALERT_N_OHM_120},
+ {0b0110, fapi2::ENUM_ATTR_MEM_SI_MC_RCV_IMP_ALERT_N_OHM_240},
+
+ // All others reserved
+ };
+ const auto l_ocmb = i_efd_data->get_ocmb_target();
+
+ FAPI_TRY(i_efd_data->alert_odt_impedance(l_alert_odt_imp));
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(l_ocmb, ALERT_ODT_IMP_MAP, mss::SET_SI_MC_RCV_IMP_ALERT_N, l_alert_odt_imp, o_setting));
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_DRAM_RTT_NOM specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_RTT_NOM>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_DRAM_RTT_NOM>
{
using attr_type = fapi2::ATTR_MEM_SI_DRAM_RTT_NOM_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -606,8 +1332,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_RTT_NOM>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_dram_rtt_nom(i_target, o_setting);
}
@@ -618,8 +1344,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_RTT_NOM>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_dram_rtt_nom(i_target, i_setting);
}
@@ -630,20 +1356,70 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_RTT_NOM>
/// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
- return i_efd_data->dram_rtt_nom(o_setting);
+ uint8_t l_rtt_nom = 0;
+
+ static const std::vector< std::pair<uint8_t, uint8_t> > RTT_NOM_MAP =
+ {
+ {0b0000, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_NOM_DISABLE},
+ {0b0001, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_NOM_OHM34},
+ {0b0010, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_NOM_OHM40},
+ {0b0011, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_NOM_OHM60},
+ {0b0100, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_NOM_OHM80},
+ {0b0101, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_NOM_OHM120},
+ {0b0110, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_NOM_OHM240},
+ // All others reserved
+ };
+ const auto l_ocmb = i_efd_data->get_ocmb_target();
+
+ switch(i_efd_data->get_rank())
+ {
+ case 0:
+ FAPI_TRY( i_efd_data->dram_rtt_nom_rank0(l_rtt_nom) );
+ break;
+
+ case 1:
+ FAPI_TRY( i_efd_data->dram_rtt_nom_rank1(l_rtt_nom) );
+ break;
+
+ case 2:
+ FAPI_TRY( i_efd_data->dram_rtt_nom_rank2(l_rtt_nom) );
+ break;
+
+ case 3:
+ FAPI_TRY( i_efd_data->dram_rtt_nom_rank3(l_rtt_nom) );
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_SPD_RANK().
+ set_FUNCTION(SET_SI_DRAM_RTT_NOM).
+ set_RANK( i_efd_data->get_rank() ).
+ set_TARGET(l_ocmb),
+ "%s SPD decoder returned invalid rank: %d",
+ spd::c_str(l_ocmb),
+ i_efd_data->get_rank());
+ break;
+ };
+
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(l_ocmb, RTT_NOM_MAP, mss::SET_SI_DRAM_RTT_NOM, l_rtt_nom, o_setting));
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_DRAM_RTT_WR specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_RTT_WR>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_DRAM_RTT_WR>
{
using attr_type = fapi2::ATTR_MEM_SI_DRAM_RTT_WR_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -656,8 +1432,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_RTT_WR>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_dram_rtt_wr(i_target, o_setting);
}
@@ -668,8 +1444,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_RTT_WR>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_dram_rtt_wr(i_target, i_setting);
}
@@ -680,20 +1456,67 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_RTT_WR>
/// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
- return i_efd_data->dram_rtt_wr(o_setting);
+ uint8_t l_rtt_wr = 0;
+
+ static const std::vector< std::pair<uint8_t, uint8_t> > RTT_WR_MAP =
+ {
+ {0b0000, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_WR_DISABLE},
+ {0b0001, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_WR_OHM80},
+ {0b0010, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_WR_OHM120},
+ {0b0011, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_WR_OHM240},
+ // All others reserved
+ };
+ const auto l_ocmb = i_efd_data->get_ocmb_target();
+
+ switch(i_efd_data->get_rank())
+ {
+ case 0:
+ FAPI_TRY( i_efd_data->dram_rtt_wr_rank0(l_rtt_wr) );
+ break;
+
+ case 1:
+ FAPI_TRY( i_efd_data->dram_rtt_wr_rank1(l_rtt_wr) );
+ break;
+
+ case 2:
+ FAPI_TRY( i_efd_data->dram_rtt_wr_rank2(l_rtt_wr) );
+ break;
+
+ case 3:
+ FAPI_TRY( i_efd_data->dram_rtt_wr_rank3(l_rtt_wr) );
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_SPD_RANK().
+ set_FUNCTION(SET_SI_DRAM_RTT_WR).
+ set_RANK( i_efd_data->get_rank() ).
+ set_TARGET(l_ocmb),
+ "%s SPD decoder returned invalid rank: %d",
+ spd::c_str(l_ocmb),
+ i_efd_data->get_rank());
+ break;
+ };
+
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(l_ocmb, RTT_WR_MAP, mss::SET_SI_DRAM_RTT_WR, l_rtt_wr, o_setting));
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_DRAM_RTT_PARK specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_RTT_PARK>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_DRAM_RTT_PARK>
{
using attr_type = fapi2::ATTR_MEM_SI_DRAM_RTT_PARK_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -706,8 +1529,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_RTT_PARK>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_dram_rtt_park(i_target, o_setting);
}
@@ -718,8 +1541,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_RTT_PARK>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_dram_rtt_park(i_target, i_setting);
}
@@ -730,20 +1553,72 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_RTT_PARK>
/// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
- return i_efd_data->dram_rtt_park(o_setting);
+ uint8_t l_rtt_park = 0;
+
+ static const std::vector< std::pair<uint8_t, uint8_t> > RTT_PARK_MAP =
+ {
+ // {key byte, RTT PARK (ohms)}
+ {0b0000, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_PARK_DISABLE},
+ {0b0001, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_PARK_OHM34},
+ {0b0010, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_PARK_OHM40},
+ {0b0011, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_PARK_OHM48},
+ {0b0100, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_PARK_OHM60},
+ {0b0101, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_PARK_OHM80},
+ {0b0110, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_PARK_OHM120},
+ {0b0111, fapi2::ENUM_ATTR_MEM_SI_DRAM_RTT_PARK_OHM240},
+ // All others reserved
+ };
+ const auto l_ocmb = i_efd_data->get_ocmb_target();
+
+ switch(i_efd_data->get_rank())
+ {
+ case 0:
+ FAPI_TRY( i_efd_data->dram_rtt_park_rank0(l_rtt_park) );
+ break;
+
+ case 1:
+ FAPI_TRY( i_efd_data->dram_rtt_park_rank1(l_rtt_park) );
+ break;
+
+ case 2:
+ FAPI_TRY( i_efd_data->dram_rtt_park_rank2(l_rtt_park) );
+ break;
+
+ case 3:
+ FAPI_TRY( i_efd_data->dram_rtt_park_rank3(l_rtt_park) );
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_SPD_RANK().
+ set_FUNCTION(SET_SI_DRAM_RTT_PARK).
+ set_RANK( i_efd_data->get_rank() ).
+ set_TARGET(l_ocmb),
+ "%s SPD decoder returned invalid rank: %d",
+ spd::c_str(l_ocmb),
+ i_efd_data->get_rank());
+ break;
+ };
+
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(l_ocmb, RTT_PARK_MAP, mss::SET_SI_DRAM_RTT_PARK, l_rtt_park, o_setting));
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_DRAM_PREAMBLE specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_PREAMBLE>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_DRAM_PREAMBLE>
{
using attr_type = fapi2::ATTR_MEM_SI_DRAM_PREAMBLE_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -756,8 +1631,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_PREAMBLE>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_dram_preamble(i_target, o_setting);
}
@@ -768,8 +1643,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_PREAMBLE>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_dram_preamble(i_target, i_setting);
}
@@ -780,7 +1655,7 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_PREAMBLE>
/// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
i_efd_data->write_preamble(o_setting);
@@ -790,11 +1665,12 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_PREAMBLE>
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_MC_DRV_EQ_DQ_DQS specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_EQ_DQ_DQS>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_MC_DRV_EQ_DQ_DQS>
{
using attr_type = fapi2::ATTR_MEM_SI_MC_DRV_EQ_DQ_DQS_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -807,8 +1683,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_EQ_DQ_DQS>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_mc_drv_eq_dq_dqs(i_target, o_setting);
}
@@ -819,8 +1695,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_EQ_DQ_DQS>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_mc_drv_eq_dq_dqs(i_target, i_setting);
}
@@ -831,7 +1707,7 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_EQ_DQ_DQS>
/// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
return i_efd_data->phy_equalization(o_setting);
@@ -840,11 +1716,12 @@ struct attrEngineTraits<attr_si_engine_fields, SI_MC_DRV_EQ_DQ_DQS>
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
/// @note attr_si_engine_fields, SI_DRAM_DRV_IMP_DQ_DQS specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_DRV_IMP_DQ_DQS>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_DRAM_DRV_IMP_DQ_DQS>
{
using attr_type = fapi2::ATTR_MEM_SI_DRAM_DRV_IMP_DQ_DQS_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
@@ -857,8 +1734,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_DRV_IMP_DQ_DQS>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
return mss::attr::get_si_dram_drv_imp_dq_dqs(i_target, o_setting);
}
@@ -869,8 +1746,8 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_DRV_IMP_DQ_DQS>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
return mss::attr::set_si_dram_drv_imp_dq_dqs(i_target, i_setting);
}
@@ -881,25 +1758,134 @@ struct attrEngineTraits<attr_si_engine_fields, SI_DRAM_DRV_IMP_DQ_DQS>
/// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ attr_integral_type& o_setting)
+ {
+ static const std::vector< std::pair<uint8_t, uint8_t> > DRAM_DIC_MAP =
+ {
+ // {key byte, DRAM DIC (ohms)}
+ {0, fapi2::ENUM_ATTR_MEM_SI_DRAM_DRV_IMP_DQ_DQS_DISABLE},
+ {1, fapi2::ENUM_ATTR_MEM_SI_DRAM_DRV_IMP_DQ_DQS_OHM34},
+ {2, fapi2::ENUM_ATTR_MEM_SI_DRAM_DRV_IMP_DQ_DQS_OHM48},
+ };
+
+ const auto l_ocmb = i_efd_data->get_ocmb_target();
+
+ attr_integral_type l_dram_dic = 0;
+ FAPI_TRY(i_efd_data->dram_dic(l_dram_dic))
+
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(l_ocmb, DRAM_DIC_MAP, SET_SI_DRAM_DRV_IMP_DQ_DQS, l_dram_dic, o_setting));
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attr_si_engine_fields, SI_ODT_WR specialization
+///
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_ODT_WR>
+{
+ using attr_type = fapi2::ATTR_MEM_SI_ODT_WR_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_SI_ODT_WR_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_SI_ODT_WR;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_si_odt_wr(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_si_odt_wr(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_efd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
- return i_efd_data->dram_dic(o_setting);
+ uint8_t l_value = 0;
+
+ const auto l_ocmb = i_efd_data->get_ocmb_target();
+
+ switch(i_efd_data->get_rank())
+ {
+ case 0:
+ FAPI_TRY( i_efd_data->odt_wr_map_rank0(l_value) );
+ break;
+
+ case 1:
+ FAPI_TRY( i_efd_data->odt_wr_map_rank1(l_value) );
+ break;
+
+ case 2:
+ FAPI_TRY( i_efd_data->odt_wr_map_rank2(l_value) );
+ break;
+
+ case 3:
+ FAPI_TRY( i_efd_data->odt_wr_map_rank3(l_value) );
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_SPD_RANK().
+ set_FUNCTION(SET_SI_ODT_WR).
+ set_RANK( i_efd_data->get_rank() ).
+ set_TARGET(l_ocmb),
+ "%s SPD decoder returned invalid rank: %d",
+ spd::c_str(l_ocmb),
+ i_efd_data->get_rank());
+ break;
+ };
+
+ // Map to attribute bitmap
+ l_value = mss::gen::align_odt_field_to_attr(l_value);
+
+ o_setting = l_value;
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
-/// @note attr_si_engine_fields, SI_VREF_DQ_TRAIN_RANGE specialization
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attr_si_engine_fields, SI_ODT_RD specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_VREF_DQ_TRAIN_RANGE>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_ODT_RD>
{
- using attr_type = fapi2::ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE_Type;
+ using attr_type = fapi2::ATTR_MEM_SI_ODT_RD_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
- static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE_TargetType;
- static constexpr generic_ffdc_codes FFDC_CODE = SET_SI_VREF_DQ_TRAIN_RANGE;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_SI_ODT_RD_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_SI_ODT_RD;
///
/// @brief attribute getter
@@ -907,10 +1893,10 @@ struct attrEngineTraits<attr_si_engine_fields, SI_VREF_DQ_TRAIN_RANGE>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& o_setting)
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
{
- return mss::attr::get_si_vref_dq_train_range(i_target, o_setting);
+ return mss::attr::get_si_odt_rd(i_target, o_setting);
}
///
@@ -919,10 +1905,10 @@ struct attrEngineTraits<attr_si_engine_fields, SI_VREF_DQ_TRAIN_RANGE>
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
- attr_type& i_setting)
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
{
- return mss::attr::set_si_vref_dq_train_range(i_target, i_setting);
+ return mss::attr::set_si_odt_rd(i_target, i_setting);
}
///
@@ -934,22 +1920,63 @@ struct attrEngineTraits<attr_si_engine_fields, SI_VREF_DQ_TRAIN_RANGE>
static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
attr_integral_type& o_setting)
{
- return i_efd_data->wr_vref_dq_range(o_setting);
+ uint8_t l_value = 0;
+
+ const auto l_ocmb = i_efd_data->get_ocmb_target();
+
+ switch(i_efd_data->get_rank())
+ {
+ case 0:
+ FAPI_TRY( i_efd_data->odt_rd_map_rank0(l_value) );
+ break;
+
+ case 1:
+ FAPI_TRY( i_efd_data->odt_rd_map_rank1(l_value) );
+ break;
+
+ case 2:
+ FAPI_TRY( i_efd_data->odt_rd_map_rank2(l_value) );
+ break;
+
+ case 3:
+ FAPI_TRY( i_efd_data->odt_rd_map_rank3(l_value) );
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_SPD_RANK().
+ set_FUNCTION(SET_SI_ODT_RD).
+ set_RANK( i_efd_data->get_rank() ).
+ set_TARGET(l_ocmb),
+ "%s SPD decoder returned invalid rank: %d",
+ spd::c_str(l_ocmb),
+ i_efd_data->get_rank());
+ break;
+ };
+
+ // Map to attribute bitmap
+ l_value = mss::gen::align_odt_field_to_attr(l_value);
+
+ o_setting = l_value;
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
///
/// @brief Traits for attr_engine
-/// @class attrEngineTraits
-/// @note attr_si_engine_fields, SI_VREF_DQ_TRAIN_VALUE specialization
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attr_si_engine_fields, SI_GEARDOWN_MODE specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_VREF_DQ_TRAIN_VALUE>
+template< proc_type P >
+struct attrEngineTraits<P, attr_si_engine_fields, attr_si_engine_fields::SI_GEARDOWN_MODE>
{
- using attr_type = fapi2::ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE_Type;
+ using attr_type = fapi2::ATTR_MEM_SI_GEARDOWN_MODE_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
- static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE_TargetType;
- static constexpr generic_ffdc_codes FFDC_CODE = SET_SI_VREF_DQ_TRAIN_VALUE;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_SI_GEARDOWN_MODE_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_SI_GEARDOWN_MODE;
///
/// @brief attribute getter
@@ -957,49 +1984,364 @@ struct attrEngineTraits<attr_si_engine_fields, SI_VREF_DQ_TRAIN_VALUE>
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_si_geardown_mode(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_si_geardown_mode(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_efd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_efd_data->geardown_during_training(o_setting);
+ }
+};
+
+//
+// Derived attributes
+//
+///
+
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, MRANKS specialization
+///
+template< proc_type P >
+struct attrEngineTraits<P, attr_engine_derived_fields, attr_engine_derived_fields::LOGICAL_RANKS>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_LOGICAL_RANKS;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& o_setting)
{
- return mss::attr::get_si_vref_dq_train_value(i_target, o_setting);
+ return mss::attr::get_logical_ranks_per_dimm(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_logical_ranks_per_dimm(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ attr_integral_type& o_setting)
+ {
+ uint8_t l_prim_stack_type = 0;
+ uint8_t l_master_ranks = 0;
+ uint8_t l_die_count = 0;
+
+ FAPI_TRY( mss::attr::get_num_master_ranks_per_dimm(i_target, l_master_ranks) );
+ FAPI_TRY( mss::attr::get_prim_die_count(i_target, l_die_count) );
+ FAPI_TRY( mss::attr::get_prim_stack_type(i_target, l_prim_stack_type) );
+
+ {
+ // For single-load-stack(3DS) the logical ranks per package ends up being the same as the die count.
+ // For MONOLITHIC & MULTI_LOAD_STACK
+ // The die count isn't guaranteed to be 1 (e.g. SDP - 1 die package, DDP - 2 die package).
+ // Value of 1 has no meaning and is used for calculation purposes as defined by the SPD spec.
+ const auto l_multiplier = (l_prim_stack_type == fapi2::ENUM_ATTR_MEM_EFF_PRIM_STACK_TYPE_3DS) ? l_die_count : 1;
+ o_setting = (l_master_ranks * l_multiplier);
+ FAPI_DBG("%s Num Logical Ranks %d", spd::c_str(i_target), o_setting);
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attr_engine_derived_fields, MEM_DIMM_SIZE specialization
+///
+template< proc_type P >
+struct attrEngineTraits<P, attr_engine_derived_fields, attr_engine_derived_fields::MEM_DIMM_SIZE>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DIMM_SIZE_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DIMM_SIZE_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DIMM_SIZE;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dimm_size(i_target, o_setting);
}
///
/// @brief attribute setter
/// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dimm_size(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_efd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+
+ static inline fapi2::ReturnCode get_value_to_set(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ attr_integral_type& o_setting)
+ {
+ uint8_t l_dram_width = 0;
+ uint8_t l_dram_density = 0;
+ uint8_t l_logical_rank_per_dimm = 0;
+ uint8_t l_bus_width = 0;
+
+ FAPI_TRY( mss::attr::get_dram_width(i_target, l_dram_width) );
+ FAPI_TRY( mss::attr::get_dram_density(i_target, l_dram_density) );
+ FAPI_TRY( mss::attr::get_logical_ranks_per_dimm(i_target, l_logical_rank_per_dimm) );
+ FAPI_TRY( mss::attr::get_prim_bus_width(i_target, l_bus_width) );
+
+ // Calculate dimm size
+ // Formula from SPD Spec (seriously, they don't have parenthesis in the spec)
+ // Total = SDRAM Capacity / 8 * Primary Bus Width / SDRAM Width * Logical Ranks per DIMM
+ o_setting = (l_dram_density * l_bus_width * l_logical_rank_per_dimm) / (8 * l_dram_width);
+
+ FAPI_DBG("%s DIMM size = %d => (%d * %d * %d) / (8 * %d)",
+ spd::c_str(i_target), o_setting, l_dram_density, l_bus_width, l_logical_rank_per_dimm, l_dram_width);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attr_engine_derived_fields, HEIGHT_3DS specialization
+///
+template< proc_type P >
+struct attrEngineTraits<P, attr_engine_derived_fields, attr_engine_derived_fields::HEIGHT_3DS>
+{
+ using attr_type = fapi2::ATTR_MEM_3DS_HEIGHT_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_3DS_HEIGHT_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_3DS_HEIGHT;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_3ds_height(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_3ds_height(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ attr_integral_type& o_setting)
+ {
+ uint8_t l_master_ranks_per_dimm = 0;
+ uint8_t l_logical_ranks_per_dimm = 0;
+
+ FAPI_TRY(mss::attr::get_num_master_ranks_per_dimm(i_target, l_master_ranks_per_dimm));
+ FAPI_TRY(mss::attr::get_logical_ranks_per_dimm(i_target, l_logical_ranks_per_dimm));
+ {
+ const uint16_t l_result = l_logical_ranks_per_dimm / l_master_ranks_per_dimm;
+
+ static const std::vector< std::pair<uint16_t, uint16_t> > HEIGHT_3DS_MAP =
+ {
+ // {key byte, 3DS HEIGHT}
+ {1, fapi2::ENUM_ATTR_MEM_3DS_HEIGHT_PLANAR},
+ {2, fapi2::ENUM_ATTR_MEM_3DS_HEIGHT_H2},
+ {4, fapi2::ENUM_ATTR_MEM_3DS_HEIGHT_H4},
+ {8, fapi2::ENUM_ATTR_MEM_3DS_HEIGHT_H8},
+ // All others reserved
+ };
+
+ // Map SPD value to desired setting
+ FAPI_TRY(lookup_table_check(i_target, HEIGHT_3DS_MAP, mss::SET_3DS_HEIGHT, l_result, o_setting));
+ }
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_CWL specialization
+///
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_CWL>
+{
+ using attr_type = fapi2::ATTR_MEM_DRAM_CWL_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_DRAM_CWL_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_CWL;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& o_setting)
{
- return mss::attr::set_si_vref_dq_train_value(i_target, o_setting);
+ return mss::attr::get_dram_cwl(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the fapi2 target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_cwl(i_target, i_setting);
}
///
/// @brief Computes setting for attribute
- /// @param[in] i_efd_data EFD data
+ /// @param[in] i_spd_data SPD data
/// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
attr_integral_type& o_setting)
{
- return i_efd_data->wr_vref_dq_value(o_setting);
+ // Taken from DDR4 JEDEC spec 1716.78C
+ // Proposed DDR4 Full spec update(79-4A)
+ // Page 26, Table 7
+ static const std::vector<std::pair<uint64_t, uint8_t> > CWL_TABLE_1 =
+ {
+ {1866, 10},
+ {2133, 11},
+ {2400, 12},
+ {2666, 14},
+ {2933, 16},
+ {3200, 16},
+ };
+
+ static const std::vector<std::pair<uint64_t, uint8_t> > CWL_TABLE_2 =
+ {
+ // Note that 2tCK write preamble is not valid for 1866 or 2133 speed grades
+ {2400, 14},
+ {2666, 16},
+ {2933, 18},
+ {3200, 18},
+ };
+
+ const auto& l_dimm = i_spd_data.get_dimm_target();
+ // TK This could change but not sure where to get this from
+ constexpr size_t MAX_RANKS_PER_DIMM = 4;
+ uint64_t l_freq = 0;
+ uint8_t l_preambles[MAX_RANKS_PER_DIMM] = {0};
+ fapi2::buffer<uint8_t> l_preamble;
+
+ FAPI_TRY( mss::attr::get_freq(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(l_dimm), l_freq) );
+ FAPI_TRY( mss::attr::get_si_dram_preamble(l_dimm, l_preambles) );
+
+ // TK Using the preamble for rank0 for now
+ l_preamble = l_preambles[0];
+
+ if (!l_preamble.getBit<fapi2::ENUM_ATTR_MEM_SI_DRAM_PREAMBLE_WRITE_PREAMBLE_BIT>())
+ {
+ FAPI_TRY(lookup_table_check(l_dimm, CWL_TABLE_1, FFDC_CODE, l_freq, o_setting));
+ }
+ else
+ {
+ FAPI_TRY(lookup_table_check(l_dimm, CWL_TABLE_2, FFDC_CODE, l_freq, o_setting));
+ }
+
+ FAPI_DBG("%s DRAM CWL %d", spd::c_str(l_dimm), o_setting);
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
///
/// @brief Traits for attr_engine
/// @class attrEngineTraits
-/// @note attr_si_engine_fields, SI_ODT_WR specialization
+/// @note attr_engine_derived_fields, DRAM_MFG_ID specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_ODT_WR>
+template < proc_type P >
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_MFG_ID>
{
- using attr_type = fapi2::ATTR_MEM_SI_ODT_WR_Type;
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_MFG_ID_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
- static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_SI_ODT_WR_TargetType;
- static constexpr generic_ffdc_codes FFDC_CODE = SET_SI_ODT_WR;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_MFG_ID_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_MFG_ID;
///
/// @brief attribute getter
@@ -1010,19 +2352,19 @@ struct attrEngineTraits<attr_si_engine_fields, SI_ODT_WR>
static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& o_setting)
{
- return mss::attr::get_si_odt_wr(i_target, o_setting);
+ return mss::attr::get_dram_mfg_id(i_target, o_setting);
}
///
/// @brief attribute setter
- /// @param[in] i_target the fapi2 target
+ /// @param[in] i_target the attr target
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& i_setting)
{
- return mss::attr::set_si_odt_wr(i_target, i_setting);
+ return mss::attr::set_dram_mfg_id(i_target, i_setting);
}
///
@@ -1031,41 +2373,149 @@ struct attrEngineTraits<attr_si_engine_fields, SI_ODT_WR>
/// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
attr_integral_type& o_setting)
{
- fapi2::buffer<uint8_t> l_buffer;
- uint8_t l_value = 0;
+ fapi2::buffer<attr_integral_type> l_temp;
+ FAPI_TRY(i_spd_data.dram_manufacturer_id_code(l_temp));
+ fapi2::endian_swap(l_temp);
+ o_setting = l_temp;
- switch(i_efd_data->get_rank())
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_TREFI specialization
+///
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TREFI>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_TREFI_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_TREFI_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_TREFI;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_trefi(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_trefi(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ const auto& l_dimm = i_spd_data.get_dimm_target();
+ uint8_t l_refresh_mode = 0;
+ uint8_t l_refresh_rate = 0;
+ uint64_t l_trefi_in_ps = 0;
+ int64_t l_tck_in_ps = 0;
+ uint64_t l_freq = 0;
+
+ FAPI_TRY( attr::get_freq(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(l_dimm), l_freq) );
+ FAPI_TRY( freq_to_ps(l_freq, l_tck_in_ps),
+ "%s Failed to calculate clock period (tCK)", spd::c_str(l_dimm) );
+
+ FAPI_TRY( mss::attr::get_mrw_fine_refresh_mode(l_refresh_mode) );
+ FAPI_TRY( mss::attr::get_mrw_refresh_rate_request(l_refresh_rate) );
+
+ switch(l_refresh_mode)
{
- case 0:
- FAPI_TRY( i_efd_data->odt_wr_map_rank0(l_value) );
- break;
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_NORMAL:
- case 1:
- FAPI_TRY( i_efd_data->odt_wr_map_rank1(l_value) );
+ FAPI_TRY( calc_trefi( mss::refresh_rate::REF1X,
+ l_refresh_rate,
+ l_trefi_in_ps),
+ "%s Failed to calculate tREF1", spd::c_str(l_dimm) );
break;
- case 2:
- FAPI_TRY( i_efd_data->odt_wr_map_rank2(l_value) );
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_2X:
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_2X:
+
+ FAPI_TRY( calc_trefi( mss::refresh_rate::REF2X,
+ l_refresh_rate,
+ l_trefi_in_ps),
+ "%s Failed to calculate tREF2", spd::c_str(l_dimm) );
break;
- case 3:
- FAPI_TRY( i_efd_data->odt_wr_map_rank3(l_value) );
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_4X:
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_4X:
+
+ FAPI_TRY( calc_trefi( mss::refresh_rate::REF4X,
+ l_refresh_rate,
+ l_trefi_in_ps),
+ "%s Failed to calculate tREF4", spd::c_str(l_dimm) );
break;
default:
- // TODO Add FFDC
- fapi2::Assert(false);
+ // Fine Refresh Mode will be a platform attribute set by the MRW,
+ // which they "shouldn't" mess up as long as use "attribute" enums.
+ // if openpower messes this up we can at least catch it
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_FINE_REFRESH_MODE().
+ set_FINE_REF_MODE(l_refresh_mode),
+ "%s Incorrect Fine Refresh Mode received: %d ",
+ spd::c_str(l_dimm),
+ l_refresh_mode);
break;
};
- // TK update to handle differentiating 2 DIMMs, defaulted to DIMM0 case for explorer
{
- // Map to attribute bitmap
- reverse(l_value);
- o_setting = l_value;
+ // Calculate refresh cycle time in nCK & set attribute
+ constexpr double PERCENT_ADJUST = 0.99;
+
+ // Calculate nck
+ uint64_t l_trefi_in_nck = 0;
+ FAPI_TRY( spd::calc_nck( l_trefi_in_ps,
+ static_cast<uint64_t>(l_tck_in_ps),
+ spd::INVERSE_DDR4_CORRECTION_FACTOR,
+ l_trefi_in_nck),
+ "%s Error in calculating tREFI, with value of l_trefi_in_ps: %d", spd::c_str(l_dimm), l_trefi_in_ps);
+
+ // Lab requested 99% of tREFI calculation to avoid any latency impact and violation of any
+ // refresh specification (across all number of ranks and frequencies) observed
+ // during lab power/thermal tests.
+
+ FAPI_INF("%s adjusting tREFI calculation by 99%, calculated tREFI (nck): %lu, adjusted tREFI (nck): %lu,",
+ spd::c_str(l_dimm), l_trefi_in_nck, l_trefi_in_nck * PERCENT_ADJUST);
+
+ // The compiler does this under the covers but just to be explicit on intent:
+ // Floating point arithmetic and truncation of result saved to an unsigned integer
+ l_trefi_in_nck = static_cast<double>(l_trefi_in_nck * PERCENT_ADJUST);
+
+ FAPI_INF("%s tCK (ps): %d, tREFI (ps): %d, tREFI (nck): %d",
+ spd::c_str(l_dimm), l_tck_in_ps, l_trefi_in_ps, l_trefi_in_nck);
+
+ o_setting = l_trefi_in_nck;
+ FAPI_DBG("%s DRAM TREFI %d", spd::c_str(l_dimm), o_setting);
}
fapi_try_exit:
@@ -1074,82 +2524,760 @@ struct attrEngineTraits<attr_si_engine_fields, SI_ODT_WR>
};
///
-/// @brief Traits for attr_engine
-/// @class attrEngineTraits
-/// @note attr_si_engine_fields, SI_ODT_RD specialization
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_TCCD_L specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_ODT_RD>
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TCCD_L>
{
- using attr_type = fapi2::ATTR_MEM_SI_ODT_RD_Type;
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_TCCD_L_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
- static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_SI_ODT_RD_TargetType;
- static constexpr generic_ffdc_codes FFDC_CODE = SET_SI_ODT_RD;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_TCCD_L_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_TCCD_L;
///
/// @brief attribute getter
- /// @param[in] i_target the fapi2 target
+ /// @param[in] i_target the attr target
/// @param[out] o_setting array to populate
/// @return FAPI2_RC_SUCCESS iff okay
///
static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& o_setting)
{
- return mss::attr::get_si_odt_rd(i_target, o_setting);
+ return mss::attr::get_dram_tccd_l(i_target, o_setting);
}
///
/// @brief attribute setter
- /// @param[in] i_target the fapi2 target
+ /// @param[in] i_target the attr target
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& i_setting)
{
- return mss::attr::set_si_odt_rd(i_target, i_setting);
+ return mss::attr::set_dram_tccd_l(i_target, i_setting);
}
///
/// @brief Computes setting for attribute
- /// @param[in] i_efd_data EFD data
+ /// @param[in] i_spd_data SPD data
/// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
attr_integral_type& o_setting)
{
- uint8_t l_value = 0;
+ return mss::calc_spd_time_in_nck<attr_eff_engine_fields,
+ attr_eff_engine_fields::DRAM_TCCD_L>(i_spd_data, o_setting);
+ }
+};
- switch(i_efd_data->get_rank())
- {
- case 0:
- FAPI_TRY( i_efd_data->odt_rd_map_rank0(l_value) );
- break;
+///
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_TWTR_L specialization
+///
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TWTR_L>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_TWTR_L_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_TWTR_L_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_TWTR_L;
- case 1:
- FAPI_TRY( i_efd_data->odt_rd_map_rank1(l_value) );
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_twtr_l(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_twtr_l(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return mss::calc_spd_time_in_nck<attr_eff_engine_fields,
+ attr_eff_engine_fields::DRAM_TWTR_L>(i_spd_data, o_setting);
+ }
+};
+
+///
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_TWTR_S specialization
+///
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TWTR_S>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_TWTR_S_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_TWTR_S_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_TWTR_S;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_twtr_s(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_twtr_s(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return mss::calc_spd_time_in_nck<attr_eff_engine_fields,
+ attr_eff_engine_fields::DRAM_TWTR_S>(i_spd_data, o_setting);
+ }
+};
+
+///
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_TFAW specialization
+///
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TFAW>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_TFAW_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_TFAW_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_TFAW;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_tfaw(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_tfaw(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return mss::calc_spd_time_in_nck<attr_eff_engine_fields,
+ attr_eff_engine_fields::DRAM_TFAW>(i_spd_data, o_setting);
+ }
+};
+
+///
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_TRCD specialization
+///
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TRCD>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_TRCD_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_TRCD_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_TRCD;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_trcd(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_trcd(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return mss::calc_spd_time_in_nck<attr_eff_engine_fields,
+ attr_eff_engine_fields::DRAM_TRCD>(i_spd_data, o_setting);
+ }
+};
+
+///
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_TRP specialization
+///
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TRP>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_TRP_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_TRP_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_TRP;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_trp(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_trp(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return mss::calc_spd_time_in_nck<attr_eff_engine_fields,
+ attr_eff_engine_fields::DRAM_TRP>(i_spd_data, o_setting);
+ }
+};
+
+///
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_TRAS specialization
+///
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TRAS>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_TRAS_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_TRAS_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_TRAS;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_tras(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_tras(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return mss::calc_spd_time_in_nck<attr_eff_engine_fields,
+ attr_eff_engine_fields::DRAM_TRAS>(i_spd_data, o_setting);
+ }
+};
+
+///
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_TWR specialization
+///
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TWR>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_TWR_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_TWR_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_TWR;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_twr(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_twr(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return mss::calc_spd_time_in_nck<attr_eff_engine_fields,
+ attr_eff_engine_fields::DRAM_TWR>(i_spd_data, o_setting);
+ }
+};
+
+///
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_TRTP specialization
+///
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TRTP>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_TRTP_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_TRTP_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_TRTP;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_trtp(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_trtp(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ const auto& l_dimm = i_spd_data.get_dimm_target();
+ int64_t l_tck_in_ps = 0;
+ uint64_t l_freq = 0;
+
+ // Values from proposed DDR4 Full spec update(79-4A)
+ // Item No. 1716.78C
+ // Page 241 & 246
+ constexpr int64_t l_max_trtp_in_ps = trtp();
+ uint8_t l_calc_trtp_in_nck = 0;
+
+ FAPI_TRY( attr::get_freq(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(l_dimm), l_freq) );
+ FAPI_TRY( freq_to_ps(l_freq, l_tck_in_ps),
+ "%s Failed to calculate clock period (tCK)", spd::c_str(l_dimm) );
+
+ // Calculate nck
+ FAPI_TRY( spd::calc_nck(l_max_trtp_in_ps, l_tck_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_calc_trtp_in_nck),
+ "%s Error in calculating trtp, with value of l_twtr_in_ps: %d",
+ spd::c_str(l_dimm), l_max_trtp_in_ps);
+
+ FAPI_INF("%s tCK (ps): %d, tRTP (ps): %d, tRTP (nck): %d",
+ spd::c_str(l_dimm), l_tck_in_ps, l_max_trtp_in_ps, l_calc_trtp_in_nck);
+
+ o_setting = l_calc_trtp_in_nck;
+ FAPI_DBG("%s DRAM TRTP %d", spd::c_str(l_dimm), o_setting);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_TRRD_S specialization
+///
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TRRD_S>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_TRRD_S_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_TRRD_S_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_TRRD_S;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_trrd_s(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_trrd_s(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ const auto& l_dimm = i_spd_data.get_dimm_target();
+
+ // Taking the worst case required minimum JEDEC value
+ // instead of calculating proposed value from SPD -- which selects optimistic values
+ // leading to errors in expected timing values
+ uint64_t l_trrd_s_in_nck = 0;
+ uint64_t l_freq = 0;
+ uint8_t l_dram_width = 0;
+ FAPI_TRY( attr::get_dram_width(l_dimm, l_dram_width) );
+ FAPI_TRY( attr::get_freq(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(l_dimm), l_freq) );
+ FAPI_TRY( trrd_s( l_dimm, l_dram_width, l_freq, l_trrd_s_in_nck) );
+
+ FAPI_INF("%s SDRAM width: %d, tRRD_S (nck): %d",
+ spd::c_str(l_dimm), l_dram_width, l_trrd_s_in_nck);
+
+ o_setting = l_trrd_s_in_nck;
+ FAPI_DBG("%s DRAM TRRD_S %d", spd::c_str(l_dimm), o_setting);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_TRRD_L specialization
+///
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TRRD_L>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_TRRD_L_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_TRRD_L_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_TRRD_L;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_trrd_l(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_trrd_l(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ const auto& l_dimm = i_spd_data.get_dimm_target();
+
+ // Taking the worst case required minimum JEDEC value
+ // instead of calculating proposed value from SPD -- which selects optimistic values
+ // leading to errors in expected timing values
+ uint8_t l_dram_width = 0;
+ uint64_t l_trrd_l_in_nck = 0;
+ uint64_t l_freq = 0;
+
+ FAPI_TRY( attr::get_freq(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(l_dimm), l_freq) );
+ FAPI_TRY( attr::get_dram_width(l_dimm, l_dram_width) );
+ FAPI_TRY( trrd_l( l_dimm, l_dram_width, l_freq, l_trrd_l_in_nck) );
+
+ FAPI_INF("%s SDRAM width: %d, tRRD_L (nck): %d",
+ spd::c_str(l_dimm), l_dram_width, l_trrd_l_in_nck);
+
+ o_setting = l_trrd_l_in_nck;
+ FAPI_DBG("%s DRAM TRRD_L %d", spd::c_str(l_dimm), o_setting);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_TRFC specialization
+///
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TRFC>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_TRFC_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_TRFC_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_TRFC;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_trfc(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_trfc(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ const auto& l_dimm = i_spd_data.get_dimm_target();
+ int64_t l_tck_in_ps = 0;
+ uint64_t l_freq = 0;
+ uint8_t l_refresh_mode = 0;
+ int64_t l_trfc_mtb = 0;
+ int64_t l_trfc_in_ps = 0;
+
+ FAPI_TRY( attr::get_freq(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(l_dimm), l_freq) );
+ FAPI_TRY( freq_to_ps(l_freq, l_tck_in_ps),
+ "%s Failed to calculate clock period (tCK)", spd::c_str(l_dimm) );
+
+ FAPI_TRY( mss::attr::get_mrw_fine_refresh_mode(l_refresh_mode) );
+
+ // Selects appropriate tRFC based on fine refresh mode
+ switch(l_refresh_mode)
+ {
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_NORMAL:
+ FAPI_TRY( i_spd_data.min_trfc1(l_trfc_mtb),
+ "%s Failed to decode SPD for tRFC1", spd::c_str(l_dimm) );
break;
- case 2:
- FAPI_TRY( i_efd_data->odt_rd_map_rank2(l_value) );
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_2X:
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_2X:
+ FAPI_TRY( i_spd_data.min_trfc2(l_trfc_mtb),
+ "%s Failed to decode SPD for tRFC2", spd::c_str(l_dimm) );
break;
- case 3:
- FAPI_TRY( i_efd_data->odt_rd_map_rank3(l_value) );
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_4X:
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_4X:
+ FAPI_TRY( i_spd_data.min_trfc4(l_trfc_mtb),
+ "%s Failed to decode SPD for tRFC4", spd::c_str(l_dimm) );
break;
default:
- // TODO Add FFDC
- fapi2::Assert(false);
+ // Fine Refresh Mode will be a platform attribute set by the MRW,
+ // which they "shouldn't" mess up as long as use "attribute" enums.
+ // if openpower messes this up we can at least catch it
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_FINE_REFRESH_MODE().
+ set_FINE_REF_MODE(l_refresh_mode),
+ "%s Incorrect Fine Refresh Mode received: %d ",
+ spd::c_str(l_dimm),
+ l_refresh_mode);
break;
- };
+ }// switch
+
+ // Calculate trfc (in ps)
+ {
+ int64_t l_trfc_ftb = 0;
+ int64_t l_ftb = 0;
+ int64_t l_mtb = 0;
+
+ FAPI_TRY( spd::get_timebases(i_spd_data, l_mtb, l_ftb) );
+
+ FAPI_INF( "%s medium timebase (ps): %ld, fine timebase (ps): %ld, tRFC (MTB): %ld, tRFC(FTB): %ld",
+ spd::c_str(l_dimm), l_mtb, l_ftb, l_trfc_mtb, l_trfc_ftb );
+
+ l_trfc_in_ps = spd::calc_timing_from_timebase(l_trfc_mtb, l_mtb, l_trfc_ftb, l_ftb);
+ }
- // TK update to handle differentiating 2 DIMMs, defaulted to DIMM0 case for explorer
{
- // Map to attribute bitmap
- reverse(l_value);
- o_setting = l_value;
+ // Calculate refresh cycle time in nCK & set attribute
+
+ uint16_t l_trfc_in_nck = 0;
+
+ // Calculate nck
+ FAPI_TRY( spd::calc_nck(l_trfc_in_ps, l_tck_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_trfc_in_nck),
+ "%s Error in calculating l_tRFC, with value of l_trfc_in_ps: %d", spd::c_str(l_dimm), l_trfc_in_ps);
+
+ FAPI_INF("%s tCK (ps): %d, tRFC (ps): %d, tRFC (nck): %d",
+ spd::c_str(l_dimm), l_tck_in_ps, l_trfc_in_ps, l_trfc_in_nck);
+
+ o_setting = l_trfc_in_nck;
+ FAPI_DBG("%s DRAM TRFC %d", spd::c_str(l_dimm), o_setting);
}
fapi_try_exit:
@@ -1158,17 +3286,98 @@ struct attrEngineTraits<attr_si_engine_fields, SI_ODT_RD>
};
///
+/// @brief Traits for attrEngineTraits
+/// @class attrEngineTraits - partial specialization
+/// @tparam P processor type
+/// @note attrEngineTraits, DRAM_TRFC_DLR specialization
+///
+template<proc_type P>
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_TRFC_DLR>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_TRFC_DLR_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_TRFC_DLR_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_TRFC_DLR;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_trfc_dlr(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_trfc_dlr(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ const auto& l_dimm = i_spd_data.get_dimm_target();
+ int64_t l_tck_in_ps = 0;
+ uint64_t l_freq = 0;
+ uint8_t l_refresh_mode = 0;
+ uint8_t l_dram_density = 0;
+ uint64_t l_trfc_dlr_in_ps = 0;
+ uint8_t l_trfc_dlr_in_nck = 0;
+
+ FAPI_TRY( attr::get_freq(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(l_dimm), l_freq) );
+ FAPI_TRY( freq_to_ps(l_freq, l_tck_in_ps),
+ "%s Failed to calculate clock period (tCK)", spd::c_str(l_dimm) );
+
+ FAPI_TRY( mss::attr::get_mrw_fine_refresh_mode(l_refresh_mode) );
+ FAPI_TRY( mss::attr::get_dram_density(l_dimm, l_dram_density) );
+
+ // Calculate refresh cycle time in ps
+ FAPI_TRY( calc_trfc_dlr(l_dimm, l_refresh_mode, l_dram_density, l_trfc_dlr_in_ps),
+ "%s Failed calc_trfc_dlr()", spd::c_str(l_dimm) );
+
+ // Calculate refresh cycle time in nck
+ FAPI_TRY( spd::calc_nck(l_trfc_dlr_in_ps, static_cast<uint64_t>(l_tck_in_ps), spd::INVERSE_DDR4_CORRECTION_FACTOR,
+ l_trfc_dlr_in_nck));
+
+ FAPI_INF("%s tCK (ps): %d, tRFC_DLR (ps): %d, tRFC_DLR (nck): %d",
+ spd::c_str(l_dimm), l_tck_in_ps, l_trfc_dlr_in_ps, l_trfc_dlr_in_nck);
+
+ o_setting = l_trfc_dlr_in_nck;
+ FAPI_DBG("%s DRAM TRFC_DLR %d", spd::c_str(l_dimm), o_setting);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
/// @brief Traits for attr_engine
/// @class attrEngineTraits
-/// @note attr_si_engine_fields, SI_GEARDOWN_MODE specialization
+/// @note attr_engine_derived_fields, RCD_MFG_ID specialization
///
-template<>
-struct attrEngineTraits<attr_si_engine_fields, SI_GEARDOWN_MODE>
+template < proc_type P >
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::RCD_MFG_ID>
{
- using attr_type = fapi2::ATTR_MEM_SI_GEARDOWN_MODE_Type;
+ using attr_type = fapi2::ATTR_MEM_EFF_RCD_MFG_ID_Type;
using attr_integral_type = std::remove_all_extents<attr_type>::type;
- static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_SI_GEARDOWN_MODE_TargetType;
- static constexpr generic_ffdc_codes FFDC_CODE = SET_SI_GEARDOWN_MODE;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_RCD_MFG_ID_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_RCD_MFG_ID;
///
/// @brief attribute getter
@@ -1179,19 +3388,119 @@ struct attrEngineTraits<attr_si_engine_fields, SI_GEARDOWN_MODE>
static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& o_setting)
{
- return mss::attr::get_si_geardown_mode(i_target, o_setting);
+ return mss::attr::get_rcd_mfg_id(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_rcd_mfg_id(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_efd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.reg_manufacturer_id_code(o_setting);
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @note attr_engine_derived_fields, DRAM_MODULE_HEIGHT specialization
+///
+template < proc_type P >
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::DRAM_MODULE_HEIGHT>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_DRAM_MODULE_HEIGHT_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_DRAM_MODULE_HEIGHT_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_DRAM_MODULE_HEIGHT;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_dram_module_height(i_target, o_setting);
}
///
/// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_dram_module_height(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_efd_data EFD data
+ /// @param[out] o_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static inline fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ return i_spd_data.module_base_height(o_setting);
+ }
+};
+
+///
+/// @brief Traits for attr_engine
+/// @class attrEngineTraits
+/// @note attr_engine_derived_fields, SPD_REVISION specialization
+///
+template < proc_type P >
+struct attrEngineTraits<P, attr_eff_engine_fields, attr_eff_engine_fields::SPD_REVISION>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_SPD_REVISION_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_SPD_REVISION_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_SPD_REVISION;
+
+ ///
+ /// @brief attribute getter
/// @param[in] i_target the fapi2 target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_spd_revision(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
/// @param[in] i_setting array to set
/// @return FAPI2_RC_SUCCESS iff okay
///
static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
attr_type& i_setting)
{
- return mss::attr::set_si_geardown_mode(i_target, i_setting);
+ return mss::attr::set_spd_revision(i_target, i_setting);
}
///
@@ -1200,10 +3509,10 @@ struct attrEngineTraits<attr_si_engine_fields, SI_GEARDOWN_MODE>
/// @param[out] o_setting value we want to set attr with
/// @return FAPI2_RC_SUCCESS iff okay
///
- static fapi2::ReturnCode get_value_to_set(const std::shared_ptr<efd::base_decoder>& i_efd_data,
+ static inline fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
attr_integral_type& o_setting)
{
- return i_efd_data->geardown_during_training(o_setting);
+ return i_spd_data.revision(o_setting);
}
};
diff --git a/src/import/generic/memory/lib/data_engine/data_engine.H b/src/import/generic/memory/lib/data_engine/data_engine.H
index aa0fb5f0a..6e206292b 100644
--- a/src/import/generic/memory/lib/data_engine/data_engine.H
+++ b/src/import/generic/memory/lib/data_engine/data_engine.H
@@ -38,225 +38,100 @@
#include <cstring>
#include <fapi2.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
-#include <generic/memory/lib/data_engine/attr_engine_traits.H>
#include <generic/memory/lib/data_engine/data_engine_utils.H>
-#include <generic/memory/lib/spd/spd_utils.H>
-#include <generic/memory/lib/utils/conversions.H>
-#include <generic/memory/lib/mss_generic_attribute_getters.H>
namespace mss
{
-
-///
-/// @brief Alias for function pointer to spd_facade timing methods
-///
-using spd_facade_fptr = fapi2::ReturnCode (spd::facade::*)(int64_t& o_timing_in_mtb) const;
-
-///
-/// @brief Algorithm to calculate SPD timings in nCK
-/// @tparam ET SPD fields enumeration (e.g. attr_eff_engine_fields)
-/// @tparam F SPD field
-/// @tparam OT output type
-/// @tparam TT defaulted to setTimingTraits<ET, F>
-/// @param[in] i_spd the SPD data
-/// @param[out] o_timing_in_ps SPD timing value in picoseconds
-/// @return FAPI2_RC_SUCCESS iff okay
-///
-template < typename ET,
- ET F,
- typename OT,
- typename TT = setTimingTraits<ET, F> >
-inline fapi2::ReturnCode calc_spd_time_in_ps(const spd::facade& i_spd,
- OT& o_timing_in_ps)
-{
- const auto l_dimm = i_spd.get_dimm_target();
- int64_t l_timing_mtb = 0;
- int64_t l_timing_ftb = 0;
- int64_t l_mtb = 0;
- int64_t l_ftb = 0;
-
- FAPI_TRY( spd::get_timebases(i_spd, l_mtb, l_ftb) );
-
- FAPI_TRY( (i_spd.*TT::get_timing_in_mtb)(l_timing_mtb),
- "Failed to get % (in MTB) for %s", TT::TIMING_NAME, spd::c_str(l_dimm) );
- FAPI_TRY( (i_spd.*TT::get_timing_in_ftb)(l_timing_ftb),
- "Failed to get %s (in FTB) for %s", TT::TIMING_NAME, spd::c_str(l_dimm) );
-
- FAPI_DBG("%s medium timebase (ps): %ld, fine timebase (ps): %ld, %s (MTB): %ld, (FTB): %ld",
- spd::c_str(l_dimm), l_mtb, l_ftb, TT::TIMING_NAME, l_timing_mtb, l_timing_ftb );
-
- o_timing_in_ps = spd::calc_timing_from_timebase(l_timing_mtb, l_mtb, l_timing_ftb, l_ftb);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Algorithm to calculate SPD timings in nCK
-/// @tparam ET SPD fields enumeration (e.g. attr_eff_engine_fields)
-/// @tparam F SPD field
-/// @tparam OT output type
-/// @tparam TT defaulted to setTimingTraits<ET, F>
-/// @param[in] i_spd the SPD data
-/// @param[out] o_timing_in_ps SPD timing value in number of clocks (nCK)
-/// @return FAPI2_RC_SUCCESS iff okay
-///
-template < typename ET,
- ET F,
- typename OT,
- typename TT = setTimingTraits<ET, F> >
-inline fapi2::ReturnCode calc_spd_time_in_nck(const spd::facade& i_spd,
- OT& o_timing_in_nck)
-{
- const auto l_dimm = i_spd.get_dimm_target();
-
- // Calculate the DIMM speed in picoseconds (a.k.a tCK == clock period)
- int64_t l_tck_in_ps = 0;
- uint64_t l_freq = 0;
- FAPI_TRY( attr::get_freq(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(l_dimm), l_freq) );
- FAPI_TRY( freq_to_ps(l_freq, l_tck_in_ps),
- "Failed to calculate clock period (tCK) for %s", spd::c_str(l_dimm) );
-
- {
- // Calculate the desired timing in ps
- int64_t l_timing_in_ps = 0;
- FAPI_TRY( (calc_spd_time_in_ps<ET, F>(i_spd, l_tck_in_ps)) );
-
- // Calculate nck
- FAPI_TRY( spd::calc_nck(l_timing_in_ps, l_tck_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, o_timing_in_nck),
- "Error in calculating %s (nCK) for target %s, with value of %d",
- TT::TIMING_NAME, spd::c_str(l_dimm), l_timing_in_ps );
-
- FAPI_INF("tCK (ps): %d, %s (ps): %d, %s (nck): %d",
- l_tck_in_ps, TT::TIMING_NAME, l_timing_in_ps, TT::TIMING_NAME, o_timing_in_nck);
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Sets preliminary data fields
-/// @tparam F pre_data_init_fields
-/// @tparam T FAPI2 target type
-/// @tparam IT Input data type
-/// @tparam TT defaulted to preDataInitTraits<T>
-/// @param[in] i_setting value we want to set attr with
-/// @return FAPI2_RC_SUCCESS iff okay
-///
-template< attr_eff_engine_fields F,
- fapi2::TargetType T,
- typename IT,
- typename TT = mss::attrEngineTraits<decltype(F), F>
- >
-inline fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target,
- const IT i_setting)
+namespace gen
{
- FAPI_TRY( (gen::set_field<TT>(i_target, i_setting)),
- "Failed set_field() for %s", spd::c_str(i_target) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Value traits for attrEnumTraits
-/// @class attrEnumTraits - attr_si_engine_fields specialization
-///
-template < >
-struct attrEnumTraits<attr_si_engine_fields>
-{
- static constexpr size_t DISPATCHER = ATTR_SI_DISPATCHER;
-};
-
-///
-/// @brief Value traits for attrEnumTraits
-/// @class attrEnumTraits - attr_eff_engine_fields specialization
-///
-template < >
-struct attrEnumTraits<attr_eff_engine_fields>
-{
- static constexpr size_t DISPATCHER = ATTR_EFF_DISPATCHER;
-};
-
-///
-/// @brief Value traits for attrEnumTraits
-/// @class attrEnumTraits - attr_eff_engine_fields specialization
-///
-template < >
-struct attrEnumTraits<pre_data_init_fields>
-{
- static constexpr size_t DISPATCHER = ATTR_PRE_DATA_ENG_DISPATCHER;
-};
///
-/// @brief attribute signal integrity engine
-/// @class attr_si_engine
-/// @tparam ET field enumeration type
-/// @tparam TT defaulted to attrEnumTraits<ET>
+/// @brief Template recursive algorithm for setting attrs
+/// @class attr_engine - partial specialization when F != 0
+/// @tparam P processor type
+/// @tparam ET enum type - conceptually a list of attrs to set
+/// @tparam F enum value - the specific attr value from ET to set
+/// @tparam TT associated traits for attr_engine
///
-template < typename ET, typename TT = attrEnumTraits<ET> >
-struct attr_si_engine
+template < proc_type P, typename ET, ET F, typename TT >
+struct attr_engine<P, ET, F, TT, false>
{
- using attr_eng_t = gen::attr_engine<ET, static_cast<ET>(TT::DISPATCHER)>;
-
///
- /// @brief Sets attr_si_engine_fields
- /// @tparam[in] IT rank input type
- /// @param[in] i_target the DIMM target
- /// @param[in] i_efd_data EFD data
- /// @param[in] i_rank current rank
+ /// @brief Sets attributes fields F in ET
+ /// @tparam IT the input type
+ /// @param[in] i_input input (efd_decoder, spd_facade, fapi2 target)
/// @return FAPI2_RC_SUCCESS iff ok
///
- static fapi2::ReturnCode set(const std::shared_ptr<efd::base_decoder>& i_efd_data)
+ template < typename IT >
+ static fapi2::ReturnCode single_set(const IT& i_input)
{
- return attr_eng_t::set(i_efd_data);
- }
-};
+ typename TT::attr_integral_type l_value = 0;
-///
-/// @brief Data structure to set effective config EFF data
-/// @class pre_attr_eff_engine
-/// @tparam F attr_eff_engine_fields enum
-///
-template < typename ET, typename TT = attrEnumTraits<ET> >
-struct attr_eff_engine
-{
- using attr_eng_t = gen::attr_engine<ET, static_cast<ET>(TT::DISPATCHER)>;
+ FAPI_TRY( TT::get_value_to_set(i_input, l_value),
+ "Failed get_value_to_set() for proc_type: %d and enum val: %d", P, F);
+
+ FAPI_TRY( set_field<TT>(i_input, l_value),
+ "Failed set_field() for proc_type: %d and enum val: %d", P, F);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
- /// @brief Sets attr_si_engine_fields
- /// @param[in] i_target the DIMM target
- /// @param[in] i_spd_data EFD data
+ /// @brief Sets attributes fields F in ET
+ /// @tparam IT the input type
+ /// @param[in] i_input input (efd_decoder, spd_facade, fapi2 target)
/// @return FAPI2_RC_SUCCESS iff ok
///
- static fapi2::ReturnCode set(const mss::spd::facade& i_spd_data)
+ template < typename IT >
+ static fapi2::ReturnCode set(const IT& i_input)
{
- return attr_eng_t::set(i_spd_data);
+ FAPI_TRY( (attr_engine<P, ET, F, TT, static_cast<size_t>(F) == 0u>::single_set(i_input)),
+ "Failed attr_engine<P, ET, F>::single_set() for proc_type: %d and enum val: %d", P, F);
+
+ // Compiler isn't smart enough to deduce F - 1u (decrementing the enum values by 1)
+ // Cast needed to help the compiler deduce this value is an ET type
+ // This does the recursive call to unroll a compile-time looping of a enum list of attrs to set
+ // The recursion stops at the base case where NEXT_FLD == 0u
+ {
+ constexpr ET NEXT_FLD = static_cast<ET>( static_cast<size_t>(F) - 1u );
+ using T = mss::attrEngineTraits<P, ET, NEXT_FLD>;
+
+ FAPI_TRY( (attr_engine <P, ET, NEXT_FLD, T, 0u == static_cast<size_t>(NEXT_FLD)>::set(i_input)),
+ "Failed (attr_engine <P, ET, NEXT_FLD>::set() for proc_type: %d and enum val: %d", P, F);
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
}
};
///
-/// @brief Data structure to set effective config EFF data
-/// @class attr_derived_engine
-/// @tparam ET attr fields enum type
+/// @brief Template recursive algorithm for setting attrs
+/// @class attr_engine - partial specialization where F == 0u
+/// @tparam P processor type
+/// @tparam ET attr fields enum type (conceptually a list of attrs to set)
+/// @tparam F enum value - the specific attr value from ET to set
+/// @tparam TT associated traits for attr_engine
///
-template < typename ET, typename TT = attrEnumTraits<ET> >
-struct attr_derived_engine
+template < proc_type P, typename ET, ET F, typename TT >
+struct attr_engine< P, ET, F, TT, true >
{
- using attr_eng_t = gen::attr_engine<ET, static_cast<ET>(TT::DISPATCHER)>;
-
///
- /// @brief Sets attr fields denoted by an eum list
- /// @param[in] i_target the DIMM target
+ /// @brief Sets attributes fields F in ET
+ /// @tparam IT the input type
+ /// @param[in] i_input input (efd_decoder, spd_facade, fapi2 target)
/// @return FAPI2_RC_SUCCESS iff ok
///
- static fapi2::ReturnCode set(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target)
+ template < typename IT >
+ static fapi2::ReturnCode set(const IT& i_input)
{
- return attr_eng_t::set(i_target);
+ FAPI_DBG("NO-OP: Reached base case (0) of recursive template for proc_type: %d and enum value: %d", P, F);
+ return fapi2::FAPI2_RC_SUCCESS;
}
};
+}// gen
}// mss
#endif
diff --git a/src/import/generic/memory/lib/data_engine/data_engine_traits_def.H b/src/import/generic/memory/lib/data_engine/data_engine_traits_def.H
index be55890ea..4852da6b1 100644
--- a/src/import/generic/memory/lib/data_engine/data_engine_traits_def.H
+++ b/src/import/generic/memory/lib/data_engine/data_engine_traits_def.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -43,62 +43,91 @@ namespace mss
{
///
-/// @brief enum list of preliminary data fields
+/// @brief enum list of preliminary data fields needed before eff_config
///
-enum generic_metadata_fields
+enum class pre_data_init_fields
{
// Template recursive base case
- ATTR_METADATA_BASE_CASE = 0,
+ ATTR_PRE_DATA_ENGINE_CASE = 0,
// Attrs to set
- DIMM_TYPE_METADATA = 1,
- DRAM_GEN_METADATA = 2,
- DIMM_POS_METADATA = 3,
+ DIMM_TYPE = 1,
+ DRAM_GEN = 2,
+ HYBRID = 3,
+ HYBRID_MEDIA = 4,
+ MRANKS = 5,
+ HOST_TO_DDR_SPEED_RATIO = 6,
+ DIMM_RANKS_CNFG = 7,
// Dispatcher set to last enum value
- ATTR_METADATA_DISPATCHER = DIMM_POS_METADATA,
+ DISPATCHER = DIMM_RANKS_CNFG,
};
///
/// @brief enum list of preliminary data fields
+/// @note Separating these fields into their own special case
+/// since this is needed for reuse in incompatible code bases
+/// (e.g. Nimbus vs Axone)
+/// @warning these depend on pre_data_init_fields fields being set
///
-enum pre_data_init_fields
+enum class generic_metadata_fields
{
// Template recursive base case
- ATTR_PRE_DATA_ENGINE_CASE = 0,
+ ATTR_METADATA_BASE_CASE = 0,
// Attrs to set
- DIMM_TYPE = 1,
- DRAM_GEN = 2,
- HYBRID = 3,
- HYBRID_MEDIA = 4,
- MRANKS = 5,
- DIMM_RANKS_CNFG = 6,
- HOST_TO_DDR_SPEED_RATIO = 7,
+ DIMM_TYPE_METADATA = 1,
+ DRAM_GEN_METADATA = 2,
+ DIMM_POS_METADATA = 3,
// Dispatcher set to last enum value
- ATTR_PRE_DATA_ENG_DISPATCHER = HOST_TO_DDR_SPEED_RATIO,
+ DISPATCHER = DIMM_POS_METADATA,
};
///
/// @brief enum list of SPD based attr fields to set
///
-enum attr_eff_engine_fields
+enum class attr_eff_engine_fields
{
// Template recursive base case
ATTR_EFF_BASE_CASE = 0,
// Attrs to set
- DRAM_WIDTH = 1,
+ DRAM_CWL = 1,
+ DRAM_TREFI = 2,
+ DRAM_TCCD_L = 3,
+ DRAM_TWTR_L = 4,
+ DRAM_TWTR_S = 5,
+ DRAM_TFAW = 6,
+ DRAM_TRCD = 7,
+ DRAM_TRP = 8,
+ DRAM_TRAS = 9,
+ DRAM_TWR = 10,
+ DRAM_TRTP = 11,
+ DRAM_TRRD_S = 12,
+ DRAM_TRRD_L = 13,
+ DRAM_TRFC = 14,
+ DRAM_TRFC_DLR = 15,
+ DRAM_WIDTH = 16,
+ PRIM_BUS_WIDTH = 17,
+ DRAM_DENSITY = 18,
+ PRIMARY_DIE_COUNT = 19,
+ PRIM_STACK_TYPE = 20,
+ COLUMN_ADDR_BITS = 21,
+ ROW_ADDR_BITS = 22,
+ DRAM_MFG_ID = 23,
+ RCD_MFG_ID = 24,
+ DRAM_MODULE_HEIGHT = 25,
+ SPD_REVISION = 26,
// Dispatcher set to last enum value
- ATTR_EFF_DISPATCHER = DRAM_WIDTH,
+ DISPATCHER = SPD_REVISION,
};
///
-/// @brief enum list of SI attr fields to set
+/// @brief enum list of SI attr fields to set from EFD
///
-enum attr_si_engine_fields
+enum class attr_si_engine_fields
{
// Template recursive base case
ATTR_SI_BASE_CASE = 0,
@@ -119,29 +148,51 @@ enum attr_si_engine_fields
SI_DRAM_PREAMBLE = 13,
SI_MC_DRV_EQ_DQ_DQS = 14,
SI_DRAM_DRV_IMP_DQ_DQS = 15,
- SI_VREF_DQ_TRAIN_RANGE = 16,
- SI_VREF_DQ_TRAIN_VALUE = 17,
- SI_ODT_WR = 18,
- SI_ODT_RD = 19,
- SI_GEARDOWN_MODE = 20,
+ SI_ODT_WR = 16,
+ SI_ODT_RD = 17,
+ SI_GEARDOWN_MODE = 18,
+
+ // Dispatcher set to last enum value
+ DISPATCHER = SI_GEARDOWN_MODE,
+};
+
+///
+/// @brief enum list of derived attributes
+/// @note these are attributes that are derived from other
+/// attributes or other APIs.
+///
+enum class attr_engine_derived_fields
+{
+ // Attributes are set recursively from the bottom up.
+ // When adding attrs that depend on other attrs
+ // being set first, they should be placed earlier in the enum list
+ // so that base level attrs are set first.
+
+ // Template recursive base case
+ ATTR_DERIVED_BASE_CASE = 0,
+
+ // Attrs to set
+ MEM_DIMM_SIZE = 1,
+ HEIGHT_3DS = 2, // HEIGHT_3DS must be calculated after LOGICAL_RANKS
+ LOGICAL_RANKS = 3,
// Dispatcher set to last enum value
- ATTR_SI_DISPATCHER = SI_GEARDOWN_MODE,
+ DISPATCHER = LOGICAL_RANKS,
};
///
/// @brief Forward declartion of traits for pre_data_engine
/// @class preDataInitTraits
-/// @tparam T proc_type (e.g. Nimbus, Axone, etc.)
+/// @tparam P processor type (e.g. Nimbus, Axone, etc.)
/// @tparam TT pre_data_init_fields (e.g. DIMM_TYPE, MRANK, etc.)
///
-template< proc_type T, pre_data_init_fields TT >
+template< proc_type P, pre_data_init_fields TT >
class preDataInitTraits;
///
/// @brief Traits associated with DIMM positioning
/// @class dimmPosTraits
-/// @tparam MC the MC type
+/// @tparam MC the memory controller type
///
template< mss::mc_type MC >
class dimmPosTraits;
@@ -149,10 +200,11 @@ class dimmPosTraits;
///
/// @brief Forward declartion of traits for attrEngineTraits
/// @class attrEngineTraits
+/// @tparam P processor type (e.g. Nimbus, Axone, etc.)
/// @tparam ET enum type
/// @tparam T enum value
///
-template < typename ET, ET T>
+template < proc_type P, typename ET, ET T = ET::DISPATCHER>
struct attrEngineTraits;
///
@@ -164,14 +216,25 @@ struct attrEngineTraits;
template < typename ET, ET T >
struct setTimingTraits;
+namespace gen
+{
///
-/// @brief Forward declartion of traits for attrEnumTraits
-/// @class attrEnumTraits
-/// @tparam ET enum type
-///
-template < typename ET >
-struct attrEnumTraits;
-
+/// @brief Template recursive algorithm for setting attrs
+/// @class attr_engine
+/// @tparam P processor type (e.g. Nimbus, Axone, etc.)
+/// @tparam ET enum type - conceptually a list of attrs to set
+/// @tparam F enum value - the specific attr value from ET to set
+/// @tparam TT associated traits for attr_engine
+/// @tparam B dispatch tag - defaulted to false
+///
+template < proc_type P,
+ typename ET,
+ ET F = ET::DISPATCHER,
+ typename TT = attrEngineTraits<P, ET, F>,
+ bool B = false>
+struct attr_engine;
+
+}// gen
}// mss
#endif
diff --git a/src/import/generic/memory/lib/data_engine/data_engine_utils.H b/src/import/generic/memory/lib/data_engine/data_engine_utils.H
index aaf9a0485..a4a8d9946 100644
--- a/src/import/generic/memory/lib/data_engine/data_engine_utils.H
+++ b/src/import/generic/memory/lib/data_engine/data_engine_utils.H
@@ -37,154 +37,104 @@
#define _MSS_DATA_ENGINE_UTILS_H_
#include <fapi2.H>
+#include <generic/memory/lib/data_engine/data_engine_traits_def.H>
#include <generic/memory/lib/utils/index.H>
#include <generic/memory/lib/utils/find.H>
#include <generic/memory/lib/utils/pos.H>
#include <generic/memory/lib/spd/ddimm/efd_decoder.H>
+#include <generic/memory/lib/spd/spd_utils.H>
#include <generic/memory/lib/spd/spd_facade.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
+#include <generic/memory/lib/utils/conversions.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/buffer_ops.H>
namespace mss
{
///
-/// @class DataSetterTraits2D
-/// @brief Traits for setting eff_config data
-/// @tparam P proc_type
-/// @tparam X size of 1st array index
-/// @tparam Y size of 2nd array index
+/// @brief Alias for function pointer to spd_facade timing methods
///
-template < proc_type, size_t X, size_t Y >
-struct DataSetterTraits2D;
+using spd_facade_fptr = fapi2::ReturnCode (spd::facade::*)(int64_t& o_timing_in_mtb) const;
///
-/// @class DataSetterTraits - Nimbus, [PORT][DIMM] array specialization
-/// @brief Traits for setting eff_config data
+/// @brief Algorithm to calculate SPD timings in nCK
+/// @tparam ET SPD fields enumeration (e.g. attr_eff_engine_fields)
+/// @tparam F SPD field
+/// @tparam OT output type
+/// @tparam TT defaulted to setTimingTraits<ET, F>
+/// @param[in] i_spd the SPD data
+/// @param[out] o_timing_in_ps SPD timing value in picoseconds
+/// @return FAPI2_RC_SUCCESS iff okay
///
-template < >
-struct DataSetterTraits2D < proc_type::NIMBUS,
- mcTypeTraits<mc_type::NIMBUS>::PORTS_PER_MCS,
- mcTypeTraits<mc_type::NIMBUS>::DIMMS_PER_PORT
- >
+template < typename ET,
+ ET F,
+ typename OT,
+ typename TT = setTimingTraits<ET, F> >
+inline fapi2::ReturnCode calc_spd_time_in_ps(const spd::facade& i_spd,
+ OT& o_timing_in_ps)
{
- static constexpr fapi2::TargetType TARGET = fapi2::TARGET_TYPE_MCA;
-};
+ const auto l_dimm = i_spd.get_dimm_target();
+ int64_t l_timing_mtb = 0;
+ int64_t l_timing_ftb = 0;
+ int64_t l_mtb = 0;
+ int64_t l_ftb = 0;
-///
-/// @brief Helper function to update a 2D array output
-/// @tparam P proc_type
-/// @tparam X size of 1st array index
-/// @tparam Y size of 2nd array index
-/// @tparam T Input/output data type
-/// @tparam TT defaulted to DataSetterTraits2D<P, X, Y>
-/// @param[in] i_target the DIMM target
-/// @param[in] i_setting array to set
-/// @param[in] i_ffdc_code FFDC function code
-/// @param[out] o_data attribute data structure to set
-/// @warning This is Nimbus specific until MCA alias to MEM_PORT
-///
-template < proc_type P,
- size_t X,
- size_t Y,
- typename T,
- typename TT = DataSetterTraits2D<P, X, Y>
- >
-fapi2::ReturnCode update_data(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const T i_setting,
- const generic_ffdc_codes i_ffdc_code,
- T (&o_data)[X][Y])
-{
- // Currenlty only valid for a DIMM target, for Nimbus, traits enforces this at compile time
- // Use case is currently for pre_eff_config which is supported in both Axone and Nimbus
- const auto l_port_index = mss::index( find_target<TT::TARGET>(i_target) );
- const auto l_dimm_index = mss::index(i_target);
+ FAPI_TRY( spd::get_timebases(i_spd, l_mtb, l_ftb) );
- FAPI_ASSERT( l_port_index < X,
- fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
- .set_INDEX(l_port_index)
- .set_LIST_SIZE(X)
- .set_FUNCTION(i_ffdc_code)
- .set_TARGET(i_target),
- "Port index (%d) was larger than max (%d) on %s",
- l_port_index,
- X,
- mss::spd::c_str(i_target) );
+ FAPI_TRY( (i_spd.*TT::get_timing_in_mtb)(l_timing_mtb),
+ "Failed to get % (in MTB) for %s", TT::TIMING_NAME, spd::c_str(l_dimm) );
+ FAPI_TRY( (i_spd.*TT::get_timing_in_ftb)(l_timing_ftb),
+ "Failed to get %s (in FTB) for %s", TT::TIMING_NAME, spd::c_str(l_dimm) );
- FAPI_ASSERT( l_dimm_index < Y,
- fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
- .set_INDEX(l_dimm_index)
- .set_LIST_SIZE(Y)
- .set_FUNCTION(i_ffdc_code)
- .set_TARGET(i_target),
- "DIMM index (%d) was larger than max (%d) on %s",
- l_dimm_index,
- Y,
- mss::spd::c_str(i_target) );
-
- o_data[l_port_index][l_dimm_index] = i_setting;
+ FAPI_DBG("%s medium timebase (ps): %ld, fine timebase (ps): %ld, %s (MTB): %ld, (FTB): %ld",
+ spd::c_str(l_dimm), l_mtb, l_ftb, TT::TIMING_NAME, l_timing_mtb, l_timing_ftb );
- return fapi2::FAPI2_RC_SUCCESS;
+ o_timing_in_ps = spd::calc_timing_from_timebase(l_timing_mtb, l_mtb, l_timing_ftb, l_ftb);
fapi_try_exit:
return fapi2::current_err;
}
///
-/// @brief Mapping boilerplate check
-/// @tparam T FAPI2 target type
-/// @tparam IT map key type
-/// @tparam OT map value type
-/// @param[in] i_target the FAPI target
-/// @param[in] i_map SPD to attribute data mapping
-/// @param[in] i_ffdc_code FFDC function code
-/// @param[in] i_key Key to query map
-/// @param[out] o_output value from key
+/// @brief Algorithm to calculate SPD timings in nCK
+/// @tparam ET SPD fields enumeration (e.g. attr_eff_engine_fields)
+/// @tparam F SPD field
+/// @tparam OT output type
+/// @tparam TT defaulted to setTimingTraits<ET, F>
+/// @param[in] i_spd the SPD data
+/// @param[out] o_timing_in_ps SPD timing value in number of clocks (nCK)
/// @return FAPI2_RC_SUCCESS iff okay
///
-template< fapi2::TargetType T, typename IT, typename OT >
-inline fapi2::ReturnCode lookup_table_check(const fapi2::Target<T>& i_target,
- const std::vector<std::pair<IT, OT>>& i_map,
- const generic_ffdc_codes i_ffdc_code,
- const IT i_key,
- OT& o_output)
+template < typename ET,
+ ET F,
+ typename OT,
+ typename TT = setTimingTraits<ET, F> >
+inline fapi2::ReturnCode calc_spd_time_in_nck(const spd::facade& i_spd,
+ OT& o_timing_in_nck)
{
- const bool l_is_val_found = mss::find_value_from_key(i_map, i_key, o_output);
+ const auto l_dimm = i_spd.get_dimm_target();
- FAPI_ASSERT( l_is_val_found,
- fapi2::MSS_LOOKUP_FAILED()
- .set_KEY(i_key)
- .set_DATA(o_output)
- .set_FUNCTION(i_ffdc_code)
- .set_TARGET(i_target),
- "Failed to find a mapped value for %d on %s",
- i_key,
- mss::spd::c_str(i_target) );
-fapi_try_exit:
- return fapi2::current_err;
-}
+ // Calculate the DIMM speed in picoseconds (a.k.a tCK == clock period)
+ int64_t l_tck_in_ps = 0;
+ uint64_t l_freq = 0;
+ FAPI_TRY( attr::get_freq(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(l_dimm), l_freq) );
+ FAPI_TRY( freq_to_ps(l_freq, l_tck_in_ps),
+ "Failed to calculate clock period (tCK) for %s", spd::c_str(l_dimm) );
-///
-/// @brief Sets attr data fields
-/// @tparam P proc_type
-/// @tparam TT data engine class traits (e.g. preDataInitTraits, etc.)
-/// @tparam T FAPI2 target type
-/// @tparam IT Input data type
-/// @param[in] i_target the FAPI target
-/// @param[in] i_setting value we want to set attr with
-/// @return FAPI2_RC_SUCCESS iff okay
-///
-template< proc_type P,
- typename TT,
- fapi2::TargetType T,
- typename IT >
-inline fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target,
- const IT i_setting)
-{
- const auto l_attr_target = mss::find_target<TT::TARGET_TYPE>(i_target);
- typename TT::attr_type l_attr_list = {};
- FAPI_TRY( TT::get_attr(l_attr_target, l_attr_list) );
+ {
+ // Calculate the desired timing in ps
+ int64_t l_timing_in_ps = 0;
+ FAPI_TRY( (calc_spd_time_in_ps<ET, F>(i_spd, l_timing_in_ps)) );
+
+ // Calculate nck
+ FAPI_TRY( spd::calc_nck(l_timing_in_ps, l_tck_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, o_timing_in_nck),
+ "Error in calculating %s (nCK) for target %s, with value of %d",
+ TT::TIMING_NAME, spd::c_str(l_dimm), l_timing_in_ps );
- FAPI_TRY( update_data<P>(i_target, i_setting, TT::FFDC_CODE, l_attr_list) );
- FAPI_TRY( TT::set_attr(l_attr_target, l_attr_list) );
+ FAPI_INF("tCK (ps): %d, %s (ps): %d, %s (nck): %d",
+ l_tck_in_ps, TT::TIMING_NAME, l_timing_in_ps, TT::TIMING_NAME, o_timing_in_nck);
+ }
fapi_try_exit:
return fapi2::current_err;
@@ -196,7 +146,7 @@ namespace gen
{
///
-/// @brief Get the target associated with the SPD facade
+/// @brief Helper to get the target associated with the SPD facade
/// @param[in] i_data the SPD data
/// return a fapi2 DIMM target
///
@@ -206,7 +156,7 @@ static inline fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_target(const spd::facad
}
///
-/// @brief Get the target associated with the EFD decoder
+/// @brief Helper to get the target associated with the EFD decoder
/// @param[in] i_data the EFD data
/// return a fapi2 DIMM target
///
@@ -216,6 +166,32 @@ static inline fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> get_target(const std::
}
///
+/// @brief Helper function to get the target associated with generic attribute setting
+/// @param[in] i_target
+/// return a fapi2 MEM_PORT target
+///
+static inline fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> get_attr_target(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&
+ i_target)
+{
+ return mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(i_target);
+}
+
+///
+/// @brief Helper function to get the target associated with generic attribute setting
+/// @param[in] i_target
+/// return a fapi2 MEM_PORT target
+///
+inline fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> get_attr_target(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
+ i_target)
+{
+ // Explorer has only one MEM_PORT per OCMB, so we are looking for the 0th pos relative to the OCMB
+ // Will need to update to take into account a mem_channel index in VPDinfo if we ever support this.
+ // Per FW, for the DDIMM case we can't support unique settings per channel because the SPD
+ // doesn't know about anything outside of the DDIMM itself.
+ return mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target)[0];
+}
+
+///
/// @brief Helper function to update the structure that holds attr data
/// @tparam X size of 1st array index
/// @tparam Y size of 2nd array index
@@ -238,10 +214,9 @@ inline fapi2::ReturnCode update_data(const std::shared_ptr<efd::base_decoder>& i
{
const auto l_ocmb = i_efd_data->get_ocmb_target();
- // TK, remove hard-code when VPDinfo struct adds an iv_dimm index
- // For explorer we can only have 1 DDIMM (index 0), or up to 2 DIMMs
- constexpr size_t l_dimm_index = 0;
- const auto l_rank = i_efd_data->get_rank();
+ // mss::index of rank number will % 4 (RANKS_PER_DIMM) to get us the corresponding dimm
+ const auto l_dimm_index = i_efd_data->get_rank() / mss::MAX_RANK_PER_DIMM;
+ const auto l_dimm_rank = i_efd_data->get_rank() % mss::MAX_RANK_PER_DIMM;
FAPI_ASSERT( l_dimm_index < X,
fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
@@ -254,19 +229,19 @@ inline fapi2::ReturnCode update_data(const std::shared_ptr<efd::base_decoder>& i
X,
mss::spd::c_str(l_ocmb) );
- FAPI_ASSERT( l_rank < Y,
+ FAPI_ASSERT( l_dimm_rank < Y,
fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
- .set_INDEX(l_rank)
+ .set_INDEX(l_dimm_rank)
.set_LIST_SIZE(X)
.set_FUNCTION(i_ffdc_code)
.set_TARGET(l_ocmb),
"Rank index (%d) was larger than max (%d) on %s",
- l_rank,
+ l_dimm_rank,
Y,
mss::spd::c_str(l_ocmb) );
- FAPI_DBG("Updating data[%d][%d] with %d for %s", l_dimm_index, l_rank, i_setting, spd::c_str(l_ocmb));
- o_data[l_dimm_index][l_rank] = i_setting;
+ FAPI_DBG("Updating data[%d][%d] with %d for %s", l_dimm_index, l_dimm_rank, i_setting, spd::c_str(l_ocmb));
+ o_data[l_dimm_index][l_dimm_rank] = i_setting;
return fapi2::FAPI2_RC_SUCCESS;
@@ -294,9 +269,8 @@ inline fapi2::ReturnCode update_data( const spd::facade& i_spd_data,
const FFDC i_ffdc_code,
T (&o_data)[X])
{
- // TK remove hard-code to DIMM0, use REL_POS attr
const auto l_dimm = i_spd_data.get_dimm_target();
- const size_t l_dimm_index = 0;
+ const size_t l_dimm_index = mss::index(l_dimm);
FAPI_ASSERT( l_dimm_index < X,
fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
@@ -321,6 +295,49 @@ fapi_try_exit:
///
/// @brief Helper function to update the structure that holds attr data
/// @tparam T the FAPI2 TargetType
+/// @tparam IT Input/Output data type
+/// @tparam FFDC the FFDC type
+/// @tparam X size of 1st array index
+/// @param[in] i_target the FAPI2 target
+/// @param[in] i_setting array to set
+/// @param[in] i_ffdc_code FFDC function code
+/// @param[out] o_data attribute data structure to set
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+template < fapi2::TargetType T,
+ typename IT,
+ typename FFDC,
+ size_t X >
+inline fapi2::ReturnCode update_data( const fapi2::Target<T>& i_target,
+ const IT i_setting,
+ const FFDC i_ffdc_code,
+ IT (&o_data)[X])
+{
+ const size_t l_dimm_index = mss::index(i_target);
+
+ FAPI_ASSERT( l_dimm_index < X,
+ fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
+ .set_INDEX(l_dimm_index)
+ .set_LIST_SIZE(X)
+ .set_FUNCTION(i_ffdc_code)
+ .set_TARGET(i_target),
+ "Dimm index (%d) was larger than max (%d) on %s",
+ l_dimm_index,
+ X,
+ mss::spd::c_str(i_target) );
+
+ FAPI_DBG("Updating data[%d] with %d for %s", l_dimm_index, i_setting, spd::c_str(i_target));
+ o_data[l_dimm_index] = i_setting;
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to update the structure that holds attr data
+/// @tparam T the FAPI2 TargetType
/// @tparam IT Input data type
/// @tparam FFDC type
/// @tparam OT Output data type
@@ -386,39 +403,18 @@ inline fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target,
{
const auto l_attr_target = mss::find_target<TT::TARGET_TYPE>(i_target);
typename TT::attr_type l_attr_list = {};
- FAPI_TRY( TT::get_attr(l_attr_target, l_attr_list) );
- FAPI_TRY( update_data(i_target, i_setting, TT::FFDC_CODE, l_attr_list) );
- FAPI_TRY( TT::set_attr(l_attr_target, l_attr_list) );
+ FAPI_TRY( TT::get_attr(l_attr_target, l_attr_list),
+ "Failed get_attr() for %s", spd::c_str(i_target) );
-fapi_try_exit:
- return fapi2::current_err;
-}
+ FAPI_TRY( update_data(i_target, i_setting, TT::FFDC_CODE, l_attr_list),
+ "Failed update_data for %s", spd::c_str(i_target) );
-///
-/// @brief Helper function to get the target associated with generic attribute setting
-/// @param[in] i_target
-/// return a fapi2 MEM_PORT target
-///
-static inline fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> get_attr_target(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&
- i_target)
-{
- return mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(i_target);
-}
+ FAPI_TRY( TT::set_attr(l_attr_target, l_attr_list),
+ "Failed set_attr() for %s", spd::c_str(i_target) );
-///
-/// @brief Helper function to get the target associated with generic attribute setting
-/// @param[in] i_target
-/// return a fapi2 MEM_PORT target
-///
-inline fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> get_attr_target(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
- i_target)
-{
- // Explorer has only one MEM_PORT per OCMB, so we are looking for the 0th pos relative to the OCMB
- // Will need to update to take into account a mem_channel index in VPDinfo if we ever support this.
- // Per FW, for the DDIMM case we can't support unique settings per channel because the SPD
- // doesn't know about anything outside of the DDIMM itself.
- return mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target)[0];
+fapi_try_exit:
+ return fapi2::current_err;
}
///
@@ -444,148 +440,22 @@ inline fapi2::ReturnCode set_field(const DT& i_data,
// Get the attribute data in its entirety
typename TT::attr_type l_attr_list = {};
- FAPI_TRY( TT::get_attr(l_attr_target, l_attr_list) );
+ FAPI_TRY( TT::get_attr(l_attr_target, l_attr_list),
+ "Failed get_attr()");
// Update the portion of interest (can vary per dimm and/or rank)
- FAPI_TRY( update_data(i_data, i_setting, TT::FFDC_CODE, l_attr_list) );
+ FAPI_TRY( update_data(i_data, i_setting, TT::FFDC_CODE, l_attr_list),
+ "Failed update_data()");
// Set the contents back to the attribute
- FAPI_TRY( TT::set_attr(l_attr_target, l_attr_list) );
+ FAPI_TRY( TT::set_attr(l_attr_target, l_attr_list),
+ "Failed set_attr()");
fapi_try_exit:
return fapi2::current_err;
}
///
-/// @brief Template recursive algorithm for setting attrs
-/// @class attr_engine
-/// @tparam ET enum type - conceptually a list of attrs to set
-/// @tparam F enum value - the specific attr value from ET to set
-/// @tparam TT defaulted to attrEngineTraits<ET, F>
-/// @tparam V defaulted to void (dispatch tag)
-///
-template < typename ET,
- ET F,
- typename TT = mss::attrEngineTraits<ET, F>,
- typename V = void >
-struct attr_engine
-{
- ///
- /// @brief Sets attributes fields F in ET
- /// @tparam T the fapi2 target type
- /// @param[in] i_target the fapi2 target
- /// @return FAPI2_RC_SUCCESS iff oka
- ///
- template < fapi2::TargetType T >
- static fapi2::ReturnCode single_set(const fapi2::Target<T>& i_target)
- {
- typename TT::attr_integral_type l_value = 0;
- FAPI_TRY( TT::get_value_to_set(i_target, l_value) );
-
- FAPI_TRY( set_field<TT>(i_target, l_value) );
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
- /// @brief Sets attributes fields F in ET
- /// @tparam DT the data type
- /// @param[in] i_data the data (efd_decoder, spd_facade, etc.)
- /// @return FAPI2_RC_SUCCESS iff ok
- ///
- template < typename DT >
- static fapi2::ReturnCode single_set(const DT& i_data)
- {
- typename TT::attr_integral_type l_value = 0;
- FAPI_TRY( TT::get_value_to_set(i_data, l_value) );
-
- FAPI_TRY( set_field<TT>(i_data, l_value) );
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
- /// @brief Sets attributes fields F in ET
- /// @tparam DT the data type
- /// @param[in] i_data the data (efd_decoder, spd_facade, etc.)
- /// @return FAPI2_RC_SUCCESS iff ok
- ///
- template < typename DT >
- static fapi2::ReturnCode set(const DT& i_data)
- {
- FAPI_TRY( (attr_engine<ET, F>::single_set(i_data)) );
-
- // Compiler isn't smart enough to deduce F - 1u (decrementing the enum values by 1)
- // Cast needed to help the compiler deduce this value is an ET type
- // This does the recursive call to unroll a compile-time looping of a enum list of attrs to set
- FAPI_TRY( (attr_engine < ET, static_cast<ET>(F - 1u) >::set(i_data)) );
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
- /// @brief Sets attributes fields F in ET
- /// @tparam T the fapi2 target type
- /// @param[in] i_target the fapi2 target
- /// @return FAPI2_RC_SUCCESS iff ok
- ///
- template < fapi2::TargetType T >
- static fapi2::ReturnCode set(const fapi2::Target<T>& i_target)
- {
- FAPI_TRY( (attr_engine<ET, F>::single_set(i_target)) );
-
- // Compiler isn't smart enough to deduce F - 1u (decrementing the enum values by 1)
- // Cast needed to help the compiler deduce this value is an ET type
- // This does the recursive call to unroll a compile-time looping of a enum list of attrs to set
- FAPI_TRY( (attr_engine < ET, static_cast<ET>(F - 1u) >::set(i_target)) );
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-};
-
-///
-/// @brief Algorithm for setting SI attrs
-/// @class attr_engine
-/// @tparam ET enum type
-/// @tparam F enum value
-/// @note partial specialization when F == 0 (base case). Which is a NOP.
-///
-template < typename ET, ET F>
-struct attr_engine< ET,
- F,
- mss::attrEngineTraits<ET, F>,
- typename std::enable_if<0u == F>::type >
-{
- ///
- /// @brief Sets attributes fields F in ET
- /// @tparam T the fapi2 target type
- /// @param[in] i_target the fapi2 target
- /// @return FAPI2_RC_SUCCESS iff ok
- ///
- template < fapi2::TargetType T >
- static fapi2::ReturnCode set(const fapi2::Target<T>& i_target)
- {
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
- ///
- /// @brief Sets attributes fields F in ET
- /// @tparam DT the data type
- /// @param[in] i_data the data (efd_decoder, spd_facade, etc.)
- /// @return FAPI2_RC_SUCCESS iff ok
- ///
- template < typename DT >
- static fapi2::ReturnCode set(const DT& i_data)
- {
- return fapi2::FAPI2_RC_SUCCESS;
- }
-};
-
-///
/// @brief Return a DIMM's position from a fapi2 target
/// @tparam TT Traits associated with DIMM position (e.g. dimmPosTraits)
/// @tparam OT the output type
@@ -609,6 +479,39 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief Shift the bits of the SPD field to match the attribute format
+/// @param[in] i_value ODT field value from SPD
+/// @return ATTR formatted uint8_t
+///
+static inline uint8_t align_odt_field_to_attr(const uint8_t i_value)
+{
+ static constexpr uint8_t ODT2_OLD = 2;
+ static constexpr uint8_t ODT3_OLD = 3;
+ static constexpr uint8_t ODT2 = 4;
+ static constexpr uint8_t ODT3 = 5;
+
+ fapi2::buffer<uint8_t> l_value(i_value);
+ // Map to attribute bitmap
+ reverse(l_value);
+
+ // l_value currently looks like:
+ // XXYY0000
+ // ODT
+ // 0123----
+ //
+ // We need it to look like:
+ // XX00YY00
+ // 01--23--
+ l_value.writeBit<ODT2>(l_value.getBit<ODT2_OLD>());
+ l_value.writeBit<ODT3>(l_value.getBit<ODT3_OLD>());
+
+ l_value.clearBit<ODT2_OLD>();
+ l_value.clearBit<ODT3_OLD>();
+
+ return l_value();
+}
+
}// gen
}//mss
diff --git a/src/import/generic/memory/lib/ecc/ecc.H b/src/import/generic/memory/lib/ecc/ecc.H
index 37a3fc067..610d20489 100644
--- a/src/import/generic/memory/lib/ecc/ecc.H
+++ b/src/import/generic/memory/lib/ecc/ecc.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,759 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file ecc.H
+/// @brief Top level API for MSS ECC
+///
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_ECC_H_
+#define _MSS_ECC_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+#include <generic/memory/lib/ecc/galois.H>
+#include <generic/memory/lib/ecc/hw_mark_store.H>
+#include <generic/memory/lib/ecc/fw_mark_store.H>
+#include <generic/memory/lib/ecc/mainline_nce_trap.H>
+#include <generic/memory/lib/ecc/mainline_rce_trap.H>
+#include <generic/memory/lib/ecc/mainline_mpe_trap.H>
+#include <generic/memory/lib/ecc/mainline_ue_trap.H>
+#include <generic/memory/lib/ecc/mainline_aue_trap.H>
+#include <generic/memory/lib/ecc/mbs_error_vector_trap.H>
+#include <generic/memory/lib/ecc/maint_current_trap.H>
+#include <generic/memory/lib/ecc/read_error_count_regs.H>
+#include <generic/memory/lib/ecc/modal_symbol_count.H>
+#include <generic/memory/lib/ecc/mark_shadow_reg.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+///
+/// @brief Get Hardware Mark Store
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_rank the desired rank
+/// @param[out] o_galois the Galois code of the mark
+/// @param[out] o_confirmed true if the mark is a chipmark
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_hwms( const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ uint64_t& o_galois,
+ mss::states& o_confirmed )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::hwms::read(i_target, i_rank, l_buffer) );
+ mss::ecc::hwms::get_chipmark(l_buffer, o_galois);
+ mss::ecc::hwms::get_confirmed(l_buffer, o_confirmed);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Set Hardware Mark Store
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_rank the desired rank
+/// @param[in] i_galois the Galois code of the mark, or set to 0 to clear mark
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode set_hwms( const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_galois )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+ uint8_t l_symbol = 0;
+
+ // galois value of 0 means to clear the mark so only fill in fields if non-zero
+ if (i_galois != 0)
+ {
+ // check for valid Galois code
+ FAPI_TRY( mss::ecc::galois_to_symbol( (uint8_t)i_galois, l_symbol) );
+
+ mss::ecc::hwms::set_chipmark(l_buffer, i_galois);
+ mss::ecc::hwms::set_confirmed(l_buffer, mss::YES);
+ mss::ecc::hwms::set_exit_1(l_buffer, mss::YES);
+ }
+
+ FAPI_TRY( mss::ecc::hwms::write(i_target, i_rank, l_buffer) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Firmware Mark Store
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_rank the desired rank
+/// @param[out] o_galois the Galois code of the mark
+/// @param[out] o_type the type code of the mark
+/// @param[out] o_region the region code of the mark
+/// @param[out] o_address the starting address of the mark
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_fwms( const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ uint64_t& o_galois,
+ mss::ecc::fwms::mark_type& o_type,
+ mss::ecc::fwms::mark_region& o_region,
+ mss::mcbist::address& o_address )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::fwms::read(i_target, i_rank, l_buffer) );
+ mss::ecc::fwms::get_mark(l_buffer, o_galois);
+ mss::ecc::fwms::get_type(l_buffer, o_type);
+ mss::ecc::fwms::get_region(l_buffer, o_region);
+ mss::ecc::fwms::get_address(l_buffer, o_address);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Set Firmware Mark Store
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_rank the desired rank
+/// @param[in] i_galois the Galois code of the mark, or set to 0 to clear mark
+/// @param[in] i_type the type code of the mark
+/// @param[in] i_region the region code of the mark
+/// @param[in] i_address the starting address of the mark
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode set_fwms( const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_galois,
+ const mss::ecc::fwms::mark_type i_type,
+ const mss::ecc::fwms::mark_region i_region,
+ const mss::mcbist::address i_address )
+{
+ fapi2::buffer<uint64_t> l_buffer = 0;
+ uint8_t l_symbol = 0;
+
+ // galois value of 0 means to clear the mark so only fill in fields if non-zero
+ if (i_galois != 0)
+ {
+ // check for valid Galois code
+ FAPI_TRY( mss::ecc::galois_to_symbol( (uint8_t)i_galois, l_symbol) );
+
+ mss::ecc::fwms::set_mark(l_buffer, i_galois);
+ mss::ecc::fwms::set_type(l_buffer, i_type);
+ mss::ecc::fwms::set_region(l_buffer, i_region);
+ mss::ecc::fwms::set_address(l_buffer, i_address);
+ mss::ecc::fwms::set_exit_1(l_buffer, mss::YES);
+ }
+
+ FAPI_TRY( mss::ecc::fwms::write(i_target, i_rank, l_buffer) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Query Hardware Marks
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_marks vector of Galois codes of any marks set
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+/// @note no rank information is returned
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode get_hw_marks( const fapi2::Target<T>& i_target,
+ std::vector<uint64_t>& o_marks )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+ uint64_t l_galois = 0;
+ auto l_confirmed = mss::states::NO;
+
+ o_marks.clear();
+
+ for (uint64_t l_rank = 0; l_rank < TT::ECC_MAX_MRANK_PER_PORT; ++l_rank)
+ {
+ FAPI_TRY( get_hwms(i_target, l_rank, l_galois, l_confirmed) );
+
+ if (l_confirmed == mss::states::YES)
+ {
+ o_marks.push_back(l_galois);
+ }
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Query Firmware Marks
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_marks vector of Galois codes of any marks set
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+/// @note no rank information is returned
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode get_fw_marks( const fapi2::Target<T>& i_target,
+ std::vector<uint64_t>& o_marks )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+ uint64_t l_galois = 0;
+ auto l_type = mss::ecc::fwms::mark_type::CHIP;
+ auto l_region = mss::ecc::fwms::mark_region::UNIVERSAL;
+ mss::mcbist::address l_address;
+
+ o_marks.clear();
+
+ for (uint64_t l_rank = 0; l_rank < TT::ECC_MAX_MRANK_PER_PORT; ++l_rank)
+ {
+ FAPI_TRY( get_fwms(i_target, l_rank, l_galois, l_type, l_region, l_address) );
+
+ if (l_region != mss::ecc::fwms::mark_region::DISABLED)
+ {
+ o_marks.push_back(l_galois);
+ }
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Mainline NCE address traps
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_address the trap address of the last mainline nce
+/// @param[out] o_on_rce mss::YES if nce is part of an rce
+/// @param[out] o_is_tce mss::YES if nce is a tce
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_nce_addr_trap( const fapi2::Target<T>& i_target,
+ mss::mcbist::address& o_address,
+ mss::states& o_on_rce,
+ mss::states& o_is_tce )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::mainline_nce_trap::read(i_target, l_buffer) );
+ mss::ecc::mainline_nce_trap::get_address(l_buffer, o_address);
+ mss::ecc::mainline_nce_trap::get_nce_on_rce(l_buffer, o_on_rce);
+ mss::ecc::mainline_nce_trap::get_nce_is_tce(l_buffer, o_is_tce);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Mainline NCE error vector traps
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_galois the Galois code
+/// @param[out] o_magnitude the magnitude of the error
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_nce_error_vector_trap( const fapi2::Target<T>& i_target,
+ uint64_t& o_galois,
+ uint64_t& o_magnitude )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::mbs_error_vector_trap::read(i_target, l_buffer) );
+ mss::ecc::mbs_error_vector_trap::get_nce_galois(i_target, l_buffer, o_galois);
+ mss::ecc::mbs_error_vector_trap::get_nce_magnitude(i_target, l_buffer, o_magnitude);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Mainline TCE address traps
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_address the trap address of the last mainline nce
+/// @param[out] o_on_rce mss::YES if nce is part of an rce
+/// @param[out] o_is_tce mss::YES if nce is a tce
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_tce_addr_trap( const fapi2::Target<T>& i_target,
+ mss::mcbist::address& o_address,
+ mss::states& o_on_rce,
+ mss::states& o_is_tce )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::mainline_nce_trap::read(i_target, l_buffer) );
+ mss::ecc::mainline_nce_trap::get_address(l_buffer, o_address);
+ mss::ecc::mainline_nce_trap::get_nce_on_rce(l_buffer, o_on_rce);
+ mss::ecc::mainline_nce_trap::get_nce_is_tce(l_buffer, o_is_tce);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Mainline TCE error vector traps
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_nce_galois the Galois code
+/// @param[out] o_nce_magnitude the magnitude of the error
+/// @param[out] o_tce_galois the Galois code
+/// @param[out] o_tce_magnitude the magnitude of the error
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_tce_error_vector_trap( const fapi2::Target<T>& i_target,
+ uint64_t& o_nce_galois,
+ uint64_t& o_nce_magnitude,
+ uint64_t& o_tce_galois,
+ uint64_t& o_tce_magnitude )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::mbs_error_vector_trap::read(i_target, l_buffer) );
+ mss::ecc::mbs_error_vector_trap::get_nce_galois(i_target, l_buffer, o_nce_galois);
+ mss::ecc::mbs_error_vector_trap::get_nce_magnitude(i_target, l_buffer, o_nce_magnitude);
+ mss::ecc::mbs_error_vector_trap::get_tce_galois(i_target, l_buffer, o_tce_galois);
+ mss::ecc::mbs_error_vector_trap::get_tce_magnitude(i_target, l_buffer, o_tce_magnitude);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Mainline MPE address traps
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_address the trap address of the last mainline mpe
+/// @param[out] o_on_rce mss::YES if mpe is part of an rce
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_mpe_addr_trap( const fapi2::Target<T>& i_target,
+ mss::mcbist::address& o_address,
+ mss::states& o_on_rce )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::mainline_mpe_trap::read(i_target, l_buffer) );
+ mss::ecc::mainline_mpe_trap::get_address(l_buffer, o_address);
+ mss::ecc::mainline_mpe_trap::get_mpe_on_rce(l_buffer, o_on_rce);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Mainline RCE address traps
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_address the trap address of the last mainline rce
+/// @param[out] o_nce_on_rce mss::YES if nce is part of an rce
+/// @param[out] o_tce_on_rce mss::YES if tce is part of an rce
+/// @param[out] o_mpe_on_rce mss::YES if mpe is part of an rce
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_rce_addr_trap( const fapi2::Target<T>& i_target,
+ mss::mcbist::address& o_address,
+ mss::states& o_nce_on_rce,
+ mss::states& o_tce_on_rce,
+ mss::states& o_mpe_on_rce )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::mainline_rce_trap::read(i_target, l_buffer) );
+ mss::ecc::mainline_rce_trap::get_address(l_buffer, o_address);
+
+ FAPI_TRY( mss::ecc::mainline_nce_trap::read(i_target, l_buffer) );
+ mss::ecc::mainline_nce_trap::get_nce_on_rce(l_buffer, o_nce_on_rce);
+ mss::ecc::mainline_nce_trap::get_nce_is_tce(l_buffer, o_tce_on_rce);
+
+ FAPI_TRY( mss::ecc::mainline_mpe_trap::read(i_target, l_buffer) );
+ mss::ecc::mainline_mpe_trap::get_mpe_on_rce(l_buffer, o_mpe_on_rce);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Mainline UE address traps
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_address the trap address of the last mainline ue
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_ue_addr_trap( const fapi2::Target<T>& i_target,
+ mss::mcbist::address& o_address )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::mainline_ue_trap::read(i_target, l_buffer) );
+ mss::ecc::mainline_ue_trap::get_address(l_buffer, o_address);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Mainline AUE address traps
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_address the trap address of the last mainline aue
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_aue_addr_trap( const fapi2::Target<T>& i_target,
+ mss::mcbist::address& o_address )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::mainline_aue_trap::read(i_target, l_buffer) );
+ mss::ecc::mainline_aue_trap::get_address(l_buffer, o_address);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get IMPE address traps
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_chipmark the mark location (Galois code) of the last mark placed
+/// @param[out] o_rank the rank of the last mark placed
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_impe_addr_trap( const fapi2::Target<T>& i_target,
+ uint64_t& o_chipmark,
+ uint64_t& o_rank )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::mark_shadow_reg::read(i_target, l_buffer) );
+ mss::ecc::mark_shadow_reg::get_chipmark(l_buffer, o_chipmark);
+ mss::ecc::mark_shadow_reg::get_rank(l_buffer, o_rank);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Maint Current address traps
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_address the last address executed
+/// @param[out] o_port_trap port value if MCBCFGQ_cfg_current_addr_trap_update_dis == 0
+/// @param[out] o_dimm_trap dimm value if MCBCFGQ_cfg_current_addr_trap_update_dis == 0
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_maint_current_addr_trap( const fapi2::Target<T>& i_target,
+ mss::mcbist::address& o_address,
+ uint64_t& o_port_trap,
+ uint64_t& o_dimm_trap )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::maint_current_trap::read(i_target, l_buffer) );
+ mss::ecc::maint_current_trap::get_address(l_buffer, o_address);
+ mss::ecc::maint_current_trap::get_port(l_buffer, o_port_trap);
+ mss::ecc::maint_current_trap::get_dimm(l_buffer, o_dimm_trap);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Per Symbol Error Counts
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_error_counts vector of symbol error counts
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode get_per_symbol_error_counts( const fapi2::Target<T>& i_target,
+ std::vector<uint64_t>& o_error_counts )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+ uint64_t l_count = 0;
+ o_error_counts.clear();
+
+ for (uint64_t l_index = 0; l_index < TT::NUM_MBSSYM_REGS; ++l_index)
+ {
+ FAPI_TRY( mss::ecc::modal_symbol_count::read(i_target, l_index, l_buffer) );
+
+ for (uint64_t l_symbol = 0; l_symbol < TT::MODAL_SYMBOL_COUNTERS_PER_REG; ++l_symbol)
+ {
+ l_count = 0;
+ mss::ecc::modal_symbol_count::get_count(l_buffer, l_symbol, l_count);
+ o_error_counts.push_back(l_count);
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Intermittent NCE error count
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_count count of intermittent NCE events
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_intermittent_nce_count( const fapi2::Target<T>& i_target,
+ uint64_t& o_count )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::read_error_count_reg0::read(i_target, l_buffer) );
+ mss::ecc::read_error_count_reg0::get_intermittent_ce_count(l_buffer, o_count);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Soft NCE error count
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_count count of soft NCE events
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_soft_nce_count( const fapi2::Target<T>& i_target,
+ uint64_t& o_count )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::read_error_count_reg0::read(i_target, l_buffer) );
+ mss::ecc::read_error_count_reg0::get_soft_ce_count(l_buffer, o_count);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Hard NCE error count
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_count count of hard NCE events
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_hard_nce_count( const fapi2::Target<T>& i_target,
+ uint64_t& o_count )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::read_error_count_reg0::read(i_target, l_buffer) );
+ mss::ecc::read_error_count_reg0::get_hard_ce_count(l_buffer, o_count);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Intermittent MCE error count
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_count count of intermittent MCE events
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_intermittent_mce_count( const fapi2::Target<T>& i_target,
+ uint64_t& o_count )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::read_error_count_reg0::read(i_target, l_buffer) );
+ mss::ecc::read_error_count_reg0::get_intermittent_mce_count(l_buffer, o_count);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Soft MCE error count
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_count count of soft MCE events
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_soft_mce_count( const fapi2::Target<T>& i_target,
+ uint64_t& o_count )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::read_error_count_reg0::read(i_target, l_buffer) );
+ mss::ecc::read_error_count_reg0::get_soft_mce_count(l_buffer, o_count);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get Hard MCE error count
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_count count of hard MCE events
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_hard_mce_count( const fapi2::Target<T>& i_target,
+ uint64_t& o_count )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::read_error_count_reg1::read(i_target, l_buffer) );
+ mss::ecc::read_error_count_reg1::get_hard_mce_count(l_buffer, o_count);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get ICE (IMPE) error count
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_count count of ICE events
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_ice_count( const fapi2::Target<T>& i_target,
+ uint64_t& o_count )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::read_error_count_reg1::read(i_target, l_buffer) );
+ mss::ecc::read_error_count_reg1::get_ice_count(l_buffer, o_count);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get UE error count
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_count count of UE events
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_ue_count( const fapi2::Target<T>& i_target,
+ uint64_t& o_count )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::read_error_count_reg1::read(i_target, l_buffer) );
+ mss::ecc::read_error_count_reg1::get_ue_count(l_buffer, o_count);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get AUE error count
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_count count of AUE events
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_aue_count( const fapi2::Target<T>& i_target,
+ uint64_t& o_count )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::read_error_count_reg1::read(i_target, l_buffer) );
+ mss::ecc::read_error_count_reg1::get_aue_count(l_buffer, o_count);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get RCE error count
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_count count of RCE events
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_rce_count( const fapi2::Target<T>& i_target,
+ uint64_t& o_count )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::read_error_count_reg1::read(i_target, l_buffer) );
+ mss::ecc::read_error_count_reg1::get_rce_count(l_buffer, o_count);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Get MCE symbol count
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @param[out] o_symbol0_count count of symbol 0 errors
+/// @param[out] o_symbol1_count count of symbol 1 errors
+/// @param[out] o_symbol2_count count of symbol 2 errors
+/// @param[out] o_symbol3_count count of symbol 3 errors
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode get_mce_symbol_count( const fapi2::Target<T>& i_target,
+ uint64_t& o_symbol0_count,
+ uint64_t& o_symbol1_count,
+ uint64_t& o_symbol2_count,
+ uint64_t& o_symbol3_count )
+{
+ fapi2::buffer<uint64_t> l_buffer;
+
+ FAPI_TRY( mss::ecc::mark_symbol_count_reg::read(i_target, l_buffer) );
+ mss::ecc::mark_symbol_count_reg::get_symbol0_count(l_buffer, o_symbol0_count);
+ mss::ecc::mark_symbol_count_reg::get_symbol1_count(l_buffer, o_symbol1_count);
+ mss::ecc::mark_symbol_count_reg::get_symbol2_count(l_buffer, o_symbol2_count);
+ mss::ecc::mark_symbol_count_reg::get_symbol3_count(l_buffer, o_symbol3_count);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/ecc/ecc_traits.H b/src/import/generic/memory/lib/ecc/ecc_traits.H
index 81d264ff7..8018c42ae 100644
--- a/src/import/generic/memory/lib/ecc/ecc_traits.H
+++ b/src/import/generic/memory/lib/ecc/ecc_traits.H
@@ -22,3 +22,33 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file ecc_traits.H
+/// @brief Traits class for the MC ECC syndrome registers
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_ECC_TRAITS_H_
+#define _MSS_ECC_TRAITS_H_
+
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
+namespace mss
+{
+
+///
+/// @class eccTraits
+/// @brief a collection of traits associated with the MC ECC interface
+/// @tparam T fapi2::TargetType representing the memory controller
+///
+template< mss::mc_type MC, fapi2::TargetType T >
+class eccTraits;
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/ecc/fw_mark_store.H b/src/import/generic/memory/lib/ecc/fw_mark_store.H
index e1fb56927..28e8668fb 100644
--- a/src/import/generic/memory/lib/ecc/fw_mark_store.H
+++ b/src/import/generic/memory/lib/ecc/fw_mark_store.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,597 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file fw_mark_store.H
+/// @brief Subroutines for the MC firmware mark store registers
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_FW_MARK_STORE_H_
+#define _MSS_FW_MARK_STORE_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_fwms_address.H>
+#include <generic/memory/lib/utils/scom.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace fwms
+{
+
+///
+/// @brief chip mark type enums
+///
+enum mark_type
+{
+ SYMBOL = 1,
+ CHIP = 0
+};
+
+///
+/// @brief Chip Mark Region. Used for region field values in the FWMS regs
+///
+enum mark_region
+{
+ DISABLED = 0b000,
+ RESERVED = 0b001,
+ BANK = 0b010,
+ BANKGROUP = 0b011,
+ SRANK = 0b100,
+ MRANK = 0b101,
+ DIMM = 0b110,
+ UNIVERSAL = 0b111
+};
+
+///
+/// @brief Read Firmware Mark Store (FWMS) register
+/// @tparam R master rank number
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< uint64_t R, fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode read_rank( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ static_assert((R < TT::ECC_MAX_MRANK_PER_PORT), "Master rank index failed range check");
+ FAPI_TRY( mss::getScom(i_target, (TT::FIRMWARE_MS0_REG + R), o_data) );
+ FAPI_INF("read_rank<%d>: 0x%016lx", R, o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Read Firmware Mark Store (FWMS) rank 0 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank0( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<0>(i_target, o_data) );
+}
+
+///
+/// @brief Read Firmware Mark Store (FWMS) rank 1 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank1( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<1>(i_target, o_data) );
+}
+
+///
+/// @brief Read Firmware Mark Store (FWMS) rank 2 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank2( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<2>(i_target, o_data) );
+}
+
+///
+/// @brief Read Firmware Mark Store (FWMS) rank 3 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank3( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<3>(i_target, o_data) );
+}
+
+///
+/// @brief Read Firmware Mark Store (FWMS) rank 4 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank4( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<4>(i_target, o_data) );
+}
+
+///
+/// @brief Read Firmware Mark Store (FWMS) rank 5 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank5( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<5>(i_target, o_data) );
+}
+
+///
+/// @brief Read Firmware Mark Store (FWMS) rank 6 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank6( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<6>(i_target, o_data) );
+}
+
+///
+/// @brief Read Firmware Mark Store (FWMS) rank 7 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank7( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<7>(i_target, o_data) );
+}
+
+///
+/// @brief Read Firmware Mark Store (FWMS) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_rank the master rank index
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ fapi2::buffer<uint64_t>& o_data )
+{
+ switch (i_rank)
+ {
+ case(0):
+ return ( read_rank0(i_target, o_data) );
+
+ case(1):
+ return ( read_rank1(i_target, o_data) );
+
+ case(2):
+ return ( read_rank2(i_target, o_data) );
+
+ case(3):
+ return ( read_rank3(i_target, o_data) );
+
+ case(4):
+ return ( read_rank4(i_target, o_data) );
+
+ case(5):
+ return ( read_rank5(i_target, o_data) );
+
+ case(6):
+ return ( read_rank6(i_target, o_data) );
+
+ case(7):
+ return ( read_rank7(i_target, o_data) );
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_RANK_PASSED()
+ .set_RANK(i_rank)
+ .set_TARGET(i_target)
+ .set_FUNCTION(FWMS_READ),
+ "%s Invalid rank passed to fwms::ecc::read (%d)",
+ mss::c_str(i_target),
+ i_rank);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write Firmware Mark Store (FWMS) register
+/// @tparam R master rank number
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< uint64_t R, fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode write_rank( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ static_assert((R < TT::ECC_MAX_MRANK_PER_PORT), "Master rank index failed range check");
+ FAPI_TRY( mss::putScom(i_target, (TT::FIRMWARE_MS0_REG + R), i_data) );
+ FAPI_DBG("write_rank<%d>: 0x%016lx", R, i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write Firmware Mark Store (FWMS) rank 0 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank0( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<0>(i_target, i_data) );
+}
+
+///
+/// @brief Write Firmware Mark Store (FWMS) rank 1 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank1( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<1>(i_target, i_data) );
+}
+
+///
+/// @brief Write Firmware Mark Store (FWMS) rank 2 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank2( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<2>(i_target, i_data) );
+}
+
+///
+/// @brief Write Firmware Mark Store (FWMS) rank 3 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank3( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<3>(i_target, i_data) );
+}
+
+///
+/// @brief Write Firmware Mark Store (FWMS) rank 4 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank4( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<4>(i_target, i_data) );
+}
+
+///
+/// @brief Write Firmware Mark Store (FWMS) rank 5 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank5( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<5>(i_target, i_data) );
+}
+
+///
+/// @brief Write Firmware Mark Store (FWMS) rank 6 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank6( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<6>(i_target, i_data) );
+}
+
+///
+/// @brief Write Firmware Mark Store (FWMS) rank 7 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank7( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<7>(i_target, i_data) );
+}
+
+///
+/// @brief Write Firmware Mark Store (FWMS) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_rank the master rank index
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const fapi2::buffer<uint64_t>& i_data )
+{
+ switch (i_rank)
+ {
+ case(0):
+ return ( write_rank0(i_target, i_data) );
+
+ case(1):
+ return ( write_rank1(i_target, i_data) );
+
+ case(2):
+ return ( write_rank2(i_target, i_data) );
+
+ case(3):
+ return ( write_rank3(i_target, i_data) );
+
+ case(4):
+ return ( write_rank4(i_target, i_data) );
+
+ case(5):
+ return ( write_rank5(i_target, i_data) );
+
+ case(6):
+ return ( write_rank6(i_target, i_data) );
+
+ case(7):
+ return ( write_rank7(i_target, i_data) );
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_RANK_PASSED()
+ .set_RANK(i_rank)
+ .set_TARGET(i_target)
+ .set_FUNCTION(FWMS_WRITE),
+ "%s Invalid rank passed to fwms::ecc::write (%d)",
+ mss::c_str(i_target),
+ i_rank);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set_mark
+/// @tparam T fapi2 Target Type defaults to defaulted port in mc const
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note FWMS0_MARK: mark (Galois field code)
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_mark( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::FIRMWARE_MS_MARK, TT::FIRMWARE_MS_MARK_LEN>(i_value);
+ FAPI_DBG("set_mark: 0x%02lx", i_value);
+}
+
+///
+/// @brief get_mark
+/// @tparam T fapi2 Target Type defaults to defaulted port in mc const
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note FWMS0_MARK: mark (Galois field code)
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_mark( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::FIRMWARE_MS_MARK, TT::FIRMWARE_MS_MARK_LEN>(o_value);
+ FAPI_INF("get_mark: 0x%02lx", o_value);
+}
+
+///
+/// @brief set_type
+/// @tparam T fapi2 Target Type defaults to defaulted port in mc const
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note FWMS0_TYPE: mark type
+/// @note Dial enums:
+/// @note SYMBOL=>0b1
+/// @note CHIP=>0b0
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_type( fapi2::buffer<uint64_t>& io_data, const mark_type i_value )
+{
+ io_data.writeBit<TT::FIRMWARE_MS_TYPE>(i_value);
+ FAPI_INF("set_type: 0x%01lx", i_value);
+}
+
+///
+/// @brief get_type
+/// @tparam T fapi2 Target Type defaults to defaulted port in mc const
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note FWMS0_TYPE: mark type
+/// @note Dial enums:
+/// @note SYMBOL=>0b1
+/// @note CHIP=>0b0
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_type( const fapi2::buffer<uint64_t>& i_data, mark_type& o_value )
+{
+ o_value = mark_type(i_data.getBit<TT::FIRMWARE_MS_TYPE>());
+ FAPI_INF("get_type: 0x%01lx", o_value);
+}
+
+///
+/// @brief set_region
+/// @tparam T fapi2 Target Type defaults to defaulted port in mc const
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note FWMS0_REGION: Selects mark region (address range to which mark applies)
+/// @note Dial enums:
+/// @note DISABLED=>0b000
+/// @note RESERVED=>0b001
+/// @note BANK=>0b010
+/// @note BANKGROUP=>0b011
+/// @note SRANK=>0b100
+/// @note MRANK=>0b101
+/// @note DIMM=>0b110
+/// @note UNIVERSAL=>0b111
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_region( fapi2::buffer<uint64_t>& io_data, const mark_region i_value )
+{
+ io_data.insertFromRight<TT::FIRMWARE_MS_REGION, TT::FIRMWARE_MS_REGION_LEN>(i_value);
+ FAPI_INF("set_region: 0x%02lx", i_value);
+}
+
+///
+/// @brief get_region
+/// @tparam T fapi2 Target Type defaults to defaulted port in mc const
+/// @tparam TT traits type defaults to eccTraits<T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note FWMS0_REGION: Selects mark region (address range to which mark applies)
+/// @note Dial enums:
+/// @note DISABLED=>0b000
+/// @note RESERVED=>0b001
+/// @note BANK=>0b010
+/// @note BANKGROUP=>0b011
+/// @note SRANK=>0b100
+/// @note MRANK=>0b101
+/// @note DIMM=>0b110
+/// @note UNIVERSAL=>0b111
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_region( const fapi2::buffer<uint64_t>& i_data, mark_region& o_value )
+{
+ uint64_t l_temp = 0;
+ i_data.extractToRight<TT::FIRMWARE_MS_REGION, TT::FIRMWARE_MS_REGION_LEN>(l_temp);
+ o_value = mark_region(l_temp);
+ FAPI_INF("get_region: 0x%02lx", o_value);
+}
+
+///
+/// @brief set_address
+/// @tparam T fapi2 Target Type defaults to defaulted port in mc const
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_address mcbist::address form of address field
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
+{
+ // construct fwms::address from mcbist::address
+ const auto l_addr = address<MC, T, TT>(i_address);
+ io_data.insert<TT::FIRMWARE_MS_ADDRESS, TT::FIRMWARE_MS_ADDRESS_LEN, TT::FIRMWARE_MS_ADDRESS>(l_addr);
+ FAPI_INF("set_address: 0x%016lx", uint64_t(l_addr));
+}
+
+///
+/// @brief get_address
+/// @tparam T fapi2 Target Type defaults to defaulted port in mc const
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_address mcbist::address form of address field
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
+{
+ // construct fwms::address from i_data
+ const auto l_addr = mss::ecc::fwms::address<MC, T, TT>(uint64_t(i_data));
+ // construct mcbist::address from fwms::address
+ o_address = l_addr.operator mss::mcbist::address();
+ FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
+}
+
+///
+/// @brief set_exit_1
+/// @tparam T fapi2 Target Type defaults to defaulted port in mc const
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_state mss::YES or mss::NO - desired state
+/// @note FWMS0_EXIT_1: When set, bypass-enabled reads using this mark will use exit 1
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_exit_1( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
+{
+ io_data.writeBit<TT::FIRMWARE_MS_EXIT1>(i_state);
+ FAPI_INF("set_exit_1: 0x%01lx", i_state);
+}
+
+///
+/// @brief get_exit_1
+/// @tparam T fapi2 Target Type defaults to defaulted port in mc const
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_state mss::YES or mss::NO - representing the state of the field
+/// @note FWMS0_EXIT_1: When set, bypass-enabled reads using this mark will use exit 1
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_exit_1( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state )
+{
+ o_state = (i_data.getBit<TT::FIRMWARE_MS_EXIT1>() == false) ? mss::NO : mss::YES;
+ FAPI_INF("get_exit_1: 0x%01lx", o_state);
+}
+
+} // close namespace fwms
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/ecc/galois.H b/src/import/generic/memory/lib/ecc/galois.H
index 951839c7a..b795e9897 100644
--- a/src/import/generic/memory/lib/ecc/galois.H
+++ b/src/import/generic/memory/lib/ecc/galois.H
@@ -22,3 +22,169 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file galois.H
+/// @brief Translate ECC mark Galois codes to symbol and DQ
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_ECC_GALOIS_H_
+#define _MSS_ECC_GALOIS_H_
+
+#include <generic/memory/lib/ecc/ecc_traits.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+///
+/// @brief Return symbol value from a given Galois code
+/// @tparam T fapi2 Target Type defaults to the default set in mc const file
+/// @tparam TT traits type defaults to eccTraits<T>
+/// @param[in] i_galois the Galois code
+/// @param[out] o_symbol symbol value represented by given Galois code
+/// @return FAPI2_RC_SUCCESS iff all is ok
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+fapi2::ReturnCode galois_to_symbol( const uint8_t i_galois, uint8_t& o_symbol )
+{
+ const auto& l_p = std::find(TT::symbol2galois, (TT::symbol2galois + TT::ECC_MAX_SYMBOLS), i_galois);
+
+ FAPI_ASSERT( l_p != (TT::symbol2galois + TT::ECC_MAX_SYMBOLS),
+ fapi2::MSS_INVALID_GALOIS_TO_SYMBOL()
+ .set_GALOIS(i_galois),
+ "Invalid Galois code: 0x%02x",
+ i_galois);
+
+ o_symbol = (l_p - TT::symbol2galois);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Return Galois code from a given symbol value
+/// @tparam T fapi2 Target Type defaults to the default set in mc const file
+/// @tparam TT traits type defaults to eccTraits<T>
+/// @param[in] i_symbol the symbol value
+/// @param[out] o_galois Galois code represented by given symbol
+/// @return FAPI2_RC_SUCCESS iff all is ok
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+fapi2::ReturnCode symbol_to_galois( const uint8_t i_symbol, uint8_t& o_galois )
+{
+ FAPI_ASSERT( i_symbol < TT::ECC_MAX_SYMBOLS,
+ fapi2::MSS_INVALID_SYMBOL_FOR_GALOIS()
+ .set_SYMBOL(i_symbol),
+ "Invalid symbol: %d",
+ i_symbol);
+
+ o_galois = TT::symbol2galois[i_symbol];
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Return symbol value from a given DQ index
+/// @tparam T fapi2 Target Type defaults to the default set in mc const file
+/// @tparam TT traits type defaults to eccTraits<T>
+/// @param[in] i_dq the DQ index
+/// @param[out] o_symbol symbol value represented by given DQ index
+/// @return FAPI2_RC_SUCCESS iff all is ok
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+fapi2::ReturnCode dq_to_symbol( const uint8_t i_dq, uint8_t& o_symbol )
+{
+ const auto& l_p = std::find(TT::symbol2dq, (TT::symbol2dq + TT::ECC_MAX_DQ_BITS), i_dq);
+
+ FAPI_ASSERT( l_p != (TT::symbol2dq + TT::ECC_MAX_DQ_BITS),
+ fapi2::MSS_INVALID_DQ_TO_SYMBOL()
+ .set_DQ(i_dq),
+ "Invalid DQ index: %d",
+ i_dq);
+
+ o_symbol = (l_p - TT::symbol2dq);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Return DQ index from a given symbol value
+/// @tparam T fapi2 Target Type defaults to the default set in mc const file
+/// @tparam TT traits type defaults to eccTraits<T>
+/// @param[in] i_symbol the symbol value
+/// @param[out] o_dq DQ index represented by given symbol value
+/// @return FAPI2_RC_SUCCESS iff all is ok
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+fapi2::ReturnCode symbol_to_dq( const uint8_t i_symbol, uint8_t& o_dq )
+{
+ FAPI_ASSERT( i_symbol < TT::ECC_MAX_SYMBOLS,
+ fapi2::MSS_INVALID_SYMBOL_TO_DQ()
+ .set_SYMBOL(i_symbol),
+ "symbol_to_dq: invalid symbol: %d",
+ i_symbol);
+
+ o_dq = TT::symbol2dq[i_symbol];
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Return DQ index from a given Galois code
+/// @tparam T fapi2 Target Type defaults to the default set in mc const file
+/// @tparam TT traits type defaults to eccTraits<T>
+/// @param[in] i_galois the Galois code
+/// @param[out] o_dq DQ index represented by given Galois code
+/// @return FAPI2_RC_SUCCESS iff all is ok
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+fapi2::ReturnCode galois_to_dq( const uint8_t i_galois, uint8_t& o_dq )
+{
+ uint8_t l_symbol = 0;
+
+ FAPI_TRY( galois_to_symbol<T>(i_galois, l_symbol), "Failed galois_to_symbol");
+ FAPI_TRY( symbol_to_dq<T>(l_symbol, o_dq), "Failed symbol_to_dq" );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Return Galois code from a given DQ index
+/// @tparam T fapi2 Target Type defaults to the default set in mc const file
+/// @tparam TT traits type defaults to eccTraits<T>
+/// @param[in] i_dq the DQ index
+/// @param[out] o_galois Galois code represented by given symbol
+/// @return FAPI2_RC_SUCCESS iff all is ok
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+fapi2::ReturnCode dq_to_galois( const uint8_t i_dq, uint8_t& o_galois )
+{
+ uint8_t l_symbol = 0;
+
+ FAPI_TRY( mss::ecc::dq_to_symbol<T>(i_dq, l_symbol), "Failed dq_to_symbol");
+ FAPI_TRY( mss::ecc::symbol_to_galois<T>(l_symbol, o_galois) , "Failed symbol_to_galois" );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // close namespace ecc
+
+} // close namespace mss
+#endif
diff --git a/src/import/generic/memory/lib/ecc/hw_mark_store.H b/src/import/generic/memory/lib/ecc/hw_mark_store.H
index 2200e9aee..bc0ccccb8 100644
--- a/src/import/generic/memory/lib/ecc/hw_mark_store.H
+++ b/src/import/generic/memory/lib/ecc/hw_mark_store.H
@@ -22,3 +22,485 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file hw_mark_store.H
+/// @brief Subroutines for the MC hardware mark store registers
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_HW_MARK_STORE_H_
+#define _MSS_HW_MARK_STORE_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+#include <generic/memory/lib/utils/scom.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace hwms
+{
+
+///
+/// @brief Read Hardware Mark Store (HWMS) register
+/// @tparam R master rank number
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< uint64_t R, fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode read_rank( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ static_assert((R < TT::ECC_MAX_MRANK_PER_PORT), "Master rank index failed range check");
+ FAPI_TRY( mss::getScom(i_target, (TT::HARDWARE_MS0_REG + R), o_data) );
+ FAPI_INF("read_rank<%d>: 0x%016lx", R, o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Read Hardware Mark Store (HWMS) rank 0 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank0( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<0>(i_target, o_data) );
+}
+
+///
+/// @brief Read Hardware Mark Store (HWMS) rank 1 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank1( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<1>(i_target, o_data) );
+}
+
+///
+/// @brief Read Hardware Mark Store (HWMS) rank 2 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank2( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<2>(i_target, o_data) );
+}
+
+///
+/// @brief Read Hardware Mark Store (HWMS) rank 3 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank3( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<3>(i_target, o_data) );
+}
+
+///
+/// @brief Read Hardware Mark Store (HWMS) rank 4 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank4( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<4>(i_target, o_data) );
+}
+
+///
+/// @brief Read Hardware Mark Store (HWMS) rank 5 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank5( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<5>(i_target, o_data) );
+}
+
+///
+/// @brief Read Hardware Mark Store (HWMS) rank 6 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank6( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<6>(i_target, o_data) );
+}
+
+///
+/// @brief Read Hardware Mark Store (HWMS) rank 7 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_rank7( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_rank<7>(i_target, o_data) );
+}
+
+///
+/// @brief Read Hardware Mark Store (HWMS) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_rank the master rank index
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ fapi2::buffer<uint64_t>& o_data )
+{
+ switch (i_rank)
+ {
+ case(0):
+ return ( read_rank0(i_target, o_data) );
+
+ case(1):
+ return ( read_rank1(i_target, o_data) );
+
+ case(2):
+ return ( read_rank2(i_target, o_data) );
+
+ case(3):
+ return ( read_rank3(i_target, o_data) );
+
+ case(4):
+ return ( read_rank4(i_target, o_data) );
+
+ case(5):
+ return ( read_rank5(i_target, o_data) );
+
+ case(6):
+ return ( read_rank6(i_target, o_data) );
+
+ case(7):
+ return ( read_rank7(i_target, o_data) );
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_RANK_PASSED()
+ .set_RANK(i_rank)
+ .set_TARGET(i_target)
+ .set_FUNCTION(HWMS_READ),
+ "%s Invalid rank passed to fwms::ecc::hwms::read (%d)",
+ mss::c_str(i_target),
+ i_rank);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write Hardware Mark Store (HWMS) register
+/// @tparam R master rank number
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< uint64_t R, fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode write_rank( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ static_assert((R < TT::ECC_MAX_MRANK_PER_PORT), "Master rank index failed range check");
+ FAPI_TRY( mss::putScom(i_target, (TT::HARDWARE_MS0_REG + R), i_data) );
+ FAPI_INF("write_rank<%d>: 0x%016lx", R, i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write Hardware Mark Store (HWMS) rank 0 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank0( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<0>(i_target, i_data) );
+}
+
+///
+/// @brief Write Hardware Mark Store (HWMS) rank 1 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank1( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<1>(i_target, i_data) );
+}
+
+///
+/// @brief Write Hardware Mark Store (HWMS) rank 2 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank2( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<2>(i_target, i_data) );
+}
+
+///
+/// @brief Write Hardware Mark Store (HWMS) rank 3 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank3( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<3>(i_target, i_data) );
+}
+
+///
+/// @brief Write Hardware Mark Store (HWMS) rank 4 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank4( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<4>(i_target, i_data) );
+}
+
+///
+/// @brief Write Hardware Mark Store (HWMS) rank 5 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank5( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<5>(i_target, i_data) );
+}
+
+///
+/// @brief Write Hardware Mark Store (HWMS) rank 6 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank6( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<6>(i_target, i_data) );
+}
+
+///
+/// @brief Write Hardware Mark Store (HWMS) rank 7 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_rank7( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_rank<7>(i_target, i_data) );
+}
+
+///
+/// @brief Write Hardware Mark Store (HWMS) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_rank the master rank index
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const fapi2::buffer<uint64_t>& i_data )
+{
+ switch (i_rank)
+ {
+ case(0):
+ return ( write_rank0(i_target, i_data) );
+
+ case(1):
+ return ( write_rank1(i_target, i_data) );
+
+ case(2):
+ return ( write_rank2(i_target, i_data) );
+
+ case(3):
+ return ( write_rank3(i_target, i_data) );
+
+ case(4):
+ return ( write_rank4(i_target, i_data) );
+
+ case(5):
+ return ( write_rank5(i_target, i_data) );
+
+ case(6):
+ return ( write_rank6(i_target, i_data) );
+
+ case(7):
+ return ( write_rank7(i_target, i_data) );
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_RANK_PASSED()
+ .set_RANK(i_rank)
+ .set_TARGET(i_target)
+ .set_FUNCTION(HWMS_WRITE),
+ "%s Invalid rank passed to fwms::ecc::hwms::write(%d)",
+ mss::c_str(i_target),
+ i_rank);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set_chipmark
+/// @tparam T fapi2 Target Type defaults to the default set in mc const file
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note HWMS0_CHIPMARK: Hardware chipmark (Galois field code)
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_chipmark( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::HARDWARE_MS_CHIPMARK, TT::HARDWARE_MS_CHIPMARK_LEN>(i_value);
+ FAPI_INF("set_chipmark: 0x%02lx", i_value);
+}
+
+///
+/// @brief get_chipmark
+/// @tparam T fapi2 Target Type defaults to the default set in mc const file
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note HWMS0_CHIPMARK: Hardware chipmark (Galois field code)
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_chipmark( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::HARDWARE_MS_CHIPMARK, TT::HARDWARE_MS_CHIPMARK_LEN>(o_value);
+ FAPI_INF("get_chipmark: 0x%02lx", o_value);
+}
+
+///
+/// @brief set_confirmed
+/// @tparam T fapi2 Target Type defaults to the default set in mc const file
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_state mss::YES or mss::NO - desired state
+/// @note HWMS0_CONFIRMED: chipmark confirmed
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_confirmed( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
+{
+ io_data.writeBit<TT::HARDWARE_MS_CONFIRMED>(i_state);
+ FAPI_INF("set_confirmed: 0x%01lx", i_state);
+}
+
+///
+/// @brief get_confirmed
+/// @tparam T fapi2 Target Type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_state mss::YES or mss::NO - representing the state of the field
+/// @note HWMS0_CONFIRMED: chipmark confirmed
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_confirmed( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state )
+{
+ o_state = (i_data.getBit<TT::HARDWARE_MS_CONFIRMED>() == false) ? mss::NO : mss::YES;
+ FAPI_INF("get_confirmed: 0x%01lx", o_state);
+}
+
+///
+/// @brief set_exit_1
+/// @tparam T fapi2 Target Type defaults to the default set in mc const file
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_state mss::YES or mss::NO - desired state
+/// @note HWMS0_EXIT_1: When set, bypass-enabled reads using this mark will
+/// @note use exit 1; otherwise exit 0
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_exit_1( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
+{
+ io_data.writeBit<TT::HARDWARE_MS_EXIT1>(i_state);
+ FAPI_INF("set_exit_1: 0x%01lx", i_state);
+}
+
+///
+/// @brief get_exit_1
+/// @tparam T fapi2 Target Type defaults to the default set in mc const file
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_state mss::YES or mss::NO - representing the state of the field
+/// @note HWMS0_EXIT_1: When set, bypass-enabled reads using this mark will
+/// @note use exit 1; otherwise exit 0
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_exit_1( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state )
+{
+ o_state = (i_data.getBit<TT::HARDWARE_MS_EXIT1>() == false) ? mss::NO : mss::YES;
+ FAPI_INF("get_exit_1: 0x%01lx", o_state);
+}
+
+} // close namespace hwms
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/ecc/mainline_aue_trap.H b/src/import/generic/memory/lib/ecc/mainline_aue_trap.H
index 49a28287f..a69098d7e 100644
--- a/src/import/generic/memory/lib/ecc/mainline_aue_trap.H
+++ b/src/import/generic/memory/lib/ecc/mainline_aue_trap.H
@@ -22,3 +22,110 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mainline_aue_trap.H
+/// @brief Subroutines for the MC mainline aue address trap registers (MBAUER*Q)
+///
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_MAINLINE_AUE_TRAP_H_
+#define _MSS_MAINLINE_AUE_TRAP_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/scom.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace mainline_aue_trap
+{
+
+///
+/// @brief Read MBS Mainline AUE Address Trap (MBAUER*Q) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ const auto& l_mcbist_target = mss::find_target<DEFAULT_MC_TARGET>(i_target);
+ const auto& l_port = mss::relative_pos<DEFAULT_MC_TARGET>(i_target);
+
+ FAPI_TRY( mss::getScom(l_mcbist_target, (TT::MAINLINE_AUE_REGS[l_port]), o_data) );
+ FAPI_INF("%s read: 0x%016lx", mss::c_str(i_target), o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write MBS Mainline AUE Address Trap (MBAUER*Q) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ const auto& l_mcbist_target = mss::find_target<DEFAULT_MC_TARGET>(i_target);
+ const auto& l_port = mss::relative_pos<DEFAULT_MC_TARGET>(i_target);
+
+ FAPI_TRY( mss::putScom(l_mcbist_target, (TT::MAINLINE_AUE_REGS[l_port]), i_data) );
+ FAPI_INF("%s write: 0x%016lx", mss::c_str(i_target), i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set_address
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_address mcbist::address form of address field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
+{
+ io_data.insertFromRight<TT::AUE_ADDR_TRAP, TT::AUE_ADDR_TRAP_LEN>(uint64_t(i_address));
+ FAPI_INF("set_address: 0x%016lx", uint64_t(i_address));
+}
+
+///
+/// @brief get_address
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_address mcbist::address form of address field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
+{
+ uint64_t l_addr = 0;
+ i_data.extractToRight<TT::AUE_ADDR_TRAP, TT::AUE_ADDR_TRAP_LEN>(l_addr);
+ o_address = mcbist::address(l_addr);
+ FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
+}
+
+} // close namespace mainline_aue_trap
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/ecc/mainline_mpe_trap.H b/src/import/generic/memory/lib/ecc/mainline_mpe_trap.H
index c07639036..68fa26001 100644
--- a/src/import/generic/memory/lib/ecc/mainline_mpe_trap.H
+++ b/src/import/generic/memory/lib/ecc/mainline_mpe_trap.H
@@ -22,3 +22,142 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mainline_mpe_trap.H
+/// @brief Subroutines for the MC mainline mpe address trap registers (MBNCER*Q)
+///
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_MAINLINE_MPE_TRAP_H_
+#define _MSS_MAINLINE_MPE_TRAP_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/scom.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace mainline_mpe_trap
+{
+
+///
+/// @brief Read MBS Mainline MPE Address Trap (MBMPER*Q) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ const auto& l_mcbist_target = mss::find_target<DEFAULT_MC_TARGET>(i_target);
+ const auto& l_port = mss::relative_pos<DEFAULT_MC_TARGET>(i_target);
+
+ FAPI_TRY( mss::getScom(l_mcbist_target, (TT::MAINLINE_MPE_REGS[l_port]), o_data) );
+ FAPI_INF("%s read: 0x%016lx", mss::c_str(i_target), o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write MBS Mainline MPE Address Trap (MBMPER*Q) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ const auto& l_mcbist_target = mss::find_target<DEFAULT_MC_TARGET>(i_target);
+ const auto& l_port = mss::relative_pos<DEFAULT_MC_TARGET>(i_target);
+
+ FAPI_TRY( mss::putScom(l_mcbist_target, (TT::MAINLINE_MPE_REGS[l_port]), i_data) );
+ FAPI_INF("%s write: 0x%016lx", mss::c_str(i_target), i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set_address
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_address mcbist::address form of address field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
+{
+ io_data.insertFromRight<TT::MPE_ADDR_TRAP, TT::MPE_ADDR_TRAP_LEN>(uint64_t(i_address));
+ FAPI_INF("set_address: 0x%016lx", uint64_t(i_address));
+}
+
+///
+/// @brief get_address
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_address mcbist::address form of address field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
+{
+ uint64_t l_addr = 0;
+ i_data.extractToRight<TT::MPE_ADDR_TRAP, TT::MPE_ADDR_TRAP_LEN>(l_addr);
+ o_address = mcbist::address(l_addr);
+ FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
+}
+
+///
+/// @brief set_mpe_on_rce
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_state mss::YES or mss::NO - desired state
+/// @note MBMPER0Q_PORT_0_MAINLINE_MPE_ON_RCE: Indicates whether if this error
+/// @note came on the retry of a UE, RCD, or AUE as part of an RCE
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_mpe_on_rce( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
+{
+ io_data.writeBit<TT::MPE_ON_RCE>(i_state);
+ FAPI_INF("set_mpe_on_rce: 0x%01lx", i_state);
+}
+
+///
+/// @brief get_mpe_on_rce
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_state mss::YES or mss::NO - representing the state of the field
+/// @note MBMPER0Q_PORT_0_MAINLINE_MPE_ON_RCE: Indicates whether if this error
+/// @note came on the retry of a UE, RCD, or AUE as part of an RCE
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_mpe_on_rce( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state )
+{
+ o_state = (i_data.getBit<TT::MPE_ON_RCE>() == false) ? mss::NO : mss::YES;
+ FAPI_INF("get_mpe_on_rce: 0x%01lx", o_state);
+}
+
+} // close namespace mainline_mpe_trap
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/ecc/mainline_nce_trap.H b/src/import/generic/memory/lib/ecc/mainline_nce_trap.H
index cbffeb8e6..b99d4716a 100644
--- a/src/import/generic/memory/lib/ecc/mainline_nce_trap.H
+++ b/src/import/generic/memory/lib/ecc/mainline_nce_trap.H
@@ -22,3 +22,175 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mainline_nce_trap.H
+/// @brief Subroutines for the MC mainline nce address trap registers (MBNCER*Q)
+///
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_MAINLINE_NCE_TRAP_H_
+#define _MSS_MAINLINE_NCE_TRAP_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/scom.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/pos.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace mainline_nce_trap
+{
+
+///
+/// @brief Read MBS Mainline NCE Address Trap (MBNCER*Q) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ const auto& l_mcbist_target = mss::find_target<DEFAULT_MC_TARGET>(i_target);
+ const auto& l_port = mss::relative_pos<DEFAULT_MC_TARGET>(i_target);
+
+ FAPI_TRY( mss::getScom(l_mcbist_target, (TT::MAINLINE_NCE_REGS[l_port]), o_data) );
+ FAPI_INF("%s read: 0x%016lx", mss::c_str(i_target), o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write MBS Mainline NCE Address Trap (MBNCER*Q) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ const auto& l_mcbist_target = mss::find_target<DEFAULT_MC_TARGET>(i_target);
+ const auto& l_port = mss::relative_pos<DEFAULT_MC_TARGET>(i_target);
+
+ FAPI_TRY( mss::putScom(l_mcbist_target, (TT::MAINLINE_NCE_REGS[l_port]), i_data) );
+ FAPI_INF("%s write: 0x%016lx", mss::c_str(i_target), i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set_address
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_address mcbist::address form of address field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
+{
+ io_data.insertFromRight<TT::NCE_ADDR_TRAP, TT::NCE_ADDR_TRAP_LEN>(uint64_t(i_address));
+ FAPI_INF("set_address: 0x%016lx", uint64_t(i_address));
+}
+
+///
+/// @brief get_address
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_address mcbist::address form of address field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
+{
+ uint64_t l_addr = 0;
+ i_data.extractToRight<TT::NCE_ADDR_TRAP, TT::NCE_ADDR_TRAP_LEN>(l_addr);
+ o_address = mcbist::address(l_addr);
+ FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
+}
+
+///
+/// @brief set_nce_on_rce
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_state mss::YES or mss::NO - desired state
+/// @note MBNCER0Q_PORT_0_MAINLINE_NCE_ON_RCE: Indicates whether if this NCE came on the
+/// @note retry of a UE, RCD, or AUE as part of an RCE
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_nce_on_rce( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
+{
+ io_data.writeBit<TT::NCE_ON_RCE>(i_state);
+ FAPI_INF("set_nce_on_rce: 0x%01lx", i_state);
+}
+
+///
+/// @brief get_nce_on_rce
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_state mss::YES or mss::NO - representing the state of the field
+/// @note MBNCER0Q_PORT_0_MAINLINE_NCE_ON_RCE: Indicates whether if this NCE came on the
+/// @note retry of a UE, RCD, or AUE as part of an RCE
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_nce_on_rce( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state )
+{
+ o_state = (i_data.getBit<TT::NCE_ON_RCE>() == false) ? mss::NO : mss::YES;
+ FAPI_INF("get_nce_on_rce: 0x%01lx", o_state);
+}
+
+///
+/// @brief set_nce_is_tce
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_state mss::YES or mss::NO - desired state
+/// @note MBNCER0Q_PORT_0_MAINLINE_NCE_IS_TCE: Indicates if this NCE is actually
+/// @note a two symbol error (TCE)
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_nce_is_tce( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
+{
+ io_data.writeBit<TT::NCE_IS_TCE>(i_state);
+ FAPI_INF("set_nce_is_tce: 0x%01lx", i_state);
+}
+
+///
+/// @brief get_nce_is_tce
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_state mss::YES or mss::NO - representing the state of the field
+/// @note MBNCER0Q_PORT_0_MAINLINE_NCE_IS_TCE: Indicates if this NCE is actually
+/// @note a two symbol error (TCE)
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_nce_is_tce( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state )
+{
+ o_state = (i_data.getBit<TT::NCE_IS_TCE>() == false) ? mss::NO : mss::YES;
+ FAPI_INF("get_nce_is_tce: 0x%01lx", o_state);
+}
+
+} // close namespace mainline_nce_trap
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/ecc/mainline_rce_trap.H b/src/import/generic/memory/lib/ecc/mainline_rce_trap.H
index 02afe5b63..747192479 100644
--- a/src/import/generic/memory/lib/ecc/mainline_rce_trap.H
+++ b/src/import/generic/memory/lib/ecc/mainline_rce_trap.H
@@ -22,3 +22,110 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mainline_rce_trap.H
+/// @brief Subroutines for the MC mainline rce address trap registers (MBRCER*Q)
+///
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_MAINLINE_RCE_TRAP_H_
+#define _MSS_MAINLINE_RCE_TRAP_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/scom.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace mainline_rce_trap
+{
+
+///
+/// @brief Read MBS Mainline RCE Address Trap (MBRCER*Q) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ const auto& l_mcbist_target = mss::find_target<DEFAULT_MC_TARGET>(i_target);
+ const auto& l_port = mss::relative_pos<DEFAULT_MC_TARGET>(i_target);
+
+ FAPI_TRY( mss::getScom(l_mcbist_target, (TT::MAINLINE_RCE_REGS[l_port]), o_data) );
+ FAPI_INF("read: 0x%016lx", o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write MBS Mainline RCE Address Trap (MBRCER*Q) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ const auto& l_mcbist_target = mss::find_target<DEFAULT_MC_TARGET>(i_target);
+ const auto& l_port = mss::relative_pos<DEFAULT_MC_TARGET>(i_target);
+
+ FAPI_TRY( mss::putScom(l_mcbist_target, (TT::MAINLINE_RCE_REGS[l_port]), i_data) );
+ FAPI_INF("write: 0x%016lx", i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set_address
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_address mcbist::address form of address field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
+{
+ io_data.insertFromRight<TT::RCE_ADDR_TRAP, TT::RCE_ADDR_TRAP_LEN>(uint64_t(i_address));
+ FAPI_INF("set_address: 0x%016lx", uint64_t(i_address));
+}
+
+///
+/// @brief get_address
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_address mcbist::address form of address field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
+{
+ uint64_t l_addr = 0;
+ i_data.extractToRight<TT::RCE_ADDR_TRAP, TT::RCE_ADDR_TRAP_LEN>(l_addr);
+ o_address = mcbist::address(l_addr);
+ FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
+}
+
+} // close namespace mainline_rce_trap
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/ecc/mainline_ue_trap.H b/src/import/generic/memory/lib/ecc/mainline_ue_trap.H
index 10da89c18..ed5e46820 100644
--- a/src/import/generic/memory/lib/ecc/mainline_ue_trap.H
+++ b/src/import/generic/memory/lib/ecc/mainline_ue_trap.H
@@ -22,3 +22,110 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mainline_ue_trap.H
+/// @brief Subroutines for the MC mainline ue address trap registers (MBUER*Q)
+///
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_MAINLINE_UE_TRAP_H_
+#define _MSS_MAINLINE_UE_TRAP_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/scom.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace mainline_ue_trap
+{
+
+///
+/// @brief Read MBS Mainline UE Address Trap (MBUER*Q) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ const auto& l_mcbist_target = mss::find_target<DEFAULT_MC_TARGET>(i_target);
+ const auto& l_port = mss::relative_pos<DEFAULT_MC_TARGET>(i_target);
+
+ FAPI_TRY( mss::getScom(l_mcbist_target, (TT::MAINLINE_UE_REGS[l_port]), o_data) );
+ FAPI_INF("read: 0x%016lx", o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write MBS Mainline UE Address Trap (MBUER*Q) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ const auto& l_mcbist_target = mss::find_target<DEFAULT_MC_TARGET>(i_target);
+ const auto& l_port = mss::relative_pos<DEFAULT_MC_TARGET>(i_target);
+
+ FAPI_TRY( mss::putScom(l_mcbist_target, (TT::MAINLINE_UE_REGS[l_port]), i_data) );
+ FAPI_INF("write: 0x%016lx", i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set_address
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_address mcbist::address form of address field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
+{
+ io_data.insertFromRight<TT::UE_ADDR_TRAP, TT::UE_ADDR_TRAP_LEN>(uint64_t(i_address));
+ FAPI_INF("set_address: 0x%016lx", uint64_t(i_address));
+}
+
+///
+/// @brief get_address
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_address mcbist::address form of address field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
+{
+ uint64_t l_addr = 0;
+ i_data.extractToRight<TT::UE_ADDR_TRAP, TT::UE_ADDR_TRAP_LEN>(l_addr);
+ o_address = mcbist::address(l_addr);
+ FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
+}
+
+} // close namespace mainline_ue_trap
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/ecc/maint_current_trap.H b/src/import/generic/memory/lib/ecc/maint_current_trap.H
index fd3b7de8e..a5e25297f 100644
--- a/src/import/generic/memory/lib/ecc/maint_current_trap.H
+++ b/src/import/generic/memory/lib/ecc/maint_current_trap.H
@@ -22,3 +22,173 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file maint_current_trap.H
+/// @brief Subroutines for the MC maint current address trap register (MCBMCATQ)
+///
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_MAINT_CURRENT_TRAP_H_
+#define _MSS_MAINT_CURRENT_TRAP_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/scom.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace maint_current_trap
+{
+
+///
+/// @brief Read MBS Mainline MPE Address Trap (MCBMCATQ) register
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mem port
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode read( const fapi2::Target<DEFAULT_MEM_PORT_TARGET>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ const auto& l_mcbist_target = mss::find_target<T>(i_target);
+
+ FAPI_TRY( mss::getScom(l_mcbist_target, TT::MPE_ADDR_TRAP_REG, o_data) );
+ FAPI_INF("read: 0x%016lx", o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write MBS Mainline MPE Address Trap (MCBMCATQ) register
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mem port
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode write( const fapi2::Target<DEFAULT_MEM_PORT_TARGET>& i_target,
+ const fapi2::buffer<uint64_t>& i_data )
+{
+ const auto& l_mcbist_target = mss::find_target<T>(i_target);
+
+ FAPI_TRY( mss::putScom(l_mcbist_target, TT::MPE_ADDR_TRAP_REG, i_data) );
+ FAPI_INF("write: 0x%016lx", i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set_address
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_address mcbist::address form of address field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
+{
+ io_data.insertFromRight<TT::CURRENT_ADDR_TRAP, TT::CURRENT_ADDR_TRAP_LEN>(uint64_t(i_address));
+ FAPI_INF("set_address: 0x%016lx", uint64_t(i_address));
+}
+
+///
+/// @brief get_address
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_address mcbist::address form of address field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
+{
+ uint64_t l_addr = 0;
+ i_data.extractToRight<TT::CURRENT_ADDR_TRAP, TT::CURRENT_ADDR_TRAP_LEN>(l_addr);
+ o_address = mcbist::address(l_addr);
+ FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
+}
+
+///
+/// @brief set_port
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value - desired value
+/// @note MCBMCATQ_CFG_CURRENT_PORT_TRAP: If MCBCFGQ_cfg_current_addr_trap_update_dis = 0, then this
+/// @note field will store port. This field is ONLY valid in maint_addr_mode. Garabage otherwise.
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_port( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::CURRENT_PORT, TT::CURRENT_PORT_LEN>(i_value);
+ FAPI_INF("set_port: 0x%01lx", i_value);
+}
+
+///
+/// @brief get_port
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value - representing the field value
+/// @note MCBMCATQ_CFG_CURRENT_PORT_TRAP: If MCBCFGQ_cfg_current_addr_trap_update_dis = 0, then this
+/// @note field will store port. This field is ONLY valid in maint_addr_mode. Garabage otherwise.
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_port( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::CURRENT_PORT, TT::CURRENT_PORT_LEN>(o_value);
+ FAPI_INF("get_port: 0x%01lx", o_value);
+}
+
+///
+/// @brief set_dimm
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value - desired value
+/// @note MCBMCATQ_CFG_CURRENT_DIMM_TRAP: If MCBCFGQ_cfg_current_addr_trap_update_dis = 0, then this
+/// @note field will store dimm select.
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_dimm( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.writeBit<TT::CURRENT_DIMM>(i_value);
+ FAPI_INF("set_dimm: 0x%01lx", i_value);
+}
+
+///
+/// @brief get_dimm
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value - representing the field value
+/// @note MCBMCATQ_CFG_CURRENT_DIMM_TRAP: If MCBCFGQ_cfg_current_addr_trap_update_dis = 0, then this
+/// @note field will store dimm select.
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_dimm( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ o_value = i_data.getBit<TT::CURRENT_DIMM>();
+ FAPI_INF("get_dimm: 0x%01lx", o_value);
+}
+
+} // close namespace maint_current_trap
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/ecc/mark_shadow_reg.H b/src/import/generic/memory/lib/ecc/mark_shadow_reg.H
index d2e0d92c3..65bd7dca2 100644
--- a/src/import/generic/memory/lib/ecc/mark_shadow_reg.H
+++ b/src/import/generic/memory/lib/ecc/mark_shadow_reg.H
@@ -22,3 +22,129 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mark_shadow_reg.H
+/// @brief Subroutines for the MC mark shadow registers (MSR)
+///
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_MARK_SHADOW_REG_H_
+#define _MSS_MARK_SHADOW_REG_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/scom.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace mark_shadow_reg
+{
+
+///
+/// @brief Read Mark Shadow register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ FAPI_TRY( mss::getScom(i_target, TT::MARK_SHADOW_REG, o_data) );
+ FAPI_INF("%s read: 0x%016lx", mss::c_str(i_target), o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write Mark Shadow register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ FAPI_TRY( mss::putScom(i_target, TT::MARK_SHADOW_REG, i_data) );
+ FAPI_INF("%s write: 0x%016lx", mss::c_str(i_target), i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set_chipmark
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_chipmark( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::SHADOW_CHIPMARK, TT::SHADOW_CHIPMARK_LEN>(i_value);
+ FAPI_INF("set_chipmark: 0x%016lx", i_value);
+}
+
+///
+/// @brief get_chipmark
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_chipmark( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::SHADOW_CHIPMARK, TT::SHADOW_CHIPMARK_LEN>(o_value);
+ FAPI_INF("get_chipmark: 0x%016lx", o_value);
+}
+
+///
+/// @brief set_rank
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_rank( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::SHADOW_RANK, TT::SHADOW_RANK_LEN>(i_value);
+ FAPI_INF("set_rank: 0x%016lx", i_value);
+}
+
+///
+/// @brief get_rank
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MEM_PORT_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+///
+template< fapi2::TargetType T = DEFAULT_MEM_PORT_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_rank( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::SHADOW_RANK, TT::SHADOW_RANK_LEN>(o_value);
+ FAPI_INF("get_rank: 0x%016lx", o_value);
+}
+
+} // close namespace mark_shadow_reg
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/ecc/mbs_error_vector_trap.H b/src/import/generic/memory/lib/ecc/mbs_error_vector_trap.H
index 529491723..302ab3fbf 100644
--- a/src/import/generic/memory/lib/ecc/mbs_error_vector_trap.H
+++ b/src/import/generic/memory/lib/ecc/mbs_error_vector_trap.H
@@ -22,3 +22,182 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mbs_error_vector_trap.H
+/// @brief Subroutines for the MC MBS error vector trap registers (MBSEVR*Q)
+///
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_MBS_ERROR_VECTOR_TRAP_H_
+#define _MSS_MBS_ERROR_VECTOR_TRAP_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/scom.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace mbs_error_vector_trap
+{
+
+///
+/// @brief Read MBS Error Vector Trap (MBSEVR*Q) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ const auto& l_mcbist_target = mss::find_target<DEFAULT_MC_TARGET>(i_target);
+ const auto& l_port = mss::relative_pos<DEFAULT_MC_TARGET>(i_target);
+
+ FAPI_TRY( mss::getScom(l_mcbist_target, (TT::ERROR_VECTOR_REGS[l_port]), o_data) );
+ FAPI_INF("%s read: 0x%016lx", mss::c_str(i_target), o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write MBS Error Vector Trap (MBSEVR*Q) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ const auto& l_mcbist_target = mss::find_target<DEFAULT_MC_TARGET>(i_target);
+ const auto& l_port = mss::relative_pos<DEFAULT_MC_TARGET>(i_target);
+
+ FAPI_TRY( mss::putScom(l_mcbist_target, (TT::ERROR_VECTOR_REGS[l_port]), i_data) );
+ FAPI_INF("%s write: 0x%016lx", mss::c_str(i_target), i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set_nce_galois
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+void set_nce_galois( const fapi2::Target<T>& i_target,
+ fapi2::buffer<uint64_t>& io_data,
+ const uint64_t i_value);
+///
+/// @brief get_nce_galois
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the register value
+/// @param[out] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+void get_nce_galois( const fapi2::Target<T>& i_target,
+ const fapi2::buffer<uint64_t>& i_data,
+ uint64_t& o_value);
+
+///
+/// @brief set_nce_magnitude
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+void set_nce_magnitude( const fapi2::Target<T>& i_target,
+ fapi2::buffer<uint64_t>& io_data,
+ const uint64_t i_value);
+
+///
+/// @brief get_nce_magnitude
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the register value
+/// @param[out] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+void get_nce_magnitude( const fapi2::Target<T>& i_target,
+ const fapi2::buffer<uint64_t>& i_data,
+ uint64_t& o_value);
+
+///
+/// @brief set_tce_galois
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+void set_tce_galois( const fapi2::Target<T>& i_target,
+ fapi2::buffer<uint64_t>& io_data,
+ const uint64_t i_value);
+
+///
+/// @brief get_tce_galois
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the register value
+/// @param[out] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+void get_tce_galois( const fapi2::Target<T>& i_target,
+ const fapi2::buffer<uint64_t>& i_data,
+ uint64_t& o_value);
+
+///
+/// @brief set_tce_magnitude
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+void set_tce_magnitude( const fapi2::Target<T>& i_target,
+ fapi2::buffer<uint64_t>& io_data,
+ const uint64_t i_value);
+
+///
+/// @brief get_tce_magnitude
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the register value
+/// @param[out] i_value the value of the field
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+void get_tce_magnitude( const fapi2::Target<T>& i_target,
+ const fapi2::buffer<uint64_t>& i_data,
+ uint64_t& o_value);
+
+} // close namespace mbs_error_vector_trap
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/ecc/modal_symbol_count.H b/src/import/generic/memory/lib/ecc/modal_symbol_count.H
index 1cca236c2..8a4c7a921 100644
--- a/src/import/generic/memory/lib/ecc/modal_symbol_count.H
+++ b/src/import/generic/memory/lib/ecc/modal_symbol_count.H
@@ -22,3 +22,552 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file modal_symbol_count.H
+/// @brief Subroutines for the MC modal symbol count (MBSSYMEC*Q) registers
+///
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_MODAL_SYMBOL_COUNT_H_
+#define _MSS_MODAL_SYMBOL_COUNT_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/scom.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace modal_symbol_count
+{
+
+///
+/// @brief Read modal symbol count (MBSSYMEC*Q) register
+/// @tparam N the register index (0-8)
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< uint64_t N, fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode read_index( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ static_assert((N < TT::NUM_MBSSYM_REGS), "Modal symbol count reg index failed range check");
+ FAPI_TRY( mss::getScom(i_target, (TT::MODAL_SYM_COUNT0_REG + N), o_data) );
+ FAPI_INF("read_index<%d>: 0x%016lx", N, o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Read modal symbol count (MBSSYMEC*Q) 0 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_index0( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_index<0>(i_target, o_data) );
+}
+
+///
+/// @brief Read modal symbol count (MBSSYMEC*Q) 1 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_index1( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_index<1>(i_target, o_data) );
+}
+
+///
+/// @brief Read modal symbol count (MBSSYMEC*Q) 2 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_index2( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_index<2>(i_target, o_data) );
+}
+
+///
+/// @brief Read modal symbol count (MBSSYMEC*Q) 3 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_index3( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_index<3>(i_target, o_data) );
+}
+
+///
+/// @brief Read modal symbol count (MBSSYMEC*Q) 4 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_index4( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_index<4>(i_target, o_data) );
+}
+
+///
+/// @brief Read modal symbol count (MBSSYMEC*Q) 5 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_index5( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_index<5>(i_target, o_data) );
+}
+
+///
+/// @brief Read modal symbol count (MBSSYMEC*Q) 6 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_index6( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_index<6>(i_target, o_data) );
+}
+
+///
+/// @brief Read modal symbol count (MBSSYMEC*Q) 7 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_index7( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_index<7>(i_target, o_data) );
+}
+
+///
+/// @brief Read modal symbol count (MBSSYMEC*Q) 8 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read_index8( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ return ( read_index<8>(i_target, o_data) );
+}
+
+///
+/// @brief Read modal symbol count (MBSSYMEC*Q) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_index the register index
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target,
+ const uint64_t i_index,
+ fapi2::buffer<uint64_t>& o_data )
+{
+ switch (i_index)
+ {
+ case(0):
+ return ( read_index0(i_target, o_data) );
+
+ case(1):
+ return ( read_index1(i_target, o_data) );
+
+ case(2):
+ return ( read_index2(i_target, o_data) );
+
+ case(3):
+ return ( read_index3(i_target, o_data) );
+
+ case(4):
+ return ( read_index4(i_target, o_data) );
+
+ case(5):
+ return ( read_index5(i_target, o_data) );
+
+ case(6):
+ return ( read_index6(i_target, o_data) );
+
+ case(7):
+ return ( read_index7(i_target, o_data) );
+
+ case(8):
+ return ( read_index8(i_target, o_data) );
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_INDEX_PASSED()
+ .set_INDEX(i_index)
+ .set_FUNCTION(SYMBOL_COUNT_READ),
+ "%s Invalid index passed to fwms::ecc::modal_symbol_count::read (%d)",
+ mss::c_str(i_target),
+ i_index);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write modal symbol count (MBSSYMEC*Q) register
+/// @tparam N the register index (0-8)
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< uint64_t N, fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode write_index( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ static_assert((N < TT::NUM_MBSSYM_REGS), "Modal symbol count reg index failed range check");
+ FAPI_TRY( mss::putScom(i_target, (TT::MODAL_SYM_COUNT0_REG + N), i_data) );
+ FAPI_INF("write_index<%d>: 0x%016lx", N, i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write modal symbol count (MBSSYMEC*Q) 0 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_index0( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_index<0>(i_target, i_data) );
+}
+
+///
+/// @brief Write modal symbol count (MBSSYMEC*Q) 1 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_index1( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_index<1>(i_target, i_data) );
+}
+
+///
+/// @brief Write modal symbol count (MBSSYMEC*Q) 2 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_index2( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_index<2>(i_target, i_data) );
+}
+
+///
+/// @brief Write modal symbol count (MBSSYMEC*Q) 3 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_index3( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_index<3>(i_target, i_data) );
+}
+
+///
+/// @brief Write modal symbol count (MBSSYMEC*Q) 4 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_index4( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_index<4>(i_target, i_data) );
+}
+
+///
+/// @brief Write modal symbol count (MBSSYMEC*Q) 5 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_index5( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_index<5>(i_target, i_data) );
+}
+
+///
+/// @brief Write modal symbol count (MBSSYMEC*Q) 6 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_index6( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_index<6>(i_target, i_data) );
+}
+
+///
+/// @brief Write modal symbol count (MBSSYMEC*Q) 7 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_index7( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_index<7>(i_target, i_data) );
+}
+
+///
+/// @brief Write modal symbol count (MBSSYMEC*Q) 8 register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write_index8( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ return ( write_index<8>(i_target, i_data) );
+}
+
+///
+/// @brief Write Hardware Mark Store (HWMS) register
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @param[in] i_target the fapi2 target of the mc
+/// @param[in] i_index the register index
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target,
+ const uint64_t i_index,
+ const fapi2::buffer<uint64_t>& i_data )
+{
+ switch (i_index)
+ {
+ case(0):
+ return ( write_index0(i_target, i_data) );
+
+ case(1):
+ return ( write_index1(i_target, i_data) );
+
+ case(2):
+ return ( write_index2(i_target, i_data) );
+
+ case(3):
+ return ( write_index3(i_target, i_data) );
+
+ case(4):
+ return ( write_index4(i_target, i_data) );
+
+ case(5):
+ return ( write_index5(i_target, i_data) );
+
+ case(6):
+ return ( write_index6(i_target, i_data) );
+
+ case(7):
+ return ( write_index7(i_target, i_data) );
+
+ case(8):
+ return ( write_index8(i_target, i_data) );
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_INDEX_PASSED()
+ .set_INDEX(i_index)
+ .set_FUNCTION(SYMBOL_COUNT_WRITE),
+ "%s Invalid index passed to fwms::ecc::modal_symbol_count::write (%d)",
+ mss::c_str(i_target),
+ i_index);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set_count
+/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_index the counter index
+/// @param[in] i_value the value of the field
+/// @note MBSSYMEC*Q_MODAL_SYMBOL_COUNTER_XX: Functional mode determined by MBSTRQ_Symbol_counter_mode:
+/// @note if 00, 0:7 = Maint NCE counter for Symbol XX if 01, 0:3 = MCBIST error counter for nibble (XX/4)
+/// @note and rank (XX%4)*2 4:7 = MCBIST error counter for nibble (XX/4) and rank ((XX%4)*2)+1 if 10,
+/// @note 0:3 = MCBIST error counter for port XX/18 and nibble XX%18 4:7 = MCBIST error rank map for
+/// @note port XX/18 and nibble XX%18
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_index, const uint64_t i_value )
+{
+ static_assert ( TT::MODAL_SYMBOL_COUNTERS_PER_REG <= 8,
+ "mss::ecc_count::modal_symbol_count: Modal symbol count field index failed range check" );
+ const uint64_t l_field = i_index % TT::MODAL_SYMBOL_COUNTERS_PER_REG;
+
+ switch (l_field)
+ {
+ case 0:
+ io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_00, TT::MODAL_SYMBOL_COUNTER_00_LEN>(i_value);
+ break;
+
+ case 1:
+ io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_01, TT::MODAL_SYMBOL_COUNTER_01_LEN>(i_value);
+ break;
+
+ case 2:
+ io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_02, TT::MODAL_SYMBOL_COUNTER_02_LEN>(i_value);
+ break;
+
+ case 3:
+ io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_03, TT::MODAL_SYMBOL_COUNTER_03_LEN>(i_value);
+ break;
+
+ case 4:
+ io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_04, TT::MODAL_SYMBOL_COUNTER_04_LEN>(i_value);
+ break;
+
+ case 5:
+ io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_05, TT::MODAL_SYMBOL_COUNTER_05_LEN>(i_value);
+ break;
+
+ case 6:
+ io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_06, TT::MODAL_SYMBOL_COUNTER_06_LEN>(i_value);
+ break;
+
+ case 7:
+ io_data.insertFromRight<TT::MODAL_SYMBOL_COUNTER_07, TT::MODAL_SYMBOL_COUNTER_07_LEN>(i_value);
+ break;
+
+ default:
+ // Shouldn't happen due to modulo above, but here just in case - JLH
+ FAPI_ERR("Modal symbol count field index failed range check");
+ fapi2::Assert(false);
+ break;
+ }
+
+ FAPI_INF("set_count(%d): 0x%02lx", l_field, i_value);
+}
+
+///
+/// @brief get_count
+/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCBIST
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[in] i_index the counter index
+/// @param[out] o_value the value of the field
+/// @note MBSSYMEC*Q_MODAL_SYMBOL_COUNTER_XX: Functional mode determined by MBSTRQ_Symbol_counter_mode:
+/// @note if 00, 0:7 = Maint NCE counter for Symbol XX if 01, 0:3 = MCBIST error counter for nibble (XX/4)
+/// @note and rank (XX%4)*2 4:7 = MCBIST error counter for nibble (XX/4) and rank ((XX%4)*2)+1 if 10,
+/// @note 0:3 = MCBIST error counter for port XX/18 and nibble XX%18 4:7 = MCBIST error rank map for
+/// @note port XX/18 and nibble XX%18
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_count( const fapi2::buffer<uint64_t>& i_data, const uint64_t i_index, uint64_t& o_value )
+{
+ const uint64_t l_field = i_index % TT::MODAL_SYMBOL_COUNTERS_PER_REG;
+ static_assert ( TT::MODAL_SYMBOL_COUNTERS_PER_REG <= 8,
+ "mss::ecc_count::get_count: Modal symbol count field index failed range check" );
+
+ switch (l_field)
+ {
+ case 0:
+ i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_00, TT::MODAL_SYMBOL_COUNTER_00_LEN>(o_value);
+ break;
+
+ case 1:
+ i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_01, TT::MODAL_SYMBOL_COUNTER_01_LEN>(o_value);
+ break;
+
+ case 2:
+ i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_02, TT::MODAL_SYMBOL_COUNTER_02_LEN>(o_value);
+ break;
+
+ case 3:
+ i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_03, TT::MODAL_SYMBOL_COUNTER_03_LEN>(o_value);
+ break;
+
+ case 4:
+ i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_04, TT::MODAL_SYMBOL_COUNTER_04_LEN>(o_value);
+ break;
+
+ case 5:
+ i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_05, TT::MODAL_SYMBOL_COUNTER_05_LEN>(o_value);
+ break;
+
+ case 6:
+ i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_06, TT::MODAL_SYMBOL_COUNTER_06_LEN>(o_value);
+ break;
+
+ case 7:
+ i_data.extractToRight<TT::MODAL_SYMBOL_COUNTER_07, TT::MODAL_SYMBOL_COUNTER_07_LEN>(o_value);
+ break;
+
+ default:
+ // shouldn't happen due to modulo above, but here just in case
+ FAPI_ERR("Modal symbol count field index failed range check");
+ fapi2::Assert(false);
+ break;
+ }
+
+ FAPI_INF("get_count(%d): 0x%02lx", l_field, o_value);
+}
+
+} // close namespace modal_symbol_count
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/ecc/read_error_count_regs.H b/src/import/generic/memory/lib/ecc/read_error_count_regs.H
index 78b0d7b31..352f28795 100644
--- a/src/import/generic/memory/lib/ecc/read_error_count_regs.H
+++ b/src/import/generic/memory/lib/ecc/read_error_count_regs.H
@@ -22,3 +22,628 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mainline_ue_trap.H
+/// @brief Subroutines for the MBS Memory Scrub/Read Error Count registers (MBSEC*Q)
+///
+// *HWP HWP Owner: Matt Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_READ_ERROR_COUNT_REGS_H_
+#define _MSS_READ_ERROR_COUNT_REGS_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/scom.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace read_error_count_reg0
+{
+
+///
+/// @brief Read MBS Memory Scrub/Read Error Count Register 0 (MBSEC0Q)
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mcbist
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ FAPI_TRY( mss::getScom(i_target, TT::READ_ERROR_COUNT_REG0, o_data) );
+ FAPI_INF("%s read: 0x%016lx", mss::c_str(i_target), o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write MBS Memory Scrub/Read Error Count Register 0 (MBSEC0Q)
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mcbist
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ FAPI_TRY( mss::putScom(i_target, TT::READ_ERROR_COUNT_REG0, i_data) );
+ FAPI_INF("%s write: 0x%016lx", mss::c_str(i_target), i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set_intermittent_ce_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note MBSEC0Q_INTERMITTENT_CE_COUNT: Intermittent CE Count This is a 12-bit count of
+/// @note intermittent CE events. Will freeze its value upon incrementing to the max
+/// @note value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_intermittent_ce_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::INTERMITTENT_CE_COUNT, TT::INTERMITTENT_CE_COUNT_LEN>(i_value);
+ FAPI_INF("set_intermittent_ce_count: 0x%03lx", i_value);
+}
+
+///
+/// @brief get_intermittent_ce_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note MBSEC0Q_INTERMITTENT_CE_COUNT: Intermittent CE Count This is a 12-bit count of
+/// @note intermittent CE events. Will freeze its value upon incrementing to the max
+/// @note value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_intermittent_ce_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::INTERMITTENT_CE_COUNT, TT::INTERMITTENT_CE_COUNT_LEN>(o_value);
+ FAPI_INF("get_intermittent_ce_count: 0x%03lx", o_value);
+}
+
+///
+/// @brief set_soft_ce_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note MBSEC0Q_SOFT_CE_COUNT: Soft CE Count This is a 12-bit count of
+/// @note soft CE events. Will freeze its value upon incrementing to the max
+/// @note value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_soft_ce_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::SOFT_CE_COUNT, TT::SOFT_CE_COUNT_LEN>(i_value);
+ FAPI_INF("set_soft_ce_count: 0x%03lx", i_value);
+}
+
+///
+/// @brief get_soft_ce_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note MBSEC0Q_SOFT_CE_COUNT: Soft CE Count This is a 12-bit count of
+/// @note soft CE events. Will freeze its value upon incrementing to the max
+/// @note value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_soft_ce_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::SOFT_CE_COUNT, TT::SOFT_CE_COUNT_LEN>(o_value);
+ FAPI_INF("get_soft_ce_count: 0x%03lx", o_value);
+}
+
+///
+/// @brief set_hard_ce_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note MBSEC0Q_HARD_CE_COUNT: Hard CE Count This is a 12-bit count of
+/// @note hard CE events. Will freeze its value upon incrementing to the max
+/// @note value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_hard_ce_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::HARD_CE_COUNT, TT::HARD_CE_COUNT_LEN>(i_value);
+ FAPI_INF("set_hard_ce_count: 0x%03lx", i_value);
+}
+
+///
+/// @brief get_hard_ce_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note MBSEC0Q_HARD_CE_COUNT: Hard CE Count This is a 12-bit count of
+/// @note hard CE events. Will freeze its value upon incrementing to the max
+/// @note value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_hard_ce_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::HARD_CE_COUNT, TT::HARD_CE_COUNT_LEN>(o_value);
+ FAPI_INF("get_hard_ce_count: 0x%03lx", o_value);
+}
+
+///
+/// @brief set_intermittent_mce_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note MBSEC0Q_INTERMITTENT_MCE_COUNT: Intermittent MCE Count This is a 12-bit count of
+/// @note intermittent Marked Chip Correctable Error events. Will freeze its value upon
+/// @note incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_intermittent_mce_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::INTERMITTENT_MCE_COUNT, TT::INTERMITTENT_MCE_COUNT_LEN>(i_value);
+ FAPI_INF("set_intermittent_mce_count: 0x%03lx", i_value);
+}
+
+///
+/// @brief get_intermittent_mce_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note MBSEC0Q_INTERMITTENT_MCE_COUNT: Intermittent MCE Count This is a 12-bit count of
+/// @note intermittent Marked Chip Correctable Error events. Will freeze its value upon
+/// @note incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_intermittent_mce_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::INTERMITTENT_MCE_COUNT, TT::INTERMITTENT_MCE_COUNT_LEN>(o_value);
+ FAPI_INF("get_intermittent_mce_count: 0x%03lx", o_value);
+}
+
+///
+/// @brief set_soft_mce_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note MBSEC0Q_SOFT_MCE_COUNT: Soft MCE Count This is a 12-bit count of
+/// @note soft Marked Chip Correctable Error events. Will freeze its value upon
+/// @note incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_soft_mce_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::SOFT_MCE_COUNT, TT::SOFT_MCE_COUNT_LEN>(i_value);
+ FAPI_INF("set_soft_mce_count: 0x%03lx", i_value);
+}
+
+///
+/// @brief get_soft_mce_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note MBSEC0Q_SOFT_MCE_COUNT: Soft MCE Count This is a 12-bit count of
+/// @note soft Marked Chip Correctable Error events. Will freeze its value upon
+/// @note incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_soft_mce_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::SOFT_MCE_COUNT, TT::SOFT_MCE_COUNT_LEN>(o_value);
+ FAPI_INF("get_soft_mce_count: 0x%03lx", o_value);
+}
+
+} // close namespace read_error_count_reg0
+
+namespace read_error_count_reg1
+{
+
+///
+/// @brief Read MBS Memory Scrub/Read Error Count Register 1 (MBSEC1Q)
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mcbist
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ FAPI_TRY( mss::getScom(i_target, TT::READ_ERROR_COUNT_REG1, o_data) );
+ FAPI_INF("%s read: 0x%016lx", mss::c_str(i_target), o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write MBS Memory Scrub/Read Error Count Register 1 (MBSEC1Q)
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mcbist
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ FAPI_TRY( mss::putScom(i_target, TT::READ_ERROR_COUNT_REG1, i_data) );
+ FAPI_INF("%s write: 0x%016lx", mss::c_str(i_target), i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set_hard_mce_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note MBSEC0Q_HARD_MCE_COUNT: Hard MCE Count This is a 12-bit count of
+/// @note hard Marked Chip Correctable Error events. Will freeze its value upon
+/// @note incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_hard_mce_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::HARD_MCE_COUNT, TT::HARD_MCE_COUNT_LEN>(i_value);
+ FAPI_INF("set_hard_mce_count: 0x%03lx", i_value);
+}
+
+///
+/// @brief get_hard_mce_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note MBSEC0Q_HARD_MCE_COUNT: Hard MCE Count This is a 12-bit count of
+/// @note hard Marked Chip Correctable Error events. Will freeze its value upon
+/// @note incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_hard_mce_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::HARD_MCE_COUNT, TT::HARD_MCE_COUNT_LEN>(o_value);
+ FAPI_INF("get_hard_mce_count: 0x%03lx", o_value);
+}
+
+///
+/// @brief set_ice_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note MBSEC0Q_ICE_COUNT: ICE (IMPE) Count This is a 12-bit count of
+/// @note Intermittent Marked-Placed Chip Error events. Will freeze its value upon
+/// @note incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_ice_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::ICE_COUNT, TT::ICE_COUNT_LEN>(i_value);
+ FAPI_INF("set_ice_count: 0x%03lx", i_value);
+}
+
+///
+/// @brief get_ice_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note MBSEC0Q_ICE_COUNT: ICE (IMPE) Count This is a 12-bit count of
+/// @note Intermittent Marked-Placed Chip Error events. Will freeze its value upon
+/// @note incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_ice_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::ICE_COUNT, TT::ICE_COUNT_LEN>(o_value);
+ FAPI_INF("get_ice_count: 0x%03lx", o_value);
+}
+
+///
+/// @brief set_ue_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note MBSEC0Q_UE_COUNT: UE Count This is a 12-bit count of
+/// @note Uncorrectable Error events. Will freeze its value upon
+/// @note incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_ue_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::UE_COUNT, TT::UE_COUNT_LEN>(i_value);
+ FAPI_INF("set_ue_count: 0x%03lx", i_value);
+}
+
+///
+/// @brief get_ue_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note MBSEC0Q_UE_COUNT: UE Count This is a 12-bit count of
+/// @note Uncorrectable Error events. Will freeze its value upon
+/// @note incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_ue_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::UE_COUNT, TT::UE_COUNT_LEN>(o_value);
+ FAPI_INF("get_ue_count: 0x%03lx", o_value);
+}
+
+///
+/// @brief set_aue_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note MBSEC0Q_AUE_COUNT: AUE Count This is a 12-bit count of
+/// @note AUE Parity Error events. Will freeze its value upon
+/// @note incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_aue_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::AUE_COUNT, TT::AUE_COUNT_LEN>(i_value);
+ FAPI_INF("set_aue_count: 0x%03lx", i_value);
+}
+
+///
+/// @brief get_aue_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note MBSEC0Q_AUE_COUNT: AUE Count This is a 12-bit count of
+/// @note AUE Parity Error events. Will freeze its value upon
+/// @note incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_aue_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::AUE_COUNT, TT::AUE_COUNT_LEN>(o_value);
+ FAPI_INF("get_aue_count: 0x%03lx", o_value);
+}
+
+///
+/// @brief set_rce_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note MBSEC0Q_RCE_COUNT: RCE Count This is a 12-bit count of
+/// @note Retried Correctable Error events. Will freeze its value upon
+/// @note incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_rce_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::RCE_COUNT, TT::RCE_COUNT_LEN>(i_value);
+ FAPI_INF("set_rce_count: 0x%03lx", i_value);
+}
+
+///
+/// @brief get_rce_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note MBSEC0Q_RCE_COUNT: RCE Count This is a 12-bit count of
+/// @note Retried Correctable Error events. Will freeze its value upon
+/// @note incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_rce_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::RCE_COUNT, TT::RCE_COUNT_LEN>(o_value);
+ FAPI_INF("get_rce_count: 0x%03lx", o_value);
+}
+
+} // close namespace read_error_count_reg1
+
+namespace mark_symbol_count_reg
+{
+
+///
+/// @brief Read MBS Mark Symbol Error Count Register (MBSMSECQ)
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mcbist
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode read( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ FAPI_TRY( mss::getScom(i_target, TT::MARK_SYMBOL_COUNT_REG, o_data) );
+ FAPI_INF("read: 0x%016lx", o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write MBS Mark Symbol Error Count Register (MBSMSECQ)
+/// @tparam T fapi2 Target Type - derived from i_target's type
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_target the fapi2 target of the mcbist
+/// @param[in] i_data the value to write to the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline fapi2::ReturnCode write( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ FAPI_TRY( mss::putScom(i_target, TT::MARK_SYMBOL_COUNT_REG, i_data) );
+ FAPI_INF("write: 0x%016lx", i_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set_symbol0_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note MBSMSECQ_MCE_SYMBOL0_COUNT: MCE Symbol 0 Error Count This is a 8-bit count
+/// @note that increments on MCE when Symbol 0 under chip mark takes error. Will freeze
+/// @note its value upon incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_symbol0_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::SYMBOL0_COUNT, TT::SYMBOL0_COUNT_LEN>(i_value);
+ FAPI_INF("set_symbol0_count: 0x%03lx", i_value);
+}
+
+///
+/// @brief get_symbol0_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note MBSMSECQ_MCE_SYMBOL0_COUNT: MCE Symbol 0 Error Count This is a 8-bit count
+/// @note that increments on MCE when Symbol 0 under chip mark takes error. Will freeze
+/// @note its value upon incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_symbol0_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::SYMBOL0_COUNT, TT::SYMBOL0_COUNT_LEN>(o_value);
+ FAPI_INF("get_symbol0_count: 0x%03lx", o_value);
+}
+
+///
+/// @brief set_symbol1_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note MBSMSECQ_MCE_SYMBOL1_COUNT: MCE Symbol 1 Error Count This is a 8-bit count
+/// @note that increments on MCE when Symbol 1 under chip mark takes error. Will freeze
+/// @note its value upon incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_symbol1_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::SYMBOL1_COUNT, TT::SYMBOL1_COUNT_LEN>(i_value);
+ FAPI_INF("set_symbol1_count: 0x%03lx", i_value);
+}
+
+///
+/// @brief get_symbol1_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note MBSMSECQ_MCE_SYMBOL1_COUNT: MCE Symbol 1 Error Count This is a 8-bit count
+/// @note that increments on MCE when Symbol 1 under chip mark takes error. Will freeze
+/// @note its value upon incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_symbol1_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::SYMBOL1_COUNT, TT::SYMBOL1_COUNT_LEN>(o_value);
+ FAPI_INF("get_symbol1_count: 0x%03lx", o_value);
+}
+
+///
+/// @brief set_symbol2_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note MBSMSECQ_MCE_SYMBOL2_COUNT: MCE Symbol 2 Error Count This is a 8-bit count
+/// @note that increments on MCE when Symbol 2 under chip mark takes error. Will freeze
+/// @note its value upon incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_symbol2_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::SYMBOL2_COUNT, TT::SYMBOL2_COUNT_LEN>(i_value);
+ FAPI_INF("set_symbol2_count: 0x%03lx", i_value);
+}
+
+///
+/// @brief get_symbol2_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note MBSMSECQ_MCE_SYMBOL2_COUNT: MCE Symbol 2 Error Count This is a 8-bit count
+/// @note that increments on MCE when Symbol 2 under chip mark takes error. Will freeze
+/// @note its value upon incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_symbol2_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::SYMBOL2_COUNT, TT::SYMBOL2_COUNT_LEN>(o_value);
+ FAPI_INF("get_symbol2_count: 0x%03lx", o_value);
+}
+
+///
+/// @brief set_symbol3_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in, out] io_data the register value
+/// @param[in] i_value the value of the field
+/// @note MBSMSECQ_MCE_SYMBOL3_COUNT: MCE Symbol 3 Error Count This is a 8-bit count
+/// @note that increments on MCE when Symbol 3 under chip mark takes error. Will freeze
+/// @note its value upon incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void set_symbol3_count( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value )
+{
+ io_data.insertFromRight<TT::SYMBOL3_COUNT, TT::SYMBOL3_COUNT_LEN>(i_value);
+ FAPI_INF("set_symbol3_count: 0x%03lx", i_value);
+}
+
+///
+/// @brief get_symbol3_count
+/// @tparam T fapi2 Target Type defaults to DEFAULT_MC_TARGET
+/// @tparam TT traits type defaults to eccTraits<DEFAULT_MC_TYPE, T>
+/// @param[in] i_data the register value
+/// @param[out] o_value the value of the field
+/// @note MBSMSECQ_MCE_SYMBOL3_COUNT: MCE Symbol 3 Error Count This is a 8-bit count
+/// @note that increments on MCE when Symbol 3 under chip mark takes error. Will freeze
+/// @note its value upon incrementing to the max value until reset.
+///
+template< fapi2::TargetType T = DEFAULT_MC_TARGET, typename TT = eccTraits<DEFAULT_MC_TYPE, T> >
+inline void get_symbol3_count( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value )
+{
+ i_data.extractToRight<TT::SYMBOL3_COUNT, TT::SYMBOL3_COUNT_LEN>(o_value);
+ FAPI_INF("get_symbol3_count: 0x%03lx", o_value);
+}
+
+} // close namespace mark_symbol_count_reg
+
+} // close namespace ecc
+
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/mss_generic_attribute_getters.H b/src/import/generic/memory/lib/mss_generic_attribute_getters.H
index f16829f3b..f18b799ea 100644
--- a/src/import/generic/memory/lib/mss_generic_attribute_getters.H
+++ b/src/import/generic/memory/lib/mss_generic_attribute_getters.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,6 +37,33 @@ namespace mss
namespace attr
{
///
+/// @brief ATTR_BAD_DQ_BITMAP getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_other_attr_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Bad DQ bitmap from a controller point of view. The data is a 10 byte bitmap for
+/// each of 4 possible ranks. The bad DQ data is stored in NVRAM, and it is stored in
+/// a special format translated to a DIMM Connector point of view. All of these details
+/// are hidden from the user of this attribute.
+///
+inline fapi2::ReturnCode get_bad_dq_bitmap(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4][10])
+{
+ uint8_t l_value[4][10] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_BAD_DQ_BITMAP, i_target, l_value) );
+ memcpy(o_array, &l_value, 40);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_BAD_DQ_BITMAP: 0x%lx",
+ uint64_t(fapi2::current_err));
+ return fapi2::current_err;
+}
+
+
+///
/// @brief ATTR_MEM_DIMM_POS_METADATA getter
/// @param[in] const ref to the TARGET_TYPE_DIMM
/// @param[out] uint32_t& reference to store the value
@@ -960,27 +987,45 @@ fapi_try_exit:
///
-/// @brief ATTR_BAD_DQ_BITMAP getter
-/// @param[in] const ref to the TARGET_TYPE_DIMM
-/// @param[out] uint8_t&[] array reference to store the value
+/// @brief ATTR_OMI_DL_PREIPL_PRBS_TIME getter
+/// @param[in] const ref to the TARGET_TYPE_OMI
+/// @param[out] uint32_t& reference to store the value
/// @note Generated by gen_accessors.pl generate_other_attr_params
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Bad DQ bitmap from a controller point of view. The data is a 10 byte bitmap for
-/// each of 4 possible ranks. The bad DQ data is stored in NVRAM, and it is stored in
-/// a special format translated to a DIMM Connector point of view. All of these details
-/// are hidden from the user of this attribute.
+/// @note The time to send pre-ipl PRBS in ms.
///
-inline fapi2::ReturnCode get_bad_dq_bitmap(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- uint8_t (&o_array)[4][10])
+inline fapi2::ReturnCode get_omi_dl_preipl_prbs_time(const fapi2::Target<fapi2::TARGET_TYPE_OMI>& i_target,
+ uint32_t& o_value)
{
- uint8_t l_value[4][10] = {};
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_BAD_DQ_BITMAP, i_target, l_value) );
- memcpy(o_array, &l_value, 40);
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_OMI_DL_PREIPL_PRBS_TIME, i_target, o_value) );
return fapi2::current_err;
fapi_try_exit:
- FAPI_ERR("failed getting ATTR_BAD_DQ_BITMAP: 0x%lx",
+ FAPI_ERR("failed getting ATTR_OMI_DL_PREIPL_PRBS_TIME: 0x%lx",
+ uint64_t(fapi2::current_err));
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief ATTR_MSS_OMI_EDPL_DISABLE getter
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_other_attr_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note EDPL (Error Detection Per Lane) is a feature in the DL that adds some additional
+/// checks to the traffic going across the OpenCAPI link in order to better track which
+/// lanes are having issues. Note: EDPL must be set the same on both sides of the link.
+/// This attribute affects both the proc/mc side and the OCMB side.
+///
+inline fapi2::ReturnCode get_mss_omi_edpl_disable(uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OMI_EDPL_DISABLE, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MSS_OMI_EDPL_DISABLE: 0x%lx",
uint64_t(fapi2::current_err));
return fapi2::current_err;
}
@@ -1464,14 +1509,60 @@ fapi_try_exit:
}
///
+/// @brief ATTR_MEM_EFF_PRIM_DIE_COUNT getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Primary SDRAM Die Count. Decodes Byte 6 (bits 6~4).
+///
+inline fapi2::ReturnCode get_prim_die_count(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_PRIM_DIE_COUNT, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_PRIM_DIE_COUNT: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_PRIM_DIE_COUNT getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Primary SDRAM Die Count. Decodes Byte 6 (bits 6~4).
+///
+inline fapi2::ReturnCode get_prim_die_count(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_PRIM_DIE_COUNT, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_PRIM_DIE_COUNT: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
/// @brief ATTR_MEM_EFF_PRIM_STACK_TYPE getter
/// @param[in] const ref to the TARGET_TYPE_DIMM
/// @param[out] uint8_t& reference to store the value
/// @note Generated by gen_accessors.pl generate_mc_port_params
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note ARRAY[DIMM] Primary SDRAM Package Type. Decodes Byte 6. This byte defines the primary
-/// set of SDRAMs. Monolithic = SPD, Multi-load stack = DDP/QDP, Single-load stack =
-/// 3DS
+/// @note ARRAY[DIMM] Primary SDRAM Package Type (bits 1~0). Decodes Byte 6. This byte defines
+/// the primary set of SDRAMs. Monolithic = SPD, Multi-load stack = DDP/QDP, Single-load
+/// stack = 3DS
///
inline fapi2::ReturnCode get_prim_stack_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
{
@@ -1494,9 +1585,9 @@ fapi_try_exit:
/// @param[out] uint8_t&[] array reference to store the value
/// @note Generated by gen_accessors.pl generate_mc_port_params
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note ARRAY[DIMM] Primary SDRAM Package Type. Decodes Byte 6. This byte defines the primary
-/// set of SDRAMs. Monolithic = SPD, Multi-load stack = DDP/QDP, Single-load stack =
-/// 3DS
+/// @note ARRAY[DIMM] Primary SDRAM Package Type (bits 1~0). Decodes Byte 6. This byte defines
+/// the primary set of SDRAMs. Monolithic = SPD, Multi-load stack = DDP/QDP, Single-load
+/// stack = 3DS
///
inline fapi2::ReturnCode get_prim_stack_type(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
uint8_t (&o_array)[2])
@@ -1514,6 +1605,52 @@ fapi_try_exit:
}
///
+/// @brief ATTR_MEM_EFF_PRIM_BUS_WIDTH getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Primary bus with (bits 1~0). Decodes Byte 13.
+///
+inline fapi2::ReturnCode get_prim_bus_width(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_PRIM_BUS_WIDTH, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_PRIM_BUS_WIDTH: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_PRIM_BUS_WIDTH getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Primary bus with (bits 1~0). Decodes Byte 13.
+///
+inline fapi2::ReturnCode get_prim_bus_width(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_PRIM_BUS_WIDTH, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_PRIM_BUS_WIDTH: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
/// @brief ATTR_MEM_EFF_DRAM_PPR getter
/// @param[in] const ref to the TARGET_TYPE_DIMM
/// @param[out] uint8_t& reference to store the value
@@ -1968,7 +2105,7 @@ fapi_try_exit:
}
///
-/// @brief ATTR_MEM_EFF_NUM_RANKS_PER_DIMM getter
+/// @brief ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM getter
/// @param[in] const ref to the TARGET_TYPE_DIMM
/// @param[out] uint8_t& reference to store the value
/// @note Generated by gen_accessors.pl generate_mc_port_params
@@ -1979,24 +2116,24 @@ fapi_try_exit:
/// number of logical ranks per DIMM. Logical rank refers the individually addressable
/// die in a 3DS stack and has no meaning for monolithic or multi-load stacked SDRAMs.
///
-inline fapi2::ReturnCode get_num_ranks_per_dimm(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+inline fapi2::ReturnCode get_logical_ranks_per_dimm(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
uint8_t& o_value)
{
uint8_t l_value[2] = {};
const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_NUM_RANKS_PER_DIMM, l_port, l_value) );
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM, l_port, l_value) );
o_value = l_value[mss::index(i_target)];
return fapi2::current_err;
fapi_try_exit:
- FAPI_ERR("failed getting ATTR_MEM_EFF_NUM_RANKS_PER_DIMM: 0x%lx (target: %s)",
+ FAPI_ERR("failed getting ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM: 0x%lx (target: %s)",
uint64_t(fapi2::current_err), mss::c_str(i_target));
return fapi2::current_err;
}
///
-/// @brief ATTR_MEM_EFF_NUM_RANKS_PER_DIMM getter
+/// @brief ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM getter
/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
/// @param[out] uint8_t&[] array reference to store the value
/// @note Generated by gen_accessors.pl generate_mc_port_params
@@ -2007,17 +2144,63 @@ fapi_try_exit:
/// number of logical ranks per DIMM. Logical rank refers the individually addressable
/// die in a 3DS stack and has no meaning for monolithic or multi-load stacked SDRAMs.
///
-inline fapi2::ReturnCode get_num_ranks_per_dimm(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+inline fapi2::ReturnCode get_logical_ranks_per_dimm(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
uint8_t (&o_array)[2])
{
uint8_t l_value[2] = {};
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_NUM_RANKS_PER_DIMM, i_target, l_value) );
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM, i_target, l_value) );
memcpy(o_array, &l_value, 2);
return fapi2::current_err;
fapi_try_exit:
- FAPI_ERR("failed getting ATTR_MEM_EFF_NUM_RANKS_PER_DIMM: 0x%lx (target: %s)",
+ FAPI_ERR("failed getting ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_3DS_HEIGHT getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint16_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Setting for 3DS stack. Calculated from logical_ranks / master_ranks
+///
+inline fapi2::ReturnCode get_3ds_height(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint16_t& o_value)
+{
+ uint16_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_3DS_HEIGHT, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_3DS_HEIGHT: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_3DS_HEIGHT getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint16_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Setting for 3DS stack. Calculated from logical_ranks / master_ranks
+///
+inline fapi2::ReturnCode get_3ds_height(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint16_t (&o_array)[2])
+{
+ uint16_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_3DS_HEIGHT, i_target, l_value) );
+ memcpy(o_array, &l_value, 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_3DS_HEIGHT: 0x%lx (target: %s)",
uint64_t(fapi2::current_err), mss::c_str(i_target));
return fapi2::current_err;
}
@@ -2074,7 +2257,8 @@ fapi_try_exit:
/// @param[out] uint16_t& reference to store the value
/// @note Generated by gen_accessors.pl generate_mc_port_params
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note ARRAY[DIMM] DRAM Manufacturer ID Code Decodes SPD Byte 350 and 351
+/// @note ARRAY[DIMM] DRAM Manufacturer ID Code Decodes SPD Byte 350 and 351 for ISDIMMs Decodes
+/// SPD Byte 552 and 553 for DDIMMs
///
inline fapi2::ReturnCode get_dram_mfg_id(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint16_t& o_value)
{
@@ -2097,7 +2281,8 @@ fapi_try_exit:
/// @param[out] uint16_t&[] array reference to store the value
/// @note Generated by gen_accessors.pl generate_mc_port_params
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note ARRAY[DIMM] DRAM Manufacturer ID Code Decodes SPD Byte 350 and 351
+/// @note ARRAY[DIMM] DRAM Manufacturer ID Code Decodes SPD Byte 350 and 351 for ISDIMMs Decodes
+/// SPD Byte 552 and 553 for DDIMMs
///
inline fapi2::ReturnCode get_dram_mfg_id(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
uint16_t (&o_array)[2])
@@ -2115,6 +2300,53 @@ fapi_try_exit:
}
///
+/// @brief ATTR_MEM_EFF_DRAM_MODULE_HEIGHT getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] DRAM Modlue Height Decodes SPD Byte 193
+///
+inline fapi2::ReturnCode get_dram_module_height(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_MODULE_HEIGHT, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_MODULE_HEIGHT: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_MODULE_HEIGHT getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] DRAM Modlue Height Decodes SPD Byte 193
+///
+inline fapi2::ReturnCode get_dram_module_height(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_MODULE_HEIGHT, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_MODULE_HEIGHT: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
/// @brief ATTR_MEM_EFF_RCD_MFG_ID getter
/// @param[in] const ref to the TARGET_TYPE_DIMM
/// @param[out] uint16_t& reference to store the value
@@ -2414,6 +2646,26 @@ fapi_try_exit:
}
///
+/// @brief ATTR_MEM_EFF_DRAM_MDS getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Controls if the given target has an MDS (managed DRAM solution)
+///
+inline fapi2::ReturnCode get_dram_mds(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_MDS, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_MDS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
/// @brief ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM getter
/// @param[in] const ref to the TARGET_TYPE_DIMM
/// @param[out] uint8_t& reference to store the value
@@ -2602,6 +2854,26 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief ATTR_MEM_EFF_SPD_REVISION getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note SPD Revision (SPD Byte 1)
+///
+inline fapi2::ReturnCode get_spd_revision(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_SPD_REVISION, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_SPD_REVISION: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
///
/// @brief ATTR_MEM_EFF_VOLT_VDDR getter
@@ -3106,100 +3378,6 @@ fapi_try_exit:
}
///
-/// @brief ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE getter
-/// @param[in] const ref to the TARGET_TYPE_DIMM
-/// @param[out] uint8_t&[] array reference to store the value
-/// @note Generated by gen_accessors.pl generate_mc_port_params
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note ARRAY[DIMM][RANK] vrefdq_train value. This is for DDR4 MRS6.
-///
-inline fapi2::ReturnCode get_si_vref_dq_train_value(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- uint8_t (&o_array)[4])
-{
- uint8_t l_value[2][4] = {};
- const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE, l_port, l_value) );
- memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed getting ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE getter
-/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
-/// @param[out] uint8_t&[] array reference to store the value
-/// @note Generated by gen_accessors.pl generate_mc_port_params
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note ARRAY[DIMM][RANK] vrefdq_train value. This is for DDR4 MRS6.
-///
-inline fapi2::ReturnCode get_si_vref_dq_train_value(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
- uint8_t (&o_array)[2][4])
-{
- uint8_t l_value[2][4] = {};
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE, i_target, l_value) );
- memcpy(o_array, &l_value, 8);
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed getting ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE getter
-/// @param[in] const ref to the TARGET_TYPE_DIMM
-/// @param[out] uint8_t&[] array reference to store the value
-/// @note Generated by gen_accessors.pl generate_mc_port_params
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note ARRAY[DIMM][RANK] vrefdq_train range. This is for DDR4 MRS6.
-///
-inline fapi2::ReturnCode get_si_vref_dq_train_range(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- uint8_t (&o_array)[4])
-{
- uint8_t l_value[2][4] = {};
- const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE, l_port, l_value) );
- memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed getting ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE getter
-/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
-/// @param[out] uint8_t&[] array reference to store the value
-/// @note Generated by gen_accessors.pl generate_mc_port_params
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note ARRAY[DIMM][RANK] vrefdq_train range. This is for DDR4 MRS6.
-///
-inline fapi2::ReturnCode get_si_vref_dq_train_range(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
- uint8_t (&o_array)[2][4])
-{
- uint8_t l_value[2][4] = {};
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE, i_target, l_value) );
- memcpy(o_array, &l_value, 8);
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed getting ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
/// @brief ATTR_MEM_SI_GEARDOWN_MODE getter
/// @param[in] const ref to the TARGET_TYPE_DIMM
/// @param[out] uint8_t&[] array reference to store the value
@@ -3590,20 +3768,20 @@ fapi_try_exit:
///
/// @brief ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN getter
/// @param[in] const ref to the TARGET_TYPE_DIMM
-/// @param[out] uint8_t&[] array reference to store the value
+/// @param[out] uint16_t&[] array reference to store the value
/// @note Generated by gen_accessors.pl generate_mc_port_params
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance Pull Down for Data and
/// Data Strobe Lines in Ohms.
///
inline fapi2::ReturnCode get_si_mc_drv_imp_dq_dqs_pull_down(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- uint8_t (&o_array)[4])
+ uint16_t (&o_array)[4])
{
- uint8_t l_value[2][4] = {};
+ uint16_t l_value[2][4] = {};
const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN, l_port, l_value) );
- memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 8);
return fapi2::current_err;
fapi_try_exit:
@@ -3615,19 +3793,19 @@ fapi_try_exit:
///
/// @brief ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN getter
/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
-/// @param[out] uint8_t&[] array reference to store the value
+/// @param[out] uint16_t&[] array reference to store the value
/// @note Generated by gen_accessors.pl generate_mc_port_params
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance Pull Down for Data and
/// Data Strobe Lines in Ohms.
///
inline fapi2::ReturnCode get_si_mc_drv_imp_dq_dqs_pull_down(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
- uint8_t (&o_array)[2][4])
+ uint16_t (&o_array)[2][4])
{
- uint8_t l_value[2][4] = {};
+ uint16_t l_value[2][4] = {};
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN, i_target, l_value) );
- memcpy(o_array, &l_value, 8);
+ memcpy(o_array, &l_value, 16);
return fapi2::current_err;
fapi_try_exit:
@@ -3639,20 +3817,20 @@ fapi_try_exit:
///
/// @brief ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP getter
/// @param[in] const ref to the TARGET_TYPE_DIMM
-/// @param[out] uint8_t&[] array reference to store the value
+/// @param[out] uint16_t&[] array reference to store the value
/// @note Generated by gen_accessors.pl generate_mc_port_params
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance Pull Up for Data and Data
/// Strobe Lines in Ohms.
///
inline fapi2::ReturnCode get_si_mc_drv_imp_dq_dqs_pull_up(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- uint8_t (&o_array)[4])
+ uint16_t (&o_array)[4])
{
- uint8_t l_value[2][4] = {};
+ uint16_t l_value[2][4] = {};
const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP, l_port, l_value) );
- memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 8);
return fapi2::current_err;
fapi_try_exit:
@@ -3664,19 +3842,19 @@ fapi_try_exit:
///
/// @brief ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP getter
/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
-/// @param[out] uint8_t&[] array reference to store the value
+/// @param[out] uint16_t&[] array reference to store the value
/// @note Generated by gen_accessors.pl generate_mc_port_params
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance Pull Up for Data and Data
/// Strobe Lines in Ohms.
///
inline fapi2::ReturnCode get_si_mc_drv_imp_dq_dqs_pull_up(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
- uint8_t (&o_array)[2][4])
+ uint16_t (&o_array)[2][4])
{
- uint8_t l_value[2][4] = {};
+ uint16_t l_value[2][4] = {};
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP, i_target, l_value) );
- memcpy(o_array, &l_value, 8);
+ memcpy(o_array, &l_value, 16);
return fapi2::current_err;
fapi_try_exit:
@@ -4032,7 +4210,8 @@ fapi_try_exit:
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Array[DIMM][RANK] READ, On Die Termination triggering bitmap. Use bitmap to determine
/// which ODT to fire for the designated rank. The bits in 8 bit field are [DIMM0 ODT0][DIMM0
-/// ODT1][DIMM0 ODT2][DIMM0 ODT3][DIMM1 ODT0][DIMM1 ODT1][DIMM1 ODT2][DIMM1 ODT3]
+/// ODT1][DIMM0 ODT2][DIMM0 ODT3][DIMM1 ODT0][DIMM1 ODT1][DIMM1 ODT2][DIMM1 ODT3] For
+/// Explorer: Only bits 0,1,4,5 are used. They correspond to A0 A1 -- -- B0 B1 -- --
///
inline fapi2::ReturnCode get_si_odt_rd(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t (&o_array)[4])
{
@@ -4057,7 +4236,8 @@ fapi_try_exit:
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Array[DIMM][RANK] READ, On Die Termination triggering bitmap. Use bitmap to determine
/// which ODT to fire for the designated rank. The bits in 8 bit field are [DIMM0 ODT0][DIMM0
-/// ODT1][DIMM0 ODT2][DIMM0 ODT3][DIMM1 ODT0][DIMM1 ODT1][DIMM1 ODT2][DIMM1 ODT3]
+/// ODT1][DIMM0 ODT2][DIMM0 ODT3][DIMM1 ODT0][DIMM1 ODT1][DIMM1 ODT2][DIMM1 ODT3] For
+/// Explorer: Only bits 0,1,4,5 are used. They correspond to A0 A1 -- -- B0 B1 -- --
///
inline fapi2::ReturnCode get_si_odt_rd(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
uint8_t (&o_array)[2][4])
@@ -4082,7 +4262,8 @@ fapi_try_exit:
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Array[DIMM][RANK] WRITE, On Die Termination triggering bitmap. Use bitmap to determine
/// which ODT to fire for the designated rank. The bits in 8 bit field are [DIMM0 ODT0][DIMM0
-/// ODT1][DIMM0 ODT2][DIMM0 ODT3][DIMM1 ODT0][DIMM1 ODT1][DIMM1 ODT2][DIMM1 ODT3]
+/// ODT1][DIMM0 ODT2][DIMM0 ODT3][DIMM1 ODT0][DIMM1 ODT1][DIMM1 ODT2][DIMM1 ODT3] For
+/// Explorer: Only bits 0,1,4,5 are used. They correspond to A0 A1 -- -- B0 B1 -- --
///
inline fapi2::ReturnCode get_si_odt_wr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t (&o_array)[4])
{
@@ -4107,7 +4288,8 @@ fapi_try_exit:
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Array[DIMM][RANK] WRITE, On Die Termination triggering bitmap. Use bitmap to determine
/// which ODT to fire for the designated rank. The bits in 8 bit field are [DIMM0 ODT0][DIMM0
-/// ODT1][DIMM0 ODT2][DIMM0 ODT3][DIMM1 ODT0][DIMM1 ODT1][DIMM1 ODT2][DIMM1 ODT3]
+/// ODT1][DIMM0 ODT2][DIMM0 ODT3][DIMM1 ODT0][DIMM1 ODT1][DIMM1 ODT2][DIMM1 ODT3] For
+/// Explorer: Only bits 0,1,4,5 are used. They correspond to A0 A1 -- -- B0 B1 -- --
///
inline fapi2::ReturnCode get_si_odt_wr(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
uint8_t (&o_array)[2][4])
diff --git a/src/import/generic/memory/lib/prd/hwp_wrappers.H b/src/import/generic/memory/lib/prd/hwp_wrappers.H
new file mode 100644
index 000000000..afbb34a81
--- /dev/null
+++ b/src/import/generic/memory/lib/prd/hwp_wrappers.H
@@ -0,0 +1,246 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/generic/memory/lib/prd/hwp_wrappers.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file hwp_wrappers.H
+/// @brief Main wrapper file for PRD calling memory procedure code
+///
+// *HWP HWP Owner: Matthew Hickman <Matthew.Hickman@ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _HWP_WRAPPERS_H_
+#define _HWP_WRAPPERS_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_memdiags.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H>
+#include <chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist_traits.H>
+
+///
+/// @brief Memdiags stop command wrapper for Nimbus
+/// @param[in] i_target the target
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode nim_stop( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target );
+
+///
+/// @brief Memdiags stop command wrapper for Explorer
+/// @param[in] i_target the target
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode exp_stop( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target );
+
+///
+/// @brief Memdiags Super Fast Init command wrapper for Nimbus
+/// @param[in] i_target the target behind which all memory should be initialized
+/// @param[in] i_pattern an index representing a pattern to use to init memory (defaults to 0)
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode nim_sf_init( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const uint64_t i_pattern );
+
+///
+/// @brief Memdiags Super Fast Init command wrapper for Nimbus
+/// @param[in] i_target the target behind which all memory should be initialized
+/// @param[in] i_pattern an index representing a pattern to use to init memory (defaults to 0)
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode exp_sf_init( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint64_t i_pattern );
+
+///
+/// @brief Memdiags Super Fast Read command wrapper for Nimbus
+/// @param[in] i_target the target behind which all memory should be read
+/// @param[in] i_stop stop conditions
+/// @param[in] i_address mcbist::address representing the address from which to start.
+// Defaults to the first address behind the target
+/// @param[in] i_end whether to end, and where
+/// Defaults to stop after slave rank
+/// @param[in] i_end_address mcbist::address representing the address to end.
+// Defaults to TT::LARGEST_ADDRESS
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode nim_sf_read( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const mss::mcbist::stop_conditions<mss::mc_type::NIMBUS>& i_stop,
+ const mss::mcbist::address& i_address = mss::mcbist::address(),
+ const mss::mcbist::end_boundary i_end = mss::mcbist::end_boundary::STOP_AFTER_SLAVE_RANK,
+ const mss::mcbist::address& i_end_address = mss::mcbist::address(
+ mss::mcbistTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCBIST>::LARGEST_ADDRESS) );
+
+///
+/// @brief Memdiags Super Fast Read command wrapper for Explorer
+/// @param[in] i_target the target behind which all memory should be read
+/// @param[in] i_stop stop conditions
+/// @param[in] i_address mcbist::address representing the address from which to start.
+// Defaults to the first address behind the target
+/// @param[in] i_end whether to end, and where
+/// Defaults to stop after slave rank
+/// @param[in] i_end_address mcbist::address representing the address to end.
+// Defaults to TT::LARGEST_ADDRESS
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode exp_sf_read( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const mss::mcbist::stop_conditions<mss::mc_type::EXPLORER>& i_stop,
+ const mss::mcbist::address& i_address = mss::mcbist::address(),
+ const mss::mcbist::end_boundary i_end = mss::mcbist::end_boundary::STOP_AFTER_SLAVE_RANK,
+ const mss::mcbist::address& i_end_address = mss::mcbist::address(
+ mss::mcbistTraits<mss::mc_type::EXPLORER, fapi2::TARGET_TYPE_OCMB_CHIP>::LARGEST_ADDRESS) );
+
+///
+/// @brief Continuous background scrub command wrapper for Nimbus
+/// @param[in] i_target the target behind which all memory should be scrubbed
+/// @param[in] i_stop stop conditions
+/// @param[in] i_speed the speed to scrub
+/// @param[in] i_address mcbist::address representing the address from which to start.
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode nim_background_scrub( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const mss::mcbist::stop_conditions<mss::mc_type::NIMBUS>& i_stop,
+ const mss::mcbist::speed i_speed,
+ const mss::mcbist::address& i_address );
+
+///
+/// @brief Continuous background scrub command wrapper for Explorer
+/// @param[in] i_target the target behind which all memory should be scrubbed
+/// @param[in] i_stop stop conditions
+/// @param[in] i_speed the speed to scrub
+/// @param[in] i_address mcbist::address representing the address from which to start.
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode exp_background_scrub( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const mss::mcbist::stop_conditions<mss::mc_type::EXPLORER>& i_stop,
+ const mss::mcbist::speed i_speed,
+ const mss::mcbist::address& i_address );
+
+///
+/// @brief Targeted scrub command wrapper for Nimbus
+/// @param[in] i_target the target behind which all memory should be scrubbed
+/// @param[in] i_stop stop conditions
+/// @param[in] i_speed the speed to scrub
+/// @param[in] i_start_address mcbist::address representing the address from which to start.
+/// @param[in] i_end_address mcbist::address representing the address at which to end.
+/// @param[in] i_end whether to end, and where
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode nim_targeted_scrub( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const mss::mcbist::stop_conditions<mss::mc_type::NIMBUS>& i_stop,
+ const mss::mcbist::address& i_start_address,
+ const mss::mcbist::address& i_end_address,
+ const mss::mcbist::end_boundary i_end );
+
+///
+/// @brief Targeted scrub command wrapper for Explorer
+/// @param[in] i_target the target behind which all memory should be scrubbed
+/// @param[in] i_stop stop conditions
+/// @param[in] i_speed the speed to scrub
+/// @param[in] i_start_address mcbist::address representing the address from which to start.
+/// @param[in] i_end_address mcbist::address representing the address at which to end.
+/// @param[in] i_end whether to end, and where
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+fapi2::ReturnCode exp_targeted_scrub( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const mss::mcbist::stop_conditions<mss::mc_type::EXPLORER>& i_stop,
+ const mss::mcbist::address& i_start_address,
+ const mss::mcbist::address& i_end_address,
+ const mss::mcbist::end_boundary i_end );
+
+///
+/// @brief Continue current command wrapper for Nimbus
+/// @param[in] i_target the target
+/// @param[in] i_end whether to end, and where (default - don't stop at end of rank)
+/// @param[in] i_stop stop conditions (default - 0 meaning 'don't change conditions')
+/// @param[in] i_speed the speed to scrub (default - SAME_SPEED meaning leave speed untouched)
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode nim_continue_cmd( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const mss::mcbist::end_boundary i_end = mss::mcbist::end_boundary::DONT_CHANGE,
+ const mss::mcbist::stop_conditions<mss::mc_type::NIMBUS>& i_stop = mss::mcbist::stop_conditions<mss::mc_type::NIMBUS>
+ (mss::mcbist::stop_conditions<mss::mc_type::NIMBUS>::DONT_CHANGE),
+ const mss::mcbist::speed i_speed = mss::mcbist::speed::SAME_SPEED );
+
+///
+/// @brief Continue current command wrapper for Explorer
+/// @param[in] i_target the target
+/// @param[in] i_end whether to end, and where (default - don't stop at end of rank)
+/// @param[in] i_stop stop conditions (default - 0 meaning 'don't change conditions')
+/// @param[in] i_speed the speed to scrub (default - SAME_SPEED meaning leave speed untouched)
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode exp_continue_cmd( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const mss::mcbist::end_boundary i_end = mss::mcbist::end_boundary::DONT_CHANGE,
+ const mss::mcbist::stop_conditions<mss::mc_type::EXPLORER>& i_stop =
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER>
+ (mss::mcbist::stop_conditions<mss::mc_type::EXPLORER>::DONT_CHANGE),
+ const mss::mcbist::speed i_speed = mss::mcbist::speed::SAME_SPEED );
+
+///
+/// @brief Broadcast mode check wrapper for Nimbus
+/// @param[in] i_target the target to effect
+/// @return o_capable - yes iff these vector of targets are broadcast capable
+///
+const mss::states nim_is_broadcast_capable(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target);
+
+
+///
+/// @brief Broadcast mode check wrapper for Nimbus
+/// @param[in] i_targets the vector of targets to analyze
+/// @return o_capable - yes iff these vector of targets are broadcast capable
+///
+const mss::states nim_is_broadcast_capable(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCBIST>>& i_targets);
+
+///
+/// @brief Broadcast mode check wrapper for Nimbus
+/// @param[in] i_kinds the dimms to effect
+/// @return o_capable - yes iff these vector of targets are broadcast capable
+///
+const mss::states nim_is_broadcast_capable(const std::vector<mss::dimm::kind<>>& i_kinds);
+
+///
+/// @brief Broadcast mode check wrapper for Explorer
+/// @param[in] i_target the target to effect
+/// @return o_capable - yes iff these vector of targets are broadcast capable
+///
+const mss::states exp_is_broadcast_capable(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
+
+
+///
+/// @brief Broadcast mode check wrapper for Explorer
+/// @param[in] i_targets the vector of targets to analyze
+/// @return o_capable - yes iff these vector of targets are broadcast capable
+///
+const mss::states exp_is_broadcast_capable(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>>& i_targets);
+
+///
+/// @brief Broadcast mode check wrapper for Explorer
+/// @param[in] i_kinds the dimms to effect
+/// @return o_capable - yes iff these vector of targets are broadcast capable
+///
+const mss::states exp_is_broadcast_capable(const std::vector<mss::dimm::kind<>>& i_kinds);
+
+#endif
diff --git a/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H b/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H
index 12821c76f..1ebd48115 100644
--- a/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H
+++ b/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H
@@ -493,7 +493,7 @@ class decoder<DDR4, BASE_CNFG, R> : public base_cnfg_decoder
right_aligned_insert(l_buffer, l_twrmin_msn, l_twrmin_lsb);
// Update output only after check passes
- FAPI_TRY( check::max_timing_range<BITS12>(i_target, l_buffer, TWRMIN));
+ FAPI_TRY( check::max_timing_range<BITS12>(i_target, l_buffer, U, TWRMIN));
o_value = l_buffer;
FAPI_INF("%s. Minimum Write Recovery Time (tWRmin) in MTB units: %d",
@@ -526,7 +526,7 @@ class decoder<DDR4, BASE_CNFG, R> : public base_cnfg_decoder
right_aligned_insert(l_buffer, l_twtr_lmin_msn, l_twtr_lmin_lsb);
// Update output only after check passes
- FAPI_TRY( check::max_timing_range<BITS12>(i_target, l_buffer, TWTR_L_MIN));
+ FAPI_TRY( check::max_timing_range<BITS12>(i_target, l_buffer, U, TWTR_L_MIN));
o_value = l_buffer;
FAPI_INF("%s. Minimum Write to Read Time - Different Bank Group (tWTR_Lmin) in MTB units: %d",
@@ -560,7 +560,7 @@ class decoder<DDR4, BASE_CNFG, R> : public base_cnfg_decoder
right_aligned_insert(l_buffer, l_twtr_smin_msn, l_twtr_smin_lsb);
// Update output only after check passes
- FAPI_TRY( check::max_timing_range<BITS12>(i_target, l_buffer, TWTR_S_MIN));
+ FAPI_TRY( check::max_timing_range<BITS12>(i_target, l_buffer, U, TWTR_S_MIN));
o_value = l_buffer;
FAPI_INF("%s. Minimum Write to Read Time - Different Bank Group (tWTR_Smin) in MTB units: %d",
@@ -1275,7 +1275,7 @@ class decoder<DDR4, BASE_CNFG, R> : public base_cnfg_decoder
right_aligned_insert(l_buffer, l_tRASmin_msn, l_tRASmin_lsb);
// Update output only after check passes
- FAPI_TRY( check::max_timing_range<BITS12>(iv_target, l_buffer, TRASMIN));
+ FAPI_TRY( check::max_timing_range<BITS12>(iv_target, l_buffer, R, TRASMIN));
o_value = l_buffer;
FAPI_INF("%s. Minimum Active to Precharge Delay Time (tRASmin) in MTB units: %d",
@@ -1305,7 +1305,7 @@ class decoder<DDR4, BASE_CNFG, R> : public base_cnfg_decoder
right_aligned_insert(l_buffer, l_trcmin_msn, l_trcmin_lsb);
// Update output only after check passes
- FAPI_TRY( check::max_timing_range<BITS12>(iv_target, l_buffer, TRCMIN));
+ FAPI_TRY( check::max_timing_range<BITS12>(iv_target, l_buffer, R, TRCMIN));
o_value = l_buffer;
FAPI_INF("%s. Minimum Active to Active/Refresh Delay Time (tRCmin) in MTB units: %d",
@@ -1336,7 +1336,7 @@ class decoder<DDR4, BASE_CNFG, R> : public base_cnfg_decoder
right_aligned_insert(l_buffer, l_trfc1min_msb, l_trfc1min_lsb);
// Update output only after check passes
- FAPI_TRY( check::max_timing_range<BITS16>(iv_target, l_buffer, TRFC1MIN));
+ FAPI_TRY( check::max_timing_range<BITS16>(iv_target, l_buffer, R, TRFC1MIN));
o_value = l_buffer;
FAPI_INF("%s. Minimum Refresh Recovery Delay Time 1 (tRFC1min) in MTB units: %d",
@@ -1366,7 +1366,7 @@ class decoder<DDR4, BASE_CNFG, R> : public base_cnfg_decoder
right_aligned_insert(l_buffer, l_trfc2min_msb, l_trfc2min_lsb);
// Update output only after check passes
- FAPI_TRY( check::max_timing_range<BITS16>(iv_target, l_buffer, TRFC2MIN));
+ FAPI_TRY( check::max_timing_range<BITS16>(iv_target, l_buffer, R, TRFC2MIN));
o_value = l_buffer;
FAPI_INF("%s. Minimum Refresh Recovery Delay Time 2 (tRFC2min) in MTB units: %d",
@@ -1396,7 +1396,7 @@ class decoder<DDR4, BASE_CNFG, R> : public base_cnfg_decoder
right_aligned_insert(l_buffer, l_trfc4min_msb, l_trfc4min_lsb);
// Update output only after check passes
- FAPI_TRY( check::max_timing_range<BITS16>(iv_target, l_buffer, TRFC4MIN));
+ FAPI_TRY( check::max_timing_range<BITS16>(iv_target, l_buffer, R, TRFC4MIN));
o_value = l_buffer;
FAPI_INF("%s. Minimum Refresh Recovery Delay Time 4 (tRFC4min) in MTB units: %d",
@@ -1426,7 +1426,7 @@ class decoder<DDR4, BASE_CNFG, R> : public base_cnfg_decoder
right_aligned_insert(l_buffer, l_tfawmin_msn, l_tfawmin_lsb);
// Update output only after check passes
- FAPI_TRY( check::max_timing_range<BITS12>(iv_target, l_buffer, TFAWMIN));
+ FAPI_TRY( check::max_timing_range<BITS12>(iv_target, l_buffer, R, TFAWMIN));
o_value = l_buffer;
FAPI_INF("%s. Minimum Four Activate Window Delay Time (tFAWmin) in MTB units: %d",
diff --git a/src/import/generic/memory/lib/spd/common/dimm_module_decoder.H b/src/import/generic/memory/lib/spd/common/dimm_module_decoder.H
index 11e5f3a6e..7ccd72116 100644
--- a/src/import/generic/memory/lib/spd/common/dimm_module_decoder.H
+++ b/src/import/generic/memory/lib/spd/common/dimm_module_decoder.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -107,6 +107,17 @@ class dimm_module_decoder
}
///
+ /// @brief Decodes SPD Revision -> SPD_REVISION
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode revision(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
/// @brief Decodes module nominal height max
/// @param[out] o_output height range encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
@@ -559,11 +570,11 @@ class dimm_module_decoder
// DDIMM information from here on out
//////////////////////////////////////////
///
- /// @brief Decodes SPD Revision for bytes 192->447 -> SPD_REVISION
+ /// @brief Decodes SPD Revision for bytes 192->447 -> SPD_REV_DDIMM_MODULE
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode ddimm_spd_revision(uint8_t& o_output) const
+ virtual fapi2::ReturnCode ddimm_module_spd_revision(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
@@ -953,7 +964,7 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWA Voltage Setting -> PMIC0_SWA_RANGE
+ /// @brief Decodes PMIC0 SWA Voltage Setting -> PMIC0_SWA_RANGE_SETTING
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -975,11 +986,22 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWA Voltage Offset -> PMIC0_SWA_OFF_RANGE
+ /// @brief Decodes PMIC0 SWA Voltage Offset -> PMIC0_SWA_OFF_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swa_pmic0(uint8_t& o_output) const
+ virtual fapi2::ReturnCode volt_offset_direction_swa_pmic0(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWA Delay -> PMIC0_SWA_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_delay_swa_pmic0(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
@@ -1008,7 +1030,7 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWB Voltage Setting -> PMIC0_SWB_RANGE
+ /// @brief Decodes PMIC0 SWB Voltage Setting -> PMIC0_SWB_RANGE_SETTING
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1030,18 +1052,29 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWB Voltage Offset -> PMIC0_SWB_OFF_RANGE
+ /// @brief Decodes PMIC0 SWB Voltage Offset -> PMIC0_SWB_OFF_DIRECTION
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_offset_direction_swb_pmic0(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWB Delay -> PMIC0_SWB_DELAY
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swb_pmic0(uint8_t& o_output) const
+ virtual fapi2::ReturnCode volt_delay_swb_pmic0(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC0 SWB Delay Sequence Order -> PMIC0_SWB_ORDER
+ /// @brief Decodes PMIC0 SWB Sequence Order -> PMIC0_SWB_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1063,7 +1096,7 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWC Voltage Setting -> PMIC0_SWC_RANGE
+ /// @brief Decodes PMIC0 SWC Voltage Setting -> PMIC0_SWC_RANGE_SETTING
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1085,18 +1118,29 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWC Voltage Offset -> PMIC0_SWC_OFF_RANGE
+ /// @brief Decodes PMIC0 SWC Voltage Offset -> PMIC0_SWC_OFF_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swc_pmic0(uint8_t& o_output) const
+ virtual fapi2::ReturnCode volt_offset_direction_swc_pmic0(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC0 SWC Delay Sequence Order -> PMIC0_SWC_ORDER
+ /// @brief Decodes PMIC0 SWC Delay -> PMIC0_SWC_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_delay_swc_pmic0(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWC Sequence Order -> PMIC0_SWC_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1118,7 +1162,7 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWD Voltage Setting -> PMIC0_SWD_RANGE
+ /// @brief Decodes PMIC0 SWD Voltage Setting -> PMIC0_SWD_RANGE_SETTING
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1140,18 +1184,29 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWD Voltage Offset -> PMIC0_SWD_OFF_RANGE
+ /// @brief Decodes PMIC0 SWD Voltage Offset -> PMIC0_SWD_OFF_DIRECTION
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_offset_direction_swd_pmic0(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWD Delay -> PMIC0_SWD_DELAY
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swd_pmic0(uint8_t& o_output) const
+ virtual fapi2::ReturnCode volt_delay_swd_pmic0(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC0 SWD Delay Sequence Order -> PMIC0_SWD_ORDER
+ /// @brief Decodes PMIC0 SWD Sequence Order -> PMIC0_SWD_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1184,7 +1239,7 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWA Voltage Setting -> PMIC1_SWA_RANGE
+ /// @brief Decodes PMIC1 SWA Voltage Setting -> PMIC1_SWA_RANGE_SETTING
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1206,18 +1261,29 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWA Voltage Offset -> PMIC1_SWA_OFF_RANGE
+ /// @brief Decodes PMIC1 SWA Voltage Offset -> PMIC1_SWA_OFF_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swa_pmic1(uint8_t& o_output) const
+ virtual fapi2::ReturnCode volt_offset_direction_swa_pmic1(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC1 SWA Delay Sequence Order -> PMIC1_SWA_ORDER
+ /// @brief Decodes PMIC1 SWA Delay -> PMIC1_SWA_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_delay_swa_pmic1(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWA Sequence Order -> PMIC1_SWA_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1239,7 +1305,7 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWB Voltage Setting -> PMIC1_SWB_RANGE
+ /// @brief Decodes PMIC1 SWB Voltage Setting -> PMIC1_SWB_RANGE_SETTING
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1261,18 +1327,29 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWB Voltage Offset -> PMIC1_SWB_OFF_RANGE
+ /// @brief Decodes PMIC1 SWB Voltage Offset -> PMIC1_SWB_OFF_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swb_pmic1(uint8_t& o_output) const
+ virtual fapi2::ReturnCode volt_offset_direction_swb_pmic1(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC1 SWB Delay Sequence Order -> PMIC1_SWB_ORDER
+ /// @brief Decodes PMIC1 SWB Delay -> PMIC1_SWB_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_delay_swb_pmic1(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWB Sequence Order -> PMIC1_SWB_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1294,7 +1371,7 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWC Voltage Setting -> PMIC1_SWC_RANGE
+ /// @brief Decodes PMIC1 SWC Voltage Setting -> PMIC1_SWC_RANGE_SETTING
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1316,18 +1393,29 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWC Voltage Offset -> PMIC1_SWC_OFF_RANGE
+ /// @brief Decodes PMIC1 SWC Voltage Offset -> PMIC1_SWC_OFF_DIRECTION
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_offset_direction_swc_pmic1(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWC Delay -> PMIC1_SWC_DELAY
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swc_pmic1(uint8_t& o_output) const
+ virtual fapi2::ReturnCode volt_delay_swc_pmic1(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC1 SWC Delay Sequence Order -> PMIC1_SWC_ORDER
+ /// @brief Decodes PMIC1 SWC Sequence Order -> PMIC1_SWC_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1349,7 +1437,7 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWD Voltage Setting -> PMIC1_SWD_RANGE
+ /// @brief Decodes PMIC1 SWD Voltage Setting -> PMIC1_SWD_RANGE_SETTING
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1371,18 +1459,29 @@ class dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWD Voltage Offset -> PMIC1_SWD_OFF_RANGE
+ /// @brief Decodes PMIC1 SWD Voltage Offset -> PMIC1_SWD_OFF_DIRECTION
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_offset_direction_swd_pmic1(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWD Delay -> PMIC1_SWD_DELAY
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swd_pmic1(uint8_t& o_output) const
+ virtual fapi2::ReturnCode volt_delay_swd_pmic1(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC1 SWD Delay Sequence Order -> PMIC1_SWD_ORDER
+ /// @brief Decodes PMIC1 SWD Sequence Order -> PMIC1_SWD_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1402,6 +1501,39 @@ class dimm_module_decoder
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
+
+ ///
+ /// @brief Decodes PMIC0 Sequence Order
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode sequence_pmic0(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 Sequence Order
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode sequence_pmic1(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM Manufacturer ID code
+ /// @param[out] o_value dram manufacturing id code
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ virtual fapi2::ReturnCode dram_manufacturer_id_code( uint16_t& o_value ) const
+ {
+ o_value = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
};
}// spd
diff --git a/src/import/generic/memory/lib/spd/common/spd_decoder_base.H b/src/import/generic/memory/lib/spd/common/spd_decoder_base.H
index 878d2f27e..d69d216b5 100644
--- a/src/import/generic/memory/lib/spd/common/spd_decoder_base.H
+++ b/src/import/generic/memory/lib/spd/common/spd_decoder_base.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -788,6 +788,66 @@ class base_cnfg_decoder
}
///
+ /// @brief Decodes Fine Offset for tWTR_L
+ /// @param[out] o_value tWTR_L offset in FTB units
+ /// @return FAPI2_RC_SUCCESS iff okay
+ /// @warning not an actual SPD field, defaulted to zero to simplify calculations
+ ///
+ virtual fapi2::ReturnCode fine_offset_min_twtr_l( int64_t& o_value ) const
+ {
+ o_value = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for twtr_s
+ /// @param[out] o_value twtr_s offset in FTB units
+ /// @return FAPI2_RC_SUCCESS iff okay
+ /// @warning not an actual SPD field, defaulted to zero to simplify calculations
+ ///
+ virtual fapi2::ReturnCode fine_offset_min_twtr_s( int64_t& o_value ) const
+ {
+ o_value = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for tfaw
+ /// @param[out] o_value tfaw offset in FTB units
+ /// @return FAPI2_RC_SUCCESS iff okay
+ /// @warning not an actual SPD field, defaulted to zero to simplify calculations
+ ///
+ virtual fapi2::ReturnCode fine_offset_min_tfaw( int64_t& o_value ) const
+ {
+ o_value = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for tras
+ /// @param[out] o_value tras offset in FTB units
+ /// @return FAPI2_RC_SUCCESS iff okay
+ /// @warning not an actual SPD field, defaulted to zero to simplify calculations
+ ///
+ virtual fapi2::ReturnCode fine_offset_min_tras( int64_t& o_value ) const
+ {
+ o_value = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for twr
+ /// @param[out] o_value twr offset in FTB units
+ /// @return FAPI2_RC_SUCCESS iff okay
+ /// @warning not an actual SPD field, defaulted to zero to simplify calculations
+ ///
+ virtual fapi2::ReturnCode fine_offset_min_twr( int64_t& o_value ) const
+ {
+ o_value = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
/// @brief Decodes Cyclical Redundancy Code (CRC) for Base Configuration Section
/// @param[out] o_value crc value from SPD
/// @return FAPI2_RC_SUCCESS iff okay
diff --git a/src/import/generic/memory/lib/spd/ddimm/ddr4/ddimm_decoder_ddr4.H b/src/import/generic/memory/lib/spd/ddimm/ddr4/ddimm_decoder_ddr4.H
index 2d1816ab3..fb93691d2 100644
--- a/src/import/generic/memory/lib/spd/ddimm/ddr4/ddimm_decoder_ddr4.H
+++ b/src/import/generic/memory/lib/spd/ddimm/ddr4/ddimm_decoder_ddr4.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -54,7 +54,7 @@ namespace spd
/// @brief DDIMM module SPD DRAM decoder
///
template < rev R >
-class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
+class decoder< DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
{
private:
@@ -114,13 +114,13 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes SPD Revision for bytes 192->447 -> SPD_REVISION
+ /// @brief Decodes SPD Revision for bytes 192->447 -> SPD_REV_DDIMM_MODULE
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode ddimm_spd_revision(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode ddimm_module_spd_revision(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::SPD_REVISION, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::SPD_REV_DDIMM_MODULE, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
@@ -642,19 +642,6 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes VDD_Core PMIC0 -> VDD_CORE_PMIC0
- /// @param[out] o_output encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- ///
- virtual fapi2::ReturnCode vdd_core_pmic0(uint8_t& o_output) const override
- {
- FAPI_TRY( (mss::spd::reader<fields_t::VDD_CORE_PMIC0, R>(iv_target, iv_data, o_output)) );
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
/// @brief Decodes PMIC0 Manfacture ID code 2nd byte
/// @param[out] o_output encoding from SPD - multiple fields used
/// @return FAPI2_RC_SUCCESS if okay
@@ -696,19 +683,6 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes VDD_Core PMIC1 -> VDD_CORE_PMIC1
- /// @param[out] o_output encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- ///
- virtual fapi2::ReturnCode vdd_core_pmic1(uint8_t& o_output) const override
- {
- FAPI_TRY( (mss::spd::reader<fields_t::VDD_CORE_PMIC1, R>(iv_target, iv_data, o_output)) );
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
/// @brief Decodes PMIC1 Manfacture ID code 2nd byte
/// @param[out] o_output encoding from SPD - multiple fields used
/// @return FAPI2_RC_SUCCESS if okay
@@ -763,13 +737,13 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWA Voltage Setting -> PMIC0_SWA_RANGE
+ /// @brief Decodes PMIC0 SWA Voltage Setting -> PMIC0_SWA_RANGE_SELECT
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
virtual fapi2::ReturnCode volt_setpoint_range_swa_pmic0(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWA_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWA_RANGE_SELECT, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
@@ -789,20 +763,33 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWA Voltage Offset -> PMIC0_SWA_OFF_RANGE
+ /// @brief Decodes PMIC0 SWA Voltage Offset -> PMIC0_SWA_OFF_DIRECTION
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_offset_direction_swa_pmic0(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWA_OFF_DIRECTION, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWA Sequence Delay -> PMIC0_SWA_DELAY
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swa_pmic0(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode volt_delay_swa_pmic0(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWA_OFF_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWA_DELAY, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWA Delay Sequence Order -> PMIC0_SWA_ORDER
+ /// @brief Decodes PMIC0 SWA Sequence Order -> PMIC0_SWA_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -828,13 +815,13 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWB Voltage Setting -> PMIC0_SWB_RANGE
+ /// @brief Decodes PMIC0 SWB Voltage Setting -> PMIC0_SWB_RANGE_SELECT
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
virtual fapi2::ReturnCode volt_setpoint_range_swb_pmic0(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWB_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWB_RANGE_SELECT, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
@@ -854,20 +841,33 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWB Voltage Offset -> PMIC0_SWB_OFF_RANGE
+ /// @brief Decodes PMIC0 SWB Voltage Offset -> PMIC0_SWB_OFF_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swb_pmic0(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode volt_offset_direction_swb_pmic0(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWB_OFF_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWB_OFF_DIRECTION, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWB Delay Sequence Order -> PMIC0_SWB_ORDER
+ /// @brief Decodes PMIC0 SWB Sequence Delay -> PMIC0_SWB_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_delay_swb_pmic0(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWB_DELAY, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWB Sequence Order -> PMIC0_SWB_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -893,13 +893,13 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWC Voltage Setting -> PMIC0_SWC_RANGE
+ /// @brief Decodes PMIC0 SWC Voltage Setting -> PMIC0_SWC_RANGE_SELECT
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
virtual fapi2::ReturnCode volt_setpoint_range_swc_pmic0(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWC_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWC_RANGE_SELECT, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
@@ -919,20 +919,33 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWC Voltage Offset -> PMIC0_SWC_OFF_RANGE
+ /// @brief Decodes PMIC0 SWC Voltage Offset -> PMIC0_SWC_OFF_DIRECTION
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_offset_direction_swc_pmic0(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWC_OFF_DIRECTION, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWC Sequence Delay -> PMIC0_SWC_DELAY
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swc_pmic0(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode volt_delay_swc_pmic0(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWC_OFF_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWC_DELAY, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWC Delay Sequence Order -> PMIC0_SWC_ORDER
+ /// @brief Decodes PMIC0 SWC Sequence Order -> PMIC0_SWC_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -958,13 +971,13 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWD Voltage Setting -> PMIC0_SWD_RANGE
+ /// @brief Decodes PMIC0 SWD Voltage Setting -> PMIC0_SWD_RANGE_SELECT
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
virtual fapi2::ReturnCode volt_setpoint_range_swd_pmic0(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWD_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWD_RANGE_SELECT, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
@@ -984,20 +997,33 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC0 SWD Voltage Offset -> PMIC0_SWD_OFF_RANGE
+ /// @brief Decodes PMIC0 SWD Voltage Offset -> PMIC0_SWD_OFF_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swd_pmic0(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode volt_offset_direction_swd_pmic0(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWD_OFF_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWD_OFF_DIRECTION, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWD Delay Sequence Order -> PMIC0_SWD_ORDER
+ /// @brief Decodes PMIC0 SWD Sequence Delay -> PMIC0_SWD_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_delay_swd_pmic0(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC0_SWD_DELAY, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWD Sequence Order -> PMIC0_SWD_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1036,13 +1062,13 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWA Voltage Setting -> PMIC1_SWA_RANGE
+ /// @brief Decodes PMIC1 SWA Voltage Setting -> PMIC1_SWA_RANGE_SELECT
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
virtual fapi2::ReturnCode volt_setpoint_range_swa_pmic1(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWA_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWA_RANGE_SELECT, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
@@ -1062,20 +1088,33 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWA Voltage Offset -> PMIC1_SWA_OFF_RANGE
+ /// @brief Decodes PMIC1 SWA Voltage Offset -> PMIC1_SWA_OFF_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swa_pmic1(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode volt_offset_direction_swa_pmic1(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWA_OFF_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWA_OFF_DIRECTION, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWA Delay Sequence Order -> PMIC1_SWA_ORDER
+ /// @brief Decodes PMIC1 SWA Sequence Delay -> PMIC1_SWA_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_delay_swa_pmic1(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWA_DELAY, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWA Sequence Order -> PMIC1_SWA_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1101,13 +1140,13 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWB Voltage Setting -> PMIC1_SWB_RANGE
+ /// @brief Decodes PMIC1 SWB Voltage Setting -> PMIC1_SWB_RANGE_SELECT
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
virtual fapi2::ReturnCode volt_setpoint_range_swb_pmic1(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWB_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWB_RANGE_SELECT, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
@@ -1127,20 +1166,33 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWB Voltage Offset -> PMIC1_SWB_OFF_RANGE
+ /// @brief Decodes PMIC1 SWB Voltage Offset -> PMIC1_SWB_OFF_DIRECTION
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_offset_direction_swb_pmic1(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWB_OFF_DIRECTION, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWB Sequence Delay -> PMIC1_SWB_DELAY
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swb_pmic1(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode volt_delay_swb_pmic1(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWB_OFF_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWB_DELAY, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWB Delay Sequence Order -> PMIC1_SWB_ORDER
+ /// @brief Decodes PMIC1 SWB Sequence Order -> PMIC1_SWB_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1166,13 +1218,13 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWC Voltage Setting -> PMIC1_SWC_RANGE
+ /// @brief Decodes PMIC1 SWC Voltage Setting -> PMIC1_SWC_RANGE_SELECT
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
virtual fapi2::ReturnCode volt_setpoint_range_swc_pmic1(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWC_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWC_RANGE_SELECT, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
@@ -1192,20 +1244,33 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWC Voltage Offset -> PMIC1_SWC_OFF_RANGE
+ /// @brief Decodes PMIC1 SWC Voltage Offset -> PMIC1_SWC_OFF_DIRECTION
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_offset_direction_swc_pmic1(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWC_OFF_DIRECTION, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWC Sequence Delay -> PMIC1_SWC_DELAY
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swc_pmic1(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode volt_delay_swc_pmic1(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWC_OFF_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWC_DELAY, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWC Delay Sequence Order -> PMIC1_SWC_ORDER
+ /// @brief Decodes PMIC1 SWC Sequence Order -> PMIC1_SWC_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1231,13 +1296,13 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWD Voltage Setting -> PMIC1_SWD_RANGE
+ /// @brief Decodes PMIC1 SWD Voltage Setting -> PMIC1_SWD_RANGE_SELECT
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
virtual fapi2::ReturnCode volt_setpoint_range_swd_pmic1(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWD_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWD_RANGE_SELECT, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
@@ -1257,20 +1322,33 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
}
///
- /// @brief Decodes PMIC1 SWD Voltage Offset -> PMIC1_SWD_OFF_RANGE
+ /// @brief Decodes PMIC1 SWD Voltage Offset -> PMIC1_SWD_OFF_DIRECTION
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode volt_offset_direction_swd_pmic1(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWD_OFF_DIRECTION, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWD Sequence Delay -> PMIC1_SWD_DELAY
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode volt_offset_range_swd_pmic1(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode volt_delay_swd_pmic1(uint8_t& o_output) const override
{
- FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWD_OFF_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::PMIC1_SWD_DELAY, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWD Delay Sequence Order -> PMIC1_SWD_ORDER
+ /// @brief Decodes PMIC1 SWD Sequence Order -> PMIC1_SWD_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -1295,6 +1373,58 @@ class decoder<DDR4, DDIMM_MODULE, R > : public dimm_module_decoder
return fapi2::current_err;
}
+ ///
+ /// @brief Decodes PMIC1 Sequence -> PMIC0_SEQUENCE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode sequence_pmic0(uint8_t& o_output) const override
+ {
+ FAPI_TRY((mss::spd::reader<fields_t::PMIC0_SEQUENCE, R>(iv_target, iv_data, o_output)));
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 Sequence -> PMIC1_SEQUENCE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode sequence_pmic1(uint8_t& o_output) const override
+ {
+ FAPI_TRY((mss::spd::reader<fields_t::PMIC1_SEQUENCE, R>(iv_target, iv_data, o_output)));
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM manufacturing ID Code
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_manufacturer_id_code(uint16_t& o_output) const override
+ {
+ uint8_t l_byte0 = 0;
+ uint8_t l_byte1 = 0;
+
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_MFR_ID_CODE_LSB, R>(iv_target, iv_data, l_byte0)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_MFR_ID_CODE_MSB, R>(iv_target, iv_data, l_byte1)) );
+
+ {
+ fapi2::buffer<uint16_t> l_buffer;
+ right_aligned_insert(l_buffer, l_byte1, l_byte0);
+ o_output = l_buffer;
+ FAPI_INF("%s. Register Manufacturer ID Code: 0x%04x",
+ spd::c_str(iv_target),
+ o_output);
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
};// decoder
}// spd
diff --git a/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_ddr4_custom_microchip_decoder.H b/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_ddr4_custom_microchip_decoder.H
index 12acc87ef..213293fdd 100644
--- a/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_ddr4_custom_microchip_decoder.H
+++ b/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_ddr4_custom_microchip_decoder.H
@@ -40,6 +40,7 @@
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <generic/memory/lib/spd/ddimm/efd_decoder.H>
#include <generic/memory/lib/utils/mss_buffer_utils.H>
+#include <generic/memory/lib/utils/find.H>
namespace mss
{
@@ -488,6 +489,19 @@ class decoder<mss::spd::device_type::DDR4, DDR4_CUSTOM_MICROCHIP, R > : public b
}
///
+ /// @brief Decodes Host RD VREF DQ -> INIT_PHY_VREF
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode init_phy_vref(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (reader<fields_t::INIT_PHY_VREF, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
/// @brief Decodes Initial WR VREF DQ setting -> WR_VREF_DQ_RANGE
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
@@ -631,208 +645,498 @@ class decoder<mss::spd::device_type::DDR4, DDR4_CUSTOM_MICROCHIP, R > : public b
}
///
+ /// @brief Decodes BIST CAL Mode -> BIST_CA_LATENCY_MODE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode bist_ca_latency_mode(uint8_t& o_output) const
+ {
+ // Note: using a one-to-one mapping to allow us to re-use the API
+ // We really just need to check that the value exists in the list
+ const std::vector<std::pair<uint8_t, uint8_t>> ALLOWED_VALUES =
+ {
+ {0b0000, 0b0000},
+ {0b0011, 0b0011},
+ {0b0100, 0b0100},
+ {0b0101, 0b0101},
+ {0b0110, 0b0110},
+ {0b1000, 0b1000},
+ };
+
+ FAPI_TRY( (reader<fields_t::BIST_CA_LATENCY_MODE, R>(iv_target, iv_data, o_output)) );
+
+ {
+ // Map EFD value to desired setting
+ // Value and key should be the same thing, just creating a helper variable to avoid confusion
+ const auto l_key = o_output;
+ uint8_t l_value = 0;
+ o_output = 0;
+ FAPI_TRY(lookup_table_check(iv_target, ALLOWED_VALUES, EFD_CA_LATENCY_MODE, l_key, o_output));
+ o_output = l_value;
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes BIST CA Parity Latency Mode -> BIST_CA_PL_MODE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode bist_ca_pl_mode(uint8_t& o_output) const
+ {
+ // Note: using a one-to-one mapping to allow us to re-use the API
+ // We really just need to check that the value exists in the list
+ const std::vector<std::pair<uint8_t, uint8_t>> ALLOWED_VALUES =
+ {
+ {0b0000, 0b0000},
+ {0b0100, 0b0100},
+ {0b0101, 0b0101},
+ {0b0110, 0b0110},
+ {0b1000, 0b1000},
+ };
+
+ FAPI_TRY( (reader<fields_t::BIST_CA_PL_MODE, R>(iv_target, iv_data, o_output)) );
+
+ {
+ // Map EFD value to desired setting
+ // Value and key should be the same thing, just creating a helper variable to avoid confusion if we return with a bad value and an RC
+ const auto l_key = o_output;
+ uint8_t l_value = 0;
+ o_output = 0;
+ FAPI_TRY(lookup_table_check(iv_target, ALLOWED_VALUES, EFD_CA_PL_MODE, l_key, l_value));
+ o_output = l_value;
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DFI Max RD Latency -> DFIMRL_DDRCLK
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dfimrl_ddrclk(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::DFIMRL_DDRCLK, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 0 -> CAC_DLY_A_0
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_0(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_A_0, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 1 -> CAC_DLY_A_1
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_1(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_A_1, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 2 -> CAC_DLY_A_2
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_2(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_A_2, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 3 -> CAC_DLY_A_3
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_3(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_A_3, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 4 -> CAC_DLY_A_4
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_4(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_A_4, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 5 -> CAC_DLY_A_5
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_5(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_A_5, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 6 -> CAC_DLY_A_6
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_6(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_A_6, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 7 -> CAC_DLY_A_7
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_7(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_A_7, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay B side Group 0 -> CAC_DLY_B_0
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_b_side_group_0(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_B_0, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay B side Group 1 -> CAC_DLY_B_1
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_b_side_group_1(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_B_1, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay B side Group 2 -> CAC_DLY_B_2
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_b_side_group_2(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_B_2, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay B side Group 3 -> CAC_DLY_B_3
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_b_side_group_3(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_B_3, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay B side Group 4 -> CAC_DLY_B_4
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_b_side_group_4(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_B_4, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay B side Group 5 -> CAC_DLY_B_5
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_b_side_group_5(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_B_5, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay B side Group 6 -> CAC_DLY_B_6
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_b_side_group_6(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_B_6, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay B side Group 7 -> CAC_DLY_B_7
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_b_side_group_7(uint8_t& o_output) const
+ {
+ FAPI_TRY( (reader<fields_t::CAC_DLY_B_7, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
/// @brief Decodes PMIC0 SWA Volt -> PMIC0_SWA_SETTING
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swa_setting(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic0_swa_offset(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC0_SWA_SETTING, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC0_SWA_OFFSET, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWA Volt -> PMIC0_SWA_RANGE
+ /// @brief Decodes PMIC0 SWA Volt -> PMIC0_SWA_OFFSET_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swa_range(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic0_swa_offset_direction(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC0_SWA_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC0_SWA_OFFSET_DIRECTION, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWB Volt -> PMIC0_SWB_SETTING
+ /// @brief Decodes PMIC0 SWB Volt -> PMIC0_SWB_OFFSET
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swb_setting(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic0_swb_offset(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC0_SWB_SETTING, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC0_SWB_OFFSET, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWB Volt -> PMIC0_SWB_RANGE
+ /// @brief Decodes PMIC0 SWB Volt -> PMIC0_SWB_OFFSET_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swb_range(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic0_swb_offset_direction(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC0_SWB_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC0_SWB_OFFSET_DIRECTION, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWC Volt -> PMIC0_SWC_SETTING
+ /// @brief Decodes PMIC0 SWC Volt -> PMIC0_SWC_OFFSET
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swc_setting(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic0_swc_offset(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC0_SWC_SETTING, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC0_SWC_OFFSET, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWC Volt -> PMIC0_SWC_RANGE
+ /// @brief Decodes PMIC0 SWC Volt -> PMIC0_SWC_OFFSET_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swc_range(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic0_swc_offset_direction(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC0_SWC_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC0_SWC_OFFSET_DIRECTION, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWD Volt -> PMIC0_SWD_SETTING
+ /// @brief Decodes PMIC0 SWD Volt -> PMIC0_SWD_OFFSET
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swd_setting(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic0_swd_offset(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC0_SWD_SETTING, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC0_SWD_OFFSET, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWD Volt -> PMIC0_SWD_RANGE
+ /// @brief Decodes PMIC0 SWD Volt -> PMIC0_SWD_OFFSET_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swd_range(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic0_swd_offset_direction(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC0_SWD_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC0_SWD_OFFSET_DIRECTION, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWA Volt -> PMIC1_SWA_SETTING
+ /// @brief Decodes PMIC1 SWA Volt -> PMIC1_SWA_OFFSET
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swa_setting(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic1_swa_offset(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC1_SWA_SETTING, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC1_SWA_OFFSET, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWA Volt -> PMIC1_SWA_RANGE
+ /// @brief Decodes PMIC1 SWA Volt -> PMIC1_SWA_OFFSET_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swa_range(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic1_swa_offset_direction(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC1_SWA_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC1_SWA_OFFSET_DIRECTION, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWB Volt -> PMIC1_SWB_SETTING
+ /// @brief Decodes PMIC1 SWB Volt -> PMIC1_SWB_OFFSET
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swb_setting(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic1_swb_offset(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC1_SWB_SETTING, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC1_SWB_OFFSET, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWB Volt -> PMIC1_SWB_RANGE
+ /// @brief Decodes PMIC1 SWB Volt -> PMIC1_SWB_OFFSET_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swb_range(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic1_swb_offset_direction(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC1_SWB_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC1_SWB_OFFSET_DIRECTION, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWC Volt -> PMIC1_SWC_SETTING
+ /// @brief Decodes PMIC1 SWC Volt -> PMIC1_SWC_OFFSET
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swc_setting(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic1_swc_offset(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC1_SWC_SETTING, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC1_SWC_OFFSET, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWC Volt -> PMIC1_SWC_RANGE
+ /// @brief Decodes PMIC1 SWC Volt -> PMIC1_SWC_OFFSET_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swc_range(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic1_swc_offset_direction(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC1_SWC_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC1_SWC_OFFSET_DIRECTION, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWD Volt -> PMIC1_SWD_SETTING
+ /// @brief Decodes PMIC1 SWD Volt -> PMIC1_SWD_OFFSET
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swd_setting(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic1_swd_offset(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC1_SWD_SETTING, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC1_SWD_OFFSET, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWD Volt -> PMIC1_SWD_RANGE
+ /// @brief Decodes PMIC1 SWD Volt -> PMIC1_SWD_OFFSET_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swd_range(uint8_t& o_output) const override
+ virtual fapi2::ReturnCode pmic1_swd_offset_direction(uint8_t& o_output) const override
{
- FAPI_TRY(( reader<fields_t::PMIC1_SWD_RANGE, R>(iv_target, iv_data, o_output)) );
+ FAPI_TRY(( reader<fields_t::PMIC1_SWD_OFFSET_DIRECTION, R>(iv_target, iv_data, o_output)) );
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_fields_ddr4.H b/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_fields_ddr4.H
index 4cebb9acb..9a1415a75 100644
--- a/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_fields_ddr4.H
+++ b/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_fields_ddr4.H
@@ -244,100 +244,200 @@ class fields<mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>
PHY_EQUALIZATION_LEN = 2,
// Byte 44: Initial WR VREF DQ setting
- WR_VREF_DQ_BYTE = 44,
+ INIT_VREF_DQ_BYTE = 44,
WR_VREF_DQ_RANGE_START = 1,
WR_VREF_DQ_RANGE_LEN = 1,
WR_VREF_DQ_VALUE_START = 2,
WR_VREF_DQ_VALUE_LEN = 6,
- // Byte 45: ODT WR Map CS Byte1
- ODT_WR_MAP1_BYTE = 45,
+ // Byte 45: Host RD VREF DQ
+ INIT_PHY_VREF_BYTE = 45,
+ INIT_PHY_VREF_START = 1,
+ INIT_PHY_VREF_LEN = 7,
+
+ // Byte 46: ODT WR Map CS Byte1
+ ODT_WR_MAP1_BYTE = 46,
ODT_WR_MAP_RANK3_START = 0,
ODT_WR_MAP_RANK3_LEN = 4,
ODT_WR_MAP_RANK2_START = 4,
ODT_WR_MAP_RANK2_LEN = 4,
- // Byte 46: ODT WR Map CS Byte0
- ODT_WR_MAP0_BYTE = 46,
+ // Byte 47: ODT WR Map CS Byte0
+ ODT_WR_MAP0_BYTE = 47,
ODT_WR_MAP_RANK1_START = 0,
ODT_WR_MAP_RANK1_LEN = 4,
ODT_WR_MAP_RANK0_START = 4,
ODT_WR_MAP_RANK0_LEN = 4,
- // Byte 47: ODT RD Map CS Byte1
- ODT_RD_MAP1_BYTE = 47,
+ // Byte 48: ODT RD Map CS Byte1
+ ODT_RD_MAP1_BYTE = 48,
ODT_RD_MAP_RANK3_START = 0,
ODT_RD_MAP_RANK3_LEN = 4,
ODT_RD_MAP_RANK2_START = 4,
ODT_RD_MAP_RANK2_LEN = 4,
- // Byte 48: ODT RD Map CS Byte0
- ODT_RD_MAP0_BYTE = 48,
+ // Byte 49: ODT RD Map CS Byte0
+ ODT_RD_MAP0_BYTE = 49,
ODT_RD_MAP_RANK1_START = 0,
ODT_RD_MAP_RANK1_LEN = 4,
ODT_RD_MAP_RANK0_START = 4,
ODT_RD_MAP_RANK0_LEN = 4,
- // Byte 49: Geardown during training
- GEARDOWN_DURING_TRAINING_BYTE = 49,
+ // Byte 50: Geardown during training
+ GEARDOWN_DURING_TRAINING_BYTE = 50,
GEARDOWN_DURING_TRAINING_START = 7,
GEARDOWN_DURING_TRAINING_LEN = 1,
- // Byte 50: PMIC0 SWA Volt
- PMIC0_SWA_BYTE = 50,
- PMIC0_SWA_SETTING_START = 0,
- PMIC0_SWA_SETTING_LEN = 7,
- PMIC0_SWA_RANGE_START = 7,
- PMIC0_SWA_RANGE_LEN = 1,
-
- // Byte 51: PMIC0 SWB Volt
- PMIC0_SWB_BYTE = 51,
- PMIC0_SWB_SETTING_START = 0,
- PMIC0_SWB_SETTING_LEN = 7,
- PMIC0_SWB_RANGE_START = 7,
- PMIC0_SWB_RANGE_LEN = 1,
-
- // Byte 52: PMIC0 SWC Volt
- PMIC0_SWC_BYTE = 52,
- PMIC0_SWC_SETTING_START = 0,
- PMIC0_SWC_SETTING_LEN = 7,
- PMIC0_SWC_RANGE_START = 7,
- PMIC0_SWC_RANGE_LEN = 1,
-
- // Byte 53: PMIC0 SWD Volt
- PMIC0_SWD_BYTE = 53,
- PMIC0_SWD_SETTING_START = 0,
- PMIC0_SWD_SETTING_LEN = 7,
- PMIC0_SWD_RANGE_START = 7,
- PMIC0_SWD_RANGE_LEN = 1,
-
- // Byte 54: PMIC1 SWA Volt
- PMIC1_SWA_BYTE = 54,
- PMIC1_SWA_SETTING_START = 0,
- PMIC1_SWA_SETTING_LEN = 7,
- PMIC1_SWA_RANGE_START = 7,
- PMIC1_SWA_RANGE_LEN = 1,
-
- // Byte 55: PMIC1 SWB Volt
- PMIC1_SWB_BYTE = 55,
- PMIC1_SWB_SETTING_START = 0,
- PMIC1_SWB_SETTING_LEN = 7,
- PMIC1_SWB_RANGE_START = 7,
- PMIC1_SWB_RANGE_LEN = 1,
-
- // Byte 56: PMIC1 SWC Volt
- PMIC1_SWC_BYTE = 56,
- PMIC1_SWC_SETTING_START = 0,
- PMIC1_SWC_SETTING_LEN = 7,
- PMIC1_SWC_RANGE_START = 7,
- PMIC1_SWC_RANGE_LEN = 1,
-
- // Byte 57: PMIC1 SWD Volt
- PMIC1_SWD_BYTE = 57,
- PMIC1_SWD_SETTING_START = 0,
- PMIC1_SWD_SETTING_LEN = 7,
- PMIC1_SWD_RANGE_START = 7,
- PMIC1_SWD_RANGE_LEN = 1,
+ // Byte 51: BIST CAL Mode
+ BIST_CA_LATENCY_MODE_BYTE = 51,
+ BIST_CA_LATENCY_MODE_START = 4,
+ BIST_CA_LATENCY_MODE_LEN = 4,
+
+ // Byte 52: BIST CA Parity Latency Mode
+ BIST_CA_PL_MODE_BYTE = 52,
+ BIST_CA_PL_MODE_START = 4,
+ BIST_CA_PL_MODE_LEN = 4,
+
+ // Byte 53: DFI Max RD Latency
+ DFI_MAX_RD_LATENCY_BYTE = 53,
+ DFIMRL_DDRCLK_START = 3,
+ DFIMRL_DDRCLK_LEN = 5,
+
+ // Byte 54: CAC Delay A side Group 0
+ CAC_DELAY_A_SIDE_GROUP_0_BYTE = 54,
+ CAC_DLY_A_0_START = 3,
+ CAC_DLY_A_0_LEN = 5,
+
+ // Byte 55: CAC Delay A side Group 1
+ CAC_DELAY_A_SIDE_GROUP_1_BYTE = 55,
+ CAC_DLY_A_1_START = 3,
+ CAC_DLY_A_1_LEN = 5,
+
+ // Byte 56: CAC Delay A side Group 2
+ CAC_DELAY_A_SIDE_GROUP_2_BYTE = 56,
+ CAC_DLY_A_2_START = 3,
+ CAC_DLY_A_2_LEN = 5,
+
+ // Byte 57: CAC Delay A side Group 3
+ CAC_DELAY_A_SIDE_GROUP_3_BYTE = 57,
+ CAC_DLY_A_3_START = 3,
+ CAC_DLY_A_3_LEN = 5,
+
+ // Byte 58: CAC Delay A side Group 4
+ CAC_DELAY_A_SIDE_GROUP_4_BYTE = 58,
+ CAC_DLY_A_4_START = 3,
+ CAC_DLY_A_4_LEN = 5,
+
+ // Byte 59: CAC Delay A side Group 5
+ CAC_DELAY_A_SIDE_GROUP_5_BYTE = 59,
+ CAC_DLY_A_5_START = 3,
+ CAC_DLY_A_5_LEN = 5,
+
+ // Byte 60: CAC Delay A side Group 6
+ CAC_DELAY_A_SIDE_GROUP_6_BYTE = 60,
+ CAC_DLY_A_6_START = 3,
+ CAC_DLY_A_6_LEN = 5,
+
+ // Byte 61: CAC Delay A side Group 7
+ CAC_DELAY_A_SIDE_GROUP_7_BYTE = 61,
+ CAC_DLY_A_7_START = 3,
+ CAC_DLY_A_7_LEN = 5,
+
+ // Byte 62: CAC Delay B side Group 0
+ CAC_DELAY_B_SIDE_GROUP_0_BYTE = 62,
+ CAC_DLY_B_0_START = 3,
+ CAC_DLY_B_0_LEN = 5,
+
+ // Byte 63: CAC Delay B side Group 1
+ CAC_DELAY_B_SIDE_GROUP_1_BYTE = 63,
+ CAC_DLY_B_1_START = 3,
+ CAC_DLY_B_1_LEN = 5,
+
+ // Byte 64: CAC Delay B side Group 2
+ CAC_DELAY_B_SIDE_GROUP_2_BYTE = 64,
+ CAC_DLY_B_2_START = 3,
+ CAC_DLY_B_2_LEN = 5,
+
+ // Byte 65: CAC Delay B side Group 3
+ CAC_DELAY_B_SIDE_GROUP_3_BYTE = 65,
+ CAC_DLY_B_3_START = 3,
+ CAC_DLY_B_3_LEN = 5,
+
+ // Byte 66: CAC Delay B side Group 4
+ CAC_DELAY_B_SIDE_GROUP_4_BYTE = 66,
+ CAC_DLY_B_4_START = 3,
+ CAC_DLY_B_4_LEN = 5,
+
+ // Byte 67: CAC Delay B side Group 5
+ CAC_DELAY_B_SIDE_GROUP_5_BYTE = 67,
+ CAC_DLY_B_5_START = 3,
+ CAC_DLY_B_5_LEN = 5,
+
+ // Byte 68: CAC Delay B side Group 6
+ CAC_DELAY_B_SIDE_GROUP_6_BYTE = 68,
+ CAC_DLY_B_6_START = 3,
+ CAC_DLY_B_6_LEN = 5,
+
+ // Byte 69: CAC Delay B side Group 7
+ CAC_DELAY_B_SIDE_GROUP_7_BYTE = 69,
+ CAC_DLY_B_7_START = 3,
+ CAC_DLY_B_7_LEN = 5,
+
+ // Byte 70: PMIC0 SWA Volt
+ PMIC0_SWA_BYTE = 70,
+ PMIC0_SWA_OFFSET_START = 0,
+ PMIC0_SWA_OFFSET_LEN = 7,
+ PMIC0_SWA_OFFSET_DIRECTION_START = 7,
+ PMIC0_SWA_OFFSET_DIRECTION_LEN = 1,
+
+ // Byte 71: PMIC0 SWB Volt
+ PMIC0_SWB_BYTE = 71,
+ PMIC0_SWB_OFFSET_START = 0,
+ PMIC0_SWB_OFFSET_LEN = 7,
+ PMIC0_SWB_OFFSET_DIRECTION_START = 7,
+ PMIC0_SWB_OFFSET_DIRECTION_LEN = 1,
+
+ // Byte 72: PMIC0 SWC Volt
+ PMIC0_SWC_BYTE = 72,
+ PMIC0_SWC_OFFSET_START = 0,
+ PMIC0_SWC_OFFSET_LEN = 7,
+ PMIC0_SWC_OFFSET_DIRECTION_START = 7,
+ PMIC0_SWC_OFFSET_DIRECTION_LEN = 1,
+
+ // Byte 73: PMIC0 SWD Volt
+ PMIC0_SWD_BYTE = 73,
+ PMIC0_SWD_OFFSET_START = 0,
+ PMIC0_SWD_OFFSET_LEN = 7,
+ PMIC0_SWD_OFFSET_DIRECTION_START = 7,
+ PMIC0_SWD_OFFSET_DIRECTION_LEN = 1,
+
+ // Byte 74: PMIC1 SWA Volt
+ PMIC1_SWA_BYTE = 74,
+ PMIC1_SWA_OFFSET_START = 0,
+ PMIC1_SWA_OFFSET_LEN = 7,
+ PMIC1_SWA_OFFSET_DIRECTION_START = 7,
+ PMIC1_SWA_OFFSET_DIRECTION_LEN = 1,
+
+ // Byte 75: PMIC1 SWB Volt
+ PMIC1_SWB_BYTE = 75,
+ PMIC1_SWB_OFFSET_START = 0,
+ PMIC1_SWB_OFFSET_LEN = 7,
+ PMIC1_SWB_OFFSET_DIRECTION_START = 7,
+ PMIC1_SWB_OFFSET_DIRECTION_LEN = 1,
+
+ // Byte 76: PMIC1 SWC Volt
+ PMIC1_SWC_BYTE = 76,
+ PMIC1_SWC_OFFSET_START = 0,
+ PMIC1_SWC_OFFSET_LEN = 7,
+ PMIC1_SWC_OFFSET_DIRECTION_START = 7,
+ PMIC1_SWC_OFFSET_DIRECTION_LEN = 1,
+
+ // Byte 77: PMIC1 SWD Volt
+ PMIC1_SWD_BYTE = 77,
+ PMIC1_SWD_OFFSET_START = 0,
+ PMIC1_SWD_OFFSET_LEN = 7,
+ PMIC1_SWD_OFFSET_DIRECTION_START = 7,
+ PMIC1_SWD_OFFSET_DIRECTION_LEN = 1,
};
public:
@@ -454,60 +554,120 @@ class fields<mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>
// Byte 43: PHY Equalization
static constexpr field_t PHY_EQUALIZATION{PHY_EQUALIZATION_BYTE, PHY_EQUALIZATION_START, PHY_EQUALIZATION_LEN};
- // Byte 44: Initial WR VREF DQ setting
- static constexpr field_t WR_VREF_DQ_RANGE{WR_VREF_DQ_BYTE, WR_VREF_DQ_RANGE_START, WR_VREF_DQ_RANGE_LEN};
- static constexpr field_t WR_VREF_DQ_VALUE{WR_VREF_DQ_BYTE, WR_VREF_DQ_VALUE_START, WR_VREF_DQ_VALUE_LEN};
+ // Byte 44: Initial VREF DQ setting
+ static constexpr field_t WR_VREF_DQ_RANGE{INIT_VREF_DQ_BYTE, WR_VREF_DQ_RANGE_START, WR_VREF_DQ_RANGE_LEN};
+ static constexpr field_t WR_VREF_DQ_VALUE{INIT_VREF_DQ_BYTE, WR_VREF_DQ_VALUE_START, WR_VREF_DQ_VALUE_LEN};
+
+ // Byte 45: Initial PHY VREF setting
+ static constexpr field_t INIT_PHY_VREF{INIT_PHY_VREF_BYTE, INIT_PHY_VREF_START, INIT_PHY_VREF_LEN};
- // Byte 45: ODT WR Map CS Byte1
+ // Byte 46: ODT WR Map CS Byte1
static constexpr field_t ODT_WR_MAP_RANK3{ODT_WR_MAP1_BYTE, ODT_WR_MAP_RANK3_START, ODT_WR_MAP_RANK3_LEN};
static constexpr field_t ODT_WR_MAP_RANK2{ODT_WR_MAP1_BYTE, ODT_WR_MAP_RANK2_START, ODT_WR_MAP_RANK2_LEN};
- // Byte 46: ODT WR Map CS Byte0
+ // Byte 47: ODT WR Map CS Byte0
static constexpr field_t ODT_WR_MAP_RANK1{ODT_WR_MAP0_BYTE, ODT_WR_MAP_RANK1_START, ODT_WR_MAP_RANK1_LEN};
static constexpr field_t ODT_WR_MAP_RANK0{ODT_WR_MAP0_BYTE, ODT_WR_MAP_RANK0_START, ODT_WR_MAP_RANK0_LEN};
- // Byte 47: ODT RD Map CS Byte1
+ // Byte 48: ODT RD Map CS Byte1
static constexpr field_t ODT_RD_MAP_RANK3{ODT_RD_MAP1_BYTE, ODT_RD_MAP_RANK3_START, ODT_RD_MAP_RANK3_LEN};
static constexpr field_t ODT_RD_MAP_RANK2{ODT_RD_MAP1_BYTE, ODT_RD_MAP_RANK2_START, ODT_RD_MAP_RANK2_LEN};
- // Byte 48: ODT RD Map CS Byte0
+ // Byte 49: ODT RD Map CS Byte0
static constexpr field_t ODT_RD_MAP_RANK1{ODT_RD_MAP0_BYTE, ODT_RD_MAP_RANK1_START, ODT_RD_MAP_RANK1_LEN};
static constexpr field_t ODT_RD_MAP_RANK0{ODT_RD_MAP0_BYTE, ODT_RD_MAP_RANK0_START, ODT_RD_MAP_RANK0_LEN};
- // Byte 49: Geardown during training
+ // Byte 50: Geardown during training
static constexpr field_t GEARDOWN_DURING_TRAINING{GEARDOWN_DURING_TRAINING_BYTE, GEARDOWN_DURING_TRAINING_START, GEARDOWN_DURING_TRAINING_LEN};
- // Byte 50: PMIC0 SWA Volt
- static constexpr field_t PMIC0_SWA_SETTING{PMIC0_SWA_BYTE, PMIC0_SWA_SETTING_START, PMIC0_SWA_SETTING_LEN};
- static constexpr field_t PMIC0_SWA_RANGE{PMIC0_SWA_BYTE, PMIC0_SWA_RANGE_START, PMIC0_SWA_RANGE_LEN};
+ // Byte 51: BIST CAL Mode
+ static constexpr field_t BIST_CA_LATENCY_MODE{BIST_CA_LATENCY_MODE_BYTE, BIST_CA_LATENCY_MODE_START, BIST_CA_LATENCY_MODE_LEN};
+
+ // Byte 52: BIST CA Parity Latency Mode
+ static constexpr field_t BIST_CA_PL_MODE{BIST_CA_PL_MODE_BYTE, BIST_CA_PL_MODE_START, BIST_CA_PL_MODE_LEN};
+
+ // Byte 53: DFI Max RD Latency
+ static constexpr field_t DFIMRL_DDRCLK{DFI_MAX_RD_LATENCY_BYTE, DFIMRL_DDRCLK_START, DFIMRL_DDRCLK_LEN};
+
+ // Byte 54: CAC Delay A side Group 0
+ static constexpr field_t CAC_DLY_A_0{CAC_DELAY_A_SIDE_GROUP_0_BYTE, CAC_DLY_A_0_START, CAC_DLY_A_0_LEN};
+
+ // Byte 55: CAC Delay A side Group 1
+ static constexpr field_t CAC_DLY_A_1{CAC_DELAY_A_SIDE_GROUP_1_BYTE, CAC_DLY_A_1_START, CAC_DLY_A_1_LEN};
+
+ // Byte 56: CAC Delay A side Group 2
+ static constexpr field_t CAC_DLY_A_2{CAC_DELAY_A_SIDE_GROUP_2_BYTE, CAC_DLY_A_2_START, CAC_DLY_A_2_LEN};
+
+ // Byte 57: CAC Delay A side Group 3
+ static constexpr field_t CAC_DLY_A_3{CAC_DELAY_A_SIDE_GROUP_3_BYTE, CAC_DLY_A_3_START, CAC_DLY_A_3_LEN};
+
+ // Byte 58: CAC Delay A side Group 4
+ static constexpr field_t CAC_DLY_A_4{CAC_DELAY_A_SIDE_GROUP_4_BYTE, CAC_DLY_A_4_START, CAC_DLY_A_4_LEN};
+
+ // Byte 59: CAC Delay A side Group 5
+ static constexpr field_t CAC_DLY_A_5{CAC_DELAY_A_SIDE_GROUP_5_BYTE, CAC_DLY_A_5_START, CAC_DLY_A_5_LEN};
+
+ // Byte 60: CAC Delay A side Group 6
+ static constexpr field_t CAC_DLY_A_6{CAC_DELAY_A_SIDE_GROUP_6_BYTE, CAC_DLY_A_6_START, CAC_DLY_A_6_LEN};
+
+ // Byte 61: CAC Delay A side Group 7
+ static constexpr field_t CAC_DLY_A_7{CAC_DELAY_A_SIDE_GROUP_7_BYTE, CAC_DLY_A_7_START, CAC_DLY_A_7_LEN};
+
+ // Byte 62: CAC Delay B side Group 0
+ static constexpr field_t CAC_DLY_B_0{CAC_DELAY_B_SIDE_GROUP_0_BYTE, CAC_DLY_B_0_START, CAC_DLY_B_0_LEN};
+
+ // Byte 63: CAC Delay B side Group 1
+ static constexpr field_t CAC_DLY_B_1{CAC_DELAY_B_SIDE_GROUP_1_BYTE, CAC_DLY_B_1_START, CAC_DLY_B_1_LEN};
+
+ // Byte 64: CAC Delay B side Group 2
+ static constexpr field_t CAC_DLY_B_2{CAC_DELAY_B_SIDE_GROUP_2_BYTE, CAC_DLY_B_2_START, CAC_DLY_B_2_LEN};
+
+ // Byte 65: CAC Delay B side Group 3
+ static constexpr field_t CAC_DLY_B_3{CAC_DELAY_B_SIDE_GROUP_3_BYTE, CAC_DLY_B_3_START, CAC_DLY_B_3_LEN};
+
+ // Byte 66: CAC Delay B side Group 4
+ static constexpr field_t CAC_DLY_B_4{CAC_DELAY_B_SIDE_GROUP_4_BYTE, CAC_DLY_B_4_START, CAC_DLY_B_4_LEN};
+
+ // Byte 67: CAC Delay B side Group 5
+ static constexpr field_t CAC_DLY_B_5{CAC_DELAY_B_SIDE_GROUP_5_BYTE, CAC_DLY_B_5_START, CAC_DLY_B_5_LEN};
+
+ // Byte 68: CAC Delay B side Group 6
+ static constexpr field_t CAC_DLY_B_6{CAC_DELAY_B_SIDE_GROUP_6_BYTE, CAC_DLY_B_6_START, CAC_DLY_B_6_LEN};
+
+ // Byte 69: CAC Delay B side Group 7
+ static constexpr field_t CAC_DLY_B_7{CAC_DELAY_B_SIDE_GROUP_7_BYTE, CAC_DLY_B_7_START, CAC_DLY_B_7_LEN};
+
+ // Byte 70: PMIC0 SWA Volt
+ static constexpr field_t PMIC0_SWA_OFFSET{PMIC0_SWA_BYTE, PMIC0_SWA_OFFSET_START, PMIC0_SWA_OFFSET_LEN};
+ static constexpr field_t PMIC0_SWA_OFFSET_DIRECTION{PMIC0_SWA_BYTE, PMIC0_SWA_OFFSET_DIRECTION_START, PMIC0_SWA_OFFSET_DIRECTION_LEN};
- // Byte 51: PMIC0 SWB Volt
- static constexpr field_t PMIC0_SWB_SETTING{PMIC0_SWB_BYTE, PMIC0_SWB_SETTING_START, PMIC0_SWB_SETTING_LEN};
- static constexpr field_t PMIC0_SWB_RANGE{PMIC0_SWB_BYTE, PMIC0_SWB_RANGE_START, PMIC0_SWB_RANGE_LEN};
+ // Byte 71: PMIC0 SWB Volt
+ static constexpr field_t PMIC0_SWB_OFFSET{PMIC0_SWB_BYTE, PMIC0_SWB_OFFSET_START, PMIC0_SWB_OFFSET_LEN};
+ static constexpr field_t PMIC0_SWB_OFFSET_DIRECTION{PMIC0_SWB_BYTE, PMIC0_SWB_OFFSET_DIRECTION_START, PMIC0_SWB_OFFSET_DIRECTION_LEN};
- // Byte 52: PMIC0 SWC Volt
- static constexpr field_t PMIC0_SWC_SETTING{PMIC0_SWC_BYTE, PMIC0_SWC_SETTING_START, PMIC0_SWC_SETTING_LEN};
- static constexpr field_t PMIC0_SWC_RANGE{PMIC0_SWC_BYTE, PMIC0_SWC_RANGE_START, PMIC0_SWC_RANGE_LEN};
+ // Byte 72: PMIC0 SWC Volt
+ static constexpr field_t PMIC0_SWC_OFFSET{PMIC0_SWC_BYTE, PMIC0_SWC_OFFSET_START, PMIC0_SWC_OFFSET_LEN};
+ static constexpr field_t PMIC0_SWC_OFFSET_DIRECTION{PMIC0_SWC_BYTE, PMIC0_SWC_OFFSET_DIRECTION_START, PMIC0_SWC_OFFSET_DIRECTION_LEN};
- // Byte 53: PMIC0 SWD Volt
- static constexpr field_t PMIC0_SWD_SETTING{PMIC0_SWD_BYTE, PMIC0_SWD_SETTING_START, PMIC0_SWD_SETTING_LEN};
- static constexpr field_t PMIC0_SWD_RANGE{PMIC0_SWD_BYTE, PMIC0_SWD_RANGE_START, PMIC0_SWD_RANGE_LEN};
+ // Byte 73: PMIC0 SWD Volt
+ static constexpr field_t PMIC0_SWD_OFFSET{PMIC0_SWD_BYTE, PMIC0_SWD_OFFSET_START, PMIC0_SWD_OFFSET_LEN};
+ static constexpr field_t PMIC0_SWD_OFFSET_DIRECTION{PMIC0_SWD_BYTE, PMIC0_SWD_OFFSET_DIRECTION_START, PMIC0_SWD_OFFSET_DIRECTION_LEN};
- // Byte 54: PMIC1 SWA Volt
- static constexpr field_t PMIC1_SWA_SETTING{PMIC1_SWA_BYTE, PMIC1_SWA_SETTING_START, PMIC1_SWA_SETTING_LEN};
- static constexpr field_t PMIC1_SWA_RANGE{PMIC1_SWA_BYTE, PMIC1_SWA_RANGE_START, PMIC1_SWA_RANGE_LEN};
+ // Byte 74: PMIC1 SWA Volt
+ static constexpr field_t PMIC1_SWA_OFFSET{PMIC1_SWA_BYTE, PMIC1_SWA_OFFSET_START, PMIC1_SWA_OFFSET_LEN};
+ static constexpr field_t PMIC1_SWA_OFFSET_DIRECTION{PMIC1_SWA_BYTE, PMIC1_SWA_OFFSET_DIRECTION_START, PMIC1_SWA_OFFSET_DIRECTION_LEN};
- // Byte 55: PMIC1 SWB Volt
- static constexpr field_t PMIC1_SWB_SETTING{PMIC1_SWB_BYTE, PMIC1_SWB_SETTING_START, PMIC1_SWB_SETTING_LEN};
- static constexpr field_t PMIC1_SWB_RANGE{PMIC1_SWB_BYTE, PMIC1_SWB_RANGE_START, PMIC1_SWB_RANGE_LEN};
+ // Byte 75: PMIC1 SWB Volt
+ static constexpr field_t PMIC1_SWB_OFFSET{PMIC1_SWB_BYTE, PMIC1_SWB_OFFSET_START, PMIC1_SWB_OFFSET_LEN};
+ static constexpr field_t PMIC1_SWB_OFFSET_DIRECTION{PMIC1_SWB_BYTE, PMIC1_SWB_OFFSET_DIRECTION_START, PMIC1_SWB_OFFSET_DIRECTION_LEN};
- // Byte 56: PMIC1 SWC Volt
- static constexpr field_t PMIC1_SWC_SETTING{PMIC1_SWC_BYTE, PMIC1_SWC_SETTING_START, PMIC1_SWC_SETTING_LEN};
- static constexpr field_t PMIC1_SWC_RANGE{PMIC1_SWC_BYTE, PMIC1_SWC_RANGE_START, PMIC1_SWC_RANGE_LEN};
+ // Byte 76: PMIC1 SWC Volt
+ static constexpr field_t PMIC1_SWC_OFFSET{PMIC1_SWC_BYTE, PMIC1_SWC_OFFSET_START, PMIC1_SWC_OFFSET_LEN};
+ static constexpr field_t PMIC1_SWC_OFFSET_DIRECTION{PMIC1_SWC_BYTE, PMIC1_SWC_OFFSET_DIRECTION_START, PMIC1_SWC_OFFSET_DIRECTION_LEN};
- // Byte 57: PMIC1 SWD Volt
- static constexpr field_t PMIC1_SWD_SETTING{PMIC1_SWD_BYTE, PMIC1_SWD_SETTING_START, PMIC1_SWD_SETTING_LEN};
- static constexpr field_t PMIC1_SWD_RANGE{PMIC1_SWD_BYTE, PMIC1_SWD_RANGE_START, PMIC1_SWD_RANGE_LEN};
+ // Byte 77: PMIC1 SWD Volt
+ static constexpr field_t PMIC1_SWD_OFFSET{PMIC1_SWD_BYTE, PMIC1_SWD_OFFSET_START, PMIC1_SWD_OFFSET_LEN};
+ static constexpr field_t PMIC1_SWD_OFFSET_DIRECTION{PMIC1_SWD_BYTE, PMIC1_SWD_OFFSET_DIRECTION_START, PMIC1_SWD_OFFSET_DIRECTION_LEN};
};
} // ns efd
diff --git a/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_traits_ddr4.H b/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_traits_ddr4.H
index b292d4180..447e661dc 100644
--- a/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_traits_ddr4.H
+++ b/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_traits_ddr4.H
@@ -294,11 +294,11 @@ class readerTraits
{
public:
- static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr size_t COMPARISON_VAL = 0x0F;
static constexpr const char* FIELD_STR = "PHY Slew Rate DQ_DQS";
template <typename T>
- using COMPARISON_OP = std::equal_to<T>;
+ using COMPARISON_OP = std::less_equal<T>;
};
///
@@ -332,11 +332,11 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
{
public:
- static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr size_t COMPARISON_VAL = 0x0E;
static constexpr const char* FIELD_STR = "ATX Slew rate";
template <typename T>
- using COMPARISON_OP = std::equal_to<T>;
+ using COMPARISON_OP = std::less_equal<T>;
};
///
@@ -370,11 +370,11 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
{
public:
- static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr size_t COMPARISON_VAL = 0x0E;
static constexpr const char* FIELD_STR = "CK Slew rate";
template <typename T>
- using COMPARISON_OP = std::equal_to<T>;
+ using COMPARISON_OP = std::less_equal<T>;
};
///
@@ -408,11 +408,11 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
{
public:
- static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr size_t COMPARISON_VAL = 0x07;
static constexpr const char* FIELD_STR = "DRAM RTT Nom";
template <typename T>
- using COMPARISON_OP = std::equal_to<T>;
+ using COMPARISON_OP = std::less_equal<T>;
};
///
@@ -503,11 +503,11 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
{
public:
- static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr size_t COMPARISON_VAL = 0x04;
static constexpr const char* FIELD_STR = "DRAM RTT WR";
template <typename T>
- using COMPARISON_OP = std::equal_to<T>;
+ using COMPARISON_OP = std::less_equal<T>;
};
///
@@ -598,11 +598,11 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
{
public:
- static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr size_t COMPARISON_VAL = 0x07;
static constexpr const char* FIELD_STR = "DRAM RTT Park";
template <typename T>
- using COMPARISON_OP = std::equal_to<T>;
+ using COMPARISON_OP = std::less_equal<T>;
};
///
@@ -780,6 +780,25 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
+/// @note PHY_VREF_PERCENT field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::INIT_PHY_VREF, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x7f;
+ static constexpr const char* FIELD_STR = "Host RD VREF DQ";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
/// @note WR_VREF_DQ_VALUE field specialization
/// @note valid for all revs
///
@@ -966,21 +985,382 @@ class readerTraits
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
};
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note BIST_CA_LATENCY_MODE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::BIST_CA_LATENCY_MODE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x08;
+ static constexpr const char* FIELD_STR = "BIST Command address Latency Mode";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note BIST_CA_PL_MODE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::BIST_CA_PL_MODE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x08;
+ static constexpr const char* FIELD_STR = "BIST CA Parity Latency Mode";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DFIMRL_DDRCLK field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DFIMRL_DDRCLK, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x0f;
+ static constexpr const char* FIELD_STR = "DFI Max RD Latency";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
///
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWA_SETTING field specialization
+/// @note CAC_DLY_A_0 field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWA_SETTING, R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_A_0, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay A side Group 0";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_A_1 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_A_1, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay A side Group 1";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_A_2 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_A_2, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay A side Group 2";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_A_3 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_A_3, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay A side Group .";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_A_4 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_A_4, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay A side Group 4";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_A_5 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_A_5, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay A side Group 5";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_A_6 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_A_6, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay A side Group 6";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_A_7 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_A_7, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay A side Group 7";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_B_0 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_B_0, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay B side Group 0";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_B_1 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_B_1, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay B side Group 1";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_B_2 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_B_2, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay B side Group 2";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_B_3 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_B_3, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay B side Group 3";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_B_4 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_B_4, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay B side Group 4";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_B_5 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_B_5, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay B side Group 5";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_B_6 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_B_6, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay B side Group 6";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CAC_DLY_B_7 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CAC_DLY_B_7, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x1f;
+ static constexpr const char* FIELD_STR = "CAC Delay B side Group 7";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC0_SWA_OFFSET field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWA_OFFSET, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x3f;
- static constexpr const char* FIELD_STR = "PMIC0 SWA Setting";
+ static constexpr const char* FIELD_STR = "PMIC0 SWA Offset";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -990,16 +1370,17 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWA_RANGE field specialization
+/// @note PMIC0_SWA_OFFSET_DIRECTION field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWA_RANGE, R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWA_OFFSET_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC0 SWA Range";
+ static constexpr const char* FIELD_STR = "PMIC0 SWA Offset Direction";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -1009,16 +1390,16 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWB_SETTING field specialization
+/// @note PMIC0_SWB_OFFSET field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWB_SETTING, R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWB_OFFSET, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x3f;
- static constexpr const char* FIELD_STR = "PMIC0 SWB Setting";
+ static constexpr const char* FIELD_STR = "PMIC0 SWB Offset";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -1028,16 +1409,17 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWB_RANGE field specialization
+/// @note PMIC0_SWB_OFFSET_DIRECTION field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWB_RANGE, R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWB_OFFSET_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC0 SWB Range";
+ static constexpr const char* FIELD_STR = "PMIC0 SWB Offset Direction";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -1047,16 +1429,16 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWC_SETTING field specialization
+/// @note PMIC0_SWC_OFFSET field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWC_SETTING, R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWC_OFFSET, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x3f;
- static constexpr const char* FIELD_STR = "PMIC0 SWC Setting";
+ static constexpr const char* FIELD_STR = "PMIC0 SWC Offset";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -1066,16 +1448,17 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWC_RANGE field specialization
+/// @note PMIC0_SWC_OFFSET_DIRECTION field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWC_RANGE, R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWC_OFFSET_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC0 SWC Range";
+ static constexpr const char* FIELD_STR = "PMIC0 SWC Offset Direction";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -1085,16 +1468,16 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWD_SETTING field specialization
+/// @note PMIC0_SWD_OFFSET field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWD_SETTING, R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWD_OFFSET, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x3f;
- static constexpr const char* FIELD_STR = "PMIC0 SWD Setting";
+ static constexpr const char* FIELD_STR = "PMIC0 SWD Offset";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -1104,16 +1487,17 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWD_RANGE field specialization
+/// @note PMIC0_SWD_OFFSET_DIRECTION field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWD_RANGE, R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWD_OFFSET_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC0 SWD Range";
+ static constexpr const char* FIELD_STR = "PMIC0 SWD Offset Direction";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -1123,16 +1507,16 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWA_SETTING field specialization
+/// @note PMIC1_SWA_OFFSET field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWA_SETTING, R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWA_OFFSET, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x3f;
- static constexpr const char* FIELD_STR = "PMIC1 SWA Setting";
+ static constexpr const char* FIELD_STR = "PMIC1 SWA Offset";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -1142,16 +1526,17 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWA_RANGE field specialization
+/// @note PMIC1_SWA_OFFSET_DIRECTION field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWA_RANGE, R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWA_OFFSET_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC1 SWA Range";
+ static constexpr const char* FIELD_STR = "PMIC1 SWA Offset Direction";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -1161,16 +1546,16 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWB_SETTING field specialization
+/// @note PMIC1_SWB_OFFSET field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWB_SETTING, R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWB_OFFSET, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x3f;
- static constexpr const char* FIELD_STR = "PMIC1 SWB Setting";
+ static constexpr const char* FIELD_STR = "PMIC1 SWB Offset";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -1180,16 +1565,17 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWB_RANGE field specialization
+/// @note PMIC1_SWB_OFFSET_DIRECTION field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWB_RANGE, R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWB_OFFSET_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC1 SWB Range";
+ static constexpr const char* FIELD_STR = "PMIC1 SWB Offset Direction";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -1199,16 +1585,16 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWC_SETTING field specialization
+/// @note PMIC1_SWC_OFFSET field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWC_SETTING, R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWC_OFFSET, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x3f;
- static constexpr const char* FIELD_STR = "PMIC1 SWC Setting";
+ static constexpr const char* FIELD_STR = "PMIC1 SWC Offset";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -1218,16 +1604,17 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWC_RANGE field specialization
+/// @note PMIC1_SWC_OFFSET_DIRECTION field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWC_RANGE, R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWC_OFFSET_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC1 SWC Range";
+ static constexpr const char* FIELD_STR = "PMIC1 SWC Offset Direction";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -1237,16 +1624,16 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWD_SETTING field specialization
+/// @note PMIC1_SWD_OFFSET field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWD_SETTING, R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWD_OFFSET, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x3f;
- static constexpr const char* FIELD_STR = "PMIC1 SWD Setting";
+ static constexpr const char* FIELD_STR = "PMIC1 SWD Offset";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -1256,16 +1643,17 @@ class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUS
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWD_RANGE field specialization
+/// @note PMIC1_SWD_OFFSET_DIRECTION field specialization
/// @note valid for all revs
///
template< mss::spd::rev R >
-class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWD_RANGE, R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWD_OFFSET_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC1 SWD Range";
+ static constexpr const char* FIELD_STR = "PMIC1 SWD Offset Direction";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
diff --git a/src/import/generic/memory/lib/spd/ddimm/efd_decoder.H b/src/import/generic/memory/lib/spd/ddimm/efd_decoder.H
index 6ac30ab0f..df0dbed5e 100644
--- a/src/import/generic/memory/lib/spd/ddimm/efd_decoder.H
+++ b/src/import/generic/memory/lib/spd/ddimm/efd_decoder.H
@@ -67,7 +67,6 @@ inline fapi2::ReturnCode reader( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHI
const std::vector<IT>& i_spd_data,
OT& o_value)
{
-
FAPI_TRY( (mss::get_field<endian::LITTLE, F, TT>(i_target, i_spd_data, mss::READ_SPD_FIELD, o_value)),
"Failed efd::read_field() for %s", spd::c_str(i_target) );
@@ -493,7 +492,7 @@ class base_decoder
}
///
- /// @brief Decodes Initial WR VREF DQ setting -> WR_VREF_DQ_RANGE
+ /// @brief Decodes Initial VREF DQ setting -> WR_VREF_DQ_RANGE
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -504,7 +503,7 @@ class base_decoder
}
///
- /// @brief Decodes Initial WR VREF DQ setting -> WR_VREF_DQ_VALUE
+ /// @brief Decodes Initial VREF DQ setting -> WR_VREF_DQ_VALUE
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -515,6 +514,17 @@ class base_decoder
}
///
+ /// @brief Decodes Initial PHY VREF -> INIT_PHY_VREF
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode init_phy_vref(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
/// @brief Decodes ODT WR Map CS Byte0 -> ODT_WR_MAP_RANK3
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
@@ -614,176 +624,385 @@ class base_decoder
}
///
- /// @brief Decodes PMIC0 SWA Volt -> PMIC0_SWA_SETTING
+ /// @brief Decodes BIST CAL Mode -> BIST_CA_LATENCY_MODE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode bist_ca_latency_mode(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes BIST CA Parity Latency Mode -> BIST_CA_PL_MODE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode bist_ca_pl_mode(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DFI Max RD Latency -> DFIMRL_DDRCLK
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dfimrl_ddrclk(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 0 -> CAC_DLY_A_0
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_0(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 1 -> CAC_DLY_A_1
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_1(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 2 -> CAC_DLY_A_2
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_2(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 3 -> CAC_DLY_A_3
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_3(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 4 -> CAC_DLY_A_4
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_4(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 5 -> CAC_DLY_A_5
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_5(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 6 -> CAC_DLY_A_6
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_6(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay A side Group 7 -> CAC_DLY_A_7
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_a_side_group_7(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay B side Group 0 -> CAC_DLY_B_0
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_b_side_group_0(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay B side Group 1 -> CAC_DLY_B_1
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_b_side_group_1(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay B side Group 2 -> CAC_DLY_B_2
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_b_side_group_2(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay B side Group 3 -> CAC_DLY_B_3
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode cac_delay_b_side_group_3(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CAC Delay B side Group 4 -> CAC_DLY_B_4
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swa_setting(uint8_t& o_output) const
+ virtual fapi2::ReturnCode cac_delay_b_side_group_4(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC0 SWA Volt -> PMIC0_SWA_RANGE
+ /// @brief Decodes CAC Delay B side Group 5 -> CAC_DLY_B_5
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swa_range(uint8_t& o_output) const
+ virtual fapi2::ReturnCode cac_delay_b_side_group_5(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC0 SWB Volt -> PMIC0_SWB_SETTING
+ /// @brief Decodes CAC Delay B side Group 6 -> CAC_DLY_B_6
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swb_setting(uint8_t& o_output) const
+ virtual fapi2::ReturnCode cac_delay_b_side_group_6(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC0 SWB Volt -> PMIC0_SWB_RANGE
+ /// @brief Decodes CAC Delay B side Group 7 -> CAC_DLY_B_7
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swb_range(uint8_t& o_output) const
+ virtual fapi2::ReturnCode cac_delay_b_side_group_7(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC0 SWC Volt -> PMIC0_SWC_SETTING
+ /// @brief Decodes PMIC0 SWA Volt -> PMIC0_SWA_OFFSET
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swc_setting(uint8_t& o_output) const
+ virtual fapi2::ReturnCode pmic0_swa_offset(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC0 SWC Volt -> PMIC0_SWC_RANGE
+ /// @brief Decodes PMIC0 SWA Volt -> PMIC0_SWA_OFFSET_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swc_range(uint8_t& o_output) const
+ virtual fapi2::ReturnCode pmic0_swa_offset_direction(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC0 SWD Volt -> PMIC0_SWD_SETTING
+ /// @brief Decodes PMIC0 SWB Volt -> PMIC0_SWB_OFFSET
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swd_setting(uint8_t& o_output) const
+ virtual fapi2::ReturnCode pmic0_swb_offset(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC0 SWD Volt -> PMIC0_SWD_RANGE
+ /// @brief Decodes PMIC0 SWB Volt -> PMIC0_SWB_OFFSET_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic0_swd_range(uint8_t& o_output) const
+ virtual fapi2::ReturnCode pmic0_swb_offset_direction(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC1 SWA Volt -> PMIC1_SWA_SETTING
+ /// @brief Decodes PMIC0 SWC Volt -> PMIC0_SWC_OFFSET
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swa_setting(uint8_t& o_output) const
+ virtual fapi2::ReturnCode pmic0_swc_offset(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC1 SWA Volt -> PMIC1_SWA_RANGE
+ /// @brief Decodes PMIC0 SWC Volt -> PMIC0_SWC_OFFSET_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swa_range(uint8_t& o_output) const
+ virtual fapi2::ReturnCode pmic0_swc_offset_direction(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC1 SWB Volt -> PMIC1_SWB_SETTING
+ /// @brief Decodes PMIC0 SWD Volt -> PMIC0_SWD_OFFSET
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swb_setting(uint8_t& o_output) const
+ virtual fapi2::ReturnCode pmic0_swd_offset(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC1 SWB Volt -> PMIC1_SWB_RANGE
+ /// @brief Decodes PMIC0 SWD Volt -> PMIC0_SWD_OFFSET_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swb_range(uint8_t& o_output) const
+ virtual fapi2::ReturnCode pmic0_swd_offset_direction(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC1 SWC Volt -> PMIC1_SWC_SETTING
+ /// @brief Decodes PMIC1 SWA Volt -> PMIC1_SWA_OFFSET
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swc_setting(uint8_t& o_output) const
+ virtual fapi2::ReturnCode pmic1_swa_offset(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC1 SWC Volt -> PMIC1_SWC_RANGE
+ /// @brief Decodes PMIC1 SWA Volt -> PMIC1_SWA_OFFSET_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swc_range(uint8_t& o_output) const
+ virtual fapi2::ReturnCode pmic1_swa_offset_direction(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWB Volt -> PMIC1_SWB_OFFSET
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swb_offset(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWB Volt -> PMIC1_SWB_OFFSET_DIRECTION
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swb_offset_direction(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWC Volt -> PMIC1_SWC_OFFSET
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swc_offset(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWC Volt -> PMIC1_SWC_OFFSET_DIRECTION
+ /// @param[out] o_output ncoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swc_offset_direction(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC1 SWD Volt -> PMIC1_SWD_SETTING
+ /// @brief Decodes PMIC1 SWD Volt -> PMIC1_SWD_OFFSET
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swd_setting(uint8_t& o_output) const
+ virtual fapi2::ReturnCode pmic1_swd_offset(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes PMIC1 SWD Volt -> PMIC1_SWD_RANGE
+ /// @brief Decodes PMIC1 SWD Volt -> PMIC1_SWD_OFFSET_DIRECTION
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode pmic1_swd_range(uint8_t& o_output) const
+ virtual fapi2::ReturnCode pmic1_swd_offset_direction(uint8_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
diff --git a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.C b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.C
index 19a839e17..ac30f2cd0 100644
--- a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.C
+++ b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -53,6 +53,12 @@ rcw_settings rdimm_rc_a1( 0x02, // RC00 Enable weak drive
0x00); // RC01 Enables all clocks
///
+/// @brief raw card A2 settings
+///
+rcw_settings rdimm_rc_a2( 0x02, // RC00 Enable weak drive
+ 0x00); // RC01 Enables all clocks
+
+///
/// @brief raw card B1 settings
/// @note need to verify, copy from b2, need to verify with b1 annex
///
@@ -66,6 +72,12 @@ rcw_settings rdimm_rc_b2( 0x02, // RC00
0x00 ); // RC01
///
+/// @brief raw card B3 settings
+///
+rcw_settings rdimm_rc_b3( 0x02, // RC00
+ 0x00 ); // RC01
+
+///
/// @brief raw card C1 settings
///
rcw_settings rdimm_rc_c1( 0x02, // RC00
@@ -79,6 +91,13 @@ rcw_settings rdimm_rc_c2( 0x02, // RC00
0x0C ); // RC01
///
+/// @brief raw card C3 settings
+/// @note same settings as C1
+///
+rcw_settings rdimm_rc_c3( 0x02, // RC00
+ 0x0C ); // RC01
+
+///
/// @brief raw card for custom dimms
///
rcw_settings rdimm_rc_custom( 0x02, // RC00
@@ -117,8 +136,11 @@ const std::vector< std::pair< uint8_t , rcw_settings> > RAW_CARDS =
{raw_card_rev::B1, rdimm_rc_b1},
{raw_card_rev::C1, rdimm_rc_c1},
{raw_card_rev::VBU, rdimm_rc_vbu},
+ {raw_card_rev::A2, rdimm_rc_a2},
{raw_card_rev::B2, rdimm_rc_b2},
{raw_card_rev::C2, rdimm_rc_c2},
+ {raw_card_rev::B3, rdimm_rc_b3},
+ {raw_card_rev::C3, rdimm_rc_c3},
{raw_card_rev::CUSTOM, rdimm_rc_custom},
};
diff --git a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.H b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.H
index fedcbe356..e624861a0 100644
--- a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.H
+++ b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -59,16 +59,19 @@ enum raw_card_rev : uint8_t
A1 = 0x20,
B1 = 0x21,
-
// RDIMM power-on
C1 = 0x22,
// TK - Change VBU value to a no-op value or a value that will never be reached -JLH
VBU = 0x23,
+ A2 = 0x40,
B2 = 0x41,
C2 = 0x42,
+ B3 = 0x61,
+ C3 = 0x62,
+
// Default settings used for DIMMs that do not use a JEDEC raw card reference
CUSTOM = 0xFF,
};
@@ -83,10 +86,13 @@ extern const std::vector< std::pair< uint8_t, rcw_settings> > RAW_CARDS;
// Exposed so we can test them.
// Alphabetized list below
extern rcw_settings rdimm_rc_a1;
+extern rcw_settings rdimm_rc_a2;
extern rcw_settings rdimm_rc_b1;
extern rcw_settings rdimm_rc_b2;
+extern rcw_settings rdimm_rc_b3;
extern rcw_settings rdimm_rc_c1;
extern rcw_settings rdimm_rc_c2;
+extern rcw_settings rdimm_rc_c3;
extern rcw_settings rdimm_rc_custom;
extern rcw_settings rdimm_rc_nvdimm;
extern rcw_settings rdimm_rc_vbu;
diff --git a/src/import/generic/memory/lib/spd/spd_checker.H b/src/import/generic/memory/lib/spd/spd_checker.H
index 0b2a33076..50e6ef347 100644
--- a/src/import/generic/memory/lib/spd/spd_checker.H
+++ b/src/import/generic/memory/lib/spd/spd_checker.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] Evan Lojewski */
/* [+] International Business Machines Corp. */
/* */
@@ -103,17 +103,20 @@ namespace check
/// @tparam TT defaulted to bitRangeTraits<TB>
/// @param[in] i_target fapi2 target
/// @param[in] i_timing the timing value
+/// @param[in] i_rev the SPD revision that needs to be checked
/// @param[in] i_ffdc ffdc function code
/// @return FAPI2_RC_SUCCESS iff okay
///
template < bit_len BL, fapi2::TargetType T, typename TT = bitRangeTraits<BL> >
fapi2::ReturnCode max_timing_range(const fapi2::Target<T>& i_target,
const int64_t i_timing,
+ const rev i_rev,
const generic_ffdc_codes i_ffdc)
{
FAPI_ASSERT( (i_timing <= TT::UPPER_BOUND) &&
(i_timing >= TT::LOWER_BOUND),
fapi2::MSS_SPD_TIMING_FAIL()
+ .set_FAILED_REVISION(i_rev)
.set_FUNCTION_CODE(i_ffdc)
.set_TARGET(i_target),
"Failed timing parameter check for %s",
diff --git a/src/import/generic/memory/lib/spd/spd_facade.H b/src/import/generic/memory/lib/spd/spd_facade.H
index ed2fd357f..53fe2a675 100644
--- a/src/import/generic/memory/lib/spd/spd_facade.H
+++ b/src/import/generic/memory/lib/spd/spd_facade.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -48,6 +48,8 @@ inline fapi2::ReturnCode get_raw_data(const fapi2::Target<fapi2::TARGET_TYPE_DIM
FAPI_TRY( fapi2::getSPD(i_target, nullptr, l_size),
"%s. Failed to retrieve SPD blob size", spd::c_str(i_target) );
+ FAPI_DBG( "SPD size %d for %s", l_size, spd::c_str(i_target) );
+
// Reassign container size with the retrieved size
// Arbitrarily set the data to zero since it will be overwritten
o_spd.assign(l_size, 0);
@@ -74,6 +76,7 @@ class facade final
std::vector<uint8_t> iv_data;
std::shared_ptr<dimm_module_decoder> iv_dimm_module_decoder;
std::shared_ptr<base_cnfg_decoder> iv_base_cnfg_decoder;
+ uint8_t iv_dimm_type;
public:
@@ -95,6 +98,11 @@ class facade final
FAPI_TRY(l_factories.create_decoder(iv_dimm_module_decoder));
FAPI_TRY(l_factories.create_decoder(iv_base_cnfg_decoder));
+ // Variable to deal with dimm modules (e.g. DDIMM) that has
+ // fields that are not disjoint between the
+ // general and dimm module section of the SPD (i.e. a hack variable)
+ FAPI_TRY( iv_base_cnfg_decoder->base_module(iv_dimm_type) );
+
o_rc = fapi2::FAPI2_RC_SUCCESS;
return;
@@ -854,6 +862,75 @@ class facade final
}
///
+ /// @brief Decodes Fine Offset for Minimum Write to Read Time - Same Bank Group
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ /// @warning not an actual SPD field, defaulted to zero to simplify calculations
+ ///
+ fapi2::ReturnCode fine_offset_min_twtr_l( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_twtr_l(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for Minimum Write to Read Time - Different Bank Group
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ /// @warning not an actual SPD field, defaulted to zero to simplify calculations
+ ///
+ fapi2::ReturnCode fine_offset_min_twtr_s( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_twtr_s(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for SDRAM Minimum Four Activate Window Delay Time
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ /// @warning not an actual SPD field, defaulted to zero to simplify calculations
+ ///
+ fapi2::ReturnCode fine_offset_min_tfaw( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_tfaw(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for SDRAM Minimum Active to Precharge Delay Time in MTB
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ /// @warning not an actual SPD field, defaulted to zero to simplify calculations
+ ///
+ fapi2::ReturnCode fine_offset_min_tras( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_tras(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for Minimum Write Recovery Time
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode fine_offset_min_twr( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_twr(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
/// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Same Bank Group
/// @param[out] o_value SPD encoded value
/// @return FAPI2_RC_SUCCESS iff okay
@@ -1041,7 +1118,17 @@ class facade final
///
fapi2::ReturnCode dram_manufacturer_id_code( uint16_t& o_value ) const
{
- FAPI_TRY( iv_base_cnfg_decoder->dram_manufacturer_id_code(o_value) );
+ // Some module fields are duplicated in the general section and
+ // dimm module sections of the SPD. For DDIMMs, we want get it
+ // from the dimm module section instead of the general section.
+ if( iv_dimm_type == spd::DDIMM )
+ {
+ FAPI_TRY( iv_dimm_module_decoder->dram_manufacturer_id_code(o_value) );
+ }
+ else
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->dram_manufacturer_id_code(o_value) );
+ }
fapi_try_exit:
return fapi2::current_err;
@@ -1059,6 +1146,20 @@ class facade final
fapi_try_exit:
return fapi2::current_err;
}
+
+ ///
+ /// @brief Decodes module base height
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode module_base_height(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->module_base_height(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
///
/// @brief Decodes module nominal height max
/// @param[out] o_value SPD encoded value
@@ -1581,13 +1682,13 @@ class facade final
}
///
- /// @brief Decodes SPD Revision for bytes 192->447 -> SPD_REVISION
+ /// @brief Decodes SPD Revision for bytes 192->447 -> SPD_REV_DDIMM_MODULE
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- fapi2::ReturnCode ddimm_spd_revision(uint8_t& o_output) const
+ fapi2::ReturnCode ddimm_module_spd_revision(uint8_t& o_output) const
{
- FAPI_TRY( iv_dimm_module_decoder->ddimm_spd_revision(o_output) );
+ FAPI_TRY( iv_dimm_module_decoder->ddimm_module_spd_revision(o_output) );
fapi_try_exit:
return fapi2::current_err;
@@ -2035,16 +2136,29 @@ class facade final
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- fapi2::ReturnCode volt_offset_range_swa_pmic0(uint8_t& o_output) const
+ fapi2::ReturnCode volt_offset_direction_swa_pmic0(uint8_t& o_output) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->volt_offset_direction_swa_pmic0(o_output) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWA Delay -> PMIC0_SWA_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode volt_delay_swa_pmic0(uint8_t& o_output) const
{
- FAPI_TRY( iv_dimm_module_decoder->volt_offset_range_swa_pmic0(o_output) );
+ FAPI_TRY( iv_dimm_module_decoder->volt_delay_swa_pmic0(o_output) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWA Delay Sequence Order -> PMIC0_SWA_ORDER
+ /// @brief Decodes PMIC0 SWA Sequence Order -> PMIC0_SWA_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -2100,16 +2214,29 @@ class facade final
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- fapi2::ReturnCode volt_offset_range_swb_pmic0(uint8_t& o_output) const
+ fapi2::ReturnCode volt_offset_direction_swb_pmic0(uint8_t& o_output) const
{
- FAPI_TRY( iv_dimm_module_decoder->volt_offset_range_swb_pmic0(o_output) );
+ FAPI_TRY( iv_dimm_module_decoder->volt_offset_direction_swb_pmic0(o_output) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWB Delay Sequence Order -> PMIC0_SWB_ORDER
+ /// @brief Decodes PMIC0 SWB Delay -> PMIC0_SWB_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode volt_delay_swb_pmic0(uint8_t& o_output) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->volt_delay_swb_pmic0(o_output) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWB Sequence Order -> PMIC0_SWB_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -2165,16 +2292,29 @@ class facade final
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- fapi2::ReturnCode volt_offset_range_swc_pmic0(uint8_t& o_output) const
+ fapi2::ReturnCode volt_offset_direction_swc_pmic0(uint8_t& o_output) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->volt_offset_direction_swc_pmic0(o_output) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWC Delay -> PMIC0_SWC_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode volt_delay_swc_pmic0(uint8_t& o_output) const
{
- FAPI_TRY( iv_dimm_module_decoder->volt_offset_range_swc_pmic0(o_output) );
+ FAPI_TRY( iv_dimm_module_decoder->volt_delay_swc_pmic0(o_output) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWC Delay Sequence Order -> PMIC0_SWC_ORDER
+ /// @brief Decodes PMIC0 SWC Sequence Order -> PMIC0_SWC_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -2230,16 +2370,29 @@ class facade final
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- fapi2::ReturnCode volt_offset_range_swd_pmic0(uint8_t& o_output) const
+ fapi2::ReturnCode volt_offset_direction_swd_pmic0(uint8_t& o_output) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->volt_offset_direction_swd_pmic0(o_output) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWD Delay -> PMIC0_SWD_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode volt_delay_swd_pmic0(uint8_t& o_output) const
{
- FAPI_TRY( iv_dimm_module_decoder->volt_offset_range_swd_pmic0(o_output) );
+ FAPI_TRY( iv_dimm_module_decoder->volt_delay_swd_pmic0(o_output) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC0 SWD Delay Sequence Order -> PMIC0_SWD_ORDER
+ /// @brief Decodes PMIC0 SWD Sequence Order -> PMIC0_SWD_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -2265,6 +2418,19 @@ class facade final
}
///
+ /// @brief Decodes PMIC0 Sequence -> PMIC0_SEQUENCE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode sequence_pmic0(uint8_t& o_output) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->sequence_pmic0(o_output) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
/// @brief Decodes PMIC1 SWA Voltage Setting -> PMIC1_SWA_VOLT_SET
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
@@ -2308,16 +2474,29 @@ class facade final
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- fapi2::ReturnCode volt_offset_range_swa_pmic1(uint8_t& o_output) const
+ fapi2::ReturnCode volt_offset_direction_swa_pmic1(uint8_t& o_output) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->volt_offset_direction_swa_pmic1(o_output) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWA Delay -> PMIC1_SWA_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode volt_delay_swa_pmic1(uint8_t& o_output) const
{
- FAPI_TRY( iv_dimm_module_decoder->volt_offset_range_swa_pmic1(o_output) );
+ FAPI_TRY( iv_dimm_module_decoder->volt_delay_swa_pmic1(o_output) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWA Delay Sequence Order -> PMIC1_SWA_ORDER
+ /// @brief Decodes PMIC1 SWA Sequence Order -> PMIC1_SWA_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -2373,16 +2552,29 @@ class facade final
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- fapi2::ReturnCode volt_offset_range_swb_pmic1(uint8_t& o_output) const
+ fapi2::ReturnCode volt_offset_direction_swb_pmic1(uint8_t& o_output) const
{
- FAPI_TRY( iv_dimm_module_decoder->volt_offset_range_swb_pmic1(o_output) );
+ FAPI_TRY( iv_dimm_module_decoder->volt_offset_direction_swb_pmic1(o_output) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWB Delay Sequence Order -> PMIC1_SWB_ORDER
+ /// @brief Decodes PMIC1 SWB Delay -> PMIC1_SWB_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode volt_delay_swb_pmic1(uint8_t& o_output) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->volt_delay_swb_pmic1(o_output) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWB Sequence Order -> PMIC1_SWB_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -2438,16 +2630,29 @@ class facade final
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- fapi2::ReturnCode volt_offset_range_swc_pmic1(uint8_t& o_output) const
+ fapi2::ReturnCode volt_offset_direction_swc_pmic1(uint8_t& o_output) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->volt_offset_direction_swc_pmic1(o_output) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWC Delay -> PMIC1_SWC_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode volt_delay_swc_pmic1(uint8_t& o_output) const
{
- FAPI_TRY( iv_dimm_module_decoder->volt_offset_range_swc_pmic1(o_output) );
+ FAPI_TRY( iv_dimm_module_decoder->volt_delay_swc_pmic1(o_output) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWC Delay Sequence Order -> PMIC1_SWC_ORDER
+ /// @brief Decodes PMIC1 SWC Sequence Order -> PMIC1_SWC_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -2503,16 +2708,29 @@ class facade final
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- fapi2::ReturnCode volt_offset_range_swd_pmic1(uint8_t& o_output) const
+ fapi2::ReturnCode volt_offset_direction_swd_pmic1(uint8_t& o_output) const
{
- FAPI_TRY( iv_dimm_module_decoder->volt_offset_range_swd_pmic1(o_output) );
+ FAPI_TRY( iv_dimm_module_decoder->volt_offset_direction_swd_pmic1(o_output) );
fapi_try_exit:
return fapi2::current_err;
}
///
- /// @brief Decodes PMIC1 SWD Delay Sequence Order -> PMIC1_SWD_ORDER
+ /// @brief Decodes PMIC1 SWD Delay -> PMIC1_SWD_DELAY
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode volt_delay_swd_pmic1(uint8_t& o_output) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->volt_delay_swd_pmic1(o_output) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWD Sequence Order -> PMIC1_SWD_ORDER
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
@@ -2536,6 +2754,19 @@ class facade final
fapi_try_exit:
return fapi2::current_err;
}
+
+ ///
+ /// @brief Decodes PMIC0 Sequence -> PMIC0_SEQUENCE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode sequence_pmic1(uint8_t& o_output) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->sequence_pmic1(o_output) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
};
///
diff --git a/src/import/generic/memory/lib/spd/spd_factory_pattern.H b/src/import/generic/memory/lib/spd/spd_factory_pattern.H
index 567ce2d82..278fdf09d 100644
--- a/src/import/generic/memory/lib/spd/spd_factory_pattern.H
+++ b/src/import/generic/memory/lib/spd/spd_factory_pattern.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -219,7 +219,8 @@ class module_factory
RDIMM_DDR4_REV_1_1 { DDR4, RDIMM_MODULE, rev::V1_1},
NVDIMM_DDR4_REV_1_0{ DDR4, NVDIMM_MODULE, rev::V1_0},
NVDIMM_DDR4_REV_1_1{ DDR4, NVDIMM_MODULE, rev::V1_1},
- DDIMM_DDR4_REV_0_0 { DDR4, DDIMM_MODULE, rev::V0_0}
+ DDIMM_DDR4_REV_0_0 { DDR4, DDIMM_MODULE, rev::V0_0},
+ DDIMM_DDR4_REV_0_3 { DDR4, DDIMM_MODULE, rev::V0_3}
{
// Setup pre-defined maps available to search through
init_map_vars(i_spd_data, iv_decoder_map);
@@ -270,6 +271,7 @@ class module_factory
const module_key NVDIMM_DDR4_REV_1_0;
const module_key NVDIMM_DDR4_REV_1_1;
const module_key DDIMM_DDR4_REV_0_0;
+ const module_key DDIMM_DDR4_REV_0_3;
std::map< module_key, std::shared_ptr<T> > iv_decoder_map;
@@ -329,6 +331,10 @@ class module_factory
// Rev 0.0
// DDIMMs start out life w/the updated general section
o_map[DDIMM_DDR4_REV_0_0] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V0_0> >(iv_target, i_spd_data);
+
+ // Remains mostly the same. New thermal sensor fields and pmic redundancy fields
+ o_map[DDIMM_DDR4_REV_0_3] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V0_3> >(iv_target, i_spd_data);
+
}
///
@@ -375,6 +381,9 @@ class module_factory
// Rev 0.0
// Life starts out at base revision level
o_map[DDIMM_DDR4_REV_0_0] = std::make_shared< decoder<DDR4, DDIMM_MODULE, rev::V0_0> >(iv_target, i_spd_data);
+
+ // Remains mostly the same. New thermal sensor fields and pmic redundancy fields
+ o_map[DDIMM_DDR4_REV_0_3] = std::make_shared< decoder<DDR4, DDIMM_MODULE, rev::V0_3> >(iv_target, i_spd_data);
}
///
diff --git a/src/import/generic/memory/lib/spd/spd_fields_ddr4.H b/src/import/generic/memory/lib/spd/spd_fields_ddr4.H
index ac110cb9d..c05527045 100644
--- a/src/import/generic/memory/lib/spd/spd_fields_ddr4.H
+++ b/src/import/generic/memory/lib/spd/spd_fields_ddr4.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -795,10 +795,10 @@ class fields<DDR4, DDIMM_MODULE>
enum
{
- // Byte 192: SPD Revision for bytes 192->447
- SPD_REV_BYTE = 192,
- SPD_REVISION_START = 0,
- SPD_REVISION_LEN = 8,
+ // Byte 192: SPD Revision DDIMM Module Type (bytes 192->447)
+ SPD_REV_DDIMM_MODULE_BYTE = 192,
+ SPD_REV_DDIMM_MODULE_START = 0,
+ SPD_REV_DDIMM_MODULE_LEN = 8,
// Byte 193: Module Height
MODULE_HEIGHT_BYTE = 193,
@@ -959,10 +959,10 @@ class fields<DDR4, DDIMM_MODULE>
VIN_BULK_ENDURANT_START = 6,
VIN_BULK_ENDURANT_LEN = 2,
- // Byte 226: VDD_Core PMIC0
- VDD_CORE_PMIC0_BYTE = 226,
- VDD_CORE_PMIC0_START = 0,
- VDD_CORE_PMIC0_LEN = 8,
+ // Byte 226: PMIC0 Sequence
+ PMIC0_SEQUENCE_BYTE = 226,
+ PMIC0_SEQUENCE_START = 0,
+ PMIC0_SEQUENCE_LEN = 8,
// Byte 227: PMIC0 Manfacture ID code 1st byte
PMIC0_MFG_CODE1_BYTE = 227,
@@ -979,10 +979,10 @@ class fields<DDR4, DDIMM_MODULE>
PMIC0_REV_START = 0,
PMIC0_REV_LEN = 8,
- // Byte 230: VDD_Core PMIC1
- VDD_CORE_PMIC1_BYTE = 230,
- VDD_CORE_PMIC1_START = 0,
- VDD_CORE_PMIC1_LEN = 8,
+ // Byte 230: PMIC1 Sequence
+ PMIC1_SEQUENCE_BYTE = 230,
+ PMIC1_SEQUENCE_START = 0,
+ PMIC1_SEQUENCE_LEN = 8,
// Byte 231: PMIC1 Manfacture ID code 1st byte
PMIC1_MFG_CODE1_BYTE = 231,
@@ -1003,76 +1003,84 @@ class fields<DDR4, DDIMM_MODULE>
PMIC0_SWA_VOLT_SET_BYTE = 234,
PMIC0_SWA_VOLT_SET_START = 0,
PMIC0_SWA_VOLT_SET_LEN = 7,
- PMIC0_SWA_RANGE_START = 7,
- PMIC0_SWA_RANGE_LEN = 1,
+ PMIC0_SWA_RANGE_SELECT_START = 7,
+ PMIC0_SWA_RANGE_SELECT_LEN = 1,
// Byte 235: PMIC0 SWA Voltage Offset
PMIC0_SWA_VOLT_OFF_BYTE = 235,
PMIC0_SWA_VOLT_OFF_START = 0,
PMIC0_SWA_VOLT_OFF_LEN = 7,
- PMIC0_SWA_OFF_RANGE_START = 7,
- PMIC0_SWA_OFF_RANGE_LEN = 1,
+ PMIC0_SWA_OFF_DIRECTION_START = 7,
+ PMIC0_SWA_OFF_DIRECTION_LEN = 1,
// Byte 236: PMIC0 SWA Delay Sequence Order
PMIC0_SWA_DELAY_BYTE = 236,
- PMIC0_SWA_ORDER_START = 0,
+ PMIC0_SWA_DELAY_START = 0,
+ PMIC0_SWA_DELAY_LEN = 4,
+ PMIC0_SWA_ORDER_START = 4,
PMIC0_SWA_ORDER_LEN = 4,
// Byte 237: PMIC0 SWB Voltage Setting
PMIC0_SWB_VOLT_SET_BYTE = 237,
PMIC0_SWB_VOLT_SET_START = 0,
PMIC0_SWB_VOLT_SET_LEN = 7,
- PMIC0_SWB_RANGE_START = 7,
- PMIC0_SWB_RANGE_LEN = 1,
+ PMIC0_SWB_RANGE_SELECT_START = 7,
+ PMIC0_SWB_RANGE_SELECT_LEN = 1,
// Byte 238: PMIC0 SWB Voltage Offset
PMIC0_SWB_VOLT_OFF_BYTE = 238,
PMIC0_SWB_VOLT_OFF_START = 0,
PMIC0_SWB_VOLT_OFF_LEN = 7,
- PMIC0_SWB_OFF_RANGE_START = 7,
- PMIC0_SWB_OFF_RANGE_LEN = 1,
+ PMIC0_SWB_OFF_DIRECTION_START = 7,
+ PMIC0_SWB_OFF_DIRECTION_LEN = 1,
// Byte 239: PMIC0 SWB Delay Sequence Order
PMIC0_SWB_DELAY_BYTE = 239,
- PMIC0_SWB_ORDER_START = 0,
+ PMIC0_SWB_DELAY_START = 0,
+ PMIC0_SWB_DELAY_LEN = 4,
+ PMIC0_SWB_ORDER_START = 4,
PMIC0_SWB_ORDER_LEN = 4,
// Byte 240: PMIC0 SWC Voltage Setting
PMIC0_SWC_VOLT_SET_BYTE = 240,
PMIC0_SWC_VOLT_SET_START = 0,
PMIC0_SWC_VOLT_SET_LEN = 7,
- PMIC0_SWC_RANGE_START = 7,
- PMIC0_SWC_RANGE_LEN = 1,
+ PMIC0_SWC_RANGE_SELECT_START = 7,
+ PMIC0_SWC_RANGE_SELECT_LEN = 1,
// Byte 241: PMIC0 SWC Voltage Offset
PMIC0_SWC_VOLT_OFF_BYTE = 241,
PMIC0_SWC_VOLT_OFF_START = 0,
PMIC0_SWC_VOLT_OFF_LEN = 7,
- PMIC0_SWC_OFF_RANGE_START = 7,
- PMIC0_SWC_OFF_RANGE_LEN = 1,
+ PMIC0_SWC_OFF_DIRECTION_START = 7,
+ PMIC0_SWC_OFF_DIRECTION_LEN = 1,
// Byte 242: PMIC0 SWC Delay Sequence Order
PMIC0_SWC_DELAY_BYTE = 242,
- PMIC0_SWC_ORDER_START = 0,
+ PMIC0_SWC_DELAY_START = 0,
+ PMIC0_SWC_DELAY_LEN = 4,
+ PMIC0_SWC_ORDER_START = 4,
PMIC0_SWC_ORDER_LEN = 4,
// Byte 243: PMIC0 SWD Voltage Setting
PMIC0_SWD_VOLT_SET_BYTE = 243,
PMIC0_SWD_VOLT_SET_START = 0,
PMIC0_SWD_VOLT_SET_LEN = 7,
- PMIC0_SWD_RANGE_START = 7,
- PMIC0_SWD_RANGE_LEN = 1,
+ PMIC0_SWD_RANGE_SELECT_START = 7,
+ PMIC0_SWD_RANGE_SELECT_LEN = 1,
// Byte 244: PMIC0 SWD Voltage Offset
PMIC0_SWD_VOLT_OFF_BYTE = 244,
PMIC0_SWD_VOLT_OFF_START = 0,
PMIC0_SWD_VOLT_OFF_LEN = 7,
- PMIC0_SWD_OFF_RANGE_START = 7,
- PMIC0_SWD_OFF_RANGE_LEN = 1,
+ PMIC0_SWD_OFF_DIRECTION_START = 7,
+ PMIC0_SWD_OFF_DIRECTION_LEN = 1,
// Byte 245: PMIC0 SWD Delay Sequence Order
PMIC0_SWD_DELAY_BYTE = 245,
- PMIC0_SWD_ORDER_START = 0,
+ PMIC0_SWD_DELAY_START = 0,
+ PMIC0_SWD_DELAY_LEN = 4,
+ PMIC0_SWD_ORDER_START = 4,
PMIC0_SWD_ORDER_LEN = 4,
// Byte 246: PMIC0 Phase Combination
@@ -1084,82 +1092,96 @@ class fields<DDR4, DDIMM_MODULE>
PMIC1_SWA_VOLT_SET_BYTE = 247,
PMIC1_SWA_VOLT_SET_START = 0,
PMIC1_SWA_VOLT_SET_LEN = 7,
- PMIC1_SWA_RANGE_START = 7,
- PMIC1_SWA_RANGE_LEN = 1,
+ PMIC1_SWA_RANGE_SELECT_START = 7,
+ PMIC1_SWA_RANGE_SELECT_LEN = 1,
// Byte 248: PMIC1 SWA Voltage Offset
PMIC1_SWA_VOLT_OFF_BYTE = 248,
PMIC1_SWA_VOLT_OFF_START = 0,
PMIC1_SWA_VOLT_OFF_LEN = 7,
- PMIC1_SWA_OFF_RANGE_START = 7,
- PMIC1_SWA_OFF_RANGE_LEN = 1,
+ PMIC1_SWA_OFF_DIRECTION_START = 7,
+ PMIC1_SWA_OFF_DIRECTION_LEN = 1,
// Byte 249: PMIC1 SWA Delay Sequence Order
PMIC1_SWA_DELAY_BYTE = 249,
- PMIC1_SWA_ORDER_START = 0,
+ PMIC1_SWA_DELAY_START = 0,
+ PMIC1_SWA_DELAY_LEN = 4,
+ PMIC1_SWA_ORDER_START = 4,
PMIC1_SWA_ORDER_LEN = 4,
// Byte 250: PMIC1 SWB Voltage Setting
PMIC1_SWB_VOLT_SET_BYTE = 250,
PMIC1_SWB_VOLT_SET_START = 0,
PMIC1_SWB_VOLT_SET_LEN = 7,
- PMIC1_SWB_RANGE_START = 7,
- PMIC1_SWB_RANGE_LEN = 1,
+ PMIC1_SWB_RANGE_SELECT_START = 7,
+ PMIC1_SWB_RANGE_SELECT_LEN = 1,
// Byte 251: PMIC1 SWB Voltage Offset
PMIC1_SWB_VOLT_OFF_BYTE = 251,
PMIC1_SWB_VOLT_OFF_START = 0,
PMIC1_SWB_VOLT_OFF_LEN = 7,
- PMIC1_SWB_OFF_RANGE_START = 7,
- PMIC1_SWB_OFF_RANGE_LEN = 1,
+ PMIC1_SWB_OFF_DIRECTION_START = 7,
+ PMIC1_SWB_OFF_DIRECTION_LEN = 1,
// Byte 252: PMIC1 SWB Delay Sequence Order
PMIC1_SWB_DELAY_BYTE = 252,
- PMIC1_SWB_ORDER_START = 0,
+ PMIC1_SWB_DELAY_START = 0,
+ PMIC1_SWB_DELAY_LEN = 4,
+ PMIC1_SWB_ORDER_START = 4,
PMIC1_SWB_ORDER_LEN = 4,
// Byte 253: PMIC1 SWC Voltage Setting
PMIC1_SWC_VOLT_SET_BYTE = 253,
PMIC1_SWC_VOLT_SET_START = 0,
PMIC1_SWC_VOLT_SET_LEN = 7,
- PMIC1_SWC_RANGE_START = 7,
- PMIC1_SWC_RANGE_LEN = 1,
+ PMIC1_SWC_RANGE_SELECT_START = 7,
+ PMIC1_SWC_RANGE_SELECT_LEN = 1,
// Byte 254: PMIC1 SWC Voltage Offset
PMIC1_SWC_VOLT_OFF_BYTE = 254,
PMIC1_SWC_VOLT_OFF_START = 0,
PMIC1_SWC_VOLT_OFF_LEN = 7,
- PMIC1_SWC_OFF_RANGE_START = 7,
- PMIC1_SWC_OFF_RANGE_LEN = 1,
+ PMIC1_SWC_OFF_DIRECTION_START = 7,
+ PMIC1_SWC_OFF_DIRECTION_LEN = 1,
// Byte 255: PMIC1 SWC Delay Sequence Order
PMIC1_SWC_DELAY_BYTE = 255,
- PMIC1_SWC_ORDER_START = 0,
+ PMIC1_SWC_DELAY_START = 0,
+ PMIC1_SWC_DELAY_LEN = 4,
+ PMIC1_SWC_ORDER_START = 4,
PMIC1_SWC_ORDER_LEN = 4,
// Byte 256: PMIC1 SWD Voltage Setting
PMIC1_SWD_VOLT_SET_BYTE = 256,
PMIC1_SWD_VOLT_SET_START = 0,
PMIC1_SWD_VOLT_SET_LEN = 7,
- PMIC1_SWD_RANGE_START = 7,
- PMIC1_SWD_RANGE_LEN = 1,
+ PMIC1_SWD_RANGE_SELECT_START = 7,
+ PMIC1_SWD_RANGE_SELECT_LEN = 1,
// Byte 257: PMIC1 SWD Voltage Offset
PMIC1_SWD_VOLT_OFF_BYTE = 257,
PMIC1_SWD_VOLT_OFF_START = 0,
PMIC1_SWD_VOLT_OFF_LEN = 7,
- PMIC1_SWD_OFF_RANGE_START = 7,
- PMIC1_SWD_OFF_RANGE_LEN = 1,
+ PMIC1_SWD_OFF_DIRECTION_START = 7,
+ PMIC1_SWD_OFF_DIRECTION_LEN = 1,
// Byte 258: PMIC1 SWD Delay Sequence Order
PMIC1_SWD_DELAY_BYTE = 258,
- PMIC1_SWD_ORDER_START = 0,
+ PMIC1_SWD_DELAY_START = 0,
+ PMIC1_SWD_DELAY_LEN = 4,
+ PMIC1_SWD_ORDER_START = 4,
PMIC1_SWD_ORDER_LEN = 4,
// Byte 259: PMIC1 Phase Combination
PMIC1_PHASE_COMBIN_BYTE = 259,
PMIC1_PHASE_COMBIN_START = 4,
PMIC1_PHASE_COMBIN_LEN = 4,
+
+ // Byte 552-553
+ DRAM_MFR_ID_CODE_LSB_BYTE = 552,
+ DRAM_MFR_ID_CODE_MSB_BYTE = 553,
+ DRAM_MFR_ID_CODE_START = 0,
+ DRAM_MFR_ID_CODE_LEN = 8,
};
public:
@@ -1170,8 +1192,8 @@ class fields<DDR4, DDIMM_MODULE>
// Second field - start bit
// Third field - bit length
- // Byte 192: SPD Revision for bytes 192->447
- static constexpr field_t SPD_REVISION{SPD_REV_BYTE, SPD_REVISION_START, SPD_REVISION_LEN};
+ // Byte 192: SPD Revision DDIMM Module Bytes (192->447)
+ static constexpr field_t SPD_REV_DDIMM_MODULE{SPD_REV_DDIMM_MODULE_BYTE, SPD_REV_DDIMM_MODULE_START, SPD_REV_DDIMM_MODULE_LEN};
// Byte 193: Module Height
static constexpr field_t MODULE_BASE_HEIGHT{MODULE_HEIGHT_BYTE, MODULE_BASE_HEIGHT_START, MODULE_BASE_HEIGHT_LEN};
@@ -1266,8 +1288,8 @@ class fields<DDR4, DDIMM_MODULE>
static constexpr field_t VIN_BULK_OPERABLE{VIN_BULK_BYTE, VIN_BULK_OPERABLE_START, VIN_BULK_OPERABLE_LEN};
static constexpr field_t VIN_BULK_ENDURANT{VIN_BULK_BYTE, VIN_BULK_ENDURANT_START, VIN_BULK_ENDURANT_LEN};
- // Byte 226: VDD_Core PMIC0
- static constexpr field_t VDD_CORE_PMIC0{VDD_CORE_PMIC0_BYTE, VDD_CORE_PMIC0_START, VDD_CORE_PMIC0_LEN};
+ // Byte 226: PMIC0 Sequence
+ static constexpr field_t PMIC0_SEQUENCE{PMIC0_SEQUENCE_BYTE, PMIC0_SEQUENCE_START, PMIC0_SEQUENCE_LEN};
// Byte 227: PMIC0 Manfacture ID code 1st byte
static constexpr field_t PMIC0_CONT_CODE{PMIC0_MFG_CODE1_BYTE, PMIC0_CONT_CODE_START, PMIC0_CONT_CODE_LEN};
@@ -1278,8 +1300,8 @@ class fields<DDR4, DDIMM_MODULE>
// Byte 229: PMIC0 Revision Number
static constexpr field_t PMIC0_REV{PMIC0_REV_BYTE, PMIC0_REV_START, PMIC0_REV_LEN};
- // Byte 230: VDD_Core PMIC1
- static constexpr field_t VDD_CORE_PMIC1{VDD_CORE_PMIC1_BYTE, VDD_CORE_PMIC1_START, VDD_CORE_PMIC1_LEN};
+ // Byte 230: PMIC1 Sequence
+ static constexpr field_t PMIC1_SEQUENCE{PMIC1_SEQUENCE_BYTE, PMIC1_SEQUENCE_START, PMIC1_SEQUENCE_LEN};
// Byte 231: PMIC1 Manfacture ID code 1st byte
static constexpr field_t PMIC1_CONT_CODE{PMIC1_MFG_CODE1_BYTE, PMIC1_CONT_CODE_START, PMIC1_CONT_CODE_LEN};
@@ -1292,46 +1314,50 @@ class fields<DDR4, DDIMM_MODULE>
// Byte 234: PMIC0 SWA Voltage Setting
static constexpr field_t PMIC0_SWA_VOLT_SET{PMIC0_SWA_VOLT_SET_BYTE, PMIC0_SWA_VOLT_SET_START, PMIC0_SWA_VOLT_SET_LEN};
- static constexpr field_t PMIC0_SWA_RANGE{PMIC0_SWA_VOLT_SET_BYTE, PMIC0_SWA_RANGE_START, PMIC0_SWA_RANGE_LEN};
+ static constexpr field_t PMIC0_SWA_RANGE_SELECT{PMIC0_SWA_VOLT_SET_BYTE, PMIC0_SWA_RANGE_SELECT_START, PMIC0_SWA_RANGE_SELECT_LEN};
// Byte 235: PMIC0 SWA Voltage Offset
static constexpr field_t PMIC0_SWA_VOLT_OFF{PMIC0_SWA_VOLT_OFF_BYTE, PMIC0_SWA_VOLT_OFF_START, PMIC0_SWA_VOLT_OFF_LEN};
- static constexpr field_t PMIC0_SWA_OFF_RANGE{PMIC0_SWA_VOLT_OFF_BYTE, PMIC0_SWA_OFF_RANGE_START, PMIC0_SWA_OFF_RANGE_LEN};
+ static constexpr field_t PMIC0_SWA_OFF_DIRECTION{PMIC0_SWA_VOLT_OFF_BYTE, PMIC0_SWA_OFF_DIRECTION_START, PMIC0_SWA_OFF_DIRECTION_LEN};
// Byte 236: PMIC0 SWA Delay Sequence Order
+ static constexpr field_t PMIC0_SWA_DELAY{PMIC0_SWA_DELAY_BYTE, PMIC0_SWA_DELAY_START, PMIC0_SWA_DELAY_LEN};
static constexpr field_t PMIC0_SWA_ORDER{PMIC0_SWA_DELAY_BYTE, PMIC0_SWA_ORDER_START, PMIC0_SWA_ORDER_LEN};
// Byte 237: PMIC0 SWB Voltage Setting
static constexpr field_t PMIC0_SWB_VOLT_SET{PMIC0_SWB_VOLT_SET_BYTE, PMIC0_SWB_VOLT_SET_START, PMIC0_SWB_VOLT_SET_LEN};
- static constexpr field_t PMIC0_SWB_RANGE{PMIC0_SWB_VOLT_SET_BYTE, PMIC0_SWB_RANGE_START, PMIC0_SWB_RANGE_LEN};
+ static constexpr field_t PMIC0_SWB_RANGE_SELECT{PMIC0_SWB_VOLT_SET_BYTE, PMIC0_SWB_RANGE_SELECT_START, PMIC0_SWB_RANGE_SELECT_LEN};
// Byte 238: PMIC0 SWB Voltage Offset
static constexpr field_t PMIC0_SWB_VOLT_OFF{PMIC0_SWB_VOLT_OFF_BYTE, PMIC0_SWB_VOLT_OFF_START, PMIC0_SWB_VOLT_OFF_LEN};
- static constexpr field_t PMIC0_SWB_OFF_RANGE{PMIC0_SWB_VOLT_OFF_BYTE, PMIC0_SWB_OFF_RANGE_START, PMIC0_SWB_OFF_RANGE_LEN};
+ static constexpr field_t PMIC0_SWB_OFF_DIRECTION{PMIC0_SWB_VOLT_OFF_BYTE, PMIC0_SWB_OFF_DIRECTION_START, PMIC0_SWB_OFF_DIRECTION_LEN};
// Byte 239: PMIC0 SWB Delay Sequence Order
+ static constexpr field_t PMIC0_SWB_DELAY{PMIC0_SWB_DELAY_BYTE, PMIC0_SWB_DELAY_START, PMIC0_SWB_DELAY_LEN};
static constexpr field_t PMIC0_SWB_ORDER{PMIC0_SWB_DELAY_BYTE, PMIC0_SWB_ORDER_START, PMIC0_SWB_ORDER_LEN};
// Byte 240: PMIC0 SWC Voltage Setting
static constexpr field_t PMIC0_SWC_VOLT_SET{PMIC0_SWC_VOLT_SET_BYTE, PMIC0_SWC_VOLT_SET_START, PMIC0_SWC_VOLT_SET_LEN};
- static constexpr field_t PMIC0_SWC_RANGE{PMIC0_SWC_VOLT_SET_BYTE, PMIC0_SWC_RANGE_START, PMIC0_SWC_RANGE_LEN};
+ static constexpr field_t PMIC0_SWC_RANGE_SELECT{PMIC0_SWC_VOLT_SET_BYTE, PMIC0_SWC_RANGE_SELECT_START, PMIC0_SWC_RANGE_SELECT_LEN};
// Byte 241: PMIC0 SWC Voltage Offset
static constexpr field_t PMIC0_SWC_VOLT_OFF{PMIC0_SWC_VOLT_OFF_BYTE, PMIC0_SWC_VOLT_OFF_START, PMIC0_SWC_VOLT_OFF_LEN};
- static constexpr field_t PMIC0_SWC_OFF_RANGE{PMIC0_SWC_VOLT_OFF_BYTE, PMIC0_SWC_OFF_RANGE_START, PMIC0_SWC_OFF_RANGE_LEN};
+ static constexpr field_t PMIC0_SWC_OFF_DIRECTION{PMIC0_SWC_VOLT_OFF_BYTE, PMIC0_SWC_OFF_DIRECTION_START, PMIC0_SWC_OFF_DIRECTION_LEN};
// Byte 242: PMIC0 SWC Delay Sequence Order
+ static constexpr field_t PMIC0_SWC_DELAY{PMIC0_SWC_DELAY_BYTE, PMIC0_SWC_DELAY_START, PMIC0_SWC_DELAY_LEN};
static constexpr field_t PMIC0_SWC_ORDER{PMIC0_SWC_DELAY_BYTE, PMIC0_SWC_ORDER_START, PMIC0_SWC_ORDER_LEN};
// Byte 243: PMIC0 SWD Voltage Setting
static constexpr field_t PMIC0_SWD_VOLT_SET{PMIC0_SWD_VOLT_SET_BYTE, PMIC0_SWD_VOLT_SET_START, PMIC0_SWD_VOLT_SET_LEN};
- static constexpr field_t PMIC0_SWD_RANGE{PMIC0_SWD_VOLT_SET_BYTE, PMIC0_SWD_RANGE_START, PMIC0_SWD_RANGE_LEN};
+ static constexpr field_t PMIC0_SWD_RANGE_SELECT{PMIC0_SWD_VOLT_SET_BYTE, PMIC0_SWD_RANGE_SELECT_START, PMIC0_SWD_RANGE_SELECT_LEN};
// Byte 244: PMIC0 SWD Voltage Offset
static constexpr field_t PMIC0_SWD_VOLT_OFF{PMIC0_SWD_VOLT_OFF_BYTE, PMIC0_SWD_VOLT_OFF_START, PMIC0_SWD_VOLT_OFF_LEN};
- static constexpr field_t PMIC0_SWD_OFF_RANGE{PMIC0_SWD_VOLT_OFF_BYTE, PMIC0_SWD_OFF_RANGE_START, PMIC0_SWD_OFF_RANGE_LEN};
+ static constexpr field_t PMIC0_SWD_OFF_DIRECTION{PMIC0_SWD_VOLT_OFF_BYTE, PMIC0_SWD_OFF_DIRECTION_START, PMIC0_SWD_OFF_DIRECTION_LEN};
// Byte 245: PMIC0 SWD Delay Sequence Order
+ static constexpr field_t PMIC0_SWD_DELAY{PMIC0_SWD_DELAY_BYTE, PMIC0_SWD_DELAY_START, PMIC0_SWD_DELAY_LEN};
static constexpr field_t PMIC0_SWD_ORDER{PMIC0_SWD_DELAY_BYTE, PMIC0_SWD_ORDER_START, PMIC0_SWD_ORDER_LEN};
// Byte 246: PMIC0 Phase Combination
@@ -1339,51 +1365,58 @@ class fields<DDR4, DDIMM_MODULE>
// Byte 247: PMIC1 SWA Voltage Setting
static constexpr field_t PMIC1_SWA_VOLT_SET{PMIC1_SWA_VOLT_SET_BYTE, PMIC1_SWA_VOLT_SET_START, PMIC1_SWA_VOLT_SET_LEN};
- static constexpr field_t PMIC1_SWA_RANGE{PMIC1_SWA_VOLT_SET_BYTE, PMIC1_SWA_RANGE_START, PMIC1_SWA_RANGE_LEN};
+ static constexpr field_t PMIC1_SWA_RANGE_SELECT{PMIC1_SWA_VOLT_SET_BYTE, PMIC1_SWA_RANGE_SELECT_START, PMIC1_SWA_RANGE_SELECT_LEN};
// Byte 248: PMIC1 SWA Voltage Offset
static constexpr field_t PMIC1_SWA_VOLT_OFF{PMIC1_SWA_VOLT_OFF_BYTE, PMIC1_SWA_VOLT_OFF_START, PMIC1_SWA_VOLT_OFF_LEN};
- static constexpr field_t PMIC1_SWA_OFF_RANGE{PMIC1_SWA_VOLT_OFF_BYTE, PMIC1_SWA_OFF_RANGE_START, PMIC1_SWA_OFF_RANGE_LEN};
+ static constexpr field_t PMIC1_SWA_OFF_DIRECTION{PMIC1_SWA_VOLT_OFF_BYTE, PMIC1_SWA_OFF_DIRECTION_START, PMIC1_SWA_OFF_DIRECTION_LEN};
// Byte 249: PMIC1 SWA Delay Sequence Order
+ static constexpr field_t PMIC1_SWA_DELAY{PMIC1_SWA_DELAY_BYTE, PMIC1_SWA_DELAY_START, PMIC1_SWA_DELAY_LEN};
static constexpr field_t PMIC1_SWA_ORDER{PMIC1_SWA_DELAY_BYTE, PMIC1_SWA_ORDER_START, PMIC1_SWA_ORDER_LEN};
// Byte 250: PMIC1 SWB Voltage Setting
static constexpr field_t PMIC1_SWB_VOLT_SET{PMIC1_SWB_VOLT_SET_BYTE, PMIC1_SWB_VOLT_SET_START, PMIC1_SWB_VOLT_SET_LEN};
- static constexpr field_t PMIC1_SWB_RANGE{PMIC1_SWB_VOLT_SET_BYTE, PMIC1_SWB_RANGE_START, PMIC1_SWB_RANGE_LEN};
+ static constexpr field_t PMIC1_SWB_RANGE_SELECT{PMIC1_SWB_VOLT_SET_BYTE, PMIC1_SWB_RANGE_SELECT_START, PMIC1_SWB_RANGE_SELECT_LEN};
// Byte 251: PMIC1 SWB Voltage Offset
static constexpr field_t PMIC1_SWB_VOLT_OFF{PMIC1_SWB_VOLT_OFF_BYTE, PMIC1_SWB_VOLT_OFF_START, PMIC1_SWB_VOLT_OFF_LEN};
- static constexpr field_t PMIC1_SWB_OFF_RANGE{PMIC1_SWB_VOLT_OFF_BYTE, PMIC1_SWB_OFF_RANGE_START, PMIC1_SWB_OFF_RANGE_LEN};
+ static constexpr field_t PMIC1_SWB_OFF_DIRECTION{PMIC1_SWB_VOLT_OFF_BYTE, PMIC1_SWB_OFF_DIRECTION_START, PMIC1_SWB_OFF_DIRECTION_LEN};
// Byte 252: PMIC1 SWB Delay Sequence Order
+ static constexpr field_t PMIC1_SWB_DELAY{PMIC1_SWB_DELAY_BYTE, PMIC1_SWB_DELAY_START, PMIC1_SWB_DELAY_LEN};
static constexpr field_t PMIC1_SWB_ORDER{PMIC1_SWB_DELAY_BYTE, PMIC1_SWB_ORDER_START, PMIC1_SWB_ORDER_LEN};
// Byte 253: PMIC1 SWC Voltage Setting
static constexpr field_t PMIC1_SWC_VOLT_SET{PMIC1_SWC_VOLT_SET_BYTE, PMIC1_SWC_VOLT_SET_START, PMIC1_SWC_VOLT_SET_LEN};
- static constexpr field_t PMIC1_SWC_RANGE{PMIC1_SWC_VOLT_SET_BYTE, PMIC1_SWC_RANGE_START, PMIC1_SWC_RANGE_LEN};
+ static constexpr field_t PMIC1_SWC_RANGE_SELECT{PMIC1_SWC_VOLT_SET_BYTE, PMIC1_SWC_RANGE_SELECT_START, PMIC1_SWC_RANGE_SELECT_LEN};
// Byte 254: PMIC1 SWC Voltage Offset
static constexpr field_t PMIC1_SWC_VOLT_OFF{PMIC1_SWC_VOLT_OFF_BYTE, PMIC1_SWC_VOLT_OFF_START, PMIC1_SWC_VOLT_OFF_LEN};
- static constexpr field_t PMIC1_SWC_OFF_RANGE{PMIC1_SWC_VOLT_OFF_BYTE, PMIC1_SWC_OFF_RANGE_START, PMIC1_SWC_OFF_RANGE_LEN};
+ static constexpr field_t PMIC1_SWC_OFF_DIRECTION{PMIC1_SWC_VOLT_OFF_BYTE, PMIC1_SWC_OFF_DIRECTION_START, PMIC1_SWC_OFF_DIRECTION_LEN};
// Byte 255: PMIC1 SWC Delay Sequence Order
+ static constexpr field_t PMIC1_SWC_DELAY{PMIC1_SWC_DELAY_BYTE, PMIC1_SWC_DELAY_START, PMIC1_SWC_DELAY_LEN};
static constexpr field_t PMIC1_SWC_ORDER{PMIC1_SWC_DELAY_BYTE, PMIC1_SWC_ORDER_START, PMIC1_SWC_ORDER_LEN};
// Byte 256: PMIC1 SWD Voltage Setting
static constexpr field_t PMIC1_SWD_VOLT_SET{PMIC1_SWD_VOLT_SET_BYTE, PMIC1_SWD_VOLT_SET_START, PMIC1_SWD_VOLT_SET_LEN};
- static constexpr field_t PMIC1_SWD_RANGE{PMIC1_SWD_VOLT_SET_BYTE, PMIC1_SWD_RANGE_START, PMIC1_SWD_RANGE_LEN};
+ static constexpr field_t PMIC1_SWD_RANGE_SELECT{PMIC1_SWD_VOLT_SET_BYTE, PMIC1_SWD_RANGE_SELECT_START, PMIC1_SWD_RANGE_SELECT_LEN};
// Byte 257: PMIC1 SWD Voltage Offset
static constexpr field_t PMIC1_SWD_VOLT_OFF{PMIC1_SWD_VOLT_OFF_BYTE, PMIC1_SWD_VOLT_OFF_START, PMIC1_SWD_VOLT_OFF_LEN};
- static constexpr field_t PMIC1_SWD_OFF_RANGE{PMIC1_SWD_VOLT_OFF_BYTE, PMIC1_SWD_OFF_RANGE_START, PMIC1_SWD_OFF_RANGE_LEN};
+ static constexpr field_t PMIC1_SWD_OFF_DIRECTION{PMIC1_SWD_VOLT_OFF_BYTE, PMIC1_SWD_OFF_DIRECTION_START, PMIC1_SWD_OFF_DIRECTION_LEN};
// Byte 258: PMIC1 SWD Delay Sequence Order
+ static constexpr field_t PMIC1_SWD_DELAY{PMIC1_SWD_DELAY_BYTE, PMIC1_SWD_DELAY_START, PMIC1_SWD_DELAY_LEN};
static constexpr field_t PMIC1_SWD_ORDER{PMIC1_SWD_DELAY_BYTE, PMIC1_SWD_ORDER_START, PMIC1_SWD_ORDER_LEN};
// Byte 259: PMIC1 Phase Combination
static constexpr field_t PMIC1_PHASE_COMBIN{PMIC1_PHASE_COMBIN_BYTE, PMIC1_PHASE_COMBIN_START, PMIC1_PHASE_COMBIN_LEN};
+ // Byte 552 and 553: DRAM manufacturing ID for DDIMMs
+ static constexpr field_t DRAM_MFR_ID_CODE_LSB{DRAM_MFR_ID_CODE_LSB_BYTE, DRAM_MFR_ID_CODE_START, DRAM_MFR_ID_CODE_LEN};
+ static constexpr field_t DRAM_MFR_ID_CODE_MSB{DRAM_MFR_ID_CODE_MSB_BYTE, DRAM_MFR_ID_CODE_START, DRAM_MFR_ID_CODE_LEN};
};
}// spd
diff --git a/src/import/generic/memory/lib/spd/spd_traits_ddr4.H b/src/import/generic/memory/lib/spd/spd_traits_ddr4.H
index c26ca2082..fd60ba00f 100644
--- a/src/import/generic/memory/lib/spd/spd_traits_ddr4.H
+++ b/src/import/generic/memory/lib/spd/spd_traits_ddr4.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -3690,11 +3690,11 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_GAIN_ADJUST, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note SPD_REVISION field specialization
+/// @note SPD_REV_DDIMM_MODULE field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::SPD_REVISION, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::SPD_REV_DDIMM_MODULE, R >
{
public:
@@ -4450,16 +4450,16 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::VIN_BULK_ENDURANT, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note VDD_CORE_PMIC0 field specialization
+/// @note PMIC0_SEQUENCE field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::VDD_CORE_PMIC0, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SEQUENCE, R >
{
public:
- static constexpr size_t COMPARISON_VAL = 0xff;
- static constexpr const char* FIELD_STR = "VDD_Core PMIC0";
+ static constexpr size_t COMPARISON_VAL = 0x4;
+ static constexpr const char* FIELD_STR = "PMIC0 Sequence";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -4526,16 +4526,16 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_REV, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note VDD_CORE_PMIC1 field specialization
+/// @note PMIC1_SEQUENCE field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::VDD_CORE_PMIC1, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SEQUENCE, R >
{
public:
- static constexpr size_t COMPARISON_VAL = 0xff;
- static constexpr const char* FIELD_STR = "VDD_Core PMIC1";
+ static constexpr size_t COMPARISON_VAL = 0x04;
+ static constexpr const char* FIELD_STR = "PMIC1 Sequence";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -4621,11 +4621,11 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWA_VOLT_SET, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWA_RANGE field specialization
+/// @note PMIC0_SWA_RANGE_SELECT field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWA_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWA_RANGE_SELECT, R >
{
public:
@@ -4659,16 +4659,35 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWA_VOLT_OFF, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWA_OFF_RANGE field specialization
+/// @note PMIC0_SWA_OFF_DIRECTION field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWA_OFF_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWA_OFF_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC0 SWA Voltage Offset Range";
+ static constexpr const char* FIELD_STR = "PMIC0 SWA Voltage Offset Direction";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC0_SWA_DELAY field specialization
+/// @note valid for all revs
+///
+template< rev R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWA_DELAY, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "PMIC0 SWA Delay";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -4716,11 +4735,11 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWB_VOLT_SET, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWB_RANGE field specialization
+/// @note PMIC0_SWB_RANGE_SELECT field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWB_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWB_RANGE_SELECT, R >
{
public:
@@ -4754,16 +4773,16 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWB_VOLT_OFF, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWB_OFF_RANGE field specialization
+/// @note PMIC0_SWB_OFF_DIRECTION field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWB_OFF_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWB_OFF_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC0 SWB Voltage Offset Range";
+ static constexpr const char* FIELD_STR = "PMIC0 SWB Voltage Offset Direction";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -4773,6 +4792,26 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWB_OFF_RANGE, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
+/// @note PMIC0_SWB_DELAY field specialization
+/// @note valid for all revs
+///
+template< rev R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWB_DELAY, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "PMIC0 SWB Delay";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
/// @note PMIC0_SWB_ORDER field specialization
/// @note valid for all revs
///
@@ -4811,11 +4850,11 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWC_VOLT_SET, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWC_RANGE field specialization
+/// @note PMIC0_SWC_RANGE_SELECT field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWC_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWC_RANGE_SELECT, R >
{
public:
@@ -4849,16 +4888,16 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWC_VOLT_OFF, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWC_OFF_RANGE field specialization
+/// @note PMIC0_SWC_OFF_DIRECTION field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWC_OFF_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWC_OFF_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC0 SWC Voltage Offset Range";
+ static constexpr const char* FIELD_STR = "PMIC0 SWC Voltage Offset Direction";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -4868,6 +4907,26 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWC_OFF_RANGE, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
+/// @note PMIC0_SWC_DELAY field specialization
+/// @note valid for all revs
+///
+template< rev R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWC_DELAY, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "PMIC0 SWC Delay";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
/// @note PMIC0_SWC_ORDER field specialization
/// @note valid for all revs
///
@@ -4906,11 +4965,11 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWD_VOLT_SET, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWD_RANGE field specialization
+/// @note PMIC0_SWD_RANGE_SELECT field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWD_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWD_RANGE_SELECT, R >
{
public:
@@ -4944,21 +5003,41 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWD_VOLT_OFF, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC0_SWD_OFF_RANGE field specialization
+/// @note PMIC0_SWD_OFF_DIRECTION field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWD_OFF_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWD_OFF_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC0 SWD Voltage Offset Range";
+ static constexpr const char* FIELD_STR = "PMIC0 SWD Voltage Offset Direction";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC0_SWD_DELAY field specialization
+/// @note valid for all revs
+///
+template< rev R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC0_SWD_DELAY, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "PMIC0 SWD Delay";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
};
+
///
/// @class readerTraits
/// @brief trait structure to hold static SPD information
@@ -5020,11 +5099,11 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWA_VOLT_SET, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWA_RANGE field specialization
+/// @note PMIC1_SWA_RANGE_SELECT field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWA_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWA_RANGE_SELECT, R >
{
public:
@@ -5058,16 +5137,35 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWA_VOLT_OFF, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWA_OFF_RANGE field specialization
+/// @note PMIC1_SWA_OFF_DIRECTION field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWA_OFF_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWA_OFF_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC1 SWA Voltage Offset Range";
+ static constexpr const char* FIELD_STR = "PMIC1 SWA Voltage Offset Direction";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC1_SWA_DELAY field specialization
+/// @note valid for all revs
+///
+template< rev R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWA_DELAY, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "PMIC1 SWA Delay";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -5115,11 +5213,11 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWB_VOLT_SET, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWB_RANGE field specialization
+/// @note PMIC1_SWB_RANGE_SELECT field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWB_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWB_RANGE_SELECT, R >
{
public:
@@ -5153,16 +5251,35 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWB_VOLT_OFF, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWB_OFF_RANGE field specialization
+/// @note PMIC1_SWB_OFF_DIRECTION field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWB_OFF_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWB_OFF_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC1 SWB Voltage Offset Range";
+ static constexpr const char* FIELD_STR = "PMIC1 SWB Voltage Offset Direction";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC1_SWB_DELAY field specialization
+/// @note valid for all revs
+///
+template< rev R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWB_DELAY, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "PMIC1 SWB Delay";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -5210,11 +5327,11 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWC_VOLT_SET, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWC_RANGE field specialization
+/// @note PMIC1_SWC_RANGE_SELECT field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWC_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWC_RANGE_SELECT, R >
{
public:
@@ -5248,16 +5365,35 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWC_VOLT_OFF, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWC_OFF_RANGE field specialization
+/// @note PMIC1_SWC_OFF_DIRECTION field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWC_OFF_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWC_OFF_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC1 SWC Voltage Offset Range";
+ static constexpr const char* FIELD_STR = "PMIC1 SWC Voltage Offset Direction";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC1_SWC_DELAY field specialization
+/// @note valid for all revs
+///
+template< rev R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWC_DELAY, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "PMIC1 SWC Delay";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -5305,11 +5441,11 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWD_VOLT_SET, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWD_RANGE field specialization
+/// @note PMIC1_SWD_RANGE_SELECT field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWD_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWD_RANGE_SELECT, R >
{
public:
@@ -5343,16 +5479,35 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWD_VOLT_OFF, R >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note PMIC1_SWD_OFF_RANGE field specialization
+/// @note PMIC1_SWD_OFF_DIRECTION field specialization
/// @note valid for all revs
///
template< rev R >
-class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWD_OFF_RANGE, R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWD_OFF_DIRECTION, R >
{
public:
static constexpr size_t COMPARISON_VAL = 0x01;
- static constexpr const char* FIELD_STR = "PMIC1 SWD Voltage Offset Range";
+ static constexpr const char* FIELD_STR = "PMIC1 SWD Voltage Offset Direction";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC1_SWD_DELAY field specialization
+/// @note valid for all revs
+///
+template< rev R >
+class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_SWD_DELAY, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "PMIC1 SWD Delay";
template <typename T>
using COMPARISON_OP = std::less_equal<T>;
@@ -5396,6 +5551,44 @@ class readerTraits < fields< DDR4, DDIMM_MODULE>::PMIC1_PHASE_COMBIN, R >
using COMPARISON_OP = std::less_equal<T>;
};
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_MFR_ID_CODE_LSB field specialization
+/// @note valid for all revisions
+///
+template< rev R >
+class readerTraits < fields<DDR4, DDIMM_MODULE>::DRAM_MFR_ID_CODE_LSB, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr const char* FIELD_STR = "DRAM manufacturer ID code, LSB";
+
+ template <typename T>
+ using COMPARISON_OP = std::greater_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_MFR_ID_CODE_MSB field specialization
+/// @note valid for all revisions
+///
+template< rev R >
+class readerTraits < fields<DDR4, DDIMM_MODULE>::DRAM_MFR_ID_CODE_MSB, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr const char* FIELD_STR = "DRAM manufacturer ID code, MSB";
+
+ template <typename T>
+ using COMPARISON_OP = std::greater_equal<T>;
+};
+
}// spd
}// mss
diff --git a/src/import/generic/memory/lib/spd/spd_utils.C b/src/import/generic/memory/lib/spd/spd_utils.C
index bfe380dc5..38bf99577 100644
--- a/src/import/generic/memory/lib/spd/spd_utils.C
+++ b/src/import/generic/memory/lib/spd/spd_utils.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -113,7 +113,7 @@ fapi2::ReturnCode get_timebases( const mss::spd::facade& i_spd_decoder,
"Could not find a mapped value that matched the key (%d) for %s",
l_spd_ftb, spd::c_str(l_target) );
- FAPI_INF("MTB: %d, FTB: %d for %s", o_mtb, o_ftb, spd::c_str(l_target));
+ FAPI_DBG("MTB: %d, FTB: %d for %s", o_mtb, o_ftb, spd::c_str(l_target));
fapi_try_exit:
return fapi2::current_err;
@@ -162,7 +162,7 @@ fapi2::ReturnCode get_tckmin( const mss::spd::facade& i_spd_decoder,
o_value = l_temp;
- FAPI_INF("%s. tCKmin (ps): %d",
+ FAPI_DBG("%s. tCKmin (ps): %d",
spd::c_str(l_target),
o_value );
@@ -213,7 +213,7 @@ fapi2::ReturnCode get_tckmax( const mss::spd::facade& i_spd_decoder,
o_value = l_temp;
- FAPI_INF( "%s. tCKmax (ps): %d",
+ FAPI_DBG( "%s. tCKmax (ps): %d",
spd::c_str(l_target),
o_value);
diff --git a/src/import/generic/memory/lib/utils/buffer_ops.H b/src/import/generic/memory/lib/utils/buffer_ops.H
index 31e7f11a2..42b02b5d1 100644
--- a/src/import/generic/memory/lib/utils/buffer_ops.H
+++ b/src/import/generic/memory/lib/utils/buffer_ops.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -103,6 +103,32 @@ static inline void reverse( T& io_buffer )
}
///
+/// @brief Reverse a given bit range of a buffer
+/// @tparam S start bit
+/// @tparam L length of bits to reverse
+/// @tparam T buffer type
+/// @param[in] io_buffer
+///
+template<uint64_t S, uint64_t L, typename T>
+static inline void reverse_range(fapi2::buffer<T>& io_buffer)
+{
+ const auto target_length = fapi2::parameterTraits<T>::bit_length();
+
+ static_assert(S < target_length,
+ "reverse_range(): Start is out of bounds");
+
+ static_assert((S + L) <= target_length,
+ "reverse_range(): (Start + Len) is out of bounds");
+
+ fapi2::buffer<T> l_tmp;
+
+ io_buffer.template extractToRight<S, L>(l_tmp);
+
+ l_tmp.reverse();
+ io_buffer.template insert<S, L>(l_tmp);
+}
+
+///
/// @brief Swizzle bits between two fapi2 buffers, and insert from source to destination
/// @tparam DS the start bit in the destination buffer - swizzle will count up from here
/// @tparam L how many bits to swizzle
diff --git a/src/import/generic/memory/lib/utils/conversions.H b/src/import/generic/memory/lib/utils/conversions.H
index 5981fe7b5..dc4290ea5 100644
--- a/src/import/generic/memory/lib/utils/conversions.H
+++ b/src/import/generic/memory/lib/utils/conversions.H
@@ -101,7 +101,7 @@ static const std::vector<std::pair<uint64_t, uint64_t>> FREQ_TO_CLOCK_PERIOD =
{DIMM_SPEED_4400, 454}, // DDR5
{DIMM_SPEED_4800, 416}, // DDR5
};
-}
+} // ns dram_freq
///
/// @brief Return the number of picoseconds
diff --git a/src/import/generic/memory/lib/utils/count_dimm.H b/src/import/generic/memory/lib/utils/count_dimm.H
index 87f54fb40..3ceea2fab 100644
--- a/src/import/generic/memory/lib/utils/count_dimm.H
+++ b/src/import/generic/memory/lib/utils/count_dimm.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -55,7 +55,6 @@ inline size_t count_dimm(const fapi2::Target<T>& i_target)
// in the case of an over-ride and there are no DIMM in the config, we want to let
// people know. Which is how we found we needed to add this code ...
size_t l_dimm_count = find_targets<fapi2::TARGET_TYPE_DIMM>(i_target).size();
- FAPI_INF("%d DIMM on %s", l_dimm_count, mss::c_str(i_target));
return l_dimm_count;
}
@@ -71,5 +70,24 @@ inline size_t count_dimm(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target)
return 1;
}
+///
+/// @brief Return the count of the number of DIMM attached to a vector of targets
+/// @tparam T the fapi2::TargetType
+/// @param[in] i_target a vector of targets
+/// @return size_t the count of DIMM attached
+///
+template< fapi2::TargetType T >
+inline size_t count_dimm(const std::vector<fapi2::Target<T>>& i_targets)
+{
+ size_t l_dimm_count = 0;
+
+ for (const auto& l_target : i_targets)
+ {
+ l_dimm_count += count_dimm(l_target);
+ }
+
+ return l_dimm_count;
+}
+
}
#endif
diff --git a/src/import/generic/memory/lib/utils/dimm/kind.H b/src/import/generic/memory/lib/utils/dimm/kind.H
index bcb29264d..cdabc493e 100644
--- a/src/import/generic/memory/lib/utils/dimm/kind.H
+++ b/src/import/generic/memory/lib/utils/dimm/kind.H
@@ -22,3 +22,252 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file kind.H
+/// @brief Encapsulation for dimms of all types
+///
+// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _GEN_MSS_KIND_H_
+#define _GEN_MSS_KIND_H_
+
+#include <fapi2.H>
+
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
+namespace mss
+{
+
+namespace dimm
+{
+
+///
+/// @class mss::dimm::kind
+/// @tparam MC the MC type
+/// @brief A class containing information about a dimm like ranks, density, configuration - what kind of dimm is it?
+///
+template<mss::mc_type MC = DEFAULT_MC_TYPE>
+class kind
+{
+ public:
+
+ ///
+ /// @brief Generate a vector of DIMM kind from a vector of DIMM
+ /// @param[in] i_dimm a vector of DIMM
+ /// @return std::vector of dimm::kind relating to the DIMM passed in
+ ///
+ static std::vector<kind> vector(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& i_dimm)
+ {
+ std::vector<kind> l_kinds;
+
+ for (const auto& d : i_dimm)
+ {
+ l_kinds.push_back( kind(d) );
+ }
+
+ return l_kinds;
+ }
+
+ ///
+ /// @brief operator=() - assign kinds (needed to sort vectors of kinds)
+ /// @param[in] i_rhs the right hand side of the assignment statement
+ /// @return reference to this
+ ///
+ inline kind& operator=(const kind& i_rhs)
+ {
+ iv_target = i_rhs.iv_target;
+ iv_master_ranks = i_rhs.iv_master_ranks;
+ iv_total_ranks = i_rhs.iv_total_ranks;
+ iv_dram_density = i_rhs.iv_dram_density;
+ iv_dram_width = i_rhs.iv_dram_width;
+ iv_dram_generation = i_rhs.iv_dram_generation;
+ iv_dimm_type = i_rhs.iv_dimm_type;
+ iv_rows = i_rhs.iv_rows;
+ iv_size = i_rhs.iv_size;
+ iv_mfgid = i_rhs.iv_mfgid;
+ iv_stack_type = i_rhs.iv_stack_type;
+ iv_hybrid = i_rhs.iv_hybrid;
+ iv_hybrid_memory_type = i_rhs.iv_hybrid_memory_type;
+ iv_rcd_mfgid = i_rhs.iv_rcd_mfgid;
+ iv_module_height = i_rhs.iv_module_height;
+ return *this;
+ }
+
+ ///
+ /// @brief operator==() - are two kinds the same?
+ /// @param[in] i_rhs the right hand side of the comparison statement
+ /// @return bool true iff the two kind are of the same kind
+ /// @warning this does not compare the targets (iv_target,) just the values
+ /// Also does not compare the mfgid as that's not really part of the DIMM kind but is additional information
+ ///
+ inline bool operator==(const kind& i_rhs) const
+ {
+ return ((iv_master_ranks == i_rhs.iv_master_ranks) &&
+ (iv_total_ranks == i_rhs.iv_total_ranks) &&
+ (iv_dram_density == i_rhs.iv_dram_density) &&
+ (iv_dram_width == i_rhs.iv_dram_width) &&
+ (iv_dram_generation == i_rhs.iv_dram_generation) &&
+ (iv_dimm_type == i_rhs.iv_dimm_type) &&
+ (iv_rows == i_rhs.iv_rows) &&
+ (iv_size == i_rhs.iv_size) &&
+ (iv_stack_type == i_rhs.iv_stack_type) &&
+ (iv_hybrid == i_rhs.iv_hybrid) &&
+ (iv_hybrid_memory_type == i_rhs.iv_hybrid_memory_type) &&
+ (iv_rcd_mfgid == i_rhs.iv_rcd_mfgid) &&
+ (iv_module_height == i_rhs.iv_module_height));
+ }
+
+ ///
+ /// @brief operator!=() - are two kinds different?
+ /// @param[in] i_rhs the right hand side of the comparison statement
+ /// @return bool true iff the two kind are of different
+ /// @warning this does not compare the targets (iv_target,) just the values
+ ///
+ inline bool operator!=(const kind& i_rhs) const
+ {
+ return !(this->operator==(i_rhs));
+ }
+
+ ///
+ /// @brief Construct a dimm::kind data structure - information about the kind of DIMM this is
+ /// @param[in] i_target a DIMM target
+ ///
+ kind(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target):
+ iv_target(i_target)
+ {
+ FAPI_TRY( mss::attr::get_dram_gen(i_target, iv_dram_generation) );
+ FAPI_TRY( mss::attr::get_dimm_type(i_target, iv_dimm_type) );
+ FAPI_TRY( mss::attr::get_dram_density(i_target, iv_dram_density) );
+ FAPI_TRY( mss::attr::get_dram_width(i_target, iv_dram_width) );
+ FAPI_TRY( mss::attr::get_num_master_ranks_per_dimm(i_target, iv_master_ranks) );
+ FAPI_TRY( mss::attr::get_logical_ranks_per_dimm(i_target, iv_total_ranks) );
+ FAPI_TRY( mss::attr::get_dram_row_bits(i_target, iv_rows) );
+ FAPI_TRY( mss::attr::get_dimm_size(i_target, iv_size) );
+ FAPI_TRY( mss::attr::get_dram_mfg_id(i_target, iv_mfgid) );
+ FAPI_TRY( mss::attr::get_prim_stack_type( i_target, iv_stack_type) );
+ FAPI_TRY( mss::attr::get_hybrid( i_target, iv_hybrid ));
+ FAPI_TRY( mss::attr::get_hybrid_memory_type( i_target, iv_hybrid_memory_type ));
+ FAPI_TRY( mss::attr::get_rcd_mfg_id(i_target, iv_rcd_mfgid) );
+ FAPI_TRY( mss::attr::get_dram_module_height(i_target, iv_module_height) );
+ return;
+
+ fapi_try_exit:
+ // Not 100% sure what to do here ...
+ FAPI_ERR("error initializing DIMM structure: %s 0x%016lx", mss::c_str(i_target), uint64_t(fapi2::current_err));
+ fapi2::Assert(false);
+ }
+
+ ///
+ /// @brief Construct a DIMM kind used to identify this DIMM for tables.
+ /// @param[in] i_master_ranks number of master ranks on the DIMM
+ /// @param[in] i_total_ranks total number of ranks on the DIMM
+ /// @param[in] i_dram_density density of the DRAM
+ /// @param[in] i_dram_width width of the DRAM
+ /// @param[in] i_dram_generation DRAM generation
+ /// @param[in] i_dimm_type DIMM type (e.g. RDIMM)
+ /// @param[in] i_rows number of rows in the DRAM
+ /// @param[in] i_size the overal size of the DIMM in GB
+ /// @param[in] i_mfgid the dram manufacturer id of the dimm, defaulted to 0
+ /// @param[in] i_stack_type dram die type, single die package or 3DS
+ /// @param[in] i_hybrid, default not hybrid
+ /// @param[in] i_hybrid_memory_type, defult none
+ /// @param[in] i_rcd_mfgid dimm register and data buffer manufacturer id, default 0
+ /// @note can't be constexpr as fapi2::Target doesn't have a constexpr ctor.
+ ///
+ kind( const uint8_t i_master_ranks,
+ const uint8_t i_total_ranks,
+ const uint8_t i_dram_density,
+ const uint8_t i_dram_width,
+ const uint8_t i_dram_generation,
+ const uint8_t i_dimm_type,
+ const uint8_t i_rows,
+ const uint32_t i_size,
+ const uint16_t i_mfgid = 0,
+ const uint8_t i_stack_type = fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_SDP,
+ const uint8_t i_hybrid = fapi2::ENUM_ATTR_EFF_HYBRID_NOT_HYBRID,
+ const uint8_t i_hybrid_memory_type = fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NONE,
+ const uint16_t i_rcd_mfgid = 0,
+ const uint8_t i_module_height = 0
+ ):
+ iv_target(0),
+ iv_master_ranks(i_master_ranks),
+ iv_total_ranks(i_total_ranks),
+ iv_dram_density(i_dram_density),
+ iv_dram_width(i_dram_width),
+ iv_dram_generation(i_dram_generation),
+ iv_dimm_type(i_dimm_type),
+ iv_rows(i_rows),
+ // TK consider calculating size rather than requiring it be set.
+ iv_size(i_size),
+ iv_mfgid(i_mfgid),
+ iv_stack_type(i_stack_type),
+ iv_hybrid(i_hybrid),
+ iv_hybrid_memory_type(i_hybrid_memory_type),
+ iv_rcd_mfgid(i_rcd_mfgid),
+ iv_module_height(i_module_height)
+ {
+ // Bit of an idiot-check to be sure a hand-crafted dimm::kind make sense wrt slaves, masters, packages, etc.
+ // Both of these are checked in eff_config. If they are messed up, they should be caught there
+ if (iv_master_ranks > iv_total_ranks)
+ {
+ FAPI_ERR("Not enough total ranks? master: %d total: %d",
+ iv_master_ranks,
+ iv_total_ranks);
+ fapi2::Assert(false);
+ }
+
+ if ((iv_total_ranks % iv_master_ranks) != 0)
+ {
+ FAPI_ERR("total or master ranks seems incorrect. master: %d total: %d",
+ iv_master_ranks,
+ iv_total_ranks);
+ fapi2::Assert(false);
+ }
+ }
+
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
+ uint8_t iv_master_ranks;
+ uint8_t iv_total_ranks;
+ uint8_t iv_dram_density;
+ uint8_t iv_dram_width;
+ uint8_t iv_dram_generation;
+ uint8_t iv_dimm_type;
+ uint8_t iv_rows;
+ uint32_t iv_size;
+ uint16_t iv_mfgid;
+ uint8_t iv_stack_type;
+ uint8_t iv_hybrid;
+ uint8_t iv_hybrid_memory_type;
+ uint16_t iv_rcd_mfgid;
+ uint8_t iv_module_height;
+
+ ///
+ /// @brief equal_config
+ /// @param[in] i_input_compare the i_kind to compare against
+ /// @return bool true iff the two kind are of the same kind for xlate purposes
+ /// @warning this does not compare the targets (iv_target,), mfgid, prim_stack_type nor hybrid type
+ ///
+ inline bool equal_config(const kind& i_input_compare) const
+ {
+ return ((iv_master_ranks == i_input_compare.iv_master_ranks) &&
+ (iv_total_ranks == i_input_compare.iv_total_ranks) &&
+ (iv_dram_density == i_input_compare.iv_dram_density) &&
+ (iv_dram_width == i_input_compare.iv_dram_width) &&
+ (iv_dram_generation == i_input_compare.iv_dram_generation) &&
+ (iv_dimm_type == i_input_compare.iv_dimm_type) &&
+ (iv_rows == i_input_compare.iv_rows) &&
+ (iv_size == i_input_compare.iv_size));
+ }
+};
+
+}
+
+}
+#endif
diff --git a/src/import/generic/memory/lib/utils/dimm/mss_timing.H b/src/import/generic/memory/lib/utils/dimm/mss_timing.H
new file mode 100644
index 000000000..2bc9805de
--- /dev/null
+++ b/src/import/generic/memory/lib/utils/dimm/mss_timing.H
@@ -0,0 +1,912 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/generic/memory/lib/utils/dimm/mss_timing.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mss_timing.H
+/// @brief Determine effective config for mss settings
+///
+// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
+// *HWP FW Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_GEN_TIMING_H_
+#define _MSS_GEN_TIMING_H_
+
+#include <cstdint>
+#include <fapi2.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/conversions.H>
+#include <generic/memory/lib/spd/spd_utils.H>
+
+namespace mss
+{
+
+///
+/// @brief Enums for ffdc error callout so we know which function had the error
+///
+enum timing_ffdc_codes
+{
+ TRAS = 0,
+ TFAW_HALF_KB_PAGE_HELPER = 1,
+ TFAW_ONE_KB_PAGE_HELPER = 2,
+ TFAW_TW_KB_PAGE_HELPER = 3,
+ TFAW_SLR_X4_HELPER = 4,
+ TFAW_SLR_X8_HELPER = 5,
+ TRRD_S_SLR = 6,
+ TRRD_L_SLR = 7,
+ TRRD_L_HALF_AND_1KB_PAGE_HELPER = 8,
+ TRRD_S_HALF_AND_1KB_PAGE_HELPER = 9,
+ TRRD_S_2KB_PAGE_HELPER = 10,
+ TRRD_S = 11,
+ TRRD_L = 12,
+ TFAW = 13,
+ TDLLK = 14,
+};
+
+enum refresh_rate : uint8_t
+{
+ REF1X = 1, ///< Refresh rate 1X
+ REF2X = 2, ///< Refresh rate 2X
+ REF4X = 4, ///< Refresh rate 4X
+};
+
+namespace spd
+{
+
+///
+/// @brief Returns clock cycles form picoseconds based on speed bin
+/// Uses SPD rounding algorithm for DDR4
+/// @tparam OT the output type, derrived from the parameters
+/// @param[in] i_freq frequency of the DIMM
+/// @param[in] timing_in_ps timing parameter in ps
+/// @return the clock cycles of timing parameter (provided in ps)
+/// @note Uses DDR4 SPD Contents Rounding Algorithm
+/// @note Item 2220.46
+///
+template<typename OT>
+inline OT ps_to_nck( const uint64_t i_freq, const OT& i_timing_in_ps)
+{
+ OT l_tck_in_ps = 0;
+ OT l_temp_nck = 0;
+
+ // No time if MT/s is 0 (well, infinite really but shut up)
+ if (i_freq == 0)
+ {
+ return 0;
+ }
+
+ FAPI_TRY( freq_to_ps(i_freq, l_tck_in_ps),
+ "Failed freq() accessor" );
+ FAPI_TRY( calc_nck(i_timing_in_ps, l_tck_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_temp_nck),
+ "Failed calc_nck()" );
+
+ return l_temp_nck;
+
+fapi_try_exit:
+ // We simply can't work if we get an unsupported value that can't be converted to a valid tCK (clock period)
+ // ...so this should be ok
+ FAPI_ERR("Obtained an invalid MSS_FREQ (%d), or overflow occurred - stopping", i_freq);
+ fapi2::Assert(false);
+
+ // Keeps compiler happy
+ return 0;
+}
+
+///
+/// @brief Returns clock cycles from nanoseconds
+/// Uses SPD rounding algorithm for DDR4
+/// @tparam OT the output type, derrived from the parameters
+/// @param[in] i_freq frequency of the DIMM
+/// @param[out] o_value_nck the end calculation in nck
+/// @return the clock cycles of timing parameter (provided in ps)
+/// @note Uses DDR4 SPD Contents Rounding Algorithm
+/// @note Item 2220.46
+///
+template<typename OT>
+inline OT ns_to_nck( const uint64_t i_freq, const OT& i_timing_in_ns)
+{
+ return ps_to_nck(i_freq, i_timing_in_ns * CONVERT_PS_IN_A_NS);
+}
+
+}// spd
+
+///
+/// @brief Calculates refresh interval time
+/// @param[in] i_mode fine refresh rate mode
+/// @param[in] i_refresh_request_rate refresh rate
+/// @param[out] o_value timing val in ps
+/// @return fapi2::ReturnCode
+///
+inline fapi2::ReturnCode calc_trefi( const refresh_rate i_mode,
+ const uint8_t i_refresh_request_rate,
+ uint64_t& o_timing )
+{
+ // Proposed DDR4 Full spec update(79-4B)
+ // Item No. 1716.78C
+ // pg.46
+ // Table 24 - tREFI and tRFC parameters (in ps)
+ constexpr uint64_t TREFI_BASE = 7800000;
+
+ uint64_t l_refresh_request = 0;
+ constexpr double TEN_PERCENT_FASTER = 0.90;
+
+ switch(i_refresh_request_rate)
+ {
+ case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_SINGLE:
+ l_refresh_request = TREFI_BASE;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_DOUBLE:
+ // We are truncating but there is no remainder with TREFI_BASE, so we are okay
+ l_refresh_request = TREFI_BASE / 2;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_SINGLE_10_PERCENT_FASTER:
+ // We are truncating but there is no remainder with TREFI_BASE, so we are okay
+ // 10% faster so 100% - 10% = 90%
+ l_refresh_request = TREFI_BASE * TEN_PERCENT_FASTER;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_DOUBLE_10_PERCENT_FASTER:
+ // We are truncating but there is no remainder with TREFI_BASE, so we are okay
+ // 10% faster so 100% - 10% = 90%
+ l_refresh_request = (TREFI_BASE / 2) * TEN_PERCENT_FASTER;
+ break;
+
+ default:
+ // Will catch incorrect MRW value set
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_REFRESH_RATE_REQUEST().set_REFRESH_RATE_REQUEST(i_refresh_request_rate),
+ "Incorrect refresh request rate received: %d ", i_refresh_request_rate);
+ break;
+ }
+
+ o_timing = (l_refresh_request / i_mode);
+
+ FAPI_INF( "tREFI (ps): %d, refresh request (ps): %d, tREFI_base (ps): %d, REF%dX",
+ o_timing, l_refresh_request, TREFI_BASE, i_mode );
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/// @brief Calculates Minimum Refresh Recovery Delay Time (different logical rank)
+/// @param[in] i_mode fine refresh rate mode
+/// @param[in] i_density SDRAM density
+/// @param[out] o_trfc_in_ps timing val in ps
+/// @return fapi2::FAPI2_RC_SUCCESS iff okay
+///
+inline fapi2::ReturnCode calc_trfc_dlr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint8_t i_refresh_mode,
+ const uint8_t i_density,
+ uint64_t& o_trfc_in_ps)
+{
+ // Proposed DDR4 3DS Addendum
+ // Item No. 1727.58A
+ // pg. 69 - 71
+ // Table 42 - Refresh parameters by logical rank density
+ const std::vector<std::pair<uint8_t, uint64_t> > TRFC_DLR1 =
+ {
+ // { density in GBs, tRFC4(min) in picoseconds }
+ {4, 90000},
+ {8, 120000},
+ {16, 185000},
+ };
+
+ // Proposed DDR4 3DS Addendum
+ // Item No. 1727.58A
+ // pg. 69 - 71
+ // Table 42 - Refresh parameters by logical rank density
+ const std::vector<std::pair<uint8_t, uint64_t> > TRFC_DLR2 =
+ {
+ // { density in GBs, tRFC4(min) in picoseconds }
+ {4, 55000},
+ {8, 90000},
+ {16, 120000},
+ };
+
+ // Proposed DDR4 3DS Addendum
+ // Item No. 1727.58A
+ // pg. 69 - 71
+ // Table 42 - Refresh parameters by logical rank density
+ const std::vector<std::pair<uint8_t, uint64_t> > TRFC_DLR4 =
+ {
+ // { density in GBs, tRFC4(min) in picoseconds }
+ {4, 40000},
+ {8, 55000},
+ {16, 90000},
+ };
+
+ bool l_is_val_found = 0;
+
+ // Selects appropriate tRFC based on fine refresh mode
+ switch(i_refresh_mode)
+ {
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_NORMAL:
+ l_is_val_found = find_value_from_key(TRFC_DLR1, i_density, o_trfc_in_ps);
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_2X:
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_2X:
+ l_is_val_found = find_value_from_key(TRFC_DLR2, i_density, o_trfc_in_ps);
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_4X:
+ case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_4X:
+ l_is_val_found = find_value_from_key(TRFC_DLR4, i_density, o_trfc_in_ps);
+ break;
+
+ default:
+ // Fine Refresh Mode will be a platform attribute set by the MRW,
+ // which they "shouldn't" mess up as long as use "attribute" enums.
+ // if openpower messes this up we can at least catch it
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_FINE_REFRESH_MODE()
+ .set_FINE_REF_MODE(i_refresh_mode),
+ "Incorrect Fine Refresh Mode received: %d ",
+ i_refresh_mode);
+ break;
+ }// switch
+
+ FAPI_ASSERT( l_is_val_found,
+ fapi2::MSS_FAILED_TO_FIND_TRFC()
+ .set_SDRAM_DENSITY(i_density)
+ .set_REFRESH_MODE(i_refresh_mode)
+ .set_DIMM_TARGET(i_target),
+ "%s: Unable to find tRFC (ps) from map with SDRAM density key %d with %d refresh mode",
+ mss::c_str(i_target),
+ i_density,
+ i_refresh_mode);
+
+ // Again, FAPI_ASSERT doesn't set current_err to good, only to bad
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief tRTP *in ps*
+/// @return constexpr value of RTP = 7500 ps
+///
+constexpr uint64_t trtp()
+{
+ // Per JEDEC spec, defaults to 7500 ps for all frequencies.
+ // (technically max of 7.5 ns or 4 nclk, which is always 7.5ns for DDR4)
+ return 7500;
+}
+
+///
+/// @brief Return the minimum allowable tRAS in picoseconds
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_freq freq for the DIMM
+/// @return value in picoseconds
+///
+inline uint64_t tras(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint64_t i_freq)
+{
+ uint64_t l_tras = 0;
+
+ switch(i_freq)
+ {
+ case 1866:
+ l_tras = 34000;
+ break;
+
+ case 2133:
+ l_tras = 33000;
+ break;
+
+ case 2400:
+ case 2666:
+ case 2933:
+ case 3200:
+ l_tras = 32000;
+ break;
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_FREQ_PASSED_IN()
+ .set_FREQ(i_freq)
+ .set_FUNCTION(TRAS)
+ .set_DIMM_TARGET(i_target),
+ "%s Invalid frequency %lu",
+ mss::c_str(i_target),
+ i_freq);
+ }
+
+ return l_tras;
+
+fapi_try_exit:
+
+ // We simply can't work if we can't get the frequency or
+ // if we get an unsupported value that can't be converted to a valid tCK (clock period)
+ // ...so this should be ok
+ FAPI_ERR("Obtained an invalid MSS_FREQ (%d) - stopping", i_freq);
+ fapi2::Assert(false);
+
+ // Keeps compiler happy
+ return 0;
+}
+
+///
+/// @brief Helper function to find tFAW based speed (MT/s) for 1/2 KB page
+/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_freq the DRAM frequency
+/// @param[out] o_output timing in clocks (nck)
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note this is only for non-3DS DIMM
+///
+template< fapi2::TargetType T >
+static fapi2::ReturnCode tfaw_half_kb_page_helper(const fapi2::Target<T>& i_target,
+ const uint64_t i_freq,
+ uint64_t& o_output)
+{
+ // Values derived from DDR4 Spec (79-4A)
+ // 13.3 Timing Parameters by Speed Grade
+ // Table 132. Pg 240
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // It could have been more "efficient" to hand-calculate the answer and
+ // use compile time constants to return the answer. To avoid magic
+ // numbers and to align (more closely) with the DDR4 JEDEC spec,
+ // we let the std library do the work for us for maintainability.
+ // Could have used compile-time constants to denote the numbers below
+ // but they are "random" and vary.
+ switch(i_freq)
+ {
+ // static_cast is needed for template deduction of std::max API
+ case 1866:
+ o_output = std::max( 16, spd::ps_to_nck(i_freq, 17000) );
+ break;
+
+ case 2133:
+ o_output = std::max( 16, spd::ps_to_nck(i_freq, 15000) );
+ break;
+
+ case 2400:
+ o_output = std::max( 16, spd::ps_to_nck(i_freq, 13000) );
+ break;
+
+ case 2666:
+ o_output = std::max( 16, spd::ps_to_nck(i_freq, 12000) );
+ break;
+
+ case 2933:
+ o_output = std::max( 16, spd::ps_to_nck(i_freq, 10875) );
+ break;
+
+ case 3200:
+ o_output = std::max( 16, spd::ps_to_nck(i_freq, 10000) );
+ break;
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_FREQ_PASSED_IN()
+ .set_FREQ(i_freq)
+ .set_FUNCTION(TFAW_HALF_KB_PAGE_HELPER)
+ .set_DIMM_TARGET(i_target),
+ "%s Invalid frequency %lu",
+ mss::c_str(i_target),
+ i_freq);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to find tFAW based speed (MT/s) for 1KB page
+/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_freq the DRAM frequency
+/// @param[out] o_output timing in clocks (nck)
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note this is only for non-3DS DIMM
+///
+template< fapi2::TargetType T >
+static fapi2::ReturnCode tfaw_1kb_page_helper(const fapi2::Target<T>& i_target,
+ const uint64_t i_freq,
+ uint64_t& o_output)
+{
+ // Values derived from DDR4 Spec (79-4A)
+ // 13.3 Timing Parameters by Speed Grade
+ // Table 132. Pg 240
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // It could have been more "efficient" to hand-calculate the answer and
+ // use compile time constants to return the answer. To avoid magic
+ // numbers and to align (more closely) with the DDR4 JEDEC spec,
+ // we let the std library do the work for us for maintainability (and ease of debug?).
+ // Could have used compile-time constants to denote the numbers below
+ // but they are "random" and vary.
+ switch(i_freq)
+ {
+ case 1866:
+ o_output = std::max( 20, spd::ns_to_nck(i_freq, 23) );
+ break;
+
+ case 2133:
+ case 2400:
+ case 2666:
+ case 2933:
+ case 3200:
+ o_output = std::max( 20, spd::ns_to_nck(i_freq, 21) );
+ break;
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_FREQ_PASSED_IN()
+ .set_FREQ(i_freq)
+ .set_FUNCTION(TFAW_ONE_KB_PAGE_HELPER)
+ .set_DIMM_TARGET(i_target),
+ "%s Invalid frequency %lu",
+ mss::c_str(i_target),
+ i_freq);
+ break;
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to find tFAW based speed (MT/s) for 2KB page
+/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_freq the DRAM frequency
+/// @param[out] o_output timing in clocks (nck)
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note this is only for non-3DS DIMM
+///
+template< fapi2::TargetType T >
+static fapi2::ReturnCode tfaw_2kb_page_helper(const fapi2::Target<T>& i_target,
+ const uint64_t i_freq,
+ uint64_t& o_output)
+{
+
+ // Values derived from DDR4 Spec (79-4A)
+ // 13.3 Timing Parameters by Speed Grade
+ // Table 132. Pg 240
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // It could have been more "efficient" to hand-calculate the answer and
+ // use compile time constants to return the answer. To avoid magic
+ // numbers and to align (more closely) with the DDR4 JEDEC spec,
+ // we let the std library do the work for us for maintainability.
+ // Could have used compile-time constants to denote the numbers below
+ // but they are "random" and vary.
+ switch(i_freq)
+ {
+ case 1866:
+ case 2133:
+ case 2400:
+ case 2666:
+ case 2933:
+ case 3200:
+ o_output = std::max( 28, spd::ns_to_nck(i_freq, 30) );
+ break;
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_FREQ_PASSED_IN()
+ .set_FREQ(i_freq)
+ .set_FUNCTION(TFAW_TW_KB_PAGE_HELPER)
+ .set_DIMM_TARGET(i_target),
+ "%s Invalid frequency %lu",
+ mss::c_str(i_target),
+ i_freq);
+ break;
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Return the minimum allowable tFAW in nck
+/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_dram_width the page size
+/// @param[in] i_freq the DRAM frequency
+/// @param[out] o_tFAW timing in clocks (nck)
+/// @return FAPI2_RC_SUCCESS iff okay
+//
+template< fapi2::TargetType T >
+fapi2::ReturnCode tfaw( const fapi2::Target<T>& i_target,
+ const uint8_t i_dram_width,
+ const uint64_t i_freq,
+ uint64_t& o_tFAW )
+{
+ switch(i_dram_width)
+ {
+ case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4:
+ FAPI_TRY( tfaw_half_kb_page_helper(i_target, i_freq, o_tFAW) );
+ break;
+
+ case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8:
+ FAPI_TRY( tfaw_1kb_page_helper(i_target, i_freq, o_tFAW) );
+ break;
+
+ case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X16:
+ FAPI_TRY( tfaw_2kb_page_helper(i_target, i_freq, o_tFAW) );
+ break;
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_DRAM_WIDTH()
+ .set_DRAM_WIDTH(i_dram_width)
+ .set_DIMM_TARGET(i_target),
+ "Invalid DRAM width with %d for target %s",
+ i_dram_width,
+ mss::c_str(i_target));
+ break;
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief tFAW_dlr *in nck*
+/// @return 16nck
+/// @note From DDR4 3DS Spec
+/// 12.2 Timing Parameters by Speed Grade
+///
+constexpr uint64_t tfaw_dlr()
+{
+ return 16;
+}
+
+///
+/// @brief tRRD_dlr *in nck*
+/// @return 4nck
+/// @note From DDR4 3DS Spec
+/// 12.2 Timing Parameters by Speed Grade
+///
+constexpr uint64_t trrd_dlr()
+{
+ return 4;
+}
+
+///
+/// @brief Helper function to find tRRD_L based speed (MT/s) for 1KB page
+/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_freq the DRAM frequency
+/// @param[out] o_output timing in clocks (nck)
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note this is only for non-3DS DIMM
+///
+template< fapi2::TargetType T >
+static fapi2::ReturnCode trrd_l_half_and_1kb_page_helper(const fapi2::Target<T>& i_target,
+ const uint64_t i_freq,
+ uint64_t& o_output)
+{
+ // Values derived from DDR4 Spec (79-4A)
+ // 13.3 Timing Parameters by Speed Grade
+ // Table 132. Pg 240
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // It could have been more "efficient" to hand-calculate the answer and
+ // use compile time constants to return the answer. To avoid magic
+ // numbers and to align (more closely) with the DDR4 JEDEC spec,
+ // we let the std library do the work for us for maintainability (and ease of debug?).
+ // Could have used compile-time constants to denote the numbers below
+ // but they are "random" and vary.
+ switch(i_freq)
+ {
+ case 1866:
+ case 2133:
+ // From the spec: Max(4nCK,5.3ns)
+ o_output = std::max( 4, spd::ps_to_nck(i_freq, 5300) );
+ break;
+
+ case 2400:
+ case 2666:
+ case 2933:
+ case 3200:
+ // Max(4nCK,4.9ns)
+ o_output = std::max( 4, spd::ps_to_nck(i_freq, 4900) );
+ break;
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_FREQ_PASSED_IN()
+ .set_FREQ(i_freq)
+ .set_FUNCTION(TRRD_L_HALF_AND_1KB_PAGE_HELPER)
+ .set_DIMM_TARGET(i_target),
+ "%s Invalid frequency %lu",
+ mss::c_str(i_target),
+ i_freq);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to find tRRD_L based speed (MT/s) for 2KB page
+/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_freq the DRAM frequency
+/// @param[out] o_output timing in clocks (nck)
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note this is only for non-3DS DIMM
+///
+template< fapi2::TargetType T >
+static fapi2::ReturnCode trrd_l_2kb_page_helper(const fapi2::Target<T>& i_target,
+ const uint64_t i_freq,
+ uint64_t& o_output)
+{
+
+ // Values derived from DDR4 Spec (79-4A)
+ // 13.3 Timing Parameters by Speed Grade
+ // Table 132. Pg 240
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // It could have been more "efficient" to hand-calculate the answer and
+ // use compile time constants to return the answer. To avoid magic
+ // numbers and to align (more closely) with the DDR4 JEDEC spec,
+ // we let the std library do the work for us for maintainability (and ease of debug?).
+ // Could have used compile-time constants to denote the numbers below
+ // but they are "random" and vary.
+ switch(i_freq)
+ {
+ case 1866:
+ case 2133:
+ case 2400:
+ case 2666:
+ case 2933:
+ case 3200:
+ o_output = std::max( 4, spd::ps_to_nck(i_freq, 6400) );
+ break;
+
+ default:
+ FAPI_TRY(fapi2::FAPI2_RC_INVALID_PARAMETER, "%s Invalid frequency %lu", mss::c_str(i_target), i_freq);
+ break;
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Return the minimum allowable tRRD_L in nck
+/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_dram_width the page size
+/// @param[in] i_freq the DRAM frequency
+/// @param[out] o_output timing in clocks (nck)
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note this is only for non-3DS DIMM
+///
+template< fapi2::TargetType T >
+fapi2::ReturnCode trrd_l( const fapi2::Target<T>& i_target,
+ const uint8_t i_dram_width,
+ const uint64_t i_freq,
+ uint64_t& o_tRRD_L )
+{
+ switch(i_dram_width)
+ {
+ case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4:
+ case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8:
+ FAPI_TRY( trrd_l_half_and_1kb_page_helper(i_target, i_freq, o_tRRD_L),
+ "Error calculating trrd l for half and 1kb page" );
+ break;
+
+ case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X16:
+ FAPI_TRY( trrd_l_2kb_page_helper(i_target, i_freq, o_tRRD_L) );
+ break;
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_PAGE_SIZE()
+ .set_DRAM_WIDTH(i_dram_width)
+ .set_DIMM_TARGET(i_target),
+ "%s Recieved an invalid page size: %lu",
+ mss::c_str(i_target),
+ i_dram_width);
+ break;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to find tRRD_S based speed (MT/s) for 1KB page
+/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_freq the DRAM frequency
+/// @param[out] o_output timing in clocks (nck)
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note this is only for non-3DS DIMM
+///
+template< fapi2::TargetType T >
+static fapi2::ReturnCode trrd_s_half_and_1kb_page_helper(const fapi2::Target<T>& i_target,
+ const uint64_t i_freq,
+ uint64_t& o_output)
+{
+ // Values derived from DDR4 Spec (79-4A)
+ // 13.3 Timing Parameters by Speed Grade
+ // Table 132. Pg 240
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // It could have been more "efficient" to hand-calculate the answer and
+ // use compile time constants to return the answer. To avoid magic
+ // numbers and to align (more closely) with the DDR4 JEDEC spec,
+ // we let the std library do the work for us for maintainability (and ease of debug?).
+ // Could have used compile-time constants to denote the numbers below
+ // but they are "random" and vary.
+ switch(i_freq)
+ {
+ case 1866:
+ o_output = std::max( 4, spd::ps_to_nck(i_freq, 4200) );
+ break;
+
+ case 2133:
+ o_output = std::max( 4, spd::ps_to_nck(i_freq, 3700) );
+ break;
+
+ case 2400:
+ o_output = std::max( 4, spd::ps_to_nck(i_freq, 3300) );
+ break;
+
+ case 2666:
+ o_output = std::max( 4, spd::ps_to_nck(i_freq, 3000) );
+ break;
+
+ case 2933:
+ o_output = std::max( 4, spd::ps_to_nck(i_freq, 2700) );
+ break;
+
+ case 3200:
+ o_output = std::max( 4, spd::ps_to_nck(i_freq, 2500) );
+ break;
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_FREQ_PASSED_IN()
+ .set_FREQ(i_freq)
+ .set_FUNCTION(TRRD_S_HALF_AND_1KB_PAGE_HELPER)
+ .set_DIMM_TARGET(i_target),
+ "%s Invalid frequency %lu",
+ mss::c_str(i_target),
+ i_freq);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to find tRRD_S based speed (MT/s) for 2KB page
+/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_freq the DRAM frequency
+/// @param[out] o_output timing in clocks (nck)
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note this is only for non-3DS DIMM
+///
+template< fapi2::TargetType T >
+static fapi2::ReturnCode trrd_s_2kb_page_helper(const fapi2::Target<T>& i_target,
+ const uint64_t i_freq,
+ uint64_t& o_output)
+{
+ // Values derived from DDR4 Spec (79-4A)
+ // 13.3 Timing Parameters by Speed Grade
+ // Table 132. Pg 240
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // It could have been more "efficient" to hand-calculate the answer and
+ // use compile time constants to return the answer. To avoid magic
+ // numbers and to align (more closely) with the DDR4 JEDEC spec,
+ // we let the std library do the work for us for maintainability (and ease of debug?).
+ // Could have used compile-time constants to denote the numbers below
+ // but they are "random" and vary.
+ switch(i_freq)
+ {
+ case 1866:
+ case 2133:
+ case 2400:
+ case 2666:
+ case 2933:
+ case 3200:
+ o_output = std::max( 4, spd::ps_to_nck(i_freq, 5300) );
+ break;
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_FREQ_PASSED_IN()
+ .set_FREQ(i_freq)
+ .set_FUNCTION(TRRD_S_2KB_PAGE_HELPER)
+ .set_DIMM_TARGET(i_target),
+ "%s Invalid frequency %lu",
+ mss::c_str(i_target),
+ i_freq);
+ break;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Return the minimum allowable tRRD_S in nck
+/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_dram_width the page size
+/// @param[in] i_freq the DRAM frequency
+/// @param[out] o_tRRD_S timing in clocks (nck)
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note this is only for non-3DS DIMM
+///
+template< fapi2::TargetType T >
+fapi2::ReturnCode trrd_s( const fapi2::Target<T>& i_target,
+ const uint8_t i_dram_width,
+ const uint64_t i_freq,
+ uint64_t& o_tRRD_S )
+{
+ switch(i_dram_width)
+ {
+ case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4:
+ case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8:
+ FAPI_TRY( trrd_s_half_and_1kb_page_helper(i_target, i_freq, o_tRRD_S),
+ "Error calculating trrd_s for half and 1kb page" );
+ break;
+
+ case fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X16:
+ FAPI_TRY( trrd_s_2kb_page_helper(i_target, i_freq, o_tRRD_S) );
+ break;
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_PAGE_SIZE()
+ .set_DRAM_WIDTH(i_dram_width)
+ .set_DIMM_TARGET(i_target),
+ "%s Recieved an invalid page size: %lu",
+ mss::c_str(i_target),
+ i_dram_width);
+ break;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // mss
+#endif
diff --git a/src/import/generic/memory/lib/utils/dump_regs.H b/src/import/generic/memory/lib/utils/dump_regs.H
index 91241cd70..f8d7e5b12 100644
--- a/src/import/generic/memory/lib/utils/dump_regs.H
+++ b/src/import/generic/memory/lib/utils/dump_regs.H
@@ -22,3 +22,34 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+
+///
+/// @file dump_regs.H
+/// @brief Dump registers
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_DUMP_REGS_H_
+#define _MSS_DUMP_REGS_H_
+
+#include <fapi2.H>
+
+namespace mss
+{
+
+///
+/// @brief Dump the registers of a target
+/// @tparam T, the fapi2::TargetType
+/// @param[in] i_target the target in question
+/// @return fapi2::FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+fapi2::ReturnCode dump_regs( const fapi2::Target<T>& i_target );
+
+}
+#endif
diff --git a/src/import/generic/memory/lib/utils/endian_utils.H b/src/import/generic/memory/lib/utils/endian_utils.H
index 20bfd7caa..94b9dbc0d 100644
--- a/src/import/generic/memory/lib/utils/endian_utils.H
+++ b/src/import/generic/memory/lib/utils/endian_utils.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,9 +37,14 @@
#ifndef _ENDIAN_UTILS_H_
#define _ENDIAN_UTILS_H_
-#include <cstdint>
#include <vector>
-#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
+#ifdef __PPE__
+ #include <mss_generic_consts.H>
+#else
+ #include <cstdint>
+ #include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#endif
namespace mss
{
@@ -67,6 +72,7 @@ void forceLE(const T& i_input, std::vector<uint8_t>& io_data)
}
}
+#ifndef __PPE__
///
/// @brief Forces native data into LE order for an array
/// @tparam T the data type to process
@@ -82,7 +88,7 @@ inline void forceLEArray(const T* i_input, const uint64_t i_size, std::vector<ui
forceLE(i_input[i], io_data);
}
}
-
+#endif
///
/// @brief Forces native data into BE order
/// @tparam T the data type to process
@@ -98,20 +104,31 @@ void forceBE(const T& i_input, std::vector<uint8_t>& io_data)
std::vector<uint8_t> l_tempBuffer;
// This loop will put i_input into l_tempBuffer in BE order
- for(size_t i = 0; i < sizeof(i_input); i++)
+
+ for(size_t i = sizeof(i_input); i > 0; i--)
{
// Grab the lowest order byte and add it to the front of the vector
const uint8_t l_byte = l_temp & 0xFF;
- l_tempBuffer.insert(l_tempBuffer.begin(), l_byte);
+ l_tempBuffer.push_back(l_byte);
// Shift higher byte value into lowest no matter existing endianness
l_temp >>= BITS_PER_BYTE;
}
// Put the new BE formatted data at the end of the input buffer
- io_data.insert(io_data.end(), l_tempBuffer.begin(), l_tempBuffer.end());
+
+ std::vector<uint8_t>::iterator it = l_tempBuffer.end();
+ --it; //Move iterator to the last element.
+
+ for(uint8_t i = l_tempBuffer.size(); i > 0; --i)
+ {
+ io_data.push_back(*it);
+ --it;
+ }
+
}
+#ifndef __PPE__
///
/// @brief Forces native data into BE order for an array
/// @tparam T the data type to process
@@ -127,6 +144,7 @@ inline void forceBEArray(const T* i_input, const uint64_t i_size, std::vector<ui
forceBE(i_input[i], io_data);
}
}
+#endif
///
/// @brief Converts LE data into native order
@@ -165,6 +183,7 @@ bool readLE(const std::vector<uint8_t>& i_input, uint32_t& io_idx, T& o_data)
return true;
}
+#ifndef __PPE__
///
/// @brief Converts LE data into native order
/// @tparam T the data type to output to
@@ -188,6 +207,7 @@ bool readLEArray(const std::vector<uint8_t>& i_input, const uint32_t i_size, uin
return l_passing;
}
+#endif
///
/// @brief Converts BE data into native order
@@ -225,6 +245,7 @@ bool readBE(const std::vector<uint8_t>& i_input, uint32_t& io_idx, T& o_data)
return true;
}
+#ifndef __PPE__
///
/// @brief Converts BE data into native order
/// @tparam T the data type to output to
@@ -248,6 +269,7 @@ bool readBEArray(const std::vector<uint8_t>& i_input, const uint32_t i_size, uin
return l_passing;
}
+#endif
}
diff --git a/src/import/generic/memory/lib/utils/find.H b/src/import/generic/memory/lib/utils/find.H
index c22199b6d..297334ae7 100644
--- a/src/import/generic/memory/lib/utils/find.H
+++ b/src/import/generic/memory/lib/utils/find.H
@@ -38,9 +38,13 @@
#include <fapi2.H>
#include <vector>
+#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/utils/index.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
namespace mss
{
+
///
/// @brief Helper to find a set of elements based on a fapi2 target
/// @tparam M the target type to be returned
@@ -117,6 +121,7 @@ static inline fapi2::Target<M> find_target_impl( const fapi2::Target<T>& i_targe
/// @tparam M the target type to be returned
/// @tparam T the fapi2 target type of the argument
/// @param[in] i_target the fapi2 target T
+/// @param[in] std::true_type tag dispatch if T == M
/// @return an M target.
/// @note Only works for valid parent-child relationships
///
@@ -145,30 +150,6 @@ inline fapi2::Target<M> find_target( const fapi2::Target<T>& i_target)
}
///
-/// @brief find the McBIST given a DIMM
-/// @param[in] i_target the fapi2 target DIMM
-/// @return a McBIST target.
-///
-template<>
-inline fapi2::Target<fapi2::TARGET_TYPE_MCBIST> find_target(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target)
-{
- return i_target.getParent<fapi2::TARGET_TYPE_MCA>().getParent<fapi2::TARGET_TYPE_MCBIST>();
-}
-
-///
-/// @brief find the PROC_CHIP given a MBA
-/// @param[in] i_target the fapi2 target MBA
-/// @return a DMI target.
-///
-template<>
-inline fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> find_target(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
-{
- return i_target.getParent<fapi2::TARGET_TYPE_MEMBUF_CHIP>()
- .getParent<fapi2::TARGET_TYPE_DMI>()
- .getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
-}
-
-///
/// @brief find the PROC_CHIP given a OCMB_CHIP
/// @param[in] i_target the fapi2 target OCMB_CHIP
/// @return a PROC_CHIP target.
@@ -183,26 +164,16 @@ inline fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> find_target(const fapi2::Targ
}
///
-/// @brief find the DMI given an MBA
-/// @param[in] i_target the fapi2 target MBA
-/// @return a DMI target.
-///
-template<>
-inline fapi2::Target<fapi2::TARGET_TYPE_DMI> find_target(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
-{
- return i_target.getParent<fapi2::TARGET_TYPE_MEMBUF_CHIP>().getParent<fapi2::TARGET_TYPE_DMI>();
-}
-
-///
-/// @brief find the PROC given a MEMBUF
-/// @param[in] i_target the fapi2 target MEMBUF
-/// @return a PROC target.
+/// @brief find the MCC given a OCMB_CHIP
+/// @param[in] i_target the fapi2 target OCMB_CHIP
+/// @return a MCC target.
///
template<>
-inline fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> find_target(const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>&
+inline fapi2::Target<fapi2::TARGET_TYPE_MCC> find_target(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
i_target)
{
- return i_target.getParent<fapi2::TARGET_TYPE_DMI>().getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+ return i_target.getParent<fapi2::TARGET_TYPE_OMI>()
+ .getParent<fapi2::TARGET_TYPE_MCC>();
}
///
@@ -230,98 +201,93 @@ find_targets( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
}
///
-/// @brief find all the MBA connected to an DMI
-/// @param[in] i_target a fapi2::Target DMI
-/// @return a vector of fapi2::TARGET_TYPE_MBA
-///
-template<>
-inline std::vector< fapi2::Target<fapi2::TARGET_TYPE_MBA> >
-find_targets( const fapi2::Target<fapi2::TARGET_TYPE_DMI>& i_target,
- fapi2::TargetState i_state )
-{
- std::vector< fapi2::Target<fapi2::TARGET_TYPE_MBA> > l_mbas;
-
- for (const auto& membuf_chip : i_target.getChildren<fapi2::TARGET_TYPE_MEMBUF_CHIP>(i_state))
- {
- auto l_these_mbas( membuf_chip.getChildren<fapi2::TARGET_TYPE_MBA>(i_state) );
- l_mbas.insert(l_mbas.end(), l_these_mbas.begin(), l_these_mbas.end());
- }
-
- return l_mbas;
-}
-
-///
-/// @brief find all the DIMM connected to a centaur
-/// @param[in] i_target a fapi2::Target TARGET_TYPE_MEMBUF_CHIP
+/// @brief find all the DIMMS connected to an MI
+/// @param[in] i_target a fapi2::Target MI
/// @return a vector of fapi2::TARGET_TYPE_DIMM
///
template<>
inline std::vector< fapi2::Target<fapi2::TARGET_TYPE_DIMM> >
-find_targets( const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_target,
+find_targets( const fapi2::Target<fapi2::TARGET_TYPE_MI>& i_target,
fapi2::TargetState i_state )
{
std::vector< fapi2::Target<fapi2::TARGET_TYPE_DIMM> > l_dimms;
- for (const auto& l_mba : i_target.getChildren<fapi2::TARGET_TYPE_MBA>(i_state))
+ for (const auto& l_omi : i_target.getChildren<fapi2::TARGET_TYPE_OMI>(i_state))
{
- auto l_these_dimms( l_mba.getChildren<fapi2::TARGET_TYPE_DIMM>(i_state) );
- l_dimms.insert(l_dimms.end(), l_these_dimms.begin(), l_these_dimms.end());
+ for (const auto& l_ocmb : l_omi.getChildren<fapi2::TARGET_TYPE_OCMB_CHIP>(i_state))
+ {
+ auto l_these_dimms( l_ocmb.getChildren<fapi2::TARGET_TYPE_DIMM>(i_state) );
+ l_dimms.insert(l_dimms.end(), l_these_dimms.begin(), l_these_dimms.end());
+ }
}
return l_dimms;
}
///
-/// @brief find all the dimm connected to an MCS
-/// @param[in] i_target a fapi2::Target MCS
-/// @return a vector of fapi2::TARGET_TYPE_DIMM
+/// @brief find all the OCMB_CHIPs connected to an MI
+/// @param[in] i_target a fapi2::Target MI
+/// @return a vector of fapi2::TARGET_TYPE_OCMB_CHIP
///
template<>
-inline std::vector< fapi2::Target<fapi2::TARGET_TYPE_DIMM> >
-find_targets( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
+inline std::vector< fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> >
+find_targets( const fapi2::Target<fapi2::TARGET_TYPE_MI>& i_target,
fapi2::TargetState i_state )
{
- std::vector< fapi2::Target<fapi2::TARGET_TYPE_DIMM> > l_dimms;
+ std::vector< fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> > l_ocmbs;
- for (const auto& p : i_target.getChildren<fapi2::TARGET_TYPE_MCA>(i_state))
+ for (const auto& l_omi : i_target.getChildren<fapi2::TARGET_TYPE_OMI>(i_state))
{
- auto l_these_dimms( p.getChildren<fapi2::TARGET_TYPE_DIMM>(i_state) );
- l_dimms.insert(l_dimms.end(), l_these_dimms.begin(), l_these_dimms.end());
+ auto l_these_ocmbs( l_omi.getChildren<fapi2::TARGET_TYPE_OCMB_CHIP>(i_state) );
+ l_ocmbs.insert(l_ocmbs.end(), l_these_ocmbs.begin(), l_these_ocmbs.end());
}
- return l_dimms;
+ return l_ocmbs;
}
///
-/// @brief find all the dimms connected to an MCBIST
-/// @param[in] i_target a fapi2::Target MCBIST
-/// @return a vector of fapi2::TARGET_TYPE_DIMM
+/// @brief find all the MEM_PORTs connected to a PROC_CHIP
+/// @param[in] i_target a fapi2::Target PROC_CHIP
+/// @return a vector of fapi2::TARGET_TYPE_MEM_PORT
///
template<>
-inline std::vector< fapi2::Target<fapi2::TARGET_TYPE_DIMM> >
-find_targets( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+inline std::vector< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> >
+find_targets( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
fapi2::TargetState i_state )
{
- std::vector< fapi2::Target<fapi2::TARGET_TYPE_DIMM> > l_dimms;
+ std::vector< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> > l_ports;
- for (const auto& p : i_target.getChildren<fapi2::TARGET_TYPE_MCA>(i_state))
+ for (const auto& l_mc : i_target.getChildren<fapi2::TARGET_TYPE_MC>(i_state))
{
- auto l_these_dimms( p.getChildren<fapi2::TARGET_TYPE_DIMM>(i_state) );
- l_dimms.insert(l_dimms.end(), l_these_dimms.begin(), l_these_dimms.end());
+ for (const auto& l_omi : l_mc.getChildren<fapi2::TARGET_TYPE_OMI>(i_state))
+ {
+ for (const auto& l_ocmb : l_omi.getChildren<fapi2::TARGET_TYPE_OCMB_CHIP>(i_state))
+ {
+ auto l_these_ports( l_ocmb.getChildren<fapi2::TARGET_TYPE_MEM_PORT>(i_state) );
+ l_ports.insert(l_ports.end(), l_these_ports.begin(), l_these_ports.end());
+ }
+ }
}
- return l_dimms;
+ return l_ports;
}
///
-/// @brief find the MCS given a DIMM
-/// @param[in] i_target the fapi2 target DIMM
-/// @return a MCS target.
+/// @brief Helper to find a set of elements based on a fapi2 target, then sort them
+/// @tparam M the target type to be returned
+/// @tparam T the fapi2 target type of the argument
+/// @param[in] i_target the fapi2 target T
+/// @param[in] i_state [optional] fapi2 target state (defaults to TARGET_STATE_FUNCTIONAL)
+/// @return a vector of M targets sorted by mss::index.
+/// @note this uses mss::index so the targets will be sorted via ATTR_REL_POS of their immediate parent
///
-template<>
-inline fapi2::Target<fapi2::TARGET_TYPE_MCS> find_target( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target)
+template< fapi2::TargetType M, fapi2::TargetType T >
+static inline std::vector< fapi2::Target<M> > find_targets_sorted_by_index( const fapi2::Target<T>& i_target,
+ fapi2::TargetState i_state = fapi2::TARGET_STATE_FUNCTIONAL )
{
- return i_target.getParent<fapi2::TARGET_TYPE_MCA>().getParent<fapi2::TARGET_TYPE_MCS>();
+ std::vector<fapi2::Target<M>> l_targets = find_targets<M, T>(i_target, i_state);
+ sort_targets_by_index(l_targets);
+ return l_targets;
}
///
@@ -432,6 +398,40 @@ bool find_value_from_key( const std::pair<T, OT> (&i_array)[N],
return false;
}
+///
+/// @brief Mapping boilerplate check
+/// @tparam T FAPI2 target type
+/// @tparam IT map key type
+/// @tparam OT map value type
+/// @param[in] i_target the FAPI target
+/// @param[in] i_map SPD to attribute data mapping
+/// @param[in] i_ffdc_code FFDC function code
+/// @param[in] i_key Key to query map
+/// @param[out] o_output value from key
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+template< fapi2::TargetType T, typename IT, typename OT >
+inline fapi2::ReturnCode lookup_table_check(const fapi2::Target<T>& i_target,
+ const std::vector<std::pair<IT, OT>>& i_map,
+ const generic_ffdc_codes i_ffdc_code,
+ const IT i_key,
+ OT& o_output)
+{
+ const bool l_is_val_found = mss::find_value_from_key(i_map, i_key, o_output);
+
+ FAPI_ASSERT( l_is_val_found,
+ fapi2::MSS_LOOKUP_FAILED()
+ .set_KEY(i_key)
+ .set_DATA(o_output)
+ .set_FUNCTION(i_ffdc_code)
+ .set_TARGET(i_target),
+ "Failed to find a mapped value for %d on %s",
+ i_key,
+ mss::spd::c_str(i_target) );
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
}// mss
#endif
diff --git a/src/import/generic/memory/lib/utils/fir/gen_mss_unmask.H b/src/import/generic/memory/lib/utils/fir/gen_mss_unmask.H
index fa14534e5..a45b48202 100644
--- a/src/import/generic/memory/lib/utils/fir/gen_mss_unmask.H
+++ b/src/import/generic/memory/lib/utils/fir/gen_mss_unmask.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,6 +38,8 @@
#include <fapi2.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
namespace mss
{
@@ -46,40 +48,63 @@ namespace unmask
///
/// @brief Unmask and setup actions performed after draminit_mc
+/// @tparam MC the memory controller type
/// @tparam T the fapi2::TargetType which hold the FIR bits
/// @param[in] i_target the fapi2::Target
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
-template< mss::mc_type MC, fapi2::TargetType T >
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
fapi2::ReturnCode after_draminit_mc( const fapi2::Target<T>& i_target );
///
/// @brief Unmask and setup actions performed after draminit_training
+/// @tparam MC the memory controller type
/// @tparam T the fapi2::TargetType which hold the FIR bits
/// @param[in] i_target the fapi2::Target
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
-template< mss::mc_type MC, fapi2::TargetType T >
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
fapi2::ReturnCode after_draminit_training( const fapi2::Target<T>& i_target );
///
/// @brief Unmask and setup actions performed after mss_scominit
+/// @tparam MC the memory controller type
/// @tparam T the fapi2::TargetType which hold the FIR bits
-/// @param[in] i_target the fapi2::Target of the MCBIST
+/// @param[in] i_target the fapi2::Target
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
-template< mss::mc_type MC, fapi2::TargetType T >
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
fapi2::ReturnCode after_scominit( const fapi2::Target<T>& i_target );
///
/// @brief Unmask and setup actions performed after mss_ddr_phy_reset
+/// @tparam MC the memory controller type
/// @tparam T the fapi2::TargetType which hold the FIR bits
-/// @param[in] i_target the fapi2::Target of the MCBIST
+/// @param[in] i_target the fapi2::Target
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
-template< mss::mc_type MC, fapi2::TargetType T >
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
fapi2::ReturnCode after_phy_reset( const fapi2::Target<T>& i_target );
+///
+/// @brief Unmask and setup actions for memdiags related FIR
+/// @tparam MC the memory controller type
+/// @tparam T the fapi2::TargetType which hold the FIR bits
+/// @param[in] i_target the fapi2::Target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
+fapi2::ReturnCode after_memdiags( const fapi2::Target<T>& i_target );
+
+///
+/// @brief Unmask and setup actions for scrub related FIR
+/// @tparam MC the memory controller type
+/// @tparam T the fapi2::TargetType which hold the FIR bits
+/// @param[in] i_target the fapi2::Target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
+fapi2::ReturnCode after_background_scrub( const fapi2::Target<T>& i_target );
}
}
diff --git a/src/import/generic/memory/lib/utils/freq/cas_latency.H b/src/import/generic/memory/lib/utils/freq/cas_latency.H
index 1b71481e2..0605189c2 100644
--- a/src/import/generic/memory/lib/utils/freq/cas_latency.H
+++ b/src/import/generic/memory/lib/utils/freq/cas_latency.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -571,7 +571,7 @@ class cas_latency
l_temp);
o_value = l_temp;
- FAPI_INF( "%s. tAAmin (ps): %d",
+ FAPI_DBG( "%s. tAAmin (ps): %d",
mss::spd::c_str(l_target),
o_value);
@@ -628,7 +628,7 @@ class cas_latency
{
FAPI_TRY( spd::calc_nck(i_taa, i_tck, spd::INVERSE_DDR4_CORRECTION_FACTOR, o_cas_latency) );
- FAPI_INF("%s. tAA (ps): %d, tCK (ps): %d, CL (nck): %d",
+ FAPI_DBG("%s. tAA (ps): %d, tCK (ps): %d, CL (nck): %d",
mss::spd::c_str(iv_target),
i_taa,
i_tck,
@@ -651,8 +651,8 @@ class cas_latency
const uint64_t l_min_cl = get_min_cl(l_cl_mask);
const uint64_t l_max_cl = get_max_cl(l_cl_mask);
- FAPI_INF("%s. min CL %lu", mss::spd::c_str(iv_target), l_min_cl);
- FAPI_INF("%s. max CL %lu", mss::spd::c_str(iv_target), l_max_cl);
+ FAPI_DBG("%s. min CL %lu", mss::spd::c_str(iv_target), l_min_cl);
+ FAPI_DBG("%s. max CL %lu", mss::spd::c_str(iv_target), l_max_cl);
for(uint64_t l_cas_latency = l_min_cl; l_cas_latency <= l_max_cl; ++l_cas_latency)
{
@@ -688,7 +688,7 @@ class cas_latency
{
const bool l_found = std::binary_search(i_common_cls.begin(), i_common_cls.end(), i_cas_latency);
- FAPI_INF("Found CL: %d in common CL mask: 0x%llX ? %s for %s",
+ FAPI_DBG("Found CL: %d in common CL mask: 0x%llX ? %s for %s",
i_cas_latency, iv_common_cl_bitmap, l_found ? "yes" : "no", mss::spd::c_str(iv_target));
return l_found;
@@ -709,7 +709,7 @@ class cas_latency
const size_t l_taa_max = (iv_is_3ds == loading::NOT_3DS) ? TAA_MAX_DDR4 : TAA_MAX_DDR4_3DS;
const bool l_is_cl_exceeding_taa = l_cas_latency_time > l_taa_max;
- FAPI_INF("%s. CL (%d) * tCK (%d) = %d > %d ? %s",
+ FAPI_DBG("%s. CL (%d) * tCK (%d) = %d > %d ? %s",
mss::spd::c_str(iv_target),
i_cas_latency,
i_tck,
@@ -758,7 +758,7 @@ class cas_latency
FAPI_TRY( freq_to_ps(l_proposed_freq, io_tck),
"%s. Failed freq_to_ps()", mss::spd::c_str(iv_target) );
- FAPI_INF("%s Supported dimm speed override %d MT/s (Clock period %d in ps)",
+ FAPI_DBG("%s Supported dimm speed override %d MT/s (Clock period %d in ps)",
mss::spd::c_str(iv_target), l_proposed_freq, io_tck);
// Sanity check
diff --git a/src/import/generic/memory/lib/utils/freq/gen_mss_freq.H b/src/import/generic/memory/lib/utils/freq/gen_mss_freq.H
index 4df0eeb06..c681f2e59 100644
--- a/src/import/generic/memory/lib/utils/freq/gen_mss_freq.H
+++ b/src/import/generic/memory/lib/utils/freq/gen_mss_freq.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -105,7 +105,7 @@ fapi2::ReturnCode get_dimm_type(const fapi2::Target<T>& i_target,
/// @return FAPI2_RC_SUCCESS iff ok
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
-fapi2::ReturnCode callout_bad_freq_calculated(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
+fapi2::ReturnCode callout_bad_freq_calculated(const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target,
const uint64_t i_final_freq);
///
@@ -164,7 +164,7 @@ fapi2::ReturnCode is_vpd_config_supported( const fapi2::Target<TT::VPD_TARGET_TY
set_MAX(VPD_KW_MAX).
set_ACTUAL(io_vpd_info.iv_size).
set_KEYWORD(VPD_BLOB).
- set_MCS_TARGET(i_target),
+ set_VPD_TARGET(i_target),
"VPD MR keyword size retrieved: %d, is larger than max: %d for %s",
io_vpd_info.iv_size, TT::VPD_KEYWORD_MAX, mss::c_str(i_target));
}
@@ -208,7 +208,7 @@ fapi2::ReturnCode check_freq_support_vpd( const fapi2::Target<TT::PORT_TARGET_TY
/// @return FAPI2_RC_SUCCESS iff ok
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
-inline fapi2::ReturnCode set_freq_attrs(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
+inline fapi2::ReturnCode set_freq_attrs(const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target,
const std::vector<uint64_t>& i_dimm_freq)
{
// Find the minimum (but non-0) freq in the vector. If we see all 0's we'll write a 0. However,
@@ -245,7 +245,7 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff okay
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
-inline fapi2::ReturnCode spd_supported_freq(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
+inline fapi2::ReturnCode spd_supported_freq(const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target,
std::vector<uint32_t>& o_supported_freqs)
{
uint64_t l_largest_tck = 0;
@@ -255,7 +255,17 @@ inline fapi2::ReturnCode spd_supported_freq(const fapi2::Target<TT::FREQ_TARGET_
// Get cached decoder
std::vector< mss::spd::facade > l_spd_facades;
- FAPI_TRY( get_spd_decoder_list(i_target, l_spd_facades), "%s get decoder - spd", mss::c_str(i_target) );
+
+ for (const auto& l_port : mss::find_targets<TT::PORT_TARGET_TYPE>(i_target))
+ {
+ std::vector< mss::spd::facade > l_these_spd_facades;
+ FAPI_TRY( get_spd_decoder_list(l_port, l_these_spd_facades), "%s get decoder - spd", mss::c_str(l_port) );
+
+ for (const auto& l_spd_facade : l_these_spd_facades)
+ {
+ l_spd_facades.push_back(l_spd_facade);
+ }
+ }
// Looking for the biggest application period on an MC.
// This will further reduce supported frequencies the system can run on.
@@ -263,7 +273,7 @@ inline fapi2::ReturnCode spd_supported_freq(const fapi2::Target<TT::FREQ_TARGET_
{
const auto l_dimm = l_cache.get_dimm_target();
const auto l_port = mss::find_target<TT::PORT_TARGET_TYPE>(l_dimm);
- const auto l_port_pos = mss::relative_pos<TT::FREQ_TARGET_TYPE>(l_port);
+ const auto l_port_pos = mss::relative_pos<TT::FREQ_DOMAIN_TARGET_TYPE>(l_port);
uint64_t l_tckmax_in_ps = 0;
uint64_t l_tck_min_in_ps = 0;
uint32_t l_dimm_freq = 0;
@@ -279,7 +289,7 @@ inline fapi2::ReturnCode spd_supported_freq(const fapi2::Target<TT::FREQ_TARGET_
l_largest_tck = std::min(l_largest_tck, l_tckmax_in_ps);
FAPI_TRY( mss::ps_to_freq(l_largest_tck, l_dimm_freq), "%s ps to freq %lu", mss::c_str(i_target), l_largest_tck );
- FAPI_INF("Biggest freq supported from SPD %d MT/s for %s",
+ FAPI_DBG("Biggest freq supported from SPD %d MT/s for %s",
l_dimm_freq, mss::c_str(l_dimm));
o_supported_freqs[l_port_pos] = std::min(l_dimm_freq, o_supported_freqs[l_port_pos]);
@@ -299,12 +309,12 @@ fapi_try_exit:
///
// Pass in the syncronous target
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
-fapi2::ReturnCode vpd_supported_freqs( const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
+fapi2::ReturnCode vpd_supported_freqs( const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target,
std::vector<std::vector<uint32_t>>& o_vpd_supported_freqs)
{
// This bitmap will keep track of the ports we visit.
// Any we don't are not configured, so will support all frequencies in the scoreboard
- fapi2::buffer<uint8_t> configured_ports;
+ fapi2::buffer<uint64_t> configured_ports;
// Clearing output Just.In.Case
o_vpd_supported_freqs.clear();
@@ -317,7 +327,8 @@ fapi2::ReturnCode vpd_supported_freqs( const fapi2::Target<TT::FREQ_TARGET_TYPE>
// Just go to find target for the port level
for( const auto& p : mss::find_targets<TT::PORT_TARGET_TYPE>(i_target) )
{
- const auto l_port_pos = mss::relative_pos<TT::FREQ_TARGET_TYPE>(p);
+ const auto l_port_pos = mss::relative_pos<TT::FREQ_DOMAIN_TARGET_TYPE>(p);
+
FAPI_TRY( configured_ports.setBit(l_port_pos) );
if( mss::count_dimm(p) == 0 )
@@ -342,7 +353,7 @@ fapi2::ReturnCode vpd_supported_freqs( const fapi2::Target<TT::FREQ_TARGET_TYPE>
// Add supported freqs to our output
if (l_supported)
{
- FAPI_INF("VPD supported freq added: %d for %s", freq, mss::c_str(p) );
+ FAPI_DBG("VPD supported freq added: %d for %s", freq, mss::c_str(p) );
o_vpd_supported_freqs[l_port_pos].push_back(freq);
}
}
@@ -381,7 +392,7 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff okay
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
-inline fapi2::ReturnCode find_min_dimm_freq(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
+inline fapi2::ReturnCode find_min_dimm_freq(const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target,
const std::vector<uint32_t>& i_supported_freqs,
std::vector<uint64_t>& o_min_dimm_freq)
{
@@ -420,14 +431,14 @@ inline fapi2::ReturnCode find_min_dimm_freq(const fapi2::Target<TT::FREQ_TARGET_
// Find CAS latency using JEDEC algorithm
FAPI_TRY( l_cas_latency.find_cl(l_desired_cl, l_tCKmin), "%s failed to find a cas latency", mss::c_str(i_target) );
- FAPI_INF("%s. Result from CL algorithm, CL (nck): %d, tCK (ps): %d",
+ FAPI_DBG("%s. Result from CL algorithm, CL (nck): %d, tCK (ps): %d",
mss::c_str(l_port), l_desired_cl, l_tCKmin);
// Find dimm transfer speed from selected tCK
FAPI_TRY( mss::ps_to_freq(l_tCKmin, l_desired_freq),
"%s. Failed ps_to_freq()", mss::c_str(l_port) );
- FAPI_INF("DIMM speed %d from selected tCK (ps): %d for %s",
+ FAPI_DBG("DIMM speed %d from selected tCK (ps): %d for %s",
l_desired_freq,
l_tCKmin,
mss::c_str(l_port));
@@ -437,7 +448,7 @@ inline fapi2::ReturnCode find_min_dimm_freq(const fapi2::Target<TT::FREQ_TARGET_
}// end else
FAPI_TRY(set_CL_attr<P>(l_port, l_desired_cl), "%s. Failed set_CL_attr()", mss::c_str(l_port) );
- } // mca
+ } // port
fapi_try_exit:
return fapi2::current_err;
@@ -452,7 +463,7 @@ fapi_try_exit:
/// @return FAPI2_RC_SUCCESS iff okay
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
-inline fapi2::ReturnCode supported_freqs(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
+inline fapi2::ReturnCode supported_freqs(const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target,
std::vector<uint32_t>& o_freqs)
{
o_freqs.clear();
@@ -462,15 +473,18 @@ inline fapi2::ReturnCode supported_freqs(const fapi2::Target<TT::FREQ_TARGET_TYP
std::vector<std::vector<uint32_t>> l_vpd_supported_freqs;
std::vector<uint32_t> l_spd_supported_freq;
std::vector<uint8_t> l_deconfigured = {0};
+ std::vector<fapi2::Target<TT::PORT_TARGET_TYPE>> l_deconfigured_targets;
// Retrieve system MRW, SPD, and VPD constraints
FAPI_TRY( max_allowed_dimm_freq<P>(l_max_mrw_freqs.data()), "%s max_allowed_dimm_freq", mss::c_str(i_target) );
+
FAPI_TRY( spd_supported_freq<P>(i_target, l_spd_supported_freq),
"%s spd supported freqs", mss::c_str(i_target) );
+
FAPI_TRY( vpd_supported_freqs<P>(i_target, l_vpd_supported_freqs),
"%s vpd supported freqs", mss::c_str(i_target) );
- // Limits the frequency by the Nimbus processor constraints (sync mode)
+ // Limits the frequency by the processor constraints (sync mode)
FAPI_TRY( limit_freq_by_processor<P>(i_target, l_scoreboard) );
// Limit frequency scoreboard according to MRW constraints
@@ -486,6 +500,7 @@ inline fapi2::ReturnCode supported_freqs(const fapi2::Target<TT::FREQ_TARGET_TYP
FAPI_TRY( l_scoreboard.template resolve<P>(i_target,
l_vpd_supported_freqs,
l_deconfigured,
+ l_deconfigured_targets,
o_freqs) );
FAPI_INF("%s supported freqs:", mss::c_str(i_target));
@@ -510,7 +525,7 @@ namespace check
/// @return FAPI2_RC_SUCCESS iff okay
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
-fapi2::ReturnCode final_freq(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target);
+fapi2::ReturnCode final_freq(const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target);
} // check nameespace
@@ -522,16 +537,16 @@ fapi2::ReturnCode final_freq(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target
/// @return FAPI2_RC_SUCCESS iff okay
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
-fapi2::ReturnCode generate_freq(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target)
+fapi2::ReturnCode generate_freq(const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target)
{
std::vector<uint64_t> l_min_dimm_freq;
std::vector<uint32_t> l_supported_freqs;
- // Get supported freqs for this MCBIST
+ // Get supported freqs for this domain
FAPI_TRY( mss::supported_freqs<P>(i_target, l_supported_freqs), "%s failed to get supported frequencies",
mss::c_str(i_target) );
- // Finds the minimum supported DIMM frequencies for this MCBIST
+ // Finds the minimum supported DIMM frequencies for this domain
FAPI_TRY(mss::find_min_dimm_freq<P>(i_target, l_supported_freqs, l_min_dimm_freq),
"%s. Failed find_min_dimm_freq()", mss::c_str(i_target) );
diff --git a/src/import/generic/memory/lib/utils/freq/mss_freq_scoreboard.H b/src/import/generic/memory/lib/utils/freq/mss_freq_scoreboard.H
index 3b2f7ded9..94bdcc980 100644
--- a/src/import/generic/memory/lib/utils/freq/mss_freq_scoreboard.H
+++ b/src/import/generic/memory/lib/utils/freq/mss_freq_scoreboard.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -161,7 +161,6 @@ class freq_scoreboard
if ( l_scoreboard_freq > i_freq_limit )
{
- FAPI_INF("Removing freq %d on port %d since it's above the limit %d", l_scoreboard_freq, i_port_pos, i_freq_limit);
l_port_supported_freqs[l_index] = false;
}
}
@@ -229,7 +228,6 @@ class freq_scoreboard
if (l_it == i_freq_list.end())
{
- FAPI_INF("Removing freq %d on port %d since it's not supported", iv_freq_values[l_index], i_port_pos);
iv_supported_port_freqs[i_port_pos][l_index] = false;
}
}
@@ -308,13 +306,15 @@ class freq_scoreboard
/// @param[in] i_target MCBIST target
/// @param[in] i_vpd_supported_freqs vector of hardware supported freqs -- from VPD
/// @param[out] o_deconfigured vector of port positions that were deconfigured by this function
+ /// @param[out] o_deconfigured_targets vector of port targets that were deconfigured by this function
/// @param[out] o_freqs vector of frequencies supported by all ports
/// @return FAPI2_RC_SUCCESS if successful
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
- fapi2::ReturnCode resolve(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
+ fapi2::ReturnCode resolve(const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target,
const std::vector<std::vector<uint32_t>>& i_vpd_supported_freqs,
std::vector<uint8_t>& o_deconfigured,
+ std::vector<fapi2::Target<TT::PORT_TARGET_TYPE>>& o_deconfigured_targets,
std::vector<uint32_t>& o_freqs)
{
const auto l_ports = mss::find_targets<TT::PORT_TARGET_TYPE>(i_target);
@@ -358,10 +358,10 @@ class freq_scoreboard
FAPI_TRY(callout_no_common_freq<P>(i_target, l_common_ports > l_empty_port_count, l_port_count));
// Now find and deconfigure all ports that don't support our selected frequency
- FAPI_TRY(deconfigure_ports<P>(i_target, l_ports, l_best_freq_index, o_deconfigured));
+ FAPI_TRY(deconfigure_ports<P>(i_target, l_ports, l_best_freq_index, o_deconfigured, o_deconfigured_targets));
// Now find all the frequencies supported by the ports that are left over
- FAPI_TRY(this->template resolve<P>(i_target, i_vpd_supported_freqs, o_deconfigured, o_freqs));
+ FAPI_TRY(this->template resolve<P>(i_target, i_vpd_supported_freqs, o_deconfigured, o_deconfigured_targets, o_freqs));
#ifndef __HOSTBOOT_MODULE
@@ -417,7 +417,7 @@ class freq_scoreboard
/// @returh l_supported_vector return the fector of supported frequencies
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
- std::vector<uint64_t> count_supported_frequencies(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
+ std::vector<uint64_t> count_supported_frequencies(const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target,
const std::vector<fapi2::Target<TT::PORT_TARGET_TYPE>>& i_ports,
std::vector<uint32_t>& o_freqs)
{
@@ -434,7 +434,7 @@ class freq_scoreboard
{
if (l_supported[l_index])
{
- FAPI_INF("%s Frequency %d is supported by port%d", mss::c_str(i_target), TT::SUPPORTED_FREQS[l_index], l_pos);
+ FAPI_DBG("%s Frequency %d is supported by port%d", mss::c_str(i_target), TT::SUPPORTED_FREQS[l_index], l_pos);
++l_support_counts[l_index];
}
@@ -442,7 +442,7 @@ class freq_scoreboard
// Note that deconfigured ports will support all frequencies due to the way the scoreboard is built
if (l_support_counts[l_index] == iv_num_ports)
{
- FAPI_INF("%s Frequency %d is supported by all ports", mss::c_str(i_target), TT::SUPPORTED_FREQS[l_index]);
+ FAPI_DBG("%s Frequency %d is supported by all ports", mss::c_str(i_target), TT::SUPPORTED_FREQS[l_index]);
o_freqs.push_back(TT::SUPPORTED_FREQS[l_index]);
}
@@ -461,15 +461,18 @@ class freq_scoreboard
/// @param[in] i_ports vector of ports
/// @param[in] i_best_freq_index index corresponding to the best case frequency
/// @param[out] o_deconfigured vector of deconfigured port positions
+ /// @param[out] o_deconfigured_targets vector of deconfigured targets
/// @return FAPI2_RC_SUCCESS iff ok
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
- fapi2::ReturnCode deconfigure_ports(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
+ fapi2::ReturnCode deconfigure_ports(const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target,
const std::vector<fapi2::Target<TT::PORT_TARGET_TYPE>>& i_ports,
const uint64_t i_best_freq_index,
- std::vector<uint8_t>& o_deconfigured)
+ std::vector<uint8_t>& o_deconfigured,
+ std::vector<fapi2::Target<TT::PORT_TARGET_TYPE>>& o_deconfigured_targets)
{
o_deconfigured.clear();
+ o_deconfigured_targets.clear();
for ( size_t l_pos = 0; l_pos < iv_num_ports; ++l_pos )
{
@@ -478,7 +481,7 @@ class freq_scoreboard
i_ports.end(),
[l_pos]( const fapi2::Target<TT::PORT_TARGET_TYPE>& i_rhs) -> bool
{
- return (mss::relative_pos<TT::FREQ_TARGET_TYPE>(i_rhs) != l_pos);
+ return (mss::relative_pos<TT::FREQ_DOMAIN_TARGET_TYPE>(i_rhs) == l_pos);
});
// If we didn't find an port for a given position, there wasn't one configured there
@@ -489,7 +492,7 @@ class freq_scoreboard
// and call it out if it doesn't support the selected freq
const auto& p = *l_it_port;
- FAPI_INF("Checking if port %d (%s) supports common frequency", l_pos, mss::c_str(p));
+ FAPI_DBG("Checking if port %d (%s) supports common frequency", l_pos, mss::c_str(p));
if (!iv_supported_port_freqs[l_pos][i_best_freq_index])
{
@@ -497,6 +500,7 @@ class freq_scoreboard
auto& l_port_supported_freqs = iv_supported_port_freqs[l_pos];
o_deconfigured.push_back(l_pos);
+ o_deconfigured_targets.push_back(p);
FAPI_ASSERT_NOEXIT( false,
fapi2::MSS_PORT_DOES_NOT_SUPPORT_MAJORITY_FREQ()
.set_FREQ_TARGET(i_target)
@@ -526,7 +530,7 @@ class freq_scoreboard
/// @return FAPI2_RC_SUCCESS iff ok
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
-fapi2::ReturnCode limit_freq_by_processor(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
+fapi2::ReturnCode limit_freq_by_processor(const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target,
freq_scoreboard& io_scoreboard);
///
@@ -541,7 +545,7 @@ fapi2::ReturnCode limit_freq_by_processor(const fapi2::Target<TT::FREQ_TARGET_TY
/// have a path for testing
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
-inline fapi2::ReturnCode limit_freq_by_mrw(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
+inline fapi2::ReturnCode limit_freq_by_mrw(const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target,
const std::vector<uint32_t>& i_max_mrw_freqs,
freq_scoreboard& io_scoreboard)
{
@@ -563,18 +567,18 @@ inline fapi2::ReturnCode limit_freq_by_mrw(const fapi2::Target<TT::FREQ_TARGET_T
fapi2::MSS_MAX_FREQ_ATTR_SIZE_CHANGED()
.set_ACTUAL_SIZE(i_max_mrw_freqs.size())
.set_SUPPOSED_SIZE(NUM_MAX_FREQS)
- .set_MCA_TARGET(i_target),
+ .set_PORT_TARGET(i_target),
"%s Incorrect number of max frequencies in attribute for (%d)",
mss::c_str(i_target),
i_max_mrw_freqs.size());
- FAPI_INF("attribute supported max allowed dimm freqs %d %d %d %d %d for %s",
+ FAPI_DBG("attribute supported max allowed dimm freqs %d %d %d %d %d for %s",
i_max_mrw_freqs[0], i_max_mrw_freqs[1], i_max_mrw_freqs[2], i_max_mrw_freqs[3], i_max_mrw_freqs[4],
mss::c_str(i_target));
for( const auto& p : mss::find_targets<TT::PORT_TARGET_TYPE>(i_target) )
{
- const auto l_port_pos = mss::relative_pos<TT::FREQ_TARGET_TYPE>(p);
+ const auto l_port_pos = mss::relative_pos<TT::FREQ_DOMAIN_TARGET_TYPE>(p);
const auto l_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(p);
const uint64_t l_dimms_on_port = l_dimms.size();
@@ -612,7 +616,7 @@ inline fapi2::ReturnCode limit_freq_by_mrw(const fapi2::Target<TT::FREQ_TARGET_T
// If we have an LRDIMM, it's treated as a one rank DIMM from the memory controller's perspective
l_rank_index = l_dimm_type == TT::LRDIMM_TYPE ? 0 : l_num_master_ranks - 1;
l_index = l_indexes[l_dimms_on_port - 1][l_rank_index];
- FAPI_INF("%s is %s. rank_index%u index:%u", spd::c_str(d), l_dimm_type == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM",
+ FAPI_DBG("%s is %s. rank_index%u index:%u", spd::c_str(d), l_dimm_type == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM",
l_rank_index, l_index);
FAPI_ASSERT( (l_index < NUM_MAX_FREQS),
@@ -625,7 +629,7 @@ inline fapi2::ReturnCode limit_freq_by_mrw(const fapi2::Target<TT::FREQ_TARGET_T
l_num_master_ranks,
mss::c_str(d));
- FAPI_INF("%s rank config %d drop %d yields max freq attribute index of %d (%d)",
+ FAPI_DBG("%s rank config %d drop %d yields max freq attribute index of %d (%d)",
mss::c_str(d), l_num_master_ranks, l_dimms_on_port,
l_indexes[l_dimms_on_port - 1][l_rank_index],
i_max_mrw_freqs[l_index] );
@@ -655,7 +659,7 @@ fapi_try_exit:
/// have a path for testing
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
-fapi2::ReturnCode limit_freq_by_vpd(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
+fapi2::ReturnCode limit_freq_by_vpd(const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target,
const std::vector<std::vector<uint32_t>>& i_hw_freqs,
freq_scoreboard& io_scoreboard)
{
@@ -669,7 +673,7 @@ fapi2::ReturnCode limit_freq_by_vpd(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i
for( const auto& p : mss::find_targets<TT::PORT_TARGET_TYPE>(i_target) )
{
- const auto l_port_pos = mss::relative_pos<TT::FREQ_TARGET_TYPE>(p);
+ const auto l_port_pos = mss::relative_pos<TT::FREQ_DOMAIN_TARGET_TYPE>(p);
const auto& l_port_freqs = i_hw_freqs[l_port_pos];
// This is the list of supported frequencies for VPD
@@ -709,13 +713,13 @@ fapi_try_exit:
/// have a path for testing
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
-fapi2::ReturnCode limit_freq_by_spd(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
+fapi2::ReturnCode limit_freq_by_spd(const fapi2::Target<TT::FREQ_DOMAIN_TARGET_TYPE>& i_target,
const std::vector<uint32_t>& i_hw_freqs,
freq_scoreboard& io_scoreboard)
{
for( const auto& p : mss::find_targets<TT::PORT_TARGET_TYPE>(i_target) )
{
- const auto l_port_pos = mss::relative_pos<TT::FREQ_TARGET_TYPE>(p);
+ const auto l_port_pos = mss::relative_pos<TT::FREQ_DOMAIN_TARGET_TYPE>(p);
// Remove any frequencies that aren't in this port's list from the scoreboard
io_scoreboard.remove_freqs_above_limit(l_port_pos, i_hw_freqs);
diff --git a/src/import/generic/memory/lib/utils/index.H b/src/import/generic/memory/lib/utils/index.H
index fde43f711..59b67c187 100644
--- a/src/import/generic/memory/lib/utils/index.H
+++ b/src/import/generic/memory/lib/utils/index.H
@@ -74,7 +74,24 @@ fapi_try_exit:
}
///
-/// @brief Return an attribute array index from a rank number
+/// @brief Sort the provided target vector in order of index (low to high)
+///
+/// @tparam T TargetType
+/// @param[in,out] io_targets vector of targets to sort
+///
+template <fapi2::TargetType T>
+inline void sort_targets_by_index(std::vector<fapi2::Target<T>>& io_targets)
+{
+ std::sort(io_targets.begin(), io_targets.end(), [] (
+ const fapi2::Target<T>& l_first_target,
+ const fapi2::Target<T>& l_second_target) -> bool
+ {
+ return mss::index(l_first_target) < mss::index(l_first_target);
+ });
+}
+
+///
+/// @brief Return a dimm rank / attribute array index from a port rank number
/// @param[in] i_rank uint64_t a rank number DIMM0 {0, 1, 2, 3} DIMM1 {0, 1, 2, 3}
/// @return size_t the attribute array index.
///
diff --git a/src/import/generic/memory/lib/utils/mc/gen_mss_port.H b/src/import/generic/memory/lib/utils/mc/gen_mss_port.H
index e44601ac2..6c4b4d4b1 100644
--- a/src/import/generic/memory/lib/utils/mc/gen_mss_port.H
+++ b/src/import/generic/memory/lib/utils/mc/gen_mss_port.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,26 +38,138 @@
#define _GEN_MSS_PORT_H_
#include <fapi2.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <generic/memory/lib/utils/mc/gen_mss_port_traits.H>
#include <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/ecc/ecc.H>
+#include <generic/memory/lib/utils/mss_bad_bits.H>
+#include <generic/memory/lib/utils/mss_rank.H>
namespace mss
{
///
+/// @brief Reads the farb0q register
+/// @tparam MC the memory controller type
+/// @tparam T the fapi2 target type of the target
+/// @tparam TT the class traits for the port
+/// @param[in] i_target the target
+/// @param[out] o_data data read from the register
+/// @return FAPI2_RC_SUCCESS if and only if ok
+/// @note Disable Port Fail after recurring RCD errors.
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = portTraits<MC> >
+fapi2::ReturnCode read_farb0q( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ FAPI_TRY( mss::getScom(i_target, TT::FARB0Q_REG, o_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Writes the farb0q register
+/// @tparam MC the memory controller type
+/// @tparam T the fapi2 target type of the target
+/// @tparam TT the class traits for the port
+/// @param[in] i_target the target
+/// @param[in] i_data data read from the register
+/// @return FAPI2_RC_SUCCESS if and only if ok
+/// @note Disable Port Fail after recurring RCD errors.
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = portTraits<MC> >
+fapi2::ReturnCode write_farb0q( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ FAPI_TRY( mss::putScom(i_target, TT::FARB0Q_REG, i_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Reads the farb6q register
+/// @tparam MC the memory controller type
+/// @tparam T the fapi2 target type of the target
+/// @tparam TT the class traits for the port
+/// @param[in] i_target the target
+/// @param[out] o_data data read from the register
+/// @return FAPI2_RC_SUCCESS if and only if ok
+/// @note Disable Port Fail after recurring RCD errors.
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = portTraits<MC> >
+fapi2::ReturnCode read_farb6q( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ FAPI_TRY( mss::getScom(i_target, TT::FARB6Q_REG, o_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Writes the farb6q register
+/// @tparam MC the memory controller type
+/// @tparam T the fapi2 target type of the target
+/// @tparam TT the class traits for the port
+/// @param[in] i_target the target
+/// @param[in] i_data data read from the register
+/// @return FAPI2_RC_SUCCESS if and only if ok
+/// @note Disable Port Fail after recurring RCD errors.
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = portTraits<MC> >
+fapi2::ReturnCode write_farb6q( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ FAPI_TRY( mss::putScom(i_target, TT::FARB6Q_REG, i_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Gets the bandwidth window data
+/// @tparam MC the memory controller type
+/// @tparam TT the class traits for the port
+/// @param[in] i_data data read from the register
+/// @param[out] o_bw_window
+/// @return FAPI2_RC_SUCCESS if and only if ok
+/// @note Disable Port Fail after recurring RCD errors.
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = portTraits<MC> >
+void get_bw_window( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_bw_window )
+{
+ o_bw_window = 0;
+ i_data.extractToRight<TT::BW_WINDOW_SIZE, TT::BW_WINDOW_SIZE_LEN>(o_bw_window);
+}
+
+///
+/// @brief Gets the bandwidth snapshot
+/// @tparam MC the memory controller type
+/// @tparam TT the class traits for the port
+/// @param[in] i_data data read from the register
+/// @param[out] o_bw_snapshot
+/// @return FAPI2_RC_SUCCESS if and only if ok
+/// @note Disable Port Fail after recurring RCD errors.
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = portTraits<MC> >
+void get_bw_snapshot( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_bw_snapshot )
+{
+ o_bw_snapshot = 0;
+ i_data.extractToRight<TT::BW_SNAPSHOT, TT::BW_SNAPSHOT_LEN>(o_bw_snapshot);
+}
+
+
+///
/// @brief ATTR_MSS_MVPD_FWMS getter declare
/// @tparam MC the memory controller type
/// @tparam T the fapi2 target type of the target
/// @param[in] const ref to the fapi2::Target<fapi2::TargetType>
/// @param[out] uint32_t* memory to store the value
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Mark store records from MPVD Lx
-/// keyword
+/// @note Mark store records from MPVD Lx keyword
///
template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T>
-inline fapi2::ReturnCode mvpd_fwms(const fapi2::Target< T>& i_target, uint32_t (&o_array)[MARK_STORE_COUNT]);
+fapi2::ReturnCode mvpd_fwms(const fapi2::Target< T>& i_target, uint32_t (&o_array)[MARK_STORE_COUNT]);
///
/// @brief Enable power management
@@ -111,9 +223,9 @@ fapi2::ReturnCode change_iml_complete( const fapi2::Target<T>& i_target, states
FAPI_DBG("Change the IML init complete bit to high for %s %s", (i_state == HIGH ? "high" : "low"),
mss::c_str(i_target));
- FAPI_TRY( mss::getScom(i_target, TT::FARB6Q_REG, l_data) );
+ FAPI_TRY( mss::getScom(i_target, TT::PMU8Q_REG, l_data) );
l_data.writeBit<TT::CFG_INIT_COMPLETE>(i_state);
- FAPI_TRY( mss::putScom(i_target, TT::FARB6Q_REG, l_data) );
+ FAPI_TRY( mss::putScom(i_target, TT::PMU8Q_REG, l_data) );
fapi_try_exit:
return fapi2::current_err;
@@ -293,6 +405,19 @@ fapi_try_exit:
///
+/// @brief Change the state of the force_str bit
+/// @tparam MC the memory controller type
+/// @tparam T the fapi2 target type of the target
+/// @tparam TT the class traits for the port
+/// @param[in] i_target the target
+/// @param[in] i_state the state
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = portTraits<MC> >
+fapi2::ReturnCode change_force_str( const fapi2::Target<T>& i_target, const states i_state );
+
+
+///
/// @brief Change the state of the MC Refresh enable bit
/// @tparam MC the memory controller type
/// @tparam T the fapi2 target type of the target
@@ -339,6 +464,19 @@ fapi_try_exit:
}
///
+/// @brief Set up memory controller specific settings for ECC registers (at the end of draminit_mc)
+/// @tparam MC the memory controller type
+/// @tparam T the fapi2 target type of the target
+/// @tparam TT the class traits for the port
+/// @param[in] i_target the target
+/// @param[in,out] io_data contents of RECR register
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template< mss::mc_type MC, fapi2::TargetType T, typename TT = portTraits<MC> >
+fapi2::ReturnCode ecc_reg_settings_draminit_mc( const fapi2::Target<T>& i_target,
+ fapi2::buffer<uint64_t>& io_data );
+
+///
/// @brief Enable Read ECC checking
/// @tparam MC the memory controller type
/// @tparam T the fapi2 target type of the target
@@ -346,9 +484,11 @@ fapi_try_exit:
/// @param[in] i_target the target
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = portTraits<MC> >
+template< mss::mc_type MC, fapi2::TargetType T, typename TT = portTraits<MC> >
fapi2::ReturnCode enable_read_ecc( const fapi2::Target<T>& i_target )
{
+ constexpr uint8_t RECR_MBSECCQ_DATA_INVERSION_NO_INVERSION = 0b00;
+ constexpr uint8_t RECR_MBSECCQ_DATA_INVERSION_INVERT_DATA_TOGGLE_CHECKS = 0b11;
fapi2::buffer<uint64_t> l_data;
uint8_t l_sim = 0;
@@ -362,13 +502,17 @@ fapi2::ReturnCode enable_read_ecc( const fapi2::Target<T>& i_target )
// VBU tests assume good ECC and we don't have good ECC (since we're not writing everything)
// so we can't run with address checking. Disable address checking in sim.
- l_data.writeBit<TT::ECC_USE_ADDR_HASH>(l_sim ? 0 : 1);
+ l_data.writeBit<TT::ECC_USE_ADDR_HASH>(l_sim ? mss::states::LOW : mss::states::HIGH);
- // The preferred operating mode is 11 (INVERT_DATA_TOGGLE_CHECKS) which stores data complemented
- // (because most bits are '0', and the dram bus pulls up, so transmitting 1s is least power) but
+ // The preferred operating mode is 11 (INVERT_DATA_TOGGLE_CHECKS) which stores data complemented
+ // (because most bits are '0', and the dram bus pulls up, so transmitting 1s is least power) but
// still flips the inversion of check bits to aid RAS. Per Brad Michael 12/15
// Leave un-inverted for sim. This allows the DIMM loader to write 0's and effect good ECC
- l_data.insertFromRight<TT::RECR_MBSECCQ_DATA_INVERSION, TT::RECR_MBSECCQ_DATA_INVERSION_LEN>(l_sim ? 0b00 : 0b11);
+ l_data.insertFromRight<TT::RECR_MBSECCQ_DATA_INVERSION, TT::RECR_MBSECCQ_DATA_INVERSION_LEN>(l_sim ?
+ RECR_MBSECCQ_DATA_INVERSION_NO_INVERSION :
+ RECR_MBSECCQ_DATA_INVERSION_INVERT_DATA_TOGGLE_CHECKS);
+
+ FAPI_TRY( ecc_reg_settings_draminit_mc<MC>(i_target, l_data) );
// bits: 60 MBSTRQ_CFG_MAINT_RCE_WITH_CE
// cfg_maint_rce_with_ce - not implemented. Need to investigate if needed for nimbus.
@@ -412,6 +556,800 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief Configures the write reorder queue bit
+/// @tparam MC the memory controller type
+/// @tparam T, the mc
+/// @tparam TT, the class traits for the port
+/// @param[in] i_target the target to effect
+/// @param[in] i_state to set the bit too
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = portTraits<MC> >
+inline fapi2::ReturnCode configure_wrq(const fapi2::Target<T>& i_target,
+ const mss::states i_state)
+{
+ // Loops through all port targets, hitting all the registers
+ for( const auto& l_port : mss::find_targets<TT::PORT_TYPE>(i_target) )
+ {
+ fapi2::buffer<uint64_t> l_data;
+
+ // Gets the reg
+ FAPI_TRY(mss::getScom(l_port, TT::WRQ_REG, l_data), "%s failed to getScom from WRQ0Q", mss::c_str(l_port));
+
+ // Sets the bit
+ l_data.writeBit<TT::WRQ_FIFO_MODE>(i_state == mss::states::ON);
+
+ // Sets the regs
+ FAPI_TRY(mss::putScom(l_port, TT::WRQ_REG, l_data), "%s failed to putScom to WRQ0Q", mss::c_str(l_port));
+ }
+
+ // In case we don't have any port's
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Configures the read reorder queue bit
+/// @tparam MC the memory controller type
+/// @tparam T, the mc
+/// @tparam TT, the class traits for the port
+/// @param[in] i_target the target to effect
+/// @param[in] i_state to set the bit too
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = portTraits<MC> >
+inline fapi2::ReturnCode configure_rrq(const fapi2::Target<T>& i_target, const mss::states i_state)
+{
+ // Loops through all port targets, hitting all the registers
+ for( const auto& l_port : mss::find_targets<TT::PORT_TYPE>(i_target) )
+ {
+ fapi2::buffer<uint64_t> l_data;
+
+ // Gets the reg
+ FAPI_TRY(mss::getScom(l_port, TT::RRQ_REG, l_data), "%s failed to getScom from RRQ0Q", mss::c_str(l_port));
+
+ // Sets the bit
+ l_data.writeBit<TT::RRQ_FIFO_MODE>(i_state == mss::states::ON);
+
+ // Sets the regs
+ FAPI_TRY(mss::putScom(l_port, TT::RRQ_REG, l_data), "%s failed to putScom to RRQ0Q", mss::c_str(l_port));
+ }
+
+ // In case we don't have any port's
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Place a symbol mark in a Firmware Mark Store register
+/// @tparam MC the memory controller type
+/// @tparam T the fapi2 target type of the target
+/// @tparam TT the class traits for the port
+/// @param[in] i_target the DIMM target
+/// @param[in] i_rank the rank
+/// @param[in] i_dq the bad DQ bit
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = portTraits<MC> >
+inline fapi2::ReturnCode place_symbol_mark(const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq)
+{
+ const auto& l_port = mss::find_target<TT::PORT_TYPE>(i_target);
+ const auto l_dimm_idx = mss::index(i_target);
+ const auto l_rank_idx = mss::index(i_rank);
+
+ uint8_t l_galois = 0;
+ mss::mcbist::address l_addr;
+
+ // For symbol marks, we set the appropriate Firmware Mark Store reg, with the symbol's
+ // Galois code, mark_type=SYMBOL, mark_region=MRANK, and the address of the DIMM+MRANK
+ // TODO RTC:165133 Remove static_cast once Galois API is updated to accept uint64_t input
+ FAPI_TRY( mss::ecc::dq_to_galois(static_cast<uint8_t>(i_dq), l_galois) );
+
+ l_addr.set_dimm(l_dimm_idx).set_master_rank(l_rank_idx);
+
+ FAPI_INF("%s Setting firmware symbol mark on rank:%d dq:%d galois:0x%02x",
+ mss::c_str(i_target), i_rank, i_dq, l_galois);
+ FAPI_TRY( mss::ecc::set_fwms(l_port, i_rank, l_galois,
+ mss::ecc::fwms::mark_type::SYMBOL,
+ mss::ecc::fwms::mark_region::MRANK,
+ l_addr) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Place a chip mark in a Hardware Mark Store register
+/// @tparam MC the memory controller type
+/// @tparam T the fapi2 target type of the target
+/// @tparam TT the class traits for the port
+/// @param[in] i_target the DIMM target
+/// @param[in] i_rank the rank
+/// @param[in] i_dq one of the bad DQ bits in the bad nibble
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = portTraits<MC> >
+inline fapi2::ReturnCode place_chip_mark(const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq)
+{
+ const auto& l_port = mss::find_target<TT::PORT_TYPE>(i_target);
+
+ uint8_t l_galois = 0;
+ uint8_t l_symbol = 0;
+
+ // For chip marks, we set the appropriate Hardware Mark Store reg, with the Galois code
+ // of the first (smallest) symbol in the bad nibble, and both confirmed and exit1 bits set
+ FAPI_TRY( mss::ecc::dq_to_symbol(static_cast<uint8_t>(i_dq), l_symbol) );
+
+ // Round down to the nearest "nibble" to get the correct symbol, then get the Galois code for it
+ l_symbol = (l_symbol / BITS_PER_NIBBLE) * BITS_PER_NIBBLE;
+ FAPI_TRY( mss::ecc::symbol_to_galois(l_symbol, l_galois) );
+
+ FAPI_INF("%s Setting hardware (chip) mark on rank:%d galois:0x%02x", mss::c_str(i_target), i_rank, l_galois);
+ FAPI_TRY( mss::ecc::set_hwms(l_port, i_rank, l_galois) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+// Forward declaration for use in repair_state classes
+template< fapi2::TargetType T >
+class repair_state_machine;
+
+///
+/// @class mss::repair_state
+/// @brief A class for keeping track of bad bit repair states in a repair_state_machine
+/// @tparam T, the fapi2 target type of the DIMM
+/// @note this is a base class
+///
+template< fapi2::TargetType T >
+class repair_state
+{
+ public:
+ /// @brief default contructor
+ repair_state() = default;
+ /// @brief default destructor
+ virtual ~repair_state() = default;
+
+ ///
+ /// @brief Perform a repair for a single bad DQ bit in a nibble
+ /// @param[in,out] io_machine the repair state machine
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_rank the rank
+ /// @param[in] i_dq the DQ bit index
+ /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+ /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+ /// @return FAPI2_RC_SUCCESS if and only if ok
+ ///
+ virtual fapi2::ReturnCode one_bad_dq(repair_state_machine<T>& io_machine,
+ const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded) = 0;
+
+ ///
+ /// @brief Perform a repair for multiple bad DQ bits in a nibble
+ /// @param[in,out] io_machine the repair state machine
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_rank the rank
+ /// @param[in] i_dq one of the bad DQ bit indexes
+ /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+ /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+ /// @return FAPI2_RC_SUCCESS if and only if ok
+ ///
+ virtual fapi2::ReturnCode multiple_bad_dq(repair_state_machine<T>& io_machine,
+ const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded) = 0;
+
+ protected:
+ ///
+ /// @brief Set a new state in the repair state machine
+ /// @param[in,out] io_machine the repair state machine
+ /// @param[in] i_state pointer to the new state to set
+ ///
+ inline void set_state(repair_state_machine<T>& io_machine, std::shared_ptr<repair_state<T>> i_state)
+ {
+ io_machine.update_state(i_state);
+ }
+};
+
+///
+/// @class mss::chip_and_symbol_mark
+/// @brief repair_state class for when both a chip mark and a symbol mark have been used
+/// @tparam T, the fapi2 target type of the DIMM
+///
+template< fapi2::TargetType T >
+class chip_and_symbol_mark : public repair_state<T>
+{
+ public:
+ /// @brief default contructor
+ chip_and_symbol_mark() = default;
+ /// @brief default destructor
+ ~chip_and_symbol_mark() = default;
+
+ ///
+ /// @brief Perform a repair for a single bad DQ bit in a nibble
+ /// @param[in,out] io_machine the repair state machine
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_rank the rank
+ /// @param[in] i_dq the DQ bit index
+ /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+ /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+ /// @return FAPI2_RC_SUCCESS if and only if ok
+ ///
+ fapi2::ReturnCode one_bad_dq(repair_state_machine<T>& io_machine,
+ const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded)
+ {
+ // repairs exceeded
+ FAPI_TRY( io_repairs_exceeded.setBit(mss::index(i_target)) );
+ FAPI_INF("%s Repairs exceeded (chip mark and symbol mark exist, plus one bad DQ) on rank:%d DQ:%d",
+ mss::c_str(i_target), i_rank, i_dq);
+ return fapi2::FAPI2_RC_SUCCESS;
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Perform a repair for multiple bad DQ bits in a nibble
+ /// @param[in,out] io_machine the repair state machine
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_rank the rank
+ /// @param[in] i_dq one of the bad DQ bit indexes
+ /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+ /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+ /// @return FAPI2_RC_SUCCESS if and only if ok
+ ///
+ fapi2::ReturnCode multiple_bad_dq(repair_state_machine<T>& io_machine,
+ const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded)
+ {
+ // repairs exceeded
+ FAPI_TRY( io_repairs_exceeded.setBit(mss::index(i_target)) );
+ FAPI_INF("%s Repairs exceeded (chip mark and symbol mark exist, plus one bad nibble) on rank:%d DQ:%d",
+ mss::c_str(i_target), i_rank, i_dq);
+ return fapi2::FAPI2_RC_SUCCESS;
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @class mss::symbol_mark_plus_unrepaired_dq
+/// @brief repair_state class for when only a symbol mark has been used, and one DQ bit remains unrepaired
+/// @tparam T, the fapi2 target type of the DIMM
+///
+template< fapi2::TargetType T >
+class symbol_mark_plus_unrepaired_dq : public repair_state<T>
+{
+ public:
+ /// @brief default contructor
+ symbol_mark_plus_unrepaired_dq() = default;
+ /// @brief default destructor
+ ~symbol_mark_plus_unrepaired_dq() = default;
+
+ ///
+ /// @brief Perform a repair for a single bad DQ bit in a nibble
+ /// @param[in,out] io_machine the repair state machine
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_rank the rank
+ /// @param[in] i_dq the DQ bit index
+ /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+ /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+ /// @return FAPI2_RC_SUCCESS if and only if ok
+ ///
+ fapi2::ReturnCode one_bad_dq(repair_state_machine<T>& io_machine,
+ const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded)
+ {
+ // repairs exceeded
+ FAPI_INF("%s Repairs exceeded (symbol mark and unrepaired DQ exist, plus bad DQ) on rank:%d DQ:%d",
+ mss::c_str(i_target), i_rank, i_dq);
+ FAPI_TRY( io_repairs_exceeded.setBit(mss::index(i_target)) );
+ return fapi2::FAPI2_RC_SUCCESS;
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Perform a repair for multiple bad DQ bits in a nibble
+ /// @param[in,out] io_machine the repair state machine
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_rank the rank
+ /// @param[in] i_dq one of the bad DQ bit indexes
+ /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+ /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+ /// @return FAPI2_RC_SUCCESS if and only if ok
+ ///
+ fapi2::ReturnCode multiple_bad_dq(repair_state_machine<T>& io_machine,
+ const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded)
+ {
+ // place a chip mark, but also repairs exceeded
+ FAPI_TRY( place_chip_mark(i_target, i_rank, i_dq) );
+ FAPI_TRY( io_repairs_applied.setBit(i_rank) );
+ FAPI_TRY( io_repairs_exceeded.setBit(mss::index(i_target)) );
+ FAPI_INF("%s Repairs exceeded (symbol mark and unrepaired DQ exist, plus bad nibble) on rank:%d DQ:%d",
+ mss::c_str(i_target), i_rank, i_dq);
+ {
+ const auto new_state = std::make_shared<chip_and_symbol_mark<fapi2::TARGET_TYPE_DIMM>>();
+ mss::repair_state<T>::set_state(io_machine, new_state);
+ }
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+};
+
+///
+/// @class mss::symbol_mark_only
+/// @brief repair_state class for when only a symbol mark has been used
+/// @tparam T, the fapi2 target type of the DIMM
+///
+template< fapi2::TargetType T >
+class symbol_mark_only : public repair_state<T>
+{
+ public:
+ /// @brief default contructor
+ symbol_mark_only() = default;
+ /// @brief default destructor
+ ~symbol_mark_only() = default;
+
+ ///
+ /// @brief Perform a repair for a single bad DQ bit in a nibble
+ /// @param[in,out] io_machine the repair state machine
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_rank the rank
+ /// @param[in] i_dq the DQ bit index
+ /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+ /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+ /// @return FAPI2_RC_SUCCESS if and only if ok
+ ///
+ fapi2::ReturnCode one_bad_dq(repair_state_machine<T>& io_machine,
+ const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded)
+ {
+ // leave an unrepaired DQ
+ const auto new_state = std::make_shared< symbol_mark_plus_unrepaired_dq<T> >();
+ mss::repair_state<T>::set_state(io_machine, new_state);
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Perform a repair for multiple bad DQ bits in a nibble
+ /// @param[in,out] io_machine the repair state machine
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_rank the rank
+ /// @param[in] i_dq one of the bad DQ bit indexes
+ /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+ /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+ /// @return FAPI2_RC_SUCCESS if and only if ok
+ ///
+ fapi2::ReturnCode multiple_bad_dq(repair_state_machine<T>& io_machine,
+ const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded)
+ {
+ // place a chip mark
+ FAPI_TRY( place_chip_mark(i_target, i_rank, i_dq) );
+ FAPI_TRY( io_repairs_applied.setBit(i_rank) );
+ {
+ const auto new_state = std::make_shared< chip_and_symbol_mark<T> >();
+ mss::repair_state<T>::set_state(io_machine, new_state);
+ }
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @class mss::chip_mark_only
+/// @brief repair_state class for when only a chip mark has been used
+/// @tparam T, the fapi2 target type of the DIMM
+///
+template< fapi2::TargetType T >
+class chip_mark_only : public repair_state<T>
+{
+ public:
+ /// @brief default contructor
+ chip_mark_only() = default;
+ /// @brief default destructor
+ ~chip_mark_only() = default;
+
+ ///
+ /// @brief Perform a repair for a single bad DQ bit in a nibble
+ /// @param[in,out] io_machine the repair state machine
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_rank the rank
+ /// @param[in] i_dq the DQ bit index
+ /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+ /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+ /// @return FAPI2_RC_SUCCESS if and only if ok
+ ///
+ fapi2::ReturnCode one_bad_dq(repair_state_machine<T>& io_machine,
+ const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded)
+ {
+ // place a symbol mark
+ FAPI_TRY( place_symbol_mark(i_target, i_rank, i_dq) );
+ FAPI_TRY( io_repairs_applied.setBit(i_rank) );
+ {
+ const auto new_state = std::make_shared<chip_and_symbol_mark<fapi2::TARGET_TYPE_DIMM>>();
+ mss::repair_state<T>::set_state(io_machine, new_state);
+ }
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Perform a repair for multiple bad DQ bits in a nibble
+ /// @param[in,out] io_machine the repair state machine
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_rank the rank
+ /// @param[in] i_dq one of the bad DQ bit indexes
+ /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+ /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+ /// @return FAPI2_RC_SUCCESS if and only if ok
+ ///
+ fapi2::ReturnCode multiple_bad_dq(repair_state_machine<T>& io_machine,
+ const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded)
+ {
+ // repairs exceeded
+ FAPI_TRY( io_repairs_exceeded.setBit(mss::index(i_target)) );
+ FAPI_INF("%s Repairs exceeded (chip mark exists, plus bad nibble) on rank:%d DQ:%d",
+ mss::c_str(i_target), i_rank, i_dq);
+ return fapi2::FAPI2_RC_SUCCESS;
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @class mss::no_fails
+/// @brief repair_state class for no fails (no marks applied)
+/// @tparam T, the fapi2 target type of the DIMM
+///
+template< fapi2::TargetType T >
+class no_fails : public repair_state<T>
+{
+ public:
+ /// @brief default contructor
+ no_fails() = default;
+ /// @brief default destructor
+ ~no_fails() = default;
+
+ ///
+ /// @brief Perform a repair for a single bad DQ bit in a nibble
+ /// @param[in,out] io_machine the repair state machine
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_rank the rank
+ /// @param[in] i_dq the DQ bit index
+ /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+ /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+ /// @return FAPI2_RC_SUCCESS if and only if ok
+ ///
+ fapi2::ReturnCode one_bad_dq(repair_state_machine<T>& io_machine,
+ const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded)
+ {
+ // place a symbol mark
+ FAPI_TRY( place_symbol_mark(i_target, i_rank, i_dq) );
+ FAPI_TRY( io_repairs_applied.setBit(i_rank) );
+ {
+ const auto new_state = std::make_shared<symbol_mark_only<fapi2::TARGET_TYPE_DIMM>>();
+ mss::repair_state<T>::set_state(io_machine, new_state);
+ }
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Perform a repair for multiple bad DQ bits in a nibble
+ /// @param[in,out] io_machine the repair state machine
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_rank the rank
+ /// @param[in] i_dq one of the bad DQ bit indexes
+ /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+ /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+ /// @return FAPI2_RC_SUCCESS if and only if ok
+ ///
+ fapi2::ReturnCode multiple_bad_dq(repair_state_machine<T>& io_machine,
+ const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded)
+ {
+ // place a chip mark
+ FAPI_TRY( place_chip_mark(i_target, i_rank, i_dq) );
+ FAPI_TRY( io_repairs_applied.setBit(i_rank) );
+ {
+ const auto new_state = std::make_shared<chip_mark_only<fapi2::TARGET_TYPE_DIMM>>();
+ mss::repair_state<T>::set_state(io_machine, new_state);
+ }
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @class mss::repair_state_machine
+/// @brief state machine class used in restore_repairs_helper
+/// @tparam T, the fapi2 target type of the DIMM
+///
+template< fapi2::TargetType T >
+class repair_state_machine
+{
+ public:
+ /// @brief constructor
+ repair_state_machine()
+ : iv_repair_state(std::make_shared<no_fails<T>>()) {}
+
+ /// @brief default destructor
+ ~repair_state_machine() = default;
+
+ ///
+ /// @brief Perform a repair for a single bad DQ bit in a nibble
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_rank the rank
+ /// @param[in] i_dq the DQ bit index
+ /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+ /// @param[in,out] io_repai:rs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+ /// @return FAPI2_RC_SUCCESS if and only if ok
+ ///
+ fapi2::ReturnCode one_bad_dq(const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded)
+ {
+ FAPI_TRY( iv_repair_state->one_bad_dq(*this, i_target, i_rank, i_dq, io_repairs_applied, io_repairs_exceeded) );
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Perform a repair for multiple bad DQ bits in a nibble
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_rank the rank
+ /// @param[in] i_dq one of the bad DQ bit indexes
+ /// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+ /// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+ /// @return FAPI2_RC_SUCCESS if and only if ok
+ ///
+ fapi2::ReturnCode multiple_bad_dq(const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ const uint64_t i_dq,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded)
+ {
+ FAPI_TRY( iv_repair_state->multiple_bad_dq(*this, i_target, i_rank, i_dq, io_repairs_applied, io_repairs_exceeded) );
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Update the state of the state machine
+ /// @param[in] i_state shared pointer to the new state
+ ///
+ void update_state(std::shared_ptr<repair_state<T>> i_state)
+ {
+ iv_repair_state = i_state;
+ }
+
+ private:
+ std::shared_ptr<repair_state<T>> iv_repair_state;
+};
+
+/// @brief Get the attributes for the reorder queue setting
+/// @tparam MC the memory controller type
+/// @tparam T, the fapi2 target type of the target
+/// @param[in] const ref to the mc target
+/// @param[out] uint8_t& reference to store the value
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Contains the settings for write/read reorder queue
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
+fapi2::ReturnCode reorder_queue_setting(const fapi2::Target<T>& i_target, uint8_t& o_value);
+
+///
+/// @brief Resets the write/read reorder queue values - needs to be called after MCBIST execution
+/// @tparam MC the memory controller type
+/// @tparam T, the mc
+/// @tparam TT, the class traits for the port
+/// @param[in] i_target the target to effect
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = portTraits<MC> >
+inline fapi2::ReturnCode reset_reorder_queue_settings(const fapi2::Target<T>& i_target)
+{
+ uint8_t l_reorder_queue = 0;
+ FAPI_TRY(reorder_queue_setting<MC>(i_target, l_reorder_queue));
+
+ // Changes the reorder queue settings
+ {
+ // Two settings are FIFO and REORDER. FIFO is a 1 in the registers, while reorder is a 0 state
+ const mss::states l_state = ((l_reorder_queue == fapi2::ENUM_ATTR_MEM_REORDER_QUEUE_SETTING_FIFO) ?
+ mss::states::ON : mss::states::OFF);
+ FAPI_TRY(configure_rrq(i_target, l_state), "%s failed to reset read reorder queue settings", mss::c_str(i_target));
+ FAPI_TRY(configure_wrq(i_target, l_state), "%s failed to reset read reorder queue settings", mss::c_str(i_target));
+ }
+
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Convert a bitmap from the BAD_DQ_BITMAP attribute to a vector of bad DQ indexes
+/// @param[in] i_bad_bits an 8-bit bitmap of bad bits
+/// @param[in] i_nibble which nibble of the bitmap to convert
+/// @return std::vector of DQ bits marked as bad in the bitmap
+///
+inline std::vector<uint64_t> bad_bit_helper(const uint8_t i_bad_bits, const size_t i_nibble)
+{
+ std::vector<uint64_t> l_output;
+ fapi2::buffer<uint8_t> l_bit_buffer(i_bad_bits);
+
+ const size_t l_start = (i_nibble == 0) ? 0 : mss::conversions::BITS_PER_NIBBLE;
+
+ for (size_t l_offset = 0; l_offset < mss::conversions::BITS_PER_NIBBLE; ++l_offset)
+ {
+ const size_t l_position_tmp = l_start + l_offset;
+
+ if (l_bit_buffer.getBit(l_position_tmp))
+ {
+ l_output.push_back(l_position_tmp);
+ }
+ }
+
+ return l_output;
+}
+
+// TODO: RTC: 157753 tparam R can be pulled from an PORT trait once we have it
+//
+/// @brief Restore symbol and chip marks according to BAD_DQ_BITMAP attribute, helper function for unit testing
+/// @tparam MC the memory controller type
+/// @tparam T, the fapi2 target type of the DIMM (derived)
+/// @tparam R the maximum rank per DIMM
+/// @tparam B the number of bytes per rank in the bad_dq_bitmap attribute
+/// @param[in] i_target A target representing a DIMM
+/// @param[in] i_bad_bits the bad bits values from the VPD, for the specified DIMM
+/// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied
+/// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, uint64_t R, uint64_t B >
+inline fapi2::ReturnCode restore_repairs_helper( const fapi2::Target<T>& i_target,
+ const uint8_t i_bad_bits[R][B],
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded)
+{
+ FAPI_INF("%s Restore repair marks from bad DQ data", mss::c_str(i_target));
+
+ using MCT = mss::mcbistMCTraits<MC>;
+ using MT = mss::mcbistTraits<MC, MCT::MC_TARGET_TYPE>;
+
+ std::vector<uint64_t> l_ranks;
+ const auto l_dimm_idx = index(i_target);
+
+ // gets all of the ranks to loop over
+ FAPI_TRY( mss::rank::ranks_on_dimm_helper<MC>(i_target, l_ranks) );
+
+ // loop through ranks
+ for (const auto l_rank : l_ranks)
+ {
+ const auto l_rank_idx = index(l_rank);
+
+ repair_state_machine<fapi2::TARGET_TYPE_DIMM> l_machine;
+
+ for (uint64_t l_byte = 0; l_byte < (MT::MAX_DQ_NIBBLES / mss::conversions::NIBBLES_PER_BYTE); ++l_byte)
+ {
+ for (size_t l_nibble = 0; l_nibble < mss::conversions::NIBBLES_PER_BYTE; ++l_nibble)
+ {
+ const auto l_bad_dq_vector = bad_bit_helper(i_bad_bits[l_rank_idx][l_byte], l_nibble);
+ FAPI_DBG("Total bad bits on DIMM:%d rank:%d nibble%d: %d",
+ l_dimm_idx, l_rank, (l_byte * NIBBLES_PER_BYTE) + l_nibble, l_bad_dq_vector.size());
+
+ // apply repairs and update repair machine state
+ // if there are no bad bits (l_bad_dq_vector.size() == 0) no action is necessary
+ if (l_bad_dq_vector.size() == 1)
+ {
+ // l_bad_dq_vector is per byte, so multiply up to get the bad dq's index
+ const uint64_t l_dq = l_bad_dq_vector[0] + (l_byte * BITS_PER_BYTE);
+ FAPI_TRY( l_machine.one_bad_dq(i_target, l_rank, l_dq, io_repairs_applied, io_repairs_exceeded) );
+ }
+ else if (l_bad_dq_vector.size() > 1)
+ {
+ // l_bad_dq_vector is per byte, so multiply up to get the bad dq's index
+ const uint64_t l_dq = l_bad_dq_vector[0] + (l_byte * BITS_PER_BYTE);
+ FAPI_TRY( l_machine.multiple_bad_dq(i_target, l_rank, l_dq, io_repairs_applied, io_repairs_exceeded) );
+ }
+
+ // if repairs have been exceeded, we're done
+ if (io_repairs_exceeded.getBit(l_dimm_idx))
+ {
+ FAPI_INF("Repairs exceeded on DIMM %s", c_str(i_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+ } // end loop through nibbles
+ } // end loop through bytes
+ } // end loop through ranks
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Restore symbol and chip marks according to BAD_DQ_BITMAP attribute
+/// @tparam MC, the memory controller type
+/// @tparam T, the fapi2 target type of the port (derived)
+/// @param[in] i_target A target representing a port
+/// @param[in,out] io_repairs_applied bit mask, where a bit set means a rank had repairs applied (bit0 = rank0, etc)
+/// @param[in,out] io_repairs_exceeded bit mask, where a bit set means a DIMM had more bad bits than could be repaired (bit0 = DIMM0 etc)
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
+inline fapi2::ReturnCode restore_repairs( const fapi2::Target<T>& i_target,
+ fapi2::buffer<uint8_t>& io_repairs_applied,
+ fapi2::buffer<uint8_t>& io_repairs_exceeded)
+{
+ uint8_t l_bad_bits[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT] = {};
+
+ io_repairs_applied = 0;
+ io_repairs_exceeded = 0;
+
+ for (const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target))
+ {
+ FAPI_TRY( mss::get_bad_dq_bitmap<MC>(l_dimm, l_bad_bits) );
+
+ FAPI_TRY( (restore_repairs_helper<MC, fapi2::TARGET_TYPE_DIMM, BAD_BITS_RANKS, BAD_DQ_BYTE_COUNT>(
+ l_dimm, l_bad_bits, io_repairs_applied, io_repairs_exceeded)) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
}// ns mss
#endif
diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_address.H b/src/import/generic/memory/lib/utils/mcbist/gen_address.H
deleted file mode 100644
index 45c4a4767..000000000
--- a/src/import/generic/memory/lib/utils/mcbist/gen_address.H
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/generic/memory/lib/utils/mcbist/gen_address.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist.H
index 0c5543750..667be0598 100644
--- a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist.H
+++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,3830 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gen_mss_mcbist.H
+/// @brief Run and manage the MCBIST engine
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _GEN_MSS_MCBIST_H_
+#define _GEN_MSS_MCBIST_H_
+
+#include <fapi2.H>
+
+#include <generic/memory/lib/utils/poll.H>
+#include <generic/memory/lib/utils/memory_size.H>
+#include <generic/memory/lib/utils/mc/gen_mss_port.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H>
+#include <generic/memory/lib/utils/conversions.H>
+#include <generic/memory/lib/utils/num.H>
+
+namespace mss
+{
+
+///
+/// @brief Gets the attribute for freq
+/// @tparam MC the memory controller type
+/// @tparam T the fapi2 target type of the target
+/// @param[in] const ref to the target
+/// @param[out] uint64_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Frequency of this memory channel in MT/s (Mega Transfers per second)
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T>
+fapi2::ReturnCode freq(const fapi2::Target<T>& i_target, uint64_t& o_value);
+
+///
+/// @brief Return the estimated time an MCBIST subtest will take to complete
+/// Useful for initial polling delays, probably isn't accurate for much else
+/// as it doesn't take refresh in to account (which will necessarily slow down
+/// the program.)
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType
+/// @param[in] i_target the target from which to gather memory frequency
+/// @param[in] i_bytes number of *bytes* in the address range
+/// @param[in] i_64B_per mss::YES if the command is 64B, mss::NO if it's 128B. Defaults to mss::YES
+/// @return the initial polling delay for this program in ns
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
+inline uint64_t calculate_initial_delay(const fapi2::Target<T>& i_target,
+ const uint64_t i_bytes,
+ const bool i_64B_per = mss::YES)
+{
+ // TODO RTC: 164104 Update MCBIST delay calculator. As we learn more about what
+ // the lab really needs, we can probably make this function better.
+ const uint64_t l_bytes_per_cmd = (i_64B_per == mss::YES) ? 64 : 128;
+
+ // Best case is a command takes 4 cycles. Given the number of commands and address space size
+ // we can get some idea of how long to wait before we start polling.
+ return cycles_to_ns(i_target, (i_bytes / l_bytes_per_cmd) * mss::CYCLES_PER_CMD);
+}
+
+
+///
+/// @brief Reads the contents of the MCBISTFIRMASK
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to mcbistTraits<MC, T>
+/// @param[in] i_target the target on which to operate
+/// @param[out] o_data the register data
+/// @return fapi2::fapi2_rc_success if ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode read_mcbfirmask( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ o_data = 0;
+
+ FAPI_TRY( fapi2::getScom(i_target, TT::MCBFIRMASK_REG, o_data ), "%s failed to read MCBISTFIRMASK regiser",
+ mss::c_str(i_target));
+ FAPI_DBG("%s MCBISTFIRMASK has data 0x%016lx", mss::c_str(i_target), o_data);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Writes the contents of the MCBISTFIRMASK
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to mcbistTraits<MC, T>
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_data the register data
+/// @return fapi2::fapi2_rc_success if ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode write_mcbfirmask( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ FAPI_TRY( fapi2::putScom(i_target, TT::MCBFIRMASK_REG, i_data ), "%s failed to write MCBISTFIRMASK regiser",
+ mss::c_str(i_target));
+ FAPI_DBG("%s MCBISTFIRMASK has data 0x%016lx", mss::c_str(i_target), i_data);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Reads the contents of the MCBISTFIRQ
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to mcbistTraits<MC, T>
+/// @param[in] i_target the target on which to operate
+/// @param[out] o_data the register data
+/// @return fapi2::fapi2_rc_success if ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode read_mcbfirq( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ o_data = 0;
+
+ FAPI_TRY( fapi2::getScom(i_target, TT::MCBFIRQ_REG, o_data ), "%s failed to read MCBISTFIRQ regiser",
+ mss::c_str(i_target));
+ FAPI_DBG("%s MCBISTFIRQ has data 0x%016lx", mss::c_str(i_target), o_data);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Writes the contents of the MCBISTFIRQ
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to mcbistTraits<MC, T>
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_data the register data
+/// @return fapi2::fapi2_rc_success if ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode write_mcbfirq( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ FAPI_TRY( fapi2::putScom(i_target, TT::MCBFIRQ_REG, i_data ), "%s failed to write MCBISTFIRQ regiser",
+ mss::c_str(i_target));
+ FAPI_DBG("%s MCBISTFIRQ has data 0x%016lx", mss::c_str(i_target), i_data);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Sets the mask for program complete
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCBIST
+/// @tparam TT traits type defaults to mcbistTraits<MC, T>
+/// @param[in,out] io_data the value of the register
+/// @param[in] i_state the state to write into the enable
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<MC, T> >
+inline void set_mcbist_program_complete_mask( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
+{
+ io_data.writeBit<TT::MCB_PROGRAM_COMPLETE_MASK>(i_state == mss::states::ON);
+ FAPI_DBG("set_mcbist_program_complete_mask to %d 0x%016lx", i_state, io_data);
+}
+
+///
+/// @brief Sets the mask for WAT debug ATTN
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCBIST
+/// @tparam TT traits type defaults to mcbistTraits<MC, T>
+/// @param[in,out] io_data the value of the register
+/// @param[in] i_state the state to write into the enable
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<MC, T> >
+inline void set_mcbist_wat_debug_attn_mask( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
+{
+ io_data.writeBit<TT::MCB_WAT_DEBUG_ATTN_MASK>(i_state == mss::states::ON);
+ FAPI_DBG("set_mcbist_wat_debug_attn_mask to %d 0x%016lx", i_state, io_data);
+}
+
+///
+/// @brief Clears the program complete and WAT debug ATTN
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCBIST
+/// @tparam TT traits type defaults to mcbistTraits<MC, T>
+/// @param[in,out] io_data the value of the register
+/// @param[in] i_state the state to write into the enable
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<MC, T> >
+inline void clear_mcbist_program_complete( fapi2::buffer<uint64_t>& io_data )
+{
+ io_data.writeBit<TT::MCB_PROGRAM_COMPLETE>(mss::states::OFF);
+ io_data.writeBit<TT::MCB_WAT_DEBUG_ATTN>(mss::states::OFF);
+ FAPI_DBG("clear_mcbist_program_complete to %d 0x%016lx", mss::states::OFF, io_data);
+}
+
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<MC, T> >
+inline void get_mcbist_program_complete_mask( const fapi2::buffer<uint64_t> i_data, mss::states& o_state )
+{
+ o_state = i_data.getBit<TT::MCB_PROGRAM_COMPLETE>() ? mss::states::HIGH : mss::states::LOW;
+ FAPI_DBG("get_mcbist_program_complete_mask %d", o_state);
+}
+
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<MC, T> >
+inline void get_mcbist_wat_debug_attn_mask( const fapi2::buffer<uint64_t> i_data, mss::states& o_state )
+{
+ o_state = i_data.getBit<TT::MCB_WAT_DEBUG_ATTN>() ? mss::states::HIGH : mss::states::LOW;
+ FAPI_DBG("mcbist_wat_debug_attn_mask %d", o_state);
+}
+
+
+namespace mcbist
+{
+
+///
+/// @class subtest_t
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType
+/// @tparam TT the mcbistTraits associated with T
+/// @brief encapsulation of an MCBIST subtest.
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE , typename TT = mcbistTraits<MC, T> >
+class subtest_t
+{
+ public:
+
+ ///
+ /// @brief Constructor
+ ///
+ subtest_t( const uint16_t i_data = 0 ):
+ iv_mcbmr(i_data)
+ {}
+
+ ///
+ /// @brief Checks if the op type requires FIFO mode to be on
+ /// @return bool fifo_mode_requried - true if FIFO mode is required to be forced on
+ ///
+ inline bool fifo_mode_required() const
+ {
+ // Gets the op type for this subtest
+ uint64_t l_value_to_find = 0;
+ iv_mcbmr.extractToRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(l_value_to_find);
+
+ // Finds if this op type is in the vector that stores the OP types that require FIFO mode to be run
+ const auto l_op_type_it = std::find(TT::FIFO_MODE_REQUIRED_OP_TYPES.begin(), TT::FIFO_MODE_REQUIRED_OP_TYPES.end(),
+ l_value_to_find);
+
+ // If the op type is required (aka was found), it will be less than end
+ // std::find returns the ending iterator if it was not found, so this will return false in that case
+ return l_op_type_it != TT::FIFO_MODE_REQUIRED_OP_TYPES.end();
+ }
+
+ ///
+ /// @brief Convert to a 16 bit int
+ /// @return the subtest as a 16 bit integer, useful for testing
+ ///
+ inline operator uint16_t()
+ {
+ return uint16_t(iv_mcbmr);
+ }
+
+ ///
+ /// @brief Complement the data for the first subcommand
+ /// @param[in] i_state the desired state (mss::ON or mss::OFF)
+ ///
+ inline void change_compliment_1st_cmd( const mss::states i_state )
+ {
+ iv_mcbmr.template writeBit<TT::COMPL_1ST_CMD>(i_state);
+ return;
+ }
+
+ ///
+ /// @brief Complement the data for the second subcommand
+ /// @param[in] i_state the desired state (mss::ON or mss::OFF)
+ /// @return void
+ ///
+ inline void change_compliment_2nd_cmd( const mss::states i_state )
+ {
+ iv_mcbmr.template writeBit<TT::COMPL_2ND_CMD>(i_state);
+ return;
+ }
+
+ ///
+ /// @brief Complement the data for the third subcommand
+ /// @param[in] i_state the desired state (mss::ON or mss::OFF)
+ /// @return void
+ ///
+ inline void change_compliment_3rd_cmd( const mss::states i_state )
+ {
+ iv_mcbmr.template writeBit<TT::COMPL_3RD_CMD>(i_state);
+ return;
+ }
+
+ ///
+ /// @brief Enable a specific port for this test - maint address mode
+ /// @param[in] i_port the port desired to be enabled - int 0, 1, 2, 3
+ /// @note The port number is relative to the MCBIST
+ /// @return void
+ ///
+ inline void enable_port( const uint64_t i_port )
+ {
+ if (TT::MULTI_PORTS == mss::states::YES)
+ {
+ constexpr uint64_t l_len = (TT::COMPL_2ND_CMD - TT::COMPL_1ST_CMD) + 1;
+ iv_mcbmr.template insertFromRight<TT::COMPL_1ST_CMD, l_len>(i_port);
+ }
+
+ return;
+ }
+
+ ///
+ /// @brief Enable a specific dimm for this test - maint address mode
+ /// @param[in] i_dimm the dimm desired to be enabled - int 0, 1
+ /// @return void
+ ///
+ inline void enable_dimm( const uint64_t i_dimm )
+ {
+ iv_mcbmr.template writeBit<TT::COMPL_3RD_CMD>(i_dimm);
+ return;
+ }
+
+ ///
+ /// @brief Get the port from this subtest
+ /// @note The port number is relative to the MCBIST
+ /// @return the port of the subtest
+ ///
+ inline uint64_t get_port() const
+ {
+ uint64_t l_port = 0;
+
+ if (TT::MULTI_PORTS == mss::states::YES)
+ {
+ constexpr uint64_t l_len = (TT::COMPL_2ND_CMD - TT::COMPL_1ST_CMD) + 1;
+ iv_mcbmr.template extractToRight<TT::COMPL_1ST_CMD, l_len>(l_port);
+ }
+
+ return l_port;
+ }
+
+ ///
+ /// @brief Get the DIMM from this subtest
+ /// @return the DIMM this subtest has been configured for
+ ///
+ inline uint64_t get_dimm() const
+ {
+
+ return iv_mcbmr.template getBit<TT::COMPL_3RD_CMD>() ? 1 : 0;
+
+ return 0;
+ }
+
+ ///
+ /// @brief Add the subtest to go to
+ /// @param[in] the subtest to jump to
+ /// @return void
+ ///
+ inline void change_goto_subtest( const uint64_t i_jmp_to )
+ {
+ iv_mcbmr.template insertFromRight<TT::GOTO_SUBTEST, TT::GOTO_SUBTEST_LEN>(i_jmp_to);
+ FAPI_INF("changing subtest to jump to %d (0x%02x)", i_jmp_to, iv_mcbmr);
+ return;
+ }
+
+ ///
+ /// @brief Generate addresses in reverse order
+ /// @param[in] i_state the desired state of the function; mss:ON, mss::OFF
+ /// @return void
+ ///
+ inline void change_addr_rev_mode( const mss::states i_state )
+ {
+ iv_mcbmr.template writeBit<TT::ADDR_REV_MODE>(i_state);
+ return;
+ }
+
+ ///
+ /// @brief Generate addresses in random order
+ /// @param[in] i_state the desired state of the function; mss:ON, mss::OFF
+ /// @return void
+ ///
+ inline void change_addr_rand_mode( const mss::states i_state )
+ {
+ iv_mcbmr.template writeBit<TT::ADDR_RAND_MODE>(i_state);
+ return;
+ }
+
+ ///
+ /// @brief Generate and check data with ECC
+ /// @param[in] i_state the desired state of the function; mss:ON, mss::OFF
+ /// @return void
+ ///
+ inline void change_ecc_mode( const mss::states i_state )
+ {
+ iv_mcbmr.template writeBit<TT::ECC_MODE>(i_state);
+ return;
+ }
+
+ ///
+ /// @brief Set the 'done after this test' bit
+ /// @param[in] i_state the desired state of the function; mss:ON, mss::OFF
+ /// @return void
+ ///
+ inline void change_done( const mss::states i_state )
+ {
+ iv_mcbmr.template writeBit<TT::DONE>(i_state);
+ return;
+ }
+
+ ///
+ /// @brief Set the data mode for this subtest
+ /// @param[in] i_mode the desired mcbist::data_mode
+ /// @return void
+ ///
+ inline void change_data_mode( const data_mode i_mode )
+ {
+ iv_mcbmr.template insertFromRight<TT::DATA_MODE, TT::DATA_MODE_LEN>(i_mode);
+ return;
+ }
+
+ ///
+ /// @brief Set the operation type for this subtest
+ /// @param[in] i_mode the desired mcbist::op_type
+ /// @return void
+ ///
+ inline void change_op_type( const op_type i_type )
+ {
+ iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(i_type);
+ return;
+ }
+
+ ///
+ /// @brief Configure which address registers to use for this subtest
+ /// @param[in] i_index 0 = MCBSA0Q, 1 = MCBSA1Q, ...
+ /// @note wraps to 0-3 no matter what value you pass in.
+ /// @return void
+ ///
+ inline void change_addr_sel( const uint16_t i_index )
+ {
+ // Roll the index around - tidy support for an index which is out of range.
+ iv_mcbmr.template insertFromRight<TT::ADDR_SEL, TT::ADDR_SEL_LEN>(i_index % TT::MAX_ADDRESS_START_END_REGISTERS);
+ FAPI_INF("changed address select to index %d (0x%x)", i_index, iv_mcbmr);
+ return;
+ }
+
+ //
+ // @brief operator== for mcbist subtests
+ // @param[in] i_rhs the right hand side of the compare
+ // @return bool, true iff i_rhs == this
+ inline bool operator==(const subtest_t& i_rhs) const
+ {
+ return i_rhs.iv_mcbmr == iv_mcbmr;
+ }
+
+ /// The mcbist 'memory register' for this subtest.
+ // Note that it is only 16 bits.
+ // Each 64b memory register contains multiple 16 bit subtest definitions.
+ // As we create a vector of subtests, we'll drop them in to their appropriate
+ // MCBMR register before executing.
+ fapi2::buffer<uint16_t> iv_mcbmr;
+};
+
+///
+/// @brief Return a write subtest - configured simply
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @return mss::mcbist::subtest_t
+/// @note Turns on ECC mode for the returned subtest - caller can turn it off
+/// @note Configures for start/end address select bit as address config register 0
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE , typename TT = mcbistTraits<MC, T> >
+inline subtest_t<MC, T, TT> write_subtest()
+{
+ // Starts life full of 0's
+ subtest_t<MC, T, TT> l_subtest;
+
+ // 0:3 = 0000 - we want subtest type to be a Write (W)
+ l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::WRITE);
+
+ // - Not a special subtest, so no other configs associated
+ // 4 = 0 - we don't want to complement data for our Writes
+ // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
+ // 7 = 0 - forward address generation
+ // 8 = 0 - non random address generation
+ // - Don't need to set up anything for LFSRs
+ // 9:11 = 000 - Fixed data mode
+
+ // 12 = 1 - ecc
+ // By default we want to turn on ECC. Caller can turn it off.
+ l_subtest.change_ecc_mode(mss::ON);
+
+ // 14:15 = 0 address select config registers 0
+
+ return l_subtest;
+}
+
+
+///
+/// @brief Return an alter subtest - configured simply
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @return mss::mcbist::subtest_t
+/// @note Turns on ECC mode for the returned subtest - caller can turn it off
+/// @note Configures for start/end address select bit as address config register 0
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE, typename TT = mcbistTraits<MC, T> >
+inline subtest_t<MC, T, TT> alter_subtest()
+{
+ // Starts life full of 0's
+ subtest_t<MC, T, TT> l_subtest;
+
+ // 0:3 = 1011 - we want subtest type to be a Alter
+ l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::ALTER);
+
+ // - Not a special subtest, so no other configs associated
+ // 4 = 0 - we don't want to complement data for our Writes
+ // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
+ // 7 = 0 - forward address generation
+ // 8 = 0 - non random address generation
+ // - Don't need to set up anything for LFSRs
+ // 9:11 = 000 - Fixed data mode
+
+ // 14:15 = 0 address select config registers 0
+
+ // By default we want to turn on ECC. Caller can turn it off.
+ l_subtest.change_ecc_mode(mss::ON);
+
+ return l_subtest;
+}
+
+///
+/// @brief Return an display subtest - configured simply
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @return mss::mcbist::subtest_t
+/// @note Turns on ECC mode for the returned subtest - caller can turn it off
+/// @note Configures for start/end address select bit as address config register 0
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE, typename TT = mcbistTraits<MC, T> >
+inline subtest_t<MC, T, TT> display_subtest()
+{
+ // Starts life full of 0's
+ subtest_t<MC, T, TT> l_subtest;
+
+ // 0:3 = 1100 - we want subtest type to be a Display
+ l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::DISPLAY);
+
+ // - Not a special subtest, so no other configs associated
+ // 4 = 0 - we don't want to complement data for our Writes
+ // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
+ // 7 = 0 - forward address generation
+ // 8 = 0 - non random address generation
+ // - Don't need to set up anything for LFSRs
+ // 9:11 = 000 - Fixed data mode
+
+ // 14:15 = 0 address select config registers 0
+
+ // By default we want to turn on ECC. Caller can turn it off.
+ l_subtest.change_ecc_mode(mss::ON);
+
+ return l_subtest;
+}
+
+///
+/// @brief Return an scrub subtest - configured simply
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @return mss::mcbist::subtest_t
+/// @note Turns on ECC mode for the returned subtest - caller can turn it off
+/// @note Configures for start/end address select bit as address config register 0
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE, typename TT = mcbistTraits<MC, T> >
+inline subtest_t<MC, T, TT> scrub_subtest()
+{
+ // Starts life full of 0's
+ subtest_t<MC, T, TT> l_subtest;
+
+ // 0:3 = 1001 - we want subtest type to be a Scrub
+ l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::SCRUB_RRWR);
+
+ // - Not a special subtest, so no other configs associated
+ // 4 = 0 - we don't want to complement data for our Writes
+ // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
+ // 7 = 0 - forward address generation
+ // 8 = 0 - non random address generation
+ // - Don't need to set up anything for LFSRs
+ // 9:11 = 000 - Fixed data mode
+
+ // 14:15 = 0 address select config registers 0
+
+ // By default we want to turn on ECC. Caller can turn it off.
+ l_subtest.change_ecc_mode(mss::ON);
+
+ return l_subtest;
+}
+
+///
+/// @brief Return a steer subtest - configured simply
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @return mss::mcbist::subtest_t
+/// @note Turns on ECC mode for the returned subtest - caller can turn it off
+/// @note Configures for start/end address select bit as address config register 0
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE, typename TT = mcbistTraits<MC, T> >
+inline subtest_t<MC, T, TT> steer_subtest()
+{
+ // Starts life full of 0's
+ subtest_t<MC, T, TT> l_subtest;
+
+ // 0:3 = 1010 - we want subtest type to be a Steer
+ l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::STEER_RW);
+
+ // - Not a special subtest, so no other configs associated
+ // 4 = 0 - we don't want to complement data for our Writes
+ // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
+ // 7 = 0 - forward address generation
+ // 8 = 0 - non random address generation
+ // - Don't need to set up anything for LFSRs
+ // 9:11 = 000 - Fixed data mode
+
+ // 14:15 = 0 address select config registers 0
+
+ // By default we want to turn on ECC. Caller can turn it off.
+ l_subtest.change_ecc_mode(mss::ON);
+
+ return l_subtest;
+}
+
+///
+/// @brief Return a read subtest - configured simply
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @return mss::mcbist::subtest_t
+/// @note Turns on ECC mode for the returned subtest - caller can turn it off
+/// @note Configures for start/end address select bit as address config register 0
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE, typename TT = mcbistTraits<MC, T> >
+inline subtest_t<MC, T, TT> read_subtest()
+{
+ // Starts life full of 0's
+ subtest_t<MC, T, TT> l_subtest;
+
+ // 0:3 = 0001 - we want subtest type to be a Read (R)
+ l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::READ);
+
+ // - Not a special subtest, so no other configs associated
+ // 4 = 0 - we don't want to complement data for our Writes
+ // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
+ // 7 = 0 - forward address generation
+ // 8 = 0 - non random address generation
+ // - Don't need to set up anything for LFSRs
+ // 9:11 = 000 - Fixed data mode
+
+ // 14:15 = 0 address select config registers 0
+
+ // By default we want to turn on ECC. Caller can turn it off.
+ l_subtest.change_ecc_mode(mss::ON);
+
+ return l_subtest;
+}
+
+///
+/// @brief Return a read write subtest - configured simply
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @return mss::mcbist::subtest_t
+/// @note Turns on ECC mode for the returned subtest - caller can turn it off
+/// @note Configures for start/end address select bit as address config register 0
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE, typename TT = mcbistTraits<MC, T> >
+inline subtest_t<MC, T, TT> read_write_subtest()
+{
+ // Starts life full of 0's
+ subtest_t<MC, T, TT> l_subtest;
+
+ // 0:3 = 0010 - we want subtest type to be a Read Write (RW)
+ l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::READ_WRITE);
+
+ // - Not a special subtest, so no other configs associated
+ // 4 = 0 - we don't want to complement data for our Writes
+ // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
+ // 7 = 0 - forward address generation
+ // 8 = 0 - non random address generation
+ // - Don't need to set up anything for LFSRs
+ // 9:11 = 000 - Fixed data mode
+
+ // 14:15 = 0 address select config registers 0
+
+ // By default we want to turn on ECC. Caller can turn it off.
+ l_subtest.change_ecc_mode(mss::ON);
+
+ return l_subtest;
+}
+
+
+///
+/// @brief Return a write read subtest - configured simply
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @return mss::mcbist::subtest_t
+/// @note Turns on ECC mode for the returned subtest - caller can turn it off
+/// @note Configures for start/end address select bit as address config register 0
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE, typename TT = mcbistTraits<MC, T> >
+inline subtest_t<MC, T, TT> write_read_subtest()
+{
+ // Starts life full of 0's
+ subtest_t<MC, T, TT> l_subtest;
+
+ // 0:3 = 0011 - we want subtest type to be a Write Read (WR)
+ l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::WRITE_READ);
+
+ // - Not a special subtest, so no other configs associated
+ // 4 = 0 - we don't want to complement data for our Writes
+ // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
+ // 7 = 0 - forward address generation
+ // 8 = 0 - non random address generation
+ // - Don't need to set up anything for LFSRs
+ // 9:11 = 000 - Fixed data mode
+
+ // 14:15 = 0 address select config registers 0
+
+ // By default we want to turn on ECC. Caller can turn it off.
+ l_subtest.change_ecc_mode(mss::ON);
+
+ return l_subtest;
+}
+
+///
+/// @brief Return a read write read subtest - configured simply
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @return mss::mcbist::subtest_t
+/// @note Turns on ECC mode for the returned subtest - caller can turn it off
+/// @note Configures for start/end address select bit as address config register 0
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE, typename TT = mcbistTraits<MC, T> >
+inline subtest_t<MC, T, TT> read_write_read_subtest()
+{
+ // Starts life full of 0's
+ subtest_t<MC, T, TT> l_subtest;
+
+ // 0:3 = 0100 - we want subtest type to be a Read Write Read (RWR)
+ l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::READ_WRITE_READ);
+
+ // - Not a special subtest, so no other configs associated
+ // 4 = 0 - we don't want to complement data for our Writes
+ // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
+ // 7 = 0 - forward address generation
+ // 8 = 0 - non random address generation
+ // - Don't need to set up anything for LFSRs
+ // 9:11 = 000 - Fixed data mode
+
+ // 14:15 = 0 address select config registers 0
+
+ // By default we want to turn on ECC. Caller can turn it off.
+ l_subtest.change_ecc_mode(mss::ON);
+
+ return l_subtest;
+}
+
+///
+/// @brief Return a read read write subtest - configured simply
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @return mss::mcbist::subtest_t
+/// @note Turns on ECC mode for the returned subtest - caller can turn it off
+/// @note Configures for start/end address select bit as address config register 0
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE, typename TT = mcbistTraits<MC, T> >
+inline subtest_t<MC, T, TT> read_read_write_subtest()
+{
+ // Starts life full of 0's
+ subtest_t<MC, T, TT> l_subtest;
+
+ // 0:3 = 1000 - we want subtest type to be a Read Read Write (RRW)
+ l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::READ_READ_WRITE);
+
+ // - Not a special subtest, so no other configs associated
+ // 4 = 0 - we don't want to complement data for our Writes
+ // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
+ // 7 = 0 - forward address generation
+ // 8 = 0 - non random address generation
+ // - Don't need to set up anything for LFSRs
+ // 9:11 = 000 - Fixed data mode
+
+ // 14:15 = 0 address select config registers 0
+
+ // By default we want to turn on ECC. Caller can turn it off.
+ l_subtest.change_ecc_mode(mss::ON);
+
+ return l_subtest;
+}
+
+///
+/// @brief Return a read write write subtest - configured simply
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @return mss::mcbist::subtest_t
+/// @note Turns on ECC mode for the returned subtest - caller can turn it off
+/// @note Configures for start/end address select bit as address config register 0
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE, typename TT = mcbistTraits<MC, T> >
+inline subtest_t<MC, T, TT> read_write_write_subtest()
+{
+ // Starts life full of 0's
+ subtest_t<MC, T, TT> l_subtest;
+
+ // 0:3 = 0101 - we want subtest type to be a Read Write Write (RWW)
+ l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::READ_WRITE_WRITE);
+
+ // - Not a special subtest, so no other configs associated
+ // 4 = 0 - we don't want to complement data for our Writes
+ // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
+ // 7 = 0 - forward address generation
+ // 8 = 0 - non random address generation
+ // - Don't need to set up anything for LFSRs
+ // 9:11 = 000 - Fixed data mode
+
+ // 14:15 = 0 address select config registers 0
+
+ // By default we want to turn on ECC. Caller can turn it off.
+ l_subtest.change_ecc_mode(mss::ON);
+
+ return l_subtest;
+}
+
+///
+/// @brief Return a random subtest - configured simply
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @return mss::mcbist::subtest_t
+/// @note Turns on ECC mode for the returned subtest - caller can turn it off
+/// @note Configures for start/end address select bit as address config register 0
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE, typename TT = mcbistTraits<MC, T> >
+inline subtest_t<MC, T, TT> random_subtest()
+{
+ // Starts life full of 0's
+ subtest_t<MC, T, TT> l_subtest;
+
+ // 0:3 = 0110 - we want subtest type to be a Random Seq, a randomly chosen read or write
+ l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::RAND_SEQ);
+
+ // - Not a special subtest, so no other configs associated
+ // 4 = 0 - we don't want to complement data for our Writes
+ // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
+ // 7 = 0 - forward address generation
+ // 8 = 0 - non random address generation
+ // - Don't need to set up anything for LFSRs
+ // 9:11 = 000 - Fixed data mode
+
+ // 14:15 = 0 address select config registers 0
+
+ // By default we want to turn on ECC. Caller can turn it off.
+ l_subtest.change_ecc_mode(mss::ON);
+
+ return l_subtest;
+}
+
+///
+/// @brief Return a goto subtest - configured simply
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] the subtest we should go to
+/// @return mss::mcbist::subtest_t
+/// @note Turns on ECC mode for the returned subtest - caller can turn it off
+/// @note Configures for start/end address select bit as address config register 0
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE, typename TT = mcbistTraits<MC, T> >
+inline subtest_t<MC, T, TT> goto_subtest( const uint64_t i_jump_to )
+{
+ // Starts life full of 0's
+ subtest_t<MC, T, TT> l_subtest;
+
+ // 0:3 = 0111 - we want subtest type to be a Goto
+ l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::GOTO_SUBTEST_N);
+
+ // Plug in the subtest the user passed in
+ l_subtest.change_goto_subtest(i_jump_to);
+ return l_subtest;
+}
+
+///
+/// @brief Return an init subtest - configured simply
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @return mss::mcbist::subtest_t
+/// @note Configures for start/end address select bit as address config register 0
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE, typename TT = mcbistTraits<MC, T> >
+inline subtest_t<MC, T, TT> init_subtest()
+{
+ return write_subtest<MC, T, TT>();
+}
+
+///
+/// @brief A class representing a series of MCBIST subtests, and the
+/// MCBIST engine parameters associated with running the subtests
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2::TargetType representing the fapi2 target which
+/// @tparam TT the mcbistTraits associated with T - derived
+/// contains the MCBIST engine (e.g., fapi2::TARGET_TYPE_MCBIST)
+/// @tparam TT, the mssTraits associtated with T
+/// @note MCBIST Memory Parameter Register defaults to
+/// - issue commands as fast as possible
+/// - even weighting of read/write if random addressing
+/// - disable clock monitoring
+/// - random command gap is disabled
+/// - BC4 disabled
+/// - no selected ports
+/// @note Address Generation Config Register defaults to
+/// - 0 fixed slots
+/// - All address counter modes on (so addr configs are start + len)
+/// - maint address mode enabled
+/// - maint broadcast mode disabled
+/// - maint slave rank boundary detect disabled
+/// @note Config register defaults to
+/// - BROADCAST_SYNC_EN disabled
+/// - BROADCAST_SYNC_WAIT 0
+/// - TIMEOUT_MODE - wait 524288 cycles until timeout is called
+/// - RESET_KEEPER - 0
+/// - CURRENT_ADDR_TRAP_UPDATE_DIS - 0
+/// - CCS_RETRY_DIS - 0
+/// - RESET_CNTS_START_OF_RANK - 0
+/// - LOG_COUNTS_IN_TRACE - 0
+/// - SKIP_INVALID_ADDR_DIMM_DIS - 0
+/// - REFRESH_ONLY_SUBTEST_EN - 0
+/// - REFRESH_ONLY_SUBTEST_TIMEBASE_SEL(0:1) - 0
+/// - RAND_ADDR_ALL_ADDR_MODE_EN - 0
+/// - REF_WAIT_TIME(0:13) - 0
+/// - MCB_LEN64 - 1
+/// - PAUSE_ON_ERROR_MODE(0:1) - don't pause on error
+/// - PAUSE_AFTER_CCS_SUBTEST - don't puase after CCS subtest
+/// - FORCE_PAUSE_AFTER_ADDR - don't pause after current address
+/// - FORCE_PAUSE_AFTER_SUBTEST - no pause after subtest
+/// - ENABLE_SPEC_ATTN - disabled
+/// - ENABLE_HOST_ATTN - enabled
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE , typename TT = mcbistTraits<MC, T> >
+class program
+{
+ private:
+
+ ///
+ /// @class broadcast_helper
+ /// @brief Nested class to help specialize broadcast mode functionality
+ /// @tparam mss::states BC - YES if broadcast mode capable
+ /// @tparam B = true - here for a little compiler magic to allow some partial specializations
+ ///
+ template< mss::states BC, bool B = true >
+ struct broadcast_helper;
+
+ ///
+ /// @class broadcast_helper - BC mode capable specialization
+ /// @tparam B = true - here for a little compiler magic to allow some partial specializations
+ ///
+ template<bool B >
+ struct broadcast_helper<mss::states::YES, B>
+ {
+
+ ///
+ /// @brief Change the broadcast sync enable bit - broadcast capable specialization
+ /// @param[in] i_state mss::ON to enable the sync pulse, mss::OFF to disable
+ /// @param[in,out] io_config configuration register
+ ///
+ static inline void broadcast_sync_enable( const mss::states i_state, fapi2::buffer<uint64_t>& io_config )
+ {
+ io_config.writeBit<TT::SYNC_EN>(i_state);
+ }
+
+ ///
+ /// @brief Change the broadcast mode sync timbase count - broadcast capable specialization
+ /// @param[in] i_broadcast_timebase
+ /// @param[in,out] io_config configuration register
+ ///
+ static inline void change_broadcast_timebase( const mss::mcbist::broadcast_timebase i_broadcast_timebase,
+ fapi2::buffer<uint64_t>& io_config )
+ {
+ io_config.insertFromRight<TT::SYNC_WAIT, TT::SYNC_WAIT_LEN>(i_broadcast_timebase);
+ }
+
+ ///
+ /// @brief Enable or disable broadcast mode - broadcast capable specialization
+ /// @param[in] i_mode true if broadcast should be enabled
+ /// @param[in,out] io_addr_gen address generation register
+ /// @warn Maint address mode must be enabled for this to work
+ /// @return void
+ ///
+ static inline void change_maint_broadcast_mode( const bool i_mode, fapi2::buffer<uint64_t>& io_addr_gen )
+ {
+ io_addr_gen.writeBit<TT::MAINT_BROADCAST_MODE_EN>(i_mode);
+ }
+ };
+
+
+ ///
+ /// @class broadcast_helper - BC mode incapable specialization
+ /// @tparam B = true - here for a little compiler magic to allow some partial specializations
+ /// @note all functions here should be empty - if we don't have broadcast mode, we don't want to do anything for it
+ ///
+ template<bool B >
+ struct broadcast_helper<mss::states::NO, B>
+ {
+
+ ///
+ /// @brief Change the broadcast sync enable bit - broadcast incapable specialization
+ /// @param[in] i_state mss::ON to enable the sync pulse, mss::OFF to disable
+ /// @param[in,out] io_config configuration register
+ ///
+ static inline void broadcast_sync_enable( const mss::states i_state, fapi2::buffer<uint64_t>& io_config )
+ {}
+
+ ///
+ /// @brief Change the broadcast mode sync timbase count - broadcast incapable specialization
+ /// @param[in] i_broadcast_timebase
+ /// @param[in,out] io_config configuration register
+ ///
+ static inline void change_broadcast_timebase( const mss::mcbist::broadcast_timebase i_broadcast_timebase,
+ fapi2::buffer<uint64_t>& io_config )
+ {}
+
+ ///
+ /// @brief Enable or disable broadcast mode - broadcast incapable specialization
+ /// @param[in] i_mode true if broadcast should be enabled
+ /// @param[in,out] io_addr_gen address generation register
+ /// @warn Maint address mode must be enabled for this to work
+ /// @return void
+ ///
+ static inline void change_maint_broadcast_mode( const bool i_mode, fapi2::buffer<uint64_t>& io_addr_gen )
+ {}
+ };
+
+ public:
+ // Setup our poll parameters so the MCBIST executer can see
+ // whether to use the delays in the instruction stream or not
+ program():
+ iv_parameters(0),
+ iv_addr_gen(0),
+ iv_test_type(CENSHMOO), // Used as default
+ iv_addr_map0(0),
+ iv_addr_map1(0),
+ iv_addr_map2(0),
+ iv_addr_map3(0),
+ iv_data_rotate_cnfg(0),
+ iv_data_rotate_seed(0),
+ iv_config(0),
+ iv_control(0),
+ iv_async(false),
+ iv_pattern(PATTERN_0),
+ iv_random24_data_seed(RANDOM24_SEEDS_0),
+ iv_random24_seed_map(RANDOM24_SEED_MAP_0),
+ iv_compare_mask(0)
+ {
+ // Enable the maintenance mode addressing
+ change_maint_address_mode(mss::ON);
+
+ // Enable 64B lengths by default. Commands which need 128B (scrub, steer, alter, display)
+ // can change this to 128B (mss::OFF).
+ change_len64(mss::ON);
+
+ // Turn off counting mode for all address configs
+ iv_addr_gen.insertFromRight<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(0b0000);
+
+ // By default if there's an error, we stop after the errored address
+ iv_config.insertFromRight<TT::CFG_PAUSE_ON_ERROR_MODE,
+ TT::CFG_PAUSE_ON_ERROR_MODE_LEN>(end_boundary::STOP_AFTER_ADDRESS);
+
+ // All mcbist attentions are host attentions, special attention bit is already clear
+ if(TT::CFG_ENABLE_ATTN_SUPPORT == mss::states::YES)
+ {
+ iv_config.setBit<TT::CFG_ENABLE_HOST_ATTN>();
+ }
+
+ }
+
+ ///
+ /// @brief Change the DIMM select in the address mapping
+ /// @param[in] i_bitmap DIMM select bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_dimm_select_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map0.insertFromRight<TT::CFG_AMAP_DIMM_SELECT, TT::CFG_AMAP_DIMM_SELECT_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the MRANK0 address mapping when not in 5D mode
+ /// @param[in] i_bitmap MRANK0 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_mrank0_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map0.insertFromRight<TT::CFG_AMAP_MRANK0, TT::CFG_AMAP_MRANK0_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the MRANK0 address mapping when in 5D mode
+ /// @param[in] i_bitmap MRANK0 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_mrank0_bit_5d( const uint64_t i_bitmap )
+ {
+ iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK0, TT::CFG_AMAP_SRANK0_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the MRANK1 address mapping when not in 5D mode
+ /// @param[in] i_bitmap MRANK1 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_mrank1_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map0.insertFromRight<TT::CFG_AMAP_MRANK1, TT::CFG_AMAP_MRANK1_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the MRANK1 address mapping when in 5D mode
+ /// @param[in] i_bitmap MRANK1 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_mrank1_bit_5d( const uint64_t i_bitmap )
+ {
+ iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK1, TT::CFG_AMAP_SRANK1_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the MRANK2 address mapping when in 5D mode
+ /// @param[in] i_bitmap MRANK2 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_mrank2_bit_5d( const uint64_t i_bitmap )
+ {
+ iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK2, TT::CFG_AMAP_SRANK2_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the SRANK0 address mapping when in 5D mode
+ /// @param[in] i_bitmap SRANK0 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_srank0_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK0, TT::CFG_AMAP_SRANK0_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the SRANK1 address mapping
+ /// @param[in] i_bitmap SRANK1 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_srank1_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK1, TT::CFG_AMAP_SRANK1_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the SRANK2 address mapping
+ /// @param[in] i_bitmap SRANK2 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_srank2_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK2, TT::CFG_AMAP_SRANK2_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the BANK2 address mapping
+ /// @param[in] i_bitmap BANK2 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_bank2_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map0.insertFromRight<TT::CFG_AMAP_BANK2, TT::CFG_AMAP_BANK2_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the BANK1 address mapping
+ /// @param[in] i_bitmap BANK1 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_bank1_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map0.insertFromRight<TT::CFG_AMAP_BANK1, TT::CFG_AMAP_BANK1_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the BANK0 address mapping
+ /// @param[in] i_bitmap BANK0 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_bank0_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map0.insertFromRight<TT::CFG_AMAP_BANK0, TT::CFG_AMAP_BANK0_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the BANK_GROUP1 address mapping
+ /// @param[in] i_bitmap BANK_GROUP1 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_bank_group1_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map1.insertFromRight<TT::CFG_AMAP_BANK_GROUP1, TT::CFG_AMAP_BANK_GROUP1_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the BANK_GROUP0 address mapping
+ /// @param[in] i_bitmap BANK_GROUP0 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_bank_group0_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map1.insertFromRight<TT::CFG_AMAP_BANK_GROUP0, TT::CFG_AMAP_BANK_GROUP0_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW17 address mapping
+ /// @param[in] i_bitmap ROW17 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row17_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW17, TT::CFG_AMAP_ROW17_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW16 address mapping
+ /// @param[in] i_bitmap ROW16 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row16_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW16, TT::CFG_AMAP_ROW16_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW15 address mapping
+ /// @param[in] i_bitmap ROW15 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row15_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW15, TT::CFG_AMAP_ROW15_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW14 address mapping
+ /// @param[in] i_bitmap ROW14 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row14_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW14, TT::CFG_AMAP_ROW14_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW13 address mapping
+ /// @param[in] i_bitmap ROW13 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_row13_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW13, TT::CFG_AMAP_ROW13_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW12 address mapping
+ /// @param[in] i_bitmap ROW12 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row12_bit( const uint64_t i_bitmap )
+ {
+ // CFG_AMAP_ROW12 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12 ,
+ iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW12, TT::CFG_AMAP_ROW12_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW11 address mapping
+ /// @param[in] i_bitmap ROW11 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row11_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW11, TT::CFG_AMAP_ROW11_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW10 address mapping
+ /// @param[in] i_bitmap ROW10 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row10_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW10, TT::CFG_AMAP_ROW10_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW9 address mapping
+ /// @param[in] i_bitmap ROW9 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row9_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW9, TT::CFG_AMAP_ROW9_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW8 address mapping
+ /// @param[in] i_bitmap ROW8 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row8_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW8, TT::CFG_AMAP_ROW8_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW7 address mapping
+ /// @param[in] i_bitmap ROW7 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row7_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW7, TT::CFG_AMAP_ROW7_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW6 address mapping
+ /// @param[in] i_bitmap ROW6 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row6_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW6, TT::CFG_AMAP_ROW6_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW5 address mapping
+ /// @param[in] i_bitmap ROW5 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row5_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW5, TT::CFG_AMAP_ROW5_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW4 address mapping
+ /// @param[in] i_bitmap ROW4 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row4_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW4, TT::CFG_AMAP_ROW4_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW3 address mapping
+ /// @param[in] i_bitmap ROW3 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row3_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW3, TT::CFG_AMAP_ROW3_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW2 address mapping
+ /// @param[in] i_bitmap ROW2 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row2_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW2, TT::CFG_AMAP_ROW2_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW1 address mapping
+ /// @param[in] i_bitmap ROW1 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row1_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW1, TT::CFG_AMAP_ROW1_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the ROW0 address mapping
+ /// @param[in] i_bitmap ROW0 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_row0_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW0, TT::CFG_AMAP_ROW0_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the COL9 address mapping
+ /// @param[in] i_bitmap COL9 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_col9_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL9, TT::CFG_AMAP_COL9_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the COL8 address mapping
+ /// @param[in] i_bitmap COL8 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_col8_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL8, TT::CFG_AMAP_COL8_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the COL7 address mapping
+ /// @param[in] i_bitmap COL7 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_col7_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL7, TT::CFG_AMAP_COL7_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the COL6 address mapping
+ /// @param[in] i_bitmap COL6 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_col6_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL6, TT::CFG_AMAP_COL6_LEN>(i_bitmap);
+ return;
+ }
+
+ /// @brief Change the COL5 address mapping
+ /// @param[in] i_bitmap COL5 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_col5_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL5, TT::CFG_AMAP_COL5_LEN>(i_bitmap);
+ return;
+ }
+
+ /// @brief Change the COL4 address mapping
+ /// @param[in] i_bitmap COL4 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_col4_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL4, TT::CFG_AMAP_COL4_LEN>(i_bitmap);
+ return;
+ }
+
+ /// @brief Change the COL3 address mapping
+ /// @param[in] i_bitmap COL3 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_col3_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL3, TT::CFG_AMAP_COL3_LEN>(i_bitmap);
+ return;
+ }
+
+ /// @brief Change the COL2 address mapping
+ /// @param[in] i_bitmap COL2 bit map in the address counter
+ /// @note Assumes data is right-aligned
+ ///
+ inline void change_col2_bit( const uint64_t i_bitmap )
+ {
+ iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL2, TT::CFG_AMAP_COL2_LEN>(i_bitmap);
+ return;
+ }
+
+ ///
+ /// @brief Change the mcbist 64/128 byte control
+ /// @param[in] i_state mss::ON if you want 64B, mss::OFF if you want 128B
+ /// @return void
+ ///
+ inline void change_len64( const mss::states i_state )
+ {
+ iv_config.writeBit<TT::CFG_MCB_LEN64>(i_state);
+ return;
+ }
+
+ ///
+ /// @brief Change the random address all address mode
+ /// @param[in] i_state mss::ON if you random addressing all addresses, mss::OFF if you don't
+ /// @return void
+ ///
+ inline void random_address_all( const mss::states i_state )
+ {
+ iv_config.writeBit<TT::RAND_ADDR_ALL_ADDR_MODE_EN>(i_state);
+ return;
+ }
+
+ ///
+ /// @brief Change the broadcast sync enable bit
+ /// @param[in] i_state mss::ON to enable the sync pulse, mss::OFF to disable
+ /// @return void
+ ///
+ inline void broadcast_sync_enable( const mss::states i_state )
+ {
+ broadcast_helper<TT::BROADCAST_CAPABLE>::broadcast_sync_enable(i_state, iv_config);
+ }
+
+ ///
+ /// @brief Change the broadcast mode sync timbase count
+ /// @param[in] i_broadcast_timebase
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_broadcast_timebase( const mss::mcbist::broadcast_timebase i_broadcast_timebase )
+ {
+ broadcast_helper<TT::BROADCAST_CAPABLE>::change_broadcast_timebase(i_broadcast_timebase, iv_config);
+ return;
+ }
+
+ ///
+ /// @brief Change the mcbist thresholds
+ /// @param[in] i_thresholds the new thresholds/stop conditions
+ /// @return void
+ ///
+ inline void change_thresholds( const stop_conditions<MC>& i_thresholds )
+ {
+ iv_thresholds = i_thresholds;
+ return;
+ }
+
+ ///
+ /// @brief Change the data rotate value
+ /// @param[in] i_data_rotate
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_data_rotate( mss::mcbist::data_rotate_mode i_data_rotate )
+ {
+ iv_data_rotate_cnfg.insertFromRight<TT::CFG_DATA_ROT, TT::CFG_DATA_ROT_LEN>(i_data_rotate);
+ return;
+ }
+
+ ///
+ /// @brief Get the data rotate value
+ /// @note Assumes data is right aligned
+ /// @return the data rotate value config
+ ///
+ inline uint64_t get_data_rotate()
+ {
+ uint64_t l_data_rotate = 0;
+ iv_data_rotate_cnfg.extractToRight<TT::CFG_DATA_ROT, TT::CFG_DATA_ROT_LEN>(l_data_rotate);
+ return l_data_rotate;
+ }
+
+ ///
+ /// @brief Change the data seed mode value
+ /// @param[in] i_data_seed_mode
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_data_seed_mode( const mss::mcbist::data_seed_mode i_data_seed_mode )
+ {
+ iv_data_rotate_cnfg.insertFromRight<TT::CFG_DATA_SEED_MODE, TT::CFG_DATA_SEED_MODE_LEN>(i_data_seed_mode);
+ return;
+ }
+
+ ///
+ /// @brief Get the data seed mode value
+ /// @note Assumes data is right aligned
+ /// @return the data seed mode value
+ ///
+ inline uint64_t get_data_seed_mode()
+ {
+ uint64_t l_data_seed_mode = 0;
+ iv_data_rotate_cnfg.extractToRight<TT::CFG_DATA_SEED_MODE, TT::CFG_DATA_SEED_MODE_LEN>(l_data_seed_mode);
+ return l_data_seed_mode;
+ }
+
+ ///
+ /// @brief Change the data rotate seed for data bits 0:63
+ /// @param[in] i_width
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_data_rotate_seed1( const uint64_t i_data_rotate_seed1 )
+ {
+ iv_data_rotate_seed.insertFromRight<TT::CFG_DATA_ROT_SEED1, TT::CFG_DATA_ROT_SEED1_LEN>(i_data_rotate_seed1);
+ return;
+ }
+
+ ///
+ /// @brief Get the data rotate seed for data bits 0:63
+ /// @note Assumes data is right aligned
+ /// @return the data rotate seed for data bits 0:63
+ ///
+ inline uint64_t get_data_rotate_seed1()
+ {
+ uint64_t l_data_rotate_seed1 = 0;
+ iv_data_rotate_seed.extractToRight<TT::CFG_DATA_ROT_SEED1, TT::CFG_DATA_ROT_SEED1_LEN>(l_data_rotate_seed1);
+ return l_data_rotate_seed1;
+ }
+
+ ///
+ /// @brief Change the data rotate seed for data bits 64:79
+ /// @param[in] i_width
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_data_rotate_seed2( const uint64_t i_data_rotate_seed2 )
+ {
+ iv_data_rotate_cnfg.insertFromRight<TT::CFG_DATA_ROT_SEED2, TT::CFG_DATA_ROT_SEED2_LEN>(i_data_rotate_seed2);
+ return;
+ }
+
+ ///
+ /// @brief Get the data rotate seed for data bits 64:79
+ /// @note Assumes data is right aligned
+ /// @return the data rotate seed for data bits 64:79
+ ///
+ inline uint64_t get_data_rotate_seed2()
+ {
+ uint64_t l_data_rotate_seed2 = 0;
+ iv_data_rotate_cnfg.extractToRight<TT::CFG_DATA_ROT_SEED2, TT::CFG_DATA_ROT_SEED2_LEN>(l_data_rotate_seed2);
+ return l_data_rotate_seed2;
+ }
+
+ ///
+ /// @brief Change the compare mask CE trap enable
+ /// @param[in] i_state mss::ON to enable the trap, mss::OFF to disable the trap
+ /// @return void
+ ///
+ inline void change_ce_trap_enable( const mss::states i_state )
+ {
+ iv_compare_mask.writeBit<TT::CFG_TRAP_CE_ENABLE>(i_state);
+ return;
+ }
+
+ ///
+ /// @brief Change the compare mask UE trap enable
+ /// @param[in] i_state mss::ON to enable the trap, mss::OFF to disable the trap
+ /// @return void
+ ///
+ inline void change_ue_trap_enable( const mss::states i_state )
+ {
+ iv_compare_mask.writeBit<TT::CFG_TRAP_UE_ENABLE>(i_state);
+ return;
+ }
+
+ ///
+ /// @brief Change the compare mask MPE trap enable
+ /// @param[in] i_state mss::ON to enable the trap, mss::OFF to disable the trap
+ /// @return void
+ ///
+ inline void change_mpe_trap_enable( const mss::states i_state )
+ {
+ iv_compare_mask.writeBit<TT::CFG_TRAP_MPE_ENABLE>(i_state);
+ return;
+ }
+
+ ///
+ /// @brief Change the forced pause state
+ /// @param[in] i_end the end_boundary to pause at
+ /// @return void
+ ///
+ inline void change_forced_pause( const end_boundary& i_end )
+ {
+ if (i_end == end_boundary::DONT_CHANGE)
+ {
+ return;
+ }
+
+ // Clear all the forced pause bits so we don't stack pauses
+ iv_config.clearBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR>();
+ iv_config.clearBit<TT::MCBIST_CFG_PAUSE_AFTER_RANK>();
+ iv_config.clearBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST>();
+ iv_addr_gen.clearBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>();
+
+ switch (i_end)
+ {
+ case end_boundary::STOP_AFTER_ADDRESS:
+ iv_config.setBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR>();
+ break;
+
+ case end_boundary::STOP_AFTER_SLAVE_RANK:
+ iv_config.setBit<TT::MCBIST_CFG_PAUSE_AFTER_RANK>();
+ iv_addr_gen.setBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>();
+ break;
+
+ case end_boundary::STOP_AFTER_MASTER_RANK:
+ iv_config.setBit<TT::MCBIST_CFG_PAUSE_AFTER_RANK>();
+ iv_addr_gen.clearBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>();
+ break;
+
+ case end_boundary::STOP_AFTER_SUBTEST:
+ iv_config.setBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST>();
+ break;
+
+ // None is all set, we cleared the bits above
+ case end_boundary::NONE:
+ break;
+
+ // Default is a no forced pause (as we cleared all the bits)
+ default:
+ FAPI_INF("no forced pause state - end state %d unknown", i_end);
+ break;
+ };
+
+ return;
+ }
+
+ ///
+ /// @brief Calculate minimum command gap for BG_SCRUB
+ /// @param[in] i_target the target behind which the memory sits
+ /// @param[in] i_freq the DRAM frequency
+ /// @param[in] i_size the sum of all DIMM sizes
+ /// @param[out] o_min_cmd_gap the setting for MCBPARMQ_CFG_MIN_CMD_GAP
+ /// @param[out] o_timebase the setting for MCBPARMQ_CFG_MIN_GAP_TIMEBASE
+ /// @return FAPI2_RC_SUCCSS iff ok
+ ///
+ inline fapi2::ReturnCode calculate_min_cmd_gap( const fapi2::Target<T>& i_target,
+ const uint64_t i_freq,
+ const uint64_t i_size,
+ uint64_t& o_min_cmd_gap,
+ mss::states& o_timebase )
+ {
+ constexpr uint64_t l_seconds = SEC_IN_HOUR * BG_SCRUB_IN_HOURS;
+ constexpr uint64_t MIN_CMD_GAP = 0x001;
+ uint64_t l_mem_cycles_per_sec;
+ uint64_t l_total_cycles;
+ uint64_t l_total_addresses;
+ uint64_t l_min_cmd_gap;
+
+ // Sanity check our inputs, just assert if bad since they come directly from eff_config
+ // this will prevent us from any divide by zero problems
+ FAPI_ASSERT( (i_freq != 0) && (i_size != 0),
+ fapi2::MSS_ZERO_FREQ_OR_SIZE().
+ set_FREQ(i_freq).
+ set_SIZE(i_size),
+ "%s received zero memory freq or size in calculate_min_cmd_gap", mss::c_str(i_target));
+
+ // MIN CMD GAP = TOTAL CYCLES / TOTAL ADDRESSES
+ // TOTAL CYCLES = 12 hours x 60 min/hr x 60 sec/min x [DRAM freq] cycles/sec x
+ // 1/2 (MEM logic runs half DRAM freq)
+ l_mem_cycles_per_sec = (i_freq * T_PER_MT) / 2;
+ l_total_cycles = l_seconds * l_mem_cycles_per_sec;
+
+ // TOTAL ADDRESSES = sum over all dimms of ( [DIMM CAPACITY]/128B )
+ l_total_addresses = i_size * BYTES_PER_GB / 128;
+
+ l_min_cmd_gap = l_total_cycles / l_total_addresses;
+
+ // If we're greater than the timebase, set the multiplier and divide down to get the gap setting
+ if (CMD_TIMEBASE < l_min_cmd_gap)
+ {
+ o_min_cmd_gap = l_min_cmd_gap / CMD_TIMEBASE;
+ o_timebase = mss::ON;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // If we're greater than the max gap setting, get as close to 12 hours as we can instead of just truncating
+ if (l_min_cmd_gap > MAX_CMD_GAP)
+ {
+ // work backwards to calculate what the total scrub time would be with the highest cmd gap with no multiplier...
+ const uint64_t l_scrub_time_fff = (l_total_addresses * MAX_CMD_GAP) / l_mem_cycles_per_sec;
+ // and with the lowest cmd gap with the multiplier
+ const uint64_t l_scrub_time_001 = (l_total_addresses * CMD_TIMEBASE) / l_mem_cycles_per_sec;
+
+ if ((l_seconds - l_scrub_time_fff) > (l_scrub_time_001 - l_seconds))
+ {
+ FAPI_INF("%s gap is greater than the field will allow. Setting to: 0x%03x", mss::c_str(i_target), MIN_CMD_GAP);
+ o_min_cmd_gap = MIN_CMD_GAP;
+ o_timebase = mss::ON;
+ }
+ else
+ {
+ FAPI_INF("%s gap is greater than the field will allow. Setting to: 0x%03x", mss::c_str(i_target), MAX_CMD_GAP);
+ o_min_cmd_gap = MAX_CMD_GAP;
+ o_timebase = mss::OFF;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Else, we're good to just set the calculated gap value directly
+ o_min_cmd_gap = l_min_cmd_gap;
+ o_timebase = mss::OFF;
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Change MCBIST Speed
+ /// @param[in] i_target the target behind which the memory sits
+ /// @param[in] i_speed the speed eunmeration
+ /// @return FAPI2_RC_SUCCSS iff ok
+ ///
+ inline fapi2::ReturnCode change_speed( const fapi2::Target<T>& i_target, const speed i_speed )
+ {
+ switch (i_speed)
+ {
+ case speed::LUDICROUS:
+ change_min_cmd_gap(0);
+ change_min_gap_timebase(mss::OFF);
+ return fapi2::FAPI2_RC_SUCCESS;
+ break;
+
+ case speed::BG_SCRUB:
+ {
+ uint64_t l_freq = 0;
+ uint64_t l_size = 0;
+ uint64_t l_min_cmd_gap = 0;
+ mss::states l_timebase = mss::OFF;
+
+ constexpr uint64_t l_seconds = SEC_IN_HOUR * BG_SCRUB_IN_HOURS;
+
+ FAPI_TRY( mss::freq(i_target, l_freq) );
+ FAPI_TRY( mss::eff_memory_size<MC>(i_target, l_size) );
+
+ FAPI_TRY( calculate_min_cmd_gap(i_target, l_freq, l_size, l_min_cmd_gap, l_timebase) );
+
+ FAPI_INF("%s setting bg scrub speed: %dMT/s, memory: %dGB, duration: %ds, gap: %d",
+ mss::c_str(i_target), l_freq, l_size, l_seconds, l_min_cmd_gap);
+
+ change_min_cmd_gap(l_min_cmd_gap);
+ change_min_gap_timebase(l_timebase);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+ break;
+
+ // Otherwise it's SAME_SPEED or something else in which case we do nothing
+ default:
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ break;
+ };
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Get a list of ports involved in the program
+ /// @param[in] i_target the target for this program
+ /// @return vector of port targets
+ ///
+ std::vector<fapi2::Target<TT::PORT_TYPE>> get_port_list( const fapi2::Target<T>& i_target ) const;
+
+ ///
+ /// @brief Change MCBIST Stop-on-error conditions (end boundaries)
+ /// @param[in] i_end the end boundary
+ /// @note By default the MCBIST is programmed to always stop after an errored address. This API
+ /// allows the caller to force a stop at a boundary or to force no stopping on errors
+ ///
+ inline void change_end_boundary( const end_boundary i_end )
+ {
+ // If there's no change, just get outta here
+ if (i_end == DONT_CHANGE)
+ {
+ return;
+ }
+
+ // The values of the enum were crafted so that we can simply insertFromRight into the register.
+ // We take note of whether to set the slave or master rank indicator and set that as well.
+ // The hardware has to have a 1 or a 0 - so there is no choice for the rank detection. So it
+ // doesn't matter that we're processing other end boundaries here - they'll just look like we
+ // asked for a master rank detect.
+ iv_config.insertFromRight<TT::CFG_PAUSE_ON_ERROR_MODE, TT::CFG_PAUSE_ON_ERROR_MODE_LEN>(i_end);
+
+ const uint64_t l_detect_slave = fapi2::buffer<uint64_t>(i_end).getBit<TT::SLAVE_RANK_INDICATED_BIT>();
+ iv_addr_gen.writeBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>( l_detect_slave );
+ FAPI_INF("load MCBIST end boundaries 0x%016lx detect slave? %s",
+ i_end, (l_detect_slave == 1 ? "yes" : "no") );
+ }
+
+ ///
+ /// @brief Change the mcbist min command gap
+ /// @param[in] i_gap minimum number of cycles between commands when cfg_en_randcmd_gap is a 0 (disabled)
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_min_cmd_gap( const uint64_t i_gap )
+ {
+ iv_parameters.insertFromRight<TT::MIN_CMD_GAP, TT::MIN_CMD_GAP_LEN>(i_gap);
+ return;
+ }
+
+ ///
+ /// @brief Change the mcbist gap timebase
+ /// @param[in] i_tb When set to mss::ON and cfg_en_randcmd_gap is a 0, then the number of minimum
+ /// cycles between commands will be cfg_min_cmd_gap multiplied by 2^13.
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_min_gap_timebase( const bool i_tb )
+ {
+ iv_parameters.writeBit<TT::MIN_GAP_TIMEBASE>(i_tb);
+ return;
+ }
+
+ ///
+ /// @brief Change the mcbist min command gap blind steer
+ /// @param[in] i_gap min gap between commands when doing steering
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_min_cmd_gap_blind_steer( const uint64_t i_gap )
+ {
+ iv_parameters.insertFromRight<TT::MIN_CMD_GAP_BLIND_STEER, TT::MIN_CMD_GAP_BLIND_STEER_LEN>(i_gap);
+ return;
+ }
+
+ ///
+ /// @brief Change the mcbist gap timebase for blind steer
+ /// @param[in] i_tb When set to mss::ON and cfg_en_randcmd_gap is a 0, then the number of minimum
+ /// cycles between commands will be cfg_min_cmd_gap multiplied by 2^13.
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_min_gap_timebase_blind_steer( const bool i_tb )
+ {
+ iv_parameters.writeBit<TT::MIN_GAP_TIMEBASE_BLIND_STEER>(i_tb);
+ return;
+ }
+
+ ///
+ /// @brief Change the weights for random mcbist reads, writes
+ /// @param[in] i_weight
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_randcmd_wgt( const uint64_t i_weight )
+ {
+ iv_parameters.insertFromRight<TT::RANDCMD_WGT, TT::RANDCMD_WGT_LEN>(i_weight);
+ return;
+ }
+
+ ///
+ /// @brief Change the weights for random mcbist command gaps
+ /// @param[in] i_weight
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_randgap_wgt( const uint64_t i_weight )
+ {
+ iv_parameters.insertFromRight<TT::RANDGAP_WGT, TT::RANDGAP_WGT_LEN>(i_weight);
+ return;
+ }
+
+ ///
+ /// @brief Enable or disable mcbist clock monitoring
+ /// @param[in] i_monitor mss::ON to monitor
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_clock_monitor_en( const bool i_monitor )
+ {
+ iv_parameters.writeBit<TT::CLOCK_MONITOR_EN>(i_monitor);
+ return;
+ }
+
+ ///
+ /// @brief Enable or disable mcbist random command gaps
+ /// @param[in] i_rndgap mss::ON to enable
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_en_randcmd_gap( const bool i_rndgap )
+ {
+ iv_parameters.writeBit<TT::EN_RANDCMD_GAP>(i_rndgap);
+ return;
+ }
+
+ ///
+ /// @brief Enable or disable mcbist BC4 support
+ /// @param[in] i_bc4 mss::ON to enable
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_bc4_en( const bool i_bc4 )
+ {
+ iv_parameters.writeBit<TT::BC4_EN>(i_bc4);
+ return;
+ }
+
+ ///
+ /// @brief Change fixed width address generator config
+ /// @param[in] i_width
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_fixed_width( const uint64_t i_width )
+ {
+ iv_addr_gen.insertFromRight<TT::FIXED_WIDTH, TT::FIXED_WIDTH_LEN>(i_width);
+ return;
+ }
+
+ ///
+ /// @brief Get the fixed width address config
+ /// @note Assumes data is right aligned
+ /// @return the fixed width address config
+ ///
+ inline uint64_t get_fixed_width() const
+ {
+ uint64_t l_fixed_width = 0;
+ iv_addr_gen.extractToRight<TT::FIXED_WIDTH, TT::FIXED_WIDTH_LEN>(l_fixed_width);
+ return l_fixed_width;
+ }
+
+ ///
+ /// @brief Enable or disable address counting mode for address config 0
+ /// @param[in] i_mode mss::ON to enable
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_address_counter_mode0( const bool i_mode )
+ {
+ fapi2::buffer<uint64_t> l_value;
+ iv_addr_gen.extract<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
+ // Bit 0 enables counter mode for start/end address field 0
+ l_value.writeBit<0>(i_mode);
+ iv_addr_gen.insert<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
+ return;
+ }
+
+ ///
+ /// @brief Enable or disable address counting mode for address config 1
+ /// @param[in] i_mode mss::ON to enable
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_address_counter_mode1( const bool i_mode )
+ {
+ fapi2::buffer<uint64_t> l_value;
+ iv_addr_gen.extract<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
+ // Bit 1 enables counter mode for start/end address field 1
+ l_value.writeBit<1>(i_mode);
+ iv_addr_gen.insert<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
+ return;
+ }
+
+ ///
+ /// @brief Enable or disable address counting mode for address config 2
+ /// @param[in] i_mode mss::ON to enable
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_address_counter_mode2( const bool i_mode )
+ {
+ fapi2::buffer<uint64_t> l_value;
+ iv_addr_gen.extract<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
+ // Bit 2 enables counter mode for start/end address field 2
+ l_value.writeBit<2>(i_mode);
+ iv_addr_gen.insert<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
+ return;
+ }
+
+ ///
+ /// @brief Enable or disable address counting mode for address config 3
+ /// @param[in] i_program, the program in question
+ /// @param[in] i_mode mss::ON to enable
+ /// @note Assumes data is right-aligned
+ /// @return void
+ ///
+ inline void change_address_counter_mode3( const bool i_mode )
+ {
+ fapi2::buffer<uint64_t> l_value;
+ iv_addr_gen.extract<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
+ // Bit 3 enables counter mode for start/end address field 3
+ l_value.writeBit<3>(i_mode);
+ iv_addr_gen.insert<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
+ return;
+ }
+
+
+ ///
+ /// @brief Enable or disable maint address mode
+ /// @param[in] i_mode mss::ON to enable
+ /// @warn Address counter modes must be 0 for this to work.
+ /// @note When enabled subtest complement bits become 3-bit port-dimm selector field
+ /// (Note: when turning this off, make sure you clear or reprogram complement bits)
+ /// @return void
+ ///
+ inline void change_maint_address_mode( const bool i_mode )
+ {
+ iv_addr_gen.writeBit<TT::MAINT_ADDR_MODE_EN>(i_mode);
+ return;
+ }
+
+ ///
+ /// @brief Enable or disable broadcast mode
+ /// @param[in] i_program the program in question
+ /// @param[in] i_mode mss::ON to enable
+ /// @warn Maint address mode must be enabled for this to work
+ /// @return void
+ ///
+ inline void change_maint_broadcast_mode( const bool i_mode )
+ {
+ broadcast_helper<TT::BROADCAST_CAPABLE>::change_maint_broadcast_mode(i_mode, iv_addr_gen);
+ return;
+ }
+
+
+ ///
+ /// @brief Enable or disable slave rank boundary detect
+ /// @param[in] i_program the program in question
+ /// @param[in] i_mode mss::ON to enable
+ /// @return void
+ ///
+ inline void change_srank_boundaries( const bool i_mode )
+ {
+ iv_addr_gen.writeBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>(i_mode);
+ return;
+ }
+
+ ///
+ /// @brief Enable or disable async mode
+ /// @param[in] i_program the program in question
+ /// @param[in] i_mode mss::ON to enable, programs will run async
+ /// @return void
+ ///
+ inline void change_async( const bool i_mode )
+ {
+ iv_async = i_mode;
+ return;
+ }
+
+ ///
+ /// @brief Select the port(s) to be used by the MCBIST
+ /// @param[in] i_ports uint64_t representing the ports. Multiple bits set imply broadcast
+ /// i_ports is a right-aligned uint64_t, of which only the right-most 4 bits are used. The register
+ /// field is defined such that the left-most bit in the field represents port 0, the right most
+ /// bit in the field represents port 3. So, to run on port 0, i_ports should be 0b1000. 0b0001
+ /// (or 0x1) is port 3 - not port 0
+ /// @return void
+ ///
+ inline void select_ports( const uint64_t i_ports )
+ {
+ if (TT::MULTI_PORTS == mss::states::YES)
+ {
+ iv_control.insertFromRight<TT::PORT_SEL, TT::PORT_SEL_LEN>(i_ports);
+ FAPI_INF("mcbist select ports: iv_control 0x%016lx (ports: 0x%x)", iv_control, i_ports);
+ }
+
+ return;
+ }
+
+ ///
+ /// @brief Process mcbist errors
+ /// @param[in] i_target the target for this program
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+ /// This shouldn't be called in firmware? Check with PRD
+ ///
+ inline fapi2::ReturnCode process_errors( const fapi2::Target<T> i_target ) const
+ {
+ // MCBIST error traits
+ using ET = mcbistMCTraits<MC>;
+
+ // Until reading the error array is documented, comparison errors 'just' result in
+ // a flag indicating there was a problem on port.
+ {
+ fapi2::buffer<uint64_t> l_data;
+ uint64_t l_port = 0;
+ uint64_t l_subtest = 0;
+ FAPI_TRY( fapi2::getScom(i_target, TT::MCBSTATQ_REG, l_data), "%s Failed getScom", mss::c_str(i_target) );
+
+ if (TT::MULTI_PORTS == mss::states::YES)
+ {
+ l_data.extractToRight<TT::LOGGED_ERROR_ON_PORT_INDICATOR, TT::LOGGED_ERROR_ON_PORT_INDICATOR_LEN>(l_port);
+ }
+
+ l_data.extractToRight<TT::SUBTEST_NUM_INDICATOR, TT::SUBTEST_NUM_INDICATOR_LEN>(l_subtest);
+
+ FAPI_ASSERT( l_port == 0,
+ ET::memdiags_compare_error_in_last_pattern()
+ .set_MC_TARGET(i_target)
+ .set_PORT(mss::first_bit_set(l_port))
+ .set_SUBTEST(l_subtest),
+ "%s MCBIST error on port %d subtest %d", mss::c_str(i_target), mss::first_bit_set(l_port), l_subtest );
+ }
+
+ // Check for UE errors
+ {
+ fapi2::buffer<uint64_t> l_read0;
+ fapi2::buffer<uint64_t> l_read1;
+
+ FAPI_TRY( fapi2::getScom(i_target, TT::SRERR0_REG, l_read0), "%s Failed getScom", mss::c_str(i_target) );
+ FAPI_TRY( fapi2::getScom(i_target, TT::SRERR1_REG, l_read1), "%s Failed getScom", mss::c_str(i_target) );
+
+ FAPI_ASSERT( ((l_read0 == 0) && (l_read1 == 0)),
+ ET::memdiags_error_in_last_pattern()
+ .set_MC_TARGET(i_target)
+ .set_STATUS0(l_read0)
+ .set_STATUS1(l_read1),
+ "%s MCBIST scrub/read error reg0: 0x%016lx reg1: 0x%016lx", mss::c_str(i_target), l_read0, l_read1 );
+ }
+
+ FAPI_INF("%s Execution success - no errors seen from MCBIST program", mss::c_str(i_target));
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Store off the pattern index. We'll use this to write the patterns when we load the program
+ /// @param[in] i_index an index such as mss::mcbist::PATTERN_0
+ /// @return fapi2::ReturnCode checks for bad pattern index
+ /// @warning if you give a pattern index which does not exist your pattern will not change.
+ /// @note patterns default to PATTERN_0
+ ///
+ inline fapi2::ReturnCode change_pattern( const uint64_t i_pattern )
+ {
+ FAPI_INF("change MCBIST pattern index %d", i_pattern);
+
+ // Sanity check the pattern since they're just numbers.
+ FAPI_ASSERT( i_pattern <= mcbist::NO_PATTERN,
+ fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().
+ set_INDEX(i_pattern).
+ set_MC_TYPE(MC),
+ "Attempting to change a pattern which does not exist %d", i_pattern );
+
+ iv_pattern = i_pattern;
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Store off the random 24b data seed index. We'll use this to write the 24b random data seeds when we load the program
+ /// @param[in] i_index an index such as mss::mcbist::RANDOM24_SEEDS_0
+ /// @return fapi2::ReturnCode checks for bad pattern index
+ /// @warning if you give a pattern index which does not exist your pattern will not change.
+ /// @note patterns default to PATTERN_0
+ ///
+ inline fapi2::ReturnCode change_random_24b_seeds( const uint64_t i_random24_seed )
+ {
+ FAPI_INF("change MCBIST 24b random data seeds index %d", i_random24_seed );
+
+ // TK Want a new RC for random 24
+ // Sanity check the pattern since they're just numbers.
+ FAPI_ASSERT( i_random24_seed <= mcbist::NO_RANDOM24_SEEDS,
+ fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().
+ set_INDEX(i_random24_seed).
+ set_MC_TYPE(MC),
+ "Attempting to change to a 24b random data seed which does not exist %d", i_random24_seed );
+
+ iv_random24_data_seed = i_random24_seed;
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Store off the random 24b data seed mapping index. We'll use this to write the 24b random data seed mappings when we load the program
+ /// @param[in] i_index an index such as mss::mcbist::RANDOM24_SEEDS_0
+ /// @return fapi2::ReturnCode checks for bad pattern index
+ /// @warning if you give a pattern index which does not exist your pattern will not change.
+ /// @note patterns default to PATTERN_0
+ ///
+ inline fapi2::ReturnCode change_random_24b_maps( const uint64_t i_random24_map )
+ {
+ FAPI_INF("change MCBIST 24b random data seed mappings index %d", i_random24_map );
+
+ // TK Want a new RC for random 24
+ // Sanity check the pattern since they're just numbers.
+ FAPI_ASSERT( i_random24_map <= mcbist::NO_RANDOM24_SEED_MAP,
+ fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().
+ set_INDEX(i_random24_map).
+ set_MC_TYPE(MC),
+ "Attempting to change to a random seed map which does not exist %d", i_random24_map );
+
+ iv_random24_seed_map = i_random24_map;
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief checks if two programs are equal
+ /// @param[in] i_rhs program to compare
+ /// @return bool true if equal
+ ///
+ inline bool operator==( const program<MC>& i_rhs ) const
+ {
+ //checks the vector first, to save time if they're not equal (no sense in checking everything else)
+ if(iv_subtests != i_rhs.iv_subtests)
+ {
+ return false;
+ }
+
+ //checks everything else
+ bool l_equal = iv_parameters == i_rhs.iv_parameters;
+ l_equal &= iv_addr_gen == i_rhs.iv_addr_gen;
+ l_equal &= iv_test_type == i_rhs.iv_test_type;
+ l_equal &= iv_poll == i_rhs.iv_poll;
+ l_equal &= iv_addr_map0 == i_rhs.iv_addr_map0;
+ l_equal &= iv_addr_map1 == i_rhs.iv_addr_map1;
+ l_equal &= iv_addr_map2 == i_rhs.iv_addr_map2;
+ l_equal &= iv_addr_map3 == i_rhs.iv_addr_map3;
+ l_equal &= iv_config == i_rhs.iv_config;
+ l_equal &= iv_control == i_rhs.iv_control;
+ l_equal &= iv_async == i_rhs.iv_async;
+ l_equal &= iv_pattern == i_rhs.iv_pattern;
+ l_equal &= iv_thresholds == i_rhs.iv_thresholds;
+ l_equal &= iv_data_rotate_cnfg == i_rhs.iv_data_rotate_cnfg;
+ l_equal &= iv_data_rotate_seed == i_rhs.iv_data_rotate_seed;
+ l_equal &= iv_random24_data_seed == i_rhs.iv_random24_data_seed;
+ l_equal &= iv_random24_seed_map == i_rhs.iv_random24_seed_map;
+ l_equal &= iv_data_rotate_cnfg == i_rhs.iv_data_rotate_cnfg;
+ l_equal &= iv_data_rotate_seed == i_rhs.iv_data_rotate_seed;
+ l_equal &= iv_compare_mask == i_rhs.iv_compare_mask;
+
+ //returns result
+ return l_equal;
+ }
+
+ // Vector of subtests. Note the MCBIST subtests are spread across
+ // 8 registers - 4 subtests fit in one 64b register
+ // (16 bits/test, 4 x 16 == 64, 4x8 = 32 subtests)
+ // We keep a vector of 16 bit subtests here, and we program the
+ // MCBIST engine (i.e., spread the subtests over the 8 registers)
+ // when we're told to execute the program.
+ std::vector< subtest_t<MC, T, TT> >iv_subtests;
+
+ // Place to hold the value of the MCBIST Memory Parameter Register. We'll scom
+ // it when we execute the program.
+ fapi2::buffer<uint64_t> iv_parameters;
+
+ // Place to hold the value of the MCBIST Address Generation Config. We'll scom
+ // it when we execute the program.
+ fapi2::buffer<uint64_t> iv_addr_gen;
+
+ test_type iv_test_type;
+
+ poll_parameters iv_poll;
+
+ // Address Map Registers
+ // We might want to refactor to a vector ... BRS
+ // uint64_t iv_addr_map0;
+ // uint64_t iv_addr_map1;
+ // uint64_t iv_addr_map2;
+ // uint64_t iv_addr_map3;
+ //Perhaps this isn't the right approach, we can discuss and change if needed, leaving the above comments for now
+ fapi2::buffer<uint64_t> iv_addr_map0;
+ fapi2::buffer<uint64_t> iv_addr_map1;
+ fapi2::buffer<uint64_t> iv_addr_map2;
+ fapi2::buffer<uint64_t> iv_addr_map3;
+
+ // Data Rotate Seed and Config Registers
+ fapi2::buffer<uint64_t> iv_data_rotate_cnfg;
+ fapi2::buffer<uint64_t> iv_data_rotate_seed;
+
+ // Config register
+ fapi2::buffer<uint64_t> iv_config;
+
+ // Control register
+ fapi2::buffer<uint64_t> iv_control;
+
+ // True iff we want to run in asynchronous mode
+ bool iv_async;
+
+ // The pattern for the pattern generator
+ uint64_t iv_pattern;
+
+ // The pattern for the random 24b seeds
+ uint64_t iv_random24_data_seed;
+
+ // The pattern for the random 24b data seed mapping
+ uint64_t iv_random24_seed_map;
+
+ // The pattern for the pattern generator
+ fapi2::buffer<uint64_t> iv_compare_mask;
+
+ // The error stop conditions, thresholds for the program
+ stop_conditions<MC> iv_thresholds;
+};
+
+///
+/// @brief Load the mcbist config register
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2::TargetType of the MCBIST engine
+/// @tparam TT the mssTraits associtated with T
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_config( const fapi2::Target<T>& i_target, const mcbist::program<MC>& i_program )
+{
+ FAPI_INF("%s loading MCBIST Config 0x%016lx", mss::c_str(i_target), i_program.iv_config);
+
+ // Copy the program's config settings - we want to modify them if we're in sim.
+ fapi2::buffer<uint64_t> l_config = i_program.iv_config;
+
+ // If we're running in Cronus, there is no interrupt so any attention bits will
+ // hang something somewhere. Make sure there's nothing in this config which can
+ // turn on attention bits unless we're running in hostboot
+#ifndef __HOSTBOOT_MODULE
+
+ if(TT::CFG_ENABLE_ATTN_SUPPORT == mss::states::YES)
+ {
+ l_config.template clearBit<TT::CFG_ENABLE_HOST_ATTN>();
+ l_config.template clearBit<TT::CFG_ENABLE_SPEC_ATTN>();
+ }
+
+#endif
+
+ FAPI_TRY( fapi2::putScom(i_target, TT::CFGQ_REG, l_config) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Load the mcbist control register
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_control( const fapi2::Target<T>& i_target, const mcbist::program<MC>& i_program )
+{
+ FAPI_INF("loading MCBIST Control 0x%016lx for %s", i_program.iv_control, mss::c_str(i_target));
+ return fapi2::putScom(i_target, TT::CNTLQ_REG, i_program.iv_control);
+}
+
+
+///
+/// @brief Load the address generator config
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_addr_gen( const fapi2::Target<T>& i_target, const mcbist::program<MC>& i_program )
+{
+ FAPI_INF("loading MCBIST Address Generation 0x%016lx for %s", i_program.iv_addr_gen, mss::c_str(i_target));
+ return fapi2::putScom(i_target, TT::MCBAGRAQ_REG, i_program.iv_addr_gen);
+}
+
+///
+/// @brief Configure address range based on index
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_start 64b right-aligned address
+/// @param[in] i_end 64b right-aligned address
+/// @param[in] i_index which start/end pair to effect
+/// @return FAPI2_RC_SUCCSS iff ok
+/// @note Only the right-most 37 bits of the start/end are used.
+/// @warn if address counting mode is enabled in the MCBIST program, these bits are start, len
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode config_address_range( const fapi2::Target<T>& i_target,
+ const uint64_t i_start,
+ const uint64_t i_end,
+ const uint64_t i_index )
+{
+ FAPI_INF("config MCBIST address range %d start: 0x%016lx (0x%016lx), end/len 0x%016lx (0x%016lx)",
+ i_index,
+ i_start, (i_start << mss::mcbist::address::MAGIC_PAD),
+ i_end, (i_end << mss::mcbist::address::MAGIC_PAD),
+ mss::c_str(i_target));
+ FAPI_ASSERT( i_index < TT::ADDRESS_PAIRS,
+ fapi2::MSS_MCBIST_INVALID_ADDRESS_PAIR_INDEX().
+ set_INDEX(i_index).
+ set_MC_TYPE(MC).
+ set_TARGET(i_target),
+ "An invalid address pair index %d for %s", i_index, mss::c_str(i_target));
+ FAPI_TRY( fapi2::putScom(i_target, TT::address_pairs[i_index].first, i_start << mss::mcbist::address::MAGIC_PAD) );
+ FAPI_TRY( fapi2::putScom(i_target, TT::address_pairs[i_index].second, i_end << mss::mcbist::address::MAGIC_PAD) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Configure address range 0
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_start 64b right-aligned address
+/// @param[in] i_end 64b right-aligned address
+/// @return FAPI2_RC_SUCCSS iff ok
+/// @note Only the right-most 37 bits of the start/end are used.
+/// @warn if address counting mode is enabled in the MCBIST program, these bits are start, len
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode config_address_range0( const fapi2::Target<T>& i_target,
+ const uint64_t i_start,
+ const uint64_t i_end )
+{
+ return config_address_range<MC>(i_target, i_start, i_end, 0);
+}
+
+
+///
+/// @brief Configure address range 1
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_start 64b right-aligned address
+/// @param[in] i_end 64b right-aligned address
+/// @return FAPI2_RC_SUCCSS iff ok
+/// @note Only the right-most 37 bits of the start/end are used.
+/// @warn if address counting mode is enabled in the MCBIST program, these bits are start, len
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode config_address_range1( const fapi2::Target<T>& i_target,
+ const uint64_t i_start,
+ const uint64_t i_end )
+{
+ return config_address_range<MC>(i_target, i_start, i_end, 1);
+}
+
+
+///
+/// @brief Configure address range 2
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_start 64b right-aligned address
+/// @param[in] i_end 64b right-aligned address
+/// @return FAPI2_RC_SUCCSS iff ok
+/// @note Only the right-most 37 bits of the start/end are used.
+/// @warn if address counting mode is enabled in the MCBIST program, these bits are start, len
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode config_address_range2( const fapi2::Target<T>& i_target,
+ const uint64_t i_start,
+ const uint64_t i_end )
+{
+ return config_address_range<MC>(i_target, i_start, i_end, 2);
+}
+
+
+///
+/// @brief Configure address range 3
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_start 64b right-aligned address
+/// @param[in] i_end 64b right-aligned address
+/// @return FAPI2_RC_SUCCSS iff ok
+/// @note Only the right-most 37 bits of the start/end are used.
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode config_address_range3( const fapi2::Target<T>& i_target,
+ const uint64_t i_start,
+ const uint64_t i_end )
+{
+ return config_address_range<MC>(i_target, i_start, i_end, 3);
+}
+
+///
+/// @brief Start or stop the MCBIST engine
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_start_stop bool START for starting, STOP otherwise
+/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode start_stop( const fapi2::Target<T>& i_target, const bool i_start_stop )
+{
+ // This is the same as the CCS start_stop ... perhaps we need one template for all
+ // 'engine' control functions? BRS
+ fapi2::buffer<uint64_t> l_buf;
+ FAPI_TRY(fapi2::getScom(i_target, TT::CNTLQ_REG, l_buf));
+
+ FAPI_TRY( fapi2::putScom(i_target, TT::CNTLQ_REG,
+ i_start_stop ? l_buf.setBit<TT::MCBIST_START>() : l_buf.setBit<TT::MCBIST_STOP>()) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Resume the MCBIST engine
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode resume( const fapi2::Target<T>& i_target )
+{
+ fapi2::buffer<uint64_t> l_buf;
+
+ FAPI_TRY( fapi2::getScom(i_target, TT::CNTLQ_REG, l_buf) );
+ FAPI_TRY( fapi2::putScom(i_target, TT::CNTLQ_REG, l_buf.setBit<TT::MCBIST_RESUME>()) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Reset the MCBIST error logs
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode reset_errors( const fapi2::Target<T>& i_target )
+{
+ fapi2::buffer<uint64_t> l_buf;
+
+ FAPI_TRY( fapi2::getScom(i_target, TT::CNTLQ_REG, l_buf) );
+ FAPI_TRY( fapi2::putScom(i_target, TT::CNTLQ_REG, l_buf.setBit<TT::MCBIST_RESET_ERRORS>()) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Return whether or not the MCBIST engine has an operation in progress
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[out] o_in_progress - false if no operation is in progress
+/// @return FAPI2_RC_SUCCESS if getScom succeeded
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode in_progress( const fapi2::Target<T>& i_target, bool& o_in_progress )
+{
+ fapi2::buffer<uint64_t> l_buf;
+
+ FAPI_TRY(fapi2::getScom(i_target, TT::STATQ_REG, l_buf));
+ o_in_progress = l_buf.getBit<TT::MCBIST_IN_PROGRESS>();
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Load a set of MCBIST subtests in to the MCBIST registers
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode load_mcbmr( const fapi2::Target<T>& i_target, const mcbist::program<MC>& i_program )
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // Leave if there are no subtests.
+ if (0 == i_program.iv_subtests.size())
+ {
+ FAPI_INF("no subtests, nothing to do for %s", mss::c_str(i_target));
+ return fapi2::current_err;
+ }
+
+ // List of the 8 MCBIST registers - each holds 4 subtests.
+ const std::vector< uint64_t > l_memory_registers =
+ {
+ TT::MCBMR0_REG, TT::MCBMR1_REG, TT::MCBMR2_REG, TT::MCBMR3_REG,
+ TT::MCBMR4_REG, TT::MCBMR5_REG, TT::MCBMR6_REG, TT::MCBMR7_REG,
+ };
+
+ std::vector< uint64_t > l_memory_register_buffers =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ };
+
+ ssize_t l_bin = -1;
+ size_t l_register_shift = 0;
+
+ // We'll shift this in to position to indicate which subtest is the last
+ const uint64_t l_done_bit( 0x8000000000000000 >> TT::DONE );
+
+ // For now limit MCBIST programs to 32 subtests.
+ const auto l_program_size = i_program.iv_subtests.size();
+ FAPI_ASSERT( l_program_size <= TT::SUBTEST_PER_PROGRAM,
+ fapi2::MSS_MCBIST_PROGRAM_TOO_BIG().
+ set_PROGRAM_LENGTH(l_program_size).
+ set_TARGET(i_target).
+ set_MC_TYPE(MC),
+ "mcbist program of length %d exceeds arbitrary maximum of %d", l_program_size, TT::SUBTEST_PER_PROGRAM );
+
+ // Distribute the program over the 8 MCBIST subtest registers
+ // We need the index, so increment thru i_program.iv_subtests.size()
+ for (size_t l_index = 0; l_index < l_program_size; ++l_index)
+ {
+ l_bin = (l_index % TT::SUBTEST_PER_REG) == 0 ? l_bin + 1 : l_bin;
+ l_register_shift = (l_index % TT::SUBTEST_PER_REG) * TT::BITS_IN_SUBTEST;
+
+ l_memory_register_buffers[l_bin] |=
+ (uint64_t(i_program.iv_subtests[l_index].iv_mcbmr) << TT::LEFT_SHIFT) >> l_register_shift;
+
+ FAPI_DBG("putting subtest %d (0x%x) in MCBMR%dQ shifted %d 0x%016llx",
+ l_index, i_program.iv_subtests[l_index].iv_mcbmr, l_bin,
+ l_register_shift, l_memory_register_buffers[l_bin]);
+ }
+
+ // l_bin and l_register_shift are the values for the last subtest we'll tell the MCBIST about.
+ // We need to set that subtest's done-bit so the MCBIST knows it's the end of the line
+ l_memory_register_buffers[l_bin] |= l_done_bit >> l_register_shift;
+ FAPI_DBG("setting MCBMR%dQ subtest %llu as the last subtest 0x%016llx",
+ l_bin, l_register_shift, l_memory_register_buffers[l_bin]);
+
+ // ... and slam the values in to the registers.
+ // Could just decrement l_bin, but that scoms the subtests in backwards and is confusing
+ for (auto l_index = 0; l_index <= l_bin; ++l_index)
+ {
+ FAPI_TRY( fapi2::putScom(i_target, l_memory_registers[l_index], l_memory_register_buffers[l_index]) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Load a set of MCBIST address map registers
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] the target to effect
+/// @param[in] the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode load_mcbamr( const fapi2::Target<T>& i_target, const mcbist::program<MC>& i_program )
+{
+ // Vector? Can decide when we fully understand the methods to twiddle the maps themselves. BRS
+ FAPI_INF("load MCBIST address map register 0: 0x%016lx for %s", i_program.iv_addr_map0, mss::c_str(i_target));
+ FAPI_TRY( fapi2::putScom(i_target, TT::MCBAMR0A0Q_REG, i_program.iv_addr_map0) );
+
+ FAPI_INF("load MCBIST address map register 1: 0x%016lx for %s", i_program.iv_addr_map1, mss::c_str(i_target));
+ FAPI_TRY( fapi2::putScom(i_target, TT::MCBAMR1A0Q_REG, i_program.iv_addr_map1) );
+
+ FAPI_INF("load MCBIST address map register 2: 0x%016lx for %s", i_program.iv_addr_map2, mss::c_str(i_target));
+ FAPI_TRY( fapi2::putScom(i_target, TT::MCBAMR2A0Q_REG, i_program.iv_addr_map2) );
+
+ FAPI_INF("load MCBIST address map register 3: 0x%016lx for %s", i_program.iv_addr_map3, mss::c_str(i_target));
+ FAPI_TRY( fapi2::putScom(i_target, TT::MCBAMR3A0Q_REG, i_program.iv_addr_map3) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Load MCBIST Memory Parameter Register
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] the target to effect
+/// @param[in] the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_mcbparm( const fapi2::Target<T>& i_target, const mcbist::program<MC>& i_program )
+{
+ FAPI_INF("load MCBIST parameter register: 0x%016lx for %s", i_program.iv_parameters, mss::c_str(i_target));
+ return fapi2::putScom(i_target, TT::MCBPARMQ_REG, i_program.iv_parameters);
+}
+
+///
+/// @brief Clear mcbist errors
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target fapi2::Target<T> of the MCBIST
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode clear_errors( const fapi2::Target<T> i_target )
+{
+ // TK: Clear the more detailed errors checked above
+ FAPI_INF("Clear MCBIST error state for %s", mss::c_str(i_target));
+ FAPI_TRY( fapi2::putScom(i_target, TT::MCBSTATQ_REG, 0) );
+ FAPI_TRY( fapi2::putScom(i_target, TT::SRERR0_REG, 0) );
+ FAPI_TRY( fapi2::putScom(i_target, TT::SRERR1_REG, 0) );
+ FAPI_TRY( fapi2::putScom(i_target, TT::FIRQ_REG, 0) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper for assembling the ecc/spare pattern
+/// @param[in] i_data the data pattern for a single beat
+/// @param[in] i_invert true if the data should be inverted
+/// @return The data pattern for this beat (a single byte of dataa)
+///
+inline uint8_t generate_eccspare_pattern_helper(const uint64_t& i_data, const bool i_invert )
+{
+ fapi2::buffer<uint64_t> l_data(i_invert ? ~i_data : i_data);
+ uint8_t l_byte = 0;
+ l_data.extractToRight<0, BITS_PER_BYTE>(l_byte);
+ return l_byte;
+}
+
+///
+/// @brief Generates the pattern for the ECC and/or spare data
+/// @param[in] i_pattern the pattern on which to operate
+/// @param[in] i_invert true if the pattern should be inverted
+/// @return ECC/spare pattern as needing to be put into the ECC/spare registers
+///
+inline fapi2::buffer<uint64_t> generate_eccspare_pattern(const pattern& i_pattern, const bool i_invert )
+{
+ constexpr uint64_t BYTE0 = BITS_PER_BYTE * 0;
+ constexpr uint64_t BYTE1 = BITS_PER_BYTE * 1;
+ constexpr uint64_t BYTE2 = BITS_PER_BYTE * 2;
+ constexpr uint64_t BYTE3 = BITS_PER_BYTE * 3;
+ constexpr uint64_t BYTE4 = BITS_PER_BYTE * 4;
+ constexpr uint64_t BYTE5 = BITS_PER_BYTE * 5;
+ constexpr uint64_t BYTE6 = BITS_PER_BYTE * 6;
+ constexpr uint64_t BYTE7 = BITS_PER_BYTE * 7;
+
+ fapi2::buffer<uint64_t> l_pattern;
+
+ // Pattern assembly is a tad weird for ECC/spare
+ // The pattern is stored in the same register by byte
+ // So we want to keep the same data as the rest of the data
+ // As such, we want to grab each piece of data on a byte by byte basis, flip as needed, and append it to the pattern
+
+ // Beat 0/1
+ l_pattern.insertFromRight<BYTE0, BITS_PER_BYTE>(generate_eccspare_pattern_helper(i_pattern[0].first, i_invert));
+ l_pattern.insertFromRight<BYTE1, BITS_PER_BYTE>(generate_eccspare_pattern_helper(i_pattern[0].second, i_invert));
+
+ // Beat 2/3
+ l_pattern.insertFromRight<BYTE2, BITS_PER_BYTE>(generate_eccspare_pattern_helper(i_pattern[1].first, i_invert));
+ l_pattern.insertFromRight<BYTE3, BITS_PER_BYTE>(generate_eccspare_pattern_helper(i_pattern[1].second, i_invert));
+
+ // Beat 4/5
+ l_pattern.insertFromRight<BYTE4, BITS_PER_BYTE>(generate_eccspare_pattern_helper(i_pattern[2].first, i_invert));
+ l_pattern.insertFromRight<BYTE5, BITS_PER_BYTE>(generate_eccspare_pattern_helper(i_pattern[2].second, i_invert));
+
+ // Beat 6/7
+ l_pattern.insertFromRight<BYTE6, BITS_PER_BYTE>(generate_eccspare_pattern_helper(i_pattern[3].first, i_invert));
+ l_pattern.insertFromRight<BYTE7, BITS_PER_BYTE>(generate_eccspare_pattern_helper(i_pattern[3].second, i_invert));
+
+ return l_pattern;
+}
+
+///
+/// @brief Load MCBIST ECC (and?) spare data pattern given a pattern
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_pattern an mcbist::patterns
+/// @param[in] i_invert whether to invert the pattern or not
+/// @note this overload disappears when we have real patterns.
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode load_eccspare_pattern( const fapi2::Target<T>& i_target, const pattern& i_pattern,
+ const bool i_invert );
+
+///
+/// @brief Load MCBIST pattern given a pattern
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_pattern an mcbist::patterns
+/// @param[in] i_invert whether to invert the pattern or not
+/// @note this overload disappears when we have real patterns.
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_pattern( const fapi2::Target<T>& i_target, const pattern& i_pattern, const bool i_invert )
+{
+ uint64_t l_address = TT::PATTERN0_REG;
+
+ // Checks that the pattern is of the expected length, if not, error out
+ // Creates helpers for FAPI_ASSERT
+ const auto EXPECTED_SIZE = TT::EXPECTED_PATTERN_SIZE;
+ const auto ACTUAL_SIZE = i_pattern.size();
+ FAPI_ASSERT(EXPECTED_SIZE == ACTUAL_SIZE,
+ fapi2::MSS_MCBIST_INCORRECT_PATTERN_LENGTH()
+ .set_TARGET(i_target)
+ .set_EXPECTED(EXPECTED_SIZE)
+ .set_ACTUAL(ACTUAL_SIZE),
+ "%s pattern expected size %u != actual size %u",
+ mss::c_str(i_target), EXPECTED_SIZE, ACTUAL_SIZE);
+
+ // TK: algorithm for patterns which include ECC bits in them
+ // Loop over the cache lines in the pattern. We write one half of the cache line
+ // to the even register and half to the odd.
+ for (const auto& l_cache_line : i_pattern)
+ {
+ const fapi2::buffer<uint64_t> l_value_first = i_invert ? ~l_cache_line.first : l_cache_line.first;
+ const fapi2::buffer<uint64_t> l_value_second = i_invert ? ~l_cache_line.second : l_cache_line.second;
+ FAPI_INF("Loading cache line pattern 0x%016lx 0x%016lx for %s", l_value_first, l_value_second, mss::c_str(i_target));
+ FAPI_TRY( fapi2::putScom(i_target, l_address, l_value_first) );
+ FAPI_TRY( fapi2::putScom(i_target, ++l_address, l_value_second) );
+ ++l_address;
+ }
+
+ FAPI_TRY(load_eccspare_pattern<MC>( i_target, i_pattern, i_invert ));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Check if patter is valid and get the index/invert
+/// @param[in] i_pattern the pattern
+/// @param[out] o_index the pattern index
+/// @param[out] o_invert if pattern is inverted
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+inline fapi2::ReturnCode get_pattern( uint64_t i_pattern, uint64_t& o_pattern_index, bool& o_invert)
+{
+ if (NO_PATTERN != i_pattern)
+ {
+ o_invert = false;
+
+ // Sanity check the pattern since they're just numbers.
+ // Belt-and-suspenders FAPI_ASSERT as the sim-only uses this API directly.
+ FAPI_ASSERT( i_pattern <= mcbist::LAST_PATTERN,
+ fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().
+ set_INDEX(i_pattern),
+ "Attempting to load a pattern which does not exist %d", i_pattern );
+
+ // The indexes are split in to even and odd where the odd indexes don't really exist.
+ // They're just indicating that we want to grab the even index and invert it. So calculate
+ // the proper vector index and acknowledge the inversion if necessary.
+ if (mss::is_odd(i_pattern))
+ {
+ o_invert = true;
+ i_pattern = i_pattern - 1;
+ }
+
+ o_pattern_index = i_pattern / 2;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Load MCBIST pattern given an index
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_index the pattern index
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_pattern( const fapi2::Target<T>& i_target, const uint64_t i_pattern )
+{
+ if (NO_PATTERN != i_pattern)
+ {
+ bool l_invert = false;
+ uint64_t l_pattern_index = 0;
+
+ FAPI_TRY(get_pattern(i_pattern, l_pattern_index, l_invert));
+ return load_pattern(i_target, patterns[l_pattern_index], l_invert);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Load MCBIST pattern given an index
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_pattern( const fapi2::Target<T>& i_target, const mcbist::program<MC>& i_program )
+{
+ return load_pattern(i_target, i_program.iv_pattern);
+}
+
+///
+/// @brief Load MCBIST maint pattern given a pattern
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @tparam MC the mc type of the T
+/// @param[in] i_target the target to effect
+/// @param[in] i_pattern an mcbist::patterns
+/// @param[in] i_invert whether to invert the pattern or not
+/// @note this overload disappears when we have real patterns.
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode load_maint_pattern( const fapi2::Target<T>& i_target, const pattern& i_pattern, const bool i_invert )
+{
+ // The scom registers are in the port target. PT: port traits
+ using PT = mcbistTraits<MC, TT::PORT_TYPE>;
+
+ // Init the fapi2 return code
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // Array access control
+ fapi2::buffer<uint64_t> l_aacr;
+ // Array access data
+ fapi2::buffer<uint64_t> l_aadr;
+
+ // first we must setup the access control register
+ // Setup the array address
+ // enable the auto increment bit
+ // set ecc mode bit on
+ l_aacr
+ .template writeBit<PT::RMW_WRT_BUFFER_SEL>(mss::states::OFF)
+ .template insertFromRight<PT::RMW_WRT_ADDRESS, PT::RMW_WRT_ADDRESS_LEN>(PT::MAINT_DATA_INDEX_START)
+ .template writeBit<PT::RMW_WRT_AUTOINC>(mss::states::ON)
+ .template writeBit<PT::RMW_WRT_ECCGEN>(mss::states::ON);
+
+ // This loop will be run twice to write the pattern twice. Once per 64B write.
+ // When MCBIST maint mode is in 64B mode it will only use the first 64B when in 128B mode
+ // MCBIST maint will use all 128B (it will perform two consecutive writes)
+ const auto l_ports = mss::find_targets<TT::PORT_TYPE>(i_target);
+ // Init the port map
+
+ for (const auto& p : l_ports)
+ {
+ l_aacr.template insertFromRight<PT::RMW_WRT_ADDRESS, PT::RMW_WRT_ADDRESS_LEN>(PT::MAINT_DATA_INDEX_START);
+
+ for (auto l_num_writes = 0; l_num_writes < 2; ++l_num_writes)
+ {
+ FAPI_INF("Setting the array access control register for %s.", mss::c_str(p));
+ FAPI_TRY( fapi2::putScom(p, PT::RMW_WRT_BUF_CTL_REG, l_aacr) );
+
+ for (const auto& l_cache_line : i_pattern)
+ {
+ fapi2::buffer<uint64_t> l_value_first = i_invert ? ~l_cache_line.first : l_cache_line.first;
+ fapi2::buffer<uint64_t> l_value_second = i_invert ? ~l_cache_line.second : l_cache_line.second;
+ FAPI_INF("Loading cache line pattern 0x%016lx 0x%016lx for %s", l_value_first, l_value_second, mss::c_str(i_target));
+ FAPI_TRY( fapi2::putScom(p, PT::RMW_WRT_BUF_DATA_REG, l_value_first));
+
+ // In order for the data to actually be written into the RMW buffer, we must issue a putscom to the MCA_AAER register
+ // This register is used for the ECC, we will just write all zero to this register. The ECC will be auto generated
+ // when the aacr MCA_WREITE_AACR_ECCGEN bit is set
+ FAPI_TRY( fapi2::putScom(p, PT::RMW_WRT_BUF_ECC_REG, 0) );
+
+ // No need to increment the address because the logic does it automatically when MCA_WREITE_AACR_AUTOINC is set
+ FAPI_TRY( fapi2::putScom(p, PT::RMW_WRT_BUF_DATA_REG, l_value_second) );
+
+ // In order for the data to actually be written into the RMW buffer, we must issue a putscom to the MCA_AAER register
+ // This register is used for the ECC, we will just write all zero to this register. The ECC will be auto generated
+ // when the aacr MCA_WREITE_AACR_ECCGEN bit is set
+ FAPI_TRY( fapi2::putScom(p, PT::RMW_WRT_BUF_ECC_REG, 0) );
+ }
+
+ l_aacr.template insertFromRight<PT::RMW_WRT_ADDRESS, PT::RMW_WRT_ADDRESS_LEN>(PT::MAINT_DATA_INDEX_END);
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+///
+/// @brief Load MCBIST maint pattern given an index
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_index the pattern index
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_maint_pattern( const fapi2::Target<T>& i_target, uint64_t i_pattern )
+{
+ if (NO_PATTERN != i_pattern)
+ {
+ bool l_invert = false;
+ uint64_t l_pattern_index = 0;
+
+ FAPI_TRY(get_pattern(i_pattern, l_pattern_index, l_invert));
+ return load_maint_pattern(i_target, patterns[l_pattern_index], l_invert);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Load MCBIST Maint mode pattern given an index
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_maint_pattern( const fapi2::Target<T>& i_target, const mcbist::program<MC>& i_program )
+{
+ return load_maint_pattern(i_target, i_program.iv_pattern);
+}
+
+
+///
+/// @brief Load MCBIST 24b random data seeds given a pattern index
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_random24_data_seed mcbist::random24_data_seed
+/// @param[in] i_random24_map mcbist::random24_seed_map
+/// @param[in] i_invert whether to invert the pattern or not
+/// @note this overload disappears when we have real patterns.
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode load_random24b_seeds( const fapi2::Target<T>& i_target,
+ const random24_data_seed& i_random24_data_seed,
+ const random24_seed_map& i_random24_map,
+ const bool i_invert )
+{
+ // Init the fapi2 return code
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ const uint64_t l_random_addr0 = TT::RANDOM_DATA_SEED0;
+ const uint64_t l_random_addr1 = TT::RANDOM_DATA_SEED1;
+ uint64_t l_index = 0;
+ uint64_t l_map_index = 0;
+ uint64_t l_map_offset = 0;
+
+ fapi2::buffer<uint64_t> l_mcbrsd0q;
+ fapi2::buffer<uint64_t> l_mcbrsd1q;
+
+
+ // We are going to loop through the random seeds and load them into the random seed registers
+ // Because the 24b random data seeds share the same registers as the 24b random data byte LFSR maps
+ // we will load those as well
+
+ for (const auto& l_seed : i_random24_data_seed)
+ {
+ FAPI_INF("Loading 24b random seed index %ld for %s", l_index, mss::c_str(i_target));
+ fapi2::buffer<uint64_t> l_value = i_invert ? ~l_seed : l_seed;
+
+ // Print an informational message to indicate if a random seed is 0
+ // TK Do we want an error here? 0 may be used on purpose to hold a byte at all 0 on purpose
+ if ( l_value == 0 )
+ {
+ FAPI_INF("Warning: Random 24b data seed is set to 0 for seed index %d for %s", l_index, mss::c_str(i_target));
+ }
+
+ // If we are processing the first 24b random data seed we will add it to the fapi buffer
+ // we won't load it yet because the second 24b seed will be loaded into the same register
+ if ( l_index == 0 )
+ {
+ l_mcbrsd0q.insertFromRight<TT::CFG_DGEN_RNDD_SEED0, TT::CFG_DGEN_RNDD_SEED0_LEN>(l_value);
+ }
+ // The second 24b random data seed is loaded into the same register as the first seed
+ // therefore we will add the second seed to the fapi buffer and then issue the putscom
+ else if (l_index == 1 )
+ {
+ l_mcbrsd0q.insertFromRight<TT::CFG_DGEN_RNDD_SEED1, TT::CFG_DGEN_RNDD_SEED1_LEN>(l_value);
+ FAPI_INF("Loading 24b random seeds 0 and 1 0x%016lx for %s", l_mcbrsd0q, mss::c_str(i_target));
+ FAPI_TRY( fapi2::putScom(i_target, l_random_addr0, l_mcbrsd0q) );
+ }
+ // The third 24b random data seed occupies the same register as the random data byte maps. Therefore we first
+ // add the third random 24b data seed to the register and then loop through all of the byte mappings a total of
+ // 9. ach of the byte mappings associates a byte of the random data to a byte in the 24b random data LFSRs
+ // Each byte map is offset by 4 bits in the register.
+ else
+ {
+ l_mcbrsd1q.insertFromRight<TT::CFG_DGEN_RNDD_SEED2, TT::CFG_DGEN_RNDD_SEED2_LEN>(l_value);
+
+ for (const auto& l_map : i_random24_map)
+ {
+ l_map_offset = TT::CFG_DGEN_RNDD_DATA_MAPPING + (l_map_index * RANDOM24_SEED_MAP_FIELD_LEN);
+ FAPI_TRY(l_mcbrsd1q.insertFromRight(l_map, l_map_offset, RANDOM24_SEED_MAP_FIELD_LEN));
+ FAPI_INF("Loading 24b random seed map index %ld for %s", l_map_index, mss::c_str(i_target));
+ FAPI_ASSERT( l_map_index < mss::mcbist::MAX_NUM_RANDOM24_MAPS,
+ fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().
+ set_INDEX(l_map_index).
+ set_MC_TYPE(MC),
+ "Attempting to load a 24b random data seed map which does not exist %d", l_map_index );
+ ++l_map_index;
+ }
+
+ FAPI_TRY( fapi2::putScom(i_target, l_random_addr1, l_mcbrsd1q) );
+ }
+
+ FAPI_ASSERT( l_index < MAX_NUM_RANDOM24_SEEDS,
+ fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().
+ set_INDEX(l_index).
+ set_MC_TYPE(MC),
+ "Attempting to load a 24b random data seed which does not exist %d", l_index );
+ ++l_index;
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+
+
+///
+/// @brief Load MCBIST 24b Random data seeds given a pattern index
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_data_seed the 24b random data seed index
+/// @param[in] i_seed_map the 24b random data map index
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_random24b_seeds( const fapi2::Target<T>& i_target, uint64_t i_data_seed,
+ uint64_t i_seed_map )
+{
+ if ((NO_RANDOM24_SEEDS != i_data_seed) && (NO_RANDOM24_SEED_MAP != i_seed_map))
+ {
+ bool l_invert = false;
+
+ // TK Want a new RC for random 24
+ // Sanity check the pattern since they're just numbers.
+ // Belt-and-suspenders FAPI_ASSERT as the sim-only uses this API directly.
+ FAPI_ASSERT( i_data_seed <= mcbist::LAST_RANDOM24_SEEDS,
+ fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().
+ set_INDEX(i_data_seed).
+ set_MC_TYPE(MC),
+ "Attempting to load a 24b random data seed set which does not exist %d", i_data_seed );
+
+ // The indexes are split in to even and odd where the odd indexes don't really exist.
+ // They're just indicating that we want to grab the even index and invert it. So calculate
+ // the proper vector index and acknowledge the inversion if necessary.
+ if ((i_data_seed % 2) != 0)
+ {
+ l_invert = true;
+ i_data_seed -= 1;
+ }
+
+ return load_random24b_seeds(i_target, random24_data_seeds[i_data_seed / 2], random24_seed_maps[i_seed_map], l_invert);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Load MCBIST 24b Random data seeds given a program conatining a pattern index
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_random24b_seeds( const fapi2::Target<T>& i_target, const mcbist::program<MC>& i_program )
+{
+ return load_random24b_seeds(i_target, i_program.iv_random24_data_seed, i_program.iv_random24_seed_map);
+}
+
+///
+/// @brief Loads the FIFO value if needed
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_fifo_mode( const fapi2::Target<T>& i_target, const mcbist::program<MC>& i_program )
+{
+ // Checks if FIFO mode is required by checking all subtests
+ const auto l_subtest_it = std::find_if(i_program.iv_subtests.begin(),
+ i_program.iv_subtests.end(), []( const mss::mcbist::subtest_t<MC, T, TT>& i_rhs) -> bool
+ {
+ return i_rhs.fifo_mode_required();
+ });
+
+ // if the FIFO load is not needed (no subtest requiring it was found), just exit out
+ if(l_subtest_it == i_program.iv_subtests.end())
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Turns on FIFO mode
+ constexpr mss::states FIFO_ON = mss::states::ON;
+
+ FAPI_TRY( configure_wrq(i_target, FIFO_ON) );
+ FAPI_TRY( configure_rrq(i_target, FIFO_ON) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Load MCBIST data patterns and configuration
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_data_config( const fapi2::Target<T>& i_target, const mcbist::program<MC>& i_program )
+{
+ // First load the data pattern registers
+ FAPI_INF("Loading the data pattern seeds for %s!", mss::c_str(i_target));
+ FAPI_TRY( mss::mcbist::load_pattern(i_target, i_program.iv_pattern) );
+
+ // Load the 24b random data pattern seeds registers
+ FAPI_INF("Loading the 24b Random data pattern seeds for %s!", mss::c_str(i_target));
+ FAPI_TRY( mss::mcbist::load_random24b_seeds(i_target, i_program.iv_random24_data_seed,
+ i_program.iv_random24_seed_map) );
+
+ // Load the maint data pattern into the Maint entry in the RMW buffer
+ // TK Might want to only load the RMW buffer if maint commands are present in the program
+ // The load takes 33 Putscoms to load 16 64B registers, might slow down mcbist programs that
+ // don't need the RMW buffer maint entry loaded
+ FAPI_INF("Loading the maint data pattern into the RMW buffer for %s!", mss::c_str(i_target));
+ FAPI_TRY( mss::mcbist::load_maint_pattern(i_target, i_program.iv_pattern) );
+
+ FAPI_INF("Loading the data rotate config and seeds for %s!", mss::c_str(i_target));
+ FAPI_TRY( fapi2::putScom(i_target, TT::DATA_ROTATE_CNFG_REG, i_program.iv_data_rotate_cnfg) );
+ FAPI_TRY( fapi2::putScom(i_target, TT::DATA_ROTATE_SEED_REG, i_program.iv_data_rotate_seed) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Load MCBIST data compare mask registers
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode load_data_compare_mask( const fapi2::Target<T>& i_target,
+ const mcbist::program<MC>& i_program )
+{
+ // Init the fapi2 return code
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // Load the MCBCM Data compare masks
+ const auto l_ports = mss::find_targets<TT::PORT_TYPE>(i_target);
+ FAPI_INF("Loading the MCBIST data compare mask registers!");
+
+ for (const auto& p : l_ports)
+ {
+ FAPI_TRY( fapi2::putScom(p, TT::COMPARE_MASK, i_program.iv_compare_mask) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Load MCBIST Thresholds
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_thresholds the thresholds
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_thresholds( const fapi2::Target<T>& i_target, const uint64_t i_thresholds )
+{
+ FAPI_INF("load MCBIST threshold register: 0x%016lx for %s", i_thresholds, mss::c_str(i_target) );
+ return fapi2::putScom(i_target, TT::THRESHOLD_REG, i_thresholds);
+}
+
+///
+/// @brief Load MCBIST Threshold Register
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType - derived
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the program containing the thresholds
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode load_thresholds( const fapi2::Target<T>& i_target, const mcbist::program<MC>& i_program )
+{
+ return load_thresholds(i_target, i_program.iv_thresholds);
+}
+
+///
+/// @brief Read entries from MCBIST Read Modify Write (RMW) array
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_start_addr the array address to read first
+/// @param[in] i_num_entries the number of array entries to read
+/// @param[in] i_roll_over_for_compare_mode set to true if only using first
+/// NUM_COMPARE_INFO_ENTRIES of array, so array address rolls over at correct value
+/// @param[out] o_data vector of output data
+/// @param[out] o_ecc_data vector of ecc data
+/// @return FAPI2_RC_SUCCSS iff ok
+/// @note The number of entries in the array depends on i_roll_over_for_compare_mode parameter:
+/// (NUM_COMPARE_LOG_ENTRIES for false, NUM_COMPARE_INFO_ENTRIES for true) but user may read more than
+/// that since reads work in a circular buffer fashion
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode read_rmw_array(const fapi2::Target<T>& i_target,
+ const uint64_t i_start_addr,
+ const uint64_t i_num_entries,
+ const bool i_roll_over_for_compare_mode,
+ std::vector< fapi2::buffer<uint64_t> >& o_data,
+ std::vector< fapi2::buffer<uint64_t> >& o_ecc_data)
+{
+ fapi2::buffer<uint64_t> l_control_value;
+ fapi2::buffer<uint64_t> l_data;
+ uint64_t l_array_addr = i_start_addr;
+
+ // Clear out any stale values from output vectors
+ o_data.clear();
+ o_ecc_data.clear();
+
+ // Set the control register for the RMW array
+ l_control_value.template writeBit<TT::RMW_WRT_BUFFER_SEL>(TT::SELECT_RMW_BUFFER)
+ // set start address
+ .template insertFromRight<TT::RMW_WRT_ADDRESS, TT::RMW_WRT_ADDRESS_LEN>(l_array_addr)
+ // enable the auto increment bit
+ .template setBit<TT::RMW_WRT_AUTOINC>()
+ // set ecc mode bit off
+ .template clearBit<TT::RMW_WRT_ECCGEN>();
+
+ FAPI_INF("Setting the RMW array access control register for %s.", mss::c_str(i_target));
+ FAPI_TRY( fapi2::putScom(i_target, TT::RMW_WRT_BUF_CTL_REG, l_control_value) );
+
+ for (uint8_t l_index = 0; l_index < i_num_entries; ++l_index)
+ {
+ // Read info out of RMW array and put into output vector
+ // Note that since we enabled AUTOINC above, reading ECC_REG will increment
+ // the array pointer so the next DATA_REG read will read the next array entry
+ FAPI_TRY( fapi2::getScom(i_target, TT::RMW_WRT_BUF_DATA_REG, l_data) );
+
+ FAPI_INF("RMW data index %d is: %016lx for %s", l_array_addr, l_data, mss::c_str(i_target));
+ o_data.push_back(l_data);
+
+ // Need to read ecc register to increment array index
+ FAPI_TRY( fapi2::getScom(i_target, TT::RMW_WRT_BUF_ECC_REG, l_data) );
+ o_ecc_data.push_back(l_data);
+ ++l_array_addr;
+
+ // Need to manually roll over address if we go beyond NUM_COMPARE_INFO_ENTRIES
+ // Since actual array is bigger than what is used for compare mode
+ if (i_roll_over_for_compare_mode &&
+ (l_array_addr >= TT::NUM_COMPARE_INFO_ENTRIES))
+ {
+ FAPI_INF("Rolling over the RMW array access control register address from %d to %d for %s.", (i_start_addr + l_index),
+ 0, mss::c_str(i_target));
+ l_control_value.clearBit<TT::RMW_WRT_ADDRESS, TT::RMW_WRT_ADDRESS_LEN>();
+ FAPI_TRY( fapi2::putScom(i_target, TT::RMW_WRT_BUF_CTL_REG, l_control_value) );
+ l_array_addr = 0;
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Read entries from MCBIST Read Modify Write (RMW) array
+/// Overload for the case where o_ecc_data is not needed
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_start_addr the array address to read first
+/// @param[in] i_num_entries the number of array entries to read
+/// @param[in] i_roll_over_for_compare_mode set to true if only using first
+/// NUM_COMPARE_INFO_ENTRIES of array, so array address rolls over at correct value
+/// @param[out] o_data vector of output data
+/// @return FAPI2_RC_SUCCSS iff ok
+/// @note The number of entries in the array depends on i_roll_over_for_compare_mode parameter:
+/// (NUM_COMPARE_LOG_ENTRIES for false, NUM_COMPARE_INFO_ENTRIES for true) but user may read more than
+/// that since reads work in a circular buffer fashion
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+inline fapi2::ReturnCode read_rmw_array(const fapi2::Target<T>& i_target,
+ const uint64_t i_start_addr,
+ const uint64_t i_num_entries,
+ const bool i_roll_over_for_compare_mode,
+ std::vector< fapi2::buffer<uint64_t> >& o_data)
+{
+ std::vector< fapi2::buffer<uint64_t> > l_temp;
+ return read_rmw_array(i_target, i_start_addr, i_num_entries, i_roll_over_for_compare_mode, o_data, l_temp);
+}
+
+///
+/// @brief Configures broadcast mode, if it is needed
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType
+/// @param[in] i_target the target to effect
+/// @param[in,out] io_program the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
+fapi2::ReturnCode configure_broadcast_mode(const fapi2::Target<T>& i_target, mcbist::program<MC>& io_program);
+
+///
+/// @brief Read entries from MCBIST Read Buffer (RB) array
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_start_addr the array address to read first
+/// @param[in] i_num_entries the number of array entries to read
+/// @param[out] o_data vector of output data
+/// @param[out] o_ecc_data vector of ecc data
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode read_rb_array(const fapi2::Target<T>& i_target,
+ const uint64_t i_start_addr,
+ const uint64_t i_num_entries,
+ std::vector< fapi2::buffer<uint64_t> >& o_data,
+ std::vector< fapi2::buffer<uint64_t> >& o_ecc_data);
+
+///
+/// @brief Read entries from MCBIST Read Buffer (RB) array
+/// Overload for the case where o_ecc_data is not needed
+/// @tparam MC the mc type of the T
+/// @tparam T, the fapi2::TargetType
+/// @tparam TT, the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_start_addr the array address to read first
+/// @param[in] i_num_entries the number of array entries to read
+/// @param[out] o_data vector of output data
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode read_rb_array(const fapi2::Target<T>& i_target,
+ const uint64_t i_start_addr,
+ const uint64_t i_num_entries,
+ std::vector< fapi2::buffer<uint64_t> >& o_data)
+{
+ std::vector< fapi2::buffer<uint64_t> > l_temp;
+ return read_rb_array<MC>(i_target, i_start_addr, i_num_entries, o_data, l_temp);
+}
+
+///
+/// @brief Poll the mcbist engine and check for errors
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_program, the mcbist program which is executing
+/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode poll( const fapi2::Target<T>& i_target, const program<MC>& i_program )
+{
+ using ET = mss::mcbistMCTraits<MC>;
+ fapi2::buffer<uint64_t> l_status;
+
+ const uint64_t l_done = fapi2::buffer<uint64_t>().setBit<TT::MCBIST_DONE>();
+ const uint64_t l_fail = fapi2::buffer<uint64_t>().setBit<TT::MCBIST_FAIL>();
+ const uint64_t l_in_progress = fapi2::buffer<uint64_t>().setBit<TT::MCBIST_IN_PROGRESS>();
+
+ // A small vector of addresses to poll during the polling loop
+ const std::vector<mss::poll_probe<T>> l_probes =
+ {
+ {i_target, "mcbist current address", TT::LAST_ADDR_REG},
+ };
+
+ mss::poll(i_target, TT::STATQ_REG, i_program.iv_poll,
+ [&l_status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
+ {
+ FAPI_DBG("mcbist statq 0x%016lx, remaining: %d", stat_reg, poll_remaining);
+ l_status = stat_reg;
+ return l_status.getBit<TT::MCBIST_IN_PROGRESS>() != 1;
+ },
+ l_probes);
+
+ // Check to see if we're still in progress - meaning we timed out.
+ FAPI_ASSERT((l_status & l_in_progress) != l_in_progress,
+ ET::mcbist_timeout().set_MC_TARGET(i_target),
+ "MCBIST timed out %s", mss::c_str(i_target));
+
+ // The control register has a bit for done-and-happy and a bit for done-and-unhappy
+ if ( ((l_status & l_done) == l_done) || ((l_status & l_fail) == l_fail) )
+ {
+ FAPI_INF("MCBIST completed, processing errors for %s", mss::c_str(i_target));
+
+ // We're done. It doesn't mean that there were no errors.
+ FAPI_TRY( i_program.process_errors(i_target) );
+
+ // If we're here there were no errors, but lets report if the fail bit was set anyway.
+ FAPI_ASSERT( (l_status & l_fail) != l_fail,
+ ET::mcbist_unknown_failure()
+ .set_MC_TARGET(i_target)
+ .set_STATUS_REGISTER(l_status),
+ "%s MCBIST reported a fail, but process_errors didn't find it 0x%016llx",
+ mss::c_str(i_target), l_status );
+
+ // And if we're here all is good with the world.
+ return fapi2::current_err;
+ }
+
+ FAPI_ASSERT(false,
+ ET::mcbist_data_fail()
+ .set_MC_TARGET(i_target)
+ .set_STATUS_REGISTER(l_status),
+ "%s MCBIST executed but we got corrupted data in the control register 0x%016llx",
+ mss::c_str(i_target), l_status );
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Clear the errors helper. Chip can specialise this
+/// function to put any necessary workaround in it.
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the mcbist program to execute
+/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode clear_error_helper( const fapi2::Target<T>& i_target, const program<MC>& i_program )
+{
+ FAPI_TRY( clear_errors(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Execute the mcbist program
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target to effect
+/// @param[in] i_program the mcbist program to execute
+/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T>, typename ET = mcbistMCTraits<MC> >
+fapi2::ReturnCode execute( const fapi2::Target<T>& i_target, const program<MC>& i_program )
+{
+ fapi2::buffer<uint64_t> l_status;
+ bool l_poll_result = false;
+ poll_parameters l_poll_parameters;
+
+ // Init the fapi2 return code
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // Before we go off into the bushes, lets see if there are any instructions in the
+ // program. If not, we can save everyone the hassle
+ FAPI_ASSERT(0 != i_program.iv_subtests.size(),
+ fapi2::MSS_MEMDIAGS_NO_MCBIST_SUBTESTS().set_MC_TARGET(i_target),
+ "Attempt to run an MCBIST program with no subtests on %s", mss::c_str(i_target));
+
+ FAPI_TRY( clear_error_helper<MC>(i_target, const_cast<program<MC>&>(i_program)) );
+
+ // Configures the write/read FIFO bit
+ FAPI_TRY( load_fifo_mode<MC>( i_target, i_program) );
+
+ // Slam the address generator config
+ FAPI_TRY( load_addr_gen<MC>(i_target, i_program) );
+
+ // Slam the parameters in to the mcbist parameter register
+ FAPI_TRY( load_mcbparm<MC>(i_target, i_program) );
+
+ // Slam the configured address maps down
+ FAPI_TRY( load_mcbamr( i_target, i_program) );
+
+ // Slam the config register down
+ FAPI_TRY( load_config<MC>( i_target, i_program) );
+
+ // Slam the control register down
+ FAPI_TRY( load_control<MC>( i_target, i_program) );
+
+ // Load the patterns and any associated bits for random, etc
+ FAPI_TRY( load_data_config<MC>( i_target, i_program) );
+
+ // Load the thresholds
+ FAPI_TRY( load_thresholds<MC>( i_target, i_program) );
+
+ // Slam the subtests in to the mcbist registers
+ // Always do this last so the action file triggers see the other bits set
+ FAPI_TRY( load_mcbmr<MC>(i_target, i_program) );
+
+ // Start the engine, and then poll for completion
+ FAPI_TRY(start_stop<MC>(i_target, mss::START));
+
+ // Verify that the in-progress bit has been set, so we know we started
+ // Don't use the program's poll as it could be a very long time. Use the default poll.
+ l_poll_result = mss::poll(i_target, TT::STATQ_REG, l_poll_parameters,
+ [&l_status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
+ {
+ FAPI_DBG("looking for mcbist start, mcbist statq 0x%llx, remaining: %d", stat_reg, poll_remaining);
+ l_status = stat_reg;
+ // We're done polling when either we see we're in progress or we see we're done.
+ return (l_status.getBit<TT::MCBIST_IN_PROGRESS>() == true) || (l_status.getBit<TT::MCBIST_DONE>() == true);
+ });
+
+ // So we've either run/are running or we timed out waiting for the start.
+ FAPI_ASSERT( l_poll_result == true,
+ ET::memdiags_failed_to_start().set_MC_TARGET(i_target),
+ "The MCBIST engine failed to start its program" );
+
+ // If the user asked for async mode, we can leave. Otherwise, poll and check for errors
+ if (!i_program.iv_async)
+ {
+ return mcbist::poll(i_target, i_program);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // namespace mcbist
+
+namespace ecc
+{
+
+///
+/// @brief Clear all MAINT.ECC counters
+/// @tparam T the fapi2::TargetType - derived
+/// @param[in] i_target the fapi2 target
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode clear_all_counters( const fapi2::Target<T>& i_target )
+{
+ return ( mss::mcbist::reset_errors(i_target) );
+}
+
+} // namespace ecc
+
+} // namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H
new file mode 100644
index 000000000..37e35c48d
--- /dev/null
+++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H
@@ -0,0 +1,441 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gen_mss_mcbist_address.H
+/// @brief Class for mcbist related addresses (addresses below the hash translation)
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _GEN_MSS_MCBIST_ADDRESS_H_
+#define _GEN_MSS_MCBIST_ADDRESS_H_
+
+#include <fapi2.H>
+#include <utility>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+
+namespace mss
+{
+
+namespace mcbist
+{
+
+///
+/// @class address
+/// @brief Represents a physical address in memory
+/// @note
+/// 0:1 port select
+/// 2 dimm select
+/// 3:4 mrank(0 to 1)
+/// 5:7 srank(0 to 2)
+/// 8:25 row(0 to 17)
+/// 26:32 col(3 to 9)
+/// 33:35 bank(0 to 2)
+/// 36:37 bank_group(0 to 1)
+///
+class address
+{
+ public:
+
+ // How far over we shift to align the address in either the register or a buffer
+ static constexpr uint64_t MAGIC_PAD = 26;
+
+ // first is the start bit of the field, second is the length
+ using field = std::pair<uint64_t, uint64_t>;
+
+ constexpr static field PORT = {0, 2};
+ constexpr static field DIMM = {2, 1};
+ constexpr static field MRANK = {3, 2};
+ constexpr static field SRANK = {5, 3};
+ constexpr static field ROW = {8, 18};
+ constexpr static field COL = {26, 7};
+ constexpr static field BANK = {33, 3};
+ constexpr static field BANK_GROUP = {36, 2};
+ constexpr static field LAST_VALID = BANK_GROUP;
+
+ ///
+ /// @brief default ctor
+ ///
+ address() = default;
+
+ // Used when accessing an integral value containing a port and DIMM combination
+ static constexpr uint64_t DIMM_BIT = 63;
+ static constexpr uint64_t PORT_START = 61;
+ static constexpr uint64_t PORT_LEN = 2;
+
+ ///
+ /// @brief Construct an address from a uint64_t
+ /// @param[in] i_value representing an address
+ ///
+ address( const uint64_t i_value ):
+ iv_address(i_value << MAGIC_PAD)
+ {
+ }
+
+ ///
+ /// @brief Construct an address from the provided buffer
+ /// @param[in] i_address fapi2::buffer address
+ ///
+ address(const fapi2::buffer<uint64_t>& i_address):
+ iv_address(i_address)
+ {
+ }
+
+ ///
+ /// @brief Conversion operator to uint64_t
+ /// @warn Right-aligns the address
+ ///
+ inline operator uint64_t() const
+ {
+ return iv_address >> MAGIC_PAD;
+ }
+
+ ///
+ /// @brief Set a field for an address
+ /// @tparam F the field to set
+ /// @param[in] i_value the value to set
+ /// @return address& for method chaining
+ ///
+ template< const field& F >
+ inline address& set_field( const uint64_t i_value )
+ {
+ iv_address.insertFromRight<F.first, F.second>(i_value);
+ return *this;
+ }
+
+ ///
+ /// @brief Get a field from an address
+ /// @tparam F the field to get
+ /// @return right-aligned uint64_t representing the value
+ ///
+ template< const field& F >
+ inline uint64_t get_field() const
+ {
+ uint64_t l_value = 0;
+ iv_address.extractToRight<F.first, F.second>(l_value);
+ return l_value;
+ }
+
+ ///
+ /// @brief Get a range of addresses.
+ /// @tparam[in] F the left-most valid field. So, if the address was for master rank,
+ /// the left-most valid field would be MRANK
+ /// @param[out] o_end representing an address to end at
+ /// @note this pointer is the start address
+ ///
+ template< const field& F >
+ inline void get_range( address& o_end ) const
+ {
+ constexpr uint64_t START = F.first + F.second;
+ constexpr uint64_t LEN = (LAST_VALID.first + LAST_VALID.second) - START;
+
+ // All we need to do is fill in the bits to the right of the last valid field
+ o_end.iv_address = iv_address;
+ o_end.iv_address.setBit<START, LEN>();
+ }
+
+
+ ///
+ /// @brief Get an end address for sim mode
+ /// @param[out] o_end representing an address to end at
+ /// @note this pointer is the start address
+ ///
+ inline void get_sim_end_address( address& o_end ) const
+ {
+ // This magic number represents a range of addresses which cover all
+ // cache lines the training algorithms touch. By effecting 0 - this end
+ // address you'll effect everything which has bad ECC in the sim.
+ // TODO: this will have to change for explorer. it's algorithm dependent.
+ // we'll need to talk to the microchip about this
+ constexpr uint64_t l_magic_sim_number = 0b1000000;
+
+ get_range<COL>(o_end);
+ o_end.set_column(l_magic_sim_number);
+ return;
+ }
+
+ ///
+ /// @brief Get a range of addresses given a master rank
+ /// @param[in] i_start representing an address to start from
+ /// @param[out] o_end representing an address to end at
+ ///
+ inline static void get_mrank_range( const address& i_start, address& o_end )
+ {
+ i_start.get_range<MRANK>(o_end);
+ }
+
+ ///
+ /// @brief Get a range of addresses given a master rank
+ /// @param[in] i_port representing the port for the starting address
+ /// @param[in] i_dimm representing the dimm for the starting address
+ /// @param[in] i_mrank representing the master rank for the starting address
+ /// @param[out] o_start representing an address to start from
+ /// @param[out] o_end representing an address to end at
+ ///
+ inline static void get_mrank_range( const uint64_t i_port,
+ const uint64_t i_dimm,
+ const uint64_t i_mrank,
+ address& o_start,
+ address& o_end )
+ {
+ o_start.set_port(i_port).set_dimm(i_dimm).set_master_rank(i_mrank);
+ get_mrank_range(o_start, o_end);
+ }
+
+ ///
+ /// @brief Get a range of addresses given a slave rank
+ /// @param[in] i_start representing an address to start from
+ /// @param[out] o_end representing an address to end at
+ ///
+ inline static void get_srank_range( const address& i_start, address& o_end )
+ {
+ i_start.get_range<SRANK>(o_end);
+ }
+
+ ///
+ /// @brief Get a range of addresses given a slave rank
+ /// @param[in] i_port representing the port for the starting address
+ /// @param[in] i_dimm representing the dimm for the starting address
+ /// @param[in] i_mrank representing the master rank for the starting address
+ /// @param[in] i_srank representing the slave rank for the starting address
+ /// @param[out] o_start representing an address to start from
+ /// @param[out] o_end representing an address to end at
+ ///
+ inline static void get_srank_range( const uint64_t i_port, const uint64_t i_dimm,
+ const uint64_t i_mrank, const uint64_t i_srank,
+ address& o_start,
+ address& o_end )
+ {
+ o_start.set_port(i_port).set_dimm(i_dimm).set_master_rank(i_mrank).set_slave_rank(i_srank);
+ get_srank_range(o_start, o_end);
+ }
+
+ ///
+ /// @brief Set the port value for an address
+ /// @param[in] i_value the value to set
+ /// @return address& for method chaining
+ ///
+ inline address& set_port( const uint64_t i_value )
+ {
+ return set_field<PORT>(i_value);
+ }
+
+ ///
+ /// @brief Get the port value for an address
+ /// @return right-aligned uint64_t representing the value
+ ///
+ inline uint64_t get_port() const
+ {
+ return get_field<PORT>();
+ }
+
+ ///
+ /// @brief Set the DIMM value for an address
+ /// @param[in] i_value the value to set
+ /// @note 0 is the DIMM[0] != 0 is DIMM[1]
+ /// @return address& for method chaining
+ ///
+ inline address& set_dimm( const uint64_t i_value )
+ {
+ return set_field<DIMM>(i_value);
+ }
+
+ ///
+ /// @brief Get the DIMM value for an address
+ /// @return right-aligned uint64_t representing the value
+ ///
+ inline uint64_t get_dimm() const
+ {
+ return get_field<DIMM>();
+ }
+
+ ///
+ /// @brief Set the port and DIMM value for an address
+ /// @param[in] i_value the value to set
+ /// @return address& for method chaining
+ /// @note Useful for indexing all ports/DIMM on a controller
+ ///
+ inline address& set_port_dimm( const fapi2::buffer<uint64_t> i_value )
+ {
+ uint64_t l_read_port = 0;
+
+ i_value.extractToRight<PORT_START, PORT_LEN>(l_read_port);
+ return set_dimm(i_value.getBit<DIMM_BIT>()).set_port(l_read_port);
+ }
+
+ ///
+ /// @brief Get the port and DIMM value for an address
+ /// @return right-aligned uint64_t representing the value
+ /// @note Useful for indexing all ports/DIMM on a controller
+ ///
+ inline uint64_t get_port_dimm() const
+ {
+ fapi2::buffer<uint64_t> l_value;
+
+ l_value.insertFromRight<PORT_START, PORT_LEN>(get_port());
+ l_value.writeBit<DIMM_BIT>(get_dimm());
+
+ return l_value;
+ }
+
+ ///
+ /// @brief Set the master rank value for an address
+ /// @param[in] i_value the value to set
+ /// @return address& for method chaining
+ ///
+ inline address& set_master_rank( const uint64_t i_value )
+ {
+ return set_field<MRANK>(i_value);
+ }
+
+ ///
+ /// @brief Get the master rank value for an address
+ /// @return right-aligned uint64_t representing the value
+ ///
+ inline uint64_t get_master_rank() const
+ {
+ return get_field<MRANK>();
+ }
+
+
+ ///
+ /// @brief Set the slave rank value for an address
+ /// @param[in] i_value the value to set
+ ///
+ inline void set_slave_rank( const uint64_t i_value )
+ {
+ set_field<SRANK>(i_value);
+ }
+
+ ///
+ /// @brief Get the slave rank value for an address
+ /// @return right-aligned uint64_t representing the value
+ ///
+ inline uint64_t get_slave_rank() const
+ {
+ return get_field<SRANK>();
+ }
+
+
+ ///
+ /// @brief Set the row value for an address
+ /// @param[in] i_value the value to set
+ /// @return address& for method chaining
+ ///
+ inline address& set_row( const uint64_t i_value )
+ {
+ return set_field<ROW>(i_value);
+ }
+
+ ///
+ /// @brief Get the row value for an address
+ /// @return right-aligned uint64_t representing the value
+ ///
+ inline uint64_t get_row() const
+ {
+ return get_field<ROW>();
+ }
+
+
+ ///
+ /// @brief Set the column value for an address
+ /// @param[in] i_value the value to set
+ /// @return address& for method chaining
+ ///
+ inline address& set_column( const uint64_t i_value )
+ {
+ return set_field<COL>(i_value);
+ }
+
+ ///
+ /// @brief Get the column value for an address
+ /// @return right-aligned uint64_t representing the value
+ ///
+ inline uint64_t get_column() const
+ {
+ return get_field<COL>();
+ }
+
+
+ ///
+ /// @brief Set the bank value for an address
+ /// @param[in] i_value the value to set
+ /// @return address& for method chaining
+ ///
+ inline address& set_bank( const uint64_t i_value )
+ {
+ return set_field<BANK>(i_value);
+ }
+
+ ///
+ /// @brief Get the bank value for an address
+ /// @return right-aligned uint64_t representing the value
+ ///
+ inline uint64_t get_bank() const
+ {
+ return get_field<BANK>();
+ }
+
+ ///
+ /// @brief Set the bank group value for an address
+ /// @param[in] i_value the value to set
+ /// @return address& for method chaining
+ ///
+ inline address& set_bank_group( const uint64_t i_value )
+ {
+ return set_field<BANK_GROUP>(i_value);
+ }
+
+ ///
+ /// @brief Get the bank group value for an address
+ /// @return right-aligned uint64_t representing the value
+ ///
+ inline uint64_t get_bank_group() const
+ {
+ return get_field<BANK_GROUP>();
+ }
+
+ ///
+ /// @brief Get the buffer object for bit operations
+ /// @return fapi2::buffer<uint64_t>&
+ ///
+ inline fapi2::buffer<uint64_t> get_address_buffer() const
+ {
+ return iv_address;
+ }
+
+ private:
+ // We use a fapi2 buffer as it has static compile-time support
+ fapi2::buffer<uint64_t> iv_address;
+};
+
+} // close namespace mcbist
+} // close namespace mss
+
+#endif
diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_ecc_trap_address.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_ecc_trap_address.H
new file mode 100644
index 000000000..ba8b1f47b
--- /dev/null
+++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_ecc_trap_address.H
@@ -0,0 +1,176 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_ecc_trap_address.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gen_mss_mcbist_ecc_trap_address.H
+/// @brief Class for ECC trap addresses (addresses below the hash translation)
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _GEN_MSS_MCBIST_ECC_TRAP_ADDRESS_H_
+#define _GEN_MSS_MCBIST_ECC_TRAP_ADDRESS_H_
+
+#include <fapi2.H>
+#include <utility>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+///
+/// @class trap_address
+/// @brief Converts trap address into mcbist::address
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2 Target Type defaults to fapi2::TARGET_TYPE_MCA or TARGET_TYPE_MEM_PORT
+/// @tparam TT traits type defaults to eccTraits<T>
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::FWMS_ADDR_TARGET_TYPE, typename TT = mss::eccTraits<MC, T> >
+class trap_address
+{
+ public:
+ // first is the start bit of the field, second is the length
+ using field = std::pair<uint64_t, uint64_t>;
+
+ constexpr static field PORT = {TT::TRAP_ADDRESS_PORT, TT::TRAP_ADDRESS_PORT_LEN};
+ constexpr static field DIMM = {TT::TRAP_ADDRESS_DIMM, TT::TRAP_ADDRESS_DIMM_LEN};
+ constexpr static field MRANK = {TT::TRAP_ADDRESS_MRANK, TT::TRAP_ADDRESS_MRANK_LEN};
+ constexpr static field SRANK = {TT::TRAP_ADDRESS_SRANK, TT::TRAP_ADDRESS_SRANK_LEN};
+ constexpr static field ROW = {TT::TRAP_ADDRESS_ROW, TT::TRAP_ADDRESS_ROW_LEN};
+ constexpr static field COL = {TT::TRAP_ADDRESS_COL, TT::TRAP_ADDRESS_COL_LEN};
+ constexpr static field BANK = {TT::TRAP_ADDRESS_BANK, TT::TRAP_ADDRESS_BANK_LEN};
+ constexpr static field BANK_GROUP = {TT::TRAP_ADDRESS_BANK_GROUP, TT::TRAP_ADDRESS_BANK_GROUP_LEN};
+
+ trap_address() = default;
+
+ ///
+ /// @brief Construct an address from a uint64_t (scom'ed value)
+ /// @param[in] i_value representing raw value from FWMS register
+ ///
+ trap_address( const uint64_t& i_value ):
+ iv_value(i_value)
+ {
+ }
+
+ ///
+ /// @brief Construct an address from an mcbist::address
+ /// @param[in] i_mcbist_address mcbist formatted address
+ /// @note Construction of mcbist::address from trap_address
+ /// @note located in mcbist::address class
+ ///
+ trap_address( const mcbist::address& i_mcbist_address )
+ {
+ iv_value.insertFromRight<PORT.first, PORT.second>(i_mcbist_address.get_field<mcbist::address::PORT>());
+ iv_value.insertFromRight<DIMM.first, DIMM.second>(i_mcbist_address.get_field<mcbist::address::DIMM>());
+ iv_value.insertFromRight<MRANK.first, MRANK.second>(i_mcbist_address.get_field<mcbist::address::MRANK>());
+ iv_value.insertFromRight<SRANK.first, SRANK.second>(i_mcbist_address.get_field<mcbist::address::SRANK>());
+ iv_value.insertFromRight<ROW.first, ROW.second>(i_mcbist_address.get_field<mcbist::address::ROW>());
+ iv_value.insertFromRight<COL.first, COL.second>(i_mcbist_address.get_field<mcbist::address::COL>());
+ iv_value.insertFromRight<BANK.first, BANK.second>(i_mcbist_address.get_field<mcbist::address::BANK>());
+ iv_value.insertFromRight<BANK_GROUP.first, BANK_GROUP.second>
+ (i_mcbist_address.get_field<mcbist::address::BANK_GROUP>());
+ }
+
+ ///
+ /// @brief Construct an mcbist::address from an ecc::trap_address
+ /// @return the mcbist::address
+ ///
+ inline operator mss::mcbist::address() const
+ {
+ mss::mcbist::address l_mcbist_address;
+ l_mcbist_address.set_port (this->get_field<PORT>());
+ l_mcbist_address.set_dimm (this->get_field<DIMM>());
+ l_mcbist_address.set_master_rank(this->get_field<MRANK>());
+ l_mcbist_address.set_slave_rank (this->get_field<SRANK>());
+ l_mcbist_address.set_row (this->get_field<ROW>());
+ l_mcbist_address.set_column (this->get_field<COL>());
+ l_mcbist_address.set_bank (this->get_field<BANK>());
+ l_mcbist_address.set_bank_group (this->get_field<BANK_GROUP>());
+ return l_mcbist_address;
+ }
+
+ ///
+ /// @brief Conversion operator to uint64_t
+ ///
+ inline operator uint64_t() const
+ {
+ uint64_t l_temp = 0;
+ iv_value.extract<TT::TRAP_ADDRESS, TT::TRAP_ADDRESS_LEN, TT::TRAP_ADDRESS>(l_temp);
+ return l_temp;
+ }
+
+ ///
+ /// @brief Get a field from an address
+ /// @tparam F the field to get
+ /// @return right-aligned uint64_t representing the value
+ ///
+ template< const field& F >
+ inline uint64_t get_field() const
+ {
+ uint64_t l_value = 0;
+ iv_value.extractToRight<F.first, F.second>(l_value);
+ return l_value;
+ }
+
+ private:
+ fapi2::buffer<uint64_t> iv_value;
+};
+
+template< mss::mc_type MC, fapi2::TargetType T , typename TT >
+constexpr typename trap_address<MC, T, TT>::field trap_address<MC, T, TT>::PORT;
+
+template< mss::mc_type MC, fapi2::TargetType T , typename TT >
+constexpr typename trap_address<MC, T, TT>::field trap_address<MC, T, TT>::DIMM;
+
+template< mss::mc_type MC, fapi2::TargetType T , typename TT >
+constexpr typename trap_address<MC, T, TT>::field trap_address<MC, T, TT>::MRANK;
+
+template< mss::mc_type MC, fapi2::TargetType T , typename TT >
+constexpr typename trap_address<MC, T, TT>::field trap_address<MC, T, TT>::SRANK;
+
+template< mss::mc_type MC, fapi2::TargetType T , typename TT >
+constexpr typename trap_address<MC, T, TT>::field trap_address<MC, T, TT>::ROW;
+
+template< mss::mc_type MC, fapi2::TargetType T , typename TT >
+constexpr typename trap_address<MC, T, TT>::field trap_address<MC, T, TT>::COL;
+
+template< mss::mc_type MC, fapi2::TargetType T , typename TT >
+constexpr typename trap_address<MC, T, TT>::field trap_address<MC, T, TT>::BANK;
+
+template< mss::mc_type MC, fapi2::TargetType T , typename TT >
+constexpr typename trap_address<MC, T, TT>::field trap_address<MC, T, TT>::BANK_GROUP;
+
+
+} // close namespace ecc
+} // close namespace mss
+#endif
diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_fwms_address.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_fwms_address.H
new file mode 100644
index 000000000..2b1bda8fe
--- /dev/null
+++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_fwms_address.H
@@ -0,0 +1,175 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_fwms_address.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gen_mss_mcbist_fwms_address.H
+/// @brief Class for FWMS trap addresses (addresses below the hash translation)
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _GEN_MSS_MCBIST_FWMS_ADDRESS_H_
+#define _GEN_MSS_MCBIST_FWMS_ADDRESS_H_
+
+#include <fapi2.H>
+#include <utility>
+#include <generic/memory/lib/ecc/ecc_traits.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H>
+
+namespace mss
+{
+
+namespace ecc
+{
+
+namespace fwms
+{
+
+///
+/// @class address
+/// @brief Converts Firmware Mark Store ADDRESS field into mcbist::address
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2 Target Type defaults to fapi2::TARGET_TYPE_MCA or TARGET_TYPE_MEM_PORT
+/// @tparam TT traits type defaults to eccTraits<MC, T>
+/// @note template argument defaults are in forward declaration in lib/mcbist/address.H
+/// @note 12 = dimm
+/// @note 13:14 = mrank
+/// @note 15:17 = srank
+/// @note 18:19 = bank group
+/// @note 20:22 = bank
+///
+// See declaration below
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::FWMS_ADDR_TARGET_TYPE, typename TT = mss::eccTraits<MC, T> >
+class address
+{
+ public:
+ // first is the start bit of the field, second is the length
+ using field = std::pair<uint64_t, uint64_t>;
+
+ constexpr static field DIMM = {TT::FIRMWARE_MS_ADDRESS, 1};
+ constexpr static field MRANK = {TT::FIRMWARE_MS_ADDRESS + 1, 2};
+ constexpr static field SRANK = {TT::FIRMWARE_MS_ADDRESS + 3, 3};
+ constexpr static field BANK_GROUP = {TT::FIRMWARE_MS_ADDRESS + 6, 2};
+ constexpr static field BANK = {TT::FIRMWARE_MS_ADDRESS + 8, 3};
+
+ address() = default;
+
+ ///
+ /// @brief Construct an address from a uint64_t (scom'ed value)
+ /// @param[in] i_value representing raw value from FWMS register
+ ///
+ address( const uint64_t& i_value ):
+ iv_value(i_value)
+ {
+ }
+
+ ///
+ /// @brief Construct an address from an mcbist::address
+ /// @param[in] i_mcbist_address mcbist formatted address
+ /// @note Construction of mcbist::address from address
+ /// @note located in mcbist::address class
+ ///
+ address( const mss::mcbist::address& i_mcbist_address )
+ {
+ iv_value.insertFromRight<DIMM.first, DIMM.second>(i_mcbist_address.get_dimm());
+ iv_value.insertFromRight<MRANK.first, MRANK.second>(i_mcbist_address.get_master_rank());
+ iv_value.insertFromRight<SRANK.first, SRANK.second>(i_mcbist_address.get_slave_rank());
+ iv_value.insertFromRight<BANK_GROUP.first, BANK_GROUP.second>(i_mcbist_address.get_bank_group());
+ iv_value.insertFromRight<BANK.first, BANK.second>(i_mcbist_address.get_bank());
+ }
+
+ ///
+ /// @brief Construct an address from an ecc::fwms::address
+ /// @tparam MC the mc type
+ /// @param[in] i_address representing an address field from a firmware mark store register
+ ///
+
+ ///
+ /// @brief Construct an mcbist::address from an ecc::fwms::address
+ /// @return the mcbist::address
+ ///
+ inline operator mss::mcbist::address() const
+ {
+ mss::mcbist::address l_mcbist_address;
+ l_mcbist_address.set_dimm (this->get_field<DIMM>());
+ l_mcbist_address.set_master_rank(this->get_field<MRANK>());
+ l_mcbist_address.set_slave_rank (this->get_field<SRANK>());
+ l_mcbist_address.set_bank_group (this->get_field<BANK_GROUP>());
+ l_mcbist_address.set_bank (this->get_field<BANK>());
+ return l_mcbist_address;
+ }
+
+ ///
+ /// @brief Conversion operator to uint64_t
+ ///
+ inline operator uint64_t() const
+ {
+ uint64_t l_temp = 0;
+ iv_value.extract<TT::FIRMWARE_MS_ADDRESS, TT::FIRMWARE_MS_ADDRESS_LEN, TT::FIRMWARE_MS_ADDRESS>(l_temp);
+ return l_temp;
+ }
+
+ ///
+ /// @brief Get a field from an address
+ /// @tparam F the field to get
+ /// @return right-aligned uint64_t representing the value
+ ///
+ template< const field& F >
+ inline uint64_t get_field() const
+ {
+ uint64_t l_value = 0;
+ iv_value.extractToRight<F.first, F.second>(l_value);
+ return l_value;
+ }
+
+ private:
+ fapi2::buffer<uint64_t> iv_value;
+
+};
+
+template< mss::mc_type MC, fapi2::TargetType T , typename TT >
+constexpr typename address<MC, T, TT>::field address<MC, T, TT>::DIMM;
+
+template< mss::mc_type MC, fapi2::TargetType T , typename TT >
+constexpr typename address<MC, T, TT>::field address<MC, T, TT>::MRANK;
+
+template< mss::mc_type MC, fapi2::TargetType T , typename TT >
+constexpr typename address<MC, T, TT>::field address<MC, T, TT>::SRANK;
+
+template< mss::mc_type MC, fapi2::TargetType T , typename TT >
+constexpr typename address<MC, T, TT>::field address<MC, T, TT>::BANK_GROUP;
+
+template< mss::mc_type MC, fapi2::TargetType T , typename TT >
+constexpr typename address<MC, T, TT>::field address<MC, T, TT>::BANK;
+
+
+} // close namespace fwms
+} // close namespace ecc
+} // close namespace mss
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.C b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.C
index ef65e381a..81988c3d9 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.C
+++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.C
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.C $ */
+/* $Source: src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.C $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -23,19 +23,20 @@
/* */
/* IBM_PROLOG_END_TAG */
+
///
-/// @file patterns.C
+/// @file gen_mss_mcbist_patterns.C
/// @brief Static definition of MCBIST patterns
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP HWP Backup: Marc Gollub <gollub@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
#include <fapi2.H>
#include <vector>
-#include <lib/mcbist/patterns.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H>
namespace mss
{
@@ -141,6 +142,5 @@ const std::vector< random24_seed_map > random24_seed_maps =
};
-}
-
-}
+} //namespace mcbist
+} //namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H
index b5faeeffd..cfb4a532d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.H
+++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.H $ */
+/* $Source: src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -24,17 +24,17 @@
/* IBM_PROLOG_END_TAG */
///
-/// @file patterns.H
+/// @file gen_mss_mcbist_patterns.H
/// @brief Static definition of MCBIST patterns
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP HWP Backup: Marc Gollub <gollub@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
-#ifndef _MSS_MCBIST_PATTERNS_
-#define _MSS_MCBIST_PATTERNS_
+#ifndef _MSS_GEN_MCBIST_PATTERNS_
+#define _MSS_GEN_MCBIST_PATTERNS_
#include <vector>
@@ -85,20 +85,19 @@ constexpr uint64_t RANDOM24_SEED_MAP_FIELD_LEN = 4;
/// Vector of cache lines, separated in to two 64B chunks
-typedef std::pair<uint64_t, uint64_t> cache_line;
-typedef std::vector< cache_line > pattern;
+using cache_line = std::pair<uint64_t, uint64_t> ;
+using pattern = std::vector< cache_line > ;
extern const std::vector< pattern > patterns;
// Vector of 24b random data seeds
-typedef std::vector< uint64_t > random24_data_seed;
+using random24_data_seed = std::vector< uint64_t > ;
extern const std::vector< random24_data_seed > random24_data_seeds;
// Vector of 24b random data seed maps
-typedef std::vector< uint64_t > random24_seed_map;
+using random24_seed_map = std::vector< uint64_t >;
extern const std::vector< random24_seed_map > random24_seed_maps;
}// mcbist
}// mss
#endif
-
diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H
new file mode 100644
index 000000000..6f570fbad
--- /dev/null
+++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H
@@ -0,0 +1,815 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gen_mss_mcbist_settings.H
+/// @brief MCBIST settings, like stop conditions, thresholds, etc
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _GEN_MSS_MCBIST_SETTINGS_H_
+#define _GEN_MSS_MCBIST_SETTINGS_H_
+
+#include <fapi2.H>
+
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/bit_count.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H>
+
+namespace mss
+{
+
+namespace mcbist
+{
+///
+/// @brief End boundaries for MCBIST programs - where to stop when stopping or pausing
+///
+enum end_boundary : uint64_t
+{
+ // We're gonna get a little hacky here. The pause on error mode field
+ // is two bits, with another bit representing slave/master. So we craft
+ // the enum so that we can insertFromRight and get the proper vaules, and
+ // leave one bit out of that two-bit range to represent master or slave
+ NONE = 0b000,
+ STOP_AFTER_ADDRESS = 0b001,
+ STOP_AFTER_MASTER_RANK = 0b010,
+ STOP_AFTER_SLAVE_RANK = 0b110,
+ STOP_AFTER_SUBTEST = 0b011,
+
+ DONT_CHANGE = 0xFF,
+};
+
+///
+/// @brief Speeds for performing MCBIST operations
+///
+enum speed
+{
+ /// As fast as possible, often the default
+ LUDICROUS = 0,
+
+ /// Background scrubbing speed.
+ BG_SCRUB = 1,
+
+ /// Used to indicate to the continue current command to not change the speed of the commands
+ SAME_SPEED = 4,
+};
+
+///
+/// @class Memory diagnostic subsystem stop-on-error settings and thresholds
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @note Matches Nimbus MBSTRQ, but might be changed later for Centaur, or mapped.
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE , typename TT = mss::mcbistTraits<MC, T> >
+class stop_conditions
+{
+ public:
+
+ // Many of the config fields share a disable bit pattern, so we define it here
+ static constexpr uint64_t DISABLE = 0b1111;
+ static constexpr uint64_t MAX_THRESHOLD = 0b1110;
+ static constexpr uint64_t DONT_CHANGE = 0;
+
+ private:
+
+ ///
+ /// @brief Little helper to convert threshold inputs to exponents
+ /// @param[in] i_value, the value of the threshold (presumably)
+ /// @return a value n such that 2^n <= i_value && n < 15
+ ///
+ uint64_t make_threshold_setting( const uint64_t i_value )
+ {
+ // If the user passes in DISABLE, let it past. This prevents callers from having to
+ // do the conditional. Zero is none which is disable
+ if ((i_value == DISABLE) || (i_value == 0))
+ {
+ return DISABLE;
+ }
+
+ // Find the first bit set. This represents the largest power of 2 this input can represent
+ // The subtraction from 63 switches from a left-count to a right-count (e.g., 0 (left most
+ // bit) is really bit 63 if you start on the right.)
+ const uint64_t l_largest = 63 - first_bit_set(i_value);
+
+ // If the first bit set is off in space and greater than 2^14, we just return 0b1110
+ // Otherwise, l_largest is the droid we're looking for
+ return l_largest >= MAX_THRESHOLD ? MAX_THRESHOLD : l_largest;
+ }
+
+ ///
+ /// @brief Generic pause on threshold
+ /// @tparam F, the bit field to manipulate
+ /// @tparam L, the length of F
+ /// @param[in] the state of the error - mss::ON or mss::OFF
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ template< uint64_t F, uint64_t L >
+ inline stop_conditions<MC, T, TT>& set_pause_on_threshold( const states i_on_or_off )
+ {
+ if (i_on_or_off == mss::OFF)
+ {
+ iv_value.insertFromRight<F, L>(DISABLE);
+ return *this;
+ }
+
+ uint64_t l_thresh = 0;
+ iv_value.extractToRight<F, L>(l_thresh);
+
+ if (l_thresh == DISABLE)
+ {
+ // Note the threshold field is an exponent, so this is 2^0, or 1 count
+ iv_value.insertFromRight<F, L>(0);
+ }
+
+ return *this;
+ }
+
+ public:
+ ///
+ /// @brief Stop/Thresholds class ctor
+ ///
+ stop_conditions():
+ iv_value(0)
+ {
+ // By default we want to start everything in 'don't stop' mode. This means disabling
+ // the errors which contain thresholds
+ set_thresh_nce_int(DISABLE)
+ .set_thresh_nce_soft(DISABLE)
+ .set_thresh_nce_hard(DISABLE)
+ .set_thresh_rce(DISABLE)
+ .set_thresh_ice(DISABLE)
+ .set_thresh_mce_int(DISABLE)
+ .set_thresh_mce_soft(DISABLE)
+ .set_thresh_mce_hard(DISABLE);
+ }
+
+ ///
+ /// @brief Stop/Thresholds class ctor
+ /// @param[in] uint64_t representing the threshold register contents
+ ///
+ stop_conditions(const uint64_t i_value):
+ iv_value(i_value)
+ {
+ }
+
+ ///
+ /// @brief Stop/Thresholds class dtor
+ ///
+ ~stop_conditions() = default;
+
+ ///
+ /// @brief uint64_t conversion
+ ///
+ inline operator uint64_t() const
+ {
+ return uint64_t(iv_value);
+ }
+
+ ///
+ /// @brief set_thresh_nce_int
+ /// @param[in] i_value the value of the field
+ /// NCE intermittent error threshold magnitude to trigger for triggering pause. If
+ /// 1111, then pause will never be triggered (disabled). Else, then MCBIST will
+ /// pause if it takes sees 2^[this value] number of errors of this type.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions<MC, T, TT>& set_thresh_nce_int( const uint64_t i_value )
+ {
+ iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_NCE_INT,
+ TT::MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN>(make_threshold_setting(i_value));
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_on_nce_int - enable NCE intermittent error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_nce_int( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_NCE_INT,
+ TT::MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_thresh_nce_soft
+ /// @param[in] i_value the value of the field
+ /// NCE soft error threshold magnitude to trigger for triggering pause. If 1111,
+ /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it
+ /// takes sees 2^[this value] number of errors of this type.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions<MC, T, TT>& set_thresh_nce_soft( const uint64_t i_value )
+ {
+ iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_NCE_SOFT,
+ TT::MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN>(make_threshold_setting(i_value));
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_on_nce_int - enable NCE soft error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_nce_soft( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_NCE_SOFT,
+ TT::MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_thresh_nce_hard
+ /// @param[in] i_value the value of the field
+ /// NCE hard error threshold magnitude to trigger for triggering pause. If 1111,
+ /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it
+ /// takes sees 2^[this value] number of errors of this type.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions<MC, T, TT>& set_thresh_nce_hard( const uint64_t i_value )
+ {
+ iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_NCE_HARD,
+ TT::MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN>(make_threshold_setting(i_value));
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_on_nce_hard - enable NCE hard error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_nce_hard( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_NCE_HARD,
+ TT::MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_thresh_rce
+ /// @param[in] i_value the value of the field
+ /// RCE error threshold magnitude to trigger for triggering pause. If 1111, then
+ /// pause will never be triggered (disabled). Else, then MCBIST will pause if it takes
+ /// sees 2^[this value] number of errors of this type.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions<MC, T, TT>& set_thresh_rce( const uint64_t i_value )
+ {
+ iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_RCE,
+ TT::MBSTRQ_CFG_THRESH_MAG_RCE_LEN>(make_threshold_setting(i_value));
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_on_rce - enable RCE error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_rce( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_RCE,
+ TT::MBSTRQ_CFG_THRESH_MAG_RCE_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_thresh_ice
+ /// @param[in] i_value the value of the field
+ /// ICE (IMPE) error threshold magnitude to trigger for triggering pause. If 1111,
+ /// then pause will never be triggered (disabled). Else, then MCBIST will pause if
+ /// it takes sees 2^[this value] number of errors of this type.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions<MC, T, TT>& set_thresh_ice( const uint64_t i_value )
+ {
+ iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_ICE,
+ TT::MBSTRQ_CFG_THRESH_MAG_ICE_LEN>(make_threshold_setting(i_value));
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_on_ice - enable ICE (IMPE) error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_ice( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_ICE,
+ TT::MBSTRQ_CFG_THRESH_MAG_ICE_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_thresh_mce_int
+ /// @param[in] i_value the value of the field
+ /// MCE intermittent error threshold magnitude to trigger for triggering pause. If
+ /// 1111, then pause will never be triggered (disabled). Else, then MCBIST will
+ /// pause if it takes sees 2^[this value] number of errors of this type.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions<MC, T, TT>& set_thresh_mce_int( const uint64_t i_value )
+ {
+ iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_MCE_INT,
+ TT::MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN>(make_threshold_setting(i_value));
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_on_mce_int - enable MCE intermittent error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_mce_int( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_MCE_INT,
+ TT::MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_thresh_mce_soft
+ /// @param[in] i_value the value of the field
+ /// MCE soft error threshold magnitude to trigger for triggering pause. If 1111,
+ /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it
+ /// takes sees 2^[this value] number of errors of this type.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions<MC, T, TT>& set_thresh_mce_soft( const uint64_t i_value )
+ {
+ iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_MCE_SOFT,
+ TT::MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN>(make_threshold_setting(i_value));
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_on_mce_soft - enable MCE soft error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_mce_soft( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_MCE_SOFT,
+ TT::MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_thresh_mce_hard
+ /// @param[in] i_value the value of the field
+ /// MCE hard error threshold magnitude to trigger for triggering pause. If 1111,
+ /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it
+ /// takes sees 2^[this value] number of errors of this type.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions<MC, T, TT>& set_thresh_mce_hard( const uint64_t i_value )
+ {
+ iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_MCE_HARD,
+ TT::MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN>(make_threshold_setting(i_value));
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_on_mce_hard - enable MCE hard error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_mce_hard( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_MCE_HARD,
+ TT::MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_pause_on_sce
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enable pause on SCE error. When enabled, MCBIST will pause at the boundary
+ /// configured if this error is seen.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_sce( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_SCE>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_on_mce
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enable pause on MCE error. When enabled, MCBIST will pause at the boundary
+ /// configured if this error is seen.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_mce( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_MCE>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_on_mpe
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enable pause on MPE error. When enabled, MCBIST will pause at the boundary
+ /// configured if this error is seen.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_mpe( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_MPE>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_on_ue
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enable pause on UE error. When enabled, MCBIST will pause at the boundary
+ /// configured if this error is seen.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_ue( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_UE>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_on_sue
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enable pause on SUE error. When enabled, MCBIST will pause at the boundary
+ /// configured if this error is seen.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_sue( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_SUE>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_on_aue
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enable pause on AUE error. When enabled, MCBIST will pause at the boundary
+ /// configured if this error is seen.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_aue( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_AUE>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_on_rcd
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enable pause on RCD error. When enabled, MCBIST will pause at the boundary
+ /// configured if this error is seen.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_on_rcd( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_RCD>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_symbol_counter_mode
+ /// @param[in] i_value the value of the field
+ /// Selects which mode to use symbol counter latches: Mode 0) MAINT 8-bit error
+ /// counters for of 72 symbols Mode 1) MCBIST 4-bit error counters for 18 nibbles x 8
+ /// ranks (port agnostic) Mode 2) MCBIST 4-bit error counters for 18 nibbles x 4
+ /// ports (rank agnostic) and 1-bit error rank map for 18 nibbles x 4 ports
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_symbol_counter_mode( const uint64_t i_value )
+ {
+ iv_value.insertFromRight<TT::MBSTRQ_CFG_SYMBOL_COUNTER_MODE,
+ TT::MBSTRQ_CFG_SYMBOL_COUNTER_MODE_LEN>(i_value);
+ return *this;
+ }
+
+ ///
+ /// @brief set_nce_soft_symbol_count_enable
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enables soft NCEs to trigger per symbol NCE error counting Only applies to
+ /// scrub where we have different types of NCE. Non scrub counts all NCE.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_nce_soft_symbol_count_enable( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_NCE_SOFT_SYMBOL_COUNT_ENABLE>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_nce_inter_symbol_count_enable
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enables intermittent NCEs to trigger per symbol NCE error counting Only applies
+ /// to scrub where we have different types of NCE. Non scrub counts all NCE.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_nce_inter_symbol_count_enable( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_NCE_INTER_SYMBOL_COUNT_ENABLE>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_nce_hard_symbol_count_enable
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enables hard NCEs to trigger per symbol NCE error counting Only applies to
+ /// scrub where we have different types of NCE. Non scrub counts all NCE.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_nce_hard_symbol_count_enable( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_NCE_HARD_SYMBOL_COUNT_ENABLE>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_mcb_error
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enable pause when MCBIST error is logged. When enabled, MCBIST will pause at
+ /// the boundary configured if this error is seen.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_mcb_error( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_MCB_ERROR>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_pause_mcb_log_full
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enable pause when MCBIST log is full. When enabled, MCBIST will pause at the
+ /// boundary configured if this error is seen.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_pause_mcb_log_full( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_MCB_LOG_FULL>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_maint_rce_with_ce
+ /// @param[in] i_on_or_off - the desired state.
+ /// cfg_maint_rce_with_ce - not implemented. Need to investigate if needed for nimbus.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_maint_rce_with_ce( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_MAINT_RCE_WITH_CE>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_mce_soft_symbol_count_enable
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enables soft MCEs to trigger per symbol MCE error counting Only applies to
+ /// scrub where we have different types of MCE. Non scrub counts all MCE.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_mce_soft_symbol_count_enable( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_MCE_SOFT_SYMBOL_COUNT_ENABLE>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_mce_inter_symbol_count_enable
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enables intermittent MCEs to trigger per symbol MCE error counting Only applies
+ /// to scrub where we have different types of MCE. Non scrub counts all MCE.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_mce_inter_symbol_count_enable( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_MCE_INTER_SYMBOL_COUNT_ENABLE>(i_on_or_off);
+ return *this;
+ }
+
+ ///
+ /// @brief set_mce_hard_symbol_count_enable
+ /// @param[in] i_on_or_off - the desired state.
+ /// Enables hard MCEs to trigger per symbol MCE error counting Only applies to
+ /// scrub where we have different types of MCE. Non scrub counts all MCE.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ ///
+ inline stop_conditions<MC, T, TT>& set_mce_hard_symbol_count_enable( const states i_on_or_off )
+ {
+ iv_value.writeBit<TT::MBSTRQ_CFG_MCE_HARD_SYMBOL_COUNT_ENABLE>(i_on_or_off);
+ return *this;
+ }
+
+ private:
+
+ fapi2::buffer<uint64_t> iv_value;
+};
+
+template< mss::mc_type MC, fapi2::TargetType T, typename TT>
+constexpr uint64_t stop_conditions<MC, T, TT>::DISABLE;
+
+template< mss::mc_type MC, fapi2::TargetType T, typename TT>
+constexpr uint64_t stop_conditions<MC, T, TT>::MAX_THRESHOLD;
+
+template< mss::mc_type MC, fapi2::TargetType T, typename TT>
+constexpr uint64_t stop_conditions<MC, T, TT>::DONT_CHANGE;
+
+///
+/// @class memdiags operational constraints
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T - derived
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE , typename TT = mcbistTraits<MC, T> >
+struct constraints
+{
+ ///
+ /// @brief constraints default constructor
+ ///
+ constraints():
+ iv_stop(),
+ iv_pattern(NO_PATTERN),
+ iv_end_boundary(NONE),
+ iv_speed(LUDICROUS),
+ iv_start_address(0),
+ iv_end_address(TT::LARGEST_ADDRESS)
+ {
+ }
+
+ ///
+ /// @brief constraints constructor
+ /// @param[in] i_pattern a pattern to set
+ ///
+ constraints( const uint64_t i_pattern ):
+ constraints()
+ {
+ iv_pattern = i_pattern;
+ FAPI_INF("setting up constraints with pattern %d", i_pattern);
+ }
+
+ ///
+ /// @brief constraints constructor
+ /// @param[in] i_stop stop conditions
+ ///
+ constraints( const stop_conditions<MC, T, TT>& i_stop ):
+ constraints()
+ {
+ iv_stop = i_stop;
+ FAPI_INF("setting up constraints with stop 0x%016lx", uint64_t(i_stop));
+ }
+
+ ///
+ /// @brief constraints constructor
+ /// @param[in] i_stop stop conditions
+ /// @param[in] i_start_address address to start from
+ ///
+ constraints( const stop_conditions<MC, T, TT>& i_stop,
+ const address& i_start_address ):
+ constraints(i_stop)
+ {
+ iv_start_address = i_start_address;
+ FAPI_INF("setting up constraints with start address 0x%016lx", uint64_t(i_start_address));
+ }
+
+ ///
+ /// @brief constraints constructor
+ /// @param[in] i_stop stop conditions
+ /// @param[in] i_speed the speed at which to run
+ /// @param[in] i_end_boundary the place to stop on error
+ /// @param[in] i_start_address address to start from
+ /// @param[in] i_end_address address to end at (optional, run to end)
+ ///
+ constraints( const stop_conditions<MC, T, TT>& i_stop,
+ const speed i_speed,
+ const end_boundary i_end_boundary,
+ const address& i_start_address,
+ const address& i_end_address = mcbist::address(TT::LARGEST_ADDRESS) ):
+ constraints(i_stop, i_start_address)
+ {
+ iv_end_boundary = i_end_boundary;
+ iv_speed = i_speed;
+ iv_end_address = i_end_address;
+
+ FAPI_INF("setting up constraints with end boundary %d and speed 0x%x", i_end_boundary, i_speed);
+
+ // If our end address is 'before' our start address, make the end address the same as the start.
+ if (iv_start_address > iv_end_address)
+ {
+ iv_end_address = iv_start_address;
+ }
+ }
+
+ // Member variable declaration
+ stop_conditions<MC, T, TT> iv_stop;
+ uint64_t iv_pattern;
+ end_boundary iv_end_boundary;
+ speed iv_speed;
+ mcbist::address iv_start_address;
+ mcbist::address iv_end_address;
+};
+
+
+} // namespace
+} // namespace
+#endif
diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H
index 54583ebd0..cd0bc5163 100644
--- a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H
+++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H
@@ -22,3 +22,44 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gen_mss_mcbist_traits.H
+/// @brief Run and manage the MCBIST engine
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _GEN_MSS_MCBIST_TRAITS_H_
+#define _GEN_MSS_MCBIST_TRAITS_H_
+
+#include <fapi2.H>
+
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+
+namespace mss
+{
+
+///
+/// @class mcbistMCTraits
+/// @tparam MC the mc type
+/// @brief A MC to MC_TARGET_TYPE mapping
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE >
+class mcbistMCTraits;
+
+///
+/// @class mcbistTraits
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @brief a collection of traits associated with the MCBIST engine or hardware
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE>
+class mcbistTraits;
+
+}// mss
+#endif
diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_mss_memdiags.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_memdiags.H
index 62af113ca..c67b51595 100644
--- a/src/import/generic/memory/lib/utils/mcbist/gen_mss_memdiags.H
+++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_memdiags.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,1288 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gen_mss_memdiags.H
+/// @brief API for memory diagnostics
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Marc Gollub <gollub@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+//
+
+#ifndef _GEN_MSS_MEMDIAGS_H_
+#define _GEN_MSS_MEMDIAGS_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/mss_generic_system_attribute_getters.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H>
+#include <generic/memory/lib/utils/fir/gen_mss_unmask.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+#include <generic/memory/lib/utils/conversions.H>
+#include <generic/memory/lib/utils/pos.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+#include <generic/memory/lib/utils/poll.H>
+
+
+namespace mss
+{
+
+///
+/// @brief Determine if a thing is functional
+/// @tparam I, the type of the item we want to check for
+/// @tparam P, the type of the parent which holds the things of interest
+/// @param[in] i_target the parent containing the thing we're looking for
+/// @param[in] i_rel_pos the relative position of the item of interest.
+/// @return bool true iff the thing at i_rel_pos is noted as functional
+///
+template< fapi2::TargetType I, fapi2::TargetType P >
+inline bool is_functional( const fapi2::Target<P>& i_target, const uint64_t i_rel_pos )
+{
+ // Not sure of a good way to do this ... we get all the functional
+ // children of the parent and look for our relative position ...
+ for (const auto& i : i_target.template getChildren<I>(fapi2::TARGET_STATE_FUNCTIONAL))
+ {
+ if (mss::template relative_pos<P>(i) == i_rel_pos)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+namespace mcbist
+{
+namespace sim
+{
+
+/// @brief Perform a sim version of initializing memory
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T
+/// @param T a fapi2::TargetType
+/// @param[in] i_target
+/// @param[in] i_pattern an index representing a pattern to use to initize memory (defaults to 0)
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode sf_init( const fapi2::Target<T>& i_target, const uint64_t i_pattern )
+{
+ FAPI_INF("Start sim init for %s", mss::c_str(i_target));
+
+ // If we're running in the simulator, we want to only touch the addresses which training touched
+
+ for (const auto& p : i_target.template getChildren<TT::PORT_TYPE>())
+ {
+ std::vector<uint64_t> l_pr;
+ mss::mcbist::program<MC> l_program;
+
+ mss::mcbist::address l_start;
+ mss::mcbist::address l_end;
+
+ size_t l_rank_address_pair = 0;
+
+ // No point in bothering if we don't have any DIMM
+ if (mss::count_dimm(p) == 0)
+ {
+ FAPI_INF("No DIMM on %s, not running sf_init", mss::c_str(p));
+ continue;
+ }
+
+ // In sim we know a few things ...
+ // Get the primary ranks for this port. We know there can only be 4, and we know we only trained the primary
+ // ranks. Therefore, we only need to clean up the primary ranks. And because there's 4 max, we can do it
+ // all using the 4 address range registers of tne MCBIST (broadcast currently not considered.)
+ // So we can write 0's to those to get their ECC fixed up.
+ FAPI_TRY( mss::rank::primary_ranks(p, l_pr) );
+ fapi2::Assert( l_pr.size() <= mss::MAX_RANK_PER_DIMM );
+
+ for (auto r = l_pr.begin(); r != l_pr.end(); ++l_rank_address_pair, ++r)
+ {
+ FAPI_INF("sim init %s, rank %d", mss::c_str(p), *r);
+
+ // Setup l_start to represent this rank, and then make the end address from that.
+ l_start.set_master_rank(*r);
+
+ // Set C3 bit to get an entire cache line
+ l_start.get_sim_end_address(l_end);
+
+ // By default we're in maint address mode, not address counting mode. So we give it a start and end, and ignore
+ // anything invalid - that's what maint address mode is all about
+ mss::mcbist::config_address_range<MC>(i_target, l_start, l_end, l_rank_address_pair);
+
+ // Write
+ {
+ // Run in ECC mode, 64B writes (superfast mode)
+
+ mss::mcbist::subtest_t<MC> l_fw_subtest =
+ mss::mcbist::write_subtest<MC>();
+
+ l_fw_subtest.enable_port(mss::relative_pos<T>(p));
+ l_fw_subtest.change_addr_sel(l_rank_address_pair);
+ l_fw_subtest.enable_dimm(mss::rank::get_dimm_from_rank(*r));
+ l_program.iv_subtests.push_back(l_fw_subtest);
+ FAPI_DBG("adding superfast write for %s rank %d (dimm %d)", mss::c_str(p), *r, mss::rank::get_dimm_from_rank(*r));
+ }
+
+ // Read - we do a read here as verification can use this as a tool as we do the write and then the read.
+ // If we failed to write properly the read would thow ECC errors. Just a write (which the real hardware would
+ // do) doesn't catch that. This takes longer, but it's not terribly long in any event.
+ {
+ // Run in ECC mode, 64B writes (superfast mode)
+ mss::mcbist::subtest_t<MC> l_fr_subtest =
+ mss::mcbist::read_subtest<MC>();
+
+ l_fr_subtest.enable_port(mss::relative_pos<T>(p));
+ l_fr_subtest.change_addr_sel(l_rank_address_pair);
+ l_fr_subtest.enable_dimm(mss::rank::get_dimm_from_rank(*r));
+ l_program.iv_subtests.push_back(l_fr_subtest);
+ FAPI_DBG("adding superfast read for %s rank %d (dimm %d)", mss::c_str(p), *r, mss::rank::get_dimm_from_rank(*r));
+ }
+ }
+
+ // Write pattern
+ FAPI_TRY( mss::mcbist::load_pattern<MC>(i_target, i_pattern) );
+
+ // Setup the sim polling based on a heuristic <cough>guess</cough>
+ // Looks like ~400ck per address for a write/read program on the sim-dimm, and add a long number of polls
+ // On real hardware wait 100ms and then start polling for another 5s
+ l_program.iv_poll.iv_initial_sim_delay = mss::cycles_to_simcycles(((l_end - l_start) * l_pr.size()) * 800);
+ l_program.iv_poll.iv_initial_delay = 100 * mss::DELAY_1MS;
+ l_program.iv_poll.iv_sim_delay = 100000;
+ l_program.iv_poll.iv_delay = 10 * mss::DELAY_1MS;
+ l_program.iv_poll.iv_poll_count = 500;
+
+ // Just one port for now. Per Shelton we need to set this in maint address mode
+ // even tho we specify the port/dimm in the subtest.
+ fapi2::buffer<uint8_t> l_port;
+ l_port.setBit(mss::relative_pos<T>(p));
+ l_program.select_ports(l_port >> 4);
+
+ // Kick it off, wait for a result
+ FAPI_TRY( mss::mcbist::execute(i_target, l_program) );
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ FAPI_INF("End sim init for %s", mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+} // namespace sim
+} // namespace mcbist
+
+
+namespace memdiags
+{
+
+// Map some of the mcbist namespace here to make it easier for users of memdiags
+// This is an intentional using statement in a header which is typically
+// disallowed - I am intentionally pulling these into this namespace for all callers.
+using mss::mcbist::constraints;
+using mss::mcbist::speed;
+using mss::mcbist::end_boundary;
+using mss::mcbist::stop_conditions;
+using mss::mcbist::cache_line;
+using mss::mcbist::pattern;
+using mss::mcbist::patterns;
+
+// Why not mss::mcbist::address? Because the fields can't be pulled in via using,
+// and it seems even more confusing to have a memdiags address but have to use
+// mcbist fields. So, we all use mcbist address until such time that its promoted
+// to some other general namespace.
+
+using mss::mcbist::PATTERN_ZEROS;
+using mss::mcbist::PATTERN_0;
+using mss::mcbist::PATTERN_ONES;
+using mss::mcbist::PATTERN_1;
+using mss::mcbist::PATTERN_2;
+using mss::mcbist::PATTERN_3;
+using mss::mcbist::PATTERN_4;
+using mss::mcbist::PATTERN_5;
+using mss::mcbist::PATTERN_6;
+using mss::mcbist::PATTERN_7;
+using mss::mcbist::PATTERN_8;
+using mss::mcbist::PATTERN_RANDOM;
+using mss::mcbist::LAST_PATTERN;
+using mss::mcbist::NO_PATTERN;
+
+///
+/// @brief Set up memory controller specific settings for pre-maint mode read
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the portTraits associated with the port
+/// @param[in] i_target the memory controller target
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template< mss::mc_type MC, fapi2::TargetType T, typename TT = portTraits<MC> >
+fapi2::ReturnCode pre_maint_read_settings( const fapi2::Target<T>& i_target );
+
+///
+/// @brief Set up memory controller specific settings for pre-scrub
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the portTraits associated with the port
+/// @param[in] i_target the memory controller target
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template< mss::mc_type MC, fapi2::TargetType T, typename TT = portTraits<MC> >
+fapi2::ReturnCode pre_scrub_settings( const fapi2::Target<T>& i_target );
+
+///
+/// @brief Stop the current command
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType of the target
+/// @param[in] i_target the target
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T>
+fapi2::ReturnCode stop( const fapi2::Target<T>& i_target )
+{
+ // Too long, make shorter
+ using TT = mss::mcbistTraits<MC, T>;
+ using ET = mss::mcbistMCTraits<MC>;
+
+ // Poll parameters are defined as TK so that we wait a nice time for operations
+ // For now use the defaults
+ mss::poll_parameters l_poll_parameters;
+ fapi2::buffer<uint64_t> l_status;
+ fapi2::buffer<uint64_t> l_last_address;
+ bool l_poll_result = false;
+
+ FAPI_INF("Stopping any mcbist operations which are in progress for %s", mss::c_str(i_target));
+
+ // TODO RTC:153951 Add masking of FIR when stopping
+ FAPI_TRY( mss::mcbist::start_stop<MC>(i_target, mss::STOP) );
+
+ // Poll waiting for the engine to stop
+ l_poll_result = mss::poll(i_target, TT::STATQ_REG, l_poll_parameters,
+ [&l_status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
+ {
+ FAPI_DBG("looking for mcbist not in-progress, mcbist statq 0x%llx, remaining: %d", stat_reg, poll_remaining);
+ l_status = stat_reg;
+ // We're done polling when either we see we're in progress or we see we're done.
+ return l_status.getBit<TT::MCBIST_IN_PROGRESS>() == false;
+ });
+
+ // Pass or fail output the current address. This is useful for debugging when we can get it.
+ // It's in the register FFDC for memdiags so we don't need it below
+ FAPI_TRY( mss::getScom(i_target, TT::LAST_ADDR_REG, l_last_address) );
+ FAPI_INF("MCBIST last address (during stop): 0x%016lx for %s",
+ l_last_address, mss::c_str(i_target));
+
+ // So we've either stopped or we timed out
+ FAPI_ASSERT( l_poll_result == true,
+ ET::memdiags_failed_to_stop()
+ .set_MC_TARGET(i_target)
+ .set_POLL_COUNT(l_poll_parameters.iv_poll_count),
+ "%s The MCBIST engine failed to stop its program",
+ mss::c_str(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+
+///
+/// @class Base class for memdiags operations
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2::TargetType of the MCBIST engine
+/// @tparam TT the mcbistTraits associated with T
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE , typename TT = mcbistTraits<MC, T> >
+class operation
+{
+ public:
+ ///
+ /// @brief memdiags::operation constructor
+ /// @param[in] i_target the target of the mcbist engine
+ /// @param[in] i_subtest the proper subtest for this operation
+ /// @param[in] i_const mss::constraint structure
+ ///
+ operation( const fapi2::Target<T>& i_target,
+ const mss::mcbist::subtest_t<MC> i_subtest,
+ const constraints<MC> i_const ):
+ iv_target(i_target),
+ iv_subtest(i_subtest),
+ iv_const(i_const)
+ {
+ FAPI_TRY( mss::attr::get_is_simulation (iv_sim) );
+ return;
+
+ fapi_try_exit:
+ // Seems like a safe risk to take ...
+ FAPI_ERR("Unable to get the attribute ATTR_IS_SIMULATION");
+ return;
+ }
+
+ operation() = delete;
+
+ ///
+ /// @brief Execute the memdiags operation
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ inline fapi2::ReturnCode execute()
+ {
+ return mss::mcbist::execute(iv_target, iv_program);
+ }
+
+ ///
+ /// @brief memdiags::operation destructor
+ ///
+ virtual ~operation() = default;
+
+ ///
+ /// @brief memdiags init helper
+ /// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
+ /// in subclassed constructores more easily.
+ /// @return FAPI2_RC_SUCCESS iff everything ok
+ ///
+ fapi2::ReturnCode base_init();
+
+ ///
+ /// @brief Configures all subtests for a multiport init
+ /// @param[in] i_dimms a vector of DIMM targets
+ ///
+ void configure_multiport_subtests(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& i_dimms);
+
+ ///
+ /// @brief memdiags multi-port init helper
+ /// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
+ /// in subclassed constructores more easily.
+ /// @return FAPI2_RC_SUCCESS iff everything ok
+ ///
+ fapi2::ReturnCode multi_port_init();
+
+ ///
+ /// @brief memdiags multi-port init for specific chip
+ /// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
+ /// in subclassed constructores more easily.
+ /// @return FAPI2_RC_SUCCESS iff everything ok
+ ///
+ fapi2::ReturnCode multi_port_init_internal();
+
+
+ ///
+ /// @brief memdiags multi-port address config helper
+ /// Initializes the address configs needed for a multi port operation
+ /// @return FAPI2_RC_SUCCESS iff everything ok
+ ///
+ fapi2::ReturnCode multi_port_addr();
+
+ ///
+ /// @brief Single port initializer
+ /// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
+ /// in subclassed constructores more easily.
+ /// @return FAPI2_RC_SUCCESS iff everything ok
+ ///
+ fapi2::ReturnCode single_port_init();
+
+ ///
+ /// @brief get the protected mcbist program - useful for testing
+ /// @return a reference to the iv_program member
+ /// @note Intentionally not const ref; allows getter to set.
+ ///
+ mss::mcbist::program<MC>& get_program()
+ {
+ return iv_program;
+ }
+
+ ///
+ /// @brief get the protected mcbist subtest_t - useful for testing
+ /// @return a reference to the iv_subtest member
+ ///
+ const mss::mcbist::subtest_t<MC>& get_subtest() const
+ {
+ return iv_subtest;
+ }
+
+ protected:
+ fapi2::Target<T> iv_target;
+ mss::mcbist::subtest_t<MC> iv_subtest;
+ constraints<MC> iv_const;
+ mss::mcbist::program<MC> iv_program;
+ uint8_t iv_sim;
+};
+
+
+
+///
+/// @brief memdiags init helper
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T
+/// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
+/// in subclassed constructors more easily.
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+template< mss::mc_type MC, fapi2::TargetType T, typename TT >
+inline fapi2::ReturnCode operation<MC, T, TT>::base_init()
+{
+ FAPI_INF("memdiags base init for %s", mss::c_str(iv_target));
+
+ // Check the state of the MCBIST engine to make sure its OK that we proceed.
+ // Force stop the engine (per spec, as opposed to waiting our turn)
+ FAPI_TRY( memdiags::stop<MC>(iv_target) );
+
+ // Zero out cmd timebase - mcbist::program constructor does that for us.
+ // Load pattern
+ FAPI_TRY( iv_program.change_pattern(iv_const.iv_pattern) );
+
+ // Load end boundaries
+ iv_program.change_end_boundary(iv_const.iv_end_boundary);
+
+ // Load thresholds
+ iv_program.change_thresholds(iv_const.iv_stop);
+
+ // Setup the requested speed
+ FAPI_TRY( iv_program.change_speed(iv_target, iv_const.iv_speed) );
+
+ // Enable maint addressing mode - enabled by default in the mcbist::program ctor
+
+ // Apparently the MCBIST engine needs the ports selected even though the ports are specified
+ // in the subtest. We can just select them all, and it adjusts when it executes the subtest
+ iv_program.select_ports(0b1111);
+
+ // Kick it off, don't wait for a result
+ iv_program.change_async(mss::ON);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Single port initializer
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T
+/// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
+/// in subclassed constructors more easily.
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+template< mss::mc_type MC, fapi2::TargetType T, typename TT >
+inline fapi2::ReturnCode operation<MC, T, TT>::single_port_init()
+{
+ using ET = mcbistMCTraits<MC>;
+ FAPI_INF("single port init for %s", mss::c_str(iv_target));
+
+ const uint64_t l_relative_port_number = iv_const.iv_start_address.get_port();
+ const uint64_t l_dimm_number = iv_const.iv_start_address.get_dimm();
+
+ // Make sure the specificed port is functional
+ FAPI_ASSERT( mss::is_functional<TT::PORT_TYPE>(iv_target, l_relative_port_number),
+ ET::memdiags_port_not_functional()
+ .set_RELATIVE_PORT_POSITION(l_relative_port_number)
+ .set_ADDRESS( uint64_t(iv_const.iv_start_address) )
+ .set_MC_TARGET(iv_target),
+ "Port with relative postion %d is not functional for %s",
+ l_relative_port_number, mss::c_str(iv_target));
+
+ // No broadcast mode for this one
+ // Push on a read subtest
+ {
+ mss::mcbist::subtest_t<MC> l_subtest = iv_subtest;
+
+ l_subtest.enable_port(l_relative_port_number);
+ l_subtest.enable_dimm(l_dimm_number);
+ iv_program.iv_subtests.push_back(l_subtest);
+ FAPI_INF("%s adding subtest 0x%04x for port %d, DIMM %d",
+ mss::c_str(iv_target), l_subtest, l_relative_port_number, l_dimm_number);
+ }
+
+ // The address should have the port and DIMM noted in it. All we need to do is calculate the
+ // remainder of the address
+ if (iv_sim)
+ {
+ iv_const.iv_start_address.get_sim_end_address(iv_const.iv_end_address);
+ }
+ else if (iv_const.iv_end_address == TT::LARGEST_ADDRESS)
+ {
+ // Only the DIMM range as we don't want to cross ports.
+ iv_const.iv_start_address.template get_range<mss::mcbist::address::DIMM>(iv_const.iv_end_address);
+ }
+
+ // Configure the address range
+ FAPI_TRY( mss::mcbist::config_address_range0<MC>(iv_target, iv_const.iv_start_address, iv_const.iv_end_address) );
+
+ // Initialize the common sections
+ FAPI_TRY( base_init() );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+
+///
+/// @brief memdiags multi-port init helper
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType - derived
+/// @tparam TT the mcbistTraits associated with T
+/// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
+/// in subclassed constructors more easily.
+/// @return FAPI2_RC_SUCCESS iff everything ok
+///
+template< mss::mc_type MC, fapi2::TargetType T, typename TT >
+inline fapi2::ReturnCode operation<MC, T, TT>::multi_port_init()
+{
+ FAPI_INF("multi-port init for %s", mss::c_str(iv_target));
+
+ const auto l_port = mss::find_targets<TT::PORT_TYPE>(iv_target);
+
+ // Make sure we have ports, if we don't then exit out
+ if(l_port.size() == 0)
+ {
+ // Cronus can have no ports under an MCBIST, FW deconfigures by association
+ FAPI_INF("%s has no attached ports skipping setup", mss::c_str(iv_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Let's assume we are going to send out all subtest unless we are in broadcast mode,
+ // where we only send up to 2 subtests under an port ( 1 for each DIMM) which is why no const
+ auto l_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(iv_target);
+
+ if( l_dimms.size() == 0)
+ {
+ // Cronus can have no DIMMS under an MCBIST, FW deconfigures by association
+ FAPI_INF("%s has no attached DIMMs skipping setup", mss::c_str(iv_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ return multi_port_init_internal();
+}
+
+
+///
+/// @class Class for memdiags' super-fast init
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2::TargetType of the MCBIST engine
+/// @tparam TT the mcbistTraits associated with T
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE , typename TT = mcbistTraits<MC, T> >
+struct sf_init_operation : public operation<MC>
+{
+
+ ///
+ /// @brief memdiags::sf_init_operation constructor
+ /// @param[in] i_target the target of the mcbist engine
+ /// @param[in] i_const mss::constraint structure
+ /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
+ ///
+ sf_init_operation( const fapi2::Target<T>& i_target,
+ const constraints<MC> i_const,
+ fapi2::ReturnCode& o_rc):
+ operation<MC>(i_target, mss::mcbist::init_subtest<MC>(), i_const)
+ {
+ // If sf_init was passed the random data pattern, then modify the subtest to use the true random data
+ if(i_const.iv_pattern == PATTERN_RANDOM)
+ {
+ this->iv_subtest.change_data_mode(mss::mcbist::data_mode::RAND_FWD_MAINT);
+ }
+
+ // We're a multi-port operation
+ o_rc = this->multi_port_init();
+ }
+
+ sf_init_operation() = delete;
+};
+
+
+
+///
+/// @class Class for memdiags' super-fast read
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2::TargetType of the MCBIST engine
+/// @tparam TT the mcbistTraits associated with T
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE , typename TT = mcbistTraits<MC, T> >
+struct sf_read_operation : public operation<MC>
+{
+
+ ///
+ /// @brief memdiags::sf_read_operation constructor
+ /// @param[in] i_target the target of the mcbist engine
+ /// @param[in] i_const mss::constraint structure
+ /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
+ ///
+ sf_read_operation( const fapi2::Target<T>& i_target,
+ const constraints<MC> i_const,
+ fapi2::ReturnCode& o_rc):
+ operation<MC>(i_target, mss::mcbist::read_subtest<MC>(), i_const)
+ {
+ // We're a multi-port operation
+ o_rc = this->multi_port_init();
+ }
+
+ sf_read_operation() = delete;
+};
+
+
+///
+/// @class Class for memdiags' super-fast read to end of port
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2::TargetType of the MCBIST engine
+/// @tparam TT the mcbistTraits associated with T
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE , typename TT = mcbistTraits<MC, T> >
+struct sf_read_eop_operation : public operation<MC>
+{
+ ///
+ /// @brief memdiags::sf_read_operation constructor
+ /// @param[in] i_target the target of the mcbist engine
+ /// @param[in] i_const mss::constraint structure
+ /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
+ ///
+ sf_read_eop_operation( const fapi2::Target<T>& i_target,
+ const constraints<MC> i_const,
+ fapi2::ReturnCode& o_rc ):
+ operation<MC>(i_target, mss::mcbist::read_subtest<MC>(), i_const)
+ {
+ // We're a single-port operation
+ o_rc = this->single_port_init();
+ }
+
+ sf_read_eop_operation() = delete;
+};
+
+///
+/// @class Class for memdiags' continuous scrub
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2::TargetType of the MCBIST engine
+/// @tparam TT the mcbistTraits associated with T
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE , typename TT = mcbistTraits<MC, T> >
+struct continuous_scrub_operation : public operation<MC>
+{
+
+ ///
+ /// @brief memdiags::continuous_scrub_operation constructor
+ /// @param[in] i_target the target of the mcbist engine
+ /// @param[in] i_const the contraints of the operation
+ /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
+ ///
+ continuous_scrub_operation( const fapi2::Target<T>& i_target,
+ const constraints<MC> i_const,
+ fapi2::ReturnCode& o_rc );
+
+ continuous_scrub_operation() = delete;
+};
+
+///
+/// @brief memdiags::continuous_scrub_operation constructor
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2::TargetType of the MCBIST engine
+/// @tparam TT the mcbistTraits associated with T
+/// @param[in] i_target the target of the mcbist engine
+/// @param[in] i_const the contraints of the operation
+/// @param[out] o_rc the fapi2::ReturnCode of the intialization process
+///
+template< mss::mc_type MC, fapi2::TargetType T, typename TT>
+continuous_scrub_operation<MC, T, TT>::continuous_scrub_operation(
+ const fapi2::Target<T>& i_target,
+ const constraints<MC> i_const,
+ fapi2::ReturnCode& o_rc ):
+ operation<MC>(i_target, mss::mcbist::scrub_subtest<MC>(), i_const)
+{
+ mss::mcbist::address l_generic_start_address;
+ mss::mcbist::address l_generic_end_address;
+
+ FAPI_INF("setting up for continuous scrub for %s", mss::c_str(i_target));
+
+ // Scrub operations run 128B
+ operation<MC>::iv_program.change_len64(mss::OFF);
+
+ // We build a little program here which allows us to restart the loop in the event of a pause.
+ // So we need to craft some of the address ranges and some of the subtests by hand.
+
+ // Setup address config 0 to cover all the addresses for a port/dimm.
+ // We leverage the MCBIST's ability to skip invalid addresses, and just setup
+ // If we're running in the simulator, we want to only touch the addresses which training touched
+ // *INDENT-OFF*
+ operation<MC>::iv_sim ?
+ l_generic_start_address.get_sim_end_address(l_generic_end_address) :
+ l_generic_start_address.get_range<mss::mcbist::address::DIMM>(l_generic_end_address);
+ // *INDENT-ON*
+
+ FAPI_TRY( mss::mcbist::config_address_range0<MC>(i_target, l_generic_start_address, l_generic_end_address) );
+
+ // We push on a fake subtest 0 and subtest 1. We fix them up after we fill in the
+ // rest of the subtests.
+ operation<MC>::iv_program.iv_subtests.push_back(operation<MC>::iv_subtest);
+ operation<MC>::iv_program.iv_subtests.push_back(operation<MC>::iv_subtest);
+
+ // a generic 0 - DIMM address range.
+ //
+ // Subtests 2-9: One subtest per port/dimm each covering the whole range of that
+ // port/dimm. scrub_subtests by default are using address config 0, so each of
+ // these get their full address complement.
+ for (const auto& p : operation<MC>::iv_target.template getChildren<TT::PORT_TYPE>())
+ {
+ for (const auto& d : p.template getChildren<fapi2::TARGET_TYPE_DIMM>())
+ {
+ // Don't destroy the subtest passed in, copy it
+ auto l_subtest = operation<MC>::iv_subtest;
+
+ l_subtest.enable_port(mss::relative_pos<T>(p));
+ l_subtest.enable_dimm(mss::index(d));
+ operation<MC>::iv_program.iv_subtests.push_back(l_subtest);
+ FAPI_INF("adding scrub subtest for %s (dimm %d) ( 0x%04x)", mss::c_str(d), mss::index(d), l_subtest);
+ }
+ }
+
+ //
+ // Subtest 10: goto subtest 2. This causes us to loop back to the first port/dimm and go thru them all
+ // This subtest will be marked the last when the MCBMR registers are filled in.
+ //
+ operation<MC>::iv_program.iv_subtests.push_back(mss::mcbist::goto_subtest<MC>(2));
+ FAPI_INF("last goto subtest (10) is going to subtest 2 ( 0x%04x) for %s", operation<MC>::iv_program.iv_subtests[2],
+ mss::c_str(operation<MC>::iv_target));
+
+ // Ok, now we can go back in to fill in the first two subtests.
+
+ {
+ auto l_subtest = operation<MC>::iv_subtest;
+ auto l_port = operation<MC>::iv_const.iv_start_address.get_port();
+ auto l_dimm = operation<MC>::iv_const.iv_start_address.get_dimm();
+ size_t l_index = 2;
+
+ // By default if we don't find our port/dimm in the subtests, we just go back to the beginning.
+ uint64_t l_goto_subtest = 2;
+
+ //
+ // subtest 0
+ //
+
+ // load the start address given and calculate the end address. Stick this into address config 1
+ // We don't need to account for the simulator here as the caller can do that when they setup the
+ // start address.
+ // *INDENT-OFF*
+ operation<MC>::iv_sim ?
+ operation<MC>::iv_const.iv_start_address.get_sim_end_address(operation<MC>::iv_const.iv_end_address) :
+ operation<MC>::iv_const.iv_start_address.template get_range<mss::mcbist::address::DIMM>(operation<MC>::iv_const.iv_end_address);
+ // *INDENT-ON*
+
+ FAPI_TRY( mss::mcbist::config_address_range1(i_target, operation<MC>::iv_const.iv_start_address,
+ operation<MC>::iv_const.iv_end_address) );
+
+ // We need to use this address range. We know it's ok to write to element 0 as we pushed it on above
+ l_subtest.change_addr_sel(1);
+ l_subtest.enable_port(l_port);
+ l_subtest.enable_dimm(l_dimm);
+
+ operation<MC>::iv_program.iv_subtests[0] = l_subtest;
+ FAPI_INF("adding scrub subtest 0 for port %d dimm %d (0x%04x) for %s", l_port, l_dimm, l_subtest, mss::c_str(i_target));
+
+ //
+ // subtest 1
+ //
+
+ // From the port/dimm specified in the start address, we know what subtest should execute next. The idea
+ // being that this 0'th subtest is a mechanism to allow the caller to start a scrub 'in the middle' and
+ // jump to the next port/dimm which would have been scrubbed. The hard part is that we don't know where
+ // in the subtest vector the 'next' port/dimm are placed. So we look for our port/dimm (skipping subtest 0
+ // since we know that's us and skipping subtest 1 since it isn't there yet.)
+ for (; l_index < operation<MC>::iv_program.iv_subtests.size(); ++l_index)
+ {
+ auto l_my_dimm = operation<MC>::iv_program.iv_subtests[l_index].get_dimm();
+ auto l_my_port = operation<MC>::iv_program.iv_subtests[l_index].get_port();
+
+ if ((l_dimm == l_my_dimm) && (l_port == l_my_port))
+ {
+ l_goto_subtest = l_index + 1;
+ break;
+ }
+ }
+
+ // Since we set l_goto_subtest up with a meaningful default, we can just make a subtest with the
+ // l_goto_subtest subtest specified and pop that in to index 1.
+ FAPI_INF("adding scrub subtest 1 to goto subtest %d (port %d, dimm %d, test 0x%04x) for %s", l_goto_subtest,
+ operation<MC>::iv_program.iv_subtests[l_goto_subtest].get_port(),
+ operation<MC>::iv_program.iv_subtests[l_goto_subtest].get_dimm(),
+ operation<MC>::iv_program.iv_subtests[l_goto_subtest], mss::c_str(i_target) );
+
+ operation<MC>::iv_program.iv_subtests[1] = mss::mcbist::goto_subtest<MC>(l_goto_subtest);
+ }
+
+ // Initialize the common sections
+ FAPI_TRY( operation<MC>::base_init() );
+
+fapi_try_exit:
+ o_rc = fapi2::current_err;
+ return;
+}
+
+
+
+///
+/// @class Class for memdiags' targeted scrub
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2::TargetType of the MCBIST engine
+/// @tparam TT the mcbistTraits associated with T
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE , typename TT = mcbistTraits<MC, T> >
+struct targeted_scrub_operation : public operation<MC>
+{
+
+ ///
+ /// @brief memdiags::targeted_scrub_operation constructor
+ /// @param[in] i_target the target of the mcbist engine
+ /// @param[in] i_const the contraints of the operation
+ /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
+ ///
+ targeted_scrub_operation( const fapi2::Target<T>& i_target,
+ const constraints<MC> i_const,
+ fapi2::ReturnCode& o_rc ):
+ operation<MC>(i_target, mss::mcbist::scrub_subtest<MC>(), i_const)
+ {
+ // Scrub operations run 128B
+ this->iv_program.change_len64(mss::OFF);
+
+ // We're a single-port operation
+ o_rc = this->single_port_init();
+
+ // Targeted scrub needs to force a pause and the end boundary. So we make sure that happens here.
+ this->iv_program.change_forced_pause( i_const.iv_end_boundary );
+ }
+
+ targeted_scrub_operation() = delete;
+};
+
+///
+/// @brief Super Fast Init - used to init all memory behind a target with a given pattern
+/// @note Uses broadcast mode if possible
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType of the target
+/// @param[in] i_target the target behind which all memory should be initialized
+/// @param[in] i_pattern an index representing a pattern to use to init memory (defaults to 0)
+/// @return FAPI2_RC_SUCCESS iff everything ok
+/// @note The function is asynchronous, and the caller should be looking for a done attention
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
+fapi2::ReturnCode sf_init( const fapi2::Target<T>& i_target,
+ const uint64_t i_pattern = PATTERN_0 )
+{
+ using ET = mss::mcbistMCTraits<MC>;
+ FAPI_INF("superfast init start for %s", mss::c_str(i_target));
+
+ uint8_t l_sim = false;
+ FAPI_TRY( mss::attr::get_is_simulation( l_sim) );
+
+ if (l_sim)
+ {
+ // Use some sort of pattern in sim in case the verification folks need to look for something
+ // TK. Need a verification pattern. This is a not-good pattern for verification ... We don't really
+ // have a good pattern for verification defined.
+ FAPI_INF("running mss sim init in place of sf_init for %s", mss::c_str(i_target));
+ return mss::mcbist::sim::sf_init<MC>(i_target, i_pattern);
+ }
+ else
+ {
+ fapi2::ReturnCode l_rc;
+ constraints<MC> l_const(i_pattern);
+ sf_init_operation<MC> l_init_op(i_target, l_const, l_rc);
+
+ FAPI_ASSERT( l_rc == fapi2::FAPI2_RC_SUCCESS,
+ ET::memdiags_sf_init_failed_init().set_MC_TARGET(i_target),
+ "Unable to initialize the MCBIST engine for a sf read %s", mss::c_str(i_target) );
+
+ return l_init_op.execute();
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Super Fast Read - used to run superfast read on all memory behind the target
+/// Determines ability to braodcast to all ports behind a target, does so if possible.
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType of the target
+/// @tparam TT the mcbistTraits associated with T - derived
+/// @param[in] i_target the target behind which all memory should be read
+/// @param[in] i_stop stop conditions
+/// @param[in] i_address mcbist::address representing the address from which to start.
+// Defaults to the first address behind the target
+/// @param[in] i_end whether to end, and where
+/// Defaults to stop after slave rank
+/// @param[in] i_end_address mcbist::address representing the address to end.
+// Defaults to TT::LARGEST_ADDRESS
+/// @return FAPI2_RC_SUCCESS iff everything ok
+/// @note The function is asynchronous, and the caller should be looking for a done attention
+/// @note The address is often the port, dimm, rank but this is not enforced in the API.
+///
+template< mss::mc_type MC, fapi2::TargetType T = mss::mcbistMCTraits<MC>::MC_TARGET_TYPE , typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode sf_read( const fapi2::Target<T>& i_target,
+ const stop_conditions<MC>& i_stop,
+ const mss::mcbist::address& i_address = mss::mcbist::address(),
+ const end_boundary i_end = end_boundary::STOP_AFTER_SLAVE_RANK,
+ const mss::mcbist::address& i_end_address = mss::mcbist::address(TT::LARGEST_ADDRESS) )
+{
+ using ET = mss::mcbistMCTraits<MC>;
+ FAPI_INF("superfast read - start for %s", mss::c_str(i_target));
+
+ FAPI_TRY( pre_maint_read_settings<MC>(i_target) );
+
+ {
+ fapi2::ReturnCode l_rc;
+ constraints<MC> l_const(i_stop, speed::LUDICROUS, i_end, i_address, i_end_address);
+ sf_read_operation<MC> l_read_op(i_target, l_const, l_rc);
+
+ FAPI_ASSERT( l_rc == fapi2::FAPI2_RC_SUCCESS,
+ ET::memdiags_sf_init_failed_init().set_MC_TARGET(i_target),
+ "Unable to initialize the MCBIST engine for a sf read %s", mss::c_str(i_target) );
+
+ return l_read_op.execute();
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Scrub - continuous scrub all memory behind the target
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType of the target
+/// @param[in] i_target the target behind which all memory should be scrubbed
+/// @param[in] i_stop stop conditions
+/// @param[in] i_speed the speed to scrub
+/// @param[in] i_address mcbist::address representing the address from which to start.
+/// @return FAPI2_RC_SUCCESS iff everything ok
+/// @note The function is asynchronous, and the caller should be looking for a done attention
+/// @note The address is often the port, dimm, rank but this is not enforced in the API.
+///
+template< mss::mc_type MC, fapi2::TargetType T >
+fapi2::ReturnCode background_scrub( const fapi2::Target<T>& i_target,
+ const stop_conditions<MC>& i_stop,
+ const speed i_speed,
+ const mss::mcbist::address& i_address )
+{
+ using ET = mss::mcbistMCTraits<MC>;
+ FAPI_INF("continuous (background) scrub for %s", mss::c_str(i_target));
+
+ FAPI_TRY( pre_scrub_settings<MC>(i_target) );
+
+ {
+ fapi2::ReturnCode l_rc;
+ constraints<MC> l_const(i_stop, i_speed, end_boundary::STOP_AFTER_ADDRESS, i_address);
+ continuous_scrub_operation<MC> l_op(i_target, l_const, l_rc);
+
+ FAPI_ASSERT( l_rc == fapi2::FAPI2_RC_SUCCESS,
+ ET::memdiags_continuous_scrub_failed_init().set_MC_TARGET(i_target),
+ "Unable to initialize the MCBIST engine for a continuous scrub %s", mss::c_str(i_target) );
+
+ return l_op.execute();
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Scrub - targeted scrub all memory described by the input address (rank, slave, etc.)
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType of the target
+/// @param[in] i_target the target behind which all memory should be scrubbed
+/// @param[in] i_stop stop conditions
+/// @param[in] i_speed the speed to scrub
+/// @param[in] i_start_address mcbist::address representing the address from which to start.
+/// @param[in] i_end_address mcbist::address representing the address at which to end.
+/// @param[in] i_end whether to end, and where
+/// @return FAPI2_RC_SUCCESS iff everything ok
+/// @note The function is asynchronous, and the caller should be looking for a done attention
+/// @note The address is often the port, dimm, rank but this is not enforced in the API.
+///
+template< mss::mc_type MC, fapi2::TargetType T >
+fapi2::ReturnCode targeted_scrub( const fapi2::Target<T>& i_target,
+ const stop_conditions<MC>& i_stop,
+ const mss::mcbist::address& i_start_address,
+ const mss::mcbist::address& i_end_address,
+ const end_boundary i_end )
+{
+ using ET = mss::mcbistMCTraits<MC>;
+ FAPI_INF("targeted scrub for %s", mss::c_str(i_target));
+
+ FAPI_TRY( pre_scrub_settings<MC>(i_target) );
+
+ {
+ fapi2::ReturnCode l_rc;
+ constraints<MC> l_const(i_stop, speed::LUDICROUS, i_end, i_start_address, i_end_address);
+ targeted_scrub_operation<MC> l_op(i_target, l_const, l_rc);
+
+ FAPI_ASSERT( l_rc == fapi2::FAPI2_RC_SUCCESS,
+ ET::memdiags_targeted_scrub_failed_init().set_MC_TARGET(i_target),
+ "Unable to initialize the MCBIST engine for a targeted scrub %s", mss::c_str(i_target) );
+
+ return l_op.execute();
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Continue current command on next address
+/// The current commaand has paused on an error, so we can record the address of the error
+/// and finish the current master or slave rank.
+/// @tparam MC the mc type of the T
+/// @tparam T the fapi2::TargetType of the target
+/// @param[in] i_target the target
+/// @param[in] i_end whether to end, and where (default - don't stop at end of rank)
+/// @param[in] i_stop stop conditions (default - 0 meaning 'don't change conditions')
+/// @param[in] i_speed the speed to scrub (default - SAME_SPEED meaning leave speed untouched)
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
+fapi2::ReturnCode continue_cmd( const fapi2::Target<T>& i_target,
+ const end_boundary i_end = end_boundary::DONT_CHANGE,
+ const stop_conditions<MC>& i_stop = stop_conditions<MC>(stop_conditions<MC>::DONT_CHANGE),
+ const speed i_speed = speed::SAME_SPEED )
+{
+ // Too long, make shorter
+ using TT = mss::mcbistTraits<MC, T>;
+ using ET = mss::mcbistMCTraits<MC>;
+
+ // We can use a local mcbist::program to help with the bit processing, and then write just the registers we touch.
+ mss::mcbist::program<MC> l_program;
+ fapi2::buffer<uint64_t> l_status;
+
+ FAPI_INF("continue_cmd for %s", mss::c_str(i_target));
+
+ // TODO RTC:155518 Check for stop or in progress before allowing continue. Not critical
+ // as the caller should know and can check the in-progress bit in the event they don't
+
+ if (i_end != end_boundary::DONT_CHANGE)
+ {
+ // Before we go too far, check to see if we're already stopped at the boundary we are asking to stop at
+ bool l_stopped_at_boundary = false;
+ uint64_t l_error_mode = 0;
+ bool l_detect_slave = false;
+
+ FAPI_TRY( mss::getScom(i_target, TT::CFGQ_REG, l_program.iv_config) );
+ FAPI_TRY( mss::getScom(i_target, TT::MCBAGRAQ_REG, l_program.iv_addr_gen) );
+ l_program.iv_config.template extractToRight<TT::CFG_PAUSE_ON_ERROR_MODE, TT::CFG_PAUSE_ON_ERROR_MODE_LEN>(l_error_mode);
+ l_detect_slave = l_program.iv_addr_gen.template getBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>();
+
+
+ switch (i_end)
+ {
+ case end_boundary::STOP_AFTER_ADDRESS:
+ l_stopped_at_boundary =
+ l_program.iv_config.template getBit< TT::MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR>() ||
+ l_error_mode == end_boundary::STOP_AFTER_ADDRESS;
+ break;
+
+ case end_boundary::STOP_AFTER_SLAVE_RANK:
+ // Note: we really want STOP_AFTER_MASTER_RANK here even though we're in the slave
+ // case because MASTER_RANK has the a 0 so that l_error_mode will check correctly
+ l_stopped_at_boundary =
+ l_program.iv_config.template getBit< TT::MCBIST_CFG_PAUSE_AFTER_RANK>() ||
+ ((l_error_mode == end_boundary::STOP_AFTER_MASTER_RANK) && (l_detect_slave == false));
+ break;
+
+ case end_boundary::STOP_AFTER_MASTER_RANK:
+ l_stopped_at_boundary =
+ l_program.iv_config.template getBit< TT::MCBIST_CFG_PAUSE_AFTER_RANK>() ||
+ ((l_error_mode == end_boundary::STOP_AFTER_MASTER_RANK) && (l_detect_slave == true));
+ break;
+
+ case end_boundary::STOP_AFTER_SUBTEST:
+ l_stopped_at_boundary =
+ l_program.iv_config.template getBit< TT::MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST>() ||
+ l_error_mode == end_boundary::STOP_AFTER_SUBTEST;
+ break;
+
+ // By default we're not stopped at a boundary we're going to continue from
+ default:
+ break;
+ };
+
+ FAPI_ASSERT( l_stopped_at_boundary == false,
+ ET::memdiags_already_at_boundary().set_MC_TARGET(i_target).set_BOUNDARY(i_stop),
+ "Asked to stop at a boundary, but we're already there" );
+
+ // Ok, if we're here either we need to change the stop and boundary conditions.
+ // Read-modify-write the fields in the program.
+ FAPI_TRY( mss::getScom(i_target, TT::MCBAGRAQ_REG, l_program.iv_addr_gen) );
+
+ // Note: we are specifically not configuring broadcast mode here
+ // The continue command is called by PRD exclusively at mainline
+ // If we're at mainline, we can't run in broadcast mode
+ // If we ever need to call continue elsewhere, we'll need to do the following
+ // 1) add the function to configure broadcast mode
+ // 2) add in a switch to disable broadcast mode if we're at runtime
+
+ l_program.change_end_boundary(i_end);
+
+ FAPI_TRY( mss::mcbist::load_addr_gen(i_target, l_program) );
+
+ FAPI_TRY( mss::mcbist::load_config(i_target, l_program) );
+ }
+
+ // Thresholds
+ // According to API definition, 0 means don't change conditions
+ if( i_stop != stop_conditions<MC>::DONT_CHANGE)
+ {
+ FAPI_TRY( mss::mcbist::load_thresholds(i_target, i_stop) );
+ }
+
+ // Setup speed
+ FAPI_TRY( l_program.change_speed(i_target, i_speed) );
+
+ // Load new speed unless we aren't changing it
+ if( i_speed != speed::SAME_SPEED )
+ {
+ FAPI_TRY( load_mcbparm(i_target, l_program) );
+ }
+
+ // Tickle the resume from pause
+ FAPI_TRY( mss::mcbist::resume(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Begin initialize memory
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2::TargetType of the MC engine
+/// @tparam TT the mcbistTraits associated with T
+/// @param[in] i_target MC
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode mss_initialize_memory(const fapi2::Target<T>& i_target )
+{
+ using ET = mss::mcbistMCTraits<MC>;
+ FAPI_INF("Start mss_initialize_memory for %s", mss::c_str(i_target));
+
+ // If there are no DIMM we don't need to bother. In fact, we can't as we didn't setup
+ // attributes for the PHY, etc.
+ if (mss::count_dimm(i_target) == 0)
+ {
+ FAPI_INF("... skipping scrub for %s - no DIMM ...", mss::c_str(i_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // If we're running in the simulator, we want to only touch the addresses which training touched
+ uint8_t l_sim = 0;
+ bool l_poll_results = false;
+ fapi2::buffer<uint64_t> l_status;
+
+ // A small vector of addresses to poll during the polling loop
+ const std::vector<mss::poll_probe<T>> l_probes =
+ {
+ {i_target, "mcbist current address", TT::LAST_ADDR_REG},
+ };
+
+ // We'll fill in the initial delay below
+ mss::poll_parameters l_poll_parameters(0, 200, 100 * mss::DELAY_1MS, 200, 10000);
+ uint64_t l_memory_size = 0;
+
+ FAPI_TRY( mss::eff_memory_size<MC>(i_target, l_memory_size) );
+ l_poll_parameters.iv_initial_delay = mss::calculate_initial_delay<MC>(i_target, (l_memory_size * mss::BYTES_PER_GB));
+
+ FAPI_TRY( mss::attr::get_is_simulation( l_sim) );
+
+ if (l_sim)
+ {
+ FAPI_INF("running mss sim init in place of scrub for %s", mss::c_str(i_target));
+
+ // Use some sort of pattern in sim in case the verification folks need to look for something
+ // TK. Need a verification pattern. This is a not-good pattern for verification ... We don't really
+ // have a good pattern for verification defined.
+ auto l_rc = mss::mcbist::sim::sf_init<MC>(i_target, mss::mcbist::PATTERN_0);
+
+ // Unmask firs and turn off FIFO mode before returning
+ FAPI_TRY ( mss::unmask::after_memdiags<MC>( i_target ) );
+ FAPI_TRY ( mss::reset_reorder_queue_settings<MC>(i_target) );
+
+ return l_rc;
+ }
+
+ // In Cronus on hardware (which is how we got here - f/w doesn't call this) we want
+ // to call sf_init (0's)
+ // TK we need to check FIR given the way this is right now, we should adjust with better stop
+ // conditions when we learn more about what we want to find in the lab
+ FAPI_TRY( mss::memdiags::sf_init<MC>(i_target, mss::mcbist::PATTERN_0) );
+
+ // Poll for completion.
+ l_poll_results = mss::poll(i_target, TT::FIRQ_REG, l_poll_parameters,
+ [&l_status](const size_t poll_remaining,
+ const fapi2::buffer<uint64_t>& stat_reg) -> bool
+ {
+ FAPI_DBG("mcbist firq 0x%llx, remaining: %d", stat_reg, poll_remaining);
+ l_status = stat_reg;
+ return l_status.getBit<TT::MCB_PROGRAM_COMPLETE>() == true;
+ },
+ l_probes);
+
+ FAPI_ASSERT( l_poll_results == true,
+ ET::memdiags_sf_init_failed_init().set_MC_TARGET(i_target),
+ "sf init for scrub/memdiags timedout %s", mss::c_str(i_target) );
+
+ // Unmask firs after memdiags and turn off FIFO mode
+ FAPI_TRY ( mss::unmask::after_memdiags<MC>( i_target ) );
+ FAPI_TRY ( mss::reset_reorder_queue_settings<MC>(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Begin background scrub helper
+/// @tparam MC the mc type of the T
+/// @tparam T fapi2::TargetType of the MCBIST engine
+/// @tparam TT the mcbistTraits associated with T
+/// @param[in] i_target MC
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = mcbistTraits<MC, T> >
+fapi2::ReturnCode mss_background_scrub_helper( const fapi2::Target<T>& i_target )
+{
+ FAPI_INF("Start mss_background_scrub_helper b on: %s", mss::c_str( i_target ));
+
+ // If there are no DIMM we don't need to bother. In fact, we can't as we didn't setup
+ // attributes for the PHY, etc.
+ if (mss::count_dimm(i_target) == 0)
+ {
+ FAPI_INF("... skipping background scrub for %s - no DIMM ...", mss::c_str(i_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // If we're running in the simulator, we want to only touch the addresses which training touched
+ uint8_t l_sim = 0;
+ FAPI_TRY( mss::attr::get_is_simulation(l_sim) );
+
+ // Kick off background scrub if we are not running in sim
+ if (!(l_sim))
+ {
+ // Start background scrub
+ FAPI_TRY ( mss::memdiags::background_scrub<MC>( i_target,
+ mss::mcbist::stop_conditions<MC>(),
+ mss::mcbist::speed::BG_SCRUB,
+ mss::mcbist::address() ) );
+ }
+
+ // Unmask firs after background scrub is started
+ FAPI_TRY ( mss::unmask::after_background_scrub<MC>( i_target ) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // namespace memdiags
+
+} // namespace mss
+#endif
diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_patterns.C b/src/import/generic/memory/lib/utils/mcbist/gen_patterns.C
deleted file mode 100644
index 03053fc0f..000000000
--- a/src/import/generic/memory/lib/utils/mcbist/gen_patterns.C
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/generic/memory/lib/utils/mcbist/gen_patterns.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_patterns.H b/src/import/generic/memory/lib/utils/mcbist/gen_patterns.H
deleted file mode 100644
index f99518b7e..000000000
--- a/src/import/generic/memory/lib/utils/mcbist/gen_patterns.H
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/generic/memory/lib/utils/mcbist/gen_patterns.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_settings.H b/src/import/generic/memory/lib/utils/mcbist/gen_settings.H
deleted file mode 100644
index 1d437f39c..000000000
--- a/src/import/generic/memory/lib/utils/mcbist/gen_settings.H
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/generic/memory/lib/utils/mcbist/gen_settings.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/generic/memory/lib/utils/mcbist/settings.H b/src/import/generic/memory/lib/utils/mcbist/settings.H
deleted file mode 100644
index 0d0b10883..000000000
--- a/src/import/generic/memory/lib/utils/mcbist/settings.H
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/generic/memory/lib/utils/mcbist/settings.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
diff --git a/src/import/generic/memory/lib/utils/mss_bad_bits.H b/src/import/generic/memory/lib/utils/mss_bad_bits.H
index e6d2cdfa5..b39d84859 100644
--- a/src/import/generic/memory/lib/utils/mss_bad_bits.H
+++ b/src/import/generic/memory/lib/utils/mss_bad_bits.H
@@ -46,6 +46,17 @@ namespace mss
{
///
+/// @brief A generic bad bits getter
+/// @tparam MC type memory controller type
+/// @param[in] i_target the fapi2 target oon which training was conducted
+/// @param[out] o_array the bad bits array
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code
+///
+template <mss::mc_type MC>
+fapi2::ReturnCode get_bad_dq_bitmap(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT]);
+
+///
/// @brief A generic bad bits setter
/// @tparam MC type memory controller type
/// @param[in] i_target the fapi2 target oon which training was conducted
@@ -57,6 +68,23 @@ fapi2::ReturnCode set_bad_dq_bitmap(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>
uint8_t (&i_array)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT]);
///
+/// @brief combine the two bad bits arrays into the io_bad_bits array
+/// @param[in] i_new_bad_bits bad bits to append
+/// @param[in,out] io_bad_bits will contain the bitwise or of the original io_bad_bits and i_new_bad_bits
+///
+inline void combine_bad_bits(const uint8_t (&i_new_bad_bits)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT],
+ uint8_t (&io_bad_bits)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT])
+{
+ for (uint8_t l_rank = 0; l_rank < BAD_BITS_RANKS; ++ l_rank)
+ {
+ for (uint8_t l_bad_dq_byte = 0; l_bad_dq_byte < BAD_DQ_BYTE_COUNT; ++l_bad_dq_byte)
+ {
+ io_bad_bits[l_rank][l_bad_dq_byte] |= i_new_bad_bits[l_rank][l_bad_dq_byte];
+ }
+ }
+}
+
+///
/// @brief Records bad bits into the bad bits attribute
/// @tparam MC MC type on which training was run
/// @tparam T fapi2::TargetType on which training was conducted
diff --git a/src/import/generic/memory/lib/utils/mss_field.H b/src/import/generic/memory/lib/utils/mss_field.H
index e22b2fa47..c69bde04f 100644
--- a/src/import/generic/memory/lib/utils/mss_field.H
+++ b/src/import/generic/memory/lib/utils/mss_field.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,8 +37,21 @@
#ifndef _MSS_FIELD_H_
#define _MSS_FIELD_H_
-#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
-#include <generic/memory/lib/utils/mss_generic_check.H>
+#ifdef __PPE__
+ #include <mss_generic_check.H>
+#else
+ #include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+ #include <generic/memory/lib/utils/mss_generic_check.H>
+#endif
+
+//Macro
+#ifdef __PPE__
+ #define TARGIDFORMAT "0x%08X"
+ #define TARGTID i_target.get()
+#else
+ #define TARGIDFORMAT "%s"
+ #define TARGTID spd::c_str(i_target)
+#endif
namespace mss
{
@@ -190,18 +203,18 @@ inline fapi2::ReturnCode get_field(const fapi2::Target<T>& i_target,
.set_LIST_SIZE(i_data.size())
.set_FUNCTION(i_ffdc_codes)
.set_TARGET(i_target),
- "Out of bounds indexing (with %d) on a list of size %d for %s",
+ "Out of bounds indexing (with %d) on a list of size %d for " TARGIDFORMAT,
BYTE,
i_data.size(),
- spd::c_str(i_target));
+ TARGTID);
{
// Extracting desired bits
const fapi2::buffer<OT> l_buffer(i_data[BYTE]);
l_buffer.template extractToRight<F.get_start(), F.get_length()>(o_value);
- FAPI_DBG("%s data[%d] = 0x%02x. Field with start bit %d, bit len %d, has data 0x%02x.",
- spd::c_str(i_target),
+ FAPI_DBG(TARGIDFORMAT " data[%d] = 0x%02x. Field with start bit %d, bit len %d, has data 0x%02x.",
+ TARGTID,
BYTE,
i_data[BYTE],
F.get_start(),
@@ -214,6 +227,7 @@ inline fapi2::ReturnCode get_field(const fapi2::Target<T>& i_target,
fapi_try_exit:
return fapi2::current_err;
}
+#ifndef __PPE__
///
/// @brief Helper function to set byte field information
@@ -274,6 +288,7 @@ inline fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target,
fapi_try_exit:
return fapi2::current_err;
}
+#endif
///
/// @brief byte field reader
@@ -303,7 +318,7 @@ inline fapi2::ReturnCode get_field( const fapi2::Target<T>& i_target,
{
IT l_temp = 0;
FAPI_TRY( (get_field<E, F>(i_target, i_data, i_ffdc_codes, l_temp)),
- "Failed get_field() for %s", spd::c_str(i_target) );
+ "Failed get_field() for " TARGIDFORMAT, TARGTID );
// Test if retrieved data seems valid
FAPI_TRY( check::invalid_value(i_target,
@@ -312,30 +327,33 @@ inline fapi2::ReturnCode get_field( const fapi2::Target<T>& i_target,
typename TT::template COMPARISON_OP<IT>() ),
F.get_byte(i_data),
l_temp,
- i_ffdc_codes),
- "Failed fail_for_invalid_value() for %s", spd::c_str(i_target) );
+ i_ffdc_codes,
+ TT::FIELD_STR),
+ "%s failed check::invalid_value() for %s",
+ TT::FIELD_STR, spd::c_str(i_target) );
// Output should only change if data check passes
o_value = static_cast<OT>(l_temp);
-
FAPI_ASSERT( o_value == l_temp,
fapi2::MSS_CONVERSION_ERROR()
.set_ORIGINAL_VAL(l_temp)
.set_CONVERTED_VAL(o_value)
.set_TARGET(i_target)
.set_FUNCTION(i_ffdc_codes),
- "Conversion error between original %d to converted %d value for %s",
- l_temp, o_value, spd::c_str(i_target) );
+ "Conversion error between original %d to converted %d value for " TARGIDFORMAT,
+ l_temp, o_value, TARGTID);
- FAPI_INF("%s: 0x%02x for %s",
+ FAPI_DBG("%s: 0x%02x for %s",
TT::FIELD_STR,
o_value,
spd::c_str(i_target));
+
fapi_try_exit:
return fapi2::current_err;
}
+#ifndef __PPE__
///
/// @brief byte field writer
/// @tparam E endian type
@@ -378,7 +396,7 @@ inline fapi2::ReturnCode set_field( const fapi2::Target<T>& i_target,
FAPI_TRY( (set_field<E, F>(i_target, i_setting, i_ffdc_codes, io_data)),
"Failed set_field() for %s", spd::c_str(i_target) );
- FAPI_INF("%s: Set value of 0x%02x. Data for buffer at byte %d, is now 0x%02x for %s",
+ FAPI_DBG("%s: Set value of 0x%02x. Data for buffer at byte %d, is now 0x%02x for %s",
TT::FIELD_STR,
i_setting,
BYTE,
@@ -388,6 +406,7 @@ inline fapi2::ReturnCode set_field( const fapi2::Target<T>& i_target,
fapi_try_exit:
return fapi2::current_err;
}
+#endif
}// mss
diff --git a/src/import/generic/memory/lib/utils/mss_generic_check.H b/src/import/generic/memory/lib/utils/mss_generic_check.H
index f31440e14..45428b8c3 100644
--- a/src/import/generic/memory/lib/utils/mss_generic_check.H
+++ b/src/import/generic/memory/lib/utils/mss_generic_check.H
@@ -37,15 +37,18 @@
#define _MSS_GENERIC_CHECK_H_
#include <fapi2.H>
-#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
-#include <generic/memory/lib/utils/scom.H>
-#include <generic/memory/lib/utils/c_str.H>
+
+#ifndef __PPE__
+ #include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+ #include <generic/memory/lib/utils/scom.H>
+ #include <generic/memory/lib/utils/c_str.H>
+#endif
namespace mss
{
namespace check
{
-
+#ifndef __PPE__
///
/// @brief Checks whether any FIRs have lit up on a target
/// @tparam MC MC type for which to check FIR's
@@ -175,6 +178,7 @@ fapi2::ReturnCode fir_or_pll_fail( const fapi2::Target<T>& i_target,
#endif
}
+#endif
///
/// @brief Checks conditional passes and implements traces & exits if it fails
/// @tparam T fapi2 target type
@@ -196,6 +200,18 @@ inline fapi2::ReturnCode invalid_value(const fapi2::Target<T>& i_target,
const FFDC i_ffdc_codes,
const char* i_err_str = "")
{
+#ifdef __PPE__
+ FAPI_ASSERT(i_conditional,
+ fapi2::MSS_FAILED_DATA_INTEGRITY_CHECK().
+ set_VALUE(i_data).
+ set_BYTE(i_byte_index).
+ set_TARGET(i_target).
+ set_FFDC_CODE(i_ffdc_codes),
+ "%s Byte %d, Data returned: %d.",
+ i_err_str,
+ i_byte_index,
+ i_data);
+#else
FAPI_ASSERT(i_conditional,
fapi2::MSS_FAILED_DATA_INTEGRITY_CHECK().
set_VALUE(i_data).
@@ -208,6 +224,7 @@ inline fapi2::ReturnCode invalid_value(const fapi2::Target<T>& i_target,
i_byte_index,
i_data);
+#endif
return fapi2::FAPI2_RC_SUCCESS;
fapi_try_exit:
diff --git a/src/import/generic/memory/lib/utils/mss_math.H b/src/import/generic/memory/lib/utils/mss_math.H
index ebb3da8e3..b3ff26fde 100644
--- a/src/import/generic/memory/lib/utils/mss_math.H
+++ b/src/import/generic/memory/lib/utils/mss_math.H
@@ -107,6 +107,35 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief Round value to a multiple of another number
+///
+/// @param[in] i_value value to round
+/// @param[in] i_multiple multiple to round to
+/// @return uint64_t rounded value
+///
+inline uint32_t round_to_nearest_multiple(const uint32_t i_value, const uint32_t i_multiple)
+{
+ return ((i_value + i_multiple / 2) / i_multiple) * i_multiple;
+}
+
+///
+/// @brief Determines if the double has decimal digits and adds 1 and rounds if true
+/// @param[in] i_val the double to be rounded up if trialing digits
+/// @return the input value rounded up to the next whole digit
+/// @note Called in p9_mss_bulk_pwr_throttles
+///
+inline uint32_t round_up(const double i_val)
+{
+ //convert to uint to truncate decimals and convert back to double for comparison
+ uint32_t temp = uint32_t (i_val);
+
+ //if not equal, lost something from truncating, so add 1
+ temp += (temp == i_val) ? 0 : 1;
+
+ //Truncate final value
+ return temp;
+}
}// mss
diff --git a/src/import/generic/memory/lib/utils/mss_rank.H b/src/import/generic/memory/lib/utils/mss_rank.H
index b43e7e6ff..f4731df46 100644
--- a/src/import/generic/memory/lib/utils/mss_rank.H
+++ b/src/import/generic/memory/lib/utils/mss_rank.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,327 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mss_rank.H
+/// @brief Tools to obtain rank info from DIMM or PORT target
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_GENERIC_RANK_H_
+#define _MSS_GENERIC_RANK_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/index.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
+namespace mss
+{
+namespace rank
+{
+
+///
+/// @brief Rank traits class for variations depending on MC
+/// @tparam MC the memory controller type
+///
+template <mss::mc_type MC = DEFAULT_MC_TYPE>
+class rankTraits;
+
+///
+/// @brief Rank info class
+/// @tparam MC the memory controller type
+/// @tparam TT the class traits for the port
+///
+template <mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = rankTraits<MC>>
+class info
+{
+
+ public:
+ // Delete default constructor
+ info() = delete;
+
+ ///
+ /// @brief Constructor for info object
+ /// @param[in] i_target DIMM target
+ /// @param[in] i_index dimm rank index 0-3
+ /// @param[out] o_rc return code, FAPI2_RC_SUCCESS if no error
+ ///
+ info(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_dimm_target, const uint8_t i_index, fapi2::ReturnCode& o_rc)
+ {
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ uint8_t l_master_ranks_per_dimm = 0;
+ FAPI_TRY(mss::attr::get_num_master_ranks_per_dimm(i_dimm_target, l_master_ranks_per_dimm));
+
+ FAPI_ASSERT((i_index < l_master_ranks_per_dimm),
+ fapi2::MSS_RANK_OUT_OF_RANGE()
+ .set_TARGET(i_dimm_target)
+ .set_RANK(i_index),
+ "Rank %u provided to info constructor for DIMM %s exceeded the number of master ranks per DIMM",
+ i_index, mss::c_str(i_dimm_target));
+ // Targets
+ iv_dimm_target = i_dimm_target;
+ iv_port_target = mss::find_target<DEFAULT_MEM_PORT_TARGET>(i_dimm_target);
+
+ // Ranks
+ iv_dimm_rank = i_index;
+ iv_port_rank = iv_dimm_rank + ((mss::index(i_dimm_target) * TT::RANK_INDEX_STEP));
+ iv_phy_rank = iv_dimm_rank + ((mss::index(i_dimm_target) * TT::PHY_RANK_INDEX_STEP));
+ fapi_try_exit:
+ o_rc = fapi2::current_err;
+ }
+
+ ///
+ /// @brief Constructor for info object
+ /// @param[in] i_target PORT target
+ /// @param[in] i_index port rank index 0-7
+ /// @param[out] o_rc return code, FAPI2_RC_SUCCESS if no error
+ ///
+ info(const fapi2::Target<DEFAULT_MEM_PORT_TARGET>& i_port_target, const uint8_t i_index, fapi2::ReturnCode& o_rc)
+ {
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ // Dimm Target
+ const uint8_t l_target_index = i_index / TT::RANK_INDEX_STEP;
+ const auto l_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_port_target);
+
+ // This assumes that the mc_type max # of dimms per port is correct
+ FAPI_ASSERT( !l_dimms.empty(),
+ fapi2::MSS_EMPTY_VECTOR().
+ set_FUNCTION(INIT_RANK_INFO).
+ set_TARGET(i_port_target),
+ "Empty dimm vector received on port %s",
+ mss::spd::c_str(i_port_target));
+
+ {
+ // This will remain false in two cases:
+ // Either:
+ // 1. The corresponding DIMM index is out of range (caused by port index out of range)
+ // 2. The corresponding DIMMs master_ranks_per_dimm is less than the desired rank
+ bool l_valid_rank = false;
+
+ for (const auto& l_dimm : l_dimms)
+ {
+ // Since we can't guarantee the order of the returned dimms, we iterate through until we (might) find
+ // the right one. There's a chance it may not exist for example given info(port, rank13) would give us
+ // a dimm index above 2, which may be out of range, so we could never find a matching dimm, so we will
+ // throw that error.
+ // If we do find the right dimm, we need to then make sure that the master_ranks_per_dimm attribute
+ // is greater than the expected dimm rank.
+ if (mss::index(l_dimm) == l_target_index)
+ {
+ uint8_t l_master_ranks_per_dimm = 0;
+ FAPI_TRY(mss::attr::get_num_master_ranks_per_dimm(l_dimm, l_master_ranks_per_dimm));
+
+ // The rank passed in matches one of a valid DIMM
+ l_valid_rank = (i_index % TT::RANK_INDEX_STEP) < l_master_ranks_per_dimm;
+
+ iv_dimm_target = l_dimm;
+ }
+ }
+
+ FAPI_ASSERT(l_valid_rank,
+ fapi2::MSS_RANK_OUT_OF_RANGE()
+ .set_TARGET(i_port_target)
+ .set_RANK(i_index),
+ "Rank %u provided to rank_info constructor for PORT %s was out of range",
+ i_index, mss::c_str(i_port_target));
+
+ // Port Target
+ iv_port_target = i_port_target;
+
+ // Ranks
+ iv_dimm_rank = i_index % TT::RANK_INDEX_STEP;
+ iv_phy_rank = get_phy_rank_from_port_rank(i_index);
+ iv_port_rank = i_index;
+ }
+
+ fapi_try_exit:
+ o_rc = fapi2::current_err;
+ }
+
+ ///
+ /// @brief Accessor for port rank
+ /// @return the number (0-7) of the rank within its port
+ ///
+ inline const uint8_t get_port_rank() const
+ {
+ return iv_port_rank;
+ }
+
+ ///
+ /// @brief Accessor for rank number of DIMM
+ /// @return the number (0-3) of the DIMM
+ ///
+ inline const uint8_t get_dimm_rank() const
+ {
+ return iv_dimm_rank;
+ }
+
+ ///
+ /// @brief Accessor for phy rank
+ /// @return the phy rank value
+ /// @note in a hypothetical 2 4-rank dimm configuration (not possible), this value is not valid
+ ///
+ inline const uint8_t get_phy_rank() const
+ {
+ return iv_phy_rank;
+ }
+
+ ///
+ /// @brief Accessor for DIMM target
+ /// @return the dimm target associated with the rank
+ ///
+ inline const fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_dimm_target() const
+ {
+ return iv_dimm_target;
+ }
+
+ ///
+ /// @brief Accessor for PORT target
+ /// @return the port target associated with the rank
+ ///
+ inline const fapi2::Target<DEFAULT_MEM_PORT_TARGET> get_port_target() const
+ {
+ return iv_port_target;
+ }
+
+ ///
+ /// @brief Calculate phy rank given port rank (unit testable)
+ ///
+ /// @param[in] l_port_rank port rank
+ /// @return phy rank
+ ///
+ inline static uint8_t get_phy_rank_from_port_rank(const uint8_t i_port_rank)
+ {
+ const uint8_t l_dimm_rank = i_port_rank % TT::RANK_INDEX_STEP;
+ const uint8_t l_dimm_index = i_port_rank / TT::RANK_INDEX_STEP;
+
+ // Dimm index * 2 sets the center point at 2
+ // Add on the dimm rank
+ // Note that this logic does NOT apply in a hypothetical/impossible 2 4-rank dimm configuration
+ return ((l_dimm_index * TT::PHY_RANK_INDEX_STEP) + (l_dimm_rank));
+ }
+
+ private:
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_dimm_target;
+ fapi2::Target<DEFAULT_MEM_PORT_TARGET> iv_port_target;
+ uint8_t iv_dimm_rank;
+ uint8_t iv_port_rank;
+
+ // Note! a configuration of 2 4-rank dimms is not possible.
+ // In this hypothetical scenario, the value for phy-rank would not
+ // be valid / does not apply, as there will be some rollover.
+ // 1 rank-per-dimm: 0 dimm0 2 dimm1
+ // 2 rank-per-dimm: 0/1 dimm0 2/3 dimm1.
+ // 2 rank single dimm 0/1
+ // 4 rank (quad encoded) 0-3.
+ uint8_t iv_phy_rank;
+};
+
+///
+/// @brief Obtains all DIMM ranks on a given port target
+/// @tparam MC the memory controller type
+/// @tparam TT the class traits for the port
+/// @param[in] i_port_target port target
+/// @param[out] o_vect vector of ranks
+/// @return FAPI2_RC_SUCCESS iff success
+///
+template <mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = rankTraits<MC>>
+fapi2::ReturnCode ranks_on_port(const fapi2::Target<DEFAULT_MEM_PORT_TARGET>& i_port_target,
+ std::vector<info<MC>>& o_vect)
+{
+ o_vect.clear();
+
+ uint8_t l_master_ranks_per_dimm[TT::MAX_DIMMS_PER_PORT] = {0};
+ FAPI_TRY(mss::attr::get_num_master_ranks_per_dimm(i_port_target, l_master_ranks_per_dimm));
+
+ FAPI_ASSERT(((l_master_ranks_per_dimm[0] <= TT::MAX_RANKS_PER_DIMM) &&
+ (l_master_ranks_per_dimm[1] <= TT::MAX_RANKS_PER_DIMM)),
+ fapi2::MSS_TOO_MANY_PRIMARY_RANKS_ON_PORT()
+ .set_PORT_TARGET(i_port_target),
+ "Primary ranks on PORT %s exceeded %u",
+ mss::c_str(i_port_target),
+ TT::MAX_RANKS_PER_DIMM);
+
+ for (const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_port_target))
+ {
+ const uint8_t l_dimm_index = mss::index(l_dimm);
+ const uint8_t l_port_index_start = l_dimm_index * TT::RANK_INDEX_STEP;
+
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ // For each rank index of the dimm from the port's perspective
+ for (uint8_t l_index = l_port_index_start; l_index < (l_port_index_start + l_master_ranks_per_dimm[l_dimm_index]);
+ ++l_index)
+ {
+ o_vect.push_back(mss::rank::info<>(i_port_target, l_index, l_rc));
+ FAPI_TRY(l_rc);
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Obtains all ranks on a given DIMM target
+/// @tparam MC the memory controller type
+/// @tparam TT the class traits for the port
+/// @param[in] i_target DIMM target
+/// @param[out] o_vect vector of ranks
+/// @return FAPI2_RC_SUCCESS iff success
+///
+template <mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = rankTraits<MC>>
+fapi2::ReturnCode ranks_on_dimm(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_dimm_target,
+ std::vector<info<MC>>& o_vect)
+{
+ o_vect.clear();
+ uint8_t l_master_ranks_per_dimm = 0;
+ FAPI_TRY(mss::attr::get_num_master_ranks_per_dimm(i_dimm_target, l_master_ranks_per_dimm));
+
+ FAPI_ASSERT(l_master_ranks_per_dimm <= TT::MAX_RANKS_PER_DIMM,
+ fapi2::MSS_TOO_MANY_PRIMARY_RANKS_ON_DIMM()
+ .set_RANK_COUNT(l_master_ranks_per_dimm)
+ .set_DIMM_TARGET(i_dimm_target),
+ "Seeing %d primary ranks on DIMM %s",
+ l_master_ranks_per_dimm,
+ mss::c_str(i_dimm_target));
+ {
+ // Return code for constructor call
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ // For each rank index from the dimm's perspective
+ for (uint8_t l_index = 0; l_index < l_master_ranks_per_dimm; l_index++)
+ {
+ o_vect.push_back(mss::rank::info<>(i_dimm_target, l_index, l_rc));
+ FAPI_TRY(l_rc, "ranks_on_dimm(): Error in rank::info constructor call for DIMM %s and rank %u",
+ mss::c_str(i_dimm_target), l_index);
+ }
+ }
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Return a vector of rank numbers which represent the ranks for this dimm
+/// @tparam MC the memory controller type
+/// @param[in] i_dimm_target TARGET_TYPE_DIMM
+/// @param[out] o_ranks a vector of ranks for dimm (numbers)
+/// @return FAPI2_RC_SUCCESS iff all is ok
+///
+template<mss::mc_type MC>
+fapi2::ReturnCode ranks_on_dimm_helper(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_dimm_target,
+ std::vector<uint64_t>& o_ranks);
+
+} // rank
+} // mss
+#endif
diff --git a/src/import/generic/memory/lib/utils/num.H b/src/import/generic/memory/lib/utils/num.H
index 62332bb65..327aca84f 100644
--- a/src/import/generic/memory/lib/utils/num.H
+++ b/src/import/generic/memory/lib/utils/num.H
@@ -22,3 +22,34 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file num.H
+/// @brief Miscellaneous number checking functions
+///
+// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _GEN_MSS_NUM_H_
+#define _GEN_MSS_NUM_H_
+
+namespace mss
+{
+
+///
+/// @brief Return whether or not a number is odd
+/// @param[in] i_number the number to check
+/// @return true if i_number is odd
+///
+template< typename T >
+constexpr bool is_odd(const T i_number)
+{
+ return (i_number & 0x1);
+}
+
+
+}
+#endif
diff --git a/src/import/generic/memory/lib/utils/power_thermal/gen_decoder.H b/src/import/generic/memory/lib/utils/power_thermal/gen_decoder.H
index 7e2c47406..f2d6370be 100644
--- a/src/import/generic/memory/lib/utils/power_thermal/gen_decoder.H
+++ b/src/import/generic/memory/lib/utils/power_thermal/gen_decoder.H
@@ -22,3 +22,587 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gen_decoder.H
+/// @brief Decoder for ATTR_MSS_MRW_PWR_CURVE_SLOPE and _INTERCEPT and THERMAL_POWER_LIMIT
+///
+// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_GEN_POWER_DECODER__
+#define _MSS_GEN_POWER_DECODER__
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+#include <generic/memory/lib/utils/power_thermal/gen_throttle_traits.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
+
+namespace mss
+{
+
+namespace power_thermal
+{
+
+constexpr uint32_t ANY_SIZE = 0xFFFFFFFF;
+constexpr uint8_t ANY_TYPE = 0xFF;
+constexpr uint8_t ANY_GEN = 0xFF;
+constexpr uint8_t ANY_WIDTH = 0xFF;
+constexpr uint8_t ANY_DENSITY = 0xFF;
+constexpr uint8_t ANY_STACK_TYPE = 0xFF;
+constexpr uint16_t ANY_MFGID = 0xFFFF;
+constexpr uint8_t ANY_HEIGHT = 0xFF;
+constexpr uint8_t ANY_PORT = 0xFF;
+
+//Currently needs to be in sorted order for lookup to work
+static const std::vector< std::pair<uint32_t , uint8_t> > DIMM_SIZE_MAP =
+{
+ {4, 0b0000},
+ {8, 0b0001},
+ {16, 0b0010},
+ {32, 0b0011},
+ {64, 0b0100},
+ {128, 0b0101},
+ {256, 0b0110},
+ {512, 0b0111},
+ {ANY_SIZE, 0b1111}
+};
+
+
+
+static const std::vector< std::pair<uint8_t , uint8_t> > DRAM_GEN_MAP =
+{
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_GEN_EMPTY, 0b00},
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_GEN_DDR3, 0b01},
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_GEN_DDR4, 0b10},
+ {ANY_GEN, 0b11}
+};
+
+static const std::vector <std::pair<uint8_t, uint8_t> > DRAM_WIDTH_MAP =
+{
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_WIDTH_X4, 0b000},
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_WIDTH_X8, 0b001},
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_WIDTH_X16, 0b010},
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_WIDTH_X32, 0b011},
+ {ANY_WIDTH, 0b111}
+};
+
+static const std::vector< std::pair<uint8_t , uint8_t> > DRAM_DENSITY_MAP =
+{
+ {4, 0b000},
+ {8, 0b001},
+ {16, 0b010},
+ {32, 0b011},
+ {64, 0b100},
+ {ANY_DENSITY, 0b111}
+};
+
+static const std::vector <std::pair<uint8_t, uint8_t> > DRAM_STACK_TYPE_MAP =
+{
+ {fapi2::ENUM_ATTR_MEM_EFF_PRIM_STACK_TYPE_SDP, 0b00},
+ {fapi2::ENUM_ATTR_MEM_EFF_PRIM_STACK_TYPE_DDP_QDP, 0b01},
+ {fapi2::ENUM_ATTR_MEM_EFF_PRIM_STACK_TYPE_3DS, 0b10},
+ {ANY_STACK_TYPE, 0b11}
+};
+
+//Note, the first entries of the pairs need to be in sorted order!!
+static const std::vector <std::pair<uint16_t, uint8_t> > DRAM_MFGID_MAP =
+{
+ //Kingston
+ {0x0198, 0b011},
+ //A-data
+ {0x04CB, 0b101},
+ //Micron
+ {0x802C, 0b000},
+ //HYNIX
+ {0x80AD, 0b001},
+ //SAMSUNG
+ {0x80CE, 0b010},
+ //Innodisk
+ {0x86F1, 0b100},
+ // ANY
+ {ANY_MFGID, 0b111}
+};
+
+static const std::vector< std::pair<uint8_t , uint8_t> > DIMM_MODULE_HEIGHT_MAP =
+{
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_MODULE_HEIGHT_1U, 0b00},
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_MODULE_HEIGHT_2U, 0b01},
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_MODULE_HEIGHT_4U, 0b10},
+ {ANY_HEIGHT, 0b11}
+};
+
+static const std::vector < std::pair< uint8_t, uint8_t> > DIMMS_PORT_MAP =
+{
+ //Num dimms per MCA, only 1 or 2 possible options. 0 is no-op
+ {1, 0b00},
+ {2, 0b01},
+ {ANY_PORT, 0b11}
+};
+
+// Forward declaration
+template<mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = throttle_traits<MC>>
+fapi2::ReturnCode generate_wildcard_mask(const uint32_t i_hash, uint32_t& o_mask);
+
+
+///
+///@brief a compare functor for the decoder::find_attr functions below
+/// @tparam MC mss::mc_type
+///
+template<mss::mc_type MC = DEFAULT_MC_TYPE>
+struct is_match
+{
+ ///
+ ///@brief functor constructor
+ ///@param[in] i_gen_key the class object's constructed hash for the installed dimm, to be compared with the attr array
+ ///
+ is_match(const uint32_t i_gen_key) : iv_gen_key(i_gen_key) {}
+ const fapi2::buffer<uint32_t> iv_gen_key;
+
+ ///
+ ///@brief Boolean compare used for find_if function
+ ///
+ bool operator()(const uint64_t i_hash)
+ {
+ // l_this_hash is the first half of the i_hash's bits
+ const uint32_t l_this_hash = i_hash >> 32;
+ uint32_t l_wildcard_mask = 0;
+
+ // Get wildcard mask. If the decoding fails(value to key), we should continue
+ generate_wildcard_mask<MC>(l_this_hash, l_wildcard_mask);
+
+ // Mask the wildcard bits
+ return ((l_this_hash | l_wildcard_mask) == (iv_gen_key | l_wildcard_mask));
+ }
+};
+
+///
+/// @brief Encode the attribute into a bit encoding
+/// @tparam S *ATTR*_SIZE enum used for fapi2::buffer position
+/// @tparam L *ATTR*_LEN enum used for fapi2::buffer position
+/// @tparam T integral type of key
+/// @tparam OT fapi2::buffer of some integral type
+/// @param[in] i_target the DIMM the encoding is for
+/// @param[in] i_attr the attribute key being used for the encoding
+/// @param[in] i_map a vector of pairs of the ATTR values and encodings for each value, sorted
+/// @param[out] o_buf the fapi2::buffer where the encoding is going into
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff attribute is found in map lookup
+///
+template<size_t S, size_t L, typename T, typename OT>
+inline fapi2::ReturnCode encode ( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const T& i_attr,
+ const std::vector<std::pair<T, OT> >& i_map,
+ fapi2::buffer<uint32_t>& o_buf)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ //used to hold result from vector pair lookup
+ OT l_encoding = 0;
+
+ //Failing out if we don't find an encoding. All suported types should be encoded above
+ FAPI_ASSERT( mss::find_value_from_key (i_map, i_attr, l_encoding),
+ fapi2::MSS_POWER_THERMAL_ENCODE_ERROR()
+ .set_ATTR(i_attr)
+ .set_DIMM_TARGET(i_target),
+ "Couldn't find encoding for power thermal encode for value: %x target: %s", i_attr, mss::c_str(i_target));
+ o_buf.insertFromRight<S, L>(l_encoding);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decode the attribute into a bit encoding
+/// @tparam S DRAM_GEN_SIZE enum used for fapi2::buffer position
+/// @tparam L DRAM_GEN_LEN enum used for fapi2::buffer position
+/// @tparam T integral type of key
+/// @tparam OT fapi2::buffer of some integral type
+/// @param[in] i_map a vector of pairs of the ATTR values and encodings for each value
+/// @param[in] i_buf the fapi2::buffer that has the encoding to parse
+/// @param[out] o_attr the attribute value from the encoding is going
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff attribute is found in map lookup
+///
+template<size_t S, size_t L, typename T, typename OT>
+inline fapi2::ReturnCode decode (const std::vector<std::pair<T, OT> >& i_map,
+ fapi2::buffer<uint32_t>& i_buf,
+ T& o_attr )
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ //used to hold result from vector pair lookup
+ OT l_encoding = 0;
+ i_buf.extractToRight<S, L>(l_encoding);
+
+ //Failing out if we don't find an decoding. All suported types should be encoded above
+ FAPI_ASSERT( mss::find_key_from_value (i_map, l_encoding, o_attr),
+ fapi2::MSS_POWER_THERMAL_DECODE_ERROR()
+ .set_ATTR(l_encoding),
+ "Couldn't find encoding for power thermal decode");
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief generates wildcard mask for the hash value
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+/// @tparam MC mss::mc_type
+/// @tparam TT throttle_traits throttle traits for the given mc_type
+/// @param[in] i_hash The encoded value
+/// @param[out] o_mask The wildcard mask
+///
+
+template<mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = throttle_traits<MC>>
+fapi2::ReturnCode generate_wildcard_mask(const uint32_t i_hash, uint32_t& o_mask)
+{
+
+ fapi2::buffer<uint32_t> l_mask;
+ fapi2::buffer<uint32_t> l_hash = i_hash;
+ uint8_t l_uint8_buf = 0;
+ uint16_t l_uint16_buf = 0;
+ uint32_t l_uint32_buf = 0;
+
+ //DIMM_SIZE wildcard
+ FAPI_TRY(( decode<TT::DIMM_SIZE_START, TT::DIMM_SIZE_LEN>
+ (DIMM_SIZE_MAP, l_hash, l_uint32_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DIMM_SIZE", l_hash );
+
+ if(ANY_SIZE == l_uint32_buf)
+ {
+ l_mask.setBit<TT::DIMM_SIZE_START, TT::DIMM_SIZE_LEN>();
+ }
+
+ //DRAM_GEN wildcard
+ FAPI_TRY(( decode<TT::DRAM_GEN_START, TT::DRAM_GEN_LEN>
+ (DRAM_GEN_MAP, l_hash, l_uint8_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DRAM_GEN", l_hash);
+
+ if(ANY_GEN == l_uint8_buf)
+ {
+ l_mask.setBit<TT::DRAM_GEN_START, TT::DRAM_GEN_LEN>();
+ }
+
+ //DIMM_TYPE wildcard
+ FAPI_TRY(( decode<TT::DIMM_TYPE_START, TT::DIMM_TYPE_LEN>
+ (TT::DIMM_TYPE_MAP, l_hash, l_uint8_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DIMM_TYPE", l_hash);
+
+ if(ANY_TYPE == l_uint8_buf)
+ {
+ l_mask.setBit<TT::DIMM_TYPE_START, TT::DIMM_TYPE_LEN>();
+ }
+
+ //DRAM_WIDTH wildcard
+ FAPI_TRY(( decode<TT::DRAM_WIDTH_START, TT::DRAM_WIDTH_LEN>
+ (DRAM_WIDTH_MAP, l_hash, l_uint8_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DRAM_WIDTH", l_hash);
+
+ if(ANY_WIDTH == l_uint8_buf)
+ {
+ l_mask.setBit<TT::DRAM_WIDTH_START, TT::DRAM_WIDTH_LEN>();
+ }
+
+ //DRAM_DENSITY wildcard
+ FAPI_TRY(( decode<TT::DRAM_DENSITY_START, TT::DRAM_DENSITY_LEN>
+ (DRAM_DENSITY_MAP, l_hash, l_uint8_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DRAM_DENSITY", l_hash);
+
+ if(ANY_DENSITY == l_uint8_buf)
+ {
+ l_mask.setBit<TT::DRAM_DENSITY_START, TT::DRAM_DENSITY_LEN>();
+ }
+
+ //DRAM_STACK_TYPE wildcard
+ FAPI_TRY(( decode<TT::DRAM_STACK_TYPE_START, TT::DRAM_STACK_TYPE_LEN>
+ (DRAM_STACK_TYPE_MAP, l_hash, l_uint8_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DRAM_STACK_TYPE", l_hash);
+
+ if(ANY_STACK_TYPE == l_uint8_buf)
+ {
+ l_mask.setBit<TT::DRAM_STACK_TYPE_START, TT::DRAM_STACK_TYPE_LEN>();
+ }
+
+ //DRAM_MFGID wildcard
+ FAPI_TRY(( decode<TT::DRAM_MFGID_START, TT::DRAM_MFGID_LEN>
+ (DRAM_MFGID_MAP, l_hash, l_uint16_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DRAM_MFG_ID", l_hash);
+
+ if(ANY_MFGID == l_uint16_buf)
+ {
+ l_mask.setBit<TT::DRAM_MFGID_START, TT::DRAM_MFGID_LEN>();
+ }
+
+
+ if (TT::MC_TARGET_TYPE == fapi2::TARGET_TYPE_MCS)
+ {
+ //NUM DROPS PER PORT wildcard
+ FAPI_TRY(( decode<TT::DIMMS_PER_PORT_START, TT::DIMMS_PER_PORT_LEN>
+ (DIMMS_PORT_MAP, l_hash, l_uint8_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DIMMS_PER_PORT", l_hash);
+
+ if(ANY_PORT == l_uint8_buf)
+ {
+ l_mask.setBit<TT::DIMMS_PER_PORT_START, TT::DIMMS_PER_PORT_LEN>();
+ }
+ }
+
+ if (TT::MC_TARGET_TYPE == fapi2::TARGET_TYPE_OCMB_CHIP)
+ {
+ //MODUEL HEIGHT wildcard
+ FAPI_TRY(( decode<TT::DIMM_MODULE_HEIGHT_START, TT::DIMM_MODULE_HEIGHT_LEN>
+ (DIMM_MODULE_HEIGHT_MAP, l_hash, l_uint8_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DIMMS_MODULE_HEIGHT", l_hash);
+
+ if(ANY_HEIGHT == l_uint8_buf)
+ {
+ l_mask.setBit<TT::DIMM_MODULE_HEIGHT_START, TT::DIMM_MODULE_HEIGHT_LEN>();
+ }
+ }
+
+ o_mask = l_mask;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @class decoder
+/// @brief Decodes the power curve and thermal power limit attributes for eff_config_thermal
+/// @tparam MC mss::mc_type
+/// @tparam TT throttle_traits throttle traits for the given mc_type
+///
+template<mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = throttle_traits<MC>>
+class decoder
+{
+ public:
+
+ //IVs for all of the attributes per MCS
+ const mss::dimm::kind<MC> iv_kind;
+
+ //Left in here rather than calculating during encode for testing
+ uint8_t iv_dimms_per_port;
+
+ //Power thermal attributes, both total and vddr versions will be used in eff_config_thermal
+ uint16_t iv_vddr_slope = 0;
+ uint16_t iv_vddr_intercept = 0;
+ uint16_t iv_total_slope = 0;
+ uint16_t iv_total_intercept = 0;
+
+ // Valid for OCMB only
+ uint32_t iv_power_limit = 0 ;
+
+ uint32_t iv_thermal_power_limit = 0;
+
+ //Generated key, used to decode all three power curve attributes
+ fapi2::buffer<uint32_t> iv_gen_key;
+
+ ///
+ /// @brief Constructor
+ /// @param[in] dimm::kind to call power thermal stuff on
+ ///
+ decoder( const mss::dimm::kind<MC>& i_kind):
+ iv_kind(i_kind)
+ {
+ iv_dimms_per_port = mss::count_dimm (find_target<TT::PORT_TARGET_TYPE>(iv_kind.iv_target));
+ };
+
+ //
+ // @brief Default destructor
+ //
+ ~decoder() = default;
+
+ ///
+ /// @brief generates the 32 bit encoding for the power curve attributes
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+ /// @note populates iv_gen_key
+ ///
+ fapi2::ReturnCode generate_encoding ();
+
+ ///
+ /// @brief Finds a value for the power curve slope attributes by matching the generated hashes
+ /// @param[in] i_array is a vector of the attribute values
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+ /// @note populates iv_vddr_slope, iv_total_slope
+ ///
+ fapi2::ReturnCode find_slope (const std::vector< const std::vector<uint64_t>* >& i_slope);
+
+ ///
+ /// @brief Finds a value for power curve intercept attributes by matching the generated hashes
+ /// @param[in] i_array is a vector of the attribute values
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+ /// @note populates iv_vddr_intercept, iv_total_intercept
+ ///
+ fapi2::ReturnCode find_intercept (const std::vector< const std::vector<uint64_t>* >& i_intercept);
+
+ ///
+ /// @brief Finds a value from ATTR_MSS_MRW_THERMAL_MEMORY_POWER_LIMIT and stores in iv variable
+ /// @param[in] i_array is a vector of the attribute values
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+ /// @note populates iv_thermal_power_limit
+ ///
+ fapi2::ReturnCode find_thermal_power_limit (const std::vector< const std::vector<uint64_t>* >& i_thermal_limits);
+
+ ///
+ /// @brief Helper function to find the value from attribute
+ /// @tparam FIELD_START the field start offset inside attribute
+ /// @tparam FIELD_LEN the field length to extract
+ /// @tparam FUNCTION the function of the field
+ /// @tparam OT output type
+ /// @param[in] i_array is a vector of the attribute values
+ /// @param[in] i_attr_description the attribute description
+ /// @param[out] o_value the output value
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+ /// @note populates iv_thermal_power_limit
+ ///
+ template<size_t FIELD_START, size_t FIELD_LEN, generic_ffdc_codes FUNCTION, typename OT>
+ fapi2::ReturnCode get_power_thermal_value(const std::vector<uint64_t>& i_array,
+ const char* const i_attr_description,
+ OT& o_value);
+};
+
+///
+/// @brief generates the 32 bit encoding for the power curve attributes
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+/// @note populates iv_gen_keys
+///
+template<mss::mc_type MC, typename TT>
+fapi2::ReturnCode decoder<MC, TT>::generate_encoding()
+{
+ //DIMM_SIZE
+ FAPI_TRY(( encode<TT::DIMM_SIZE_START, TT::DIMM_SIZE_LEN>
+ (iv_kind.iv_target, iv_kind.iv_size, DIMM_SIZE_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DIMM_SIZE", iv_kind.iv_size, mss::c_str(iv_kind.iv_target) );
+
+ //DRAM_GEN
+ FAPI_TRY(( encode<TT::DRAM_GEN_START, TT::DRAM_GEN_LEN>
+ (iv_kind.iv_target, iv_kind.iv_dram_generation, DRAM_GEN_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DRAM_GEN", iv_kind.iv_dram_generation, mss::c_str(iv_kind.iv_target) );
+
+ //DIMM_TYPE
+ FAPI_TRY(( encode<TT::DIMM_TYPE_START, TT::DIMM_TYPE_LEN>
+ (iv_kind.iv_target, iv_kind.iv_dimm_type, TT::DIMM_TYPE_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DIMM_TYPE", iv_kind.iv_dimm_type, mss::c_str(iv_kind.iv_target) );
+
+ //DRAM WIDTH
+ FAPI_TRY(( encode<TT::DRAM_WIDTH_START, TT::DRAM_WIDTH_LEN>
+ (iv_kind.iv_target, iv_kind.iv_dram_width, DRAM_WIDTH_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DRAM_WIDTH", iv_kind.iv_dram_width, mss::c_str(iv_kind.iv_target) );
+
+ //DRAM DENSITY
+ FAPI_TRY(( encode<TT::DRAM_DENSITY_START, TT::DRAM_DENSITY_LEN>
+ (iv_kind.iv_target, iv_kind.iv_dram_density, DRAM_DENSITY_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DRAM_DENSITY", iv_kind.iv_dram_density, mss::c_str(iv_kind.iv_target) );
+
+ //DRAM STACK TYPE
+ FAPI_TRY(( encode<TT::DRAM_STACK_TYPE_START, TT::DRAM_STACK_TYPE_LEN>
+ (iv_kind.iv_target, iv_kind.iv_stack_type, DRAM_STACK_TYPE_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DRAM_STACK_TYPE", iv_kind.iv_stack_type, mss::c_str(iv_kind.iv_target) );
+
+ //DRAM MFG ID
+ FAPI_TRY(( encode<TT::DRAM_MFGID_START, TT::DRAM_MFGID_LEN>
+ (iv_kind.iv_target, iv_kind.iv_mfgid, DRAM_MFGID_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DRAM_MFG_ID", iv_kind.iv_mfgid, mss::c_str(iv_kind.iv_target) );
+
+ if (TT::MC_TARGET_TYPE == fapi2::TARGET_TYPE_MCS)
+ {
+ //NUM DROPS PER PORT
+ FAPI_TRY(( encode<TT::DIMMS_PER_PORT_START, TT::DIMMS_PER_PORT_LEN>
+ (iv_kind.iv_target, iv_dimms_per_port, DIMMS_PORT_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DIMMS_PER_PORT", iv_dimms_per_port, mss::c_str(iv_kind.iv_target) );
+ }
+
+ if (TT::MC_TARGET_TYPE == fapi2::TARGET_TYPE_OCMB_CHIP)
+ {
+ //DIMM_MODULE_HEIGHT
+ FAPI_TRY(( encode<TT::DIMM_MODULE_HEIGHT_START, TT::DIMM_MODULE_HEIGHT_LEN>
+ (iv_kind.iv_target, iv_kind.iv_module_height, DIMM_MODULE_HEIGHT_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DIMM_MODULE_HEIGHT", iv_kind.iv_module_height, mss::c_str(iv_kind.iv_target) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to find the value from attribute
+/// @param[in] i_array is a vector of the attribute values
+/// @param[in] i_attr_description the attribute description
+/// @param[out] o_value the output value
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+/// @note populates iv_thermal_power_limit
+///
+template<mss::mc_type MC, typename TT>
+template<size_t FIELD_START, size_t FIELD_LEN, generic_ffdc_codes FUNCTION, typename OT>
+fapi2::ReturnCode decoder<MC, TT>::get_power_thermal_value(const std::vector<uint64_t>& i_array,
+ const char* const i_attr_description,
+ OT& o_value)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // Find iterator to matching key (if it exists)
+ auto l_value_iterator = std::find_if(i_array.begin(),
+ i_array.end(),
+ is_match<>(iv_gen_key));
+
+ FAPI_ASSERT(l_value_iterator != i_array.end(),
+ fapi2::MSS_NO_POWER_THERMAL_ATTR_FOUND()
+ .set_GENERATED_KEY(iv_gen_key)
+ .set_FUNCTION(FUNCTION)
+ .set_DIMM_TARGET(iv_kind.iv_target)
+ .set_SIZE(iv_kind.iv_size)
+ .set_DRAM_GEN(iv_kind.iv_dram_generation)
+ .set_DIMM_TYPE(iv_kind.iv_dimm_type)
+ .set_DRAM_WIDTH( iv_kind.iv_dram_width)
+ .set_DRAM_DENSITY(iv_kind.iv_dram_density)
+ .set_STACK_TYPE(iv_kind.iv_stack_type)
+ .set_MFGID(iv_kind.iv_mfgid)
+ .set_MODULE_HEIGHT(iv_kind.iv_module_height),
+ "Couldn't find %s value for generated key:0x%08lx, for target %s. "
+ "DIMM values for generated key are "
+ "size is %d, gen is %d, type is %d, width is %d, density %d, stack %d, mfgid %d, dimms %d, height %d",
+ i_attr_description,
+ iv_gen_key,
+ mss::c_str(iv_kind.iv_target),
+ iv_kind.iv_size,
+ iv_kind.iv_dram_generation,
+ iv_kind.iv_dimm_type,
+ iv_kind.iv_dram_width,
+ iv_kind.iv_dram_density,
+ iv_kind.iv_stack_type,
+ iv_kind.iv_mfgid,
+ iv_dimms_per_port,
+ iv_kind.iv_module_height
+ );
+ {
+ const fapi2::buffer<uint64_t> l_temp(*l_value_iterator);
+ l_temp.extractToRight<FIELD_START, FIELD_LEN>(o_value);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // power_thermal
+} // mss
+#endif
diff --git a/src/import/generic/memory/lib/utils/power_thermal/gen_throttle.H b/src/import/generic/memory/lib/utils/power_thermal/gen_throttle.H
index 4d99317bf..0b15b6ab2 100644
--- a/src/import/generic/memory/lib/utils/power_thermal/gen_throttle.H
+++ b/src/import/generic/memory/lib/utils/power_thermal/gen_throttle.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,3 +22,1309 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file gen_throttle.H
+/// @brief throttle API
+///
+
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_GEN_POWER_THROTTLE_
+#define _MSS_GEN_POWER_THROTTLE_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/power_thermal/gen_throttle_traits.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+#include <generic/memory/lib/mss_generic_system_attribute_getters.H>
+#include <generic/memory/lib/mss_generic_system_attribute_setters.H>
+#include <generic/memory/lib/mss_generic_attribute_setters.H>
+#include <generic/memory/lib/utils/mss_math.H>
+#include <generic/memory/lib/utils/pos.H>
+
+namespace mss
+{
+
+namespace power_thermal
+{
+
+///
+/// @brief throttle constants used in the power_thermal functions
+///
+enum throttle_const : size_t
+{
+ /// Dram data bus utilization is bus utilization / 4
+ DRAM_BUS_UTILS = 4,
+
+ /// 10000 to convert to and from c%
+ UTIL_CONVERSION = 10000,
+
+ /// Conversion to percentage
+ PERCENT_CONVERSION = 100,
+
+};
+
+///
+/// @brief Calculate the N throttle for a given dram data bus utilization value
+///
+/// @tparam T1 template parameter, type of input to be processed
+/// @tparam T2 template parameter, type of input to be processed
+/// @param[in] i_dram_util dram data bus utilization value
+/// @param[in] i_throttle_m M throttle value in N/M throttling
+///
+/// @return int32_t calculated N throttle value
+///
+template<typename T1, typename T2>
+inline uint32_t calc_n_from_dram_util(const T1 i_dram_util, const T2 i_throttle_m)
+{
+ constexpr uint64_t CONVERT_ADDR_UTIL_TO_DATA_UTIL = 4;
+
+ return (static_cast<int>(static_cast<double>(i_dram_util)
+ * (i_throttle_m)
+ / (CONVERT_ADDR_UTIL_TO_DATA_UTIL)
+ / (PERCENT_CONVERSION)
+ )
+ );
+}
+
+///
+/// @brief Calculate N (address operations) allowed within a window of M DRAM clocks
+/// @param[in] i_databus_util databus utilization percentage (e.g. 5% = 5)
+/// @param[in] i_num_dram_clocks window of M DRAM clocks
+/// @return number of throttled commands allowed
+/// @note Uses N/M Throttling.
+/// Equation: N = (DRAM data bus utilization * M) / (4 * 10000)
+///
+inline uint32_t throttled_cmds(const uint32_t i_databus_util, const uint32_t i_num_dram_clocks)
+{
+ constexpr uint64_t l_divisor = DRAM_BUS_UTILS * UTIL_CONVERSION;
+ const uint64_t l_dividend = i_databus_util * i_num_dram_clocks;
+ const uint64_t l_result = l_dividend / l_divisor;
+
+ //Make sure N is not equal to 0, or we brick the dram until reboot
+ return ((l_result == 0) ? 1 : l_result);
+}
+
+///
+/// @brief Calculate the port databus utilization based off of N throttles and M dram clocks
+/// @tparam MC mss::mc_type
+/// @tparam TT throttle_traits throttle traits for the given mc_type
+/// @tparam T output type
+/// @param[in] i_n_throttles N (address operations) allowed within a window of M DRAM clocks
+/// @param[in] i_num_dram_clocks window of M DRAM clocks
+/// @param[out] o_calc_util
+/// @return FAPI2_RC_SUCCESS iff method was a success
+/// @note Uses N/M Throttling.
+/// @note DRAM databus utilization = N * 4 * 10000 / M
+///
+template<mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = throttle_traits<MC>, typename T>
+fapi2::ReturnCode calc_util_from_throttles(const uint16_t i_n_throttles,
+ const uint32_t i_num_dram_clocks,
+ T& o_calc_util)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ constexpr uint32_t l_multiplier = DRAM_BUS_UTILS * UTIL_CONVERSION;
+ const uint64_t l_calc_util_uint64 = static_cast<uint64_t>((static_cast<double>(i_n_throttles) * l_multiplier) /
+ i_num_dram_clocks);
+ FAPI_ASSERT( (i_num_dram_clocks != 0),
+ fapi2::MSS_M_DRAM_CLOCKS_EQUALS_ZERO(),
+ "ATTR_MSS_MRW_MEM_M_DRAM_CLOCKS was not set and equals zero");
+
+ o_calc_util = (static_cast<double>(i_n_throttles) * l_multiplier) / i_num_dram_clocks;
+
+ // Best way to check for overflow if o_calc_util can be a double?
+ // If o_calc_util overflows, the value inside will be below the expected outcome
+ // So compare o_calc_util with the calculated value, but store calculated value in largest storage
+ // Compare ">=" because o_calc_util can be a double, and so we can't compare just equality due to truncation
+ FAPI_ASSERT( o_calc_util >= l_calc_util_uint64,
+ fapi2::MSS_OUTPUT_OVERFLOW_CALC_UTIL()
+ .set_RESULT(o_calc_util),
+ "Overflow of output variable in calc_util_from_throttles throttles: %d, multiplier %d, dram_clocks %d",
+ i_n_throttles,
+ l_multiplier,
+ i_num_dram_clocks);
+
+ // Check for the minimum
+ if(o_calc_util < TT::MIN_UTIL)
+ {
+ FAPI_INF("Calculated utilization (%f) is less than the minimum utilization: %lu. Setting to minimum value",
+ o_calc_util, TT::MIN_UTIL);
+ o_calc_util = TT::MIN_UTIL;
+ }
+
+ FAPI_INF("In calc_util_from_throttles, calculated %f for output utilization from throttles:%d, dram_clocks %d",
+ o_calc_util, i_n_throttles, i_num_dram_clocks);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Perform thermal calculations as part of the effective configuration
+/// @tparam MC mss::mc_type
+/// @tparam T the fapi2 target type of the target
+/// @tparam TT throttle_traits throttle traits for the given mc_type
+/// @param[in] i_target the MCS target in which the runtime throttles will be reset
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = throttle_traits<MC>>
+fapi2::ReturnCode restore_runtime_throttles( const fapi2::Target<T>& i_target )
+{
+
+ uint32_t l_max_databus = 0;
+ uint32_t l_throttle_m_clocks = 0;
+
+ FAPI_TRY( mss::attr::get_mrw_mem_m_dram_clocks(l_throttle_m_clocks) );
+ FAPI_TRY( mss::attr::get_mrw_max_dram_databus_util(l_max_databus) );
+
+ //Set runtime throttles to unthrottled value, using max dram utilization and M throttle
+ //Do I need to check to see if any DIMMS configured on the port?
+ for (const auto& l_port : mss::find_targets<TT::PORT_TARGET_TYPE>(i_target))
+ {
+ uint16_t l_run_throttle = 0;
+
+ if (mss::count_dimm (l_port) != 0)
+ {
+ l_run_throttle = mss::power_thermal::throttled_cmds (l_max_databus, l_throttle_m_clocks);
+ }
+
+ FAPI_TRY( mss::attr::set_runtime_mem_throttled_n_commands_per_port( l_port, l_run_throttle) );
+ FAPI_TRY( mss::attr::set_runtime_mem_throttled_n_commands_per_slot( l_port, l_run_throttle) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Update the runtime throttles to the worst case of the general throttle values and the runtime values
+/// @tparam MC mss::mc_type
+/// @tparam T the fapi2 target type of the target
+/// @tparam TT throttle_traits throttle traits for the given mc_type
+/// @param[in] i_target the MCS target in which the runtime throttles will be set
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = throttle_traits<MC>>
+fapi2::ReturnCode update_runtime_throttle(const fapi2::Target<T>& i_target)
+
+{
+
+ if (mss::count_dimm(i_target) == 0)
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ for (const auto& l_port : mss::find_targets<TT::PORT_TARGET_TYPE>(i_target))
+ {
+
+ uint16_t l_run_slot = 0;
+ uint16_t l_run_port = 0;
+ uint16_t l_calc_slot = 0;
+ uint16_t l_calc_port = 0;
+
+ FAPI_TRY(mss::attr::get_runtime_mem_throttled_n_commands_per_slot(l_port, l_run_slot));
+ FAPI_TRY(mss::attr::get_runtime_mem_throttled_n_commands_per_port(l_port, l_run_port));
+ FAPI_TRY(mss::attr::get_mem_throttled_n_commands_per_slot(l_port, l_calc_slot));
+ FAPI_TRY(mss::attr::get_mem_throttled_n_commands_per_port(l_port, l_calc_port));
+
+ //Choose the worst case between runtime and calculated throttles
+ //Have to make sure the calc_slot isn't equal to 0 though
+ l_run_slot = (l_calc_slot != 0) ?
+ std::min(l_run_slot, l_calc_slot) : l_run_slot;
+ l_run_port = (l_calc_port != 0) ?
+ std::min(l_run_port, l_calc_port) : l_run_port;
+
+ FAPI_INF("New runtime throttles for %s for slot are %d, port are %d",
+ mss::c_str(l_port),
+ l_run_slot,
+ l_run_port);
+
+ FAPI_TRY( mss::attr::set_runtime_mem_throttled_n_commands_per_port(l_port, l_run_port) );
+ FAPI_TRY( mss::attr::set_runtime_mem_throttled_n_commands_per_slot(l_port, l_run_slot) );
+ }
+
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+
+///
+/// @brief Update the runtime throttles to the worst case of the general throttle values and the runtime values
+/// @tparam MC mss::mc_type
+/// @tparam T the fapi2 target type of the target
+/// @tparam TT throttle_traits throttle traits for the given mc_type
+/// @param[in] i_target the MCS target in which the runtime throttles will be set
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = throttle_traits<MC>>
+fapi2::ReturnCode update_runtime_throttles(const std::vector< fapi2::Target<T> >& i_targets)
+
+{
+ for (const auto& l_mc : i_targets)
+ {
+ FAPI_TRY(update_runtime_throttle(l_mc));
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @class throttle
+/// @brief Determine power_thermal throttles for memory
+/// @tparam MC mss::mc_type
+/// @tparam TT throttle_traits throttle traits for the given mc_type
+///
+template<mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = throttle_traits<MC>>
+class throttle
+{
+ private:
+ ///
+ /// @brief Calculate the power (cW) of inputs and the power curve
+ /// @tparam T the type of i_util and return value
+ /// @param[in] i_util the databus utilization that the power will be based on
+ /// @param[in] l_pos the dimm position for the power value being calculated.
+ /// @return Integral type T
+ ///
+ template<typename T>
+ inline T calc_power (const T i_util, const size_t i_pos, fapi2::ReturnCode& o_rc ) const
+ {
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+ FAPI_ASSERT( (i_pos < TT::DIMMS_PER_PORT),
+ fapi2::MSS_POWER_THERMAL_DIMM_INDEX_OUT_OF_BOUND()
+ .set_INPUT_SIZE(i_pos)
+ .set_MAX_SIZE(TT::DIMMS_PER_PORT),
+ "The dimm is index is out of bound for the port index: %d, max: %d for port %s",
+ i_pos, TT::DIMMS_PER_PORT, mss::c_str(iv_target) );
+
+ return ((i_util / UTIL_CONVERSION) * iv_pwr_slope[i_pos]) + iv_pwr_int[i_pos];
+
+ fapi_try_exit:
+ o_rc = fapi2::current_err;
+ return 0;
+ }
+
+ ///
+ /// @brief Raise the o_value by the percent passed in
+ /// @param[in] i_uplift the percent the o_Value should be raised by
+ /// @param[out] o_value the value that will be modified
+ ///
+ inline void calc_power_uplift (const uint8_t i_uplift, double& o_value) const
+ {
+ o_value *= (1 + (static_cast<double>(i_uplift) / PERCENT_CONVERSION));
+ }
+
+ public:
+ const fapi2::Target<TT::PORT_TARGET_TYPE>& iv_target;
+
+ uint32_t iv_databus_port_max;
+
+ uint8_t iv_power_uplift_idle;
+ uint8_t iv_power_uplift;
+
+ uint16_t iv_runtime_n_slot;
+ uint16_t iv_runtime_n_port;
+ uint32_t iv_m_clocks;
+ uint32_t iv_dimm_thermal_limit[TT::DIMMS_PER_PORT] = {};
+ uint16_t iv_pwr_slope[TT::DIMMS_PER_PORT] = {};
+ uint16_t iv_pwr_int[TT::DIMMS_PER_PORT] = {};
+ uint16_t iv_n_slot;
+ uint16_t iv_n_port;
+ uint32_t iv_port_power_limit;
+ uint32_t iv_calc_port_maxpower;
+
+ //default ctor deleted
+ throttle() = delete;
+
+ ///
+ /// @brief Constructor
+ /// @param[in] i_target port target to call power thermal stuff on
+ /// @param[out] o_rc fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ctor was successful
+ ///
+ throttle( const fapi2::Target<TT::PORT_TARGET_TYPE>& i_port, fapi2::ReturnCode& o_rc);
+
+ //
+ // @brief Destructor
+ //
+ ~throttle() = default;
+
+ ///
+ /// @brief Calculates the min and max power usage for a port
+ /// @param[in] i_idle_util the utilization of the databus in idle mode
+ /// @param[in] i_max_util the utilization of the port at maximum possible (mrw or calculated)
+ /// @param[out] o_port_power_idle max value of port power in cW
+ /// @param[out] o_port_power_max max value of port power in cW
+ /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
+ /// @note Called twice in p9_mss_bulk_pwr_throttles
+ ///
+ fapi2::ReturnCode calc_port_power( const double i_idle_util [TT::DIMMS_PER_PORT],
+ const double i_max_util [TT::DIMMS_PER_PORT],
+ double& o_port_power_idle,
+ double& o_port_power_max) const;
+ ///
+ /// @brief Calculates max and min power usages based off of DIMM power curves
+ /// @param[in] i_databus_port_max max databus utilization for the port (either calculated or mrw)
+ /// @param[in] i_port_power_calc_idle double of the port's power consumption at idle
+ /// @param[out] o_dimm_power_idle array of dimm power in cW
+ /// @param[out] o_dimm_power_max array of dimm power in cW
+ /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
+ /// @note Called in p9_mss_bulk_pwr_throttles
+ /// @note used for the thermal throttles
+ ///
+ fapi2::ReturnCode calc_dimm_power(const double i_databus_idle,
+ const double i_databus_max,
+ double o_dimm_power_idle [TT::DIMMS_PER_PORT],
+ double o_dimm_power_max [TT::DIMMS_PER_PORT]) const;
+
+ ///
+ /// @brief Calculate the power curve in order to calculate databus utilization
+ /// @param[in] i_power_idle double of the port's power consumption at idle
+ /// @param[in] i_power_max double of the port's power consumption at max utilization
+ /// @param[out] o_power_slope
+ /// @param[out] o_power_int
+ /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
+ /// @note Called in p9_mss_bulk_pwr_throttles
+ /// @note Power curve needed to calculate the utilization
+ ///
+ fapi2::ReturnCode calc_power_curve(const double i_power_idle,
+ const double i_power_max,
+ uint32_t& o_power_slope,
+ uint32_t& o_power_int) const;
+ ///
+ /// @brief Calculate the databus utilization given the power curve
+ /// @param[in] i_slope the slope of power curve
+ /// @param[in] i_int the intercept of power curve
+ /// @param[in] i_power_limit either iv_port_power_limit or thermal_power_limit depending on throttle type
+ /// @param[out] o_port_util the port's databus utilization
+ /// @note Called in p9_mss_bulk_pwr_throttles
+ /// @note Chooses worst case between the maximum allowed databus utilization and the calculated value
+ ///
+ void calc_util_usage(const uint32_t i_slope,
+ const uint32_t i_int,
+ const uint32_t i_power_limit,
+ double& o_util) const;
+ ///
+ /// @brief set iv_n_port, iv_n_slot, iv_calc_port_maxpower
+ /// @param[in] i_util_port pass in the calculated port databus utilization
+ /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+ ///
+ fapi2::ReturnCode calc_slots_and_power (const double i_util_port);
+
+ ///
+ /// @brief calculated the output power estimate from the calculated N throttle
+ /// @param[in] i_n_slot the N throttle per slot
+ /// @param[in] i_n_port the N throttle per port
+ /// @param[out] o_power the calculated power
+ /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
+ ///
+ fapi2::ReturnCode calc_power_from_n (const uint16_t i_n_slot, const uint16_t i_n_port, uint32_t& o_power) const;
+
+ ///
+ /// @brief Converts the port maximum databus util to a dimm level based on powerslopes and dimms installed
+ /// @param[in] i_databus_port_max max databus utilization for the port (either calculated or mrw)
+ /// @param[out] o_databus_dimm_max array of dimm utilization values
+ /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
+ /// @note Called in p9_mss_bulk_pwr_throttles
+ /// @used to calculate the port power based off of DIMM power curves
+ ///
+ fapi2::ReturnCode calc_databus( const double i_databus_port_max,
+ double o_databus_dimm_max [TT::DIMMS_PER_PORT]);
+ ///
+ /// @brief Converts the port and slot util to a dimm level based on powerslopes and number of dimms installed
+ /// @param[in] i_util_slot databus utilization for the slot
+ /// @param[in] i_util_port databus utilization for the port
+ /// @param[out] o_util_dimm_max array of dimm utilization values
+ /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
+ /// @note determines worst case utilization per dimms, takes into account port and combine slot throttles
+ ///
+ fapi2::ReturnCode calc_split_util(
+ const double i_util_slot,
+ const double i_util_port,
+ double o_util_dimm_max [TT::DIMMS_PER_PORT]) const;
+
+
+ ///
+ /// @brief Calculate ATTR_MSS_CHANNEL_PAIR_MAXPOWER and ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
+ /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+ /// @note Called in p9_mss_bulk_pwr_throttles
+ /// @note determines the throttle levels based off of the port's power curve, max databus utilization,
+ /// and memwat target.
+ /// @note currently sets the slot and port throttles to the same value
+ ///
+ fapi2::ReturnCode power_regulator_throttles ();
+
+ ///
+ /// @brief Set ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
+ /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+ /// @note Called in p9_mss_bulk_pwr_throttles
+ /// @note Sets the throttle levels based off of the dimm's thermal limits
+ /// @note both DIMM's on a port are set to the same throttle level
+ ///
+ fapi2::ReturnCode thermal_throttles ();
+};
+
+
+///
+/// @brief Constructor
+/// @tparam MC mss::mc_type
+/// @tparam TT throttle_traits throttle traits for the given mc_type
+/// @param[in] i_target MCS target to call power thermal stuff on
+/// @param[out] o_rc, a return code which determines the success of the constructor
+///
+template<mss::mc_type MC, typename TT>
+throttle<MC, TT>::throttle( const fapi2::Target<TT::PORT_TARGET_TYPE>& i_port, fapi2::ReturnCode& o_rc) :
+ iv_target(i_port),
+ iv_databus_port_max(0),
+ iv_runtime_n_slot(0),
+ iv_runtime_n_port(0),
+ iv_n_slot(0),
+ iv_n_port(0),
+ iv_port_power_limit(0),
+ iv_calc_port_maxpower(0)
+{
+ FAPI_TRY( mss::attr::get_mrw_max_dram_databus_util(iv_databus_port_max), "%s Error in throttle ctor",
+ mss::c_str(i_port) );
+ FAPI_TRY( mss::attr::get_mrw_dimm_power_curve_percent_uplift(iv_power_uplift), "%s Error in throttle ctor",
+ mss::c_str(i_port) );
+ FAPI_TRY( mss::attr::get_mrw_dimm_power_curve_percent_uplift_idle(iv_power_uplift_idle), "%s Error in throttle ctor",
+ mss::c_str(i_port) );
+ FAPI_TRY( mss::attr::get_dimm_thermal_limit( iv_target, iv_dimm_thermal_limit), "%s Error in throttle ctor",
+ mss::c_str(i_port) );
+ FAPI_TRY( mss::attr::get_total_pwr_intercept( iv_target, iv_pwr_int), "%s Error in throttle ctor", mss::c_str(i_port) );
+ FAPI_TRY( mss::attr::get_total_pwr_slope( iv_target, iv_pwr_slope), "%s Error in throttle ctor", mss::c_str(i_port) );
+ FAPI_TRY( mss::attr::get_runtime_mem_throttled_n_commands_per_slot(iv_target, iv_runtime_n_slot ),
+ "%s Error in throttle ctor",
+ mss::c_str(i_port) );
+ FAPI_TRY( mss::attr::get_runtime_mem_throttled_n_commands_per_port(iv_target, iv_runtime_n_port ),
+ "%s Error in throttle ctor",
+ mss::c_str(i_port) );
+ FAPI_TRY( mss::attr::get_mrw_mem_m_dram_clocks(iv_m_clocks), "%s Error in throttle ctor", mss::c_str(i_port) );
+
+ //Port power limit = sum of dimm power limits
+ for ( const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(iv_target) )
+ {
+ uint32_t l_dimm_limit = 0;
+ FAPI_TRY( mss::attr::get_mem_watt_target( l_dimm, l_dimm_limit) );
+ iv_port_power_limit += l_dimm_limit;
+ }
+
+ FAPI_INF("Setting up throttle for target %s, Values are: max databus is %d, uplifts are %d %d, runtime throttles are %d %d",
+ mss::c_str(iv_target),
+ iv_databus_port_max,
+ iv_power_uplift,
+ iv_power_uplift_idle,
+ iv_runtime_n_slot,
+ iv_runtime_n_port);
+
+ FAPI_INF("The dimm power limit is %d, dram clocks are %d, dimm power curve slopes are %d %d for %s",
+ iv_port_power_limit,
+ iv_m_clocks,
+ iv_pwr_slope[0],
+ iv_pwr_slope[1],
+ mss::c_str(iv_target));
+
+ FAPI_INF("DIMM power curve intercepts are %d %d, DIMM power thermal limits are %d %d for %s",
+ iv_pwr_int[0],
+ iv_pwr_int[1],
+ iv_dimm_thermal_limit[0],
+ iv_dimm_thermal_limit[1],
+ mss::c_str(iv_target));
+
+ FAPI_ASSERT( (iv_databus_port_max != 0),
+ fapi2::MSS_NO_DATABUS_UTILIZATION()
+ .set_PORT_DATABUS_UTIL(iv_databus_port_max)
+ .set_DIMM_COUNT(mss::count_dimm(iv_target)),
+ "Failed to get max databus utilization for target %s",
+ mss::c_str(iv_target));
+
+ FAPI_ASSERT( (iv_port_power_limit != 0),
+ fapi2::MSS_NO_PORT_POWER_LIMIT()
+ .set_COUNT_DIMMS( mss::count_dimm(iv_target))
+ .set_PORT_POWER_LIMIT( iv_port_power_limit),
+ "Error calculating port_power_limit on target %s with %d DIMMs installed",
+ mss::c_str(iv_target),
+ iv_port_power_limit);
+
+ //Checking to make sure all of the attributes are valid
+ for ( const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(iv_target) )
+ {
+ const auto l_pos = mss::index(l_dimm);
+ FAPI_ASSERT( (iv_pwr_int[l_pos] != 0),
+ fapi2::MSS_POWER_INTERCEPT_NOT_SET(),
+ "The attribute ATTR_MSS_TOTAL_PWR_INTERCEPT equals 0 for %s",
+ mss::c_str(l_dimm));
+
+ FAPI_ASSERT( (iv_pwr_slope[l_pos] != 0),
+ fapi2::MSS_POWER_SLOPE_NOT_SET(),
+ "The attribute ATTR_MSS_TOTAL_PWR_SLOPE equals 0 for %s",
+ mss::c_str(l_dimm));
+ }
+
+fapi_try_exit:
+ o_rc = fapi2::current_err;
+ return;
+}
+
+///
+/// @brief Set ATTR_MSS_CHANNEL_PAIR_MAXPOWER, ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT and _PER_PORT
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Called in p9_mss_bulk_pwr_throttles
+/// @note determines the throttle levels based off of the port's power curve,
+/// @note the _per_slot throttles are set to the _per_port values
+/// @note throttles are all equalized and set to the worst case value
+///
+template<mss::mc_type MC, typename TT>
+fapi2::ReturnCode throttle<MC, TT>::power_regulator_throttles ()
+{
+ double l_port_power_calc_idle = 0;
+ double l_port_power_calc_max = 0;
+ uint32_t l_port_power_slope = 0;
+ uint32_t l_port_power_int = 0;
+ double l_calc_util_port = 0;
+ double l_databus_dimm_max[TT::DIMMS_PER_PORT] = {};
+ double l_calc_databus_port_idle[TT::DIMMS_PER_PORT] = {TT::IDLE_UTIL, TT::IDLE_UTIL};
+
+ //Decide utilization for each dimm based off of dimm count and power slopes
+ FAPI_TRY( calc_databus(iv_databus_port_max, l_databus_dimm_max),
+ "Failed to calculate each DIMMs' percentage of dram databus utilization for target %s, max port databus is %d",
+ mss::c_str(iv_target),
+ iv_databus_port_max);
+
+ //Use the dimm utilizations and dimm power slopes to calculate port min and max power
+ FAPI_TRY( calc_port_power(l_calc_databus_port_idle,
+ l_databus_dimm_max,
+ l_port_power_calc_idle,
+ l_port_power_calc_max),
+ "Failed to calculate the max and idle power for port %s",
+ mss::c_str(iv_target));
+
+ FAPI_INF("POWER throttles: %s max port power is %f", mss::c_str(iv_target), l_port_power_calc_max);
+
+ //Calculate the power curve slope and intercept using the port's min and max power values
+ FAPI_TRY(calc_power_curve(l_port_power_calc_idle,
+ l_port_power_calc_max,
+ l_port_power_slope,
+ l_port_power_int),
+ "Failed to calculate the power curve for port %s, calculated port power max is %f, idle is %f",
+ mss::c_str(iv_target),
+ l_port_power_calc_max,
+ l_port_power_calc_idle);
+
+ FAPI_INF("%s POWER Port power limit is %d", mss::c_str(iv_target), iv_port_power_limit);
+ //Calculate the port's utilization to get under watt target using the port's calculated slopes
+ calc_util_usage(l_port_power_slope,
+ l_port_power_int,
+ iv_port_power_limit,
+ l_calc_util_port);
+
+ FAPI_INF("%s POWER calc util port is %f", mss::c_str(iv_target), l_calc_util_port);
+
+ //Calculate the new slot values and the max power value for the port
+ FAPI_TRY( calc_slots_and_power( l_calc_util_port),
+ "%s Error calculating the final throttles and power values for target with passed in port utilization %f",
+ mss::c_str(iv_target),
+ l_calc_util_port);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief set iv_n_port, iv_n_slot, iv_calc_port_maxpower
+/// @param[in] i_util_port pass in the calculated port databus utilization
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+///
+template<mss::mc_type MC, typename TT>
+fapi2::ReturnCode throttle<MC, TT>::calc_slots_and_power (const double i_util_port)
+{
+ //Calculate the Port N throttles
+ iv_n_port = power_thermal::throttled_cmds(i_util_port, iv_m_clocks);
+
+ //Set iv_n_slot to the lower value between the slot runtime and iv_n_port
+ iv_n_slot = (iv_runtime_n_slot != 0) ? std::min (iv_n_port, iv_runtime_n_slot) : iv_n_port;
+
+ //Choose the lowest value of the runtime and the calculated
+ iv_n_port = (iv_runtime_n_port != 0) ? std::min (iv_n_port, iv_runtime_n_port) : iv_n_port;
+
+ //Use the throttle value to calculate the power that gets to exactly that value
+ FAPI_TRY( calc_power_from_n(iv_n_slot, iv_n_port, iv_calc_port_maxpower));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Set ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT and PER_PORT
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Called in p9_mss_bulk_pwr_throttles
+/// @note Sets the throttle levels based off of the dimm's thermal limits
+/// @note both DIMM's on a port are set to the same throttle level
+///
+template<mss::mc_type MC, typename TT>
+fapi2::ReturnCode throttle<MC, TT>::thermal_throttles ()
+{
+ double l_dimm_power_idle [TT::DIMMS_PER_PORT] = {};
+ double l_dimm_power_max [TT::DIMMS_PER_PORT] = {};
+ uint32_t l_dimm_power_slope [TT::DIMMS_PER_PORT] = {};
+ uint32_t l_dimm_power_int [TT::DIMMS_PER_PORT] = {};
+ double l_calc_util [TT::DIMMS_PER_PORT] = {};
+ const auto l_count = count_dimm (iv_target);
+ uint8_t l_found_ddimm = 0;
+
+ //Calculate the dimm power range for each dimm at max utilization for each
+ FAPI_TRY( calc_dimm_power(TT::IDLE_UTIL,
+ iv_databus_port_max,
+ l_dimm_power_idle,
+ l_dimm_power_max));
+
+ //Let's calculate the N throttle for each DIMM
+ for ( const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(iv_target) )
+ {
+ uint16_t l_temp_n_slot = 0;
+ const uint8_t l_pos = mss::index(l_dimm);
+ mss::dimm::kind<MC> l_kind (l_dimm);
+ l_found_ddimm = (l_kind.iv_dimm_type == fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_DDIMM) ? 1 : l_found_ddimm;
+ //Calculate the power curve taking the thermal limit into account
+ FAPI_TRY( calc_power_curve(l_dimm_power_idle[l_pos],
+ l_dimm_power_max[l_pos],
+ l_dimm_power_slope[l_pos],
+ l_dimm_power_int[l_pos]),
+ "Failed to calculate the power curve for dimm %s, calculated dimm power curve slope is %d, intercept %d",
+ mss::c_str(l_dimm),
+ l_dimm_power_slope[l_pos],
+ l_dimm_power_int[l_pos]);
+
+ //Calculate the databus utilization at the calculated power curve
+ calc_util_usage(l_dimm_power_slope[l_pos],
+ l_dimm_power_int[l_pos],
+ iv_dimm_thermal_limit[l_pos],
+ l_calc_util[l_pos]);
+
+ FAPI_INF("THERMAL throttles: %s dram databus utilization is %f", mss::c_str(l_dimm), l_calc_util[l_pos]);
+
+ l_temp_n_slot = power_thermal::throttled_cmds (l_calc_util[l_pos], iv_m_clocks);
+
+ //Set to the min between the two value
+ //If iv_n_slot == 0 (so uninitialized), set it to the calculated slot value
+ //The l_n_slot value can't be equal to 0 because there's a dimm installed
+ if ((l_temp_n_slot < iv_n_slot) || (iv_n_slot == 0))
+ {
+ iv_n_slot = l_temp_n_slot;
+ }
+ }
+
+ //Set to lowest value between calculated and runtime
+ FAPI_INF("THERMAL throttles: runtime slot is %d, calc n slot is %d for %s", iv_runtime_n_slot, iv_n_slot,
+ mss::c_str(iv_target));
+ //DDDIMMs: Taking the min of the SLOT and the iv_runtime_port throttle value
+ //ISDIMMs: Taking the min of the SLOT * (# of dimms on the port) and the iv_runtime_port throttle value
+ //Thermal throttling happens after the POWER calculations. the iv_runtime_n_port value shouldn't be set to 0
+ iv_n_port = (l_found_ddimm) ?
+ std::min(iv_runtime_n_port, static_cast<uint16_t>(iv_n_slot)) :
+ std::min(iv_runtime_n_port, static_cast<uint16_t>(iv_n_slot * l_count));
+ iv_n_port = (iv_n_port == 0) ? TT::MIN_THROTTLE : iv_n_port;
+
+ iv_n_slot = std::min(iv_n_slot, iv_runtime_n_slot);
+ iv_n_slot = (iv_n_slot == 0) ? TT::MIN_THROTTLE : iv_n_slot;
+
+ //Now time to get and set iv_calc_port_max from the calculated N throttle
+ FAPI_TRY( calc_power_from_n(iv_n_slot, iv_n_port, iv_calc_port_maxpower),
+ "Failed to calculate the final max port maxpower. Slot throttle value is %d, port value is %d for %s",
+ iv_n_slot,
+ iv_n_port,
+ mss::c_str(iv_target));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ FAPI_ERR("Error calculating mss::power_thermal::thermal_throttles() for %s", mss::c_str(iv_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calculates the min and max power usage for a port based off of power curves and utilizations
+/// @param[in] i_idle_util the utilization of the databus in idle mode (0% most likely)
+/// @param[in] i_max_util the utilization of the dimm at maximum possible percentage (mrw or calculated)
+/// @param[out] o_port_power_idle max value of port power in cW
+/// @param[out] o_port_power_max max value of port power in cW
+/// @return fapi2::FAPI2_RC_SUCCESS iff the method was a success
+/// @note Called twice in p9_mss_bulk_pwr_throttles
+/// @note uses dimm power curves from class variables
+///
+template<mss::mc_type MC, typename TT>
+fapi2::ReturnCode throttle<MC, TT>::calc_port_power(const double i_idle_util [TT::DIMMS_PER_PORT],
+ const double i_max_util [TT::DIMMS_PER_PORT],
+ double& o_port_power_idle,
+ double& o_port_power_max) const
+{
+ //Playing it safe
+ o_port_power_idle = 0;
+ o_port_power_max = 0;
+ fapi2::ReturnCode l_rc;
+
+ //Calculate the port power curve info by summing the dimms on the port
+ for ( const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(iv_target) )
+ {
+ const auto l_pos = mss::index(l_dimm);
+ //Printing as decimals because HB messes up floats
+ FAPI_INF("%s max dram databus for DIMM in pos %d is %d, databus for idle is %d",
+ mss::c_str(iv_target),
+ l_pos,
+ static_cast<uint64_t>( i_max_util[l_pos]),
+ static_cast<uint64_t>( i_idle_util[l_pos]) );
+ //Sum up the dimm's power to calculate the port power curve
+ o_port_power_idle += calc_power(i_idle_util[l_pos], l_pos, l_rc);
+ FAPI_TRY(l_rc, "calc_power failed");
+ o_port_power_max += calc_power(i_max_util[l_pos], l_pos, l_rc);
+ FAPI_TRY(l_rc, "calc_power failed");
+ }
+
+ //Raise the powers by the uplift percent
+ calc_power_uplift(iv_power_uplift_idle, o_port_power_idle);
+ calc_power_uplift(iv_power_uplift, o_port_power_max);
+
+ FAPI_ASSERT( (o_port_power_max > 0),
+ fapi2::MSS_NO_PORT_POWER()
+ .set_COUNT_DIMMS(mss::count_dimm(iv_target))
+ .set_MAX_UTILIZATION_DIMM_0(i_max_util[0])
+ .set_MAX_UTILIZATION_DIMM_1(i_max_util[1]),
+ "No Port Power limit was calculated for %s, %d DIMMs installed, utilizations: DIMM 0 %d, DIMM 1 %d",
+ mss::c_str(iv_target),
+ mss::count_dimm(iv_target),
+ i_max_util[0],
+ i_max_util[1]);
+
+ //FAPI_ASSERTs don't set the current err to good
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calculates max and min power usages based off of DIMM power curves
+/// @param[in] i_databus_idle idle databus utilization (either calculated or mrw)
+/// @param[in] i_databus_max max databus utilization (either calculated or mrw)
+/// @param[out] o_dimm_power_idle array of dimm power in cW
+/// @param[out] o_dimm_power_max array of dimm power in cW
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
+/// @note Called in p9_mss_bulk_pwr_throttles
+/// @note used for the thermal throttles
+///
+template<mss::mc_type MC, typename TT>
+fapi2::ReturnCode throttle<MC, TT>::calc_dimm_power(const double i_databus_idle,
+ const double i_databus_max,
+ double o_dimm_power_idle [TT::DIMMS_PER_PORT],
+ double o_dimm_power_max [TT::DIMMS_PER_PORT]) const
+{
+ for ( const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(iv_target) )
+ {
+ fapi2::ReturnCode l_rc;
+ const uint8_t l_pos = mss::index(l_dimm);
+ o_dimm_power_idle[l_pos] = calc_power(i_databus_idle, l_pos, l_rc);
+ FAPI_TRY(l_rc, "calc_power failed");
+ o_dimm_power_max[l_pos] = calc_power(i_databus_max, l_pos, l_rc);
+ FAPI_TRY(l_rc, "calc_power failed");
+
+ //Raise the powers by the uplift percent
+ calc_power_uplift(iv_power_uplift_idle, o_dimm_power_idle[l_pos]);
+ calc_power_uplift(iv_power_uplift, o_dimm_power_max[l_pos]);
+
+ FAPI_INF("Calc_dimm_power: dimm (%d) power max is %f, dimm slope %d, intercept %d for %s",
+ l_pos,
+ o_dimm_power_max[l_pos],
+ iv_pwr_slope[l_pos],
+ iv_pwr_int[l_pos],
+ mss::c_str(l_dimm));
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ FAPI_INF("Error calculating mss::power_thermal::calc_dimm_power for %s", mss::c_str(iv_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calculate the port power curve in order to calculate the port utilization
+/// @param[in] i_power_idle double of the port's power consumption at idle
+/// @param[in] i_power_max double of the port's power consumption at max utilization
+/// @param[out] o_slope
+/// @param[out] o_int
+/// @note Called in p9_mss_bulk_pwr_throttles
+/// @note Port power curve needed to calculate the port utilization
+///
+template<mss::mc_type MC, typename TT>
+fapi2::ReturnCode throttle<MC, TT>::calc_power_curve(const double i_power_idle,
+ const double i_power_max,
+ uint32_t& o_slope,
+ uint32_t& o_int) const
+{
+ auto l_min_util = TT::MIN_UTIL;
+ const double l_divisor = ((static_cast<double>(iv_databus_port_max) / UTIL_CONVERSION) - TT::IDLE_UTIL);
+ FAPI_ASSERT ((l_divisor > 0),
+ fapi2::MSS_CALC_POWER_CURVE_DIVIDE_BY_ZERO()
+ .set_PORT_DATABUS_UTIL(iv_databus_port_max)
+ .set_UTIL_CONVERSION(UTIL_CONVERSION)
+ .set_IDLE_UTIL(l_min_util)
+ .set_RESULT(l_divisor),
+ "Calculated zero for the divisor in calc_power_curve on target %s",
+ mss::c_str(iv_target) );
+
+ o_slope = (i_power_max - i_power_idle) / l_divisor;
+ o_int = i_power_idle - (o_slope * TT::IDLE_UTIL);
+ FAPI_INF("Calc_power_curve: power idle is %f, max is %f, slope is %d, int is %d for %s",
+ i_power_idle,
+ i_power_max,
+ o_slope,
+ o_int,
+ mss::c_str(iv_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ FAPI_INF("Error calculating mss::power_thermal::calc_power_curve for %s", mss::c_str(iv_target));
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Calculate the databus utilization given the power curve
+/// @param[in] i_slope
+/// @param[in] i_int
+/// @param[in] i_power_limit either the port_power_limit or the dimm thermal power limit
+/// @param[out] o_port_util the port's databus utilization
+/// @note Called in p9_mss_bulk_pwr_throttles
+/// @note Chooses worst case between the maximum allowed databus utilization and the calculated value
+///
+template<mss::mc_type MC, typename TT>
+void throttle<MC, TT>::calc_util_usage(const uint32_t i_slope,
+ const uint32_t i_int,
+ const uint32_t i_power_limit,
+ double& o_util) const
+{
+ // Return 0 utilization if our intercept is above the power limit
+ o_util = (i_power_limit > i_int) ? (((static_cast<double>(i_power_limit) - i_int) / i_slope ) * UTIL_CONVERSION) : 0;
+
+ // Cast to uint32 for edge case where it has decimals
+ o_util = (static_cast<uint32_t>(o_util) < iv_databus_port_max) ? static_cast<uint32_t>(o_util) : iv_databus_port_max;
+
+ // Check for the minimum threshnold and update if need be
+ if(o_util < TT::MIN_UTIL)
+ {
+ FAPI_INF("Calculated utilization (%f) is less than the minimum utilization: %lu. Setting to minimum value for %s",
+ o_util,
+ TT::MIN_UTIL, mss::c_str(iv_target));
+ o_util = TT::MIN_UTIL;
+ }
+}
+
+///
+/// @brief calculated the output power estimate from the calculated N throttle
+/// @param[in] i_n_slot the throttle per slot in terms of N commands
+/// @param[in] i_n_port the throttle per port in terms of N commands
+/// @param[out] o_power the calculated power
+/// @return fapi2::ReturnCode iff it was a success
+///
+template<mss::mc_type MC, typename TT>
+fapi2::ReturnCode throttle<MC, TT>::calc_power_from_n (const uint16_t i_n_slot,
+ const uint16_t i_n_port,
+ uint32_t& o_power) const
+{
+ double l_calc_util_port = 0;
+ double l_calc_util_slot = 0;
+ double l_calc_databus_port_max[TT::DIMMS_PER_PORT] = {};
+ double l_calc_databus_port_idle[TT::DIMMS_PER_PORT] = {};
+ double l_port_power_max = 0;
+ double l_port_power_idle = 0;
+
+ FAPI_TRY( calc_util_from_throttles(i_n_slot, iv_m_clocks, l_calc_util_slot),
+ "%s Error calculating utilization from slot throttle %d and mem clocks %d",
+ mss::c_str(iv_target),
+ i_n_slot,
+ iv_m_clocks);
+ FAPI_TRY( calc_util_from_throttles(i_n_port, iv_m_clocks, l_calc_util_port),
+ "%s Error calculating utilization from port throttle %d and mem clocks %d",
+ mss::c_str(iv_target),
+ i_n_port,
+ iv_m_clocks);
+
+ //Determine the utilization for each DIMM that will maximize the port power
+ FAPI_TRY( calc_split_util(l_calc_util_slot, l_calc_util_port, l_calc_databus_port_max),
+ "Error splitting the utilization for target %s with slot utilizatio %f and port util %f",
+ mss::c_str(iv_target),
+ l_calc_util_slot,
+ l_calc_util_port);
+
+ FAPI_TRY( calc_port_power(l_calc_databus_port_idle,
+ l_calc_databus_port_max,
+ l_port_power_idle,
+ l_port_power_max),
+ "Error calculating the port power value for %s. Slot value is %d, port value is %d",
+ mss::c_str(iv_target),
+ i_n_slot,
+ i_n_port);
+
+ o_power = mss::round_up (l_port_power_max);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Converts the port maximum databus to a dimm level based on powerslopes and dimms installed
+/// @param[in] i_databus_port_max max databus utilization for the port (either calculated or mrw)
+/// @param[out] o_databus_dimm_max array of dimm utilization values
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
+/// @note Called in p9_mss_bulk_pwr_throttles
+/// @used to calculate the port power based off of DIMM power curves
+///
+template<mss::mc_type MC, typename TT>
+fapi2::ReturnCode throttle<MC, TT>::calc_databus (const double i_databus_port_max,
+ double o_databus_dimm_max [TT::DIMMS_PER_PORT])
+{
+ const uint8_t l_count_dimms = count_dimm(iv_target);
+
+ //No work for no dimms
+ if (l_count_dimms == 0)
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ for (const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(iv_target))
+ {
+ //Left early if count_dimms == 0
+ // For DDIMM, set each virtual DIMM to the same utilization value since mrw slope/intercept/limit attributes
+ // are equally divided by number of virtual dimms (ie. mrw values are for whole DDIMM, not individual virtual DIMMs)
+ // For ISDIMM, divide utilization by number of DIMMs on the port
+ mss::dimm::kind<MC> l_kind (l_dimm);
+ o_databus_dimm_max[mss::index(l_dimm)] = (l_kind.iv_dimm_type == fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_DDIMM) ?
+ i_databus_port_max :
+ i_databus_port_max / l_count_dimms;
+ }
+
+ //If the power slopes aren't equal, set the dimm with the highest power slope
+ //Should be correct even if only one DIMM is installed
+ if (iv_pwr_slope[0] != iv_pwr_slope[1])
+ {
+ o_databus_dimm_max[0] = (iv_pwr_slope[0] > iv_pwr_slope[1]) ? i_databus_port_max : 0;
+ o_databus_dimm_max[1] = (iv_pwr_slope[1] > iv_pwr_slope[0]) ? i_databus_port_max : 0;
+ }
+
+ //Make sure both are not 0
+ FAPI_ASSERT ( (o_databus_dimm_max[0] != 0) || (o_databus_dimm_max[1] != 0),
+ fapi2::MSS_NO_DATABUS_UTILIZATION()
+ .set_PORT_DATABUS_UTIL(i_databus_port_max)
+ .set_DIMM_COUNT(l_count_dimms),
+ "Failed to calculated databus utilization for target %s",
+ mss::c_str(iv_target));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Converts the port and slot util to a dimm level based on powerslopes and number of dimms installed
+/// @param[in] i_util_slot databus utilization for the slot
+/// @param[in] i_util_port databus utilization for the port
+/// @param[out] o_util_dimm_max array of dimm utilization values
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
+/// @note determines worst case utilization per dimms, takes into account port and combine slot throttles
+/// @note used in calculating the port power, not for calculating the slot and port utilization
+///
+template<mss::mc_type MC, typename TT>
+fapi2::ReturnCode throttle<MC, TT>::calc_split_util(
+ const double i_util_slot,
+ const double i_util_port,
+ double o_util_dimm_max [TT::DIMMS_PER_PORT]) const
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ uint8_t l_found_ddimm = 0;
+ const uint8_t l_count_dimms = count_dimm (iv_target);
+ //The total utilization to be used is limited by either what the port can allow or what the dimms can use
+ FAPI_ASSERT( (i_util_slot <= i_util_port),
+ fapi2::MSS_SLOT_UTIL_EXCEEDS_PORT()
+ .set_SLOT_UTIL(i_util_slot)
+ .set_PORT_UTIL(i_util_port),
+ "The slot utilization (%f) exceeds the port's utilization (%f) for %s",
+ i_util_slot,
+ i_util_port,
+ mss::c_str(iv_target));
+
+ if (l_count_dimms == 0)
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ for ( const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(iv_target) )
+ {
+ mss::dimm::kind<MC> l_kind (l_dimm);
+ l_found_ddimm = (l_kind.iv_dimm_type == fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_DDIMM) ? 1 : l_found_ddimm;
+ }
+
+ //assumptions slot <= port, l_count_dimms <=2
+ if (i_util_slot * l_count_dimms > i_util_port)
+ {
+ FAPI_INF("i_util_slot is %f, i_util_port is %f, l_count_dimms is %d for %s",
+ i_util_slot,
+ i_util_port,
+ l_count_dimms,
+ mss::c_str(iv_target));
+ const uint8_t l_high_pos = (iv_pwr_slope[0] >= iv_pwr_slope[1]) ? 0 : 1;
+
+ //Highest power_slope gets the higher utilization
+ o_util_dimm_max[l_high_pos] = std::min(i_util_slot, i_util_port);
+ //Set the other dimm to the left over utilization (i_util_port - i_util_slot) if not a DDIMM, otherwise set to same value as above
+ o_util_dimm_max[(!l_high_pos)] = (l_found_ddimm) ?
+ o_util_dimm_max[l_high_pos] :
+ ((l_count_dimms == TT::DIMMS_PER_PORT) ?
+ (i_util_port - o_util_dimm_max[l_high_pos]) :
+ 0
+ );
+
+ FAPI_INF("Split utilization for target %s, DIMM in %d gets %f, DIMM in %d gets %f",
+ mss::c_str(iv_target),
+ l_high_pos,
+ o_util_dimm_max[l_high_pos],
+ !l_high_pos,
+ o_util_dimm_max[!l_high_pos]);
+ }
+ else
+ {
+ //If only 1 dimm, i_util_port == i_util_slot
+ //If 2 dimms, 2*i_util_slot <= i_util_pot
+ //Either way, limit utilization by the slot value
+ for (const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(iv_target))
+ {
+ const size_t l_pos = mss::index(l_dimm);
+ o_util_dimm_max[l_pos] = i_util_slot;
+ }
+ }
+
+ //make sure both are not 0
+ FAPI_ASSERT ( (o_util_dimm_max[0] != 0) || (o_util_dimm_max[1] != 0),
+ fapi2::MSS_NO_DATABUS_UTILIZATION()
+ .set_PORT_DATABUS_UTIL(i_util_port)
+ .set_DIMM_COUNT(mss::count_dimm(iv_target)),
+ "Failed to calculated util utilization for target %s",
+ mss::c_str(iv_target));
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief set the safemode throttle register
+/// @tparam MC mss::mc_type
+/// @tparam T the fapi2 target type of the target
+/// @tparam TT portTraits port traits for the given MC target type
+/// @param[in] i_target the port target
+/// @return fapi2::FAPI2_RC_SUCCESS if ok
+/// @note sets FARB4Q
+/// @note used to set throttle window (N throttles / M clocks)
+///
+template<mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = throttle_traits<MC>>
+fapi2::ReturnCode calc_utilization(const fapi2::Target<T>& i_target,
+ const uint32_t i_input_databus_util,
+ const uint32_t i_dram_clocks,
+ const uint16_t i_safemode_throttle_per_port,
+ const uint32_t i_max_databus_util,
+ uint32_t& o_util,
+ bool& o_util_error,
+ bool& o_safemode)
+{
+ constexpr uint64_t l_min_util = TT::MIN_UTIL;
+
+ o_util = i_input_databus_util;
+ o_safemode = false;
+
+ // Use MRW safemode throttle values if input utilization is zero
+ if (i_input_databus_util == 0)
+ {
+ FAPI_TRY(calc_util_from_throttles<MC>(i_safemode_throttle_per_port,
+ i_dram_clocks,
+ o_util),
+ "%s Error calculating utilization from safemode throttle %d and mem clocks %d",
+ mss::c_str(i_target),
+ i_safemode_throttle_per_port,
+ i_dram_clocks);
+ FAPI_INF("%s Safemode throttles being used since input util is zero: Using N=%d, Utilization %f",
+ mss::c_str(i_target),
+ i_safemode_throttle_per_port,
+ o_util);
+ o_safemode = true;
+ }
+ else if (i_input_databus_util < l_min_util)
+ {
+ o_util_error = true;
+ }
+
+ // Make sure MIN_UTIL <= input_utilization <= max_utilization
+ o_util = (o_util >= l_min_util) ? std::min(o_util, i_max_databus_util) : l_min_util;
+
+ FAPI_INF("%s MRW dram clock window: %d, databus utilization: %d",
+ mss::c_str(i_target),
+ i_dram_clocks,
+ o_util);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Equalize the throttles and estimated power at those throttle levels
+/// @tparam MC mss::mc_type
+/// @tparam T the fapi2 MC target type of the target
+/// @tparam TT throttle_traits throttle traits for the given mc_type
+/// @param[in] i_targets vector of MCS targets all on the same VDDR domain
+/// @param[in] i_throttle_type denotes if this was done for POWER (VMEM) or THERMAL (VMEM+VPP) throttles
+/// @param[out] o_exceeded_power vector of MCA targets where the estimated power exceeded the maximum allowed
+/// @return FAPI2_RC_SUCCESS iff ok
+/// @note sets the throttles and power to the worst case
+/// Called by p9_mss_bulk_pwr_throttles and by p9_mss_utils_to_throttle (so by IPL or by OCC)
+///
+template<mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = throttle_traits<MC>>
+fapi2::ReturnCode equalize_throttles (const std::vector< fapi2::Target<T> >& i_targets,
+ const throttle_type i_throttle_type,
+ std::vector< fapi2::Target<TT::PORT_TARGET_TYPE> >& o_exceeded_power)
+
+{
+ o_exceeded_power.clear();
+
+ //Set to max values so every compare will change to min value
+ uint16_t l_min_slot = ~(0);
+ uint16_t l_min_port = ~(0);
+
+ //Loop through all of the MC targets to find the worst case throttle value (lowest) for the slot and port
+ for (const auto& l_mc : i_targets)
+ {
+ for (const auto& l_port : mss::find_targets<TT::PORT_TARGET_TYPE>(l_mc))
+ {
+ uint16_t l_calc_slot = 0;
+ uint16_t l_calc_port = 0;
+ uint16_t l_run_slot = 0;
+ uint16_t l_run_port = 0;
+
+ if (mss::count_dimm(l_port) == 0)
+ {
+ FAPI_INF("Seeing no DIMMs on %s -- skipping", mss::c_str(l_port));
+ continue;
+ }
+
+ FAPI_TRY(mss::attr::get_mem_throttled_n_commands_per_slot(l_port, l_calc_slot));
+ FAPI_TRY(mss::attr::get_mem_throttled_n_commands_per_port(l_port, l_calc_port));
+ FAPI_TRY(mss::attr::get_runtime_mem_throttled_n_commands_per_slot(l_port, l_run_slot));
+ FAPI_TRY(mss::attr::get_runtime_mem_throttled_n_commands_per_port(l_port, l_run_port));
+
+ //Find the smaller of the three values (calculated slot, runtime slot, and min slot)
+ l_min_slot = (l_calc_slot != 0) ? std::min( std::min (l_calc_slot, l_run_slot),
+ l_min_slot) : l_min_slot;
+ l_min_port = (l_calc_port != 0) ? std::min( std::min( l_calc_port, l_run_port),
+ l_min_port) : l_min_port;
+ }
+ }
+
+ FAPI_INF("Calculated min slot is %d, min port is %d for the system", l_min_slot, l_min_port);
+
+ //Now set every port to have those values
+ {
+ for (const auto& l_mc : i_targets)
+ {
+ for (const auto& l_port : mss::find_targets<TT::PORT_TARGET_TYPE>(l_mc))
+ {
+ uint16_t l_fin_slot = 0;
+ uint16_t l_fin_port = 0;
+ uint32_t l_fin_power = 0;;
+
+ if (mss::count_dimm(l_port) == 0)
+ {
+ FAPI_INF("Seeing no DIMMs on %s -- skipping", mss::c_str(l_port));
+ continue;
+ }
+
+ // Declaring above to avoid fapi2 jump
+ uint64_t l_power_limit = 0;
+
+ l_fin_slot = l_min_slot;
+ l_fin_port = l_min_port;
+
+ //Need to create throttle object for each port in order to get dimm configuration and power curves
+ //To calculate the slot/port utilization and total port power consumption
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ const auto l_dummy = mss::power_thermal::throttle<MC>(l_port, l_rc);
+ FAPI_TRY(l_rc, "Failed creating a throttle object in equalize_throttles for %s", mss::c_str(l_port));
+
+ FAPI_TRY( l_dummy.calc_power_from_n(l_fin_slot, l_fin_port, l_fin_power),
+ "Failed calculating the power value for throttles: slot %d, port %d for target %s",
+ l_fin_slot,
+ l_fin_port,
+ mss::c_str(l_port));
+
+ // You may ask why this is not a variable within the throttle struct
+ // It's because POWER throttling is on a per port basis while the THERMAL throttle is per dimm
+ // Didn't feel like adding a variable just for this check
+ l_power_limit = (i_throttle_type == throttle_type::POWER) ?
+ l_dummy.iv_port_power_limit : (l_dummy.iv_dimm_thermal_limit[0] + l_dummy.iv_dimm_thermal_limit[1]);
+
+ FAPI_INF("%s Calculated power is %d, limit is %ld", mss::c_str(l_port), l_fin_power, l_power_limit);
+
+ //If there's an error with calculating port power, the wrong watt target was passed in
+ //Returns an error but doesn't deconfigure anything. Calling function can log if it wants to
+ //Called by OCC and by p9_mss_eff_config_thermal, thus different ways for error handling
+ //Continue setting throttles to prevent a possible throttle == 0
+ //The error will be the last bad port found
+ if (l_fin_power > l_power_limit)
+ {
+ //Need this because of pos traits and templating stuff
+ uint64_t l_fail = mss::fapi_pos(l_port);
+
+ //Set the failing port. OCC just needs one failing port, doesn't need all of them
+ FAPI_TRY( mss::attr::set_port_pos_of_fail_throttle(l_fail) );
+
+ FAPI_ASSERT_NOEXIT( false,
+ fapi2::MSS_CALC_PORT_POWER_EXCEEDS_MAX()
+ .set_CALCULATED_PORT_POWER(l_fin_power)
+ .set_MAX_POWER_ALLOWED(l_power_limit)
+ .set_PORT_POS(mss::pos(l_port))
+ .set_PORT_TARGET(l_port),
+ "Error calculating the final port power value for target %s, calculated power is %d, max value can be %d",
+ mss::c_str(l_port),
+ l_fin_power,
+ l_power_limit);
+
+ o_exceeded_power.push_back(l_port);
+ }
+
+ FAPI_INF("%s Final throttles values for slot %d, for port %d, power value %d",
+ mss::c_str(l_port),
+ l_fin_slot,
+ l_fin_port,
+ l_fin_power);
+
+ //Even if there's an error, still calculate and set the throttles.
+ //OCC will set to safemode if there's an error
+ //Better to set the throttles than leave them 0, and potentially brick the memory
+ FAPI_TRY( mss::attr::set_mem_throttled_n_commands_per_port( l_port, l_fin_port) );
+ FAPI_TRY( mss::attr::set_mem_throttled_n_commands_per_slot( l_port, l_fin_slot) );
+ FAPI_TRY( mss::attr::set_port_maxpower( l_port, l_fin_power) );
+ }
+ }
+ }
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ FAPI_ERR("Error equalizing memory throttles");
+ return fapi2::current_err;
+}
+
+} //ns power_thermal
+}// mss
+
+#endif
diff --git a/src/import/generic/memory/lib/utils/power_thermal/gen_throttle_traits.H b/src/import/generic/memory/lib/utils/power_thermal/gen_throttle_traits.H
index 17758adf1..d6d30fa66 100644
--- a/src/import/generic/memory/lib/utils/power_thermal/gen_throttle_traits.H
+++ b/src/import/generic/memory/lib/utils/power_thermal/gen_throttle_traits.H
@@ -22,3 +22,36 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gen_throttle_traits.H
+/// @brief Contains throttle traits information
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP FW Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: CI
+
+#ifndef _GEN_THROTTLE_TRAITS_H_
+#define _GEN_THROTTLE_TRAITS_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
+namespace mss
+{
+
+namespace power_thermal
+{
+
+///
+/// @class Traits for throttle
+/// @tparam MC mss::mc_type memory controller type
+///
+template< mss::mc_type MC = DEFAULT_MC_TYPE >
+class throttle_traits;
+
+} //ns power_thermal
+} // ns mss
+#endif
diff --git a/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H b/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
index bcf4f1207..77f177c40 100644
--- a/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
+++ b/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] Evan Lojewski */
/* [+] International Business Machines Corp. */
/* */
@@ -38,7 +38,9 @@
#ifndef _MSS_GENERIC_CONSTS_H_
#define _MSS_GENERIC_CONSTS_H_
-#include <cstdint>
+#ifndef __PPE__
+ #include <cstdint>
+#endif
namespace mss
{
@@ -52,6 +54,39 @@ enum common_consts
MEMCMP_EQUAL = 0, ///< Equal comparison value for memcmp
BAD_BITS_RANKS = 4, ///< Bad bit attribute's number of ranks
BAD_DQ_BYTE_COUNT = 10, ///< Bad bit attribute's number of byte
+ ATTR_RANK0 = 0, ///< Attribute index for rank0
+ ATTR_RANK1 = 1, ///< Attribute index for rank1
+ ATTR_RANK2 = 2, ///< Attribute index for rank2
+ ATTR_RANK3 = 3, ///< Attribute index for rank3
+};
+
+///
+/// @brief Common mcbist constants
+///
+enum mcbist_common_consts
+{
+ CYCLES_PER_CMD = 4, ///< Best case cycles per MCBIST command
+ MAX_RANK_PER_DIMM = 4,
+
+ BYTES_PER_GB = 1000000000, ///< Multiplier to go from GB to B
+ T_PER_MT = 1000000, ///< Multiplier to go from MT/s to T/s
+
+ // Number of double words in...
+ NUM_DW_IN_128B = 16,
+ NUM_DW_IN_64B = 8,
+
+ BG_SCRUB_IN_HOURS = 12,
+ CMD_TIMEBASE = 8192, ///< Represents the timebase multiplier for the MCBIST inter cmd gap
+ MAX_CMD_GAP = 4095, ///< Represents the maximum (non-multplied) time for MCBIST inter cmd gap
+
+
+ // MCBIST polling constant for actual HW
+ // The specific value here is not important, only that it is very large to avoid polling timeouts,
+ // but not to avoid any actual hardware timeouts
+ // Note: ~0 is not used as that would cause MCBIST to never timeout even if the hardware is in an infinite loop
+ // You can't get greater than ~0, so you'd never timeout
+ // TODO RTC:166340 - Clean up MCBIST polling
+ OVERLY_LARGE_NUMBER_OF_POLLS = 5000000000000,
};
///
@@ -60,12 +95,13 @@ enum common_consts
enum common_timings
{
DELAY_1NS = 1,
- DELAY_10NS = 10 , ///< general purpose 10 ns delay for HW mode
- DELAY_100NS = 100, ///< general purpose 100 ns delay for HW mode
- DELAY_1US = 1000, ///< general purpose 1 usec delay for HW mode
- DELAY_10US = 10000, ///< general purpose 1 usec delay for HW mode
- DELAY_100US = 100000, ///< general purpose 100 usec delay for HW mode
- DELAY_1MS = 1000000, ///< general purpose 1 ms delay for HW mode
+ DELAY_10NS = 10 , ///< general purpose 10 ns delay for HW mode
+ DELAY_100NS = 100, ///< general purpose 100 ns delay for HW mode
+ DELAY_1US = 1000, ///< general purpose 1 usec delay for HW mode
+ DELAY_10US = 10000, ///< general purpose 1 usec delay for HW mode
+ DELAY_100US = 100000, ///< general purpose 100 usec delay for HW mode
+ DELAY_1MS = 1000000, ///< general purpose 1 ms delay for HW mode
+ DELAY_1S = 1000000000, ///< general purpose 1 sec delay for HW mode
};
///
@@ -80,6 +116,17 @@ enum conversions
NIBBLES_PER_BYTE = 2,
BITS_PER_NIBBLE = 4,
BITS_PER_BYTE = 8,
+ BIT_POS_FOR_BYTE0 = BITS_PER_BYTE * 0,
+ BIT_POS_FOR_BYTE1 = BITS_PER_BYTE * 1,
+ BIT_POS_FOR_BYTE2 = BITS_PER_BYTE * 2,
+ BIT_POS_FOR_BYTE3 = BITS_PER_BYTE * 3,
+ BIT_POS_FOR_BYTE4 = BITS_PER_BYTE * 4,
+ BIT_POS_FOR_BYTE5 = BITS_PER_BYTE * 5,
+ BIT_POS_FOR_BYTE6 = BITS_PER_BYTE * 6,
+ BIT_POS_FOR_BYTE7 = BITS_PER_BYTE * 7,
+
+ // Used by exp_decoder.C for dA to cA
+ DECI_TO_CENTI = 10,
};
enum generic_sizes
@@ -141,8 +188,11 @@ enum generic_ffdc_codes
SET_MRANKS = 0x102A,
SET_HOST_TO_DDR_SPEED_RATIO = 0x102B,
SET_ATTR_HOST_TO_DDR_SPEED_RATIO = 0x102C,
+ CCS_INST_CONFIGURE_RANK = 0x102D,
SET_DIMM_RANKS_CNFG = 0x1039,
DDIMM_RAWCARD_DECODE = 0x103a,
+ INIT_RANK_INFO = 0x103B,
+ BIAS_PMIC_FROM_SPD = 0x103C,
SET_DRAM_WIDTH = 0x1040,
SET_SI_VREF_DRAM_WR = 0x1041,
@@ -170,6 +220,58 @@ enum generic_ffdc_codes
SET_DRAM_GEN_METADATA = 0x1063,
SET_DIMM_TYPE_METADATA = 0x1064,
SET_DIMM_POS_METADATA = 0x1065,
+ SET_LOGICAL_RANKS = 0x1066,
+ SET_PRIM_STACK_TYPE = 0x1067,
+ SET_DIMM_SIZE = 0x1068,
+ SET_PRIM_BUS_WIDTH = 0x1069,
+ SET_PRIM_DIE_COUNT = 0x1070,
+ SET_DRAM_DENSITY = 0x1071,
+
+ // Power thermal functions
+ POWER_LIMIT = 0x1072,
+ SLOPE = 0x1073,
+ INTERCEPT = 0x1074,
+
+ SET_SI_RD_VREF_DQ = 0x1075,
+ SET_CAC_DELAY_A = 0x1076,
+ SET_CAC_DELAY_B = 0x1077,
+ EFD_CA_LATENCY_MODE = 0x1080,
+ EFD_CA_PL_MODE = 0x1081,
+ SET_COL_ADDR_BITS = 0x1082,
+ SET_ROW_ADDR_BITS = 0x1083,
+ SET_3DS_HEIGHT = 0x1084,
+ SET_DRAM_CWL = 0x1085,
+ SET_DRAM_TREFI = 0x1086,
+ SET_DRAM_TCCD_L = 0x1087,
+ SET_DRAM_TWTR_L = 0x1088,
+ SET_DRAM_TWTR_S = 0x1089,
+ SET_DRAM_TFAW = 0x108A,
+ SET_DRAM_TRCD = 0x108B,
+ SET_DRAM_TRP = 0x108C,
+ SET_DRAM_TRAS = 0x108D,
+ SET_DRAM_TWR = 0x108E,
+ SET_DRAM_TRTP = 0x108F,
+ SET_DRAM_TRRD_S = 0x1090,
+ SET_DRAM_TRRD_L = 0x1091,
+ SET_DRAM_TRFC = 0x1092,
+ SET_DRAM_TRFC_DLR = 0x1093,
+ SET_DRAM_MFG_ID = 0x1094,
+
+ // Used in fw_mark_store.H for MSS_INVALID_RANK_PASSED
+ FWMS_READ = 0x1095,
+ FWMS_WRITE = 0x1096,
+
+ // Used in hw_mark_store.H for MSS_INVALID_RANK_PASSED
+ HWMS_READ = 0x1097,
+ HWMS_WRITE = 0x1098,
+
+ // MSS_INVALID_INDEX_PASSED
+ SYMBOL_COUNT_READ = 0x1099,
+ SYMBOL_COUNT_WRITE = 0x109A,
+
+ SET_RCD_MFG_ID = 0x109B,
+ SET_DRAM_MODULE_HEIGHT = 0x109C,
+ SET_SPD_REVISION = 0x109D,
};
///
@@ -242,6 +344,510 @@ enum states
NO_CHIP_SELECT_ACTIVE = 0xFF,
};
+
+enum port_select
+{
+ // Port selects for MCBIST and CCS
+ // Select for 1 port
+ PORT0 = 0b1000,
+ PORT1 = 0b0100,
+ PORT2 = 0b0010,
+ PORT3 = 0b0001,
+ // Selects for 2 port combinations
+ PORT01 = PORT0 | PORT1,
+ PORT02 = PORT0 | PORT2,
+ PORT03 = PORT0 | PORT3,
+ PORT12 = PORT1 | PORT2,
+ PORT13 = PORT1 | PORT3,
+ PORT23 = PORT2 | PORT3,
+ // Selects for 3 port combinations
+ PORT012 = PORT0 | PORT1 | PORT2,
+ PORT013 = PORT0 | PORT1 | PORT3,
+ PORT023 = PORT0 | PORT2 | PORT3,
+ PORT123 = PORT1 | PORT2 | PORT3,
+ // Select all
+ PORT0123 = PORT0 | PORT1 | PORT2 | PORT3,
+ // Maybe a better name for disabling all
+ PORT_NONE = 0b0000,
+};
+
+enum dimm_select
+{
+ // Dimm selects for MCBIST and CCS
+ // Select for 1 dimm
+ DIMM0 = 0b10,
+ DIMM1 = 0b01,
+ // Selects for 2 dimm combinations
+ DIMM01 = DIMM0 | DIMM1,
+ // Maybe a better name for disabling all
+ DIMM_NONE = 0b00,
+};
+
+namespace mcbist
+{
+
+enum broadcast_timebase
+{
+ // Number of 1024 2:1 cycle timebases to wait starting MCBIST
+ // for SRQs to get synced for broadcast mode
+ TB_COUNT_2 = 0b0000001,
+ TB_COUNT_4 = 0b0000011,
+ TB_COUNT_8 = 0b0000111,
+ TB_COUNT_16 = 0b0001111,
+ TB_COUNT_32 = 0b0011111,
+ TB_COUNT_64 = 0b0111111,
+ TB_COUNT_128 = 0b1111111,
+};
+
+enum data_rotate_mode
+{
+ // MCBIST data rotate modes refer to register MCBDRCR bits 0:3
+ ROTATE_0_BITS = 0b0000,
+ ROTATE_1_BITS = 0b0001,
+ ROTATE_2_BITS = 0b0010,
+ ROTATE_3_BITS = 0b0011,
+ ROTATE_4_BITS = 0b0100,
+ ROTATE_5_BITS = 0b0101,
+ ROTATE_6_BITS = 0b0110,
+ ROTATE_7_BITS = 0b0111,
+ ROTATE_8_BITS = 0b1000,
+ ROTATE_9_BITS = 0b1001,
+ ROTATE_10_BITS = 0b1010,
+ ROTATE_11_BITS = 0b1011,
+ ROTATE_12_BITS = 0b1100,
+ ROTATE_13_BITS = 0b1101,
+ ROTATE_14_BITS = 0b1110,
+ ROTATE_15_BITS = 0b1111,
+};
+
+enum data_seed_mode
+{
+ // MCBIST data seed modes refer to register MCBDRCR bits 21:22
+ ALL_UNIQUE = 0b00,
+ REPEAT_SEED_0 = 0b01,
+ REPEAT_SEED_1 = 0b10,
+ REPEAT_SEED_2 = 0b11,
+};
+
+enum data_mode
+{
+ // MCBIST test data modes
+ FIXED_DATA_MODE = 0b000,
+ RAND_FWD_MODE = 0b001,
+ RAND_REV_MODE = 0b010,
+ RAND_FWD_MAINT = 0b011,
+ RAND_REV_MAINT = 0b100,
+ DATA_EQ_ADDR = 0b101,
+ ROTATE_LEFT_MODE = 0b110,
+ ROTATE_RIGHT_MODE = 0b111,
+};
+
+// 0:3 Operation Type
+enum op_type
+{
+ WRITE = 0b0000, // fast, with no concurrent traffic
+ READ = 0b0001, // fast, with no concurrent traffic
+ READ_WRITE = 0b0010,
+ WRITE_READ = 0b0011,
+ READ_WRITE_READ = 0b0100,
+ READ_WRITE_WRITE = 0b0101,
+ RAND_SEQ = 0b0110,
+ READ_READ_WRITE = 0b1000,
+ SCRUB_RRWR = 0b1001,
+ STEER_RW = 0b1010,
+ ALTER = 0b1011, // (W)
+ DISPLAY = 0b1100, // (R, slow)
+ CCS_EXECUTE = 0b1111,
+
+ // if bits 9:11 (Data Mode bits) = 000 (bits 4:8 used to specify which subtest to go to)
+ // Refresh only cmd if bits 9:11 (Data Mode bits) /= 000
+ GOTO_SUBTEST_N = 0b0111,
+};
+
+
+enum test_type
+{
+ USER_MODE = 0,
+ CENSHMOO = 1,
+ SUREFAIL = 2,
+ MEMWRITE = 3,
+ MEMREAD = 4,
+ CBR_REFRESH = 5,
+ MCBIST_SHORT = 6,
+ SHORT_SEQ = 7,
+ DELTA_I = 8,
+ DELTA_I_LOOP = 9,
+ SHORT_RAND = 10,
+ LONG1 = 11,
+ BUS_TAT = 12,
+ SIMPLE_FIX = 13,
+ SIMPLE_RAND = 14,
+ SIMPLE_RAND_2W = 15,
+ SIMPLE_RAND_FIXD = 16,
+ SIMPLE_RA_RD_WR = 17,
+ SIMPLE_RA_RD_R = 18,
+ SIMPLE_RA_FD_R = 19,
+ SIMPLE_RA_FD_R_INF = 20,
+ SIMPLE_SA_FD_R = 21,
+ SIMPLE_RA_FD_W = 22,
+ INFINITE = 23,
+ WR_ONLY = 24,
+ W_ONLY = 25,
+ R_ONLY = 26,
+ W_ONLY_RAND = 27,
+ R_ONLY_RAND = 28,
+ R_ONLY_MULTI = 29,
+ SHORT = 30,
+ SIMPLE_RAND_BARI = 31,
+ W_R_INFINITE = 32,
+ W_R_RAND_INFINITE = 33,
+ R_INFINITE1 = 34,
+ R_INFINITE_RF = 35,
+ MARCH = 36,
+ SIMPLE_FIX_RF = 37,
+ SHMOO_STRESS = 38,
+ SIMPLE_RAND_RA = 39,
+ SIMPLE_FIX_RA = 40,
+ SIMPLE_FIX_RF_RA = 41,
+ TEST_RR = 42,
+ TEST_RF = 43,
+ W_ONLY_INFINITE_RAND = 44,
+ MCB_2D_CUP_SEQ = 45,
+ MCB_2D_CUP_RAND = 46,
+ SHMOO_STRESS_INFINITE = 47,
+ HYNIX_1_COL = 48,
+ RMWFIX = 49,
+ RMWFIX_I = 50,
+ W_INFINITE = 51,
+ R_INFINITE = 52,
+};
+
+
+} // namespace mcbist
+
+namespace omi
+{
+
+///
+/// @brief dl0 no forward progress timer
+///
+enum no_forward_progress_timer
+{
+ NO_FORWARD_TIMER_1US = 0b0000,
+ NO_FORWARD_TIMER_2US = 0b0001,
+ NO_FORWARD_TIMER_4US = 0b0010,
+ NO_FORWARD_TIMER_8US = 0b0011,
+ NO_FORWARD_TIMER_16US = 0b0100,
+ NO_FORWARD_TIMER_32US = 0b0101,
+ NO_FORWARD_TIMER_64US = 0b0110,
+ NO_FORWARD_TIMER_128US = 0b0111,
+ NO_FORWARD_TIMER_256US = 0b1000,
+ NO_FORWARD_TIMER_512US = 0b1001,
+ NO_FORWARD_TIMER_1MS = 0b1010,
+ NO_FORWARD_TIMER_2MS = 0b1011,
+ NO_FORWARD_TIMER_4MS = 0b1100,
+ NO_FORWARD_TIMER_8MS = 0b1101,
+ NO_FORWARD_TIMER_16MS = 0b1110,
+ NO_FORWARD_TIMER_DISABLED = 0b1111,
+};
+
+///
+/// @brief dl0 PHY control mode - determines the amount of time needed to receive pattern A or pattern B
+///
+enum phy_ctr_mode
+{
+ PHY_CTR_MODE_1US = 0b0000,
+ PHY_CTR_MODE_50US = 0b0001,
+ PHY_CTR_MODE_100US = 0b0010,
+ PHY_CTR_MODE_200US = 0b0011,
+ PHY_CTR_MODE_500US = 0b0100,
+ PHY_CTR_MODE_1MS = 0b0101,
+ PHY_CTR_MODE_2MS = 0b0110,
+ PHY_CTR_MODE_3MS = 0b0111,
+ PHY_CTR_MODE_4MS = 0b1000,
+ PHY_CTR_MODE_5MS = 0b1001,
+ PHY_CTR_MODE_6MS = 0b1010,
+ PHY_CTR_MODE_8MS = 0b1011,
+ PHY_CTR_MODE_10MS = 0b1100,
+ PHY_CTR_MODE_15MS = 0b1101,
+ PHY_CTR_MODE_30MS = 0b1110,
+ PHY_CTR_MODE_60MS = 0b1111,
+};
+
+///
+/// @brief dl0 supported link widths
+///
+enum link_widths
+{
+ LINK_WIDTHS_X4PLUS1 = 0b1000,
+ LINK_WIDTHS_X16 = 0b0100,
+ LINK_WIDTHS_X8 = 0b0010,
+ LINK_WIDTHS_X4 = 0b0001,
+};
+
+///
+/// @brief dl0 train mode
+///
+enum train_mode
+{
+ TX_ZEROS = 0b0000,
+ TX_PATTERN_A = 0b0001,
+ TX_PATTERN_B = 0b0010,
+ TX_SYNC_PATTERN = 0b0011,
+ TX_TRAINING_STATE1 = 0b0100,
+ TX_TRAINING_STATE2 = 0b0101,
+ TX_TRAINING_STATE3 = 0b0110,
+ TX_TRAINING_STATE0 = 0b0111,
+ ENABLE_AUTO_TRAINING = 0b1000,
+};
+
+
+///
+/// @brief These values are the number of clock cycles and the times specified assume a 625ps period.
+/// This timer value must be greater than the di/dt timer
+///
+enum rx_cdr_timer
+{
+ CDR_TIMER_DISABLED = 0b0001,
+ CDR_TIMER_60NS = 0b0001,
+ CDR_TIMER_125NS = 0b0010,
+ CDR_TIMER_185NS = 0b0011,
+ CDR_TIMER_250NS = 0b0100,
+ CDR_TIMER_375NS = 0b0101,
+ CDR_TIMER_500NS = 0b0110,
+ CDR_TIMER_750NS = 0b0111,
+ CDR_TIMER_1US = 0b1000,
+ CDR_TIMER_2US = 0b1001,
+ CDR_TIMER_4US = 0b1010,
+ CDR_TIMER_8US = 0b1011,
+ CDR_TIMER_16US = 0b1100,
+ CDR_TIMER_32US = 0b1101,
+ CDR_TIMER_64US = 0b1110,
+ CDR_TIMER_128US = 0b1111,
+};
+
+///
+/// @brief Amount of time to wait after lane is turned on/off before another lane can be turned on/off
+///
+enum didt_timer
+{
+ DIDT_TIMER_DISABLED = 0b0000,
+ DIDT_TIMER_5NS = 0b0001,
+ DIDT_TIMER_10NS = 0b0010,
+ DIDT_TIMER_15NS = 0b0011,
+ DIDT_TIMER_20NS = 0b0100,
+ DIDT_TIMER_30NS = 0b0101,
+ DIDT_TIMER_45NS = 0b0110,
+ DIDT_TIMER_60NS = 0b0111,
+ DIDT_TIMER_90NS = 0b1000,
+ DIDT_TIMER_125NS = 0b1001,
+ DIDT_TIMER_185NS = 0b1010,
+ DIDT_TIMER_250NS = 0b1011,
+ DIDT_TIMER_375NS = 0b1100,
+ DIDT_TIMER_500NS = 0b1101,
+ DIDT_TIMER_768NS = 0b1110,
+ DIDT_TIMER_1US = 0b1111,
+};
+
+///
+/// @brief Calibration timer - amount of time betweem re-calibration for a given lane
+///
+enum recal_timer
+{
+ RECAL_TIMER_DISABLED = 0b000,
+ RECAL_TIMER_25MS = 0b001,
+ RECAL_TIMER_50MS = 0b010,
+ RECAL_TIMER_100MS = 0b011,
+ RECAL_TIMER_200MS = 0b100,
+ RECAL_TIMER_400MS = 0b101,
+ RECAL_TIMER_800MS = 0b110,
+ RECAL_TIMER_1600MS = 0b111,
+};
+
+///
+/// @brief PMU prescalar value
+///
+enum pmu_prescalar
+{
+ PRESCALAR_16BIT = 0b000,
+ PRESCALAR_8BIT = 0b001,
+ PRESCALAR_20BIT = 0b100,
+};
+
+
+///
+/// @brief PMU cntrx pair selector
+///
+enum cntrl_pair_selector
+{
+ SEL_ODD = 0b00,
+ SEL_EVEN = 0b01,
+ SEL_BOTH_AND = 0b10,
+ SEL_BOTH_XOR = 0b11,
+};
+
+///
+/// @brief PMU cntrx event selector
+///
+enum cntrl_event_selector
+{
+ SIG_7_6 = 0b00,
+ SIG_5_4 = 0b01,
+ SIG_3_2 = 0b10,
+ SIG_1_0 = 0b11,
+};
+
+///
+/// @brief Configuration override to select lane width for dynamic lane power down modes.
+///
+enum lan_width_override
+{
+ TL_CTR_BY_SIDEBAND = 0b00,
+ DL_OVERRIDE_X2 = 0b01,
+ DL_OVERRIDE_X4 = 0b10,
+ DL_OVERRIDE_X8 = 0b11,
+};
+
+///
+/// @brief Number of consecutive pattern B seen before indicating received pattern B
+///
+enum b_hysteresis
+{
+ B_HYSTERESIS_16 = 0b0000,
+ B_HYSTERESIS_24 = 0b0001,
+ B_HYSTERESIS_32 = 0b0010,
+ B_HYSTERESIS_40 = 0b0011,
+ B_HYSTERESIS_48 = 0b0100,
+ B_HYSTERESIS_56 = 0b0101,
+ B_HYSTERESIS_64 = 0b0110,
+ B_HYSTERESIS_72 = 0b0111,
+ B_HYSTERESIS_80 = 0b1000,
+ B_HYSTERESIS_96 = 0b1001,
+ B_HYSTERESIS_128 = 0b1010,
+ B_HYSTERESIS_256 = 0b1011,
+ B_HYSTERESIS_512 = 0b1100,
+ B_HYSTERESIS_1K = 0b1101,
+ B_HYSTERESIS_2K = 0b1110,
+ B_HYSTERESIS_4K = 0b1111,
+};
+
+///
+/// @brief Number of consecutive pattern A seen before indicating received pattern A.
+///
+enum a_hysteresis
+{
+ A_HYSTERESIS_16 = 0b0000,
+ A_HYSTERESIS_24 = 0b0001,
+ A_HYSTERESIS_32 = 0b0010,
+ A_HYSTERESIS_48 = 0b0011,
+ A_HYSTERESIS_64 = 0b0100,
+ A_HYSTERESIS_96 = 0b0101,
+ A_HYSTERESIS_128 = 0b0110,
+ A_HYSTERESIS_256 = 0b0111,
+ A_HYSTERESIS_512 = 0b1000,
+ A_HYSTERESIS_1024 = 0b1001,
+ A_HYSTERESIS_2K = 0b1010,
+ A_HYSTERESIS_4K = 0b1011,
+ A_HYSTERESIS_8K = 0b1100,
+ A_HYSTERESIS_16K = 0b1101,
+ A_HYSTERESIS_32K = 0b1110,
+ A_HYSTERESIS_64K = 0b1111,
+};
+
+///
+/// @brief Lanes disabled
+///
+enum
+{
+ LANE_DISABLED_NONE = 0b00000000,
+ LANE_DISABLED_7 = 0b00000001,
+ LANE_DISABLED_6 = 0b00000010,
+ LANE_DISABLED_5 = 0b00000100,
+ LANE_DISABLED_4 = 0b00001000,
+ LANE_DISABLED_3 = 0b00010000,
+ LANE_DISABLED_2 = 0b00100000,
+ LANE_DISABLED_1 = 0b01000000,
+ LANE_DISABLED_0 = 0b10000000,
+};
+
+///
+/// @brief dl0 inject crc direction
+///
+enum crc_inject_dir
+{
+ CRC_DIR_RX = 0,
+ CRC_DIR_TX = 1,
+};
+
+///
+/// @brief dl0 crc injection rate
+///
+enum crc_inject_rate
+{
+ CRC_INJ_RATE_1US = 0b0000,
+ CRC_INJ_RATE_8US = 0b0001,
+ CRC_INJ_RATE_64US = 0b0010,
+ CRC_INJ_RATE_512US = 0b0011,
+ CRC_INJ_RATE_4MS = 0b0100,
+ CRC_INJ_RATE_32MS = 0b0101,
+ CRC_INJ_RATE_256MS = 0b0110,
+ CRC_INJ_RATE_2S = 0b0111,
+};
+
+///
+/// @brief CFG_DL0_EDPL_TIME: dl0 edpl time window
+///
+enum edpl_time_win
+{
+ EDPL_TIME_WIN_NO = 0b0000,
+ EDPL_TIME_WIN_4US = 0b0001,
+ EDPL_TIME_WIN_32US = 0b0010,
+ EDPL_TIME_WIN_256US = 0b0011,
+ EDPL_TIME_WIN_2MS = 0b0100,
+ EDPL_TIME_WIN_16MS = 0b0101,
+ EDPL_TIME_WIN_128MS = 0b0110,
+ EDPL_TIME_WIN_1S = 0b0111,
+ EDPL_TIME_WIN_8S = 0b1000,
+ EDPL_TIME_WIN_64S = 0b1001,
+ EDPL_TIME_WIN_512S = 0b1010,
+ EDPL_TIME_WIN_4KS = 0b1011,
+ EDPL_TIME_WIN_32KS = 0b1100,
+ EDPL_TIME_WIN_256KS = 0b1101,
+ EDPL_TIME_WIN_2MILLIONS = 0b1110,
+ EDPL_TIME_WIN_16MILLIONS = 0b1111,
+};
+
+///
+/// @brief CFG_DL0_EDPL_THRESHOLD: dl0 edpl threshold
+///
+enum edpl_err_thres
+{
+ EDPL_ERR_THRES_DISABLED = 0b000,
+ EDPL_ERR_THRES_2 = 0b001,
+ EDPL_ERR_THRES_4 = 0b010,
+ EDPL_ERR_THRES_8 = 0b011,
+ EDPL_ERR_THRES_16 = 0b100,
+ EDPL_ERR_THRES_32 = 0b101,
+ EDPL_ERR_THRES_64 = 0b110,
+ EDPL_ERR_THRES_128 = 0b111,
+};
+
+///
+/// @brief CONFIG1_CFG_PREIPL_PRBS_TIME: config1 pre-ipl prbs time
+///
+enum preipl_prbs_time
+{
+ PREIPL_PRBS_256US = 0b000,
+ PREIPL_PRBS_1US = 0b001,
+ PREIPL_PRBS_4MS = 0b010,
+ PREIPL_PRBS_16MS = 0b011,
+ PREIPL_PRBS_64MS = 0b100,
+ PREIPL_PRBS_256MS = 0b101,
+ PREIPL_PRBS_1S = 0b110,
+ PREIPL_PRBS_4S = 0b111,
+};
+
+}
///
/// @brief Supported DIMM speed equality deliberations
///
@@ -260,6 +866,7 @@ namespace spd
enum rev : uint8_t
{
V0_0 = 0x00, ///< represents Rev 0.0
+ V0_3 = 0x03, ///< represents Rev 0.3
V1_0 = 0x10, ///< represents Rev 1.0
V1_1 = 0x11, ///< represents Rev 1.1
V1_2 = 0x12, ///< represents Rev 1.2
@@ -269,7 +876,7 @@ enum rev : uint8_t
GEN_SEC_MAX = V1_1,
RDIMM_MAX = V1_1,
LRDIMM_MAX = V1_2,
- DDIMM_MAX = V0_0,
+ DDIMM_MAX = V0_3,
};
///
@@ -356,6 +963,7 @@ enum class throttle_type
};
+
///
/// @brief Trait classes for mc_type
/// @tparam MC the mc_type
diff --git a/src/import/generic/memory/lib/utils/voltage/gen_mss_volt.H b/src/import/generic/memory/lib/utils/voltage/gen_mss_volt.H
index d84c97dbe..9ff39109e 100644
--- a/src/import/generic/memory/lib/utils/voltage/gen_mss_volt.H
+++ b/src/import/generic/memory/lib/utils/voltage/gen_mss_volt.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -115,8 +115,6 @@ inline fapi2::ReturnCode setup_voltage_rail_values(const fapi2::Target<TT::SPD_T
FAPI_TRY( (mss::set_voltage_attributes<M, D>(l_voltage_target, l_dram_voltages)),
"Failed to set volt attributes for %s", mss::c_str(l_voltage_target) );
- FAPI_INF("%s End setup_voltage_rail_values", mss::c_str(i_target));
-
fapi_try_exit:
return fapi2::current_err;
}
diff --git a/src/import/generic/memory/mss_git_data_helper.H b/src/import/generic/memory/mss_git_data_helper.H
index c20a62ab0..ef09834fa 100644
--- a/src/import/generic/memory/mss_git_data_helper.H
+++ b/src/import/generic/memory/mss_git_data_helper.H
@@ -22,3 +22,37 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file mss_git_data_helper.H
+/// @brief Helper file to print out the git data
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_GIT_DATA_HELPER_
+#define _MSS_GIT_DATA_HELPER_
+
+#ifndef __HOSTBOOT_MODULE
+ #include <generic/memory/mss_git_data.H>
+#endif
+
+namespace mss
+{
+
+///
+/// @brief Prints out the git commit data
+/// @pram[in] i_print additional print information to be added to the print statement
+///
+inline void display_git_commit_info(const char* i_print)
+{
+#ifndef __HOSTBOOT_MODULE
+ FAPI_INF("%s Git commit ID: %s", i_print, GIT_COMMIT_ID.c_str());
+#endif
+}
+
+} // ns mss
+
+#endif
diff --git a/src/import/generic/procedures/xml/attribute_info/generic_memory_attributes.xml b/src/import/generic/procedures/xml/attribute_info/generic_memory_attributes.xml
index 48c351b5f..ea15be54c 100644
--- a/src/import/generic/procedures/xml/attribute_info/generic_memory_attributes.xml
+++ b/src/import/generic/procedures/xml/attribute_info/generic_memory_attributes.xml
@@ -86,9 +86,15 @@
The map from the Dual Inline Memory Module
(DIMM) Data (DQ) Pin to the Module Package Data (DQ) Pinout
</description>
- <initToZero></initToZero>
+ <platInit/>
+ <mrwHide/>
+ <default>
+ <!-- Default to a 1:1 layout to match the DDIMM specification -->
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,
+ 27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,
+ 51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71
+ </default>
<valueType>uint8</valueType>
- <writeable/>
<mssUnits></mssUnits>
<mssBlobStart>0</mssBlobStart>
<mssBlobLength>72</mssBlobLength>
@@ -388,4 +394,33 @@
<mssAccessorName>dimm_type_metadata</mssAccessorName>
</attribute>
+ <attribute>
+ <id>ATTR_MSS_OMI_EDPL_DISABLE</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ EDPL (Error Detection Per Lane) is a feature in the DL that adds some additional checks to
+ the traffic going across the OpenCAPI link in order to better track which lanes are having issues.
+ Note: EDPL must be set the same on both sides of the link. This attribute affects both the proc/mc
+ side and the OCMB side.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>FALSE = 0, TRUE = 1</enum>
+ <platInit/>
+ <initToZero/>
+ <mssAccessorName>mss_omi_edpl_disable</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_OMI_DL_PREIPL_PRBS_TIME</id>
+ <targetType>TARGET_TYPE_OMI</targetType>
+ <description>
+ The time to send pre-ipl PRBS in ms.
+ </description>
+ <valueType>uint32</valueType>
+ <default>0x400</default>
+ <platInit/>
+ <mrwHide/>
+ <mssAccessorName>omi_dl_preipl_prbs_time</mssAccessorName>
+ </attribute>
+
</attributes>
diff --git a/src/import/generic/procedures/xml/attribute_info/generic_memory_eff_attributes.xml b/src/import/generic/procedures/xml/attribute_info/generic_memory_eff_attributes.xml
index 8890a447b..50246bb19 100644
--- a/src/import/generic/procedures/xml/attribute_info/generic_memory_eff_attributes.xml
+++ b/src/import/generic/procedures/xml/attribute_info/generic_memory_eff_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2018,2019 -->
+<!-- Contributors Listed Below - COPYRIGHT 2018,2020 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -64,7 +64,7 @@
</description>
<initToZero></initToZero>
<valueType>uint8</valueType>
- <enum> EMPTY = 0, RDIMM = 1, UDIMM = 2, LRDIMM = 3, DDIMM = 4</enum>
+ <enum> EMPTY = 0, RDIMM = 1, UDIMM = 2, LRDIMM = 3, DDIMM = 4, MDS_LRDIMM = 5, MDS = 6</enum>
<writeable/>
<array>2</array>
<mssAccessorName>dimm_type</mssAccessorName>
@@ -187,6 +187,7 @@
</description>
<initToZero></initToZero>
<valueType>uint8</valueType>
+ <enum> NUM10 = 10</enum>
<writeable/>
<array>2</array>
<mssAccessorName>dram_column_bits</mssAccessorName>
@@ -212,11 +213,36 @@
</attribute>
<attribute>
+ <id>ATTR_MEM_EFF_PRIM_DIE_COUNT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ ARRAY[DIMM]
+ Primary SDRAM Die Count.
+ Decodes Byte 6 (bits 6~4).
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <enum>
+ D1 = 1,
+ D2 = 2,
+ D3 = 3,
+ D4 = 4,
+ D5 = 5,
+ D6 = 6,
+ D7 = 7,
+ D8 = 8
+ </enum>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>prim_die_count</mssAccessorName>
+ </attribute>
+
+ <attribute>
<id>ATTR_MEM_EFF_PRIM_STACK_TYPE</id>
<targetType>TARGET_TYPE_MEM_PORT</targetType>
<description>
ARRAY[DIMM]
- Primary SDRAM Package Type.
+ Primary SDRAM Package Type (bits 1~0).
Decodes Byte 6.
This byte defines the primary set of SDRAMs.
Monolithic = SPD, Multi-load stack = DDP/QDP, Single-load stack = 3DS
@@ -230,6 +256,24 @@
</attribute>
<attribute>
+ <id>ATTR_MEM_EFF_PRIM_BUS_WIDTH</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ ARRAY[DIMM]
+ Primary bus with (bits 1~0).
+ Decodes Byte 13.
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <enum>
+ 8_BITS = 8, 16_BITS = 16, 32_BITS = 32, 64_BITS = 64
+ </enum>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>prim_bus_width</mssAccessorName>
+ </attribute>
+
+ <attribute>
<id>ATTR_MEM_EFF_DRAM_PPR</id>
<targetType>TARGET_TYPE_MEM_PORT</targetType>
<description>
@@ -522,7 +566,7 @@
</attribute>
<attribute>
- <id>ATTR_MEM_EFF_NUM_RANKS_PER_DIMM</id>
+ <id>ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM</id>
<targetType>TARGET_TYPE_MEM_PORT</targetType>
<description>
ARRAY[DIMM]
@@ -542,7 +586,21 @@
</enum>
<writeable/>
<array>2</array>
- <mssAccessorName>num_ranks_per_dimm</mssAccessorName>
+ <mssAccessorName>logical_ranks_per_dimm</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_3DS_HEIGHT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Setting for 3DS stack. Calculated from logical_ranks / master_ranks
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint16</valueType>
+ <enum>PLANAR = 0, H2 = 2, H4 = 4, H8 = 8</enum>
+ <array>2</array>
+ <writeable/>
+ <mssAccessorName>3ds_height</mssAccessorName>
</attribute>
<attribute>
@@ -567,7 +625,8 @@
<description>
ARRAY[DIMM]
DRAM Manufacturer ID Code
- Decodes SPD Byte 350 and 351
+ Decodes SPD Byte 350 and 351 for ISDIMMs
+ Decodes SPD Byte 552 and 553 for DDIMMs
</description>
<enum>MICRON = 0x802C, SAMSUNG = 0x80CE, HYNIX = 0x80AD </enum>
<initToZero></initToZero>
@@ -578,6 +637,22 @@
</attribute>
<attribute>
+ <id>ATTR_MEM_EFF_DRAM_MODULE_HEIGHT</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ ARRAY[DIMM]
+ DRAM Modlue Height
+ Decodes SPD Byte 193
+ </description>
+ <enum>1U = 0, 2U = 1, 4U = 2 </enum>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <array>2</array>
+ <mssAccessorName>dram_module_height</mssAccessorName>
+ </attribute>
+
+ <attribute>
<id>ATTR_MEM_EFF_RCD_MFG_ID</id>
<targetType>TARGET_TYPE_MEM_PORT</targetType>
<description>
@@ -693,6 +768,18 @@
</attribute>
<attribute>
+ <id>ATTR_MEM_EFF_DRAM_MDS</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ Controls if the given target has an MDS (managed DRAM solution)
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <mssAccessorName>dram_mds</mssAccessorName>
+ </attribute>
+
+ <attribute>
<id>ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM</id>
<targetType>TARGET_TYPE_MEM_PORT</targetType>
<description>
@@ -818,4 +905,16 @@
<mssAccessorName>volt_vpp</mssAccessorName>
</attribute>
+ <attribute>
+ <id>ATTR_MEM_EFF_SPD_REVISION</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ SPD Revision (SPD Byte 1)
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <writeable/>
+ <mssAccessorName>spd_revision</mssAccessorName>
+ </attribute>
+
</attributes>
diff --git a/src/import/generic/procedures/xml/attribute_info/generic_memory_mrw_attributes.xml b/src/import/generic/procedures/xml/attribute_info/generic_memory_mrw_attributes.xml
index 31ac9b4c0..49d4a17ed 100644
--- a/src/import/generic/procedures/xml/attribute_info/generic_memory_mrw_attributes.xml
+++ b/src/import/generic/procedures/xml/attribute_info/generic_memory_mrw_attributes.xml
@@ -251,7 +251,7 @@
<valueType>uint32</valueType>
<platInit/>
<mssUnits>c%</mssUnits>
- <default>0x00002328</default>
+ <default>0x00002710</default>
<initToZero/>
<mssAccessorName>mrw_max_dram_databus_util</mssAccessorName>
</attribute>
@@ -606,4 +606,159 @@
<mssAccessorName>mrw_supported_dram_width</mssAccessorName>
</attribute>
+ <attribute>
+ <id>ATTR_MSS_MRW_OCMB_THERMAL_MEMORY_POWER_LIMIT</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ Machine Readable Workbook Thermal Memory Power Limit
+ Used to calculate throttles to meet the thermal power per DIMM limit
+ Per DIMM basis, uses first matching KEY entry
+ KEY (0-21): In order
+ DIMM_SIZE = bits 0-3,
+ DIMM_GEN = 4-5,
+ DIMM_TYPE = 6-8,
+ DIMM_WIDTH = 9-11,
+ DIMM_DENSITY = 12-14,
+ DIMM_STACK_TYPE = 15-16,
+ DRAM_MFGID = 17-19,
+ DIMM_HEIGHT = 20-21,
+ Bits 22-32: Not used
+ VALUE (bits 32-47) in cW: thermal power limit
+ DDIMM: Total OCMB+DRAM power limit per DDIMM
+ non-DDIMM: VMEM+VPP power limit per DIMM
+ </description>
+ <valueType>uint64</valueType>
+ <mssUnits>cW</mssUnits>
+ <default>0xfffffc0009c40000</default>
+ <array>25</array>
+ <platInit/>
+ <mssAccessorName>mrw_ocmb_thermal_memory_power_limit</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MSS_MRW_OCMB_PWR_SLOPE</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ Machine Readable Workbook Power Curve Slope for DIMM
+ Used to calculate thermal throttles and port power
+ Per DIMM basis, uses first matching KEY entry
+ KEY (0-21): In order
+ DIMM_SIZE = bits 0-3,
+ DIMM_GEN = 4-5,
+ DIMM_TYPE = 6-8,
+ DIMM_WIDTH = 9-11,
+ DIMM_DENSITY = 12-14,
+ DIMM_STACK_TYPE = 15-16,
+ DRAM_MFGID = 17-19,
+ DIMM_HEIGHT = 20-21,
+ Bits 22-32: Not used
+ VALUE (bits 32-47) in cW/utilization: DIMM power slope
+ DDIMM: Total OCMB+DRAM power slope per DDIMM
+ non-DDIMM: VMEM+VPP power slope per DIMM
+ </description>
+ <valueType>uint64</valueType>
+ <mssUnits>cW</mssUnits>
+ <default>0xfffffc0004620000</default>
+ <array>50</array>
+ <platInit/>
+ <mssAccessorName>mrw_ocmb_pwr_slope</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MSS_MRW_OCMB_PWR_INTERCEPT</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ Machine Readable Workbook Power Curve Intercept for DIMM
+ Used to calculate thermal throttles and port power
+ Per DIMM basis, uses first matching KEY entry
+ KEY (0-21): In order
+ DIMM_SIZE = bits 0-3,
+ DIMM_GEN = 4-5,
+ DIMM_TYPE = 6-8,
+ DIMM_WIDTH = 9-11,
+ DIMM_DENSITY = 12-14,
+ DIMM_STACK_TYPE = 15-16,
+ DRAM_MFGID = 17-19,
+ DIMM_HEIGHT = 20-21,
+ Bits 22-32: Not used
+ VALUE (bits 32-47) in cW/utilization: DIMM power intercept
+ DDIMM: Total OCMB+DRAM power intercept per DDIMM
+ non-DDIMM: VMEM+VPP power intercept per DIMM
+ </description>
+ <valueType>uint64</valueType>
+ <mssUnits>cW/utilization</mssUnits>
+ <default>0xfffffc0005260000</default>
+ <array>50</array>
+ <platInit/>
+ <mssAccessorName>mrw_ocmb_pwr_intercept</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MSS_MRW_OCMB_CURRENT_CURVE_WITH_LIMIT</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ Machine Readable Workbook Current Curve Intercept and limit for DIMM
+ Used to calculate throttles to meet regulator current per DIMM limit
+ Per DIMM basis, uses first matching KEY entry
+ For DDIMM, use PMIC SW output that provides worst case throttling
+ KEY (0-21): In order
+ DIMM_SIZE = bits 0-3,
+ DIMM_GEN = 4-5,
+ DIMM_TYPE = 6-8,
+ DIMM_WIDTH = 9-11,
+ DIMM_DENSITY = 12-14,
+ DIMM_STACK_TYPE = 15-16,
+ DRAM_MFGID = 17-19,
+ DIMM_HEIGHT = 20-21,
+ Bits 22-32: Not used
+ VALUE (bits 32-39): Current limit (dA)
+ DDIMM: PMIC output current limit per DDIMM
+ non-DDIMM: VMEM regulator current limit per DIMM
+ VALUE (bits 40-51): Current slope (cA/utilization)
+ DDIMM: PMIC output current slope per DDIMM
+ non-DDIMM: VMEM regulator current slope per DIMM
+ VALUE (bits 52-63): Current intercept (cA)
+ DDIMM: PMIC output current intercept per DDIMM
+ non-DDIMM: VMEM regulator current intercept per DIMM
+ </description>
+ <valueType>uint64</valueType>
+ <mssUnits>dA, cA/utilization, cA</mssUnits>
+ <default>0xFFFFFC0064152094</default>
+ <array>25</array>
+ <platInit/>
+ <mssAccessorName>mrw_ocmb_current_curve_with_limit</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MSS_MRW_SAFEMODE_DRAM_DATABUS_UTIL</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ Machine Readable Workbook value for safe mode dram data bus utilization in centi percent (c%).
+ Set to below optimum value/ rate.
+ On a per port basis
+ Also used for emergency mode throttle
+ Used to thermally protect the system in all supported environmental conditions when OCC is not functional
+ Consumer: thermal_init, initfile
+ Default to 2500 c%%
+ </description>
+ <valueType>uint32</valueType>
+ <default>0x000009C4</default>
+ <platInit/>
+ <initToZero/>
+ <mssAccessorName>mrw_safemode_dram_databus_util</mssAccessorName>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_MEM_PORT_POS_OF_FAIL_THROTTLE</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ This is the fapi position of the port that failed to calculate
+ memory throttles given the passed in watt target and or utilization
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint64</valueType>
+ <mssAccessorName>port_pos_of_fail_throttle</mssAccessorName>
+ <writeable/>
+ </attribute>
+
</attributes>
diff --git a/src/import/generic/procedures/xml/attribute_info/generic_memory_si_attributes.xml b/src/import/generic/procedures/xml/attribute_info/generic_memory_si_attributes.xml
index 1ec910f04..9ff21bdd1 100644
--- a/src/import/generic/procedures/xml/attribute_info/generic_memory_si_attributes.xml
+++ b/src/import/generic/procedures/xml/attribute_info/generic_memory_si_attributes.xml
@@ -106,7 +106,7 @@
<initToZero></initToZero>
<valueType>uint8</valueType>
<writeable/>
- <enum>OHM34 = 34, OHM48 = 48</enum>
+ <enum>DISABLE = 0, OHM34 = 34, OHM48 = 48</enum>
<mssUnits>ohm</mssUnits>
<mssAccessorName>si_dram_drv_imp_dq_dqs</mssAccessorName>
<array>2 4</array>
@@ -140,7 +140,7 @@
<initToZero></initToZero>
<valueType>uint8</valueType>
<writeable/>
- <enum>DISABLE = 0, OHM34 = 34, OHM40 = 40, OHM48 = 48, OHM60 = 60, OHM80 = 80, OHM120 = 120, OHM240 = 240</enum>
+ <enum>DISABLE = 0, OHM34 = 34, OHM40 = 40, OHM60 = 60, OHM80 = 80, OHM120 = 120, OHM240 = 240</enum>
<mssUnits>ohm</mssUnits>
<mssAccessorName>si_dram_rtt_nom</mssAccessorName>
<array>2 4</array>
@@ -172,42 +172,13 @@
<initToZero></initToZero>
<valueType>uint8</valueType>
<writeable/>
- <enum>DISABLE = 0, HIGHZ = 1, OHM80 = 80, OHM120 = 120, OHM240 = 240</enum>
+ <enum>DISABLE = 0, OHM80 = 80, OHM120 = 120, OHM240 = 240</enum>
<mssUnits>ohm</mssUnits>
<mssAccessorName>si_dram_rtt_wr</mssAccessorName>
<array>2 4</array>
</attribute>
<attribute>
- <id>ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE</id>
- <targetType>TARGET_TYPE_MEM_PORT</targetType>
- <description>
- ARRAY[DIMM][RANK]
- vrefdq_train value. This is for DDR4 MRS6.
- </description>
- <initToZero></initToZero>
- <valueType>uint8</valueType>
- <writeable/>
- <array>2 4</array>
- <mssAccessorName>si_vref_dq_train_value</mssAccessorName>
- </attribute>
-
- <attribute>
- <id>ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE</id>
- <targetType>TARGET_TYPE_MEM_PORT</targetType>
- <description>
- ARRAY[DIMM][RANK]
- vrefdq_train range. This is for DDR4 MRS6.
- </description>
- <initToZero></initToZero>
- <valueType>uint8</valueType>
- <enum>RANGE1 = 0, RANGE2 = 1</enum>
- <writeable/>
- <array>2 4</array>
- <mssAccessorName>si_vref_dq_train_range</mssAccessorName>
- </attribute>
-
- <attribute>
<id>ATTR_MEM_SI_GEARDOWN_MODE</id>
<targetType>TARGET_TYPE_MEM_PORT</targetType>
<description>
@@ -278,7 +249,7 @@
<initToZero></initToZero>
<valueType>uint8</valueType>
<writeable/>
- <enum>DISABLE = 0</enum>
+ <enum>DISABLE = 0, OHM_20 = 20, OHM_24 = 24, OHM_30 = 30, OHM_40 = 40, OHM_60 = 60, OHM_120 = 120</enum>
<mssUnits>ohm</mssUnits>
<mssAccessorName>si_mc_drv_imp_clk</mssAccessorName>
<array>2 4</array>
@@ -294,7 +265,7 @@
<initToZero></initToZero>
<valueType>uint8</valueType>
<writeable/>
- <enum>DISABLE = 0</enum>
+ <enum>DISABLE = 0, OHM_20 = 20, OHM_24 = 24, OHM_30 = 30, OHM_40 = 40, OHM_60 = 60, OHM_120 = 120</enum>
<mssUnits>ohm</mssUnits>
<mssAccessorName>si_mc_drv_imp_cmd_addr</mssAccessorName>
<array>2 4</array>
@@ -340,9 +311,11 @@
Memory Controller side Drive Impedance Pull Down for Data and Data Strobe Lines in Ohms.
</description>
<initToZero></initToZero>
- <valueType>uint8</valueType>
+ <valueType>uint16</valueType>
<writeable/>
- <enum>DISABLE = 0</enum>
+ <enum>DISABLE = 0, OHM_28 = 28, OHM_30 = 30, OHM_32 = 32, OHM_34 = 34, OHM_36 = 36, OHM_40 = 40, OHM_43 = 43,
+ OHM_48 = 48, OHM_53 = 53, OHM_60 = 60, OHM_68 = 68, OHM_80 = 80, OHM_96 = 96, OHM_120 = 120, OHM_160 = 160,
+ OHM_240 = 240, OHM_480 = 480</enum>
<mssUnits>ohm</mssUnits>
<mssAccessorName>si_mc_drv_imp_dq_dqs_pull_down</mssAccessorName>
<array>2 4</array>
@@ -356,9 +329,11 @@
Memory Controller side Drive Impedance Pull Up for Data and Data Strobe Lines in Ohms.
</description>
<initToZero></initToZero>
- <valueType>uint8</valueType>
+ <valueType>uint16</valueType>
<writeable/>
- <enum>DISABLE = 0</enum>
+ <enum>DISABLE = 0, OHM_28 = 28, OHM_30 = 30, OHM_32 = 32, OHM_34 = 34, OHM_36 = 36, OHM_40 = 40, OHM_43 = 43,
+ OHM_48 = 48, OHM_53 = 53, OHM_60 = 60, OHM_68 = 68, OHM_80 = 80, OHM_96 = 96, OHM_120 = 120, OHM_160 = 160,
+ OHM_240 = 240, OHM_480 = 480</enum>
<mssUnits>ohm</mssUnits>
<mssAccessorName>si_mc_drv_imp_dq_dqs_pull_up</mssAccessorName>
<array>2 4</array>
@@ -453,7 +428,7 @@
<initToZero></initToZero>
<valueType>uint8</valueType>
<writeable/>
- <enum>DISABLE = 0</enum>
+ <enum>DISABLE = 0, OHM_40 = 40, OHM_48 = 48, OHM_60 = 60, OHM_80 = 80, OHM_120 = 120, OHM_240 = 240</enum>
<mssUnits>ohm</mssUnits>
<mssAccessorName>si_mc_rcv_imp_alert_n</mssAccessorName>
<array>2 4</array>
@@ -469,7 +444,7 @@
<initToZero></initToZero>
<valueType>uint8</valueType>
<writeable/>
- <enum>DISABLE = 0</enum>
+ <enum>DISABLE = 0, OHM_40 = 40, OHM_60 = 60, OHM_80 = 80, OHM_120 = 120, OHM_240 = 240</enum>
<mssUnits>ohm</mssUnits>
<mssAccessorName>si_mc_rcv_imp_dq_dqs</mssAccessorName>
<array>2 4</array>
@@ -483,6 +458,7 @@
READ, On Die Termination triggering bitmap. Use bitmap to determine which ODT to fire for the designated rank.
The bits in 8 bit field are
[DIMM0 ODT0][DIMM0 ODT1][DIMM0 ODT2][DIMM0 ODT3][DIMM1 ODT0][DIMM1 ODT1][DIMM1 ODT2][DIMM1 ODT3]
+ For Explorer: Only bits 0,1,4,5 are used. They correspond to A0 A1 -- -- B0 B1 -- --
</description>
<initToZero></initToZero>
<valueType>uint8</valueType>
@@ -499,6 +475,7 @@
WRITE, On Die Termination triggering bitmap. Use bitmap to determine which ODT to fire for the designated rank.
The bits in 8 bit field are
[DIMM0 ODT0][DIMM0 ODT1][DIMM0 ODT2][DIMM0 ODT3][DIMM1 ODT0][DIMM1 ODT1][DIMM1 ODT2][DIMM1 ODT3]
+ For Explorer: Only bits 0,1,4,5 are used. They correspond to A0 A1 -- -- B0 B1 -- --
</description>
<initToZero></initToZero>
<valueType>uint8</valueType>
diff --git a/src/import/generic/procedures/xml/error_info/generic_error.xml b/src/import/generic/procedures/xml/error_info/generic_error.xml
index 7b3f1e894..d25d1885b 100644
--- a/src/import/generic/procedures/xml/error_info/generic_error.xml
+++ b/src/import/generic/procedures/xml/error_info/generic_error.xml
@@ -68,6 +68,47 @@
</hwpError>
<hwpError>
+ <rc>RC_MSS_FAILED_SPD_REVISION_FALLBACK</rc>
+ <description>
+ Unable to fall back SPD decoder to the highest decoded
+ revision. Most likely a programming error.
+ </description>
+ <ffdc>FAILED_REVISION</ffdc>
+ <ffdc>FUNCTION_CODE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_FAILED_TO_FIND_TRFC</rc>
+ <description>
+ Unable to find tRFC (ps) from map with SDRAM density key
+ </description>
+ <ffdc>SDRAM_DENSITY</ffdc>
+ <ffdc>REFRESH_MODE</ffdc>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
<rc>RC_MSS_FREQ_CL_EXCEEDS_TAA_MAX</rc>
<description>
Calculated Cas Latency exceeds JEDEC value for TAA Max
@@ -129,6 +170,17 @@
</hwpError>
<hwpError>
+ <rc>RC_MSS_FREQ_INDEX_TOO_LARGE</rc>
+ <description>Error calculating the index into max_freq array</description>
+ <ffdc>INDEX</ffdc>
+ <ffdc>NUM_MAX_FREQS</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
<rc>RC_MSS_FREQ_INVALID_CALCULATED_TCK</rc>
<description>
Invalid value clock period (less than equal 0).
@@ -204,6 +256,18 @@
</callout>
</hwpError>
+ <hwpError>
+ <rc>RC_MSS_INVALID_CAST_CALC_NCK</rc>
+ <description>Invalid cast or calculation for calc_nck</description>
+ <ffdc>TIMING_PS</ffdc>
+ <ffdc>NCK_NS</ffdc>
+ <ffdc>CORRECTION_FACTOR</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
<hwpError>
<rc>RC_MSS_INVALID_CLOCK_PERIOD</rc>
<description>
@@ -216,17 +280,170 @@
</callout>
</hwpError>
-<hwpError>
- <rc>RC_MSS_INVALID_FREQUENCY</rc>
- <description>
- An invalid frequency was passed to frequency to clock period
- </description>
- <ffdc>FREQ</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
-</hwpError>
+ <hwpError>
+ <rc>RC_MSS_INVALID_DB_MDQ_DRIVE_STRENGTH</rc>
+ <description>
+ Bad SPD data for bytes 145 - 147.
+ Reserved settings for data buffer MDQ drive strength received.
+ This could be code problem (decoding) or bad SPD.
+ </description>
+ <ffdc>DATA_RATE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_DIMM_SPEED</rc>
+ <description>
+ Invalid DIMM speed received. Possibly a programming error.
+ </description>
+ <ffdc>DIMM_SPEED</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_DIMM_TYPE</rc>
+ <description>
+ Received a DIMM type unsupported by the SPD decoder factory
+ </description>
+ <ffdc>DIMM_TYPE</ffdc>
+ <ffdc>FUNCTION</ffdc>
+ <callout>
+ <procedure>MEMORY_PLUGGING_ERROR</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>LOW</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_DRAM_GEN</rc>
+ <description>
+ Received a DRAM gen unsupported by the SPD decoder factory
+ </description>
+ <ffdc>DRAM_GEN</ffdc>
+ <ffdc>FUNCTION</ffdc>
+ <callout>
+ <procedure>MEMORY_PLUGGING_ERROR</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>LOW</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_FREQ_PASSED_IN</rc>
+ <description>
+ An invalid Freq value has been set
+ </description>
+ <ffdc>FREQ</ffdc>
+ <ffdc>FUNCTION</ffdc>
+ <ffdc>DIMM_TARGET</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_FREQUENCY</rc>
+ <description>
+ An invalid frequency was passed to frequency to clock period
+ </description>
+ <ffdc>FREQ</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_FREQ_LIST_PASSED</rc>
+ <description>
+ Wrong size vector passed into frequency scoreboard function
+ </description>
+ <ffdc>SIZE</ffdc>
+ <ffdc>EXPECTED</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_FINE_REFRESH_MODE</rc>
+ <description>
+ Invalid fine refresh mode received from the mrw
+ </description>
+ <ffdc>FINE_REF_MODE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_HYBRID_MODULE</rc>
+ <description>
+ Received an invalid or unsupported hybrid media (SPD byte 3, bits [6:4])
+ for a specified hybrid modue (SPD byte 3, bit [7])
+ </description>
+ <ffdc>HYBRID</ffdc>
+ <ffdc>HYBRID_MEDIA</ffdc>
+ <ffdc>FUNCTION</ffdc>
+ <callout>
+ <procedure>MEMORY_PLUGGING_ERROR</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>LOW</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
<hwpError>
<rc>RC_MSS_INVALID_PORT_INDEX_PASSED</rc>
@@ -240,6 +457,89 @@
</hwpError>
<hwpError>
+ <rc>RC_MSS_INVALID_RANK</rc>
+ <description>
+ Invalid rank passed into function
+ </description>
+ <ffdc>FUNCTION</ffdc>
+ <ffdc>RANK</ffdc>
+ <ffdc>PORT_TARGET</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_REFRESH_RATE_REQUEST</rc>
+ <description>
+ Invalid refresh request rate received.
+ Possibly due to bad MRW setting for ATTR_MSS_MRW_REFRESH_RATE_REQUEST.
+ </description>
+ <ffdc>REFRESH_RATE_REQUEST</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_SPD_PARAMETER_RECEIVED</rc>
+ <description>
+ Unable to fall back SPD decoder to the highest decoded
+ revision. Most likely a programming error.
+ </description>
+ <ffdc>SPD_PARAM</ffdc>
+ <ffdc>FUNCTION_CODE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_SPD_RANK</rc>
+ <description>
+ Invalid rank passed into attribute engine.
+ May be due to problem in SPD.
+ </description>
+ <ffdc>FUNCTION</ffdc>
+ <ffdc>RANK</ffdc>
+ <ffdc>TARGET</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_SPD_RESERVED_BITS</rc>
+ <description>
+ Invalid SPD reserved bits received.
+ This could be code problem (decoding) or bad SPD.
+ </description>
+ <ffdc>FUNCTION_CODE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
<rc>RC_MSS_INVALID_TIMING_VALUE</rc>
<description>Invalid value calculated for timing value based on MTB and FTB from SPD.</description>
<ffdc>VALUE</ffdc>
@@ -256,6 +556,36 @@
</gard>
</hwpError>
+ <hwpError>
+ <rc>RC_MSS_INVALID_VPD_FREQ_LIST_PASSED</rc>
+ <description>
+ Wrong size vector passed into limit_freq_by_vpd function
+ </description>
+ <ffdc>SIZE</ffdc>
+ <ffdc>EXPECTED</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_VPD_KEYWORD_MAX</rc>
+ <description>
+ VPD keyword is too big for space allocated for it.
+ </description>
+ <ffdc>MAX</ffdc>
+ <ffdc>ACTUAL</ffdc>
+ <ffdc>KEYWORD</ffdc>
+ <callout>
+ <hw>
+ <hwid>VPD_PART</hwid>
+ <refTarget>VPD_TARGET</refTarget>
+ </hw>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
<hwpError>
<rc>RC_MSS_LOOKUP_FAILED</rc>
<description>
@@ -274,6 +604,39 @@
</hwpError>
<hwpError>
+ <rc>RC_MSS_MEMDIAGS_NO_MCBIST_SUBTESTS</rc>
+ <description>Attempt to run an MCBIST program with no subtests</description>
+ <ffdc>MC_TARGET</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_MCBIST_EXCEEDED_MAX_SUBTESTS</rc>
+ <description>Attempt to run an MCBIST program exceeding the max number of subtests (32)</description>
+ <ffdc>MC_TARGET</ffdc>
+ <ffdc>NUMBER_OF_SUBTESTS</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_MCBIST_INCORRECT_PATTERN_LENGTH</rc>
+ <description>MCBIST pattern has an incorrect length</description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>ACTUAL</ffdc>
+ <ffdc>EXPECTED</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
<rc>RC_MSS_VOLT_WRONG_NUMBER_OF_VOLTAGES</rc>
<description>Incorrect number of voltages supplied to set_voltage_attributes function</description>
<ffdc>VOLT_TARGET</ffdc>
@@ -310,18 +673,31 @@
<description>
When considering the frequencies in the MRW and the max supported
frequencies based on DIMM config, the indicated port's DIMM do not support
- the frequency of the majority of other ports' DIMM, so it will be deconfigured
+ the frequency of the majority of other ports' DIMM in the frequency domain.
+ DIMM on the offending port will be deconfigured so the IPL can continue.
+ All DIMM in the offending port's frequency domain will be marked as
+ Hardware Callout.
</description>
<ffdc>FREQ_TARGET</ffdc>
<ffdc>PORT_TARGET</ffdc>
<ffdc>FREQUENCY</ffdc>
- <callout>
+ <callout>
+ <procedure>MEMORY_PLUGGING_ERROR</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
<childTargets>
- <parent>PORT_TARGET</parent>
+ <parent>FREQ_TARGET</parent>
<childType>TARGET_TYPE_DIMM</childType>
</childTargets>
<priority>MEDIUM</priority>
</callout>
+ <deconfigure>
+ <childTargets>
+ <parent>PORT_TARGET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ </childTargets>
+ </deconfigure>
</hwpError>
<hwpError>
@@ -376,6 +752,7 @@
Settings are incorrect for received data.
This could be code problem (decoding) or bad data.
</description>
+ <ffdc>TARGET</ffdc>
<ffdc>VALUE</ffdc>
<ffdc>BYTE</ffdc>
<ffdc>FFDC_CODE</ffdc>
@@ -392,4 +769,516 @@
</deconfigure>
</hwpError>
+ <hwpError>
+ <rc>RC_MSS_ZERO_FREQ_OR_SIZE</rc>
+ <description>
+ An zero memory frequency was passed to calculate min cmd gap
+ </description>
+ <ffdc>FREQ</ffdc>
+ <ffdc>SIZE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_MEMDIAGS_INVALID_PATTERN_INDEX</rc>
+ <description>An invalid pattern index was passed to the pattern loader</description>
+ <ffdc>INDEX</ffdc>
+ <ffdc>MC_TYPE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_MCBIST_PROGRAM_TOO_BIG</rc>
+ <description>MCBIST program larger than currently supported size</description>
+ <ffdc>PROGRAM_LENGTH</ffdc>
+ <ffdc>TARGET</ffdc>
+ <ffdc>MC_TYPE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_MCBIST_INVALID_ADDRESS_PAIR_INDEX</rc>
+ <description>An invalid address pair index</description>
+ <ffdc>INDEX</ffdc>
+ <ffdc>MC_TYPE</ffdc>
+ <ffdc>TARGET</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_POWER_INTERCEPT_NOT_SET</rc>
+ <description>
+ The attribute ATTR_MSS_TOTAL_POWER_INTERCEPT was not set and equals 0
+ </description>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_POWER_SLOPE_NOT_SET</rc>
+ <description>
+ The attribute ATTR_MSS_TOTAL_POWER_INTERCEPT was not set and equals 0
+ </description>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_NO_DATABUS_UTILIZATION</rc>
+ <description>
+ There are 2 DIMMS on the port but both have 0 databus utilization
+ </description>
+ <ffdc>PORT_DATABUS_UTIL</ffdc>
+ <ffdc>DIMM_COUNT</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_CALC_POWER_CURVE_DIVIDE_BY_ZERO</rc>
+ <description>
+ Denominator equals 0
+ </description>
+ <ffdc>PORT_DATABUS_UTIL</ffdc>
+ <ffdc>UTIL_CONVERSION</ffdc>
+ <ffdc>IDLE_UTIL</ffdc>
+ <ffdc>RESULT</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_NO_PORT_POWER_LIMIT</rc>
+ <description>
+ Got 0 when calculating port power limit.
+ Either no dimms or attribute MEM_WATT_TARGET wasn't set
+ </description>
+ <ffdc>COUNT_DIMMS</ffdc>
+ <ffdc>PORT_POWER_LIMIT</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_NO_PORT_POWER</rc>
+ <description>
+ Got 0 when calculating port power limits using the DIMMs databus utilization
+ </description>
+ <ffdc>COUNT_DIMMS</ffdc>
+ <ffdc>MAX_UTILIZATION_DIMM_0</ffdc>
+ <ffdc>MAX_UTILIZATION_DIMM_1</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_M_DRAM_CLOCKS_EQUALS_ZERO</rc>
+ <description>
+ ATTR_MSS_MRW_MEM_M_DRAM_CLOCKS was not set and equals zero
+ </description>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_MAX_FREQ_ATTR_SIZE_CHANGED</rc>
+ <description>
+ Number of entries for MSS_MRW_MAX_FREQ attribute from VPD has changed without updating the code
+ Asserted because direct accesses to array
+ </description>
+ <ffdc>ACTUAL_SIZE</ffdc>
+ <ffdc>SUPPOSED_SIZE</ffdc>
+ <ffdc>PORT_TARGET</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_CALC_PORT_POWER_EXCEEDS_MAX</rc>
+ <description>
+ The calculated port power from equalizing throttles exceeds the maximum allowed power
+ </description>
+ <ffdc>CALCULATED_PORT_POWER</ffdc>
+ <ffdc>MAX_POWER_ALLOWED</ffdc>
+ <ffdc>PORT_POS</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <childTargets>
+ <parent>PORT_TARGET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ </childTargets>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <childTargets>
+ <parent>PORT_TARGET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ </childTargets>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_SPD_REV_ENCODING_LEVEL_NOT_SUPPORTED</rc>
+ <description>
+ SPD revision on byte 1 (bits 7~4) has a unsupported encoding level
+ that is greater than the largest decoded SPD decoder. There is
+ no backward compatible revision to fallback to. This could be
+ bad SPD or a programming error.
+ </description>
+ <ffdc>ENCODING_LEVEL</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_SPD_TIMING_FAIL</rc>
+ <description>
+ Timing SPD parameter failed to meet JEDEC SPD timing
+ bounds. FUNCTION_CODE ffdc field encodes which timing param.
+ </description>
+ <ffdc>FAILED_REVISION</ffdc>
+ <ffdc>FUNCTION_CODE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_TOO_MANY_DIMMS_ON_PORT</rc>
+ <description>There seem to be too many dimms on the port</description>
+ <ffdc>DIMM_COUNT</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <childTargets>
+ <parent>PORT_TARGET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ </childTargets>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_SLOT_UTIL_EXCEEDS_PORT</rc>
+ <description>
+ The memory throttle per slot (DIMM) exceeds the allowed throttle for the port
+ </description>
+ <ffdc>SLOT_UTIL</ffdc>
+ <ffdc>PORT_UTIL</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_OUTPUT_OVERFLOW_CALC_UTIL</rc>
+ <description>
+ Type of output variable is not large enough for the calculations
+ </description>
+ <ffdc>RESULT</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_POWER_THERMAL_DECODE_ERROR</rc>
+ <description>
+ There was no match or value found in decoding the power thermal attributes
+ </description>
+ <ffdc>DIMM_TARGET</ffdc>
+ <ffdc>ATTR</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_MRW_SAFEMODE_UTIL_THROTTLE_NOT_SUPPORTED</rc>
+ <description>
+ The MRW safemode utilization that is less than the minimum utilization supported. Check ATTR_MSS_MRW_SAFEMODE_DRAM_DATABUS_UTIL.
+ </description>
+ <ffdc>MRW_SAFEMODE_UTIL</ffdc>
+ <ffdc>MIN_UTIL_VALUE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_NO_POWER_THERMAL_ATTR_FOUND</rc>
+ <description>
+ There was no match or value found in decoding the power thermal attributes
+ </description>
+ <ffdc>GENERATED_KEY</ffdc>
+ <ffdc>FUNCTION</ffdc>
+ <ffdc>DIMM_TARGET</ffdc>
+ <ffdc>SIZE</ffdc>
+ <ffdc>DRAM_GEN</ffdc>
+ <ffdc>DIMM_TYPE</ffdc>
+ <ffdc>DRAM_WIDTH</ffdc>
+ <ffdc>DRAM_DENSITY</ffdc>
+ <ffdc>STACK_TYPE</ffdc>
+ <ffdc>MFGID</ffdc>
+ <ffdc>MODULE_HEIGHT</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_POWER_THERMAL_ENCODE_ERROR</rc>
+ <description>
+ There was no match or value found in encoding the power thermal attributes
+ </description>
+ <ffdc>DIMM_TARGET</ffdc>
+ <ffdc>ATTR</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_POWER_THERMAL_ATTR_VECTORS_INCORRECT</rc>
+ <description>
+ The attributes vectors size is incorrect for find_xxx functions
+ </description>
+ <ffdc>FUNCTION</ffdc>
+ <ffdc>INPUT_SIZE</ffdc>
+ <ffdc>EXPECTED_SIZE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_POWER_THERMAL_DIMM_INDEX_OUT_OF_BOUND</rc>
+ <description>
+ The dimm index is out of bound for the port
+ </description>
+ <ffdc>INPUT_SIZE</ffdc>
+ <ffdc>MAX_SIZE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_TOO_MANY_PRIMARY_RANKS_ON_DIMM</rc>
+ <description>
+ Too many primary ranks were seen on the dimm according
+ to the call to master_ranks_per_dimm</description>
+ <ffdc>RANK_COUNT</ffdc>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_TOO_MANY_PRIMARY_RANKS_ON_PORT</rc>
+ <description>
+ Too many primary ranks were seen on the port according
+ to the call to master_ranks_per_dimm</description>
+ <callout>
+ <target>PORT_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>PORT_TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_RANK_OUT_OF_RANGE</rc>
+ <description>
+ The rank provided to the rank::info constructor exceeded
+ the maximum rank for the MC
+ </description>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <ffdc>TARGET</ffdc>
+ <ffdc>RANK</ffdc>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_GALOIS_TO_SYMBOL</rc>
+ <description> An invalid galois code was found</description>
+ <ffdc>GALOIS</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_SYMBOL_FOR_GALOIS</rc>
+ <description> An invalid symbol was passed to symbol_to_galois</description>
+ <ffdc>SYMBOL</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_DQ_TO_SYMBOL</rc>
+ <description> An invalid DQ bit index received to map to Galois symbol</description>
+ <ffdc>DQ</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_SYMBOL_TO_DQ</rc>
+ <description> An invalid symbol received to map to DQ bit index</description>
+ <ffdc>SYMBOL</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_RANK_PASSED</rc>
+ <description> An invalid rank was passed to ecc::read function</description>
+ <ffdc>RANK</ffdc>
+ <ffdc>FUNCTION</ffdc>
+ <ffdc>TARGET</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_INDEX_PASSED</rc>
+ <description> An invalid index was passed to MODAL_SYMBOL_COUNT function</description>
+ <ffdc>INDEX</ffdc>
+ <ffdc>FUNCTION</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_DRAM_WIDTH</rc>
+ <description>
+ Code only supports x4 and x8 drams at this time
+ </description>
+ <ffdc>DRAM_WIDTH</ffdc>
+ <callout>
+ <procedure>MEMORY_PLUGGING_ERROR</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_PAGE_SIZE</rc>
+ <description>
+ Invalid page size
+ </description>
+ <ffdc>DRAM_WIDTH</ffdc>
+ <callout>
+ <procedure>MEMORY_PLUGGING_ERROR</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+
</hwpErrors>
diff --git a/src/import/hwpf/fapi2/include/error_info.H b/src/import/hwpf/fapi2/include/error_info.H
index c6717a3bb..e67e376e0 100644
--- a/src/import/hwpf/fapi2/include/error_info.H
+++ b/src/import/hwpf/fapi2/include/error_info.H
@@ -311,12 +311,14 @@ struct ErrorInfoCDG
/// @param[in] i_deconfigure True if Target should be deconfigured
/// @param[in] i_gard True if Target should be GARDed
/// @param[in] i_priority The priority of any callout
+ /// @param[in] i_gardType Type of GARD
///
ErrorInfoCDG(const Target<TARGET_TYPE_ALL>& i_target,
const bool i_callout,
const bool i_deconfigure,
const bool i_gard,
- const CalloutPriorities::CalloutPriority i_priority);
+ const CalloutPriorities::CalloutPriority i_priority,
+ const GardTypes::GardType i_gardType);
#ifdef FAPI_CUSTOM_MALLOC
///
@@ -348,6 +350,9 @@ struct ErrorInfoCDG
// GARD Information
bool iv_gard;
+
+ // GARD Type
+ GardTypes::GardType iv_gardType;
};
///
@@ -598,6 +603,7 @@ struct ErrorInfoEntryTargetCDG
uint8_t iv_deconfigure;
uint8_t iv_gard;
uint8_t iv_calloutPriority;
+ uint8_t iv_gardType;
void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
const void* const* i_object) const;
};
diff --git a/src/import/hwpf/fapi2/include/error_info_defs.H b/src/import/hwpf/fapi2/include/error_info_defs.H
index 3f8fc9de6..bed1add8e 100644
--- a/src/import/hwpf/fapi2/include/error_info_defs.H
+++ b/src/import/hwpf/fapi2/include/error_info_defs.H
@@ -278,6 +278,29 @@ enum CollectTrace
};
}
+///
+/// @enum gardType
+///
+/// This enumeration defines the possible gard types
+/// NOTE:This gardType is same as the gard types defined in HWAS
+/// so they should always be kept in sync.
+///
+namespace GardTypes
+{
+enum GardType
+{
+ GARD_NULL = 0x00,
+ GARD_User_Manual = 0xD2, //Manual Guard.
+ GARD_Unrecoverable = 0xE2, //TODO:RTC-76814
+ GARD_Fatal = 0xE3, //IPL Failures, and others.
+ GARD_Predictive = 0xE6, //Policy flag to disable.
+ GARD_Power = 0xE9, //Needed since EID is NOT passed in.
+ GARD_PHYP = 0xEA, //Needed since EID is NOT passed in.
+ GARD_Reconfig = 0xEB, //Force deconfig on reconfig loop
+ GARD_Void = 0xFF,
+};
+}
+
// @brief convert the processor relative sbe target instance into a fapi pos
//
// @param[in] i_targType - type of target from SBE FFDC buffer
diff --git a/src/import/hwpf/fapi2/include/fapi2_hw_access.H b/src/import/hwpf/fapi2/include/fapi2_hw_access.H
index 4c7142369..07bf77a08 100644
--- a/src/import/hwpf/fapi2/include/fapi2_hw_access.H
+++ b/src/import/hwpf/fapi2/include/fapi2_hw_access.H
@@ -91,6 +91,9 @@ inline OpModes getOpMode(void);
/// result in error.
/// i_mappings may contain an arbitrary amount of abstract/HW pairs, but the
/// function may return an error if too many mappings are specified.
+/// If the hardware supports a "broadcast" group, that must also be mapped
+/// explicitly via this function - platforms are not expected to map the
+/// broadcast group implicitly.
template< MulticastType M, typename V >
inline ReturnCode setMulticastGroupMap(const Target<TARGET_TYPE_PROC_CHIP, M, V>& i_chip,
const std::vector< MulticastGroupMapping >& i_mappings);
diff --git a/src/import/hwpf/fapi2/include/target_types.H b/src/import/hwpf/fapi2/include/target_types.H
index 16d0f9305..0eccb41a1 100644
--- a/src/import/hwpf/fapi2/include/target_types.H
+++ b/src/import/hwpf/fapi2/include/target_types.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -49,46 +49,48 @@ namespace fapi2
/// Target Kind
enum TargetType : uint64_t
{
- TARGET_TYPE_NONE = 0x0000000000000000, ///< No type
- TARGET_TYPE_SYSTEM = 0x0000000000000001, ///< System type
- TARGET_TYPE_DIMM = 0x0000000000000002, ///< DIMM type
- TARGET_TYPE_PROC_CHIP = 0x0000000000000004, ///< Processor type
- TARGET_TYPE_MEMBUF_CHIP = 0x0000000000000008, ///< Membuf type
- TARGET_TYPE_EX = 0x0000000000000010, ///< EX - 2x Core, L2, L3 - can be deconfigured
- TARGET_TYPE_MBA = 0x0000000000000020, ///< MBA type
- TARGET_TYPE_MCS = 0x0000000000000040, ///< MCS type
- TARGET_TYPE_XBUS = 0x0000000000000080, ///< XBUS type
- TARGET_TYPE_ABUS = 0x0000000000000100, ///< ABUS type
- TARGET_TYPE_L4 = 0x0000000000000200, ///< L4 type
- TARGET_TYPE_CORE = 0x0000000000000400, ///< Core
- TARGET_TYPE_EQ = 0x0000000000000800, ///< EQ - 4x core, 2x L2, 2x L3 - can be deconfigured
- TARGET_TYPE_MCA = 0x0000000000001000, ///< MCA type
- TARGET_TYPE_MCBIST = 0x0000000000002000, ///< MCBIST type
- TARGET_TYPE_MI = 0x0000000000004000, ///< MI Memory Interface (Cumulus)
- TARGET_TYPE_CAPP = 0x0000000000008000, ///< CAPP target
- TARGET_TYPE_DMI = 0x0000000000010000, ///< DMI type
- TARGET_TYPE_OBUS = 0x0000000000020000, ///< OBUS type
- TARGET_TYPE_OBUS_BRICK = 0x0000000000040000, ///< OBUS BRICK type
- TARGET_TYPE_SBE = 0x0000000000080000, ///< SBE type
- TARGET_TYPE_PPE = 0x0000000000100000, ///< PPE type
- TARGET_TYPE_PERV = 0x0000000000200000, ///< Pervasive type
- TARGET_TYPE_PEC = 0x0000000000400000, ///< PEC type
- TARGET_TYPE_PHB = 0x0000000000800000, ///< PHB type
- TARGET_TYPE_MC = 0x0000000001000000, ///< MC type
- TARGET_TYPE_OMI = 0x0000000002000000, ///< OMI type
- TARGET_TYPE_OMIC = 0x0000000004000000, ///< OMIC type
- TARGET_TYPE_MCC = 0x0000000008000000, ///< MCC type
- TARGET_TYPE_OCMB_CHIP = 0x0000000010000000, ///< OCMB type
- TARGET_TYPE_MEM_PORT = 0x0000000020000000, ///< MEM_PORT type
- TARGET_TYPE_NMMU = 0x0000000040000000, ///< NEST MMU type
- TARGET_TYPE_RESERVED = 0x0000000080000000, ///< Reserved for Cronus (Z)
- TARGET_TYPE_PAU = 0x0000000100000000, ///< PAU type
- TARGET_TYPE_IOHS = 0x0000000200000000, ///< IOHS type
- TARGET_TYPE_FC = 0x0000000400000000, ///< Fused Core type
- TARGET_TYPE_PMIC = 0x0000000800000000, ///< PMIC type
- TARGET_TYPE_MULTICAST = 0x8000000000000000, ///< MULTICAST type
- TARGET_TYPE_ALL = 0x7FFFFFFFFFFFFFFF, ///< Any/All types
- TARGET_TYPE_ALL_MC = 0xFFFFFFFFFFFFFFFF, ///< Any/All types + Multicast
+ TARGET_TYPE_NONE = 0x0000000000000000, ///< No type
+ TARGET_TYPE_SYSTEM = 0x0000000000000001, ///< System type
+ TARGET_TYPE_DIMM = 0x0000000000000002, ///< DIMM type
+ TARGET_TYPE_PROC_CHIP = 0x0000000000000004, ///< Processor type
+ TARGET_TYPE_MEMBUF_CHIP = 0x0000000000000008, ///< Membuf type
+ TARGET_TYPE_EX = 0x0000000000000010, ///< EX - 2x Core, L2, L3 - can be deconfigured
+ TARGET_TYPE_MBA = 0x0000000000000020, ///< MBA type
+ TARGET_TYPE_MCS = 0x0000000000000040, ///< MCS type
+ TARGET_TYPE_XBUS = 0x0000000000000080, ///< XBUS type
+ TARGET_TYPE_ABUS = 0x0000000000000100, ///< ABUS type
+ TARGET_TYPE_L4 = 0x0000000000000200, ///< L4 type
+ TARGET_TYPE_CORE = 0x0000000000000400, ///< Core
+ TARGET_TYPE_EQ = 0x0000000000000800, ///< EQ - 4x core, 2x L2, 2x L3 - can be deconfigured
+ TARGET_TYPE_MCA = 0x0000000000001000, ///< MCA type
+ TARGET_TYPE_MCBIST = 0x0000000000002000, ///< MCBIST type
+ TARGET_TYPE_MI = 0x0000000000004000, ///< MI Memory Interface (Cumulus)
+ TARGET_TYPE_CAPP = 0x0000000000008000, ///< CAPP target
+ TARGET_TYPE_DMI = 0x0000000000010000, ///< DMI type
+ TARGET_TYPE_OBUS = 0x0000000000020000, ///< OBUS type
+ TARGET_TYPE_OBUS_BRICK = 0x0000000000040000, ///< OBUS BRICK type
+ TARGET_TYPE_SBE = 0x0000000000080000, ///< SBE type
+ TARGET_TYPE_PPE = 0x0000000000100000, ///< PPE type
+ TARGET_TYPE_PERV = 0x0000000000200000, ///< Pervasive type
+ TARGET_TYPE_PEC = 0x0000000000400000, ///< PEC type
+ TARGET_TYPE_PHB = 0x0000000000800000, ///< PHB type
+ TARGET_TYPE_MC = 0x0000000001000000, ///< MC type
+ TARGET_TYPE_OMI = 0x0000000002000000, ///< OMI type
+ TARGET_TYPE_OMIC = 0x0000000004000000, ///< OMIC type
+ TARGET_TYPE_MCC = 0x0000000008000000, ///< MCC type
+ TARGET_TYPE_OCMB_CHIP = 0x0000000010000000, ///< OCMB type
+ TARGET_TYPE_MEM_PORT = 0x0000000020000000, ///< MEM_PORT type
+ TARGET_TYPE_NMMU = 0x0000000040000000, ///< NEST MMU type
+ TARGET_TYPE_RESERVED = 0x0000000080000000, ///< Reserved for Cronus (Z)
+ TARGET_TYPE_PAU = 0x0000000100000000, ///< PAU type
+ TARGET_TYPE_IOHS = 0x0000000200000000, ///< IOHS type
+ TARGET_TYPE_FC = 0x0000000400000000, ///< Fused Core type
+ TARGET_TYPE_PMIC = 0x0000000800000000, ///< PMIC type
+ TARGET_TYPE_PAUC = 0x0000001000000000, ///< PAUC type
+ TARGET_TYPE_GENERICI2CSLAVE = 0x0000002000000000, ///< GENERICI2CSLAVE type
+ TARGET_TYPE_MULTICAST = 0x8000000000000000, ///< MULTICAST type
+ TARGET_TYPE_ALL = 0x7FFFFFFFFFFFFFFF, ///< Any/All types
+ TARGET_TYPE_ALL_MC = 0xFFFFFFFFFFFFFFFF, ///< Any/All types + Multicast
// Compound target types
TARGET_TYPE_CHIPS = TARGET_TYPE_PROC_CHIP |
@@ -122,14 +124,16 @@ enum TargetType : uint64_t
TARGET_TYPE_NMMU |
TARGET_TYPE_PAU |
TARGET_TYPE_IOHS |
- TARGET_TYPE_FC,
+ TARGET_TYPE_FC |
+ TARGET_TYPE_PAUC,
TARGET_TYPE_MULTICASTABLE = TARGET_TYPE_CORE |
TARGET_TYPE_EQ |
- TARGET_TYPE_MCBIST |
- TARGET_TYPE_OBUS |
- TARGET_TYPE_PERV |
- TARGET_TYPE_PEC,
+ TARGET_TYPE_IOHS |
+ TARGET_TYPE_MC |
+ TARGET_TYPE_PAUC |
+ TARGET_TYPE_PEC |
+ TARGET_TYPE_PERV,
// Mappings to target types found in the error xml files
TARGET_TYPE_EX_CHIPLET = TARGET_TYPE_EX,
diff --git a/src/import/hwpf/fapi2/include/variable_buffer.H b/src/import/hwpf/fapi2/include/variable_buffer.H
index 0c1414486..5b31937d4 100644
--- a/src/import/hwpf/fapi2/include/variable_buffer.H
+++ b/src/import/hwpf/fapi2/include/variable_buffer.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -475,7 +475,7 @@ class variable_buffer
///
inline fapi2::ReturnCodes flipBit( bits_type SB, bits_type L = 1)
{
- ReturnCodes rc;
+ ReturnCodes rc = FAPI2_RC_SUCCESS;
// make sure we are within our container
if((SB + L) <= this->iv_perceived_bit_length)
diff --git a/src/import/hwpf/fapi2/src/error_info.C b/src/import/hwpf/fapi2/src/error_info.C
index a3ee3c8c6..861393eb5 100644
--- a/src/import/hwpf/fapi2/src/error_info.C
+++ b/src/import/hwpf/fapi2/src/error_info.C
@@ -118,18 +118,21 @@ ErrorInfoBusCallout::ErrorInfoBusCallout(
/// @param[in] i_deconfigure True if Target should be deconfigured
/// @param[in] i_gard True if Target should be GARDed
/// @param[in] i_priority The priority of any callout
+/// @param[in] i_gardType Type of GARD
///
ErrorInfoCDG::ErrorInfoCDG(
const Target<TARGET_TYPE_ALL>& i_target,
const bool i_callout,
const bool i_deconfigure,
const bool i_gard,
- const CalloutPriorities::CalloutPriority i_priority):
+ const CalloutPriorities::CalloutPriority i_priority,
+ const GardTypes::GardType i_gardType):
iv_target(i_target),
iv_callout(i_callout),
iv_calloutPriority(i_priority),
iv_deconfigure(i_deconfigure),
- iv_gard(i_gard)
+ iv_gard(i_gard),
+ iv_gardType(i_gardType)
{}
///
@@ -336,13 +339,15 @@ void ErrorInfoEntryTargetCDG::addErrorInfo(
iv_deconfigure,
iv_gard,
static_cast<CalloutPriorities::CalloutPriority>
- (iv_calloutPriority)
+ (iv_calloutPriority),
+ static_cast<GardTypes::GardType>(iv_gardType)
);
- FAPI_DBG("addErrorInfo: Adding target 0x%lx cdg (%d:%d:%d), pri: %d",
+ FAPI_INF("addErrorInfo: Adding target 0x%lx cdg (%d:%d:%d), pri: %d, gtyp: %d",
ei->iv_target.get(),
ei->iv_callout, ei->iv_deconfigure,
- ei->iv_gard, ei->iv_calloutPriority);
+ ei->iv_gard, ei->iv_calloutPriority,
+ ei->iv_gardType);
// Add the ErrorInfo
i_info->iv_CDGs.push_back(std::shared_ptr<ErrorInfoCDG>(ei));
diff --git a/src/import/hwpf/fapi2/tools/parseErrorInfo.pl b/src/import/hwpf/fapi2/tools/parseErrorInfo.pl
index c6044e5b8..75c3fe2fd 100755
--- a/src/import/hwpf/fapi2/tools/parseErrorInfo.pl
+++ b/src/import/hwpf/fapi2/tools/parseErrorInfo.pl
@@ -513,6 +513,7 @@ print CRFILE "#include <p9_quad_scom_addresses.H>\n";
print CRFILE "#include <p9_xbus_scom_addresses.H>\n";
print CRFILE "#include <cen_gen_scom_addresses.H>\n";
print CRFILE "#include <centaur_misc_constants.H>\n";
+print CRFILE "#include <explorer_scom_addresses.H>\n";
print CRFILE "namespace fapi2\n";
print CRFILE "{\n";
print CRFILE "void getAddressData(const fapi2::HwpFfdcId i_ffdcId,\n";
@@ -1266,6 +1267,10 @@ foreach my $argnum ( 0 .. $#ARGV )
# Add the Target to cdgTargetHash to be processed with any
# callout and deconfigure requests
$cdgTargetHash{ $gard->{target} }{gard} = 1;
+ if ( exists $gard->{gardType} )
+ {
+ $cdgTargetHash{ $gard->{target} }{gardType} = $gard->{gardType};
+ }
$elementsFound++;
}
if ( exists $gard->{childTargets} )
@@ -1323,6 +1328,7 @@ foreach my $argnum ( 0 .. $#ARGV )
my $priority = 'NONE';
my $deconf = 0;
my $gard = 0;
+ my $gardType = 'GARD_Fatal';
if ( exists $cdgTargetHash{$cdg}->{callout} )
{
@@ -1339,6 +1345,11 @@ foreach my $argnum ( 0 .. $#ARGV )
if ( exists $cdgTargetHash{$cdg}->{gard} )
{
$gard = 1;
+
+ if ( exists $cdgTargetHash{$cdg}->{gardType} )
+ {
+ $gardType = $cdgTargetHash{$cdg}->{gardType};
+ }
}
# Add the Target to the objectlist if it doesn't already exist
@@ -1355,6 +1366,8 @@ foreach my $argnum ( 0 .. $#ARGV )
$eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_gard = $gard; \\\n";
$eiEntryStr .=
" l_entries[$eiEntryCount].target_cdg.iv_calloutPriority = fapi2::CalloutPriorities::$priority; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].target_cdg.iv_gardType = fapi2::GardTypes::$gardType; \\\n";
$eiEntryCount++;
}
diff --git a/src/import/hwpf/fapi2/xml/attribute_info/chip_attributes.xml b/src/import/hwpf/fapi2/xml/attribute_info/chip_attributes.xml
index e131d9065..ed6f06f2e 100644
--- a/src/import/hwpf/fapi2/xml/attribute_info/chip_attributes.xml
+++ b/src/import/hwpf/fapi2/xml/attribute_info/chip_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2015,2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -42,7 +42,8 @@
NIMBUS = 0x5,
CUMULUS = 0x6,
AXONE = 0x7,
- EXPLORER = 0x8
+ EXPLORER = 0x8,
+ GEMINI = 0x9
</enum>
<platInit/>
<privileged/>
diff --git a/src/import/hwpf/fapi2/xml/attribute_info/common_attributes.xml b/src/import/hwpf/fapi2/xml/attribute_info/common_attributes.xml
index 4a97f47db..54488b163 100644
--- a/src/import/hwpf/fapi2/xml/attribute_info/common_attributes.xml
+++ b/src/import/hwpf/fapi2/xml/attribute_info/common_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2015,2019 -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2020 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -41,7 +41,8 @@
TARGET_TYPE_DIMM,
TARGET_TYPE_L4,TARGET_TYPE_MC,
TARGET_TYPE_MEM_PORT,
- TARGET_TYPE_PMIC
+ TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
1 if the target is functional, else 0. Set by the platform.
@@ -58,7 +59,8 @@
<id>ATTR_POS</id>
<targetType>
TARGET_TYPE_PROC_CHIP, TARGET_TYPE_MEMBUF_CHIP,
- TARGET_TYPE_DIMM, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_PMIC
+ TARGET_TYPE_DIMM, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
Physical position of chip/dimm within drawer
@@ -81,7 +83,8 @@
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV,
TARGET_TYPE_PEC, TARGET_TYPE_PHB, TARGET_TYPE_CAPP,
TARGET_TYPE_MBA, TARGET_TYPE_ABUS, TARGET_TYPE_L4, TARGET_TYPE_MC,
- TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
Logical position of target within a system. This is derived from the SMP location
@@ -112,7 +115,8 @@
TARGET_TYPE_MBA, TARGET_TYPE_ABUS, TARGET_TYPE_L4,
TARGET_TYPE_MEM_PORT,
TARGET_TYPE_DIMM,
- TARGET_TYPE_PMIC
+ TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
A target's position relative to its immediate parent target.
@@ -129,7 +133,8 @@
PROC - MC - MI - DMI
PROC - MC - MI - MCC - OMI
(OMIC - OMI is not supported)
- PROC - PMIC
+ OCMB - PMIC
+ OCMB - GENERICI2CSLAVE
MEMBUF - MBA - DIMM
MEMBUF - L4
OCMB - MEM_PORT - DIMM
diff --git a/src/import/hwpf/fapi2/xml/attribute_info/i2cslave_attributes.xml b/src/import/hwpf/fapi2/xml/attribute_info/i2cslave_attributes.xml
new file mode 100644
index 000000000..2f8356261
--- /dev/null
+++ b/src/import/hwpf/fapi2/xml/attribute_info/i2cslave_attributes.xml
@@ -0,0 +1,54 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/import/hwpf/fapi2/xml/attribute_info/i2cslave_attributes.xml $ -->
+<!-- -->
+<!-- OpenPOWER HostBoot Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2020 -->
+<!-- [+] International Business Machines Corp. -->
+<!-- -->
+<!-- -->
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); -->
+<!-- you may not use this file except in compliance with the License. -->
+<!-- You may obtain a copy of the License at -->
+<!-- -->
+<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
+<!-- -->
+<!-- Unless required by applicable law or agreed to in writing, software -->
+<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
+<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -->
+<!-- implied. See the License for the specific language governing -->
+<!-- permissions and limitations under the License. -->
+<!-- -->
+<!-- IBM_PROLOG_END_TAG -->
+<attributes>
+ <!-- ******************************************************************************** -->
+ <attribute>
+ <id>ATTR_I2C_DEV_TYPE</id>
+ <targetType>TARGET_TYPE_GENERICI2CSLAVE</targetType>
+ <description>
+ Device type of I2C slave device
+ </description>
+ <enum>
+ ADS7138_ADC,
+ PCA9554A_GPIO_EXPANDER
+ </enum>
+ <valueType>uint8</valueType>
+ <platInit/>
+ <default>0xFF</default><!-- Ensures platform explicitly puts a valid number in here -->
+ </attribute>
+ <!-- ******************************************************************************** -->
+ <attribute>
+ <id>ATTR_I2C_SUB_POS</id>
+ <targetType>TARGET_TYPE_GENERICI2CSLAVE</targetType>
+ <description>
+ Represents the ordinal position of this target compared to other peer
+ GENERICI2CSLAVE targets with the same ATTR_I2C_DEV_TYPE
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+ <default>0xFF</default><!-- Ensures platform explicitly puts a valid number in here -->
+ </attribute>
+ <!-- ******************************************************************************** -->
+</attributes>
diff --git a/src/import/hwpf/fapi2/xml/attribute_info/scratch_attributes.xml b/src/import/hwpf/fapi2/xml/attribute_info/scratch_attributes.xml
index 7af9c5474..5d5087b29 100644
--- a/src/import/hwpf/fapi2/xml/attribute_info/scratch_attributes.xml
+++ b/src/import/hwpf/fapi2/xml/attribute_info/scratch_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2015,2019 -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2020 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -40,7 +40,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
Scratch uint8_t attribute.
@@ -59,7 +60,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -79,7 +81,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -99,7 +102,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -119,7 +123,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -139,7 +144,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -159,7 +165,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -179,7 +186,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -200,7 +208,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -221,7 +230,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -242,7 +252,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -263,7 +274,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -284,7 +296,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -305,7 +318,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -326,7 +340,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -347,7 +362,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -369,7 +385,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -389,7 +406,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT,TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -409,7 +427,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -429,7 +448,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -449,7 +469,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -469,7 +490,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -489,7 +511,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -509,7 +532,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -530,7 +554,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -551,7 +576,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -572,7 +598,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -593,7 +620,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -614,7 +642,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -635,7 +664,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -656,7 +686,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -677,7 +708,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
@@ -699,7 +731,8 @@
TARGET_TYPE_CAPP, TARGET_TYPE_DMI, TARGET_TYPE_OBUS ,TARGET_TYPE_OBUS_BRICK ,
TARGET_TYPE_SBE, TARGET_TYPE_PPE, TARGET_TYPE_PERV, TARGET_TYPE_PEC,
TARGET_TYPE_PHB, TARGET_TYPE_MC, TARGET_TYPE_OMI, TARGET_TYPE_OMIC,
- TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC
+ TARGET_TYPE_MCC, TARGET_TYPE_OCMB_CHIP, TARGET_TYPE_MEM_PORT, TARGET_TYPE_PMIC,
+ TARGET_TYPE_GENERICI2CSLAVE
</targetType>
<description>
diff --git a/src/import/hwpf/fapi2/xml/attribute_info/system_attributes.xml b/src/import/hwpf/fapi2/xml/attribute_info/system_attributes.xml
index 94b8a15ea..ea374136c 100644
--- a/src/import/hwpf/fapi2/xml/attribute_info/system_attributes.xml
+++ b/src/import/hwpf/fapi2/xml/attribute_info/system_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2015,2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -91,7 +91,8 @@
<enum>
DECONFIGURE = 0x1,
BAD_DQ_BIT_SET = 0x2,
- RCD_PARITY_ERROR = 0x4
+ RCD_PARITY_ERROR = 0x4,
+ OCMB_FW_UPDATE = 0x8
</enum>
<writeable/>
</attribute>
diff --git a/src/import/libmctp b/src/import/libmctp
new file mode 160000
+Subproject 195a7c5e212f7fb50c850880519073ec9913360
diff --git a/src/import/tools/genMemVpd.pl b/src/import/tools/genMemVpd.pl
new file mode 100755
index 000000000..ce1ba352a
--- /dev/null
+++ b/src/import/tools/genMemVpd.pl
@@ -0,0 +1,1637 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/import/tools/genMemVpd.pl $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2016,2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+################################################################################
+# This script creates binary vpd files to be used to build the direct memory
+# eeprom image. There are two 'types', MR and MT. MR is for the 'memory rotator'
+# direct memory attributes and MT is for the 'memory terminator' direct memory
+# attributes.
+#
+# For MR and MT, there can be unique attribute values based on the
+# MCS position, the data rate of the system, and the rank count of the dimms
+# plugged in.
+#
+# There are 16 possible MCS positions (4 possible procs x 4 MCS
+# positions). MRW attribute ATTR_MEMVPD_POS, similiar to ATTR_FAPI_POS,
+# but will differ on multiple node systems, goes from 0 to 15. For a
+# 2 proc system, there will only be 8 MCSs, but up to 16 is supported by the
+# script for the general case.
+#
+# Each dimm can have rank count 0 (not there), 1, 2, or 4 ranks. Each
+# 'pair' combination (dimm0 rank count by dimm1 rank count), may need
+# unique vpd attribute values. There are 16 combinations of dimm0 rank count by
+# dimm1 rank count. For MR, the rank count is summarized into drop 1 for
+# those combinations with only one dimm (a 0 in the pair) and drop 2 for
+# those combinations with two dimms (does not have a 0 in the pair).
+#
+# There are 1024 (16 MCS positions x 4 freqencies x 16 dimm rank pairs)
+# configurations. In a particular system, some may not be supported and
+# many commbinations will use the same attribute values. It was 'decided'
+# to support up to 36 unique sets of values. For MR, they are stored in
+# vpd keywords J0..J9,JA..JZ and for MT in vpd keywords X0..X9,XA..XZ.
+# In practice, the eeprom will likely not be big enough for this many
+# keywords (each is 255 bytes), so the actual number will be less.
+#
+# The 'values' for the attributes in a vpd keyword are provided in files
+# with a '.vpd' extension and is in the format of an attribute override file,
+# but only has direct values (no enumerations) so that this script does not
+# have to be built to a particular build, like the attribute override tool.
+#
+# The vpd text file (.vpd extension) also has a header to specify the data
+# rate frequencies and rank count pairs supported by the file. The 'target'
+# line specifies the MCS positions supported. There can be multiple target
+# lines, similiar to an attribute override file, but only one header which
+# must preceed the first target line.
+#
+# example partial file: template_mr_00_freq_2400_2133_drop_2_1.vpd
+#
+# #DATA_RATE = 2400, 2133
+# #NUM_DROPS = 2, 1
+# target = k0:n0:s0:p9.mcs:p0,1:call
+# #MSS:description:MR Keyword Layout Version Number. Increases when attributes
+# # are added, removed, or redefined. Does not reset.
+# #MSS:mssUnit:num
+# ATTR_MSS_VPD_MR_0_VERSION_LAYOUT u8 0x00
+# #MSS:description:MR Keyword Data Version Number. Increases when data changes
+# # with the above layout version. Resets when layout version number
+# # increments.
+# #MSS:mssUnit:num
+# ATTR_MSS_VPD_MR_1_VERSION_DATA u8 0x00
+# #MSS:description:Hash Signature for the MT Keyword. The hash signature is
+# # 32bits for 256 bytes of data.
+# #MSS:mssUnit:hash
+# ATTR_MSS_VPD_MR_2_SIGNATURE_HASH u32 0x00000000
+# #MSS:description:Phase rotator delay value of command/address of A## in
+# # ticks. Ticks are 1/128 of one cycle of clock.
+# #MSS:mssUnit:tick
+# ATTR_MSS_VPD_MR_MC_PHASE_ROT_ADDR_A00[0] u8[2] 0x03
+# ATTR_MSS_VPD_MR_MC_PHASE_ROT_ADDR_A00[1] u8[2] 0x08
+#
+# example partial file: template_mt_00_dimm0dimm1_10_20_11_22.vpd
+#
+# #RANK_CONFIG = 0x10, 0x20, 0x11, 0x22
+# target = k0:n0:s0:p9.mcs:p0,1:call
+# #MSS:description:MT Keyword Layout Version Number. Increases when attributes
+# # are added, removed, or redefined. Does not reset.
+# #MSS:mssUnit:num
+# ATTR_MSS_VPD_MT_0_VERSION_LAYOUT u8 0x00
+# #MSS:description:MT Keyword Data Version Number. Increases when data changes
+# # with the above layout version. Resets when layout version number increments
+# #MSS:mssUnit:num
+# ATTR_MSS_VPD_MT_1_VERSION_DATA u8 0x00
+# #MSS:description:Hash Signature for the MT Keyword. The hash signature is
+# # 32bits for 256 bytes of data.
+# #MSS:mssUnit:encode
+# ATTR_MSS_VPD_MT_2_SIGNATURE_HASH u32 0x00000000
+# #MSS:description:Memory Controller side Read Vref setting. Dividing by 1000
+# # gives you percentage of Vdd
+# #MSS:enum:VDD40375 = 40375, ...
+# #MSS:mssUnit:percent of Vdd
+# ATTR_MSS_VPD_MT_VREF_MC_RD[0] u32[2] 0x000131AA
+# ATTR_MSS_VPD_MT_VREF_MC_RD[1] u32[2] 0x000131AA
+#
+# The script parses the ATTR_ lines for values to build the binary file,
+# but does not care about the specifics, other then data type (u8, u16,..)
+# and value.
+#
+# The script also builds a "mapping" from the configurations in the vpd
+# text files to the generated keyword files. The mapping is provided in
+# a binary MR and MT keyword file. At run time, the getVPD call is passed
+# a VPDInfo structure with frequency and dimm counts. The target's MEMVPD_POS,
+# frequency, and dimm rank count pair is used with the MR or MT keyword
+# mapping to select a vpd keyword (X0..XZ or J0..JZ), returning the values.
+#
+# More details...
+#
+# The format of the file name of the vpd text files is:
+# $SystemName_$KeyWordType_$DecoderVersion_$KeyWordDependentInfo.vpd
+# $KeyWordType is expected to be MR or MT (case insensitive)
+# The script picks the files with the highest $DecoderVersion and
+# replaces the output files.
+# $SystemName_$KeyWordType is a required parameter, called the 'prefix'.
+#
+# The input and output directories can be optionally specified as parameters.
+# The same directory can be used for both. The default is to use the
+# directory where the script is (./).
+#
+# The script also creates 3 information files.
+# $SystemName_$KeyWordType_mapping.csv has a text version of the mapping
+# keyword for human readable convenience.
+# $SystemName_$KeyWordType_trace.txt has a detailed execution trace for
+# debuging.
+# $SystemName_$KeyWordType_report.csv shows the mapped to keyword
+# for each of the 1024 possible configurations along with the vpd text
+# file it came from. There should not be any "duplicates", meaning there
+# was a overlap in the vpd text file specifications. Either the vpd text
+# files need to be fixed, or there is a bug in the script. The report
+# can also be used to debug if at run time the wrong vpd is thought to have
+# been returned.
+
+#TODO RTC:154580 support split eeproms
+
+use strict;
+
+################################################################################
+# Use of the following packages
+################################################################################
+
+use Getopt::Long;
+
+################################################################################
+# define constants and data type conventions
+################################################################################
+
+# a number is a hash with these members
+use constant NUM_VALUE => "num_value"; #numeric value
+use constant NUM_SIZE => "num_size"; #number of bytes
+
+# a fileInfo is a hash with these members
+use constant FILE_NAME => "file_name"; #name of the binary file to write
+use constant FILE_SIZE => "file_size"; #final size to create
+use constant FILE_DATA => "file_data"; #array to hold data until written
+use constant FILE_PTR => "file_ptr"; #current end of data pointer
+
+# a configuration is a hash with these members
+use constant CONF_MCS => "config_mcs_mask";
+use constant CONF_FREQ => "config_freq_mask";
+use constant CONF_RANK => "config_rank_mask";
+use constant CONF_KEY_CHAR => "config_keyword_character";
+use constant CONF_VPD_TEXT_FILE => "config_vpd_text_file";
+use constant CONF_BIN_FILE => "config_bin_file";
+
+# global constants
+use constant VPD_BIN_FILE_SIZE => 255; #all vpd binary key word file size
+use constant DQ_VPD_BIN_FILE_SIZE => 160; # DQ vpd binary key word file size
+use constant DQ_Q0_BIN_FILE_SIZE => 36; # DQ map file size (Q0)
+use constant CKE_VPD_BIN_DATA_SIZE => 16; # CKE "blob" size per MCS
+use constant CKE_BIN_FILE_SIZE => 136; # CKE full binary file size
+use constant VM_BIN_FILE_SIZE => 4; # VM (4-byte timestamp) binary file size
+
+################################################################################
+# configuration structures.
+# These masks (and the version) are written to the binary mapping vpd keyword
+# and used by the decode hwp.
+################################################################################
+use constant MAPPING_LAYOUT_VERSION => 1; #version of decode algorithm
+
+my %g_freqMask = ( #frequency index to mask
+ 1866 => 0x80, #1866
+ 2133 => 0x40, #2133
+ 2400 => 0x20, #2400
+ 2666 => 0x10
+); #2666
+use constant FREQ_ALL => 0xf0;
+
+my %g_rankMask = ( #dimm rank count pair to mask
+ 0x00 => 0x8000,
+ 0x01 => 0x4000, #dimm0 rank count=0 dimm1 rank count=1
+ 0x02 => 0x2000,
+ 0x04 => 0x1000,
+ 0x10 => 0x0800,
+ 0x11 => 0x0400,
+ 0x12 => 0x0200, #dimm0 rank count=1 dimm1 rank count=2
+ 0x14 => 0x0100,
+ 0x20 => 0x0080,
+ 0x21 => 0x0040,
+ 0x22 => 0x0020,
+ 0x24 => 0x0010,
+ 0x40 => 0x0008,
+ 0x41 => 0x0004,
+ 0x42 => 0x0002, #dimm0 rank count=4 dimm1 rank count=2
+ 0x44 => 0x0001
+);
+
+use constant RANK_DROP1 => 0x7888; #pairs with just one dimm
+use constant RANK_DROP2 => 0x0777; #pairs with two dimms
+
+my %g_mcsMask = ( #MCS MEMVPD_POS to mask
+ 0 => 0x8000, #proc=0 mcs position=0 memvpd_pos=0
+ 1 => 0x4000,
+ 2 => 0x2000,
+ 3 => 0x1000,
+ 4 => 0x0800, #proc=1 mcs position=0 memvpd_pos=4
+ 5 => 0x0400,
+ 6 => 0x0200,
+ 7 => 0x0100,
+ 8 => 0x0080, #proc=2 mcs position=0 memvpd_pos=8
+ 9 => 0x0040,
+ 10 => 0x0020,
+ 11 => 0x0010,
+ 12 => 0x0008, #proc=3 mcs position=0 memvpd_pos=12
+ 13 => 0x0004,
+ 14 => 0x0002,
+ 15 => 0x0001
+);
+my $g_mcs_added_to_cfg = 0;
+
+use constant MCS_ALL => 0xffff;
+use constant MAX_NUM_PROCS => 4;
+use constant MAX_POSITION => 3;
+
+################################################################################
+# Global data
+################################################################################
+my %g_configs = (); #hash of configuration hashes (a list of all configs)
+my $g_tarType = ""; #supported target types (MR, MT, Q#, CK)
+
+################################################################################
+# Main flow:
+# - get parameters and validate
+# - get list of vpd text files to process
+# - process each vpd text file
+# - construct mapping and keyword binary file
+# - construct report
+################################################################################
+
+sub main { }
+my $cfgPrefix = undef;
+my $cfgInputVpdTextDir = ".";
+my $cfgOutputVpdBinDir = ".";
+my $cfgHelp = 0;
+my $cfgVerbose = 0;
+my $cfgVersion = undef;
+my %ckeKeywordData; # CKE hash table (mcsMask -> hash ref with blob data for those masked mcs's)
+
+# Process command line parameters, issue help text if needed
+GetOptions(
+ "prefix=s" => \$cfgPrefix,
+ "version:s" => \$cfgVersion,
+ "input-vpd-text-dir:s" => \$cfgInputVpdTextDir,
+ "output-vpd-bin-dir:s" => \$cfgOutputVpdBinDir,
+ "help" => \$cfgHelp,
+ "verbose" => \$cfgVerbose
+);
+
+if ($cfgHelp)
+{
+ display_help();
+ exit(0);
+}
+
+# Check mandatory parameters
+if ( $cfgPrefix eq undef )
+{
+ print STDERR "\n==>prefix is a required parameter\n";
+}
+
+if ( $cfgPrefix eq undef )
+{
+ display_help();
+ exit(1);
+}
+
+# Validate vpd type
+{
+ ( my $system, $g_tarType ) = $cfgPrefix =~ m/^(.*?)_(\S+)/;
+ $g_tarType = uc $g_tarType;
+ if ( ( "MR" ne $g_tarType )
+ && ( "MT" ne $g_tarType )
+ && ( "CKE_MAP" ne $g_tarType )
+ && ( "DQ_MAP" ne $g_tarType )
+ && ( "VM" ne $g_tarType ) )
+ {
+ fatal( "error in --prefix parameter: $cfgPrefix" . " unsupported target type = $g_tarType" );
+ }
+}
+
+# Ensure directories consistently end with a /
+{
+ local $/ = '/'; #use temporary version of $/ for the chomp
+ chomp($cfgInputVpdTextDir);
+ $cfgInputVpdTextDir .= "/";
+
+ chomp($cfgOutputVpdBinDir);
+ $cfgOutputVpdBinDir .= "/";
+}
+
+# Show parameters
+{
+ verbose("Parameters=");
+ verbose(" Prefix = $cfgPrefix");
+ verbose(" Input vpd text file directory = $cfgInputVpdTextDir");
+ verbose(" Ouput vpd bin file directory = $cfgOutputVpdBinDir");
+}
+
+# skip vpd input files for VM type
+if ( "VM" ne $g_tarType )
+{
+ # Get the list of input vpd text files from the input directory
+ my @vpdTextFiles = getVpdTextFileList( $cfgInputVpdTextDir, $cfgPrefix );
+ {
+ my $numVpdTextFiles = scalar(@vpdTextFiles);
+ if ( $numVpdTextFiles == 0 )
+ {
+ fatal("No input vpd text files");
+ }
+ verbose("Input Vpd Text Files ($numVpdTextFiles)=");
+ foreach my $file (@vpdTextFiles)
+ {
+ verbose(" $file");
+ }
+ }
+
+ # Process vpd text files
+ foreach my $file (@vpdTextFiles)
+ {
+ if ( "CKE_MAP" eq $g_tarType )
+ {
+ processCkeVpdTextFile( $file, \%ckeKeywordData );
+ }
+ else
+ {
+ processVpdTextFile($file);
+ }
+ }
+}
+
+# Create VPD mapping binary file
+if ( "DQ_MAP" eq $g_tarType )
+{
+ createDqMappingFile();
+}
+elsif ( "CKE_MAP" eq $g_tarType )
+{
+ createCkBinaryFile( \%ckeKeywordData );
+ verbose("Output binary Vpd File=");
+ verbose( " $cfgPrefix" . "_CKE.bin" );
+
+ verbose("Support files created(1)=");
+ verbose( " $cfgPrefix" . "_trace.csv" );
+}
+elsif ( "VM" eq $g_tarType )
+{
+ unless (defined ($cfgVersion))
+ {
+ fatal( "Need to supply a version (0-F) for VM keyword" );
+ }
+ unless ($cfgVersion =~ m/^(0x)?[[:xdigit:]]$/)
+ {
+ fatal( "Invalid VM version ($cfgVersion), must be a single character (0-F)" );
+ }
+
+ createVMFile();
+ # createVMFile already reported created file
+ verbose("Support file created:");
+ verbose( " $cfgPrefix" . "_trace.txt" );
+}
+else
+{
+ createMappingFile();
+}
+
+# Create report
+if ( ("CKE_MAP" ne $g_tarType) &&
+ ("VM" ne $g_tarType) )
+{
+ createReport();
+
+ # Show what files have been created
+ {
+ my @keys = sort { $a <=> $b } keys %g_configs;
+ my $numBinVpdFiles = ( scalar @keys ) + 1;
+ verbose("Output binary Vpd Files ($numBinVpdFiles)=");
+ if ( $g_tarType eq "DQ_MAP" )
+ {
+ verbose( " $cfgPrefix" . "_Q0.bin" );
+ }
+ else
+ {
+ verbose( " $cfgPrefix" . "_" . $g_tarType . ".bin" );
+ }
+ foreach my $key (@keys)
+ {
+ my $ref_config = $g_configs{$key};
+ verbose(" $ref_config->{CONF_BIN_FILE}");
+ }
+ verbose("Support files created(3)=");
+ verbose( " $cfgPrefix" . "_map.csv" );
+ verbose( " $cfgPrefix" . "_report.csv" );
+ verbose( " $cfgPrefix" . "_trace.csv" );
+ }
+
+}
+
+verbose("Successful completion");
+exit(0);
+
+################################################################################
+# Get the list of input vpd text files from input directory
+#
+# file name format =
+# $SystemName_$KeyWordType_$DecoderVersion_$KeyWordDependentInfo.vpd
+# Return the files of the highest $DecoderVersion. This is the mem
+# team decode version of the vpd data, not the decode of the selection
+# criteria done by p9_get_mem_vpd_keyword.C
+################################################################################
+sub getVpdTextFileList
+{
+ my ( $inputVpdTextDir, $prefix ) = @_;
+
+ opendir( FILEDIR, $inputVpdTextDir )
+ || fatal("Couldn't open input vpd text file dir $inputVpdTextDir: $!");
+
+ # get ALL the vpd files to find the largest vpd decode version
+ my @allVpdTextFiles = grep {/^$prefix.*vpd/} readdir(FILEDIR);
+ my $largestDecode = "";
+ my $largestDecodeValue = -1;
+ foreach my $vpdFile (@allVpdTextFiles)
+ {
+ my ( $system, $tarType ) = $prefix =~ m/^(.*?)_(\S+)/;
+ my ( $decode, $rest ) = $vpdFile =~ m/^${prefix}_(.*?)_(\S+)/;
+
+ my $decodeValue = eval($decode);
+ if ( undef eq $decodeValue )
+ {
+ warning("decode $decode is not a number: $vpdFile SKIPPED");
+ }
+ if ( $decodeValue > $largestDecodeValue )
+ {
+ $largestDecodeValue = $decodeValue;
+ $largestDecode = $decode;
+ }
+ }
+
+ # only get files for the largest attribute decode version
+ rewinddir(FILEDIR);
+ my $prefixDecode = $prefix . "_" . $largestDecode;
+ my @vpdTextFiles = grep {/^$prefixDecode.*vpd/} readdir(FILEDIR);
+
+ closedir FILEDIR;
+
+ return @vpdTextFiles;
+}
+
+################################################################################
+# Process CKE vpd text file
+#
+# Parsing logic:
+# - keep reading lines as long as $stateKeepReading
+# - first target line marks the end of the header
+# - there can be multiple target lines
+################################################################################
+sub processCkeVpdTextFile
+{
+ my ( $vpdFile, $io_cke_entries ) = @_; # vpd text file, %hash ref to be appended (mscMask, hash ref with blob data)
+
+ trace( "Process cke vpd text file = " . $vpdFile );
+
+ my %config = (); # configuration for current section
+ my %fileInfo = (); # fileInfo for current section
+ my $mcsMask = 0; # MCS mask for this target
+ my $row = 0; # row count for error message
+
+ # Open vpd text file to parse
+ open( VPDINPUTTEXT, "<$cfgInputVpdTextDir$vpdFile" )
+ or fatal("open failed for $cfgInputVpdTextDir$vpdFile: $!");
+
+ # State variables to control parsing the vpd text file
+ my $stateKeepReading = 1; #keep reading lines until EOF
+ my $stateProcHeader = 1; #process header lines until first target line
+ my $stateProcSection = 0; #working on the attributes for a target line
+
+ while ($stateKeepReading)
+ {
+ # Actions to be be performed based on this line of text
+ my $actionTarget = 0;
+ my $actionAttr = 0;
+ my $actionWriteFile = 0;
+
+ my $line = <VPDINPUTTEXT>;
+ $line =~ s/(\r|\n)//g;
+
+ $row++;
+ if ($line) #determine all actions based on text line
+ {
+ if ( $line =~ /ATTR_/ ) #first since will be the most of these
+ {
+ if ($stateProcHeader)
+ {
+ fatal( "ATTR before header complete:\n" .
+ " $vpdFile\n" . " row $row:$line" );
+ }
+ $actionAttr = 1;
+ }
+ elsif ( $line =~ /target/ )
+ {
+ $stateProcHeader = 0;
+ $actionTarget = 1;
+
+ if ($stateProcSection)
+ {
+ $actionWriteFile = 1; #process previous section before next
+ }
+ }
+
+ # At this point, everything of interest has been processed.
+ # The only lines not processed above should be comment lines,
+ # which can be ignored (skipped).
+ }
+ else # determine actions based on hitting end of the text file
+ {
+ $stateKeepReading = 0;
+ if ($stateProcSection)
+ {
+ $actionWriteFile = 1;
+ }
+ }
+
+ # Process all actions needed based on text line
+
+ # needs to be before target in case there is a previous target to
+ # finish out before starting the next section.
+ if ($actionWriteFile)
+ {
+ $io_cke_entries->{$mcsMask} = {%fileInfo};
+ trace( "Adding CKE entry "
+ . sprintf( "0x%02X", $mcsMask )
+ . " -> name: "
+ . $fileInfo{FILE_NAME}
+ . ", size: "
+ . $fileInfo{FILE_SIZE}
+ . ", ptr: "
+ . $fileInfo{FILE_PTR} );
+ }
+ if ($actionTarget)
+ {
+ $mcsMask = procTarget( $line, $vpdFile, $row );
+ $stateProcSection = 1;
+ %fileInfo = newFileInfo( $vpdFile, CKE_VPD_BIN_DATA_SIZE );
+ }
+ if ($actionAttr)
+ {
+ my ( $attr, $type, $value ) = split( /\s+/, $line );
+ my %num = newNum( $value, $type );
+ trace(" $attr $type $value bytes=$num{NUM_SIZE}");
+ filePushNum( \%fileInfo, \%num );
+ }
+ }
+}
+
+################################################################################
+# Process vpd text file
+#
+# Parsing logic: (example of vpd text file in initial prologue)
+# - keep reading lines as long as $stateKeepReading
+# - process the header, which has the frequrency and rank pair/drop
+# configuration lines
+# - the first target line marks the end of the header.
+# - there can be multiple target lines
+################################################################################
+
+sub processVpdTextFile
+{
+ my ($vpdFile) = @_;
+
+ trace( "Process file = " . $vpdFile );
+
+ my %config = (); # configuration for current section
+ my %fileInfo = (); # fileInfo for current section
+ my $freqMask = 0; # frequenices (data rates) for this vpd file
+ my $rankMask = 0; # dimm rank count pairs for this vpd file
+ my $mcsMask = 0; # MCS mask for this target
+ my $row = 0; # row count for error message
+
+ # Open vpd text file to parse
+ open( VPDINPUTTEXT, "<$cfgInputVpdTextDir$vpdFile" )
+ or fatal("open failed for $cfgInputVpdTextDir$vpdFile: $!");
+
+ # State variables to control parsing the vpd text file
+ my $stateKeepReading = 1; #keep reading lines until EOF
+ my $stateProcHeader = 1; #process header lines until first target line
+ my $stateProcSection = 0; #working on the attributes for a target line
+ my $stateDataRateSet = 0; #Data Rate (frequency) as been found or default
+ my $stateRankConfigSet = 0; #Rank Count (drop) has been found
+
+ while ($stateKeepReading)
+ {
+ # Actions to be be performed based on this line of text
+ my $actionDataRate = 0;
+ my $actionRankConfig = 0;
+ my $actionDropConfig = 0;
+ my $actionTarget = 0;
+ my $actionAttr = 0;
+ my $actionWriteFile = 0;
+
+ my $line = <VPDINPUTTEXT>;
+ $line =~ s/(\r|\n)//g;
+
+ $row++;
+ if ($line) #determine all actions based on text line
+ {
+ if ( $line =~ /ATTR_/ ) #first since will be the most of these
+ {
+ if ($stateProcHeader)
+ {
+ fatal( "ATTR before header complete:\n" .
+ " $vpdFile\n" . " row $row:$line" );
+ }
+ $actionAttr = 1;
+ }
+ elsif ( $line =~ /DATA_RATE/ )
+ {
+ if ( !$stateProcHeader )
+ {
+ fatal( "DATA_RATE outside of header:\n" .
+ " $vpdFile\n" . " row $row:$line" );
+ }
+ $actionDataRate = 1;
+ }
+ elsif ( $line =~ /RANK_CONFIG/ )
+ {
+ if ( !$stateProcHeader )
+ {
+ fatal( "RANK_CONFIG outside of header:\n" .
+ " $vpdFile\n" . " row $row:$line" );
+ }
+ $actionRankConfig = 1;
+ }
+ elsif ( $line =~ /NUM_DROPS/ )
+ {
+ if ( !$stateProcHeader )
+ {
+ fatal( "NUM_DROPS outside of header:\n" .
+ " $vpdFile\n" . " row $row:$line" );
+ }
+ $actionDropConfig = 1;
+ }
+ elsif ( $line =~ /target/ )
+ {
+ # MT files can default to all frequencies if not specified
+ if ( ( !$stateDataRateSet )
+ && ( "MT" eq $g_tarType ) )
+ {
+ $freqMask = FREQ_ALL;
+ trace( "Freq Mask = 0x" .
+ sprintf( "%02X", $freqMask ) . " - DEFAULT VALUE" );
+ $stateDataRateSet = 1;
+ }
+ if ( ( $stateDataRateSet and $stateRankConfigSet )
+ || ( "DQ_MAP" eq $g_tarType ) )
+ {
+ $stateProcHeader = 0;
+ $actionTarget = 1;
+ }
+ else
+ {
+ fatal( "target before header is complete:\n" .
+ " $vpdFile\n" . " row $row:$line" );
+ }
+ if ($stateProcSection)
+ {
+ $actionWriteFile = 1; #process previous section before next
+ }
+ }
+
+ # At this point, everthing of interest has been processed.
+ # The only lines not processed above should be comment lines,
+ # which can be ignored (skipped).
+ }
+ else # determine actions based on hitting end of the text file
+ {
+ $stateKeepReading = 0;
+ if ($stateProcSection)
+ {
+ $actionWriteFile = 1;
+ }
+ }
+
+ # Process all actions needed based on text line
+ if ($actionDataRate)
+ {
+ $freqMask = procDataRate( $line, $vpdFile, $row );
+ $stateDataRateSet = 1;
+ }
+ if ($actionRankConfig)
+ {
+ $rankMask = procRankConfig( $line, $vpdFile, $row );
+ $stateRankConfigSet = 1;
+ }
+ if ($actionDropConfig)
+ {
+ $rankMask = procDropConfig( $line, $vpdFile, $row );
+ $stateRankConfigSet = 1;
+ }
+
+ # needs to be before target in case there is a previous target to
+ # finish out before starting the next section.
+ if ($actionWriteFile)
+ {
+ trace( "addConfiguration for " . $vpdFile . " -> " . $config{CONF_BIN_FILE} );
+ addConfiguration( \%config ); #capture final configuration
+ fileWrite( \%fileInfo );
+ }
+ if ($actionTarget)
+ {
+ $mcsMask = procTarget( $line, $vpdFile, $row );
+ $g_mcs_added_to_cfg |= $mcsMask;
+ $stateProcSection = 1;
+ %config = ();
+ %config = newConfiguration( $mcsMask, $freqMask, $rankMask, $vpdFile );
+ %fileInfo = ();
+ if ( "DQ_MAP" eq $g_tarType )
+ {
+ %fileInfo = newFileInfo( $config{CONF_BIN_FILE}, DQ_VPD_BIN_FILE_SIZE );
+ }
+ else
+ {
+ %fileInfo = newFileInfo( $config{CONF_BIN_FILE}, VPD_BIN_FILE_SIZE );
+ }
+
+ traceConfig( "createConfig:", \%config );
+ }
+ if ($actionAttr)
+ {
+ my ( $attr, $type, $value ) = split( /\s+/, $line );
+ my %num = newNum( $value, $type );
+ trace(" $attr $type $value bytes=$num{NUM_SIZE}");
+ filePushNum( \%fileInfo, \%num );
+ }
+ }
+}
+
+# process the DATA_RATE line
+#
+# Must be in the 'header' before the first 'target' line
+# # DATA_RATE = XXXX[,XXXX,XXXX,XXXX]
+# at least one frequency, up to 4 frequencies
+sub procDataRate
+{
+ my ( $line, $file, $row ) = @_;
+
+ my $freqMask = 0;
+
+ ( undef, my $rest ) = split( /\=/, $line );
+
+ my @freqs = split( /\,/, $rest );
+ foreach my $freqText (@freqs)
+ {
+ my $freq = eval($freqText);
+ if ( undef eq $freq )
+ {
+ fatal( "Invalid freq value = $freqText\n" .
+ " $file\n" . " row $row: $line" );
+ }
+
+ if ( undef eq $g_freqMask{$freq} )
+ {
+ fatal( "$freq not a supported value\n" .
+ " $file\n" . " row $row: $line" );
+ }
+ else
+ {
+ $freqMask |= $g_freqMask{$freq};
+ }
+ }
+ trace( "Freq Mask = 0x" . sprintf( "%02X", $freqMask ) );
+ return $freqMask;
+}
+
+# process the RANK_CONFIG line
+#
+# Must be in the 'header' before the first 'target' line
+# # RANK_CONFIG = 0xXX[,0xXX,...,0xXX]
+# X = 0,1,2, or 4
+# at least one dimm count pair, up to 16 pairs
+# the 0xXX format is for reability, its just a number (0x10 same as 16).
+# The first X is dimm0 rank count. Second is dimm1 rank count.
+sub procRankConfig
+{
+ my ( $line, $file, $row ) = @_;
+
+ my $rankMask = 0;
+
+ ( undef, my $rest ) = split( /\=/, $line );
+
+ my @ranks = split( /\,/, $rest );
+ foreach my $rankText (@ranks)
+ {
+ my $rank = eval($rankText);
+ if ( undef eq $rank )
+ {
+ fatal( "Invalid rank value = $rankText\n" .
+ " $file\n" . " row $row: $line" );
+ }
+ my $mask = $g_rankMask{$rank};
+ if ( undef == $mask )
+ {
+ fatal( "Unsupported rank configuration = 0x"
+ . sprintf( "%02X", $rank ) . "\n"
+ . " $file\n"
+ . " row $row: $line" );
+ }
+ $rankMask |= $mask;
+ }
+ trace( "Rank Config = 0x" . sprintf( "%04X", $rankMask ) );
+ return $rankMask;
+}
+
+# process the NUM_DROPS line
+#
+# Must be in the 'header' before the first 'target' line
+# # NUM_DROPS = X[,X]
+# X = 0 or 1
+sub procDropConfig
+{
+ my ( $line, $file, $row ) = @_;
+
+ my $dropMask = 0;
+
+ ( undef, my $rest ) = split( /\=/, $line );
+
+ my @drops = split( /\,/, $rest );
+ foreach my $dropText (@drops)
+ {
+ my $drop = eval($dropText);
+ if ( undef eq $drop )
+ {
+ fatal( "Invalid drop value = $dropText\n" .
+ " $file\n" . " row $row: $line" );
+ }
+ if ( 1 == $drop )
+ {
+ $dropMask |= RANK_DROP1;
+ }
+ elsif ( 2 == $drop )
+ {
+ $dropMask |= RANK_DROP2;
+ }
+ else
+ {
+ fatal( "Unsupported drop configuration = $drop\n" .
+ " $file\n" . " row $row: $line" );
+ }
+ }
+ trace( "Num Drops Config = 0x" . sprintf( "%04X", $dropMask ) );
+ return $dropMask;
+}
+
+# process the target line
+#
+# Concludes the 'header'.
+# target = k0:n0:s0:p9.mcs:pXXX:cXXX
+# XXX = all or a list of comma separated positions (0,1,2 or 3).
+sub procTarget
+{
+ my ( $line, $file, $row ) = @_;
+
+ my $mcsMask = 0;
+
+ ( undef, my $rest ) = split( /\=/, $line );
+ ( undef, undef, undef, my $p9mcs, my $proc, my $chip ) = split( /\:/, $line );
+
+ if ( ( "p9.mcs" ne $p9mcs )
+ && ( "pu.mcs" ne $p9mcs )
+ && ( "p9n.mcs" ne $p9mcs ) )
+ {
+ fatal( "Invalid target value = $p9mcs, "
+ . "p9.mcs, pu.mcs or p9n.mcs expected\n"
+ . " $file\n"
+ . " row $row: $line" );
+ }
+
+ my @plist = procPositions( $line, $file, $row, $proc, "p" );
+ my @clist = procPositions( $line, $file, $row, $chip, "c" );
+
+ #The MCS bit mask (g_mscMask) is based on the ATTR_MEMVPD_POS of the MCS.
+ #The MEMVPD_POS is the hash key to find the mask value in g_mscMask.
+ #Proc 0 MCS 0 is bit 0x8000. MEMVPD_POS = 0
+ #Proc 0 MCS 1 is bit 0x4000. MEMVPD_POS = 1, ... etc.
+ #MEMVPD_POS can be calculated by proc num * 4 + mcs position within the proc
+ foreach my $ppos (@plist)
+ {
+ foreach my $cpos (@clist)
+ {
+ my $memVpdPos = ( $ppos * 4 ) + $cpos;
+ $mcsMask |= $g_mcsMask{$memVpdPos};
+ }
+ }
+
+ trace( "Target Mask = 0x" . sprintf( "%04X", $mcsMask ) );
+ return $mcsMask;
+}
+
+# helper to get list of MemPos in mcsMask;
+sub convertMcsMaskToMemPosArray
+{
+ my ($mcsMask) = @_;
+
+ #printf("Target Mask = 0x".sprintf("%04X",$mcsMask)."\n");
+
+ my @aMemPos;
+
+ my %bitToPos = reverse %g_mcsMask;
+
+ foreach my $bitPos ( keys %bitToPos )
+ {
+ if ( ( $bitPos & $mcsMask ) == $bitPos )
+ {
+ push( @aMemPos, $bitToPos{$bitPos} );
+ }
+ }
+ return @aMemPos;
+}
+
+# helper to process positions
+# pXXX or cXXX
+# where XXX is "all" or a comma separated list of digits 0,1,2,3
+sub procPositions
+{
+ my ( $line, $file, $row, $position, $expected ) = @_;
+
+ my @list = ();
+
+ my $type = substr( $position, 0, 1 );
+ my $rest = substr( $position, 1 );
+ if ( $type ne $expected )
+ {
+ fatal( "Invalid target specification $type, $expected expected\n" .
+ " $file\n" . " row $row: $line" );
+ }
+
+ if ( "ALL" eq uc($rest) )
+ {
+ for ( my $i = 0; $i < MAX_NUM_PROCS; $i++ )
+ {
+ $list[$i] = $i;
+ }
+ }
+ else
+ {
+ my $i = 0;
+ my @positions = split( /\,/, $rest );
+ foreach my $posText (@positions)
+ {
+ my $pos = eval($posText);
+ if ( undef eq $pos )
+ {
+ fatal( "Invalid position value = $posText\n" .
+ " $file\n" . " row $row: $line" );
+ }
+ if ( MAX_POSITION < $pos )
+ {
+ fatal( "Position out of 0 to "
+ . MAX_POSITION
+ . " range = $posText\n"
+ . " $file\n"
+ . " row $row: $line" );
+ }
+ $list[ $i++ ] = $pos;
+ }
+ }
+ return @list;
+}
+
+################################################################################
+# File functions
+################################################################################
+
+# create a new file info
+sub newFileInfo
+{
+ my ( $fileName, $fileSize ) = @_;
+
+ my %fileInfo = ();
+ $fileInfo{FILE_NAME} = $fileName;
+ $fileInfo{FILE_SIZE} = $fileSize;
+ $fileInfo{FILE_PTR} = 0;
+
+ return %fileInfo;
+}
+
+# append "number" to the end of data to be written
+sub filePushNum
+{
+ my $ref_fileInfo = shift;
+ my $ref_num = shift;
+
+ my $newPtr = $ref_fileInfo->{FILE_PTR} + $ref_num->{NUM_SIZE};
+ if ( $newPtr > $ref_fileInfo->{FILE_SIZE} )
+ {
+ fatal( "bin file size exceeded\n"
+ . " file=$ref_fileInfo->{FILE_NAME}\n"
+ . " limit=$ref_fileInfo->{FILE_SIZE}" );
+ }
+ $ref_fileInfo->{FILE_PTR} = $newPtr;
+
+ my $fullValue = $ref_num->{NUM_VALUE};
+ my $byteValue = $fullValue % 256;
+ for ( my $i = 0; $i < $ref_num->{NUM_SIZE}; $i++ )
+ {
+ $newPtr--;
+ $ref_fileInfo->{FILE_DATA}[$newPtr] = $byteValue; #big endian order
+ $fullValue -= $byteValue;
+ $fullValue /= 256;
+ $byteValue = $fullValue % 256;
+ }
+}
+
+# Write the data to the file
+sub fileWrite
+{
+ my $ref_fileInfo = shift;
+
+ my $outBinFile = $cfgOutputVpdBinDir . $ref_fileInfo->{FILE_NAME};
+ open( BIN_FILE, ">:raw", $outBinFile )
+ || fatal("couldn't open $outBinFile: $!");
+
+ for ( my $i = 0; $i < $ref_fileInfo->{FILE_PTR}; $i++ )
+ {
+ print BIN_FILE pack( 'C', $ref_fileInfo->{FILE_DATA}[$i] );
+ }
+ for ( my $i = $ref_fileInfo->{FILE_PTR}; $i < $ref_fileInfo->{FILE_SIZE}; $i++ )
+ {
+ print BIN_FILE pack( 'C', 0 );
+ }
+ close(BIN_FILE);
+ my $pad = $ref_fileInfo->{FILE_SIZE} - $ref_fileInfo->{FILE_PTR};
+
+ trace( "create bin file = $ref_fileInfo->{FILE_NAME} " .
+ "data=$ref_fileInfo->{FILE_PTR} pad = $pad" );
+}
+
+################################################################################
+# Configuration helpers
+################################################################################
+
+# create a configuration
+my $static_keyChar = undef;
+
+sub newConfiguration
+{
+ my ( $mcsMask, $freqMask, $rankMask, $vpdFile ) = @_;
+
+ my %config = ();
+ $config{CONF_MCS} = $mcsMask;
+ $config{CONF_FREQ} = $freqMask;
+ $config{CONF_RANK} = $rankMask;
+ $config{CONF_VPD_TEXT_FILE} = $vpdFile;
+
+ if ( undef eq $static_keyChar )
+ {
+ $static_keyChar = '0';
+ if ( "DQ_MAP" eq $g_tarType )
+ {
+ # Q0 is reserved for mapping
+ $static_keyChar = '1';
+ }
+ }
+ elsif ( '9' eq $static_keyChar )
+ {
+ $static_keyChar = 'A';
+ }
+ elsif ( 'Z' eq $static_keyChar )
+ {
+ fatal("Ran out of keyword characters");
+ }
+ else
+ {
+ $static_keyChar++;
+ }
+ $config{CONF_KEY_CHAR} = ord($static_keyChar);
+
+ my $binFileName = "";
+ if ( "MR" eq uc $g_tarType )
+ {
+ $binFileName = $cfgPrefix . '_J' . $static_keyChar . ".bin";
+ }
+ elsif ( "MT" eq uc $g_tarType )
+ {
+ $binFileName = $cfgPrefix . '_X' . $static_keyChar . ".bin";
+ }
+ elsif ( "DQ_MAP" eq uc $g_tarType )
+ {
+ $binFileName = $cfgPrefix . '_Q' . $static_keyChar . ".bin";
+ }
+ else
+ {
+ fatal("unsupported target type = $g_tarType");
+ }
+ $config{CONF_BIN_FILE} = $binFileName;
+
+ return %config;
+}
+
+# capture a copy of a configuration and add to global list
+sub addConfiguration
+{
+ my $ref_config = shift;
+
+ my %config = %{$ref_config}; #create a copy
+
+ $g_configs{ $config{CONF_KEY_CHAR} } = \%config;
+}
+
+sub createCkBinaryFile
+{
+ my ($rCkeKeywordData) = @_;
+
+ # open file for binary version of mapping data
+ my %fileInfo = newFileInfo( $cfgPrefix . "_CK.bin", CKE_BIN_FILE_SIZE );
+ trace( "Create output binary file: " . $fileInfo{FILE_NAME} );
+
+ # start with header
+ # - version
+ # - number of entries
+ # - size of data entries (blob size)
+ # - reserved
+ my %num = newNum( MAPPING_LAYOUT_VERSION, "u8" );
+ filePushNum( \%fileInfo, \%num );
+ str2num( \%num, 8, "u8" );
+ filePushNum( \%fileInfo, \%num );
+
+ # bytes per data entry
+ str2num( \%num, 16, "u8" );
+ filePushNum( \%fileInfo, \%num );
+ str2num( \%num, 0, "u8" );
+ filePushNum( \%fileInfo, \%num );
+
+ for ( my $i = 0; $i < 8; $i++ ) # only room for 2 processors (4 pos per processor)
+ {
+ my $mcsMaskBit = $g_mcsMask{$i};
+ my $added_entry = 0;
+
+ foreach my $key ( keys %$rCkeKeywordData )
+ {
+ if ( ( $key & $mcsMaskBit ) == $mcsMaskBit )
+ {
+ my $newDataPtr = $fileInfo{FILE_PTR};
+ my $rblobData = $rCkeKeywordData->{$key};
+
+ trace("$i -- Found CKE entry:");
+ trace( "Key "
+ . sprintf( "0x%02X", $key )
+ . " -> name: "
+ . $rblobData->{FILE_NAME}
+ . ", size: "
+ . $rblobData->{FILE_SIZE}
+ . ", ptr: "
+ . $rblobData->{FILE_PTR} );
+
+ # add one glob of data for the section
+ for ( my $i = 0; $i < $rblobData->{FILE_PTR}; $i++ )
+ {
+ trace( "Adding " . sprintf( "0x%02X", $rblobData->{FILE_DATA}[$i] ) .
+ " to index " . $newDataPtr );
+ $fileInfo{FILE_DATA}[ $newDataPtr++ ] = $rblobData->{FILE_DATA}[$i];
+ }
+ trace( "File_ptr = " . $newDataPtr . ", previously " . $fileInfo{FILE_PTR} );
+ $fileInfo{FILE_PTR} = $newDataPtr;
+
+ str2num( \%num, 0, "u8" );
+ for ( my $i = $rblobData->{FILE_PTR}; $i < $rblobData->{FILE_SIZE}; $i++ )
+ {
+ filePushNum( \%fileInfo, \%num );
+ }
+ $added_entry = 1;
+ }
+ }
+ if ( $added_entry == 0 )
+ {
+ trace( "No entry found for $i " . sprintf( "(0x%02X)", $mcsMaskBit ) );
+
+ # add a blank entry for missing vpd
+ str2num( \%num, 0, "u8" );
+ for ( my $i = 0; $i < CKE_VPD_BIN_DATA_SIZE; $i++ )
+ {
+ filePushNum( \%fileInfo, \%num );
+ }
+ }
+ }
+ fileWrite( \%fileInfo );
+}
+
+sub createDqMappingFile
+{
+ # open file for human readable csv version of mapping data
+ ( my $system, my $tarType ) = $cfgPrefix =~ m/^(.*?)_(\S+)/;
+ my $outCsvFile = $cfgOutputVpdBinDir . $cfgPrefix . "_map.csv";
+ trace("createDqMappingFile: $outCsvFile");
+ open( CSV_FILE, ">$outCsvFile" )
+ || fatal("Couldn't open $outCsvFile: $!");
+ print CSV_FILE "MCS,KEYCHAR,VPDFILE\n";
+
+ # open file for binary version of mapping data
+ my %fileInfo = newFileInfo( $cfgPrefix . "_Q0.bin", DQ_Q0_BIN_FILE_SIZE );
+
+ # start with header
+ # - version
+ # - number of mapped entries
+ # - size of data entries
+ # - reserved
+ my %num = newNum( MAPPING_LAYOUT_VERSION, "u8" );
+ filePushNum( \%fileInfo, \%num );
+
+ # Number of map entries
+ # i.e. count the number of bits set in $g_mcs_added_to_cfg (uint16 = 0..15)
+ my $totalMappedEntries = grep $g_mcs_added_to_cfg & 1 << $_, 0 .. 15;
+ trace("Adding $totalMappedEntries entries into map file");
+ str2num( \%num, $totalMappedEntries, "u8" );
+ filePushNum( \%fileInfo, \%num );
+
+ # bytes per data entry
+ str2num( \%num, 0, "u8" );
+ filePushNum( \%fileInfo, \%num );
+ str2num( \%num, 0, "u8" );
+ filePushNum( \%fileInfo, \%num );
+
+ my @keys = sort { $a <=> $b } keys %g_configs;
+ foreach my $key (@keys)
+ {
+ my $ref_config = $g_configs{$key};
+ my $mcsMask = $ref_config->{CONF_MCS};
+ my $keyChar = $ref_config->{CONF_KEY_CHAR};
+ my $vpdFile = $ref_config->{CONF_VPD_TEXT_FILE};
+ my $binFile = $ref_config->{CONF_BIN_FILE};
+
+ print CSV_FILE "0x"
+ . sprintf( "%04X", $mcsMask ) . "," . "0x"
+ . sprintf( "%02X", $keyChar ) . ","
+ . chr($keyChar)
+ . "-$vpdFile\n";
+
+ my @memPositions = convertMcsMaskToMemPosArray($mcsMask);
+ foreach my $mempos (@memPositions)
+ {
+ print CSV_FILE $mempos . ", " . chr($keyChar) . "\n";
+
+ str2num( \%num, $mempos, "u8" );
+ filePushNum( \%fileInfo, \%num );
+ str2num( \%num, $keyChar, "u8" );
+ filePushNum( \%fileInfo, \%num );
+ }
+ }
+
+ fileWrite( \%fileInfo );
+ close(CSV_FILE);
+}
+
+# create mapping bin file and csv
+sub createMappingFile
+{
+ # open file for human readable csv version of mapping data
+ ( my $system, my $tarType ) = split( /\_/, $cfgPrefix );
+ my $outCsvFile = $cfgOutputVpdBinDir . $cfgPrefix . "_map.csv";
+ trace("createMappingFile: $outCsvFile");
+ open( CSV_FILE, ">$outCsvFile" )
+ || fatal("Couldn't open $outCsvFile: $!");
+ print CSV_FILE "MCS,RANK,FREQ,KEYCHAR,VPDFILE\n";
+
+ # open file for binary version of mapping data
+ my %fileInfo = newFileInfo( $cfgPrefix . "_" . uc($tarType) . ".bin", VPD_BIN_FILE_SIZE );
+
+ # start with header
+ # - version
+ # - number of entries
+ # - reserved
+ my %num = newNum( MAPPING_LAYOUT_VERSION, "u8" );
+ filePushNum( \%fileInfo, \%num );
+ str2num( \%num, scalar keys %g_configs, "u8" );
+ filePushNum( \%fileInfo, \%num );
+ str2num( \%num, 0, "u8" );
+ filePushNum( \%fileInfo, \%num );
+
+ my @keys = sort { $a <=> $b } keys %g_configs;
+ foreach my $key (@keys)
+ {
+ my $ref_config = $g_configs{$key};
+
+ my $mcsMask = $ref_config->{CONF_MCS};
+ my $freqMask = $ref_config->{CONF_FREQ};
+ my $rankMask = $ref_config->{CONF_RANK};
+ my $keyChar = $ref_config->{CONF_KEY_CHAR};
+ my $vpdFile = $ref_config->{CONF_VPD_TEXT_FILE};
+ my $binFile = $ref_config->{CONF_BIN_FILE};
+
+ print CSV_FILE "0x"
+ . sprintf( "%04X", $mcsMask ) . "," . "0x"
+ . sprintf( "%04X", $rankMask ) . "," . "0x"
+ . sprintf( "%02X", $freqMask ) . "," . "0x"
+ . sprintf( "%02X", $keyChar ) . ","
+ . chr($keyChar)
+ . "-$vpdFile\n";
+
+ #write bin config line
+ # - MCS mask
+ # - Rank mask
+ # - Frequency mask
+ # - keyword character
+ str2num( \%num, $mcsMask, "u16" );
+ filePushNum( \%fileInfo, \%num );
+ str2num( \%num, $rankMask, "u16" );
+ filePushNum( \%fileInfo, \%num );
+ str2num( \%num, $freqMask, "u8" );
+ filePushNum( \%fileInfo, \%num );
+ str2num( \%num, $keyChar, "u8" );
+ filePushNum( \%fileInfo, \%num );
+ }
+ fileWrite( \%fileInfo );
+ close(CSV_FILE);
+}
+
+# create a file and add a 4-byte binary timestamp
+sub createVMFile
+{
+ # open file for binary version of mapping data
+ my %fileInfo = newFileInfo( $cfgPrefix . "_VM.bin", VM_BIN_FILE_SIZE );
+ trace( "Create output binary file: " . $fileInfo{FILE_NAME} );
+
+ my $time = time;
+ $time = $time & 0xfffffff0;
+ $time = $time | hex($cfgVersion);
+ my %num = newNum( $time, "u32" );
+ filePushNum( \%fileInfo, \%num );
+ fileWrite( \%fileInfo );
+ verbose( "\nTranslated VM timestamp in file: ".
+ scalar localtime($num{NUM_VALUE}) );
+ verbose( "Created " . $cfgOutputVpdBinDir . $fileInfo{FILE_NAME} );
+}
+
+# create report
+sub createReport
+{
+ my $numUnf = 0;
+ my $numOK = 0;
+ my $numDup = 0;
+
+ # open file for report. Report can be used to validate mapping.
+ my $outCsvFile = $cfgOutputVpdBinDir . $cfgPrefix . "_report.csv";
+ open( CSV_FILE, ">$outCsvFile" )
+ || fatal("Couldn't open $outCsvFile: $!");
+ trace("createReport: $outCsvFile");
+ print CSV_FILE "CHK,MCS,FREQ,RANK,BINFILE,VPDFILE\n";
+
+ my $numMCS = scalar keys %g_mcsMask;
+ my $numFreq = scalar keys %g_freqMask;
+ my $numRank = scalar keys %g_rankMask;
+
+ for ( my $i = 0; $i < $numMCS; $i++ )
+ {
+ my @freqs = sort { $a <=> $b } keys %g_freqMask;
+ foreach my $freq (@freqs)
+ {
+ my @keys = sort { $a <=> $b } keys %g_rankMask;
+ foreach my $key (@keys)
+ {
+ my @configList = checkConfig( $g_mcsMask{$i}, $g_freqMask{$freq}, $g_rankMask{$key} );
+ my $numHits = scalar @configList;
+ my $status = "";
+ if ( 0 == $numHits )
+ {
+ $status = "UNF";
+ print CSV_FILE "$status,$i,$freq," . "0x" . sprintf( "%02X", $key ) . ',"",""' . "\n";
+ $numUnf++;
+ }
+ else
+ {
+ if ( 1 == $numHits )
+ {
+ $status = "OK ";
+ $numOK++;
+ }
+ else
+ {
+ $status = "DUP";
+ $numDup++;
+ }
+ for ( my $m = 0; $m < $numHits; $m++ )
+ {
+ print CSV_FILE "$status,$i,$freq," . "0x"
+ . sprintf( "%02X", $key ) . ","
+ . "$configList[$m]->{CONF_BIN_FILE},"
+ . "$configList[$m]->{CONF_VPD_TEXT_FILE}\n";
+ }
+ }
+ }
+ }
+ }
+ verbose( "Of the " . $numMCS * $numFreq * $numRank . " combinations:" );
+ verbose( " " . sprintf( "%4D", $numOK ) . " are mapped to vpd data" );
+ verbose( " " . sprintf( "%4D", $numUnf ) . " are undefined" );
+ verbose( " " . sprintf( "%4D", $numDup ) . " are duplicated (should be 0)" );
+ if ($numDup)
+ {
+ warning( "There are $numDup duplicate mappings, there should be none.\n"
+ . " Review $cfgPrefix"
+ . "_report.txt and correct the vpd files" );
+
+ }
+ close(CSV_FILE);
+}
+
+# Return list of configs that this configuration "hits"
+# Ideally, it is just one or none. A dup means there is a overlap problem
+# in the vpd text files
+sub checkConfig
+{
+ my ( $mcsMask, $freqMask, $rankMask ) = @_;
+
+ my @configList = ();
+ trace( "checkConfig:"
+ . " mcsMask="
+ . sprintf( "%04X", $mcsMask )
+ . " freqMask="
+ . sprintf( "%02X", $freqMask )
+ . " rankMask="
+ . sprintf( "%04X", $rankMask ) );
+
+ my @keys = sort { $a <=> $b } keys %g_configs;
+ foreach my $key (@keys)
+ {
+ my $ref_config = $g_configs{$key};
+ my $status = "UNF";
+
+ my $mcsHit = $mcsMask & $ref_config->{CONF_MCS};
+ my $freqHit = $freqMask & $ref_config->{CONF_FREQ};
+ my $rankHit = $rankMask & $ref_config->{CONF_RANK};
+ if ( ( $mcsHit && $freqHit && $rankHit )
+ || ( ( "DQ_MAP" eq $g_tarType ) && $mcsHit ) )
+ {
+ push @configList, $ref_config;
+ $status = "HIT";
+ }
+ trace( " $status==> " . $ref_config->{CONF_BIN_FILE} );
+ trace( " mscHit=0x" . sprintf( "%04X", $mcsHit ) .
+ " 0x" . sprintf( "%04X", $ref_config->{CONF_MCS} ) );
+ trace( " freqHit=" . sprintf( "%02X", $freqHit ) .
+ " 0x" . sprintf( "%02X", $ref_config->{CONF_FREQ} ) );
+ trace( " rankHit=" . sprintf( "%04X", $rankHit ) .
+ " 0x" . sprintf( "%04X", $ref_config->{CONF_RANK} ) );
+ }
+
+ return @configList;
+}
+
+################################################################################
+# Number helpers
+################################################################################
+
+# create a "number" hash
+sub newNum
+{
+ my ( $value, $type ) = @_;
+
+ my ($sign, $decSize) = $type =~ /(u|s)(\d+)/;
+ my $byteSize = $decSize / 8;
+
+ my %number = ();
+ $number{NUM_VALUE} = str2value($value);
+ $number{NUM_SIZE} = $byteSize;
+
+ return %number;
+}
+
+# update a "number" hash
+sub str2num
+{
+ my $ref_num = shift;
+ my $value = shift;
+ my $type = shift;
+
+ my ($sign, $decSize) = $type =~ /(u|s)(\d+)/;
+ my $byteSize = $decSize / 8;
+
+ $ref_num->{NUM_VALUE} = str2value($value);
+ $ref_num->{NUM_SIZE} = $byteSize;
+}
+
+# Convert a string into a numeric value scalar
+sub str2value
+{
+ my ($text) = @_;
+
+ my $value = eval($text);
+ if ( $value eq undef )
+ {
+ fatal("str2value: $text is not a number");
+ }
+
+ return $value;
+}
+
+################################################################################
+# trace and related helpers
+################################################################################
+
+# verbose to STDOUT and trace
+sub verbose
+{
+ my ($text) = @_;
+
+ if ($cfgVerbose)
+ {
+ print STDOUT $text . "\n";
+ }
+ trace($text);
+}
+
+# trace
+my $static_traceInit = 0;
+
+sub trace
+{
+ my ($text) = @_;
+
+ if ( 0 == $static_traceInit )
+ {
+ my $outTextFile = $cfgOutputVpdBinDir . $cfgPrefix . "_trace.txt";
+ open( TRACE_FILE, ">$outTextFile" )
+ || fatal("couldn't open $outTextFile: $!");
+ $static_traceInit = 1;
+ }
+ print TRACE_FILE $text . "\n";
+}
+
+# add a configuration to the trace
+sub traceConfig
+{
+ my ( $tag, $ref_config ) = @_;
+
+ my $mcsMask = $ref_config->{CONF_MCS};
+ my $freqMask = $ref_config->{CONF_FREQ};
+ my $rankMask = $ref_config->{CONF_RANK};
+ my $keyChar = chr( $ref_config->{CONF_KEY_CHAR} );
+ my $vpdFile = $ref_config->{CONF_VPD_TEXT_FILE};
+ my $binFile = $ref_config->{CONF_BIN_FILE};
+
+ trace("$tag $binFile");
+ trace( " key=$keyChar mcsMask="
+ . sprintf( "%04X", $mcsMask )
+ . " freqMask="
+ . sprintf( "%02X", $freqMask )
+ . " rankMask="
+ . sprintf( "%04X", $rankMask ) );
+ trace(" from= $vpdFile");
+}
+
+#warning error
+sub warning
+{
+ my ($text) = @_;
+
+ trace("[WARNING!] $text");
+ print STDERR "[WARNING!] $text\n";
+}
+
+#fatal error
+sub fatal
+{
+ my ($text) = @_;
+
+ trace("[FATAL!] $text");
+ print STDERR "[FATAL!] $text\n";
+
+ exit(1);
+}
+
+# Display the parameters
+sub display_help
+{
+ use File::Basename;
+ my $scriptname = basename($0);
+
+ print STDERR "
+usage:
+ $scriptname --help
+ $scriptname --prefix <system_kw>
+ [--version <single hex character>]
+ [--input-vpd-text-dir=./] [--output-vpd-bin-dir=./]
+ [--verbose]
+ --prefix
+ Prefix of vpd input files to process (template_MR or template_MT)
+ Available kw = MR, MT, CKE_MAP, DQ_MAP and VM
+ --version
+ Hex character used in the last nibble of the VM keyword
+ --input-vpd-text-dir
+ Optional path to directory with input vpd files.
+ Defaults to current directory (./)
+ --output-vpd-bin-dir
+ Optional path to directory for output binary and support files.
+ Defaults to current directory (./)
+ --verbose
+ Optional additional execution information.
+ Defaults to not verbose.
+\n";
+}
diff --git a/src/include/arch/memorymap.H b/src/include/arch/memorymap.H
index 7b75f6363..1ea479d8c 100644
--- a/src/include/arch/memorymap.H
+++ b/src/include/arch/memorymap.H
@@ -39,8 +39,13 @@ constexpr uint64_t MMIO_OFFSET_PER_CHIP = (4*TERABYTE); //0x40000000000
constexpr uint64_t MMIO_OFFSET_PER_GROUP = (32*TERABYTE); //0x200000000000
constexpr uint64_t MMIO_BASE = 0x6000000000000;
+
/**
* @brief Compute MMIO value for a given chip and base value
+ * @param[in] i_baseAddr group0-chip0 address
+ * @param[in] i_group Fabric Group ID to compute address for
+ * @param[in] i_chip Fabric Chip ID to compute address for
+ * @return Fully qualified memory address
*/
inline uint64_t computeMemoryMapOffset( uint64_t i_baseAddr,
uint8_t i_group,
@@ -52,6 +57,26 @@ inline uint64_t computeMemoryMapOffset( uint64_t i_baseAddr,
};
/**
+ * @brief Determine fabric id from a MMIO address
+ * @param[in] i_addr position-specific memory address
+ * @param[out] i_group Fabric Group ID to compute address for
+ * @param[out] i_chip Fabric Chip ID to compute address for
+ */
+inline void getFabricIdFromAddr( uint64_t i_addr,
+ uint8_t& o_group,
+ uint8_t& o_chip )
+{
+ // chop off any high-order offset
+ uint64_t l_addr = i_addr % MMIO_BASE;
+ // use integer math to get the group id
+ o_group = l_addr / MMIO_OFFSET_PER_GROUP;
+ // chop off the group
+ l_addr = l_addr % MMIO_OFFSET_PER_GROUP;
+ // use integer math to get the chip id
+ o_chip = l_addr % MMIO_OFFSET_PER_CHIP;
+};
+
+/**
* @brief A few default values that will need to be known
* by low-level code
*/
diff --git a/src/include/arch/ppc.H b/src/include/arch/ppc.H
index 4d1762db7..b9b8df7ee 100644
--- a/src/include/arch/ppc.H
+++ b/src/include/arch/ppc.H
@@ -417,6 +417,24 @@ inline void writeScratchReg(uint64_t _scratch_addr, uint64_t _data)
}
+#ifdef __HOSTBOOT_RUNTIME
+
+/** @brief getDarn - deliver a random number instruction
+ * Returns 64 bits of random data, requires random number generator
+ * configured appropriately + locked down, only available at runtime.
+ */
+ALWAYS_INLINE
+inline uint64_t getDarn()
+{
+ register uint64_t rt = 0;
+ asm volatile(".long 0x7C0105E6 | "
+ "((%0 & 0x1F) << 21)" :
+ "=r" (rt));
+ return rt;
+}
+
+#endif
+
/** @brief This is a special assembler instruction that is a nop on
* regular hardware, but has special meaning to Simics. Code that
* executes this instruction in Simics will cause a "hap," a
@@ -457,10 +475,12 @@ inline void MAGIC_INSTRUCTION(int _n)
{
register int n = _n;
isync();
- asm volatile("rlwimi %0,%0,0,%1,%2" \
- :: "i" (((n) >> 8) & 0x1f), \
- "i" (((n) >> 4) & 0xf), \
- "i" ((((n) >> 0) & 0xf) | 16)); \
+ long register r3 asm("r3");
+ asm volatile("rlwimi %1,%1,0,%2,%3" \
+ : "=r"(r3) : "i" (((n) >> 8) & 0x1f), \
+ "i" (((n) >> 4) & 0xf), \
+ "i" ((((n) >> 0) & 0xf) | 16), \
+ "r"(r3)); \
}
// Simics components that we can raise log levels for
@@ -503,6 +523,7 @@ enum
MAGIC_FAKEPAYLOAD_ENTER = 7010, // Entered the fake payload.
MAGIC_SIMICS_CHECK = 7011, // Check if system is running on simics
MAGIC_LOAD_PAYLOAD = 7012, // load payload from flash
+ MAGIC_HB_DUMP = 7014, // Create a hostboot dump
MAGIC_BREAK_ON_ERROR = 7018, // Breakpoint in error cases if
// env var HB_BREAK_ON_ERROR
MAGIC_GET_SBE_TRACES = 7019, // Collect SBE traces
@@ -512,6 +533,7 @@ enum
MAGIC_TOGGLE_OUTPUT = 7023, // Enable simic log capture
MAGIC_CONTINUOUS_TRACE = 7055, // extract mixed trace buffer
+ MAGIC_GCOV_MODULE_UNLOAD = 7056, // extract gcov info
// 8000-8999 are defined by the Simics CEC team
diff --git a/src/include/bootloader/bootloader_trace.H b/src/include/bootloader/bootloader_trace.H
index 69c708ad0..0c82a936e 100644
--- a/src/include/bootloader/bootloader_trace.H
+++ b/src/include/bootloader/bootloader_trace.H
@@ -166,9 +166,9 @@ enum BootloaderTraces
/** Bootloader main removeECC returned error */
BTLDR_TRC_MAIN_REMOVEECC_FAIL = 0xF1,
-
+
/** Bootloader PNOR Access readTOC checkForNullBuffer null buffer */
- BTLDR_TRC_PA_READTOC_CHKNULLBUFFER_NULL = 0xF2,
+ BTLDR_TRC_PA_READTOC_CHKNULLBUFFER_NULL = 0xF2, // deprecated - do not use
/** Bootloader PNOR Access readTOC performHdrChecksum checksum error */
BTLDR_TRC_PA_READTOC_HDRCHECKSUM_ERR = 0xF3,
diff --git a/src/include/bootloader/hbblreasoncodes.H b/src/include/bootloader/hbblreasoncodes.H
index 7ea0f189f..0f2bf568a 100644
--- a/src/include/bootloader/hbblreasoncodes.H
+++ b/src/include/bootloader/hbblreasoncodes.H
@@ -50,6 +50,7 @@ namespace Bootloader
MOD_BOOTLOADER_VERIFY = 0x05, /**< bootloader.C : verifyContainer */
MOD_BOOTLOADER_ASSERT = 0x06, /**< bootloader.H assert */
MOD_BOOTLOADER_VERIFY_COMP_ID = 0x07, /**< bootloader.C : verifyComponentId */
+ MOD_PNORACC_FINDTOC = 0x08, /**< bl_pnorAccess.C : find TOC */
};
/**
@@ -66,15 +67,25 @@ namespace Bootloader
RC_STD_EX_W_DSISR = HBBL_COMP_ID | 0x04, /**< Std Except w/ DSISR */
RC_STD_EX_W_SRR1 = HBBL_COMP_ID | 0x05, /**< Std Except w/ SRR1 */
RC_HYPE_EXCEPTION = HBBL_COMP_ID | 0x06, /**< Hypervisor Exception */
+ //termination_rc
RC_REMOVE_ECC_FAIL = HBBL_COMP_ID | 0x07, /**< Remove ECC Failed */
RC_CHK_NULL_BUFFER = HBBL_COMP_ID | 0x08, /**< Check for NULL Buffr */
+ //termination_rc
RC_HDR_CHECKSUM_ERR = HBBL_COMP_ID | 0x09, /**< Hdr Checksum Error */
+ //termination_rc
RC_CHECK_HEADER_ERR = HBBL_COMP_ID | 0x0A, /**< Check Header Error */
+ //termination_rc
RC_PARSE_ENTRIES_ERR = HBBL_COMP_ID | 0x0B, /**< Parse Entries Error */
+ //termination_rc
RC_NO_HBB_IN_TOC = HBBL_COMP_ID | 0x0C, /**< No HBB Sect in TOC */
RC_PNOR_SECID_OUT_OF_RANGE = HBBL_COMP_ID | 0x0D, /**< Requested PNOR SecId DNE in string array */
RC_PNOR_NULLPTR = HBBL_COMP_ID | 0x0E, /**< Requested address to compare is a nullptr */
+ //termination_rc
RC_BAD_WORK_LEN = HBBL_COMP_ID | 0x0F, /**< Working length too large */
+ //termination_rc
+ RC_LPC_ERR = HBBL_COMP_ID | 0x10, /**< LPC Error */
+ //termination_rc
+ RC_TOC_NOT_FOUND_ERR = HBBL_COMP_ID | 0x11, /**< TOC Not Found Error */
};
}; // end Bootloader
diff --git a/src/include/iterator b/src/include/iterator
index 396e1b594..dbd712b9e 100644
--- a/src/include/iterator
+++ b/src/include/iterator
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -62,11 +64,11 @@ struct iterator_traits<T*>
* @param[in] i - The iterator to advance.
* @param[in] n - The distance to advance the iterator.
*
- * This function is equivalent to calling (++i) n times.
+ * This function is equivalent to calling (++i) n times.
*
- * If the iterator supports random access then this function will be
+ * If the iterator supports random access then this function will be
* implemented in linear time with respect to n.
- *
+ *
*/
template <typename InputIterator, typename Distance>
void advance(InputIterator& i, Distance n)
@@ -90,11 +92,11 @@ void advance(InputIterator& i, Distance n)
* access iterators.
*/
template <typename InputIterator>
-typename iterator_traits<InputIterator>::difference_type
+typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last)
{
return Util::__Util_Iterator_Impl::distance<
- InputIterator,
+ InputIterator,
typename iterator_traits<InputIterator>::difference_type>
(first, last);
}
@@ -129,7 +131,7 @@ class back_insert_iterator
/** Dereference operator.
*
* This is used to make the standard pattern '*i = x' work on
- * an iterator. Since we need to 'push_back' into the
+ * an iterator. Since we need to 'push_back' into the
* container we don't actually return anything except ourself,
* which allows the operator= to be called.
*/
@@ -168,16 +170,44 @@ class back_insert_iterator
* copy(v.rbegin(), v.rend(), back_inserter(v2));
*
* @param[in] s - Sequence to create an iterator for.
- *
+ *
* @return The back_insert_iterator.
*/
template <typename BackInsertionSequence>
-back_insert_iterator<BackInsertionSequence>
+back_insert_iterator<BackInsertionSequence>
back_inserter(BackInsertionSequence& s)
{
return back_insert_iterator<BackInsertionSequence>(s);
}
+/**
+ * begin(array)
+ * Returns pointer to beginning of array
+ *
+ * Example:
+ * int c_array[] = {0, 1, 2};
+ * vector<int> l_cpp_array (begin(c_array), end(c_array));
+ */
+template <typename T, size_t size>
+T* begin(T (&c_array)[size])
+{
+ return &c_array[0];
+}
+
+/**
+ * end(array)
+ * Returns pointer to end of array (i.e. the element after the last element)
+ *
+ * Example:
+ * int c_array[] = {0, 1, 2};
+ * vector<int> l_cpp_array (begin(c_array), end(c_array));
+ */
+template <typename T, size_t size>
+T* end(T (&c_array)[size])
+{
+ return &c_array[0] + size;
+}
+
}; // namespace std.
#endif
diff --git a/src/include/kernel/ptmgr.H b/src/include/kernel/ptmgr.H
index d6e6be151..da0a96aed 100644
--- a/src/include/kernel/ptmgr.H
+++ b/src/include/kernel/ptmgr.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2015 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -28,7 +28,6 @@
#include <stdint.h>
#include <util/lockfree/stack.H>
#include <kernel/vmmmgr.H>
-#include <config.h>
/**
* @class PageTableManager
diff --git a/src/include/kernel/terminate.H b/src/include/kernel/terminate.H
index b80331495..ce634e5c8 100644
--- a/src/include/kernel/terminate.H
+++ b/src/include/kernel/terminate.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -87,4 +87,15 @@ void termModifySRC(uint8_t i_moduleID,
*/
void termSetHbDump(void);
+/** @fn termSetIstep
+ *
+ * @brief Set istep into progress code word of the SRC.
+ *
+ * @param[in] i_istep: Encoded istep value
+ * @param[out] NONE:
+ *
+ * @return Nothing
+ */
+void termSetIstep(uint32_t i_istep);
+
#endif
diff --git a/src/include/runtime/README.md b/src/include/runtime/README.md
new file mode 100755
index 000000000..68b7382be
--- /dev/null
+++ b/src/include/runtime/README.md
@@ -0,0 +1,107 @@
+# interface.h::hostInterfaces::hbrt_fw_msg
+How to create an HBRT to FW request message interface
+ 0) If passing an HBRT to FSP via MBOX or receiving a firmware notify message,
+ then use instruction 'generic_hbrt_fsp_message.H::GenericFspMboxMessage_t'
+ and/or 'How to create an HBRT Firmware Notify message' below.
+ 1) The biggest part will be defining the interface. Inspect the current
+ interfaces (req_hcode_update, error_log, etc) for inspiration.
+ 2) Once an interface has been designed, add it to the anonymous
+ hbrt_fw_msg::union, among the other interfaces.
+ 3) Append a new hbrt_fw_msg::io_type, that will be used to
+ identify the interface.
+ 4) How to use the new interface to pass a message
+ a) Make sure 'g_hostInterfaces' and 'g_hostInterfaces->firmware_request'
+ are not NULL.
+ b) Create the firmware_request request struct (hostInterfaces::hbrt_fw_msg)
+ to send data.
+ c) Populate the firmware_request request struct with data.
+ b) Create the firmware_request response struct (hostInterfaces::hbrt_fw_msg)
+ to retrieve data. 'Zero' it out. Currently, this appears to be not
+ used, but is needed for the firmware request call.
+ d) Make the firmware_request call via method 'firmware_request_helper'
+ Examples:
+ ~/src/usr/sbeio/runtime/sbeio_vital_attn.C::vital_attn_inform_opal
+ ~/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C::notifyNvdimmProtectionChange
+ ~/src/usr/isteps/pm/runtime/rt_pm.C::hcode_update
+ ~/src/usr/errl/runtime/rt_errlmanager.C::sendMboxMsg
+ 5) Update /hostboot/src/usr/util/runtime/rt_fwreq_helper.C::firmware_request_helper,
+ to capture data from the request if an error occurs. Capture data in the
+ TWO switch statements 'switch (l_req_fw_msg->io_type)'. Look at others
+ for examples.
+
+# generic_hbrt_fsp_message.H::GenericFspMboxMessage_t
+# How to create an HBRT Generic FSP Firmware request
+ Firmware request:
+ 1) The biggest part will be defining the interface. Inspect the current
+ interfaces (AttributeSetter_t, SingleScomOpHbrtFspData_t,
+ TargetDeconfigHbrtFspData_t, etc) for inspiration.
+ 2) Once an interface has been designed, add the structure to the file,
+ generic_hbrt_fsp_message.H, among the other interfaces.
+ 3) Create an MBOX message queue enum for the interface and add to:
+ /hostboot/src/include/usr/mbox/mbox_queues.H::queue_id_t
+ see current message queues for example
+ 4) Add a new message type for the interface to:
+ enum GenericFspMboxMessage_t::GENERIC_FSP_MBOX_MESSAGE_MSG_TYPE in
+ file generic_hbrt_fsp_message.H.
+ 5) How to use the new interface to pass a message
+ a) Make sure g_hostInterfaces and g_hostInterfaces->firmware_request
+ are not NULL.
+ b) Determine size of data. It could be as simple as the size of the
+ structure itself.
+ c) Use createGenericFspMsg to create the messages for you.
+ c) Populate the firmware_request request struct with data.
+ d) Make the firmware_request call via method
+ firmware_request_helper
+ Examples:
+ ~/src/usr/hwas/hwasPlatDeconfigGard.C::platPostDeconfigureTarget
+ ~/src/usr/fsiscom/runtime/rt_fsiscom.C::sendScomOpToFsp
+ ~/src/usr/fsiscom/runtime/rt_fsiscom.C::sendMultiScomReadToFsp
+ ~/src/usr/hwas/hwasPlatDeconfigGard.C::DeconfigGard::platPostDeconfigureTarget
+
+# How to create an HBRT Firmware Notify message
+ Firmware notify:
+ 1) The biggest part will be defining the interface. Inspect the current
+ interfaces (sbeRetryReqData_t, HbrtAttrSyncData_t, etc) for inspiration.
+ 2) Once an interface has been designed, add the structure to this file
+ with the other interfaces.
+ 3) Since this is a message sent from the HWSV team, you will need for
+ them to provide the message queue and message type, once you have
+ this info
+ a) Add the message queue to:
+ /hostboot/src/include/usr/mbox/mbox_queues.H::queue_id_t
+ b) Add the message type to:
+ enum generic_hbrt_fsp_message.H::GENERIC_FSP_MBOX_MESSAGE_MSG_TYPE
+ 4) Create a method to process the notify call in file:
+ ~/src/usr/util/runtime/rt_fwnotify.C. This method is where the
+ interface in step 1 will be used.
+ Examples:
+ ~/src/usr/util/runtime/rt_fwnotify.C::sbeAttemptRecovery
+ ~/src/usr/util/runtime/rt_fwnotify.C::occActiveNotification
+ ~/src/usr/util/runtime/rt_fwnotify.C::attrSyncRequest
+ 5) Update the case statement 'switch (l_hbrt_fw_msg->io_type)' found in
+ method ~/src/usr/util/runtime/rt_fwnotify.C::firmware_notify to
+ call method created in step 4.
+
+# Integration testing the Firmware Request/Notify Message
+ This is not a true integration test but a verification that the data is
+ being sent, via the firmware request, in the format that the caller
+ intended. Ensuring that the data is in the correct format and is correct
+ in of itself.
+
+ Add a test case to the file:
+ ~/src/usr/isteps/pm/runtime/test/firmwareRequestTest.H
+ This is where the message will being sent via the
+ hostInterfaces::firmware_request(...) method. Here, is where you will
+ create a unique test case for your interface. Follow the examples in
+ this file. There are plenty of examples.
+
+ Add stub test code to the file/method:
+ ~/src/usr/testcore/rtloader/loader.H::rt_firmware_request(...)
+ This is where the message will be received and can be tested for
+ correctness. Follow the examples in this file. There are plenty of
+ examples.
+
+
+
+
+
diff --git a/src/include/runtime/generic_hbrt_fsp_message.H b/src/include/runtime/generic_hbrt_fsp_message.H
index 3d2f48c0a..f3d252ae2 100644
--- a/src/include/runtime/generic_hbrt_fsp_message.H
+++ b/src/include/runtime/generic_hbrt_fsp_message.H
@@ -30,10 +30,14 @@
/** @file generic_hbrt_fsp_message.H
+ *
* @brief A generic structure for passing data
*
* This file has a generic struct to be used by the
* FSP/HWSV team to send and receive data.
+ *
+ * @note See README.md file on how to create an HBRT to FW
+ * request/notify message interface
*/
// Sentinel value for bad SCOM reads
@@ -54,12 +58,42 @@ private:
};
+// Latest attribute setter (struct AttributeSetter_t) version
+enum ATTRIBUTE_SETTER_VERSION: uint8_t
+{
+ ATTRIBUTE_STRUCT_VERSION_FIRST = 0x01,
+ ATTRIBUTE_STRUCT_VERSION_LATEST = ATTRIBUTE_STRUCT_VERSION_FIRST,
+};
+
+/**
+ * A useful struct to serialize/deserialize the Attributes data
+ * from GenericFspMboxMessage_t::data.
+ */
+struct AttributeSetter_t // a firmware_request call
+{
+ ATTRIBUTE_SETTER_VERSION iv_structVersion;// latest attribute setter version
+ uint8_t iv_reserved;
+ uint16_t iv_numAttributes; // number of attributes being sent
+ uint8_t iv_attrData[]; // points to a stream of
+ // AttributeTank::Attribute structures
+ // A method to set the local vars to a default state
+ void initialize()
+ {
+ iv_structVersion = ATTRIBUTE_STRUCT_VERSION_LATEST;
+ iv_reserved = 0;
+ iv_numAttributes = 0;
+ };
+} PACKED ;
+
/**
* A useful struct to pack/access the HUID and HWAS state
* from the GenericFspMboxMessage_t.data.
* The HUID will be in the first 4 bytes followed by the HWAS state.
+ *
+ * @note message queue = MBOX::FSP_TARG_DECONFIG_MSGQ;
+ * message type = MSG_DECONFIG_TARGET
*/
-struct TargetDeconfigHbrtFspData_t
+struct TargetDeconfigHbrtFspData_t // a firmware_request call
{
uint32_t huid;
TARGETING::HwasState hwasState;
@@ -70,8 +104,11 @@ struct TargetDeconfigHbrtFspData_t
* This struct contains the message-specific data for
* MSG_SINGLE_SCOM_OP calls to the FSP.
* It shows the format of GenericFspMboxMessage_t.data.
+ *
+ * @note message queue = MBOX::FSP_SCOM_OPS_MSGQ
+ * message type = MSG_SINGLE_SCOM_OP
*/
-struct SingleScomOpHbrtFspData_t
+struct SingleScomOpHbrtFspData_t // a firmware_request call
{
uint8_t scom_op; // DeviceFW::READ, DeviceFW::WRITE
uint32_t huid; // hardware target
@@ -85,8 +122,11 @@ struct SingleScomOpHbrtFspData_t
* This struct contains the message-specific data for
* MSG_MULTI_SCOM_OP calls to the FSP.
* It shows the format of GenericFspMboxMessage_t.data.
+ *
+ * @note message queue = MBOX::FSP_SCOM_OPS_MSGQ
+ * message type = MSG_MULTI_SCOM_OP
*/
-struct MultiScomReadHbrtFspData_t
+struct MultiScomReadHbrtFspData_t // a firmware_request call
{
uint32_t huid; // hardware target
uint8_t scom_num; // number of SCOMs to read
@@ -107,8 +147,11 @@ struct MultiScomReadHbrtFspData_t
/**
* A useful struct to access the PLID from GenericFspMboxMessage_t.data
* in the case where the FSP is requesting Hostboot to restart a SBE
+ *
+ * @note message queue = MBOX::FSP_SCOM_OPS_MSGQ
+ * message type = MSG_SBE_ERROR
*/
-struct SbeRetryReqData_t
+struct SbeRetryReqData_t // a firmware_notify call
{
uint32_t huid;
uint32_t plid;
@@ -122,8 +165,10 @@ struct SbeRetryReqData_t
* The HUID will be the first 4 bytes followed by a 4-byte attribute ID,
* then a 4-byte size of attribute data, and finally the attribute's data
*
+ * @note message queue = MBOX::HB_ATTR_SYNC_MSGQ
+ * message type = MSG_ATTR_SYNC_REQUEST
*/
-struct HbrtAttrSyncData_t
+struct HbrtAttrSyncData_t // a firmware_notify call
{
// HUID of target on which we want to update the attribute
uint32_t huid;
@@ -187,14 +232,15 @@ struct GenericFspMboxMessage_t
MSG_TOD_BACKUP_RESET = 0x0001,
MSG_TOD_BACKUP_RESET_INFORM_PHYP = 0x0002,
MSG_TOD_TOPOLOGY_DATA = 0x0003,
- MSG_DECONFIG_TARGET = 0x0004,
- MSG_SINGLE_SCOM_OP = 0x0005,
- MSG_MULTI_SCOM_OP = 0x0006,
- MSG_ATTR_SYNC_REQUEST = 0x000000A5,
+ MSG_DECONFIG_TARGET = 0x0004, // for TargetDeconfigHbrtFspData_t
+ MSG_SINGLE_SCOM_OP = 0x0005, // for SingleScomOpHbrtFspData_t
+ MSG_MULTI_SCOM_OP = 0x0006, // for MultiScomReadHbrtFspData_t
+ MSG_ATTR_WRITE_OP = 0x0007, // for AttributeSetter_t
+ MSG_ATTR_SYNC_REQUEST = 0x000000A5, // for HbrtAttrSyncData_t
MSG_OCC_ACTIVE = 0x000000A6,
- MSG_SBE_ERROR = 0x000000D4,
- MSG_SBE_RECOVERY_SUCCESS = 0x000000D5,
- MSG_SBE_RECOVERY_FAILED = 0x000000D6,
+ MSG_SBE_ERROR = 0x000000D4, // for SbeRetryReqData_t
+ MSG_SBE_RECOVERY_SUCCESS = 0x000000D5, // associated with SbeRetryReqData_t
+ MSG_SBE_RECOVERY_FAILED = 0x000000D6, // associated with SbeRetryReqData_t
};
/**
diff --git a/src/include/runtime/hbrt_utilities.H b/src/include/runtime/hbrt_utilities.H
index 649677422..2ee2172df 100644
--- a/src/include/runtime/hbrt_utilities.H
+++ b/src/include/runtime/hbrt_utilities.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -29,7 +29,16 @@
#define HBRT_TRACE_NAME "HBRT"
-#include "interface.h"
+extern trace_desc_t *g_trac_runtime;
+
+#include <vector>
+
+#include "interface.h" // hostInterfaces
+#include "generic_hbrt_fsp_message.H" // GenericFspMboxMessage_t, AttributeSetter_t
+#include "targeting/common/attributeTank.H" // TARGETING::AttributeTank::Attribute
+#include <initservice/initserviceif.H> // INITSERVICE
+#include "util/runtime/rt_fwreq_helper.H" // firmware_request_helper
+#include "runtime/runtime_reasoncodes.H" // MOD_XXX and RC_XXX
/** @file hbrt_utilities.H
* @brief A file to put HBRT Interface utilities
@@ -54,9 +63,9 @@
* to newly created data.)
*
* @post The request/response messages point to a valid struct,
- * the request/response message size are equal to each other
- * and contain the size of the request/response messages
- * respectively upon a successful call else all the output
+ * the request/response messages' size are equal to each other, request
+ * message is initalized (data size is set) and response message is
+ * zeroed out, upon a successful call else all the output
* parameters will either be NULL or 0 based on type.
*
* @note Use this function iff hbrt_fw_msg::io_type is of type
@@ -65,7 +74,7 @@
* @note Caller is responsible for deleting (use delete []) the
* allocated memory
*
- * @param[in] i_fspReqPayloadSize The size of the payload that will
+ * @param[in] i_fspReqPayloadSize The size of the payload that will
* populate GenericFspMboxMessage_t::data
* @param[out] o_fspMsgSize Return the size of the
* GenericFspMboxMessage_t, adjusted to
@@ -76,66 +85,23 @@
* will be equal to the request msg size
* @param[out] o_responseMsg The allocated response message (not
* NULL), zeroed out
+ * @return true if NO issue allocating memory for request/response messages,
+ * else false
*/
-void createGenericFspMsg(uint32_t i_fspReqPayloadSize,
- uint32_t &o_fspMsgSize,
- uint64_t &o_requestMsgSize,
- hostInterfaces::hbrt_fw_msg* &o_requestMsg,
- uint64_t &o_responseMsgSize,
- hostInterfaces::hbrt_fw_msg* &o_responseMsg)
-{
- // Do some quick initialization of the output data
- o_fspMsgSize = o_requestMsgSize = o_responseMsgSize = 0;
- o_requestMsg = o_responseMsg = nullptr;
-
- // Calculate the total size of the Generic FSP Message.
- o_fspMsgSize = GENERIC_FSP_MBOX_MESSAGE_BASE_SIZE +
- i_fspReqPayloadSize;
-
- // The total Generic FSP Message size must be at a minimum the
- // size of the FSP generic message (sizeof(GenericFspMboxMessage_t))
- if (o_fspMsgSize < sizeof(GenericFspMboxMessage_t))
- {
- o_fspMsgSize = sizeof(GenericFspMboxMessage_t);
- }
+bool createGenericFspMsg(uint32_t i_fspReqPayloadSize,
+ uint32_t &o_fspMsgSize,
+ uint64_t &o_requestMsgSize,
+ hostInterfaces::hbrt_fw_msg* &o_requestMsg,
+ uint64_t &o_responseMsgSize,
+ hostInterfaces::hbrt_fw_msg* &o_responseMsg);
- // Calculate the total size of the hbrt_fw_msgs which
- // means only adding hostInterfaces::HBRT_FW_MSG_BASE_SIZE to
- // the previous calculated Generic FSP Message size.
- o_requestMsgSize = o_responseMsgSize =
- hostInterfaces::HBRT_FW_MSG_BASE_SIZE + o_fspMsgSize;
- // Create the hbrt_fw_msgs
- o_responseMsg = reinterpret_cast<hostInterfaces::hbrt_fw_msg *>
- (new uint8_t[o_responseMsgSize]);
- o_requestMsg = reinterpret_cast<hostInterfaces::hbrt_fw_msg *>
- (new uint8_t[o_requestMsgSize]);
-
- // If anyone of these two message's memory can't be allocated, then
- // delete both messages (in case one did allocate memory), set both
- // messages to NULL pointers and set their respective sizes to zero.
- if (!o_responseMsg || !o_requestMsg)
- {
- // OK to delete a NULL pointer if it happens
- delete []o_responseMsg;
- delete []o_requestMsg;
-
- // Return output data zeroed out
- o_responseMsg = o_requestMsg = nullptr;
- o_fspMsgSize = o_requestMsgSize = o_responseMsgSize = 0;
- }
- else
- {
- // Initialize/zero out hbrt_fw_msgs
- o_requestMsg->generic_msg.initialize();
- memset(o_responseMsg, 0, o_responseMsgSize);
+/**
+ * @brief Serializes a list of Attributes to be sent to FSP
+ */
+errlHndl_t sendAttributes(const std::vector<TARGETING::AttributeTank::Attribute>&
+ i_attributeList);
- // We can at least set these parameters based on current usage
- o_requestMsg->io_type = hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ;
- o_requestMsg->generic_msg.dataSize = o_fspMsgSize;
- o_requestMsg->generic_msg.__req = GenericFspMboxMessage_t::REQUEST;
- }
-} // end createGenericFspMsg
#endif //__HOSTBOOT_RUNTIME_INTERFACE_VERSION_ONLY
#endif // __RUNTIME__UTILITIES_H
diff --git a/src/include/runtime/interface.h b/src/include/runtime/interface.h
index cd6d0e23a..6304ec6ba 100644
--- a/src/include/runtime/interface.h
+++ b/src/include/runtime/interface.h
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2019 */
+/* Contributors Listed Below - COPYRIGHT 2013,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -193,6 +193,10 @@ enum MemoryError_t
/* Defined Return Codes for wakeup() */
#define HBRT_RC_WAKEUP_INVALID_ON_CORE_XSTOP -12289 /* -0x3001 */
+/* Define a const, for hostInterfaces::nvdimm_operation_t::procId,
+ * that will flag when to apply the NVDIMM operation(s) to all NVDIMMs
+ */
+const uint64_t HBRT_NVDIMM_OPERATION_APPLY_TO_ALL_NVDIMMS = 0xFFFFFFFFFFFFFFFF;
/** @typedef hostInterfaces_t
* @brief Interfaces provided by the underlying environment (ex. Sapphire).
@@ -541,19 +545,25 @@ typedef struct hostInterfaces
/**
* @brief Structure to be sent and received in the
* firmware_request call
+ *
+ * @note see README.md file on how to create an HBRT to FW
+ * request message interface
*/
- enum
+
+ enum // hbrt_fw_msg::io_type the struct associated with io_type
{
- HBRT_FW_MSG_TYPE_REQ_NOP = 0,
- HBRT_FW_MSG_TYPE_RESP_NOP = 1,
- HBRT_FW_MSG_TYPE_RESP_GENERIC = 2,
- HBRT_FW_MSG_TYPE_REQ_HCODE_UPDATE = 3,
- HBRT_FW_MSG_HBRT_FSP_REQ = 4,
- HBRT_FW_MSG_TYPE_ERROR_LOG = 5,
- HBRT_FW_MSG_HBRT_FSP_RESP = 6,
- HBRT_FW_MSG_TYPE_I2C_LOCK = 7,
- HBRT_FW_MSG_TYPE_SBE_STATE = 8,
- HBRT_FW_MSG_TYPE_NVDIMM_PROTECTION = 9,
+ HBRT_FW_MSG_TYPE_REQ_NOP = 0,
+ HBRT_FW_MSG_TYPE_RESP_NOP = 1, // struct resp_generic
+ HBRT_FW_MSG_TYPE_RESP_GENERIC = 2, // struct resp_generic
+ HBRT_FW_MSG_TYPE_REQ_HCODE_UPDATE = 3, // struct req_hcode_update
+ HBRT_FW_MSG_HBRT_FSP_REQ = 4, // struct GenericFspMboxMessage_t
+ HBRT_FW_MSG_TYPE_ERROR_LOG = 5, // struct error_log
+ HBRT_FW_MSG_HBRT_FSP_RESP = 6, // struct GenericFspMboxMessage_t
+ HBRT_FW_MSG_TYPE_I2C_LOCK = 7, // struct req_i2c_lock
+ HBRT_FW_MSG_TYPE_SBE_STATE = 8, // struct sbe_state
+ HBRT_FW_MSG_TYPE_NVDIMM_PROTECTION = 9, // struct nvdimm_protection_state
+ HBRT_FW_MSG_TYPE_NVDIMM_OPERATION = 10, // struct nvdimm_operation_t
+ HBRT_FW_MSG_TYPE_GARD_EVENT = 11, // struct gard_event_t
};
// NVDIMM protection state enum
@@ -563,6 +573,88 @@ typedef struct hostInterfaces
HBRT_FW_NVDIMM_PROTECTED = 1
};
+ // NVDIMM valid operations
+ // @note Multiple operations can be triggered at the same time using
+ // a single NVDIMM operation call. Having said that, operation
+ // combinations should be sensical. Nonsensical operations will
+ // error out.
+ enum NVDIMM_Op_t: uint16_t
+ {
+ /// The following operations pertain to arming/disarming
+ /// the NVDIMM
+ // Disarm the NV logic such that the next save attempt is a NOOP
+ HBRT_FW_NVDIMM_DISARM = 0x0001,
+ // Disable encryption on the NVDIMM and clear saved values from FW
+ HBRT_FW_NVDIMM_DISABLE_ENCRYPTION = 0x0002,
+ // Remove keys
+ HBRT_FW_NVDIMM_REMOVE_KEYS = 0x0004,
+ // Enable encryption on the NVDIMM
+ HBRT_FW_NVDIMM_ENABLE_ENCRYPTION = 0x0008,
+ // Arm the NV logic
+ HBRT_FW_NVDIMM_ARM = 0x0010,
+
+ /// The following operations pertain to the Health of the NVDIMM
+ /// This operation can be performed with the arming/disarming
+ /// operation, these operation types are orthogonal to each other
+ // Manufacturing(MNFG) energy source(ES) health check request
+ HBRT_FW_MNFG_ES_HEALTH_CHECK = 0x0020,
+ // Manufacturing(MNFG) non-volatile memory(NVM) health check request
+ HBRT_FW_MNFG_NVM_HEALTH_CHECK = 0x0040,
+
+ /// The following operations pertain to the decommission of an NVDIMM
+ // Factory Default returns the NVDIMM to the factory default state
+ HBRT_FW_NVDIMM_FACTORY_DEFAULT = 0x0080,
+ // Secure Erase Verify all NAND flash blocks have been erased
+ HBRT_FW_NVDIMM_SECURE_EV_START = 0x0100,
+ // Secure Erase Verify Status checks if SEV operation has completed
+ HBRT_FW_NVDIMM_SECURE_EV_STATUS = 0x0200,
+ };
+
+ // NVDIMM (PHYP -> HBRT) message to request NVDIMM operation(s)
+ struct nvdimm_operation_t
+ {
+ uint64_t procId; // Retrieve all NVDIMMs under the processor ID; all
+ // FFs (HBRT_NVDIMM_OPERATION_APPLY_TO_ALL_NVDIMMS)
+ // means operate on all NVDIMMs in the system
+ uint32_t rsvd1; // reserved
+ uint16_t rsvd2; // reserved
+ NVDIMM_Op_t opType; // NVDIMM operation(s) to perform,
+ // see @note associated with NVDIMM_Op_t above
+ } __attribute__ ((packed));
+
+ // Gard event error type
+ // @note This needs to stay in sync with the FSP Mailbox specification for
+ // command : Gard-able Error Detected - cmd 0xCE, s/c 0x63, mod 01
+ enum GARD_ERROR_t: uint32_t
+ {
+ HBRT_GARD_ERROR_UNKNOWN = 0x0000,
+ HBRT_GARD_ERROR_COMPUTATION_TEST_FAILURE = 0x0001,
+ HBRT_GARD_ERROR_SLB = 0x0002,
+ HBRT_GARD_ERROR_CHIP_TOD_FAILURE = 0x0003,
+ HBRT_GARD_ERROR_TIMEFAC_FAILURE = 0x0004,
+ HBRT_GARD_ERROR_PROC_RECOVERY_THRESHOLD = 0x0005,
+ HBRT_GARD_ERROR_NX = 0x0008,
+ HBRT_GARD_ERROR_SLW = 0x0009,
+ HBRT_GARD_ERROR_CAPP_UNIT = 0x000A,
+
+ // Mark the end of the gard error types.
+ // This is not valid, just a marker
+ HBRT_GARD_ERROR_LAST,
+ };
+
+ // Gard event (PHYP/OPAL -> HBRT)
+ struct gard_event_t
+ {
+ GARD_ERROR_t i_error_type; // Gard event error type enum
+ uint32_t i_procId; // Processor ID for
+ // error types 0x0001 to 0x0005
+ // Chip ID for
+ // error types 0x0008 to 0x000A
+ uint32_t i_plid; // Platform log identifier
+ uint16_t i_sub_unit_mask; // Currently not being used
+ uint16_t i_recovery_level; // Currently not being used
+ } __attribute__ ((packed));
+
struct hbrt_fw_msg // define struct hbrt_fw_msg
{
hbrt_fw_msg() { req_hcode_update = { 0 }; }; // ctor
@@ -593,7 +685,7 @@ typedef struct hostInterfaces
} req_hcode_update;
// This struct is sent from HBRT with
- // io_type set to HBRT_FW_MSG_TYPE_ERR_LOG
+ // io_type set to HBRT_FW_MSG_TYPE_ERROR_LOG
// Send an error log to FSP
struct
{
@@ -633,6 +725,14 @@ typedef struct hostInterfaces
uint64_t i_state; // NVDIMM protection state enum
} __attribute__ ((packed)) nvdimm_protection_state;
+ // This struct is sent from PHYP to HBRT with
+ // io_type set to HBRT_FW_MSG_TYPE_NVDIMM_OPERATION
+ struct nvdimm_operation_t nvdimm_operation;
+
+ // This struct is sent from PHYP/OPAL to HBRT with
+ // io_type set to HBRT_FW_MSG_TYPE_GARD_EVENT
+ struct gard_event_t gard_event;
+
// This struct is sent from HBRT with
// io_type set to HBRT_FW_MSG_HBRT_FSP_REQ or
// HBRT_FW_MSG_HBRT_FSP_RESP
@@ -1032,6 +1132,11 @@ struct postInitCalls_t
*/
void (*callCommitRsvdTraceBufErrl)();
+ /**
+ * @brief Sends current NV_STATUS to host
+ *
+ */
+ void (*callSendNvStatus)();
};
extern hostInterfaces_t* g_hostInterfaces;
diff --git a/src/include/securerom/ROM.H b/src/include/securerom/ROM.H
index f4cf76528..0d97537e0 100644
--- a/src/include/securerom/ROM.H
+++ b/src/include/securerom/ROM.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -284,7 +284,7 @@ enum HW_SB_FLAGS
// SW Security Flags
enum SW_SB_FLAGS
{
- // placeholder
+ HASH_PAGE_TABLE_FLAG = 0x80000000
};
// Structure to store all hw and sw flag values in a container header
@@ -295,7 +295,8 @@ struct sb_flags_t
hw_opal(false),
hw_phyp(false),
hw_lab_override(false),
- hw_key_transition(false)
+ hw_key_transition(false),
+ sw_hash(false)
{
}
@@ -305,6 +306,7 @@ struct sb_flags_t
bool hw_lab_override; ///< Whether to enable lab security override;
///< Only applicable for SBE partition
bool hw_key_transition; ///< Indicates this is a key transition container
+ bool sw_hash; ///< Indicates presence of hash page table
};
/**
diff --git a/src/include/usr/console/consoleif.H b/src/include/usr/console/consoleif.H
index 497252ded..fc3b83d24 100644
--- a/src/include/usr/console/consoleif.H
+++ b/src/include/usr/console/consoleif.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2017 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -26,8 +26,8 @@
#ifndef __CONSOLE_CONSOLEIF_H
#define __CONSOLE_CONSOLEIF_H
-#include <config.h>
#include <stdarg.h>
+#include <stddef.h>
namespace CONSOLE
{
diff --git a/src/include/usr/console/uartif.H b/src/include/usr/console/uartif.H
index 768e0d45b..982400227 100644
--- a/src/include/usr/console/uartif.H
+++ b/src/include/usr/console/uartif.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -25,7 +25,6 @@
#ifndef __CONSOLE_UARTIF_H
#define __CONSOLE_UARTIF_H
-#include <config.h>
#include <stdarg.h>
namespace CONSOLE
diff --git a/src/include/usr/cxxtest/TestSuite.H b/src/include/usr/cxxtest/TestSuite.H
index 0c9e2305a..716637049 100755
--- a/src/include/usr/cxxtest/TestSuite.H
+++ b/src/include/usr/cxxtest/TestSuite.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,6 +40,7 @@
#include <trace/interface.H>
#include <sys/sync.h>
#include <usr/cxxtest/cxxtest_data.H>
+#include <vector>
extern trace_desc_t *g_trac_test;
@@ -76,6 +77,9 @@ public:
class AbortTest {};
+void sortTests(std::vector<const char *> & i_list,
+ std::vector<const char *> & o_serial_list,
+ std::vector<const char *> & o_parallel_list);
void doTrace( );
void doWarn( );
void doFailTest( );
diff --git a/src/include/usr/devicefw/driverif.H b/src/include/usr/devicefw/driverif.H
index 048b8dc19..66c420c21 100644
--- a/src/include/usr/devicefw/driverif.H
+++ b/src/include/usr/devicefw/driverif.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2019 */
+/* Contributors Listed Below - COPYRIGHT 2011,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -103,6 +103,8 @@ namespace DeviceFW
I2C_SMBUS_WORD = 3, ///< I2c SMBUS Read/Write Word
I2C_SMBUS_BYTE = 4, ///< I2c SMBUS Read/Write Byte
I2C_SMBUS_SEND_OR_RECV = 5, ///< I2c SMBUS Send/Receive Byte
+ I2C_SMBUS_WORD_NO_PEC = 6, ///< I2c SMBUS Read/Write Word without PEC byte
+ I2C_SMBUS_BLOCK_NO_BYTE_COUNT = 7, ///< I2c SMBUS Block Read/Write without first byte being a byte count
};
#ifndef PARSER
diff --git a/src/include/usr/devicefw/userif.H b/src/include/usr/devicefw/userif.H
index d626d49c0..ec94bef32 100644
--- a/src/include/usr/devicefw/userif.H
+++ b/src/include/usr/devicefw/userif.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2019 */
+/* Contributors Listed Below - COPYRIGHT 2011,2020 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -68,7 +68,8 @@ namespace DeviceFW
AHB_SIO, // AST Hostbridge via SIO
DVPD, // Direct access memory VPD
NODECOMM, // Internode communication
- NVDIMM, // Non-volatile DIMM controller access
+ NVDIMM, // Routes message to non-volatile DIMM controller access
+ NVDIMM_RAW, // Non-volatile DIMM controller access
FAPI_I2C, // FAPI2-triggered i2c accesses
MMIO, // Memory Mapped I/O
IDEC, // Read and set EC and CHIPID values
@@ -379,12 +380,45 @@ namespace DeviceFW
static_cast<uint64_t>(( i_mailbox_id ))
/**
- * Construct the device addressing parameters for the NVDIMM device ops.
- * @param[i] i_address - NVDIMM address to internal register
+ * @brief Construct the device addressing parameters for the
+ * NVDIMM device ops.
+ * @details This call includes setting the page based off the address
+ * and then performing the read/write of that NVDIMM address.
+ * @see DEVICE_NVDIMM_RAW_ADDRESS for an NVDIMM read/write call without
+ * page setting.
+ * @param[i] i_address - NVDIMM address to an internal register
*/
#define DEVICE_NVDIMM_ADDRESS(i_address)\
DeviceFW::NVDIMM, static_cast<uint64_t>((i_address))
+ /**
+ * @brief Construct the device addressing parameters for the
+ * NVDIMM RAW device ops + use block size specified
+ * @details This a raw call to read/write a NVDIMM address which means it
+ * will not set the page before it does the read/write call. Hence,
+ * for this call to work properly, the page must have been set
+ * properly beforehand.
+ * @see DEVICE_NVDIMM_ADDRESS for a NVDIMM read/write call with
+ * page setting.
+ * @param[i] i_address - NVDIMM address to an internal register
+ * @param[i] i_blockSize - maximum block size for operation (0 = default size, 2 and 32 valid)
+ */
+ #define DEVICE_NVDIMM_RAW_ADDRESS_WITH_BLOCKSIZE(i_address, i_blockSize)\
+ DeviceFW::NVDIMM_RAW, static_cast<uint64_t>((i_address)), static_cast<uint64_t>((i_blockSize))
+
+ /**
+ * @brief Construct the device addressing parameters for the
+ * NVDIMM RAW device ops.
+ * @details This a raw call to read/write a NVDIMM address which means it
+ * will not set the page before it does the read/write call. Hence,
+ * for this call to work properly, the page must have been set
+ * properly beforehand.
+ * @see DEVICE_NVDIMM_ADDRESS for a NVDIMM read/write call with
+ * page setting.
+ * @param[i] i_address - NVDIMM address to an internal register
+ */
+ #define DEVICE_NVDIMM_RAW_ADDRESS(i_address)\
+ DEVICE_NVDIMM_RAW_ADDRESS_WITH_BLOCKSIZE(i_address, 0)
/**
* Construct the device addressing parameters for the FAPI I2C operation
diff --git a/src/include/usr/diag/attn/attn.H b/src/include/usr/diag/attn/attn.H
index 186974224..c32212663 100644
--- a/src/include/usr/diag/attn/attn.H
+++ b/src/include/usr/diag/attn/attn.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -34,7 +34,6 @@
#include <errl/errlentry.H>
// Custom compile configs
-#include <config.h>
namespace ATTN
{
diff --git a/src/include/usr/diag/prdf/prdfMain_ipl.H b/src/include/usr/diag/prdf/prdfMain_ipl.H
index 08b626ce2..302cd4e61 100644
--- a/src/include/usr/diag/prdf/prdfMain_ipl.H
+++ b/src/include/usr/diag/prdf/prdfMain_ipl.H
@@ -27,7 +27,6 @@
#define __prdfMain_ipl_H
// Custom compile configs
-#include <config.h>
/**
* @file prdfMain_ipl.H
@@ -48,7 +47,7 @@ extern errlHndl_t noLock_initialize();
/**
* @brief Restores hardware DRAM repairs to reflect what is stored in VPD.
- * @param i_trgt An MBA or MCA target.
+ * @param i_trgt An MBA, MCA, or OCMB target.
* @return Non-SUCCESS if conditions are such that a callout had to be made,
* SUCCESS otherwise.
*/
@@ -57,17 +56,17 @@ extern uint32_t restoreDramRepairs( const TARGETING::TargetHandle_t i_trgt );
/**
* @brief Analyzes IPL CE statistics during MNFG IPL
- * @param i_mba An MBA target.
+ * @param i_trgt An MBA, MCBIST, or OCMB_CHIP target.
* @param o_calloutMade True if callout has been made, false otherwise .
* @return Non-SUCCESS if internal function fails, SUCCESS otherwise.
*/
-extern int32_t analyzeIplCEStats( const TARGETING::TargetHandle_t i_mba,
+extern int32_t analyzeIplCEStats( const TARGETING::TargetHandle_t i_trgt,
bool &o_calloutMade );
/**
* @brief Starts memory background scrubbing on the given target.
* @param i_trgt A target that contains the maintenance command logic (i.e.
- * MCBIST or MBA).
+ * MCBIST or MBA or OCMB_CHIP).
* @return If an error log is returned, then some internal function failed. See
* the FFDC in the error log for failure details.
*/
diff --git a/src/include/usr/dump/dumpif.H b/src/include/usr/dump/dumpif.H
index ea48a71fd..0b616be74 100644
--- a/src/include/usr/dump/dumpif.H
+++ b/src/include/usr/dump/dumpif.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2019 */
+/* Contributors Listed Below - COPYRIGHT 2012,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -146,10 +146,19 @@ namespace DUMP
#define DUMP_ARCH_REG_TYPE_SPR 0x02
// Architected register data content entries
+ union reg_t
+ {
+ char name[sizeof(uint32_t)*2];
+ struct
+ {
+ uint32_t type;
+ uint32_t num;
+ }PACKED;
+ }PACKED;
+
struct hostArchRegDataEntry
{
- uint32_t regType;
- uint32_t regNum;
+ reg_t reg;
uint64_t regVal;
} PACKED;
diff --git a/src/include/usr/errl/errlentry.H b/src/include/usr/errl/errlentry.H
index a41cb7bcf..905203a9e 100644
--- a/src/include/usr/errl/errlentry.H
+++ b/src/include/usr/errl/errlentry.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2019 */
+/* Contributors Listed Below - COPYRIGHT 2011,2020 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -860,17 +860,15 @@ private:
*/
void addVersionInfo(void);
-#ifdef CONFIG_BMC_IPMI
/**
- * @brief called by addHwCallout to retrieve the serial and part number
- * from the current target. If the current target does not contain
- * ATTR_PART_NUMBER or ATTR_SERIAL_NUMBER, find the first parent that does
- * and adds the attribute to the error log.
+ * @brief called by addHwCallout to retrieve various pieces of card
+ * and/or chip data, e.g. part number, serial number, ecid.
*
* @param[in] i_target The target to get the numbers for
*/
- void addPartAndSerialNumbersToErrLog(const TARGETING::Target * i_target);
+ void addPartIdInfoToErrLog(const TARGETING::Target * i_target);
+#ifdef CONFIG_BMC_IPMI
/**
* @brief called by addHwCallout to retrieve the FRU ID and sensor ID
* from the current target. If the current target does not contain
@@ -1146,4 +1144,10 @@ inline bool ErrlEntry::getDoHbDump()
*/
#define ERRL_GETEID_SAFE(errhdl) (errhdl == NULL ? 0 : errhdl->eid())
+// These defines allow standard logging of error information in traces
+#define TRACE_ERR_FMT "Error info: PLID=0x%08X, EID=0x%08X, Reason=0x%04X. "
+
+#define TRACE_ERR_ARGS(pError) \
+ ERRL_GETPLID_SAFE(pError), ERRL_GETEID_SAFE(pError), ERRL_GETRC_SAFE(pError)
+
#endif //ERRLENTRY_H
diff --git a/src/include/usr/errl/errlmanager.H b/src/include/usr/errl/errlmanager.H
index f7407d8c4..cfd5ee21d 100644
--- a/src/include/usr/errl/errlmanager.H
+++ b/src/include/usr/errl/errlmanager.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -35,7 +35,6 @@
/*****************************************************************************/
// I n c l u d e s
/*****************************************************************************/
-#include <config.h>
#include <util/singleton.H>
#include <errl/errlentry.H>
#include <errldisplay/errldisplay.H>
@@ -82,6 +81,32 @@ void errlCommit(errlHndl_t& io_err, compId_t i_committerComp );
uint8_t getHiddenLogsEnable();
/**
+ * @brief Returns the cached VERSION partition, if any. Makes a call to
+ * ErrlManager::getCachedVersionPartition
+ * @return uint8_t* The pointer to the binary contents of the VERSION
+ * partition; nullptr will be returned if VERSION hasn't been
+ * cached yet of if there was an error during caching
+ */
+const uint8_t* getCachedVersionPartition();
+
+/**
+ * @brief Returns the size of the cached VERSION partition. Makes a call
+ * to ErrlManager::getCachedVersionPartitionSize
+ * @return size_t The size of the cached VERSION partition. A 0 will be
+ * returned if VERSION hasn't been cached yet or if there was an
+ * error during caching
+ */
+size_t getCachedVersionPartitionSize();
+
+/*
+ * @brief Call to ErrlManager to cache the VERSION PNOR partition into an
+ * internal buffer.
+ *
+ * @return errlHndl_t nullptr on success; non-nullptr on error.
+ */
+errlHndl_t cacheVersionPartition();
+
+/**
* @brief Global enums used by static errlResourceReady function
*/
enum errlManagerNeeds
@@ -209,6 +234,34 @@ public:
*/
static bool errlCommittedThisBoot();
+ /**
+ * @brief Returns the cached VERSION partition, if any
+ * @return uint8_t* The pointer to the binary contents of the VERSION
+ * partition
+ */
+ const uint8_t* getCachedVersionPartition() const;
+
+ /**
+ * @brief Returns the size of the cached VERSION partition
+ * @return size_t The size of the cached VERSION partition
+ */
+ size_t getCachedVersionPartitionSize() const;
+
+ /**
+ * @brief Cache the VERSION PNOR partition into a member buffer. The
+ * buffer is dynamically allocated here to hold the contents of the
+ * partition. If any error occurs during the execution, the buffer
+ * is deleted and the error is returned. This function is not
+ * supposed to be called within ErrlManager message handler, since
+ * the function itself makes synchronous calls to various message
+ * handlers. Note that once the partition is cached, the cache is
+ * never purged to make sure all possible error logs receive the
+ * VERSION field. No-op on FSP systems.
+ *
+ * @return errlHndl_t nullptr on success; non-nullptr on error.
+ */
+ errlHndl_t cacheVersionPartition();
+
/**
* @brief Value to determine what logs are to be skipped. Mirrors
@@ -424,6 +477,11 @@ private:
bool iv_pnorReadyForErrorLogs;
/**
+ * @brief Indicates if we have processed a shutdown event message
+ */
+ bool iv_recvdShutdownEvent;
+
+ /**
* @brief
* Pointer to the header that precedes the error log storage buffer
* in L3 RAM. This may go away when we adopt PNOR, or else become
@@ -634,6 +692,15 @@ private:
bool allowCallHomeEselsToBmc(void);
#endif
+ const uint8_t* iv_versionPartitionCache; // The bin contents of the VERSION
+ // partition; once cached, the
+ // constents are never removed
+
+ size_t iv_versionPartitionCacheSize; // The size of the VERSION partition
+
+ bool iv_isVersionPartitionCached; // Whether the caching of the VERSION
+ // partition has been attempted
+
};
diff --git a/src/include/usr/errl/errludattribute.H b/src/include/usr/errl/errludattribute.H
new file mode 100644
index 000000000..8321785cb
--- /dev/null
+++ b/src/include/usr/errl/errludattribute.H
@@ -0,0 +1,87 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/errl/errludattribute.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef ERRL_UDATTRIBUTE_H
+#define ERRL_UDATTRIBUTE_H
+
+/**
+ * Defines the classes that allow you to save attribute data to
+ * an error log.
+ */
+
+#include <errl/errluserdetails.H>
+
+namespace TARGETING // Forward reference
+{ class Target; }
+
+namespace ERRORLOG
+{
+class ErrlUserDetailsAttribute : public ErrlUserDetails {
+ public:
+
+ /**
+ * @brief Constructor to add a single attribute
+ *
+ * @param i_target Target from whom the attribute is being read
+ * @param i_attr Attribute id/hash
+ */
+ ErrlUserDetailsAttribute(const TARGETING::Target * i_pTarget,
+ uint32_t i_attr);
+
+ /**
+ * @brief Constructor to add no attributes (need to call addData)
+ *
+ * @param i_target Target from whom the attribute is being read
+ */
+ ErrlUserDetailsAttribute(const TARGETING::Target * i_pTarget);
+
+ /**
+ * @brief Add an additional attribute to the log
+ *
+ * @param i_attr Attribute id/hash
+ */
+ void addData(uint32_t i_attr);
+
+
+ /**
+ * @brief Destructor
+ */
+ virtual ~ErrlUserDetailsAttribute();
+
+ private:
+
+ // Disabled
+ ErrlUserDetailsAttribute(const ErrlUserDetailsAttribute &);
+ ErrlUserDetailsAttribute & operator=(const ErrlUserDetailsAttribute &);
+
+ // internal function
+ void dumpAll();
+
+ const TARGETING::Target * iv_pTarget;
+ uint32_t iv_dataSize;
+};
+}
+
+#endif //ERRL_UDATTRIBUTE_H
diff --git a/src/include/usr/errl/errludprintk.H b/src/include/usr/errl/errludprintk.H
index 4d304ff46..629716e68 100644
--- a/src/include/usr/errl/errludprintk.H
+++ b/src/include/usr/errl/errludprintk.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2014 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -39,7 +41,7 @@ namespace ERRORLOG
class ErrlUserDetailsPrintk : public ErrlUserDetails
{
public:
- enum { DEFAULT_SIZE_BYTES = 256 };
+ enum { DEFAULT_SIZE_BYTES = 1280 };
/** @brief Constructor
*
diff --git a/src/include/usr/errldisplay/errldisplay.H b/src/include/usr/errldisplay/errldisplay.H
index b5856b7f1..a219a47c3 100644
--- a/src/include/usr/errldisplay/errldisplay.H
+++ b/src/include/usr/errldisplay/errldisplay.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -35,7 +35,6 @@
/*****************************************************************************/
// I n c l u d e s
/*****************************************************************************/
-#include <config.h>
#include <errl/errlentry.H>
namespace ERRORLOGDISPLAY
diff --git a/src/include/usr/expscom/expscom_reasoncodes.H b/src/include/usr/expscom/expscom_reasoncodes.H
index 9eb7ebc29..67608b69c 100644
--- a/src/include/usr/expscom/expscom_reasoncodes.H
+++ b/src/include/usr/expscom/expscom_reasoncodes.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -43,6 +43,12 @@ namespace EXPSCOM
RC_INVALID_OPTYPE = EXPSCOM_COMP_ID | 0x03,
RC_INVALID_ADDRESS = EXPSCOM_COMP_ID | 0x04,
};
+
+ enum UserDetailsTypes
+ {
+ EXPSCOM_UDT_ACTIVE_LOG = 0x01,
+ EXPSCOM_UDT_SAVED_LOG = 0x02,
+ };
};
#endif
diff --git a/src/include/usr/expupd/expupd.H b/src/include/usr/expupd/expupd.H
new file mode 100644
index 000000000..a686d7f91
--- /dev/null
+++ b/src/include/usr/expupd/expupd.H
@@ -0,0 +1,45 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/expupd/expupd.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __EXPUPD_H
+#define __EXPUPD_H
+
+#include <isteps/hwpisteperror.H>
+
+namespace expupd
+{
+
+/**
+ * @brief Check flash image SHA512 hash value of each explorer chip
+ * and update the flash if it does not match the SHA512 hash
+ * of the image in PNOR.
+ *
+ * @param[out] o_stepError Error handle for logging istep failures
+ *
+ */
+void updateAll(ISTEP_ERROR::IStepError& o_stepError);
+
+}//namespace expupd
+
+#endif
diff --git a/src/include/usr/expupd/expupd_reasoncodes.H b/src/include/usr/expupd/expupd_reasoncodes.H
new file mode 100644
index 000000000..d5837206a
--- /dev/null
+++ b/src/include/usr/expupd/expupd_reasoncodes.H
@@ -0,0 +1,54 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/expupd/expupd_reasoncodes.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __EXPUPD_REASONCODES_H
+#define __EXPUPD_REASONCODES_H
+
+#include <hbotcompid.H>
+
+namespace EXPUPD
+{
+
+ enum ExpUpdModuleId
+ {
+ MOD_OCMB_FW_VALIDATE_IMAGE = 0x01,
+ MOD_PARSE_TAGGED_DATA_TRIPLET = 0x02,
+ };
+
+ enum ExpUpdReasonCode
+ {
+ INVALID_PARMS = EXPUPD_COMP_ID | 0x01,
+ INVALID_EYE_CATCHER = EXPUPD_COMP_ID | 0x02,
+ INVALID_HEADER_VERSION = EXPUPD_COMP_ID | 0x03,
+ INVALID_HEADER_SIZE = EXPUPD_COMP_ID | 0x04,
+ MISSING_SHA512_HASH = EXPUPD_COMP_ID | 0x05,
+ INVALID_DATA_TRIPLET_SIZE = EXPUPD_COMP_ID | 0x06,
+ INVALID_HASH_TRIPLET_SIZE = EXPUPD_COMP_ID | 0x07,
+ INVALID_TAG_ID = EXPUPD_COMP_ID | 0x08,
+ };
+
+}; // namespace EXPUPD
+
+#endif
diff --git a/src/include/usr/expupd/ocmbFwImage_const.H b/src/include/usr/expupd/ocmbFwImage_const.H
new file mode 100644
index 000000000..b97b1adcf
--- /dev/null
+++ b/src/include/usr/expupd/ocmbFwImage_const.H
@@ -0,0 +1,111 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/expupd/ocmbFwImage_const.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __OCMBFWIMAGE_CONST_H
+#define __OCMBFWIMAGE_CONST_H
+
+namespace expupd
+{
+
+// ********************************WARNING**********************************
+//
+// THIS FILE MUST BE KEPT IN SYNC WITH src/build/buildpnor/pkgOcmbFw.pl
+//
+// ********************************WARNING**********************************
+
+
+/**
+ * @brief Eyecatcher value is the ascii representation of the
+ * null terminated string, "OCMBHDR".
+ */
+constexpr uint64_t EYE_CATCHER_VALUE = 0x4F434D4248445200ULL;
+
+constexpr uint32_t MAX_BIN_TRACE = 256;
+
+/**
+ * @brief Miscellaneous constants related to the OCMB firmware header
+ */
+enum OCMBFW_HEADER_CONSTS: uint32_t
+{
+ HEADER_VERSION_MAJOR = 1,
+ HEADER_VERSION_MINOR = 0,
+ HEADER_MAX_SIZE = 4096,
+};
+
+/**
+ * @brief Header for the OCMB flash image content
+ */
+typedef struct ocmbFwHeader
+{
+ // See EYE_CATCHER_VALUE above
+ uint64_t eyeCatcher;
+
+ // The major and minor version of this header
+ uint32_t majorVersion;
+ uint32_t minorVersion;
+
+ // The total size of this header (must be 8 byte aligned)
+ uint32_t headerSize;
+
+ // The number of "tagged data triplets" included
+ // in this header. (see taggedTriplet_t)
+ uint32_t numTriplets;
+
+ // Variable sized, unordered tagged data triplets start here
+}ocmbFwHeader_t;
+
+/**
+ * @brief Tag Id's for tagged triplets
+ */
+enum TRIPLET_TAG_IDS: uint32_t
+{
+ // Data contains 64 bytes of SHA512 hash data
+ TAG_SHA512 = 1,
+
+ // Data contains a null-terminated string of comma separated
+ // key/value pairs with the following format:
+ // <key1>=<value1>,<key2>=<value2>,<key3>=<value3>
+ //
+ // Keys and values are defined by the manufacturer and must
+ // not contain the characters "=" or ","
+ TAG_KEY_VALUE_PAIRS = 2,
+};
+
+/**
+ * @brief Tagged triplet data format
+ */
+typedef struct taggedTriplet
+{
+ // Identifies the data format for this triplet
+ uint32_t tagId;
+
+ // Size of the data that follows (must be 8 byte aligned)
+ uint32_t dataSize;
+
+ // variable sized data starts here
+}taggedTriplet_t;
+
+} //namespace expupd
+
+#endif
diff --git a/src/include/usr/fapi2/attribute_service.H b/src/include/usr/fapi2/attribute_service.H
index 6144524c5..58d958f73 100644
--- a/src/include/usr/fapi2/attribute_service.H
+++ b/src/include/usr/fapi2/attribute_service.H
@@ -115,7 +115,7 @@ ReturnCode getTargetingAttr(const Target<TARGET_TYPE_ALL,
/// @param[in] o_pAttr Pointer to attribute where value is copied to
/// @return boolean describing if it was successful
///
-bool setTargetingAttrHelper(TARGETING::Target * l_pTargTarget,
+bool setTargetingAttrHelper(TARGETING::Target * i_pTargTarget,
const TARGETING::ATTRIBUTE_ID i_targAttrId,
const uint32_t i_attrSize,
void * o_pAttr);
@@ -191,6 +191,19 @@ ReturnCode platGetTargetPos(const Target<TARGET_TYPE_ALL>& i_pFapiTarget,
///
+/// @brief This function is called by the FAPI_ATTR_SET macro when accessing
+/// an attribute that should never be set. This is used to handle config-
+/// dependent cases where the attribute may need to be writable in general
+/// but not in some specific cases.
+///
+/// @param[in] i_pTargTarget Pointer to TARGETING Target
+/// @param[in] i_fapiAttrId FAPI attribute id
+/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+///
+ReturnCode platErrorOnSet( TARGETING::Target * i_pTargTarget,
+ const fapi2::AttributeId i_fapiAttrId );
+
+///
/// @brief This function is called by the FAPI_ATTR_GET macro when getting
/// ATTR_FUSED_CORE_MODE. It should not be called directly
///
@@ -500,13 +513,23 @@ ReturnCode getPllBucket(const Target<TARGET_TYPE_ALL>& i_fapiTarget,
//
// @param[in] i_fapiTarget The target for the attribute operation.
// @param[in] i_attr Which ATTR extracting from VPD
-// @param[out] o_val The retrieved attribute value.
+// @param[out] o_val The retrieved attribute value
// @return ReturnCode Zero on success, else platform specified error.
ReturnCode platGetMBvpdSlopeInterceptData(
const Target<TARGET_TYPE_ALL>& i_fapiTarget,
const uint32_t i_attr,
uint32_t& o_val);
+/// @brief This function is called by the FAPI_ATTR_GET functions that lookup
+/// values in the MEM_PLL_FREQ_BUCKETS tree. The key's used to lookup values in that
+/// tree are the ATTR_FREQ_OMI_MHZ and ATTR_OMI_PLL_VCO attributes. These are on the
+/// processor target but it is expected that all of the values match.
+/// @param[out] o_omiFreq OMI Frequency of the system
+/// @param[out] o_omiVco OMI VCO of the system
+/// @return ReturnCode Zero on success, else platform specified error.
+errlHndl_t getOmiFreqAndVco(TARGETING::ATTR_FREQ_OMI_MHZ_type & o_omiFreq,
+ TARGETING::ATTR_OMI_PLL_VCO_type & o_omiVco);
+
/// @brief This function is called by the FAPI_ATTR_GET macro when getting
// ATTR_FREQ_MCA_MHZ
// @param[in] i_fapiTarget FAPI2 Target pointer
@@ -523,6 +546,22 @@ ReturnCode platGetFreqMcaMhz(const Target<TARGET_TYPE_ALL>& i_fapiTarget,
ReturnCode platSetFreqMcaMhz(const Target<TARGET_TYPE_ALL>& i_fapiTarget,
uint32_t i_val);
+/// @brief This function is called by the FAPI_ATTR_GET macro when getting
+// ATTR_MC_PLL_BUCKET
+// @param[in] i_fapiTarget FAPI2 Target pointer
+// @param[in] o_val PLL bucket associated with a given OMI freq
+// @return ReturnCode Zero on success, else platform specified error.
+ReturnCode platGetMcPllBucket(const Target<TARGET_TYPE_ALL>& i_fapiTarget,
+ uint8_t& o_val);
+
+/// @brief This function is called by the FAPI_ATTR_SET macro when getting
+// ATTR_OCMB_COUNTER
+// @param[in] i_fapiTarget FAPI2 Target pointer
+// @param[out] o_val The retrieved attribute value
+// @return ReturnCode Zero on success, else platform specified error.
+ReturnCode platIncrementOcmbCounter(const Target<TARGET_TYPE_ALL>& i_fapiTarget,
+ uint32_t& o_val);
+
// -----------------------------------------------------------------------------
// End TODO: End to be supported functions
// -----------------------------------------------------------------------------
@@ -1666,11 +1705,51 @@ fapiToTargeting::ID, sizeof(VAL), &(VAL))
//----------------------------------------------------------------------------
// MACRO to route ATTR_FREQ_MCA_MHZ access to the correct HB function
//----------------------------------------------------------------------------
+
+#undef ATTR_FREQ_MCA_MHZ_GETMACRO
#define ATTR_FREQ_MCA_MHZ_GETMACRO(ID, TARGET, VAL) \
AttrOverrideSync::getAttrOverrideFunc(ID, TARGET, &VAL)\
? fapi2::ReturnCode() : \
fapi2::platAttrSvc::\
platGetFreqMcaMhz(TARGET, VAL)
+#undef ATTR_FREQ_MCA_MHZ_SETMACRO
+#define ATTR_FREQ_MCA_MHZ_SETMACRO(ID, TARGET, VAL) \
+ AttrOverrideSync::getAttrOverrideFunc(ID, TARGET, &VAL)\
+ ? fapi2::ReturnCode() : \
+ fapi2::platAttrSvc::platErrorOnSet(TARGET, VAL)
+#ifdef CONFIG_AXONE
+//----------------------------------------------------------------------------
+// MACRO to route ATTR_MC_PLL_BUCKET access to the correct HB function
+//----------------------------------------------------------------------------
+
+#undef ATTR_MC_PLL_BUCKET_GETMACRO
+#define ATTR_MC_PLL_BUCKET_GETMACRO(ID, TARGET, VAL) \
+ AttrOverrideSync::getAttrOverrideFunc(ID, TARGET, &VAL)\
+ ? fapi2::ReturnCode() : \
+ fapi2::platAttrSvc::\
+ platGetMcPllBucket(TARGET, VAL)
+#undef ATTR_MC_PLL_BUCKET_SETMACRO
+#define ATTR_MC_PLL_BUCKET_SETMACRO(ID, TARGET, VAL) \
+ AttrOverrideSync::getAttrOverrideFunc(ID, TARGET, &VAL)\
+ ? fapi2::ReturnCode() : \
+ fapi2::platAttrSvc::platErrorOnSet(TARGET, VAL)
+
+#endif //CONFIG_AXONE
+
+//----------------------------------------------------------------------------
+// MACRO to route ATTR_OCMB_COUNTER access to the correct HB function
+//----------------------------------------------------------------------------
+#undef ATTR_OCMB_COUNTER_GETMACRO
+#define ATTR_OCMB_COUNTER_GETMACRO(ID, TARGET, VAL) \
+ AttrOverrideSync::getAttrOverrideFunc(ID, TARGET, &VAL)\
+ ? fapi2::ReturnCode() : \
+ fapi2::platAttrSvc::\
+ platIncrementOcmbCounter(TARGET, VAL)
+#undef ATTR_OCMB_COUNTER_SETMACRO
+#define ATTR_OCMB_COUNTER_SETMACRO(ID, TARGET, VAL) \
+ AttrOverrideSync::getAttrOverrideFunc(ID, TARGET, &VAL)\
+ ? fapi2::ReturnCode() : \
+ fapi2::platAttrSvc::platErrorOnSet(TARGET, VAL)
#endif // ATTRIBUTESERVICE_H_
diff --git a/src/include/usr/fapi2/dimmBadDqBitmapFuncs.H b/src/include/usr/fapi2/dimmBadDqBitmapFuncs.H
index 5d51b7153..a51f5c92e 100644
--- a/src/include/usr/fapi2/dimmBadDqBitmapFuncs.H
+++ b/src/include/usr/fapi2/dimmBadDqBitmapFuncs.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -41,7 +41,7 @@ extern "C"
* dimmBadDqBitmapAccessHwp to get the DQ bitmap and returns the data
* for the specified rank.
*
- * @param[in] i_fapiTrgt Reference to MCA/MBA/MEM_PORT Target
+ * @param[in] i_fapiTrgt Reference to MCA/MBA/MEM_PORT/OCMB_CHIP Target
* @param[in] i_dimm MCA/MBA port DIMM number
* @param[in] i_rank DIMM rank number
* @param[out] o_data Reference to data where Bad DQ bitmap is copied to
@@ -50,8 +50,8 @@ extern "C"
* @return ReturnCode
*/
fapi2::ReturnCode p9DimmGetBadDqBitmap( const fapi2::Target
- <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|fapi2::TARGET_TYPE_MEM_PORT>
- & i_fapiTrgt,
+ <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|
+ fapi2::TARGET_TYPE_MEM_PORT|fapi2::TARGET_TYPE_OCMB_CHIP> & i_fapiTrgt,
const uint8_t i_dimm,
const uint8_t i_rank,
uint8_t (&o_data)[mss::BAD_DQ_BYTE_COUNT],
@@ -67,7 +67,7 @@ fapi2::ReturnCode p9DimmGetBadDqBitmap( const fapi2::Target
* dimmBadDqBitmapAccessHwp to get the DQ bitmap, fills in the data for the
* specified rank and calls dimmBadDqBitmapAccessHwp to set the DQ bitmap
*
- * @param[in] i_fapiTrgt Reference to MCA/MBA/MEM_PORT Target
+ * @param[in] i_fapiTrgt Reference to MCA/MBA/MEM_PORT/OCMB_CHIP Target
* @param[in] i_dimm MCA/MBA port DIMM number
* @param[in] i_rank DIMM rank number
* @param[in] i_data Reference to data where Bad DQ bitmap is copied from
@@ -76,8 +76,8 @@ fapi2::ReturnCode p9DimmGetBadDqBitmap( const fapi2::Target
* @return ReturnCode
*/
fapi2::ReturnCode p9DimmSetBadDqBitmap( const fapi2::Target
- <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|fapi2::TARGET_TYPE_MEM_PORT>
- & i_fapiTrgt,
+ <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|
+ fapi2::TARGET_TYPE_MEM_PORT|fapi2::TARGET_TYPE_OCMB_CHIP> & i_fapiTrgt,
const uint8_t i_dimm,
const uint8_t i_rank,
const uint8_t (&i_data)[mss::BAD_DQ_BYTE_COUNT],
diff --git a/src/include/usr/fapi2/fapiPlatTrace.H b/src/include/usr/fapi2/fapiPlatTrace.H
index d780832ca..94f6a20b2 100644
--- a/src/include/usr/fapi2/fapiPlatTrace.H
+++ b/src/include/usr/fapi2/fapiPlatTrace.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2016 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,7 +40,6 @@
#include <stdio.h>
#include <trace/interface.H>
-#include <config.h>
//******************************************************************************
// Trace buffer names
diff --git a/src/include/usr/fapi2/hwpf_fapi2_reasoncodes.H b/src/include/usr/fapi2/hwpf_fapi2_reasoncodes.H
index f0ae90b3a..793474322 100644
--- a/src/include/usr/fapi2/hwpf_fapi2_reasoncodes.H
+++ b/src/include/usr/fapi2/hwpf_fapi2_reasoncodes.H
@@ -68,6 +68,13 @@ namespace fapi2
MOD_FAPI2_PLAT_GET_PROC_TEST = 0x19,
MOD_FAPI2_MONITOR_FOR_FSP_MSGS = 0x1A,
MOD_FAPI2_PLAT_GET_VPD_OCMB = 0x1B,
+ MOD_FAPI2_PLAT_ERROR_ON_SET = 0x1C,
+ MOD_FAPI2_PLAT_GET_MC_PLL_BUCKET = 0x1D,
+ MOD_FAPI2_PLAT_GET_FREQ_MCA_MHZ = 0x1E,
+ MOD_GET_OMI_FREQ_AND_VCO = 0x1F,
+ MOD_FAPI2_SPD_ACCESS = 0x20,
+ MOD_FAPI2_EXPLR_IB_I2C_READ = 0x21,
+ MOD_FAPI2_EXPLR_IB_I2C_WRITE = 0x22,
};
/**
@@ -128,6 +135,8 @@ namespace fapi2
RC_SET_ATTR_NOT_VALID = FAPI2_COMP_ID | 0x3F,
RC_FAILED_TO_GET_RING_LIST = FAPI2_COMP_ID | 0x40,
RC_ATTR_OVERRIDE_DISALLOWED = FAPI2_COMP_ID | 0x41,
+ RC_UNKNOWN_OCMB_CHIP_TYPE = FAPI2_COMP_ID | 0x42,
+ RC_INVALID_BUFFER_SIZE = FAPI2_COMP_ID | 0x43,
// HWP generated errors
RC_HWP_GENERATED_ERROR = HWPF_COMP_ID | 0x0f,
@@ -137,6 +146,9 @@ namespace fapi2
// PLL_BUCKET generated errors
RC_NO_MATCHING_FREQ = HWPF_COMP_ID | 0x31,
RC_FREQ_LIST_NOT_FOUND = HWPF_COMP_ID | 0x32,
+ RC_PROC_FREQ_MISMATCH = HWPF_COMP_ID | 0x33,
+
+ RC_INVALID_SPD_DRAM_GEN = FAPI2_COMP_ID | 0x34,
};
/**
diff --git a/src/include/usr/fapi2/rowRepairsFuncs.H b/src/include/usr/fapi2/rowRepairsFuncs.H
index 373ec3319..78e00b126 100644
--- a/src/include/usr/fapi2/rowRepairsFuncs.H
+++ b/src/include/usr/fapi2/rowRepairsFuncs.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,7 +39,7 @@ extern "C"
* Row Repair Data getter procedure to get the DQ bitmap and returns the data
* for the specified rank.
*
- * @param[in] i_fapiTrgt Reference to MCA/MBA/MEM_PORT Target
+ * @param[in] i_fapiTrgt Reference to MCA/MBA/MEM_PORT/OCMB_CHIP Target
* @param[in] i_dimm MCA/MBA port DIMM number
* @param[in] i_rank DIMM rank number
* @param[out] o_data Reference to data where Row Repair Data is copied to
@@ -48,8 +48,8 @@ extern "C"
* @return ReturnCode
*/
fapi2::ReturnCode getRowRepair( const fapi2::Target
- <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|fapi2::TARGET_TYPE_MEM_PORT>
- & i_fapiTrgt,
+ <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|
+ fapi2::TARGET_TYPE_MEM_PORT|fapi2::TARGET_TYPE_OCMB_CHIP> & i_fapiTrgt,
const uint8_t i_dimm,
const uint8_t i_rank,
uint8_t (&o_data)[mss::ROW_REPAIR_BYTE_COUNT],
@@ -62,7 +62,7 @@ fapi2::ReturnCode getRowRepair( const fapi2::Target
* Row Repair Data setter procedure to set the data
* for the specified rank.
*
- * @param[in] i_fapiTrgt Reference to MCA/MBA/MEM_PORT Target
+ * @param[in] i_fapiTrgt Reference to MCA/MBA/MEM_PORT/OCMB_CHIP Target
* @param[in] i_dimm MCA/MBA port DIMM number
* @param[in] i_rank DIMM rank number
* @param[out] i_data Reference to data where Row Repair Data is
@@ -71,8 +71,8 @@ fapi2::ReturnCode getRowRepair( const fapi2::Target
* @return ReturnCode
*/
fapi2::ReturnCode setRowRepair( const fapi2::Target
- <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|fapi2::TARGET_TYPE_MEM_PORT>
- & i_fapiTrgt,
+ <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|
+ fapi2::TARGET_TYPE_MEM_PORT|fapi2::TARGET_TYPE_OCMB_CHIP> & i_fapiTrgt,
const uint8_t i_dimm,
const uint8_t i_rank,
uint8_t (&i_data)[mss::ROW_REPAIR_BYTE_COUNT],
diff --git a/src/include/usr/fapi2/target.H b/src/include/usr/fapi2/target.H
index 7b286db87..31e909a68 100644
--- a/src/include/usr/fapi2/target.H
+++ b/src/include/usr/fapi2/target.H
@@ -267,6 +267,9 @@ inline TARGETING::TYPE convertFapi2TypeToTargeting(fapi2::TargetType i_T)
case fapi2::TARGET_TYPE_MEM_PORT:
o_targetingType = TARGETING::TYPE_MEM_PORT;
break;
+ case fapi2::TARGET_TYPE_PMIC:
+ o_targetingType = TARGETING::TYPE_PMIC;
+ break;
default:
FAPI_ERR("convertFapi2TypeToTargeting:: Chiplet type not supported 0x%.8X!", i_T);
assert(false);
@@ -382,6 +385,9 @@ inline fapi2::TargetType convertTargetingTypeToFapi2(TARGETING::TYPE i_T)
case TARGETING::TYPE_MEM_PORT:
o_targetingType = fapi2::TARGET_TYPE_MEM_PORT;
break;
+ case TARGETING::TYPE_PMIC:
+ o_targetingType = fapi2::TARGET_TYPE_PMIC;
+ break;
default:
o_targetingType = fapi2::TARGET_TYPE_NONE;
break;
@@ -920,9 +926,11 @@ inline std::vector<Target<K_CHILD, M, V> >
// valid children for OCMB
// OCMB -> MEM_PORT
// OCMB -> DIMM
+ // OCMB -> PMIC
static_assert(!((T_SELF == fapi2::TARGET_TYPE_OCMB_CHIP) &&
(K_CHILD != fapi2::TARGET_TYPE_MEM_PORT) &&
- (K_CHILD != fapi2::TARGET_TYPE_DIMM)),
+ (K_CHILD != fapi2::TARGET_TYPE_DIMM) &&
+ (K_CHILD != fapi2::TARGET_TYPE_PMIC)),
"improper child of fapi2::TARGET_TYPE_OCMB_CHIP");
// valid children for MEM_PORT
diff --git a/src/include/usr/fapiwrap/fapiWrapif.H b/src/include/usr/fapiwrap/fapiWrapif.H
new file mode 100644
index 000000000..6a59e4c3f
--- /dev/null
+++ b/src/include/usr/fapiwrap/fapiWrapif.H
@@ -0,0 +1,79 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/fapiwrap/fapiWrapif.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef _FAPIWRAPIF_H
+#define _FAPIWRAPIF_H
+
+#include <errl/errlentry.H> // Also gets us targeting/common/target.H
+
+
+/* *** Overview ***
+ There has been a trend to create more HWPs that process raw data.
+ This allows Hostboot and Cronus (and other platforms to share more code.
+ The trick is that we generally want to call these HWPs inside what has
+ traditionally been Hostboot-only code. The fapiwrap directory will help
+ encapsulate all of the calls to ekb code in one place. That way if we
+ ever need to remove HWPs/EKB code it will be easier to stub out the calls.
+ We have found in the past we have contaminated a lot of Hostboot-only
+ code with calls to EKB code. This directory should help address that problem.
+*/
+
+
+namespace FAPIWRAP
+{
+ /**
+ * @brief This function wraps around the FAPI2 HWP "exp_getidec" which
+ * takes in a OCMB target and returns the associated chipId
+ * and ec level.
+ * Chip Ids can be found in src/import/chips/common/utils/chipids.H
+ * @param[in] i_ocmbChip - Explorer OCMB target to lookup values on
+ * @param[out] o_chipId - Power Chip Id associated with this OCMB
+ * @param[out] o_ec - EC level of this chip
+ * @return errlHndl_t - nullptr if no error, otherwise contains error
+ */
+ errlHndl_t explorer_getidec( TARGETING::Target * i_ocmbChip,
+ uint16_t& o_chipId,
+ uint8_t& o_ec);
+
+ /**
+ * @brief This function wraps around the FAPI2 HWP "get_pmic_i2c_addr" which
+ * takes in a DDIMM's DDR4 SPD data and a PMIC's position relative to
+ * its parent OCMB's chip and returns the device address of that pmic
+ * This wrapper will actually lookup the SPD of a given ocmb target so
+ * the caller doesnt need to worry about it.
+ * @param[in] i_ocmbChip - Parent ocmb of the PMIC we wish to find the device addres of
+ * @param[in] i_pmic_id - PMIC's position relative to parent OCMB
+ * @param[out]o_pmic_devAddr - If this pmic exists on the ocmb then return the device address
+ found in the SPD. Otherwise return NO_PMIC_DEV_ADDR
+ * @return errlHndl_t - nullptr if no error, otherwise contains error
+ */
+ errlHndl_t get_pmic_dev_addr( TARGETING::Target * i_ocmbChip,
+ const uint8_t i_pmic_id,
+ uint8_t& o_pmic_devAddr);
+
+ constexpr uint8_t NO_PMIC_DEV_ADDR = 0xFF;
+
+}
+
+#endif \ No newline at end of file
diff --git a/src/include/usr/gcov.h b/src/include/usr/gcov.h
index ede5e547b..975e755a9 100644
--- a/src/include/usr/gcov.h
+++ b/src/include/usr/gcov.h
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -39,6 +41,7 @@
#include <stddef.h>
#include <stdint.h>
#include <string.h>
+#include <arch/ppc.H>
/** @struct gcov_info
* @brief Structure generated by gcc. Do not use.
@@ -56,23 +59,111 @@
* aligned on a 64-bit boundary. The unusedN fields are to ensure proper
* alignment.
*/
+
+// Inferred settings
+#define BITS_PER_UNIT 8
+#define LONG_LONG_TYPE_SIZE 64
+
+#define _STRINGIFY(X) #X
+#define STRINGIFY(X) _STRINGIFY(X)
+
+static_assert(sizeof(long long) * 8 == LONG_LONG_TYPE_SIZE,
+ "sizeof(long long) * 8 must be LONG_LONG_TYPE_SIZE ("
+ STRINGIFY(LONG_LONG_TYPE_SIZE)
+ ")");
+
+/* The following typedefs and structures were taken from:
+ * https://github.com/gcc-mirror/gcc/blob/gcc-4_9-branch/libgcc/libgcov.h
+ */
+
+#if BITS_PER_UNIT == 8
+typedef unsigned gcov_unsigned_t __attribute__ ((mode (SI)));
+typedef unsigned gcov_position_t __attribute__ ((mode (SI)));
+#if LONG_LONG_TYPE_SIZE > 32
+typedef signed gcov_type __attribute__ ((mode (DI)));
+typedef unsigned gcov_type_unsigned __attribute__ ((mode (DI)));
+#else
+typedef signed gcov_type __attribute__ ((mode (SI)));
+typedef unsigned gcov_type_unsigned __attribute__ ((mode (SI)));
+#endif
+#else
+#if BITS_PER_UNIT == 16
+typedef unsigned gcov_unsigned_t __attribute__ ((mode (HI)));
+typedef unsigned gcov_position_t __attribute__ ((mode (HI)));
+#if LONG_LONG_TYPE_SIZE > 32
+typedef signed gcov_type __attribute__ ((mode (SI)));
+typedef unsigned gcov_type_unsigned __attribute__ ((mode (SI)));
+#else
+typedef signed gcov_type __attribute__ ((mode (HI)));
+typedef unsigned gcov_type_unsigned __attribute__ ((mode (HI)));
+#endif
+#else
+typedef unsigned gcov_unsigned_t __attribute__ ((mode (QI)));
+typedef unsigned gcov_position_t __attribute__ ((mode (QI)));
+#if LONG_LONG_TYPE_SIZE > 32
+typedef signed gcov_type __attribute__ ((mode (HI)));
+typedef unsigned gcov_type_unsigned __attribute__ ((mode (HI)));
+#else
+typedef signed gcov_type __attribute__ ((mode (QI)));
+typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
+#endif
+#endif
+#endif
+
+static_assert(sizeof(gcov_type) == 8, "gcov_type isn't 64 bits for some reason");
+
+#if __GNUC__ == 4 && __GNUC_MINOR__ == 9
+#define GCOV_COUNTERS 9
+#elif __GNUC__ == 8 && __GNUC_MINOR__ <= 3
+#define GCOV_COUNTERS 9
+#else
+#error GCOV implementation does not support this compiler yet
+#endif
+
+/* Structures embedded in coveraged program. The structures generated
+ by write_profile must match these. */
+
+/* Information about counters for a single function. */
+struct gcov_ctr_info
+{
+ gcov_unsigned_t num; /* number of counters. */
+ gcov_type *values; /* their values. */
+};
+
+/* Information about a single function. This uses the trailing array
+ idiom. The number of counters is determined from the merge pointer
+ array in gcov_info. The key is used to detect which of a set of
+ comdat functions was selected -- it points to the gcov_info object
+ of the object file containing the selected comdat function. */
+
+struct gcov_fn_info
+{
+ const struct gcov_info *key; /* comdat key */
+ gcov_unsigned_t ident; /* unique ident of function */
+ gcov_unsigned_t lineno_checksum; /* function lineno_checksum */
+ gcov_unsigned_t cfg_checksum; /* function cfg checksum */
+ struct gcov_ctr_info ctrs[0]; /* instrumented counters */
+};
+
+/* Type of function used to merge counters. */
+typedef void (*gcov_merge_fn) (gcov_type *, gcov_unsigned_t);
+
+/* Information about a single object file. */
struct gcov_info
{
- uint32_t version;
- uint32_t unused0;
- gcov_info* next;
- uint32_t timestamp;
- uint32_t unused1;
- char* filename;
- uint32_t n_functions;
- uint32_t unused2;
- void* functions;
- uint32_t counter_mask;
- uint32_t unused3;
- uint32_t n_counters;
- uint32_t unused4;
- uint64_t* counters;
-} PACKED;
+ gcov_unsigned_t version;/* expected version number */
+ struct gcov_info *next; /* link to next, used by libgcov */
+
+ gcov_unsigned_t stamp; /* uniquifying time stamp */
+ const char *filename; /* output file name */
+
+ gcov_merge_fn merge[GCOV_COUNTERS]; /* merge functions (null for
+ unused) */
+
+ unsigned n_functions; /* number of functions */
+ const struct gcov_fn_info *const *functions; /* pointer to pointers
+ to function information */
+};
// Preprocessor magic to create a variable name based off the module name.
// GCOV_INFO_OBJ() will create a post-processed name like
@@ -90,6 +181,9 @@ struct gcov_info
#define __GCOV_INFO_OBJ(X,Y) X ## Y
#define _GCOV_INFO_OBJ(X,Y) __GCOV_INFO_OBJ(X,Y)
#define GCOV_INFO_OBJ() _GCOV_INFO_OBJ(__GCOV_PREFIX, _gcov_info_head)
+#define GCOV_INFO_MAGIC() _GCOV_INFO_OBJ(__GCOV_PREFIX, _gcov_info_magic)
+
+uint32_t GCOV_INFO_MAGIC() = 0xbeefb055;
/** Pointer to the beginning of the gcov_info chain for this module. */
gcov_info* GCOV_INFO_OBJ() = NULL;
@@ -121,7 +215,7 @@ void __gcov_init(gcov_info* i_info)
//
#ifdef __HOSTBOOT_MODULE
// Forward declaration of __gcov_module_copychain for modules.
-extern "C" void __gcov_module_copychain(gcov_info* chain);
+extern "C" void __gcov_module_copychain(gcov_info** chain);
/** Function called by module unloading to move the module's gcov_info
* instances to the global chain.
@@ -129,7 +223,7 @@ extern "C" void __gcov_module_copychain(gcov_info* chain);
extern "C"
void __gcov_module_unload(void* unused)
{
- __gcov_module_copychain(GCOV_INFO_OBJ());
+ __gcov_module_copychain(&GCOV_INFO_OBJ());
}
// Register __gcov_module_unload with __cxa_atexit.
extern void* __dso_handle;
@@ -137,27 +231,93 @@ extern "C" int __cxa_atexit(void(*)(void*),void*,void*);
int __unused_gcov_cxa_register =
__cxa_atexit(&__gcov_module_unload, NULL, __dso_handle);
#else
+
+// This is set to 1 for now because it reduces memory pressure, but it
+// won't work on hardware. See the comment below about
+// MAGIC_GCOV_MODULE_UNLOAD.
+#define HOSTBOOT_GCOV_EAGER_DATA_EXTRACTION 1
+
/** Function called by a module being unloaded (via __gcov_module_unload) to
* copy the module's gcov_info chain into the base gcov_info chain.
*/
extern "C"
-void __gcov_module_copychain(gcov_info* chain)
+void __gcov_module_copychain(gcov_info** const chain_ptr)
{
+ gcov_info* chain = *chain_ptr;
+
+#if HOSTBOOT_GCOV_EAGER_DATA_EXTRACTION
+ asm volatile("mr %%r3, %0"
+ :
+ : "r" (chain)
+ : "%r3");
+
+ /* This magic instruction will cause simics to read the gcov_info
+ * pointer in r3 and use it to immediately extract this unloading
+ * module's data. We do this to reduce the max simultaneous memory
+ * pressure, otherwise we run out of memory having to preserve and
+ * store all the gcov info for all unloaded modules until the end
+ * of the run. This only works in simics, but the alternative
+ * won't work on hardware until we find other ways to reduce our
+ * memory footprint. */
+
+ MAGIC_INSTRUCTION(MAGIC_GCOV_MODULE_UNLOAD);
+#else
while(chain != NULL)
{
// Copy old info.
- gcov_info* new_info = new gcov_info();
- memcpy(new_info, chain, sizeof(gcov_info));
+ gcov_info* const new_info = new gcov_info();
+
+ memcpy(new_info, chain, sizeof(*chain));
+
+ char* const new_filename = strdup(chain->filename);
+ new_info->filename = new_filename;
- // Copy old counters.
- uint64_t* new_counters = new uint64_t[chain->n_counters]();
- memcpy(new_counters, chain->counters,
- chain->n_counters*sizeof(uint64_t));
- new_info->counters = new_counters;
+ struct gcov_fn_info** const new_functions
+ = new struct gcov_fn_info*[new_info->n_functions];
+
+ new_info->functions = new_functions;
+
+ unsigned int num_gcov_counters = 0;
+
+ for (unsigned int i = 0; i < GCOV_COUNTERS; ++i)
+ {
+ if (new_info->merge[i]) {
+ ++num_gcov_counters;
+ }
+ }
+
+ for (unsigned int i = 0; i < chain->n_functions; ++i)
+ {
+ // malloc(base structure size + trailing array size)
+ new_functions[i] =
+ ((struct gcov_fn_info*)
+ (new char[sizeof(*new_functions[i])
+ + (sizeof(new_functions[i]->ctrs[0])
+ * num_gcov_counters)]));
+
+ struct gcov_fn_info* const new_info = new_functions[i];
+ const struct gcov_fn_info* const old_info = chain->functions[i];
+
+ for (unsigned int j = 0; j < num_gcov_counters; ++j)
+ {
+ const gcov_unsigned_t num_values = old_info->ctrs[j].num;
+
+ new_info->key = NULL;
+ new_info->ctrs[j].num = num_values;
+ new_info->ctrs[j].values = new gcov_type[num_values];
+
+ memcpy(new_info->ctrs[j].values,
+ old_info->ctrs[j].values,
+ sizeof(gcov_type) * num_values);
+ }
+ }
// Atomically push new_info onto the core_gcov_info_head stack.
do
{
+ /* GCOV_INFO_OBJ() in this function is always
+ core_gcov_info_head because this function is only
+ defined when __HOSTBOOT_MODULE is not defined */
new_info->next = GCOV_INFO_OBJ();
} while (!__sync_bool_compare_and_swap(&GCOV_INFO_OBJ(),
new_info->next, new_info));
@@ -165,10 +325,16 @@ void __gcov_module_copychain(gcov_info* chain)
// Advance to next info in this modules chain.
chain = chain->next;
}
+#endif // #if HOSTBOOT_GCOV_EAGER_DATA_EXTRACTION
+
+ /* Then we set the module info pointer to NULL so that simics
+ * won't dump it twice. */
+
+ *chain_ptr = NULL;
}
#endif
-/** Unneeded function but must be defined to compile.
+/** Unneeded function but must be defined to link.
*
* This function appears to be typically used by libgcov.so when instrumented
* on a real linux-based system. It can be used to merge counters across
@@ -182,4 +348,13 @@ void __gcov_merge_add()
while(1);
}
+/** Unneeded function but must be defined to link. */
+
+extern "C"
+void __gcov_exit()
+{
+ MAGIC_INSTRUCTION(MAGIC_BREAK);
+ while (1);
+}
+
#endif
diff --git a/src/include/usr/gpio/gpioddreasoncodes.H b/src/include/usr/gpio/gpioddreasoncodes.H
index 20ad10002..d794ff470 100644
--- a/src/include/usr/gpio/gpioddreasoncodes.H
+++ b/src/include/usr/gpio/gpioddreasoncodes.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -40,10 +40,13 @@ namespace GPIO
GPIO_READ = 0x01,
GPIO_WRITE = 0x02,
GPIO_READATTRIBUTES = 0x03,
+
+ // Use 0x10-0x1F range for PCA9551 functions
+ GPIO_PCA9551_SET_LED = 0x10,
};
/**
- * @enum grioReasonCode
+ * @enum gpioReasonCode
*/
enum gpioReasonCode
{
@@ -51,6 +54,9 @@ namespace GPIO
GPIO_ATTR_INFO_NOT_FOUND = GPIO_COMP_ID | 0x01,
GPIO_I2C_TARGET_NOT_FOUND = GPIO_COMP_ID | 0x02,
GPIO_INVALID_OP = GPIO_COMP_ID | 0x03,
+
+ // Use 0x10-0x1F range for PCA9551 functions
+ GPIO_PCA9551_DATA_MISMATCH = GPIO_COMP_ID | 0x10,
};
};
diff --git a/src/include/usr/gpio/gpioif.H b/src/include/usr/gpio/gpioif.H
index 03a5a9a89..2a010039b 100644
--- a/src/include/usr/gpio/gpioif.H
+++ b/src/include/usr/gpio/gpioif.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -26,6 +26,8 @@
#ifndef __GPIOIF_H
#define __GPIOIF_H
+#include <errl/errlentry.H>
+
namespace GPIO
{
/**
@@ -33,10 +35,125 @@ namespace GPIO
*/
enum gpioDevice_t
{
- PCA95X_GPIO = 0,
+ // Corresponds to attribute ...
+ PCA95X_GPIO = 0, // GPIO_INFO
+ PCA9551_GPIO_PHYS_PRES = 1, // GPIO_INFO_PHYS_PRES
INVALID_GPIO,
};
+/* The following enums and interfaces are specific to PCA9551 GPIO Devices.
+ * Documentation here: https://www.nxp.com/docs/en/data-sheet/PCA9551.pdf
+ */
+
+/**
+ * @brief Specific to PCA9551: LED Bit Mask to match how their status is read
+ * back from LED "INPUT" register on PCA9551 Devices
+ */
+enum PCA9551_LEDS_t : uint8_t
+{
+ PCA9551_LED0 = 0x01,
+ PCA9551_LED1 = 0x02,
+ PCA9551_LED2 = 0x04,
+ PCA9551_LED3 = 0x08,
+ PCA9551_LED4 = 0x10,
+ PCA9551_LED5 = 0x20,
+ PCA9551_LED6 = 0x40,
+ PCA9551_LED7 = 0x80,
+};
+
+/**
+ * @brief Specific to PCA9551: Values used by the LED select registers
+ * to determine the source of the LED data.
+ */
+enum PCA9551_LED_Output_Settings_t : uint8_t
+{
+ PCA9551_OUTPUT_LOW = 0x00, // LED on
+ PCA9551_OUTPUT_HIGH_IMPEDANCE = 0x01, // LED off; default
+ PCA9551_OUTPUT_PWM0 = 0x02, // Output blinks at PWM0 rate
+ PCA9551_OUTPUT_PWM1 = 0x03, // Output blinks at PWM1 rate
+};
+
+/**
+ * @brief Specific to PCA9551: Control register definition:
+ sepcificies which register the operation will target
+ */
+enum PCA9551_Registers_t : uint8_t
+{
+ PCA9551_REGISTER_INPUT = 0x00, // INPUT (read only) input register
+ PCA9551_REGISTER_PCS0 = 0x01, // PSC0 (r/w) frequency prescaler 0
+ PCA9551_REGISTER_PWM0 = 0x02, // PWM0 (r/w) PWM register 0
+ PCA9551_REGISTER_PCS1 = 0x03, // PSC1 (r/w) frequency prescaler 1
+ PCA9551_REGISTER_PWM1 = 0x04, // PWM1 (r/w) PWM register 1
+ PCA9551_REGISTER_LS0 = 0x05, // LS0 (r/w) LED0 to LED3 selector
+ PCA9551_REGISTER_LS1 = 0x06, // LS1 (r/w) LED4 to LED7 selector
+};
+
+/**
+ * @brief Specific to PCA9551: Helper constants to work with the bits in the
+ * PCA9551 registers
+ */
+enum PCA9551_Constants_t : uint8_t
+{
+ // Mask shifted to apply 2-bit settings to a specific LED in the output
+ // settings register
+ PCA9551_LED_SETTINGS_MASK = 0x03,
+
+ // Amount to shift the LED value per LED when walking through the LEDs
+ // in the INPUT register (related to PCA9551_LEDS_t above)
+ PCA9551_LED_SHIFT_AMOUNT = 0x01,
+
+ // Amount to shift the LED Settings MASK per LED when walking through the
+ // LEDs in the output settings register (ie, 2 bits at a time)
+ PCA9551_LED_SETTINGS_MASK_SHIFT_AMOUNT = 0x02,
+
+ // LED Divider: While the INPUT register can contain all 8 LED values
+ // (since each value is represented by one bit), the SETTINGS registers
+ // (PCA9551_REGISTER_LS0 and PCA9551_REGISTER_LS1) can only cover 4 LEDs
+ // each since each setting requires 2 bits.
+ // This divisor takes LEDs 4 to 7 and makes them look like LEDs 0 to 3
+ PCA9551_LED_SETTINGS_DIVISOR = 0x80,
+};
+
+/**
+ * @brief Returns the PCA9551 Device's INPUT register which reflects the state
+ * of the device's LEDs (aka pins)
+ *
+ * @param[in] i_target - Target that contains ATTR_GPIO_INFO_PHYS_PRES attribute
+ * to run the commands against
+ *
+ * @param[out] o_led_data - The INPUT register data from the device
+ *
+ * @return errlHndl_t nullptr on success; non-nullptr on error.
+ */
+errlHndl_t gpioPca9551GetLeds(TARGETING::Target * i_target,
+ uint8_t & o_led_data);
+
+/**
+ * @brief Sets the given LED (aka pin) of a PCA9551 Device to a certain setting
+ * and returns the INPUT register which reflects the state of device's
+ * LEDs (aka pins) after the setting has been run
+ *
+ * @param[in] i_target - Target that contains ATTR_GPIO_INFO_PHYS_PRES attribute
+ * to run the commands against
+ *
+ * @param[in] i_led - The specific LED Target that contains ATTR_GPIO_INFO_PHYS_PRES attribute
+ * to run the commands against
+ *
+ * @param[in] i_setting - the output setting to set the LED to
+ *
+ * @param[out] o_led_data - The INPUT register data from the device after the
+ * 'set' procedure has been run allowing the caller to
+ * evaluate if the set actually went through
+ *
+ * @return errlHndl_t nullptr on success; non-nullptr on error.
+ */
+
+errlHndl_t gpioPca9551SetLed(TARGETING::Target * i_target,
+ const PCA9551_LEDS_t i_led,
+ const PCA9551_LED_Output_Settings_t i_setting,
+ uint8_t & o_led_data);
+
+
}; // GPIO NAMESPACE
#endif
diff --git a/src/include/usr/hbotcompid.H b/src/include/usr/hbotcompid.H
index e3a3ec5d7..d8d819f50 100644
--- a/src/include/usr/hbotcompid.H
+++ b/src/include/usr/hbotcompid.H
@@ -484,6 +484,38 @@ const compId_t UCD_COMP_ID = 0x4100;
const char UCD_COMP_NAME[] = "ucd";
//@}
+
+//
+/** @name EXPUPD
+ * Explorer update component
+ */
+//@{
+const compId_t EXPUPD_COMP_ID = 0x4200;
+const char EXPUPD_COMP_NAME[] = "expupd";
+
+//@}
+
+//
+/** @name BPM
+ * BPM flash update component
+ */
+//@{
+const compId_t BPM_COMP_ID = 0x4300;
+const char BPM_COMP_NAME[] = "bpm";
+
+//@}
+
+//
+/** @name FAPIWRAP
+ * Wrapper around fapi2 HWP for hb platform to use
+ */
+//@{
+const compId_t FAPIWRAP_COMP_ID = 0x4400;
+const char FAPIWRAP_COMP_NAME[] = "fapiwrap";
+
+//@}
+
+//
//
/** @name HDAT
* HDAT component
diff --git a/src/include/usr/hwas/common/hwasCallout.H b/src/include/usr/hwas/common/hwasCallout.H
index a39e4a229..3cf4a2638 100644
--- a/src/include/usr/hwas/common/hwasCallout.H
+++ b/src/include/usr/hwas/common/hwasCallout.H
@@ -180,13 +180,17 @@ enum callOutPriority
enum busTypeEnum
{
+ NO_BUS_TYPE = 0,
FSI_BUS_TYPE = 1,
DMI_BUS_TYPE = 2,
A_BUS_TYPE = 3,
X_BUS_TYPE = 4,
I2C_BUS_TYPE = 5,
PSI_BUS_TYPE = 6,
- O_BUS_TYPE = 7
+ O_BUS_TYPE = 7,
+ OMI_BUS_TYPE = 8,
+
+ LAST_BUS_TYPE, //for looping in testcases
};
// Used by Hostboot code where real clock targets do not exist
@@ -226,6 +230,8 @@ enum partTypeEnum
BPM_CABLE_PART_TYPE = 13, //Backup Power Module Cable for NVDIMM
NV_CONTROLLER_PART_TYPE = 14, //Controller for NVDIMM
BPM_PART_TYPE = 15, //Backup Power Module for NVDIMM
+
+ LAST_PART_TYPE, //for looping in testcases
};
enum sensorTypeEnum
@@ -234,6 +240,8 @@ enum sensorTypeEnum
GPU_FUNC_SENSOR = 1,
GPU_TEMPERATURE_SENSOR = 2,
GPU_MEMORY_TEMP_SENSOR = 3,
+
+ LAST_SENSOR_TYPE, //for looping in testcases
};
//-- Flags
diff --git a/src/include/usr/hwas/common/hwas_reasoncodes.H b/src/include/usr/hwas/common/hwas_reasoncodes.H
index b60e10032..f2d4e0da0 100644
--- a/src/include/usr/hwas/common/hwas_reasoncodes.H
+++ b/src/include/usr/hwas/common/hwas_reasoncodes.H
@@ -42,6 +42,10 @@ namespace HWAS
MOD_DISCOVER_TARGETS = 0x0B,
MOD_UPDATE_PROC_COMPAT_RISK_LEVEL = 0x0C,
MOD_CHECK_PG_FOR_DESC = 0x0D,
+ MOD_OCMB_IDEC = 0x0E,
+ MOD_OCMB_IDEC_PHASE_1 = 0x0F,
+ MOD_OCMB_IDEC_PHASE_2 = 0x10,
+ MOD_OCMB_TRANSLATE_SPD_IDEC = 0x11,
};
enum HwasReasonCode
@@ -80,6 +84,11 @@ namespace HWAS
RC_FORCED_NATIVE_INVALID_MIXED_EC = HWAS_COMP_ID | 0x1C,
RC_FORCED_NATIVE_OF_INCOMPATIBLE_RISK = HWAS_COMP_ID | 0x1D,
RC_PARTIAL_GOOD_MISSING_TARGET = HWAS_COMP_ID | 0x1E,
+ RC_OCMB_SPD_REVISION_MISMATCH = HWAS_COMP_ID | 0x1F,
+ RC_OCMB_UNEXPECTED_IDEC = HWAS_COMP_ID | 0x20,
+ RC_OCMB_UNKNOWN_CHIP_TYPE = HWAS_COMP_ID | 0x21,
+ RC_OCMB_INTERFACE_TYPE_MISMATCH = HWAS_COMP_ID | 0x22,
+ RC_OCMB_CHIP_ID_MISMATCH = HWAS_COMP_ID | 0x23,
};
enum HwasPlatUserDetailsTypes
diff --git a/src/include/usr/hwas/common/pgLogic.H b/src/include/usr/hwas/common/pgLogic.H
index 66e59f5f0..12eac2f49 100644
--- a/src/include/usr/hwas/common/pgLogic.H
+++ b/src/include/usr/hwas/common/pgLogic.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -129,6 +129,7 @@ namespace PARTIAL_GOOD
// MC
// PG/AG Masks
extern const uint16_t MC_R1_AG_MASK;
+ extern const uint16_t MC_R1_AG_MASK_AXONE;
extern const uint16_t MC_R2_PG_MASK;
extern const uint16_t MC_R3_PG_MASK;
@@ -533,17 +534,27 @@ namespace PARTIAL_GOOD
},
{ TARGETING::TYPE_MC,
{
- // MC Rule 1
+ // MC Rule 1 (Cumulus)
new PartialGoodRule
(
- {&PREDICATE_CUMULUS, &PREDICATE_AXONE},
+ {&PREDICATE_CUMULUS},
ALL_ON_PG_MASK,
MC_R1_AG_MASK,
USE_CHIPLET_ID,
APPLICABLE_TO_ALL,
NO_SPECIAL_RULE
),
- // MC Rule 2: Chiplet N1 must be checked for chip unit 1
+ // MC Rule 1 (Axone)
+ new PartialGoodRule
+ (
+ {&PREDICATE_AXONE},
+ ALL_ON_PG_MASK,
+ MC_R1_AG_MASK_AXONE,
+ USE_CHIPLET_ID,
+ APPLICABLE_TO_ALL,
+ NO_SPECIAL_RULE
+ ),
+ // MC Rule 2: Chiplet N1 must be checked for chip unit 1 (Axone & Cumulus)
new PartialGoodRule
(
{&PREDICATE_CUMULUS, &PREDICATE_AXONE},
@@ -553,7 +564,7 @@ namespace PARTIAL_GOOD
ONE_BIT_CU_MASK,
NO_SPECIAL_RULE
),
- // MC Rule 3: Chiplet N3 must be checked for chip unit 0
+ // MC Rule 3: Chiplet N3 must be checked for chip unit 0 (Axone & Cumulus)
new PartialGoodRule
(
{&PREDICATE_CUMULUS, &PREDICATE_AXONE},
@@ -670,6 +681,17 @@ namespace PARTIAL_GOOD
APPLICABLE_TO_ALL,
NO_SPECIAL_RULE
),
+ // @todo-RTC:208518 - Add Axone NPU PG rules
+ // NPU Rule 2: This logic is for Axone only.
+ new PartialGoodRule
+ (
+ {&PREDICATE_AXONE},
+ NPU_R1_PG_MASK, //wrong
+ ALL_OFF_AG_MASK,
+ USE_CHIPLET_ID,
+ APPLICABLE_TO_ALL,
+ NO_SPECIAL_RULE
+ ),
}// End of PG Rules for NPU Target
},
{ TARGETING::TYPE_OBUS,
@@ -724,13 +746,24 @@ namespace PARTIAL_GOOD
// here.
new PartialGoodRule
(
- PREDICATE_P9,
+ {&PREDICATE_NIMBUS, &PREDICATE_CUMULUS},
MASK_NA,
MASK_NA,
INDEX_NA,
APPLICABLE_TO_ALL,
ObusBrickSpecialRule
),
+ // Axone will have some special rules related to the NPUs
+ // @todo-RTC:208518 - Add Axone OBUS_BRICK PG rules
+ new PartialGoodRule
+ (
+ {&PREDICATE_AXONE},
+ MASK_NA,
+ MASK_NA,
+ INDEX_NA,
+ APPLICABLE_TO_ALL,
+ NO_SPECIAL_RULE
+ ),
}// End of PG Rules for OBUS BRICK Target
},
{ TARGETING::TYPE_OMI, {new PartialGoodRule(),}},
diff --git a/src/include/usr/hwas/common/vpdConstants.H b/src/include/usr/hwas/common/vpdConstants.H
index 498f6d622..9461550e9 100644
--- a/src/include/usr/hwas/common/vpdConstants.H
+++ b/src/include/usr/hwas/common/vpdConstants.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -45,38 +45,43 @@ const uint32_t VPD_CP00_PG_DATA_ENTRIES = VPD_CP00_PG_DATA_LENGTH / 2;
// '0' = region is good (NOTE: opposite of P8 where '1' represented good)
// '1' = region is bad or does not exist
-const uint32_t VPD_CP00_PG_FSI_INDEX = 0;
+const uint32_t VPD_CP00_PG_FSI_INDEX = 0;
// all good - 4:FSI0, 5:FSI1, 6:FSIa
-const uint32_t VPD_CP00_PG_FSI_GOOD = 0xF1FF;
+const uint32_t VPD_CP00_PG_FSI_GOOD = 0xF1FF;
-const uint32_t VPD_CP00_PG_PERVASIVE_INDEX = 1;
+const uint32_t VPD_CP00_PG_PERVASIVE_INDEX = 1;
// all good - 3:VITAL, 4:PRV, 5:NET, 6:PIB, 7:OCC, 8:ANPERV, 14:PLLNEST
-const uint32_t VPD_CP00_PG_PERVASIVE_GOOD = 0xE07D;
+const uint32_t VPD_CP00_PG_PERVASIVE_GOOD = 0xE07D;
+// all good - 3:VITAL, 4:PRV, 5:NET, 6:PIB, 7:OCC, 8:BE, 9:SBE 14:PLLNEST
+const uint32_t VPD_CP00_PG_PERVASIVE_GOOD_AXONE = 0xE03D;
-const uint32_t VPD_CP00_PG_N0_INDEX = 2;
+const uint32_t VPD_CP00_PG_N0_INDEX = 2;
// all good - 3:VITAL, 4:PRV, 5:NX, 6:CXA0, 7:PBIOE0, 8:PBIOE1, 9:PBIOE2
-const uint32_t VPD_CP00_PG_N0_GOOD = 0xE03F;
+const uint32_t VPD_CP00_PG_N0_GOOD = 0xE03F;
-const uint32_t VPD_CP00_PG_N1_INDEX = 3;
+const uint32_t VPD_CP00_PG_N1_INDEX = 3;
// all good - 3:VITAL, 4:PRV, 5:MCD, 6:VA, 7:PBIOO0+, 8:PBIOO1+, 9:MCS23+
-const uint32_t VPD_CP00_PG_N1_GOOD = 0xE03F;
-const uint32_t VPD_CP00_PG_N1_PG_MASK = 0x01C0;
-const uint32_t VPD_CP00_PG_N1_PBIOO0 = 0x0100;
-const uint32_t VPD_CP00_PG_N1_PBIOO1 = 0x0080;
-const uint32_t VPD_CP00_PG_N1_MCS23 = 0x0040;
+const uint32_t VPD_CP00_PG_N1_GOOD = 0xE03F;
+const uint32_t VPD_CP00_PG_N1_PG_MASK = 0x01C0;
+const uint32_t VPD_CP00_PG_N1_PBIOO0 = 0x0100;
+const uint32_t VPD_CP00_PG_N1_PBIOO1 = 0x0080;
+const uint32_t VPD_CP00_PG_N1_MCS23 = 0x0040;
-const uint32_t VPD_CP00_PG_N2_INDEX = 4;
+const uint32_t VPD_CP00_PG_N2_INDEX = 4;
// all good - 3:VITAL, 4:PRV, 5:CXA1, 6:PCIS0, 7:PCIS1, 8:PCIS2, 9:IOPSI
-const uint32_t VPD_CP00_PG_N2_GOOD = 0xE03F;
+const uint32_t VPD_CP00_PG_N2_GOOD = 0xE03F;
+// all good - 3:VITAL, 4:PRV, 6:PCIS0, 7:PCIS1, 8:PCIS2, 9:IOPSI
+const uint32_t VPD_CP00_PG_N2_GOOD_AXONE = 0xE43F;
-const uint32_t VPD_CP00_PG_N3_INDEX = 5;
+
+const uint32_t VPD_CP00_PG_N3_INDEX = 5;
// all good - 3:VITAL, 4:PRV, 5:PB, 6:BR, 7:NPU+, 8:MM, 9:INT, 10:MCS01+
-const uint32_t VPD_CP00_PG_N3_GOOD = 0xE01F;
-const uint32_t VPD_CP00_PG_N3_PG_MASK = 0x0120;
-const uint32_t VPD_CP00_PG_N3_NPU = 0x0100;
-const uint32_t VPD_CP00_PG_N3_MCS01 = 0x0020;
+const uint32_t VPD_CP00_PG_N3_GOOD = 0xE01F;
+const uint32_t VPD_CP00_PG_N3_PG_MASK = 0x0120;
+const uint32_t VPD_CP00_PG_N3_NPU = 0x0100;
+const uint32_t VPD_CP00_PG_N3_MCS01 = 0x0020;
-const uint32_t VPD_CP00_PG_XBUS_INDEX = 6;
+const uint32_t VPD_CP00_PG_XBUS_INDEX = 6;
// all good - 3:VITAL, 4:PRV, 5:IOX0*, 6:IOX1, 7:IOX2, 8:IOPPE
// 9:PBIOX0*+, 10:PBIOX1+, 11:PBIOX2+, 14:PLLIOX
// Nimbus doesn't physically have PBIOX0 and IOX0. IOX0 is
@@ -92,14 +97,14 @@ const uint32_t VPD_CP00_PG_XBUS_INDEX = 6;
// 0xE40D --> xbus chiplet good
// and rely solely on the pbiox as the Xbus target indicator
// (0x0040, 0x0020, 0x0010) for all types of chips.
-const uint32_t VPD_CP00_PG_XBUS_GOOD_NIMBUS = 0xE40D;
-const uint32_t VPD_CP00_PG_XBUS_GOOD_CUMULUS= 0xE00D;
-const uint32_t VPD_CP00_PG_XBUS_PG_MASK = 0x00170;
-const uint32_t VPD_CP00_PG_XBUS_IOX[3] = {0x0040, 0x0020, 0x0010};
-
-const uint32_t VPD_CP00_PG_MC01_INDEX = 7;
-const uint32_t VPD_CP00_PG_MC23_INDEX = 8;
-const uint32_t VPD_CP00_PG_MCxx_INDEX[4] = {VPD_CP00_PG_MC01_INDEX,
+const uint32_t VPD_CP00_PG_XBUS_GOOD_NIMBUS = 0xE40D;
+const uint32_t VPD_CP00_PG_XBUS_GOOD_CUMULUS = 0xE00D;
+const uint32_t VPD_CP00_PG_XBUS_PG_MASK = 0x00170;
+const uint32_t VPD_CP00_PG_XBUS_IOX[3] = {0x0040, 0x0020, 0x0010};
+
+const uint32_t VPD_CP00_PG_MC01_INDEX = 7;
+const uint32_t VPD_CP00_PG_MC23_INDEX = 8;
+const uint32_t VPD_CP00_PG_MCxx_INDEX[4] = {VPD_CP00_PG_MC01_INDEX,
VPD_CP00_PG_MC01_INDEX,
VPD_CP00_PG_MC23_INDEX,
VPD_CP00_PG_MC23_INDEX}; // by MCS
@@ -109,56 +114,60 @@ const uint32_t VPD_CP00_PG_MCxx_INDEX[4] = {VPD_CP00_PG_MC01_INDEX,
// Cumulus:
// all good - 3:VITAL, 4:PRV, 5:MC01, 6:IOM01, 7:IOM01PPE, 14:PLLMEM
// all good - 3:VITAL, 4:PRV, 5:MC23, 6:IOM23, 7:IOM23PPE, 14:PLLMEM
-const uint32_t VPD_CP00_PG_MCxx_GOOD = 0xE0FD;
-const uint32_t VPD_CP00_PG_MCxx_PG_MASK = 0x0300; // Nimbus only
+// Axone:
+// all good - 3:VITAL, 4:PRV, 5:MC01, 6:OMI00, 7:OMI01, 8:OMI002 9:OMIPPE00 14:PLLOMI00
+// all good - 3:VITAL, 4:PRV, 5:MC23, 6:OMI10, 7:OMI11, 8:OMI012 9:OMIPPE10 14:PLLOMI10
+const uint32_t VPD_CP00_PG_MCxx_GOOD = 0xE0FD;
+const uint32_t VPD_CP00_PG_MCxx_GOOD_AXONE = 0xE03D;
+const uint32_t VPD_CP00_PG_MCxx_PG_MASK = 0x0300; // Nimbus only
// iom0 and iom4 need to be good for zqcal to work on any
// of the MCAs on that side
-const uint32_t VPD_CP00_PG_MCA_MAGIC_PORT_MASK = 0x0200;
-const uint32_t VPD_CP00_PG_MCxx_IOMyy[4] = {0x0200, 0x0100, 0x0200, 0x0100};
+const uint32_t VPD_CP00_PG_MCA_MAGIC_PORT_MASK = 0x0200;
+const uint32_t VPD_CP00_PG_MCxx_IOMyy[4] = {0x0200, 0x0100, 0x0200, 0x0100};
-const uint32_t VPD_CP00_PG_OB0_INDEX = 9;
-const uint32_t VPD_CP00_PG_OB3_INDEX = 12;
+const uint32_t VPD_CP00_PG_OB0_INDEX = 9;
+const uint32_t VPD_CP00_PG_OB3_INDEX = 12;
// all good - 3:VITAL, 4:PRV, 5:PLIOOAx, 6:IOOx, 14:PLLIOO; x=0, 1*, 2*, 3
-const uint32_t VPD_CP00_PG_OBUS_GOOD = 0xE1FD;
+const uint32_t VPD_CP00_PG_OBUS_GOOD = 0xE1FD;
-const uint32_t VPD_CP00_PG_PCI0_INDEX = 13;
+const uint32_t VPD_CP00_PG_PCI0_INDEX = 13;
// all good - 3:VITAL, 4:PRV, 5:PCI00, 6:IOPCI0, 14:PLLPCI0
// all good - 3:VITAL, 4:PRV, 5:PCI11, 6:PCI12, 7:IOPCI1, 14:PLLPCI1
// all good - 3:VITAL, 4:PRV, 5:PCI23, 6:PCI24, 7:PCI25, 8:IOPCI2, 14:PLLPCI2
-const uint32_t VPD_CP00_PG_PCIx_GOOD[3] = {0xE1FD, 0xE0FD, 0xE07D};
+const uint32_t VPD_CP00_PG_PCIx_GOOD[3] = {0xE1FD, 0xE0FD, 0xE07D};
-const uint32_t VPD_CP00_PG_EP0_INDEX = 16;
-const uint32_t VPD_CP00_PG_EP5_INDEX = 21;
+const uint32_t VPD_CP00_PG_EP0_INDEX = 16;
+const uint32_t VPD_CP00_PG_EP5_INDEX = 21;
// all good - 3:VITAL, 4:PRV, 5:EQPB, 6:L30+, 7:L31+,
// 8:L20+, 9:L21+, 10:AN, 11:PBLEQ, 12:REFR0, 13:REFR1, 14:DPLL
-const uint32_t VPD_CP00_PG_EPx_GOOD = 0xE001;
-const uint32_t VPD_CP00_PG_EPx_PG_MASK = 0x03CC;
-const uint32_t VPD_CP00_PG_EPx_L3L2REFR[2] = {0x0288, 0x0144};
+const uint32_t VPD_CP00_PG_EPx_GOOD = 0xE001;
+const uint32_t VPD_CP00_PG_EPx_PG_MASK = 0x03CC;
+const uint32_t VPD_CP00_PG_EPx_L3L2REFR[2] = {0x0288, 0x0144};
-const uint32_t VPD_CP00_PG_EC00_INDEX = 32;
+const uint32_t VPD_CP00_PG_EC00_INDEX = 32;
// all good - 3:VITAL, 4:PRV, 5:C00, 6:C01
-const uint32_t VPD_CP00_PG_ECxx_GOOD = 0xE1FF;
-const uint32_t VPD_CP00_PG_ECxx_MAX_ENTRIES = 24;
+const uint32_t VPD_CP00_PG_ECxx_GOOD = 0xE1FF;
+const uint32_t VPD_CP00_PG_ECxx_MAX_ENTRIES = 24;
-const uint32_t VPD_CP00_PG_MAX_USED_INDEX = 55;
-const uint32_t VPD_CP00_PG_xxx_VITAL = 0x1000;
-const uint32_t VPD_CP00_PG_xxx_PERV = 0x0800;
-const uint32_t VPD_CP00_PG_RESERVED_GOOD = 0xFFFF;
+const uint32_t VPD_CP00_PG_MAX_USED_INDEX = 55;
+const uint32_t VPD_CP00_PG_xxx_VITAL = 0x1000;
+const uint32_t VPD_CP00_PG_xxx_PERV = 0x0800;
+const uint32_t VPD_CP00_PG_RESERVED_GOOD = 0xFFFF;
// constants the platReadPR will use for looking at the VPD data
-const uint32_t VPD_VINI_PR_DATA_LENGTH = 8; //@deprecrated
+const uint32_t VPD_VINI_PR_DATA_LENGTH = 8; //@deprecrated
// constants the platReadLx will use for looking at the VPD data
-const uint32_t VPD_CRP0_LX_HDR_DATA_LENGTH = 256;
+const uint32_t VPD_CRP0_LX_HDR_DATA_LENGTH = 256;
-const uint32_t VPD_CRP0_LX_FREQ_INDEP_INDEX = 8;
-const uint32_t VPD_CRP0_LX_PORT_DISABLED = 0;
+const uint32_t VPD_CRP0_LX_FREQ_INDEP_INDEX = 8;
+const uint32_t VPD_CRP0_LX_PORT_DISABLED = 0;
-const uint8_t VPD_CRP0_LX_MIN_X = 1;
-const uint8_t VPD_CRP0_LX_MAX_X = 8;
+const uint8_t VPD_CRP0_LX_MIN_X = 1;
+const uint8_t VPD_CRP0_LX_MAX_X = 8;
// constants for the error log parser for partial good issues
-const uint8_t MODEL_PG_DATA_ENTRIES = 2;
+const uint8_t MODEL_PG_DATA_ENTRIES = 2;
}
diff --git a/src/include/usr/hwas/hwasPlat.H b/src/include/usr/hwas/hwasPlat.H
index 8ccddd588..fa07c72c8 100644
--- a/src/include/usr/hwas/hwasPlat.H
+++ b/src/include/usr/hwas/hwasPlat.H
@@ -25,7 +25,6 @@
#ifndef __HWAS_PLAT_H
#define __HWAS_PLAT_H
-#include <config.h>
/**
* @file hwas/hwasPlat.H
diff --git a/src/include/usr/i2c/eeprom_const.H b/src/include/usr/i2c/eeprom_const.H
index e9e157757..275388450 100644
--- a/src/include/usr/i2c/eeprom_const.H
+++ b/src/include/usr/i2c/eeprom_const.H
@@ -108,7 +108,7 @@ enum EECACHE_VERSION
*
* uniqueRecord is useful if you want to quickly compare the "unique"
* bits of a header entry which includes the target_huid, port, engine,
-* devAddr, mux_huid, and mux_select.
+* devAddr, mux_huid, and mux_select, and size
*
*/
union eepromRecordHeader
@@ -124,7 +124,10 @@ union eepromRecordHeader
uint32_t cache_copy_size; // Size of data saved in cache (in KB)
uint32_t internal_offset; // offset from start of EECACHE section where cached
// data exists
- uint8_t cached_copy_valid; // if == 0 , cached data is invalid
+ uint8_t cached_copy_valid : 1, // This bit is set when we think the contents of the
+ // cache is valid.
+ unused : 7;
+
} PACKED completeRecord;
struct uniqueRecord
@@ -167,9 +170,9 @@ struct eecacheSectionHeader
*/
struct eeprom_addr_t
{
- uint64_t port;
- uint64_t engine;
- uint64_t devAddr;
+ uint8_t port;
+ uint8_t engine;
+ uint8_t devAddr;
int64_t eepromRole;
uint64_t offset;
eeprom_addr_size_t addrSize;
@@ -235,5 +238,30 @@ struct EepromInfo_t
}
};
+/**
+ * @brief Define a set of information that describes the
+ different virtual addresses associated with a given
+ cache entry along with a byte telling us if there has been
+ an update detected on the eeprom this boot
+ */
+struct EeepromEntryMetaData_t
+{
+ uint64_t header_entry_address;
+ uint64_t cache_entry_address;
+ uint8_t mark_target_changed; // This byte is set after we detect a target has changed.
+ // Either removed, replaced, or added we don't care. But
+ // we need to use this bits so future targets associated
+ // with this eeprom can know they need to notify HWAS that
+ // they have been changed. This bit should get cleared after
+ // all eeproms have been cached.
+
+ EeepromEntryMetaData_t()
+ : header_entry_address(0),
+ cache_entry_address(0),
+ mark_target_changed(0)
+ {
+ }
+};
+
}
#endif \ No newline at end of file
diff --git a/src/include/usr/i2c/eepromddreasoncodes.H b/src/include/usr/i2c/eepromddreasoncodes.H
index a2c7b1c83..41de06dfa 100644
--- a/src/include/usr/i2c/eepromddreasoncodes.H
+++ b/src/include/usr/i2c/eepromddreasoncodes.H
@@ -57,6 +57,9 @@ enum eepromModuleId
EEPROM_CACHE_EEPROM = 0x07,
EEPROM_CLEAR_EECACHE = 0x08,
EEPROM_CACHE_PERFORM_OP = 0x09,
+ EEPROM_INVALIDATE_CACHE = 0x0A,
+ EEPROM_RESOLVE_SOURCE = 0x0B,
+ EEPROM_CACHE_INIT_RT = 0x0C,
};
/**
@@ -87,6 +90,14 @@ enum eepromReasonCode
EEPROM_NEW_DEVICE_DETECTED = EEPROM_COMP_ID | 0x0E, // While looking up a part, found that current EEPROM size does not
// match what we have seen in previous IPLs indicating a new part has
// been installed on the system.
+ EEPROM_CACHE_NOT_FOUND_IN_MAP = EEPROM_COMP_ID | 0x0F, // An entry we thought would be in the global map that keeps track of
+ // what eeproms have been cached was not found
+ EEPROM_CACHE_NOT_FOUND_IN_PNOR = EEPROM_COMP_ID | 0x10, // An entry we thought would be in the the EECACHE section of PNOR seems
+ // to be missing
+ EEPROM_CACHE_NO_VPD_IN_RSV_MEM = EEPROM_COMP_ID | 0x11, // When looking up the VPD section in reserved memory no entry was found.
+ EEPROM_DUPLICATE_CACHE_ENTRY = EEPROM_COMP_ID | 0x12 // While parsing eecache found in reserved memory we found at least two
+ // cache entries that had identical "unique" identifiers
+ // (see structs defined in eeprom_const.H)
};
enum UserDetailsTypes
diff --git a/src/include/usr/i2c/tpmddif.H b/src/include/usr/i2c/tpmddif.H
index 0f57e4797..2a0c964c5 100644
--- a/src/include/usr/i2c/tpmddif.H
+++ b/src/include/usr/i2c/tpmddif.H
@@ -65,7 +65,8 @@ enum tpm_locality_t
/**
* @brief TPM Models that are supported
*
- * @note Must stay in sync with TPM_MODEL in attribute_types_hb.xml
+ * @note Must stay in sync with TPM_MODEL in attribute_types_hb.xml and
+ * the attribute usage in processMrw.pl.
* @note Not using Attribute Enums since FSP does not currently support
* overriding enum values
*/
diff --git a/src/include/usr/initservice/mboxRegs.H b/src/include/usr/initservice/mboxRegs.H
index 889f2126b..ce43a4d52 100644
--- a/src/include/usr/initservice/mboxRegs.H
+++ b/src/include/usr/initservice/mboxRegs.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -157,10 +157,12 @@ namespace SPLESS
struct
{
uint32_t procMemToUse :7; //0:6
- uint32_t reserved1 :23; //7:22
+ uint32_t reserved1 :9; //7:15
+ uint32_t smfConfig :1; //16
+ uint32_t reserved2 :6; //17:22
uint32_t groupPumpMode :1; //23
uint32_t isSlave :1; //24
- uint32_t reserved2 :1; //25
+ uint32_t reserved3 :1; //25
uint32_t groupId :3; //26:28
uint32_t chipId :3; //29:31
} PACKED;
diff --git a/src/include/usr/ipmi/ipmi_reasoncodes.H b/src/include/usr/ipmi/ipmi_reasoncodes.H
index 65d8e64d3..6bb7e4b4b 100644
--- a/src/include/usr/ipmi/ipmi_reasoncodes.H
+++ b/src/include/usr/ipmi/ipmi_reasoncodes.H
@@ -5,9 +5,10 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2017 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
+/* [+] Maxim Polyakov */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -64,6 +65,7 @@ namespace IPMI
RC_INVALID_VPD_DATA = IPMI_COMP_ID | 0x0e,
RC_INVALID_SENSOR_NUMBER = IPMI_COMP_ID | 0x0f,
RC_INVALID_SENSOR_SETTING = IPMI_COMP_ID | 0x10,
+ RC_GET_DCMI_CAP_CMD_FAILED = IPMI_COMP_ID | 0x11,
};
};
diff --git a/src/include/usr/ipmi/ipmiif.H b/src/include/usr/ipmi/ipmiif.H
index 0421aaef3..68adfa392 100644
--- a/src/include/usr/ipmi/ipmiif.H
+++ b/src/include/usr/ipmi/ipmiif.H
@@ -5,9 +5,10 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
+/* [+] Maxim Polyakov */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -304,7 +305,10 @@ namespace IPMI
inline const command_t hiomap_event(void)
{ return std::make_pair(NETFUN_IBM, 0x0f); }
- // $TODO RTC:123256 - need to add code to get dcmi capabilities
+ // Used to get dcmi capabilities
+ inline const command_t get_dcmi_capability_info(void)
+ { return std::make_pair(NETFUN_GRPEXT, 0x01); }
+
// This is a dcmi message used to request the
// user defined power limit from the BMC.
inline const command_t get_power_limit(void)
diff --git a/src/include/usr/isteps/istep07list.H b/src/include/usr/isteps/istep07list.H
index 4b1feb1b6..2fb8eb49f 100644
--- a/src/include/usr/isteps/istep07list.H
+++ b/src/include/usr/isteps/istep07list.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -170,7 +170,6 @@ const DepModInfo g_istep07Dependancies = {
#ifndef CONFIG_FSP_BUILD
DEP_LIB(libnvram.so),
#endif
- DEP_LIB(libsmf.so),
NULL
}
};
diff --git a/src/include/usr/isteps/istep08list.H b/src/include/usr/isteps/istep08list.H
index 6ee38287c..5820907f9 100644
--- a/src/include/usr/isteps/istep08list.H
+++ b/src/include/usr/isteps/istep08list.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -267,6 +267,9 @@ const DepModInfo g_istep08Dependancies = {
DEP_LIB(libisteps_nest.so),
DEP_LIB(libsbe.so),
DEP_LIB(libimageprocs.so),
+#ifdef CONFIG_AXONE
+ DEP_LIB(libisteps_mss.so),
+#endif
NULL
}
};
diff --git a/src/include/usr/isteps/istep09list.H b/src/include/usr/isteps/istep09list.H
index 4adcc0810..d52d29d30 100644
--- a/src/include/usr/isteps/istep09list.H
+++ b/src/include/usr/isteps/istep09list.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -58,7 +58,6 @@
#include <initservice/initsvcreasoncodes.H>
// include prototypes file
-#include <config.h>
namespace ISTEP_09
{
diff --git a/src/include/usr/isteps/istep10list.H b/src/include/usr/isteps/istep10list.H
index 642fcd0ee..e6aceef33 100644
--- a/src/include/usr/isteps/istep10list.H
+++ b/src/include/usr/isteps/istep10list.H
@@ -68,7 +68,6 @@
#include <initservice/initsvcreasoncodes.H>
// include prototypes file
-#include <config.h>
namespace ISTEP_10
{
diff --git a/src/include/usr/isteps/istep11list.H b/src/include/usr/isteps/istep11list.H
index b00f92e60..40c31d9d3 100644
--- a/src/include/usr/isteps/istep11list.H
+++ b/src/include/usr/isteps/istep11list.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -74,7 +74,6 @@
#include <initservice/initsvcreasoncodes.H>
// include prototypes file
-#include <config.h>
namespace ISTEP_11
{
diff --git a/src/include/usr/isteps/istep12list.H b/src/include/usr/isteps/istep12list.H
index 2fadd6fee..e002e48db 100644
--- a/src/include/usr/isteps/istep12list.H
+++ b/src/include/usr/isteps/istep12list.H
@@ -69,7 +69,6 @@
// include prototypes file
-#include <config.h>
namespace ISTEP_12
{
@@ -290,6 +289,7 @@ const DepModInfo g_istep12Dependancies = {
DEP_LIB(libnestmemutils.so),
DEP_LIB(libisteps_io.so),
DEP_LIB(libisteps_mss.so),
+ DEP_LIB(libexpupd.so),
NULL
}
};
diff --git a/src/include/usr/isteps/istep13list.H b/src/include/usr/isteps/istep13list.H
index 5a00e9537..89041eae0 100644
--- a/src/include/usr/isteps/istep13list.H
+++ b/src/include/usr/isteps/istep13list.H
@@ -69,7 +69,6 @@
#include <initservice/initsvcreasoncodes.H>
// include prototypes file
-#include <config.h>
namespace ISTEP_13
{
@@ -296,6 +295,7 @@ const DepModInfo g_istep13Dependancies = {
DEP_LIB(libistep13.so),
DEP_LIB(libisteps_mss.so),
DEP_LIB(libcen.so),
+ DEP_LIB(libnestmemutils.so),
NULL
}
};
diff --git a/src/include/usr/isteps/istep14list.H b/src/include/usr/isteps/istep14list.H
index ac358f7b8..f335a35b5 100644
--- a/src/include/usr/isteps/istep14list.H
+++ b/src/include/usr/isteps/istep14list.H
@@ -55,7 +55,6 @@
#include <initservice/initsvcstructs.H>
#include <initservice/initsvcreasoncodes.H>
-#include <config.h>
namespace ISTEP_14
{
diff --git a/src/include/usr/isteps/istep15list.H b/src/include/usr/isteps/istep15list.H
index d32145d0c..d93acf859 100644
--- a/src/include/usr/isteps/istep15list.H
+++ b/src/include/usr/isteps/istep15list.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -47,7 +47,6 @@
#include <initservice/initsvcstructs.H>
#include <initservice/initsvcreasoncodes.H>
-#include <config.h>
namespace ISTEP_15
{
@@ -141,7 +140,6 @@ const DepModInfo g_istep15Dependancies = {
DEP_LIB(libpm.so),
DEP_LIB(libimageprocs.so),
DEP_LIB(libisteps_mss.so),
- DEP_LIB(libsmf.so),
NULL
}
};
diff --git a/src/include/usr/isteps/istep21list.H b/src/include/usr/isteps/istep21list.H
index 18f029fad..65f62fab4 100644
--- a/src/include/usr/isteps/istep21list.H
+++ b/src/include/usr/isteps/istep21list.H
@@ -135,7 +135,6 @@ const DepModInfo g_istep21Dependancies = {
#ifdef CONFIG_UCD_FLASH_UPDATES
DEP_LIB(libucd.so),
#endif
- DEP_LIB(libsmf.so),
NULL
}
};
diff --git a/src/include/usr/isteps/istep_reasoncodes.H b/src/include/usr/isteps/istep_reasoncodes.H
index 5bd5fbf94..468ac5d9a 100644
--- a/src/include/usr/isteps/istep_reasoncodes.H
+++ b/src/include/usr/isteps/istep_reasoncodes.H
@@ -68,6 +68,7 @@ namespace ISTEP
MOD_MSS_SCRUB = 0x25,
MOD_CALL_UPDATE_UCD_FLASH = 0x26,
MOD_LOAD_HCODE = 0x27,
+ MOD_DISCOVER_TARGETS = 0x28,
};
/**
@@ -142,6 +143,7 @@ namespace ISTEP
RC_SLAVE_CORE_WAKEUP_ERROR = ISTEP_COMP_ID | 0x4E,
RC_UCD_IMG_NOT_IN_CONTAINER = ISTEP_COMP_ID | 0x4F,
RC_MM_UNMAP_FAILED = ISTEP_COMP_ID | 0x50,
+ RC_CANNOT_BOOT_WITH_MISMATCHED_BARS = ISTEP_COMP_ID | 0x51,
};
};
diff --git a/src/include/usr/isteps/nvdimm/bpmreasoncodes.H b/src/include/usr/isteps/nvdimm/bpmreasoncodes.H
new file mode 100644
index 000000000..2957e2e6e
--- /dev/null
+++ b/src/include/usr/isteps/nvdimm/bpmreasoncodes.H
@@ -0,0 +1,90 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/isteps/nvdimm/bpmreasoncodes.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file bpmreasoncode.H
+ *
+ * @brief Reason codes and module ids for the BPM
+ */
+#ifndef __BPMREASONCODES_H
+#define __BPMREASONCODES_H
+
+#include <hbotcompid.H>
+
+namespace BPM_RC
+{
+
+ enum bpmModuleId
+ {
+ BPM_ISSUE_COMMAND = 0x00,
+ BPM_IN_UPDATE_MODE = 0x01,
+ BPM_UPDATE_FIRMWARE = 0x02,
+ BPM_ENTER_BSL_MODE = 0x03,
+ BPM_SETUP_PAYLOAD = 0x04,
+ BPM_DUMP_SEGMENT = 0x05,
+ BPM_DISABLE_WRITE_PROTECTION = 0x06,
+ BPM_WRITE_MAGIC_REG = 0x07,
+ BPM_GET_RESPONSE = 0x08,
+ BPM_RETRY_BLOCK_WRITE = 0x09,
+ BPM_WAIT_FOR_CMD_BIT_RESET = 0x0A,
+ BPM_WAIT_FOR_BUSY_BIT_RESET = 0x0B,
+ BPM_CHECK_FIRMWARE_CRC = 0x0C,
+ BPM_VERIFY_GOOD_BPM_STATE = 0x0D,
+ BPM_RUN_FW_UPDATES = 0x0F,
+ BPM_WRITE_VIA_SCAP = 0x10,
+ BPM_BLOCK_WRITE = 0x11,
+ BPM_RUN_UPDATE = 0x12,
+ BPM_START_UPDATE = 0xFD,
+ BPM_END_UPDATE = 0xFE,
+ BPM_DUMMY_ERROR = 0xFF,
+ };
+
+ enum bpmReasonCode
+ {
+ BPM_INVALID_PAYLOAD_SIZE = BPM_COMP_ID | 0x00,
+ BPM_UPDATE_MODE_VERIFICATION_FAIL = BPM_COMP_ID | 0x01,
+ BPM_RESET_VECTOR_NEVER_RECEIVED = BPM_COMP_ID | 0x02,
+ BPM_FAILED_TO_ENTER_BSL_MODE = BPM_COMP_ID | 0x03,
+ BPM_INVALID_PAYLOAD_DATA_SIZE = BPM_COMP_ID | 0x04,
+ BPM_BSL_MODE_ENABLED = BPM_COMP_ID | 0x05,
+ BPM_DISABLE_WRITE_PROTECTION_FAILED = BPM_COMP_ID | 0x06,
+ BPM_WRITE_TO_MAGIC_REG_FAILED = BPM_COMP_ID | 0x07,
+ BPM_RESPONSE_CRC_MISMATCH = BPM_COMP_ID | 0x08,
+ BPM_EXCEEDED_RETRY_LIMIT = BPM_COMP_ID | 0x09,
+ BPM_CMD_STATUS_ERROR_BIT_SET = BPM_COMP_ID | 0x0A,
+ BPM_FIRMWARE_CRC_VERIFY_FAILURE = BPM_COMP_ID | 0x0B,
+ BPM_VERSION_MISMATCH = BPM_COMP_ID | 0x0C,
+ BPM_EXCEEDED_RETRY_LIMIT_REG = BPM_COMP_ID | 0x0D,
+ BPM_EXCEEDED_RETRY_LIMIT_DATA = BPM_COMP_ID | 0x0E,
+ BPM_BAD_RESPONSE = BPM_COMP_ID | 0x0F,
+ BPM_UPDATE_SUCCESSFUL = BPM_COMP_ID | 0xFC,
+ BPM_ENTER_UPDATE_MODE = BPM_COMP_ID | 0xFD,
+ BPM_EXIT_UPDATE_MODE = BPM_COMP_ID | 0xFE,
+ BPM_DUMMY_REASONCODE = BPM_COMP_ID | 0xFF,
+ };
+
+};
+
+
+#endif
diff --git a/src/include/usr/isteps/nvdimm/nvdimm.H b/src/include/usr/isteps/nvdimm/nvdimm.H
index 567299925..966d4fd17 100644
--- a/src/include/usr/isteps/nvdimm/nvdimm.H
+++ b/src/include/usr/isteps/nvdimm/nvdimm.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -29,20 +29,24 @@
namespace NVDIMM
{
+
enum nvdimm_err_status
{
- NSTD_VAL_NOPRSV = 0x08, // memory valid, contents not preserved (genesis)
- NSTD_VAL_NOPRSV_MASK = 0xF7,
- NSTD_VAL_PRSV = 0x04, // memory contents preserved
- NSTD_VAL_PRSV_MASK = 0xFB,
- NSTD_ERR_NOPRSV = 0x02, // memory failed to preserve contents
- NSTD_ERR_NOPRSV_MASK = 0xFD,
- NSTD_ERR_NOBKUP = 0x01, // memory unable to preserve future content
- NSTD_ERR_NOBKUP_MASK = 0xFE,
- NSTD_ERR = 0x03, // NSTD_ERR_NOPRSV+NSTD_ERR_NOBKUP
+ NSTD_VAL_ERASED = 0x08, // Image erased, SCM device contents not persisted
+ NSTD_VAL_ERASED_MASK = 0xF7,
+ NSTD_VAL_RESTORED = 0x04, // Valid image successfully restored, SCM persisted
+ NSTD_VAL_RESTORED_MASK = 0xFB,
+ NSTD_VAL_SR_FAILED = 0x02, // Save/Restore failed to persist memory contents
+ NSTD_VAL_SR_FAILED_MASK = 0xFD,
+ NSTD_VAL_DISARMED = 0x01, // memory unable to preserve future content
+ NSTD_VAL_DISARMED_MASK = 0xFE,
+ NSTD_ERR_VAL_SR = 0x40, // Partially working. Error detected but save/restore (SR) may still work
+ NSTD_ERR_VAL_SR_MASK = 0xBF,
+ NSTD_ERR = 0x03, // NSTD_ERR_NOPRSV+NSTD_ERR_NOBKUP
};
#ifndef __HOSTBOOT_RUNTIME
+
/**
* @brief Entry function to NVDIMM management
* - Restore image from NVDIMM NAND flash to DRAM
@@ -69,15 +73,105 @@ void nvdimm_restore(TARGETING::TargetHandleList &i_nvdimmList);
**/
bool nvdimm_update(TARGETING::TargetHandleList &i_nvdimmList);
+
+/**
+ * @brief Entry function to set NVDIMM thresholds
+ *
+ * @param[in] i_nvdimmList - list of nvdimm targets
+ *
+ **/
+void nvdimm_thresholds(TARGETING::TargetHandleList &i_nvdimmList);
+
+
#endif
/**
+ * @brief Entry function to NVDIMM unlock encryption
+ *
+ * @param[in] i_nvdimmList - list of nvdimm targets
+ *
+ * @return true if no errors logged, else false
+ */
+bool nvdimm_encrypt_unlock(TARGETING::TargetHandleList &i_nvdimmList);
+
+
+/**
+ * @brief Entry function to NVDIMM generate keys
+ * Generate encryption keys and set the FW key attribute
+ *
+ * @return true if no errors logged, else false
+ */
+bool nvdimm_gen_keys(void);
+
+/**
+ * @brief Entry function to NVDIMM remove keys
+ * Set the FW key attribute = 0
+ * Tell HWSV to clear anchor key attribute
+ *
+ * @return true if no errors logged, else false
+ */
+bool nvdimm_remove_keys(void);
+
+/**
+ * @brief Entry function to NVDIMM enable encryption
+ *
+ * @param[in] i_nvdimmList - list of nvdimm targets
+ *
+ * @return true if no errors logged, else false
+ */
+bool nvdimm_encrypt_enable(TARGETING::TargetHandleList &i_nvdimmList);
+
+/**
+ * @brief Entry function to NVDIMM crypto erase
+ *
+ * @param[in] i_nvdimmList - list of nvdimm targets
+ *
+ * @return true if no errors logged, else false
+ */
+bool nvdimm_crypto_erase(TARGETING::TargetHandleList &i_nvdimmList);
+
+/**
+ * @brief Entry function to NVDIMM factory default
+ *
+ * @param[in] i_nvdimmList - list of nvdimm targets
+ *
+ * @return true if no errors logged, else false
+ */
+bool nvdimmFactoryDefault(TARGETING::TargetHandleList &i_nvdimmList);
+
+/**
+ * @brief Entry function to NVDIMM secure erase verify
+ *
+ * @param[in] i_nvdimmList - list of nvdimm targets
+ *
+ * @return true if no errors logged, else false
+ */
+bool nvdimmSecureEraseVerifyStart(TARGETING::TargetHandleList &i_nvdimmList);
+
+/**
+ * @brief Entry function to NVDIMM secure erase verify status
+ *
+ * @param[in] i_nvdimmList - list of nvdimm targets
+ *
+ * @return true if no errors logged, else false
+ */
+bool nvdimmSecureEraseVerifyStatus(TARGETING::TargetHandleList &i_nvdimmList);
+
+/**
+ * @brief Helper function to get list of nvdimm target pointers
+ *
+ * @param[out] o_nvdimmList - list of nvdimm targets
+ *
+ */
+void nvdimm_getNvdimmList(TARGETING::TargetHandleList &o_nvdimmList);
+
+/**
* @brief This function erases image on the nvdimm target
*
* @param[in] i_nvdimm - nvdimm target with NV controller
*
- * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * @return errlHndl_t - nullptr if successful, otherwise a pointer to
* the error log.
*/
errlHndl_t nvdimmEraseNF(TARGETING::Target *i_nvdimm);
@@ -92,17 +186,6 @@ errlHndl_t nvdimmEraseNF(TARGETING::Target *i_nvdimm);
*/
void nvdimmSetStatusFlag(TARGETING::Target *i_nvdimm, const uint8_t i_status_flag);
-#ifdef __HOSTBOOT_RUNTIME
-
-/**
- * @brief Check nvdimm error state
- *
- * @param[in] i_nvdimm - nvdimm target
- *
- * @return bool - true if nvdimm is in any error state, false otherwise
- */
-bool nvdimmInErrorState(TARGETING::Target *i_nvdimm);
-
/**
* @brief This function arms/disarms the trigger based on i_state
*
@@ -110,7 +193,7 @@ bool nvdimmInErrorState(TARGETING::Target *i_nvdimm);
*
* @param[in] i_state - true to arm, false to disarm
*
- * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * @return errlHndl_t - nullptr if successful, otherwise a pointer to
* the error log.
*/
errlHndl_t nvdimmChangeArmState(TARGETING::Target *i_nvdimm, bool i_state);
@@ -130,39 +213,290 @@ errlHndl_t nvdimmChangeArmState(TARGETING::Target *i_nvdimm, bool i_state);
bool nvdimmArm(TARGETING::TargetHandleList &i_nvdimmTargetList);
/**
+ * @brief Disarms the trigger to enable backup in the event of a
+ * power loss on each NVDIMM
+ *
+ * @param[in] i_nvdimmTargetList : list of dimms that are NVDIMMs
+ * @return true if no errors logged, else false
+ */
+bool nvdimmDisarm(TARGETING::TargetHandleList &i_nvdimmTargetList);
+
+#ifdef __HOSTBOOT_RUNTIME
+
+/**
+ * @brief Check nvdimm error state
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @return bool - true if nvdimm is in any error state, false otherwise
+ */
+bool nvdimmInErrorState(TARGETING::Target *i_nvdimm);
+
+/**
+ * @brief Check the ES (enery source)/backup power module(BPM) health status of
+ * the individual NVDIMMs supplied in list
+ *
+ * @details The BPM will trigger the health check when power is applied at the
+ * beginning of the IPL, with results ready to check about 20 mins
+ * later. It is the caller's responsibility to ensure enough time has
+ * passed to make this call.
+ * Excerpt from the Jedec Standard, Byte Addressable Energy Backed
+ * Interface of the interested flags (bits 0 .. 2).
+ * ES_CMD_STATUS0
+ * Bit 0 : Health Check in Progress
+ * Bit 1 : Health Check Succeeded
+ * Bit 2 : Health Check Failed
+ *
+ * @param[in] i_nvdimmTargetList - list of NVDIMMs to check the ES health of
+ *
+ * @return false if one or more NVDIMMs fail ES health check, else true
+ */
+bool nvDimmEsCheckHealthStatus(const TARGETING::TargetHandleList
+ &i_nvdimmTargetList);
+
+/**
+ * @brief A wrapper around the call to nvDimmEsCheckHealthStatus
+ *
+ * @details This will aggregate all the NVDIMMs of the system and pass
+ * them to the call nvDimmEsCheckHealthStatus
+ *
+ * @see nvDimmEsCheckHealthStatus for more details
+ *
+ * @return false if one or more NVDIMMs fail an ES health check, else true
+ */
+bool nvDimmEsCheckHealthStatusOnSystem();
+
+
+/**
+ * @brief Check the NVM (non-volatile memory)/flash health status of the
+ * individual NVDIMMs supplied in list.
+ *
+ * @details This method will check the flash error count registers
+ * (FLASH_ERROR_COUNT0 to FLASH_ERROR_COUNT2) to determine if the
+ * number of flash error exceeds the maximum allowed. Will also check
+ * the flash bad block percentage register (FLASH_BAD_BLK_PCT) to
+ * determine if the percentage exceeds the maximum allowed.
+ * If any one of these or both of these fail their perspective
+ * maximums then a callout will be made with either or both failures.
+ *
+ * @param[in] i_nvdimmTargetList - list of NVDIMMs to check the NVM health of
+ *
+ * @return false if one or more NVDIMMs fail NVM health check, else true
+ */
+bool nvDimmNvmCheckHealthStatus(const TARGETING::TargetHandleList
+ &i_nvdimmTargetList);
+
+/**
+ * @brief A wrapper around the call to nvDimmNvmCheckHealthStatus
+ *
+ * @details This will aggregate all the NVDIMMs of the system and pass
+ * them to the call nvDimmNvmCheckHealthStatus
+ *
+ * @see nvDimmNvmCheckHealthStatus for more details
+ *
+ * @return false if one or more NVDIMMs fail an NVM health check, else true
+ */
+bool nvDimmNvmCheckHealthStatusOnSystem();
+
+
+/**
+ * @brief Send NV_STATUS to host
+ */
+void nvdimmSendNvStatus();
+
+#endif
+
+/**
* @brief NVDIMM protection state
*
- * NOT_PROTECTED - default state
- * PROTECTED - switches to this when armed & OCC is in control
- * UNPROTECTED_BECAUSE_ERROR - PRD detected error on NV controller
- * Note: error will stay with target preventing PROTECTED status
- * until power is cycled again
+ * NVDIMM_ARMED - set armed state
+ * NVDIMM_DISARMED - set disarmed state
+ * OCC_ACTIVE - set active state
+ * OCC_INACTIVE - set inactive state
+ * NVDIMM_FATAL_HW_ERROR - set fatal hw state
+ * NVDIMM_RISKY_HW_ERROR - set risky hw state
+ * NVDIMM_ENCRYPTION_ERROR - set encryption state
+ * Note: fatal error will stay with target preventing
+ * PROTECTED status until power is cycled again
+ * ENCRYPTION_ENABLED - contents of nvdimm are encrypted
+ * ENCRYPTION_DISABLED - contents of nvdimm are not encrypted
+ * ERASE_VERIFY_STARTED - set secure_erase_verify_complete to 0
+ * ERASE_VERIFY_COMPLETE = set secure_erase_verify_complete to 1
*/
enum nvdimm_protection_t
{
- NOT_PROTECTED = 0,
- PROTECTED = 1,
- UNPROTECTED_BECAUSE_ERROR = 2
+ NVDIMM_ARMED = 0,
+ NVDIMM_DISARMED = 1,
+ OCC_ACTIVE = 2,
+ OCC_INACTIVE = 3,
+ NVDIMM_FATAL_HW_ERROR = 4,
+ NVDIMM_RISKY_HW_ERROR = 5,
+ NVDIMM_ENCRYPTION_ERROR = 6,
+ ENCRYPTION_ENABLED = 7,
+ ENCRYPTION_DISABLED = 8,
+ ERASE_VERIFY_STARTED = 9,
+ ERASE_VERIFY_COMPLETED = 10,
+ SEND_NV_STATUS = 11,
+ /* deprecated, still used by PRD */
+ UNPROTECTED_BECAUSE_ERROR = 4,
};
/**
* @brief Notify PHYP of NVDIMM protection status
*
- * @param i_target Processor with NVDIMM
+ * @param i_target Processor with NVDIMM or NVDIMM itself
+ * - ARMED state updated per NVDIMM
+ * - ERROR states updated per NVDIMM
+ * - OCC state updated per PROC
* @param i_state Protection state of NVDIMM
+ *
+ * @return errlHndl_t - nullptr if successful, otherwise a pointer to
+ * the error log.
*/
errlHndl_t notifyNvdimmProtectionChange(TARGETING::Target* i_target,
const nvdimm_protection_t i_state);
-#endif
+
+/**
+ * @brief Get operational unit operation timeout
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[out] o_timeout - operation timeout
+ *
+ * @return errlHndl_t - nullptr if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t getOperOpsTimeout(TARGETING::Target* i_nvdimm,
+ uint16_t& o_timeout);
+
+
+/**
+ * @brief Wait for operational unit operation to complete
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[in] i_cmd - operational unit ops command
+ *
+ * @return errlHndl_t - nullptr if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t waitOperOpsComplete(TARGETING::Target* i_nvdimm,
+ uint8_t i_cmd);
+
+
+/**
+ * @brief Get the vendor log unit
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[in] i_unitId - vendor log unit id
+ *
+ * @param[out] o_unitData - vendor log unit data
+ *
+ * @return errlHndl_t - nullptr if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t getLogPerUnit(TARGETING::Target* i_nvdimm,
+ uint16_t i_unitId,
+ std::vector<uint8_t>& o_unitData);
+
+/**
+ * @brief Calculate host CRC
+ *
+ * @param[in] i_data - host data
+ *
+ * @param[in] i_data_size - data size
+ *
+ * @return crc
+ */
+uint16_t crc16(const uint8_t * i_data, int i_size);
+
+
+/**
+ * @brief Get operational unit crc
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[out] o_crc - nvdimm hw crc
+ *
+ * @return errlHndl_t - nullptr if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t getOperUnitCrc(TARGETING::Target* i_nvdimm, uint16_t& o_crc);
+
+
+/**
+ * @brief Compare host and nvdimm checksum
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[in] i_unitData - data sent to the nvdimm by the host
+ *
+ * @return errlHndl_t - nullptr if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t compareCksum(TARGETING::Target* i_nvdimm,
+ std::vector<uint8_t>& i_unitData);
+
+
+/**
+ * @brief Function to add NVDIMM vendor log data to errorlog FFDC
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[inout] io_err - error log to add FFDC data. Must not be nullptr
+ *
+ */
+void nvdimmAddVendorLog(TARGETING::Target *i_nvdimm, errlHndl_t& io_err);
+
+
+/**
+ * @brief Add NVDIMM Update regs to FFDC for errors encountered
+ * during NVDIMM firmware update process
+ * Regs specified in NVDIMM IPL Error Handling Document
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[in] io_err - error log to add FFDC data. Must not be nullptr
+ *
+ */
+void nvdimmAddUpdateRegs(TARGETING::Target *i_nvdimm, errlHndl_t& io_err);
+
+
+/**
+ * @brief Function to add some NVDIMM Page 4 status regs to errorlog FFDC
+ * PANIC_CNT Counts FPGA firmware events
+ * PARITY_ERROR_COUNT Counts FPGA SRAM parity errors
+ * FLASH_ERROR_COUNT0 Counts FLASH read/write errors
+ * FLASH_ERROR_COUNT1
+ * FLASH_ERROR_COUNT2
+ * FLASH_BAD_BLOCK_COUNT0 Counts bad blocks within the flash array
+ * FLASH_BAD_BLOCK_COUNT1
+ * SCAP_STATUS BackupPowerModule/SuperCap state
+ * STATUS_EVENT_INT_INFO1 NVDIMM error info
+ * STATUS_EVENT_INT_INFO2
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[inout] io_err - error log to add FFDC data. Must not be nullptr
+ *
+ */
+void nvdimmAddPage4Regs(TARGETING::Target *i_nvdimm, errlHndl_t& io_err);
+
+
/**
* @brief Entry function to NVDIMM initialization
* - Checks for ready state
* - Waits for the ongoing backup to complete
* - Disarms the trigger for draminit
* @param i_target nvdimm target
+ *
+ * @return errlHndl_t - nullptr if successful, otherwise a pointer to
+ * the error log.
*/
void nvdimm_init(TARGETING::Target *i_nvdimm);
+
}
#endif // NVDIMM_EXT_H__
diff --git a/src/include/usr/isteps/nvdimm/nvdimmif.H b/src/include/usr/isteps/nvdimm/nvdimmif.H
index 4ddfcf970..e96bb17d4 100644
--- a/src/include/usr/isteps/nvdimm/nvdimmif.H
+++ b/src/include/usr/isteps/nvdimm/nvdimmif.H
@@ -42,6 +42,22 @@ namespace NVDIMM
*/
void getNVDIMMs( std::list<EEPROM::EepromInfo_t>& o_info );
+/**
+ * @brief Check if given address is owned by nvdimms and return
+ a new address that isn't if it was
+ * @param[in] i_topAddr = High mainstore address (see get_top_homer_mem_addr)
+ * @return uint64_t - Highest address without a nvdimm
+ */
+uint64_t get_top_addr_with_no_nvdimms( uint64_t i_topAddr );
+
+// Make a very simple inline if we don't support NVDIMMs in this compile
+#ifndef CONFIG_NVDIMM
+inline uint64_t get_top_addr_with_no_nvdimms( uint64_t i_topAddr )
+{
+ return i_topAddr;
+};
+#endif
+
}; // end namespace NVDIMM
#endif // end __NVDIMMIF_H
diff --git a/src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H b/src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H
index 0b1680d92..134988be6 100644
--- a/src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H
+++ b/src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -85,6 +85,32 @@ enum nvdimmModuleId
VALIDATE_FW_IMAGE = 0x23,
WAIT_FW_OPS_BLOCK_RECEIVED = 0x24,
NVDIMM_IS_UPDATE_NEEDED = 0x25,
+ NVDIMM_RUN_UPDATE_USING_LID = 0x26,
+ NVDIMM_GET_TPM = 0x27,
+ NVDIMM_SET_KEY_REG = 0x28,
+ NVDIMM_ENCRYPT_ENABLE = 0x29,
+ NVDIMM_CRYPTO_ERASE = 0x2A,
+ NVDIMM_CHECK_VALID_ATTR_DATA = 0x2B,
+ NVDIMM_HANDLE_CONFLICTING_KEYS = 0x2C,
+ NVDIMM_ENCRYPT_UNLOCK = 0x2D,
+ NVDIMM_GET_DARN_NUMBER = 0x2E,
+ NVDIMM_KEYIFY_RANDOM_NUMBER = 0x2F,
+ SET_ATTR_NVDIMM_ENCRYPTION_KEYS_FW = 0x30,
+ SEND_ATTR_NVDIMM_ARMED = 0x31,
+ NVDIMM_FACTORY_RESET = 0x32,
+ NVDIMM_ES_HEALTH_CHECK = 0x33, // Health check on the ES (energy source)/backup power module
+ NVDIMM_CHECK_RESETN = 0x34,
+ NVDIMM_CHECK_CSAVE = 0x35,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK = 0x36,
+ NVDIMM_SET_EVENT_NOTIFICATION = 0x37,
+ NVDIMM_NVM_HEALTH_CHECK = 0x38, // Health check on the NVM (non-volatile memory)/flash
+ NVDIMM_WAIT_OPER_OPS_COMPLETE = 0x39,
+ NVDIMM_COMPARE_CKSUM = 0x3A,
+ NVDIMM_CHECK_FW_SLOT = 0x3B,
+ NVDIMM_ARM_PRE_CHECK = 0x3C,
+ NVDIMM_ARM = 0x3D,
+ CLEAR_FW_OPS_STATUS = 0x3E,
+ NVDIMM_SECURE_ERASE_VERIFY_STATUS = 0x3F,
};
/**
@@ -95,52 +121,102 @@ enum nvdimmModuleId
*/
enum nvdimmReasonCode
{
- NVDIMM_INVALID_REASONCODE = NVDIMM_COMP_ID | 0x00, // Invalid Reasoncode
- NVDIMM_INVALID_OPERATION = NVDIMM_COMP_ID | 0x01,
- NVDIMM_INVALID_DEVICE_TYPE = NVDIMM_COMP_ID | 0x02,
- NVDIMM_ATTR_INFO_NOT_FOUND = NVDIMM_COMP_ID | 0x03,
- NVDIMM_INVALID_CHIP = NVDIMM_COMP_ID | 0x04,
- NVDIMM_I2C_MASTER_PATH_ERROR = NVDIMM_COMP_ID | 0x05,
- NVDIMM_TARGET_NULL = NVDIMM_COMP_ID | 0x06,
- NVDIMM_INVALID_ADDR_OFFSET_SIZE = NVDIMM_COMP_ID | 0x07,
- NVDIMM_OVERFLOW_ERROR = NVDIMM_COMP_ID | 0x08,
- NVDIMM_I2C_WRITE_PAGE_SIZE_ZERO = NVDIMM_COMP_ID | 0x09,
- NVDIMM_INVALID_OFFSET = NVDIMM_COMP_ID | 0x0A,
- NVDIMM_READ_FAILURE = NVDIMM_COMP_ID | 0x0B, // NV Controller read failure
- NVDIMM_WRITE_FAILURE = NVDIMM_COMP_ID | 0x0C, // NV Controller write failure
- NVDIMM_BACKUP_TIMEOUT = NVDIMM_COMP_ID | 0x0D, // Backup/save timeout
- NVDIMM_RESTORE_TIMEOUT = NVDIMM_COMP_ID | 0x0E, // Restore timeout
- NVDIMM_ERASE_TIMEOUT = NVDIMM_COMP_ID | 0x0F, // Erase timeout
- NVDIMM_CHARGE_TIMEOUT = NVDIMM_COMP_ID | 0x10, // Battery charging timeout
- NVDIMM_ARM_TIMEOUT = NVDIMM_COMP_ID | 0x11, // Arming timeout
- NVDIMM_SET_ES_ERROR = NVDIMM_COMP_ID | 0x12, // Failure to set the ES policy
- NVDIMM_MSS_STR_ENTRY_ERROR = NVDIMM_COMP_ID | 0x13, // Failure to enter STR
- NVDIMM_MSS_STR_EXIT_ERROR = NVDIMM_COMP_ID | 0x14, // Failure to exit STR
- NVDIMM_MSS_POST_RSTR_ERROR = NVDIMM_COMP_ID | 0x15, // Failure to perform post restore work
- NVDIMM_OPEN_PAGE_TIMEOUT = NVDIMM_COMP_ID | 0x16, // Open page timeout
- NVDIMM_STATUS_TIMEOUT = NVDIMM_COMP_ID | 0x17, // Status timeout
- NVDIMM_ARM_FAILED = NVDIMM_COMP_ID | 0x18, // Failure to arm reset_n
- NVDIMM_ERASE_FAILED = NVDIMM_COMP_ID | 0x19, // Failure to erase
- NVDIMM_RESTORE_FAILED = NVDIMM_COMP_ID | 0x1A, // Failure to restore
- NVDIMM_NOT_READY = NVDIMM_COMP_ID | 0x1B, // NVDIMM not ready for host to access
- NVDIMM_NULL_FIRMWARE_REQUEST_PTR = NVDIMM_COMP_ID | 0x1C, // Firmware request is NULL
- NVDIMM_UNSUPPORTED_NVDIMM_TYPE = NVDIMM_COMP_ID | 0x1D, // Unsupported NVDIMM type for update
- NVDIMM_OPERATION_IN_PROGRESS = NVDIMM_COMP_ID | 0x1E, // NV controller is busy
- NVDIMM_CHECKSUM_ERROR = NVDIMM_COMP_ID | 0x1F, // Checksum error between host and nv calculated
- NVDIMM_ZERO_TOTAL_REGIONS = NVDIMM_COMP_ID | 0x20, // Zero write regions calculated
- NVDIMM_UPDATE_MODE_UNCHANGED = NVDIMM_COMP_ID | 0x21, // Unable to change update mode
- NVDIMM_FW_OPS_IN_PROGRESS_TIMEOUT = NVDIMM_COMP_ID | 0x22, // Operations In Progress timeout
- NVDIMM_DATA_SIZE_TOO_LARGE = NVDIMM_COMP_ID | 0x23, // Trying to write too much data
- NVDIMM_DATA_SIZE_INVALID = NVDIMM_COMP_ID | 0x24, // Data size is invalid
- NVDIMM_BLOCK_NOT_RECEIVED = NVDIMM_COMP_ID | 0x25, // Block data not received
- NVDIMM_FW_OPS_NOT_SUCCESSFUL = NVDIMM_COMP_ID | 0x26, // Unsuccessful Firmware Operation
- NVDIMM_UPDATE_NOT_SUPPORTED = NVDIMM_COMP_ID | 0x27, // NV controller cannot be updated
+ NVDIMM_INVALID_REASONCODE = NVDIMM_COMP_ID | 0x00, // Invalid Reasoncode
+ NVDIMM_INVALID_OPERATION = NVDIMM_COMP_ID | 0x01,
+ NVDIMM_INVALID_DEVICE_TYPE = NVDIMM_COMP_ID | 0x02,
+ NVDIMM_ATTR_INFO_NOT_FOUND = NVDIMM_COMP_ID | 0x03,
+ NVDIMM_INVALID_CHIP = NVDIMM_COMP_ID | 0x04,
+ NVDIMM_I2C_MASTER_PATH_ERROR = NVDIMM_COMP_ID | 0x05,
+ NVDIMM_TARGET_NULL = NVDIMM_COMP_ID | 0x06,
+ NVDIMM_INVALID_ADDR_OFFSET_SIZE = NVDIMM_COMP_ID | 0x07,
+ NVDIMM_OVERFLOW_ERROR = NVDIMM_COMP_ID | 0x08,
+ NVDIMM_I2C_WRITE_PAGE_SIZE_ZERO = NVDIMM_COMP_ID | 0x09,
+ NVDIMM_INVALID_OFFSET = NVDIMM_COMP_ID | 0x0A,
+ NVDIMM_READ_FAILURE = NVDIMM_COMP_ID | 0x0B, // NV Controller read failure
+ NVDIMM_WRITE_FAILURE = NVDIMM_COMP_ID | 0x0C, // NV Controller write failure
+ NVDIMM_BACKUP_TIMEOUT = NVDIMM_COMP_ID | 0x0D, // Backup/save timeout
+ NVDIMM_RESTORE_TIMEOUT = NVDIMM_COMP_ID | 0x0E, // Restore timeout
+ NVDIMM_ERASE_TIMEOUT = NVDIMM_COMP_ID | 0x0F, // Erase timeout
+ NVDIMM_CHARGE_TIMEOUT = NVDIMM_COMP_ID | 0x10, // Battery charging timeout
+ NVDIMM_ARM_TIMEOUT = NVDIMM_COMP_ID | 0x11, // Arming timeout
+ NVDIMM_SET_ES_ERROR = NVDIMM_COMP_ID | 0x12, // Failure to set the ES policy
+ NVDIMM_MSS_STR_ENTRY_ERROR = NVDIMM_COMP_ID | 0x13, // Failure to enter STR
+ NVDIMM_MSS_STR_EXIT_ERROR = NVDIMM_COMP_ID | 0x14, // Failure to exit STR
+ NVDIMM_MSS_POST_RSTR_ERROR = NVDIMM_COMP_ID | 0x15, // Failure to perform post restore work
+ NVDIMM_OPEN_PAGE_TIMEOUT = NVDIMM_COMP_ID | 0x16, // Open page timeout
+ NVDIMM_STATUS_TIMEOUT = NVDIMM_COMP_ID | 0x17, // Status timeout
+ NVDIMM_ARM_FAILED = NVDIMM_COMP_ID | 0x18, // Failure to arm reset_n
+ NVDIMM_ERASE_FAILED = NVDIMM_COMP_ID | 0x19, // Failure to erase
+ NVDIMM_RESTORE_FAILED = NVDIMM_COMP_ID | 0x1A, // Failure to restore
+ NVDIMM_NOT_READY = NVDIMM_COMP_ID | 0x1B, // NVDIMM not ready for host to access
+ NVDIMM_NULL_FIRMWARE_REQUEST_PTR = NVDIMM_COMP_ID | 0x1C, // Firmware request is NULL
+ NVDIMM_UNSUPPORTED_NVDIMM_TYPE = NVDIMM_COMP_ID | 0x1D, // Unsupported NVDIMM type for update
+ NVDIMM_OPERATION_IN_PROGRESS = NVDIMM_COMP_ID | 0x1E, // NV controller is busy
+ NVDIMM_CHECKSUM_ERROR = NVDIMM_COMP_ID | 0x1F, // Checksum error between host and nv calculated
+ NVDIMM_ZERO_TOTAL_REGIONS = NVDIMM_COMP_ID | 0x20, // Zero write regions calculated
+ NVDIMM_UPDATE_MODE_UNCHANGED = NVDIMM_COMP_ID | 0x21, // Unable to change update mode
+ NVDIMM_FW_OPS_IN_PROGRESS_TIMEOUT = NVDIMM_COMP_ID | 0x22, // Operations In Progress timeout
+ NVDIMM_DATA_SIZE_TOO_LARGE = NVDIMM_COMP_ID | 0x23, // Trying to write too much data
+ NVDIMM_DATA_SIZE_INVALID = NVDIMM_COMP_ID | 0x24, // Data size is invalid
+ NVDIMM_BLOCK_NOT_RECEIVED = NVDIMM_COMP_ID | 0x25, // Block data not received
+ NVDIMM_FW_OPS_NOT_SUCCESSFUL = NVDIMM_COMP_ID | 0x26, // Unsuccessful Firmware Operation
+ NVDIMM_UPDATE_NOT_SUPPORTED = NVDIMM_COMP_ID | 0x27, // NV controller cannot be updated
+ NVDIMM_START_UPDATE = NVDIMM_COMP_ID | 0x28, // start update
+ NVDIMM_UPDATE_COMPLETE = NVDIMM_COMP_ID | 0x29, // update completed
+ NVDIMM_TPM_NOT_FOUND = NVDIMM_COMP_ID | 0x2A, // TPM not found
+ NVDIMM_POWER_SAVE_FAILURE = NVDIMM_COMP_ID | 0x2B, // Save failed due to power loss
+ NVDIMM_CSAVE_ERROR = NVDIMM_COMP_ID | 0x2C, // CSave failed due to error
+ NVDIMM_VOLTAGE_REGULATOR_FAILED = NVDIMM_COMP_ID | 0x2D,
+ NVDIMM_VDD_LOST = NVDIMM_COMP_ID | 0x2E,
+ NVDIMM_VPP_LOST = NVDIMM_COMP_ID | 0x2F,
+ NVDIMM_VTT_LOST = NVDIMM_COMP_ID | 0x30,
+ NVDIMM_DRAM_NOT_SELF_REFRESH = NVDIMM_COMP_ID | 0x31,
+ NVDIMM_CONTROLLER_HARDWARE_ERROR = NVDIMM_COMP_ID | 0x32,
+ NVDIMM_NVM_CONTROLLER_ERROR = NVDIMM_COMP_ID | 0x33,
+ NVDIMM_NVM_LIFETIME_ERROR = NVDIMM_COMP_ID | 0x34,
+ NVDIMM_NOT_ENOUGH_ENERGY_FOR_CSAVE = NVDIMM_COMP_ID | 0x35,
+ NVDIMM_INVALID_FIRMWARE_ERROR = NVDIMM_COMP_ID | 0x36, // Module Health Status Registers
+ NVDIMM_CONFIG_DATA_ERROR = NVDIMM_COMP_ID | 0x37,
+ NVDIMM_NO_ES_PRESENT = NVDIMM_COMP_ID | 0x38,
+ NVDIMM_ES_POLICY_NOT_SET = NVDIMM_COMP_ID | 0x39,
+ NVDIMM_ES_HARDWARE_FAILURE = NVDIMM_COMP_ID | 0x3A,
+ NVDIMM_ES_HEALTH_ASSESSMENT_ERROR = NVDIMM_COMP_ID | 0x3B,
+ NVDIMM_ES_LIFETIME_ERROR = NVDIMM_COMP_ID | 0x3C,
+ NVDIMM_ES_TEMP_ERROR = NVDIMM_COMP_ID | 0x3D,
+ NVDIMM_SET_EVENT_NOTIFICATION_ERROR = NVDIMM_COMP_ID | 0x3E,
+ NVDIMM_VERIF_BYTE_CHECK_FAILED = NVDIMM_COMP_ID | 0x3F, // Encryption key reg verif failed
+ NVDIMM_ENCRYPTION_ENABLE_FAILED = NVDIMM_COMP_ID | 0x40, // Encryption enable failed
+ NVDIMM_ENCRYPTION_ERASE_PENDING_FAILED = NVDIMM_COMP_ID | 0x41, // Encryption crypto erase pending failed
+ NVDIMM_ENCRYPTION_ERASE_FAILED = NVDIMM_COMP_ID | 0x42, // Encryption crypto erase failed
+ NVDIMM_ENCRYPTION_UNLOCK_FAILED = NVDIMM_COMP_ID | 0x43, // Encryption unlock failed
+ NVDIMM_ENCRYPTION_INVALID_ATTRIBUTE = NVDIMM_COMP_ID | 0x44, // Encryption attribute key data invalid
+ NVDIMM_ENCRYPTION_KEY_ATTRS_INVALID = NVDIMM_COMP_ID | 0x45, // Encryption key attributes are both invalid
+ NVDIMM_ENCRYPTION_MAX_DARN_ERRORS = NVDIMM_COMP_ID | 0x46, // Darn random key gen reached max errors
+ NVDIMM_ENCRYPTION_BAD_RANDOM_DATA = NVDIMM_COMP_ID | 0x47, // Generated key data not valid
+ NVDIMM_CANNOT_MAKE_ATTRIBUTE = NVDIMM_COMP_ID | 0x48, // Cannot make Attribute
+ NVDIMM_ES_HEALTH_CHECK_IN_PROGRESS_FAILURE = NVDIMM_COMP_ID | 0x49, // !< pertains to ES_CMD_STATUS0[0]; the ES health check in progress flag
+ NVDIMM_ES_HEALTH_CHECK_REPORTED_FAILURE = NVDIMM_COMP_ID | 0x4A, // !< pertains to ES_CMD_STATUS0[2]; the ES health check reported a failure flag
+ NVDIMM_ES_LIFETIME_MIN_REQ_NOT_MET = NVDIMM_COMP_ID | 0x4B, // !< pertains to ES_LIFETIME; BPM does not meet minimum requirement for a new BPM
+ NVDIMM_ES_HEALTH_CHECK_NEVER_INITIATED = NVDIMM_COMP_ID | 0x4C, // !< An ES health check was never initiated at start of IPL
+ NVDIMM_NVM_HEALTH_CHECK_FAILED = NVDIMM_COMP_ID | 0x4D, // !< An NVM health check on the NVDIMM failed
+ NVDIMM_VENDOR_LOG_TIMEOUT = NVDIMM_COMP_ID | 0x4E, // Vendor log for FFDC timeout
+ NVDIMM_VENDOR_LOG_CKSUM_FAILED = NVDIMM_COMP_ID | 0x4F, // Vendor log for FFDC checksum fail
+ NVDIMM_INVALID_FW_SLOT = NVDIMM_COMP_ID | 0x50,
+ NVDIMM_ERASE_ERROR = NVDIMM_COMP_ID | 0x51,
+ NVDIMM_ARM_PRE_CHECK_FAILED = NVDIMM_COMP_ID | 0x52,
+ NVDIMM_ARM_ENCRYPTION_UNLOCK_FAILED = NVDIMM_COMP_ID | 0x53,
+ NVDIMM_ARM_RETRY = NVDIMM_COMP_ID | 0x54,
+ NVDIMM_CLEAR_FW_OPS_STATUS_TIMEOUT = NVDIMM_COMP_ID | 0x55, // Failed to clear FW_OPS_STATUS
+ NVDIMM_NOT_RUNNING_LATEST_LEVEL = NVDIMM_COMP_ID | 0x56, // Either running from slot 0 or level was not updated
+ NVDIMM_ERASE_VERIFY_STATUS_NONZERO = NVDIMM_COMP_ID | 0x57,
+ NVDIMM_ERASE_VERIFY_RESULT_NONZERO = NVDIMM_COMP_ID | 0x58,
};
enum UserDetailsTypes
{
NVDIMM_UDT_NO_FORMAT = 0x0,
NVDIMM_UDT_PARAMETERS = 0x1,
+ NVDIMM_OP_PARAMETERS = 0x2,
};
}; // end NVDIMM
diff --git a/src/include/usr/isteps/pm/occAccess.H b/src/include/usr/isteps/pm/occAccess.H
index a5b46ff45..f8c3ea8c7 100644
--- a/src/include/usr/isteps/pm/occAccess.H
+++ b/src/include/usr/isteps/pm/occAccess.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2017 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -25,7 +25,6 @@
#ifndef OCCACCESS_H_
#define OCCACCESS_H_
-#include <config.h>
#include <errl/errlentry.H>
#include <targeting/common/commontargeting.H>
diff --git a/src/include/usr/isteps/pm/occCheckstop.H b/src/include/usr/isteps/pm/occCheckstop.H
index 026c8db55..edb4b4ab3 100644
--- a/src/include/usr/isteps/pm/occCheckstop.H
+++ b/src/include/usr/isteps/pm/occCheckstop.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2017 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -47,6 +47,10 @@ namespace HBOCC
NOT_FIR_MASTER = 0x00000000,
IS_FIR_MASTER = 0x00000001,
+ // SMF Mode
+ SMF_MODE_DISABLED = 0x00000000,
+ SMF_MODE_ENABLED = 0x00000001,
+
// SRAM Addresses for OCC Main App and GPE0 app
OCC_405_SRAM_ADDRESS = 0xFFF40000,
OCC_GPE0_SRAM_ADDRESS = 0xFFF01000,
diff --git a/src/include/usr/isteps/pm/pm_common_ext.H b/src/include/usr/isteps/pm/pm_common_ext.H
index 307dfbc7f..5c6e3985d 100644
--- a/src/include/usr/isteps/pm/pm_common_ext.H
+++ b/src/include/usr/isteps/pm/pm_common_ext.H
@@ -52,6 +52,11 @@ namespace HBPM
// FIR collection configuration data needed by FIR Master
// OCC in the event of a checkstop
uint8_t firdataConfig[3072];
+
+ // For informing OCC if SMF mode is enabled:
+ // 0x00000000 = Default (SMF disabled)
+ // 0x00000001 = SMF mode is enabled
+ uint32_t smfMode;
};
/**
diff --git a/src/include/usr/isteps/spless_255list.H b/src/include/usr/isteps/spless_255list.H
index 074e898d5..c19aa080e 100644
--- a/src/include/usr/isteps/spless_255list.H
+++ b/src/include/usr/isteps/spless_255list.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,7 +38,6 @@
#include <initservice/initsvcstructs.H>
#include <initservice/initsvcreasoncodes.H>
-#include <config.h>
/**
diff --git a/src/include/usr/mbox/mbox_queues.H b/src/include/usr/mbox/mbox_queues.H
index aa2b9a4a8..19c5eeabc 100644
--- a/src/include/usr/mbox/mbox_queues.H
+++ b/src/include/usr/mbox/mbox_queues.H
@@ -82,6 +82,8 @@ namespace MBOX
FSP_TARG_DECONFIG_MSGQ = 0x80000010,
FSP_SCOM_OPS_MSGQ = 0x80000011,
FSP_OCC_MSGQ_ID = 0x80000012,
+ FSP_NVDIMM_KEYS_MSGQ_ID = 0x80000013, // Attribute write request, equivalent
+ // to HWSV's ATTR_WRITE_OP_QUEUE_ID
FSP_LID_MSGQ = FSP_ATTR_SYNC_MSGQ,
diff --git a/src/include/usr/mmio/mmio_reasoncodes.H b/src/include/usr/mmio/mmio_reasoncodes.H
index 86ff60b5b..fb7a059a8 100644
--- a/src/include/usr/mmio/mmio_reasoncodes.H
+++ b/src/include/usr/mmio/mmio_reasoncodes.H
@@ -36,6 +36,12 @@ namespace MMIO
MOD_MMIO_PERFORM_OP = 0x02,
MOD_MMIO_GET_PROC_SCOM = 0x03,
MOD_MMIO_SET_PROC_SCOM = 0x04,
+ MOD_VALIDATE_OCMB_MMIO_OP = 0x05,
+ MOD_MMIO_CHAN_CHECKSTOP = 0x06,
+ MOD_CHECK_OCMB_ERROR = 0x07,
+ MOD_DETERMINE_CALLOUTS = 0x08,
+ MOD_DETERMINE_EXP_CALLOUTS = 0x09,
+ RT_OCMB_MMIO_PERFORM_OP = 0x0A,
};
enum MMIOReasonCode
@@ -52,6 +58,8 @@ namespace MMIO
RC_BAD_MMIO_WRITE = MMIO_COMP_ID | 0x09,
RC_PROC_NOT_FOUND = MMIO_COMP_ID | 0x0A,
RC_BAR_OFFSET_MISMATCH = MMIO_COMP_ID | 0x0B,
+ RC_MMIO_CHAN_CHECKSTOP = MMIO_COMP_ID | 0x0C,
+ RC_UNSUPPORTED_CHIPID = MMIO_COMP_ID | 0x0D,
};
};
diff --git a/src/include/usr/pnor/pnor_const.H b/src/include/usr/pnor/pnor_const.H
index 801fa34aa..c975c684c 100644
--- a/src/include/usr/pnor/pnor_const.H
+++ b/src/include/usr/pnor/pnor_const.H
@@ -27,7 +27,6 @@
#include <stdint.h>
#include <builtins.h>
-#include <config.h>
namespace PNOR
{
@@ -41,7 +40,6 @@ enum SectionId
// Value of HB_EXT_CODE must be 1 for debug framework.
#ifndef BOOTLOADER
HB_EXT_CODE, /**< Hostboot Extended Image */
- GLOBAL_DATA, /**< Global Data */
#endif
HB_BASE_CODE, /**< Hostboot Base Image */
#ifndef BOOTLOADER
@@ -77,6 +75,7 @@ enum SectionId
HDAT, /**< HDAT data */
EECACHE,
OCMBFW, /**< OCMB image */
+ BOOTKERNEL, /**< Bootkernel -- HB uses for PHYP */
#endif
NUM_SECTIONS, /**< Number of defined sections */
@@ -112,7 +111,8 @@ struct SectionInfo_t
reprovision(false),
Volatile(false),
secure(false),
- clearOnEccErr(false)
+ clearOnEccErr(false),
+ hasHashTable(false)
{}
SectionId id; /**< Identifier for this section */
const char* name; /**< Name of the section */
@@ -127,6 +127,7 @@ struct SectionInfo_t
bool Volatile; /**< Section loses contents on non HB reboots */
bool secure; /**< Indicates if a section is secure */
bool clearOnEccErr; /**< Indicates on ECC errors, clear and reboot*/
+ bool hasHashTable; /**< Indicates if there exists a hash page table*/
size_t secureProtectedPayloadSize; /**< Cache the secure payload size so
that the secure container only
needs to be parsed once */
diff --git a/src/include/usr/pnor/pnor_reasoncodes.H b/src/include/usr/pnor/pnor_reasoncodes.H
index fb7435a33..10c3e7b22 100644
--- a/src/include/usr/pnor/pnor_reasoncodes.H
+++ b/src/include/usr/pnor/pnor_reasoncodes.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -98,8 +98,7 @@ namespace PNOR
MOD_PNORCOMMON_PARSETOC = 0xC0, /**< PNOR::parseTOC */
// spnorrp.C
- // Note: 0xD0 is available, so should be the next one used for spnorrp.
- // Remove this comment after doing so.
+ MOD_SPNORRP_VERIFY_PAGE = 0xD0, /**< SPnorRP::verify_page */
MOD_SPNORRP_DIDSTARTUPFAIL = 0xD1, /**< didSecureStartupFail(rc) */
MOD_SPNORRP_ALLOCATE_BLOCK = 0xD2, /**< SPnorRP::initDaemon */
MOD_SPNORRP_WAITFORMESSAGE = 0xD3, /**< SPnorRP::waitForMessage */
@@ -192,7 +191,7 @@ namespace PNOR
RC_NOT_PAGE_ALIGNED = PNOR_COMP_ID | 0x3B,
RC_SECURE_PRO_SIZE_MISMATCH = PNOR_COMP_ID | 0x3C,
RC_READ_ONLY_PERM_FAIL = PNOR_COMP_ID | 0x3D,
-
+ RC_VERIFY_PAGE_FAILED = PNOR_COMP_ID | 0x3E,
//@fixme-RTC:131607-Temporary value to allow HWSV compile
//termination_rc
RC_PNOR_CORRUPTION = PNOR_COMP_ID | 0x99,
diff --git a/src/include/usr/pnor/pnorif.H b/src/include/usr/pnor/pnorif.H
index 11cc98a10..9a2fb39fc 100644
--- a/src/include/usr/pnor/pnorif.H
+++ b/src/include/usr/pnor/pnorif.H
@@ -31,7 +31,6 @@
#include <pnor/pnor_const.H>
#include <errl/errlentry.H>
#include <utility>
-#include <config.h>
namespace PNOR
{
@@ -269,7 +268,6 @@ bool cmpSecurebootMagicNumber(const uint8_t* i_vaddr);
* False otherwise.
*/
bool isSectionEmpty(const PNOR::SectionId i_section);
-
} // PNOR
#endif
diff --git a/src/include/usr/runtime/customize_attrs_for_payload.H b/src/include/usr/runtime/customize_attrs_for_payload.H
index a5158f996..6d6928bda 100644
--- a/src/include/usr/runtime/customize_attrs_for_payload.H
+++ b/src/include/usr/runtime/customize_attrs_for_payload.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,7 +33,7 @@
*/
#include <errl/errlentry.H>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <targeting/common/attributes.H>
namespace RUNTIME
@@ -42,7 +42,7 @@ namespace RUNTIME
static const TARGETING::ATTR_HBRT_HYP_ID_type HBRT_HYP_ID_UNKNOWN
= 0xFFFFFFFFFFFFFFFFULL;
-static const RT_TARG::rtChipId_t RT_TYPE_UNKNOWN
+static const TARGETING::rtChipId_t RT_TYPE_UNKNOWN
= 0xFFFFFFFFFFFFFFFFULL;
/**
diff --git a/src/include/usr/runtime/runtime.H b/src/include/usr/runtime/runtime.H
index 9d22e387b..eba9f68bf 100644
--- a/src/include/usr/runtime/runtime.H
+++ b/src/include/usr/runtime/runtime.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -188,7 +188,7 @@ errlHndl_t sendSBESystemConfig();
// HOMER*8/OCC_Common/VPD/ATTR/HBRT_Image/Res/Res/Res
// should be the same as HDAT_RHB_MAX_RANGE_ENTRIES_PER_NODE in
// src/hdat/fsp/hdat.H
-#define HB_RSV_MEM_NUM_PTRS 50
+#define HB_RSV_MEM_NUM_PTRS 60
//Note this means the Reserved Mem sub-section is the 6th
//(0 based) of the MDT section (See HDAT spec 11.1.1)
diff --git a/src/include/usr/runtime/runtime_reasoncodes.H b/src/include/usr/runtime/runtime_reasoncodes.H
index 6b77d621a..8bc4c858d 100644
--- a/src/include/usr/runtime/runtime_reasoncodes.H
+++ b/src/include/usr/runtime/runtime_reasoncodes.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -66,6 +66,10 @@ namespace RUNTIME
MOD_CHECK_HB_RES_MEM_LIMIT = 0x26, /**< populate_hbruntime.C */
MOD_INIT_RT_RES_MEM_TRACE_BUF = 0x27, /**< rt_rsvdtracebuffer.C */
MOD_OPEN_UNTRUSTED_SP_AREAS = 0x28, /**< populate_hbruntime.C */
+ MOD_SEND_ATTRIBUTES_TO_FSP = 0x29, /**< hbrt_utilities.H */
+ MOD_RT_DO_NVDIMM_OP = 0x2A, /**< rt_fwnotify.C */
+ SET_ATTR_NVDIMM_ENCRYPTION_ENABLE = 0x2B, /**< rt_fwnotify.C */
+ MOD_CONFIGURE_HBRT_HYP_IDS = 0x2C,
};
enum RuntimeReasonCode
@@ -139,6 +143,13 @@ namespace RUNTIME
RC_SP_ATTN_AREA_OVERFLOW = RUNTIME_COMP_ID | 0x42,
RC_SP_ATTN_AREA1_SIZE_OVERFLOW = RUNTIME_COMP_ID | 0x43,
RC_UNKNOWN_LABEL = RUNTIME_COMP_ID | 0x44,
+ RC_NULL_FIRMWARE_MSG_PTR = RUNTIME_COMP_ID | 0x45,
+ RC_SERIALIZE_ATTRIBUTE_FAILED = RUNTIME_COMP_ID | 0x46,
+ RC_NO_SPACE_FOR_ATTRIBUTE_SERIALIZATION = RUNTIME_COMP_ID | 0x47,
+ RC_CANNOT_MAKE_ATTRIBUTE = RUNTIME_COMP_ID | 0x48,
+ RT_NO_OMI_TARGET_FOUND = RUNTIME_COMP_ID | 0x49,
+ RC_LOG_GARD_EVENT_UNKNOWN_ERROR_TYPE = RUNTIME_COMP_ID | 0x4A,
+ RC_LOG_GARD_EVENT = RUNTIME_COMP_ID | 0x4B,
};
enum UserDetailsTypes
diff --git a/src/include/usr/sbeio/runtime/sbe_msg_passing.H b/src/include/usr/sbeio/runtime/sbe_msg_passing.H
index e50b4493e..e280e3e2f 100644
--- a/src/include/usr/sbeio/runtime/sbe_msg_passing.H
+++ b/src/include/usr/sbeio/runtime/sbe_msg_passing.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -90,6 +90,7 @@ namespace SBE_MSG
PASSTHRU_HBRT_GET_PSTATE = 0x00E10001, // HBRT Get PState Table
PASSTHRU_HBRT_OVERRIDE_ATTR = 0x00E10002, // HBRT Apply Override
// attributes
+ PASSTHRU_HBRT_NVDIMM_OP = 0x00E10003, // HBRT NVDIMM operation
};
diff --git a/src/include/usr/sbeio/runtime/sbeio_nvdimm_operation.H b/src/include/usr/sbeio/runtime/sbeio_nvdimm_operation.H
new file mode 100644
index 000000000..2b650bfae
--- /dev/null
+++ b/src/include/usr/sbeio/runtime/sbeio_nvdimm_operation.H
@@ -0,0 +1,58 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/sbeio/runtime/sbeio_nvdimm_operation.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SBE_MSG_SBEIO_NVDIMM_OPERATION_H
+#define __SBE_MSG_SBEIO_NVDIMM_OPERATION_H
+
+#include <errl/errlentry.H>
+#include <targeting/common/target.H>
+
+namespace SBE_MSG
+{
+
+/**
+ * @brief SBE pass-through command for executing nvdimm operations at runtime.
+ * This command acts as a bridge between sbe pass-through and the
+ * runtime doNvDimmOperation function.
+ *
+ * @param[in] i_targetHandle - The target of the request.
+ * @param[in] i_reqDataSize - Size of the nvdimm operation blob.
+ * @param[in] i_reqData - NVDIMM operation data.
+ * @param[out] o_rspStatus - The return value from doNvDimmOperation
+ * @param[out] o_rspDataSize - Set to 0 on return.
+ * @param[out] o_rspData - Not Used.
+ *
+ * @return nullptr upon success, pointer to ErrlEntry if an error occurred.
+ *
+ */
+errlHndl_t sbeNvdimmOperation( TARGETING::TargetHandle_t i_targetHandle,
+ uint32_t i_reqDataSize,
+ uint8_t * i_reqData,
+ uint32_t * o_rspStatus,
+ uint32_t * o_rspDataSize,
+ uint8_t * o_rspData );
+
+}
+
+#endif
diff --git a/src/include/usr/sbeio/sbe_psudd.H b/src/include/usr/sbeio/sbe_psudd.H
index 3a21ad122..688c9086b 100644
--- a/src/include/usr/sbeio/sbe_psudd.H
+++ b/src/include/usr/sbeio/sbe_psudd.H
@@ -338,7 +338,7 @@ class SbePsu
*/
enum psuSecurityListBinDumpNonReservedMsgs
{
- SBE_SECURITY_LIST_BIN_DUMP_REQ_USED_REGS = 0x01,
+ SBE_SECURITY_LIST_BIN_DUMP_REQ_USED_REGS = 0x03,
SBE_SECURITY_LIST_BIN_DUMP_RSP_USED_REGS = 0x01,
};
diff --git a/src/include/usr/scom/centaurScomCache.H b/src/include/usr/scom/centaurScomCache.H
index 94f345694..0817ae11e 100644
--- a/src/include/usr/scom/centaurScomCache.H
+++ b/src/include/usr/scom/centaurScomCache.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,11 +42,6 @@
extern trace_desc_t* g_trac_scom;
-// These defines allow standard logging of error information in traces
-#define TRACE_ERR_FMT "Error info: PLID=0x%08X, EID=0x%08X, Reason=0x%04X. "
-#define TRACE_ERR_ARGS(pError) \
- ERRL_GETPLID_SAFE(pError), ERRL_GETEID_SAFE(pError), ERRL_GETRC_SAFE(pError)
-
namespace SECUREBOOT
{
diff --git a/src/include/usr/secureboot/drtm.H b/src/include/usr/secureboot/drtm.H
index e061502ae..345407f81 100644
--- a/src/include/usr/secureboot/drtm.H
+++ b/src/include/usr/secureboot/drtm.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,7 +27,6 @@
#define __SECUREBOOT_DRTM_H
#include <initservice/mboxRegs.H>
-#include <config.h>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <vector>
diff --git a/src/include/usr/secureboot/nodecommif.H b/src/include/usr/secureboot/nodecommif.H
index cd445d7c9..9dec0605c 100644
--- a/src/include/usr/secureboot/nodecommif.H
+++ b/src/include/usr/secureboot/nodecommif.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -26,7 +26,6 @@
#define __NODECOMMIF_H
#include <initservice/mboxRegs.H>
-#include <config.h>
#include <errl/errlentry.H>
namespace SECUREBOOT
diff --git a/src/include/usr/secureboot/phys_presence_if.H b/src/include/usr/secureboot/phys_presence_if.H
new file mode 100644
index 000000000..a723e8726
--- /dev/null
+++ b/src/include/usr/secureboot/phys_presence_if.H
@@ -0,0 +1,68 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/secureboot/phys_presence_if.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file phys_presence_if.H
+ *
+ * @brief Interfaces to Detect and Open Physical Presence Windows
+ *
+ */
+#ifndef __PHYS_PRESENCE_H
+#define __PHYS_PRESENCE_H
+// -----------------------------------------------
+// Includes
+// -----------------------------------------------
+
+#include <errl/errlentry.H>
+#include <targeting/common/commontargeting.H>
+#include <config.h>
+
+namespace SECUREBOOT
+{
+ /**
+ * @brief Checks if the Physical Presence Window was opened and if
+ * Physical Presence was asserted.
+ *
+ * @post Will ensure the window is closed at the end of the function
+ *
+ * @return errlHndl_t nullptr on success; non-nullptr on error.
+ */
+ errlHndl_t detectPhysPresence(void);
+
+ /**
+ * @brief Handle Physical Presence Window first checks to see if a physical
+ * presence window should be opened. Then, if necessary, it sets up
+ * the physical presence detect circuit and then shuts down the
+ * system.
+ *
+ * @post If successful, this function will shutdown the system
+ *
+ * @return errlHndl_t nullptr on success; non-nullptr on error.
+ */
+ errlHndl_t handlePhysPresenceWindow(void);
+
+} // namespace SECUREBOOT
+
+
+#endif // __PHYS_PRESENCE_H
diff --git a/src/include/usr/secureboot/secure_reasoncodes.H b/src/include/usr/secureboot/secure_reasoncodes.H
index d121fc7b9..9e0e52c6e 100644
--- a/src/include/usr/secureboot/secure_reasoncodes.H
+++ b/src/include/usr/secureboot/secure_reasoncodes.H
@@ -53,7 +53,7 @@ namespace SECUREBOOT
MOD_CHECK_RISK_LEVEL_FOR_SMF = 0x13,
MOD_SMF_SPLIT_SMF_MEM = 0x14,
- // Use 0x20-0x2F range for Node Communications
+ // Use 0x20-0x3F range for Node Communications
MOD_NCDD_CHECK_FOR_ERRORS = 0x20,
MOD_NCDD_WAIT_FOR_CMD_COMP = 0x21,
MOD_NC_XBUS_TEST = 0x22,
@@ -70,7 +70,12 @@ namespace SECUREBOOT
MOD_NC_PROCESS_SLAVE_QUOTE = 0x2D,
MOD_NCT_SEND = 0x2E,
MOD_NCT_RECEIVE = 0x2F,
- };
+
+ // Use 0x40-0x4F range for Physical Presence Detection
+ MOD_PHYS_PRES_DETECT = 0x40,
+ MOD_PHYS_PRES_OPEN_WINDOW = 0x41,
+
+ };
enum SECUREReasonCode
{
@@ -123,6 +128,16 @@ namespace SECUREBOOT
RC_NCT_INITIATION_MISMATCH = SECURE_COMP_ID | 0x33,
RC_NCEX_NO_FUNCTIONAL_PRIMARY_TPM = SECURE_COMP_ID | 0x34,
+ // Use 0x20-0x3F range for Node Communications
+
+ // RC_PHYS_PRES_WINDOW_OPENED_SHUTDOWN Must have one unique use
+ // for Shutdown path since FSP relies on it.
+ // termination_rc
+ RC_PHYS_PRES_WINDOW_OPENED_SHUTDOWN = SECURE_COMP_ID | 0x40,
+ RC_PHYS_PRES_ATTR_NOT_FOUND = SECURE_COMP_ID | 0x41,
+ RC_PHYS_PRES_WINDOW_NOT_CLOSED = SECURE_COMP_ID | 0x42,
+ RC_PHYS_PRES_WINDOW_NOT_OPENED = SECURE_COMP_ID | 0x43,
+
// Reason codes 0xA0 - 0xEF reserved for trustedboot_reasoncodes.H
};
diff --git a/src/include/usr/secureboot/service.H b/src/include/usr/secureboot/service.H
index bb6ea1516..2a01cdd6b 100644
--- a/src/include/usr/secureboot/service.H
+++ b/src/include/usr/secureboot/service.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -26,7 +26,6 @@
#define __SECUREBOOT_SERVICE_H
#include <errl/errlentry.H>
-#include <config.h>
#include <secureboot/settings.H>
#include <utility>
#include <cstdint>
diff --git a/src/include/usr/secureboot/trustedbootif.H b/src/include/usr/secureboot/trustedbootif.H
index 66d44852e..16da54c03 100644
--- a/src/include/usr/secureboot/trustedbootif.H
+++ b/src/include/usr/secureboot/trustedbootif.H
@@ -41,7 +41,6 @@
#include <secureboot/containerheader.H>
#include <targeting/common/commontargeting.H>
#include <targeting/common/utilFilter.H>
-#include <config.h>
namespace TRUSTEDBOOT
{
diff --git a/src/include/usr/targeting/common/attributeTank.H b/src/include/usr/targeting/common/attributeTank.H
index a3f9afeab..1a4c5a4ce 100644
--- a/src/include/usr/targeting/common/attributeTank.H
+++ b/src/include/usr/targeting/common/attributeTank.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -34,13 +34,12 @@
#include <stdint.h>
#include <list>
#include <vector>
+#include <attributeenums.H> // TARGETING::ATTRIBUTE_ID
#ifndef STANDALONE_COMPILE
#include <targeting/adapters/mutexadapter.H>
#include <targeting/common/error.H>
namespace TARGETING
{
-
-
/**
* @class AttributeTank
*
@@ -146,6 +145,328 @@ namespace AttributeTank
#ifndef STANDALONE_COMPILE
/**
+ * @struct Attribute
+ *
+ * This structure defines a single attribute.
+ */
+ struct Attribute
+ {
+ /**
+ * @brief Constructor
+ */
+ Attribute()
+ : iv_hdr(),
+ iv_pVal(NULL)
+ {
+ }
+
+ /**
+ * @brief Destructor. Frees memory
+ */
+ ~Attribute()
+ {
+ delete[] iv_pVal;
+ iv_pVal = NULL;
+ }
+
+ /**
+ * @brief Set the Attribute ID
+ */
+ void setId(const uint32_t i_attrId)
+ {
+ iv_hdr.iv_attrId = i_attrId;
+ }
+
+ /**
+ * @brief Set the Attribute Target Type
+ */
+ void setTargetType(const uint32_t i_targetType)
+ {
+ iv_hdr.iv_targetType = i_targetType;
+ }
+
+ /**
+ * @brief Set the Attribute Position
+ */
+ void setPosition(const uint16_t i_pos)
+ {
+ iv_hdr.iv_pos = i_pos;
+ }
+
+ /**
+ * @brief Set the Attribute Unit Position
+ */
+ void setUnitPosition(const uint8_t i_unitPos)
+ {
+ iv_hdr.iv_unitPos = i_unitPos;
+ }
+
+ /**
+ * @brief Set the Attribute Node
+ */
+ void setNode(const uint8_t i_node)
+ {
+ iv_hdr.iv_node = i_node;
+ }
+
+ /**
+ * @brief Set the Attribute Flags
+ */
+ void setFlags(const uint8_t i_flags)
+ {
+ iv_hdr.iv_flags = i_flags;
+ }
+
+ /**
+ * @brief Get the size of all the Attribute's data members,
+ * aggregated together
+ *
+ * return Aggregated size of the Attribute's data members
+ */
+ uint32_t getSize() const
+ {
+ return (sizeof(iv_hdr) + iv_hdr.iv_valSize);
+ }
+
+ /**
+ * @brief Get a constant reference to the Attribute Header.
+ * Returning a reference for fast retrieval.
+ *
+ * @note Caller should not attempt to modify contents of the
+ * Attribute Header. Use appropriate Attribute set methods
+ *
+ * return A constant reference to the Attribute Header
+ */
+ const AttributeHeader & getHeader() const
+ {
+ return iv_hdr;
+ }
+
+ /**
+ * @brief Set the Attribute Value to a copy of the given buffer
+ *
+ * @pre Passing in nonsensical parameters will produce unpredictable
+ * results, ie passing in a null buffer with size > 0
+ *
+ * @note Passing in a null buffer with size 0 will clear the value
+ *
+ * @param[in] i_buffer The buffer that contains the value to
+ * be copied
+ * @param[in] i_bufferSize Size of the given buffer
+ *
+ * return The size of the data that was copied
+ */
+ uint32_t setValue(const void * const i_buffer,
+ const uint32_t i_bufferSize)
+
+ {
+ // Reuse storage when possible
+ if (i_bufferSize != iv_hdr.iv_valSize)
+ {
+ // Clean up current Attribute Value
+ delete []iv_pVal;
+ iv_pVal = NULL;
+
+ // Set size and allocate memory space
+ iv_hdr.iv_valSize = i_bufferSize;
+ if (iv_hdr.iv_valSize)
+ {
+ iv_pVal = new uint8_t[iv_hdr.iv_valSize];
+ }
+ }
+
+ // Make a copy of the data. Passing in a size of 0
+ // or NULL turns this call to no-op
+ memcpy(iv_pVal, i_buffer, iv_hdr.iv_valSize);
+
+ return iv_hdr.iv_valSize;
+ }
+
+ /**
+ * @brief Get a constant pointer to the Attribute Value.
+ * Returning a constant pointer for fast retrieval.
+ *
+ * @note Caller should not attempt to modify the contents nor
+ * delete the pointer, use method setValue if
+ * need be.
+ *
+ * return A constant pointer to the Attribute Value
+ */
+ const void* getValue() const
+ {
+ return iv_pVal;
+ }
+
+ /**
+ * @brief Return a copy of the Attribute Value into caller's bufffer
+ *
+ * @param[in] i_buffer The buffer to copy Attribute Value into
+ * @param[in] i_bufferSize Size of the given buffer
+ *
+ * return The size of the Attribute Value that was copied
+ * or 0 if unable to copy the Attribute Value - buffer
+ * size to small will cause this
+ */
+ uint32_t cloneValue(void* const o_buffer,
+ const uint32_t i_bufferSize) const
+ {
+ // Return the size of the cloned data
+ uint32_t l_attributeValueSize(0);
+
+ // Is the buffer large enough to contain the Attribute Value?
+ if (i_bufferSize >= iv_hdr.iv_valSize)
+ {
+ // Buffer is large enough to contain the Attribute Value -
+ // copy the Attribute Value to given buffer
+ memcpy(o_buffer, iv_pVal, iv_hdr.iv_valSize);
+
+ // Return the size of the cloned data
+ l_attributeValueSize = iv_hdr.iv_valSize;
+ }
+
+ return l_attributeValueSize;
+ }
+
+ /**
+ * @brief Serialize the Attribute, if the buffer given is large
+ * enough to contain the Attribute's data members
+ *
+ * @param[out] o_buffer The buffer to contain the serialized
+ * data members
+ * @param[in] i_bufferSize Size of the given buffer
+ *
+ * return 0 if buffer is to small to contain the data members;
+ * otherwise the aggregated size of the Attribute's data
+ * members copied
+ */
+ uint32_t serialize(void* const o_buffer,
+ const uint32_t i_bufferSize) const
+ {
+ // Return the size of the serialized data
+ uint32_t l_attributeSize(0);
+
+ // If buffer size greater than or equal to the size of the
+ // Attribute's data members aggregated together then
+ // copy the data members to buffer
+ if (i_bufferSize >= getSize())
+ {
+ // Get an Attribute handle to buffer for easy access
+ uint8_t* l_attribute = static_cast<uint8_t*>(o_buffer);
+
+ // Copy the Attribute Header
+ memcpy(l_attribute, &iv_hdr, sizeof(iv_hdr));
+ l_attribute += sizeof(iv_hdr);
+
+ // Copy the Attribute Value
+ memcpy(l_attribute, iv_pVal, iv_hdr.iv_valSize);
+
+ // Return the size of the serialized data
+ l_attributeSize = sizeof(iv_hdr) + iv_hdr.iv_valSize;
+ }
+
+ return l_attributeSize;
+ }
+
+ /**
+ * @brief Deserialize the buffer, if the buffer given is at least
+ * the same size as an Attribute
+ *
+ * @param[out] i_buffer The buffer to deserialize
+ * @param[in] i_bufferSize Size of the given buffer
+ *
+ * @post If the buffer is large enough to populate the Attribute, then
+ * the Attribute will be populated, with it's own copy of the
+ * data. If the buffer is too small, then the Attribute is
+ * untouched.
+ *
+ * return 0 if buffer is to small to populate an Attribute;
+ * otherwise the aggregated size of the Attribute's data
+ * members deserialized
+ */
+ uint32_t deserialize(const void* const i_buffer,
+ const uint32_t i_bufferSize)
+ {
+ // Return the size of the Attribute
+ uint32_t l_attributeSize(0);
+
+ // Get an Attribute handle to buffer for easy access
+ const Attribute* const l_attribute =
+ reinterpret_cast<const Attribute* const>(i_buffer);
+
+ // Get the minimum size needed to check for values
+ uint32_t l_attributeHeaderSize(sizeof(iv_hdr));
+
+ // Make sure the buffer is not just large enough to inspect the
+ // Attribute Header but large enough to read Values if they exist
+ // Need to make sure size is at minimum threshold before calling
+ // getSize(), because getSize assumes the data is there to read
+ if ( (i_bufferSize >= l_attributeHeaderSize) &&
+ (i_bufferSize >= (l_attribute->getSize())) )
+ {
+ // Get an uint8_t handle to buffer for easy access
+ const uint8_t* l_attributeData =
+ reinterpret_cast<const uint8_t*>(i_buffer);
+
+ // Copy header data
+ memcpy(&iv_hdr, l_attributeData, l_attributeHeaderSize);
+
+ // Free iv_pVal data, if it currently has data, and set to NULL
+ delete []iv_pVal; // OK to delete a NULL ptr
+ iv_pVal = NULL;
+
+ // Populate values if they exist
+ uint32_t l_valueSize = iv_hdr.iv_valSize;
+ if (l_valueSize)
+ {
+ // Copy the Attribute Value
+ iv_pVal = new uint8_t[l_valueSize];
+ l_attributeData += l_attributeHeaderSize;
+ memcpy(iv_pVal, l_attributeData, l_valueSize);
+ }
+
+ // Return the size of the Attribute
+ l_attributeSize = getSize();
+ }
+
+ return l_attributeSize;
+ }
+
+
+ /**
+ * @brief Assignment operator defined
+ */
+ Attribute& operator=(const Attribute& rhs)
+ {
+ // check for self-assignment
+ if (&rhs != this)
+ {
+ // Deep copy the attribute value
+ setValue(rhs.iv_pVal, rhs.iv_hdr.iv_valSize);
+ // Copy the Attribute header
+ iv_hdr = rhs.iv_hdr;
+ }
+
+ return *this;
+ }
+
+ /**
+ * @brief Copy constructor defined
+ */
+ Attribute(const Attribute& rhs)
+ : iv_hdr(),
+ iv_pVal(NULL)
+ {
+ // Call the assignment operator to do the work
+ *this = rhs;
+ }
+
+ // Private data
+ private:
+ AttributeHeader iv_hdr;
+ uint8_t * iv_pVal; // Pointer to attribute value
+ };
+
+ /**
* @struct AttributeSerializedChunk
*
* This structure defines a chunk of memory for containing serialized
@@ -183,7 +504,7 @@ namespace AttributeTank
/**
* @brief Destructor. Deletes all Attributes
*/
- virtual ~AttributeTank();
+ ~AttributeTank();
/**
* @brief Checks if the platform has enabled synchronization
@@ -209,9 +530,8 @@ namespace AttributeTank
* specific node (i_node)
* @param[in] i_node See i_nodeFilter
*/
- virtual void clearAllAttributes(
- const NodeFilter i_nodeFilter = NODE_FILTER_NONE,
- const uint8_t i_node = ATTR_NODE_NA);
+ void clearAllAttributes(const NodeFilter i_nodeFilter = NODE_FILTER_NONE,
+ const uint8_t i_node = ATTR_NODE_NA);
/**
* @brief Clear any non-const attribute for a specified ID and Target
@@ -225,11 +545,11 @@ namespace AttributeTank
* @param[in] i_unitPos Target Unit Position
* @param[in] i_node Target Node
*/
- virtual void clearNonConstAttribute(const uint32_t i_attrId,
- const uint32_t i_targetType,
- const uint16_t i_pos,
- const uint8_t i_unitPos,
- const uint8_t i_node);
+ void clearNonConstAttribute(const uint32_t i_attrId,
+ const uint32_t i_targetType,
+ const uint16_t i_pos,
+ const uint8_t i_unitPos,
+ const uint8_t i_node);
/**
* @brief Set an Attribute
@@ -251,14 +571,14 @@ namespace AttributeTank
* @param[in] i_valSize Size of attribute value in bytes
* @param[in] i_pVal Pointer to attribute value
*/
- virtual void setAttribute(const uint32_t i_attrId,
- const uint32_t i_targetType,
- const uint16_t i_pos,
- const uint8_t i_unitPos,
- const uint8_t i_node,
- const uint8_t i_flags,
- const uint32_t i_valSize,
- const void * i_pVal);
+ void setAttribute(const uint32_t i_attrId,
+ const uint32_t i_targetType,
+ const uint16_t i_pos,
+ const uint8_t i_unitPos,
+ const uint8_t i_node,
+ const uint8_t i_flags,
+ const uint32_t i_valSize,
+ const void * i_pVal);
/**
* @brief Get a copy of an Attribute
@@ -266,21 +586,24 @@ namespace AttributeTank
* This is called on an OverrideAttributeTank to query/get an Attribute
* Override when an attribute is got
*
+ * @note Caller's responsibility to ensure the passed in buffer
+ * is large enough to contain the Attribute Value.
+ *
* @param[in] i_attrId Attribute ID
* @param[in] i_targetType Target Type attribute is for
* @param[in] i_pos Target Position
* @param[in] i_unitPos Target Unit Position
* @param[in] i_node Target Node
- * @param[out] o_pVal Pointer to attribute value
+ * @param[out] o_pVal Pointer to a copy of the attribute value
*
* return true if attribute exists and a copy was written to o_pVal
*/
- virtual bool getAttribute(const uint32_t i_attrId,
- const uint32_t i_targetType,
- const uint16_t i_pos,
- const uint8_t i_unitPos,
- const uint8_t i_node,
- void * o_pVal) const;
+ bool getAttribute(const uint32_t i_attrId,
+ const uint32_t i_targetType,
+ const uint16_t i_pos,
+ const uint8_t i_unitPos,
+ const uint8_t i_node,
+ void * o_pVal) const;
/**
* @brief Serialize all Attributes into newly allocated memory chunks
@@ -310,7 +633,7 @@ namespace AttributeTank
* specific node (i_node)
* @param[in] i_node See i_nodeFilter
*/
- virtual void serializeAttributes(
+ void serializeAttributes(
const AllocType i_allocType,
const uint32_t i_chunkSize,
std::vector<AttributeSerializedChunk> & o_attributes,
@@ -327,8 +650,7 @@ namespace AttributeTank
* @param[in] i_attributes Reference to AttributeSerializedChunk containing
* attributes.
*/
- virtual void deserializeAttributes(
- const AttributeSerializedChunk & i_attributes);
+ void deserializeAttributes(const AttributeSerializedChunk & i_attributes);
/**
@@ -344,9 +666,8 @@ namespace AttributeTank
*
* @param[in] i_echoAttributes Select whether or not to echo the attributes
*/
- virtual void deserializeAttributes(
- const AttributeSerializedChunk & i_attributes,
- bool i_echoAttributes );
+ void deserializeAttributes(const AttributeSerializedChunk & i_attributes,
+ bool i_echoAttributes );
/**
@@ -359,7 +680,7 @@ namespace AttributeTank
*
* return true if any attributes exist
*/
- virtual bool attributesExist() const { return iv_attributesExist; }
+ bool attributesExist() const { return iv_attributesExist; }
/**
* @brief Check if an attribute exists in the tank
@@ -374,7 +695,7 @@ namespace AttributeTank
*
* return true if any attributes exist
*/
- virtual bool attributeExists(const uint32_t i_attrId) const;
+ bool attributeExists(const uint32_t i_attrId) const;
/**
* @brief This function writes attributes in an AttributeTank to targeting
@@ -392,32 +713,25 @@ namespace AttributeTank
*/
size_t size() const;
-private:
- // Copy constructor and assignment operator disabled
- AttributeTank(const AttributeTank & i_right);
- AttributeTank & operator=(const AttributeTank & i_right);
-
/**
- * @struct Attribute
+ * @brief Return a copy of all attributes in the tank
*
- * This structure defines a single attribute.
+ * @param[out] List of all attributes in this tank
+ * @return n/a
*/
- struct Attribute
- {
- /**
- * @brief Constructor
- */
- Attribute();
+ void getAllAttributes( std::list<Attribute *>& o_attributes ) const;
- /**
- * @brief Destructor. Frees memory
- */
- ~Attribute();
+ /**
+ * @brief Return a string description of the given tank layer
+ *
+ * @return String representation of layer
+ */
+ static const char* layerToString( TankLayer i_layer );
- // Public data
- AttributeHeader iv_hdr;
- uint8_t * iv_pVal; // Pointer to attribute value
- };
+private:
+ // Copy constructor and assignment operator disabled
+ AttributeTank(const AttributeTank & i_right);
+ AttributeTank & operator=(const AttributeTank & i_right);
// The attributes
// Note: A possible performance boost could be to store the elements in a
@@ -429,7 +743,8 @@ private:
// Lock for thread safety (class provided by platform)
mutable TARG_MUTEX_TYPE iv_mutex;
-};
+
+}; // end AttributeTank
#endif //STANDALONE_COMPILE
diff --git a/src/include/usr/targeting/common/hbrt_target.H b/src/include/usr/targeting/common/hbrt_target.H
new file mode 100644
index 000000000..1a6989bf4
--- /dev/null
+++ b/src/include/usr/targeting/common/hbrt_target.H
@@ -0,0 +1,45 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/targeting/common/hbrt_target.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __HBRT_TARGET_H
+#define __HBRT_TARGET_H
+
+#include <errl/errlentry.H>
+
+namespace TARGETING
+{
+ typedef uint64_t rtChipId_t;
+ /**
+ * @brief Convert a TARGETING::Target to an unit ID that can be used
+ * in calls to the runtime host
+ * @param[in] The HB TARGETING::Target
+ * @param[out] Sapphire target id
+ * @return an error handle on error
+ */
+ errlHndl_t getRtTarget(const TARGETING::Target* i_target,
+ rtChipId_t &o_targetId);
+
+}
+
+#endif \ No newline at end of file
diff --git a/src/include/usr/targeting/common/target.H b/src/include/usr/targeting/common/target.H
index 08fcb3f76..3e7eb82e7 100644
--- a/src/include/usr/targeting/common/target.H
+++ b/src/include/usr/targeting/common/target.H
@@ -47,6 +47,9 @@
#include <targeting/common/util.H>
#include <targeting/common/pointer.H>
#include <vector>
+#ifdef __HOSTBOOT_MODULE
+#include <array>
+#endif
// This component
#include <targeting/common/attributes.H>
@@ -181,6 +184,34 @@ class Target
template<const ATTRIBUTE_ID A>
bool tryGetAttrNotSynced(
typename AttributeTraits<A>::Type& o_attrValue) const;
+
+ /**
+ * @brief Try to get the target's specified std::array attribute value
+ *
+ * A special tryGetAttr function for getting the attribute values
+ * of the attributes which support std::array.
+ * It returns false (with invalid o_attrValue) if the specified
+ * attribute does not exist for the associated target, true (with a
+ * valid o_attrValue) otherwise.
+ *
+ * @param[out] o_attrValue Value of the attribute
+ *
+ * @pre Target service must be initialized
+ *
+ * @post See "return"
+ *
+ * @return bool indicating whether the specified attribute was returned
+ * or not
+ *
+ * @retval true Attribute returned in o_attrValue
+ * @retval false Attribute not found; o_attValue not valid
+ */
+#ifdef __HOSTBOOT_MODULE
+ template<const ATTRIBUTE_ID A>
+ bool tryGetAttr(
+ typename AttributeTraits<A>::TypeStdArr& o_attrValue) const;
+#endif
+
/**
* @brief Get the target's specified attribute value
*
@@ -250,6 +281,26 @@ class Target
const char* getAttrAsString() const;
/**
+ * @brief For targets whose attribute value type is an array, return
+ * the array in std::array form.
+ *
+ * @pre Target service must be initialized
+ *
+ * @post Target's specified attribute value returned as a std::array,
+ * or assert called if specified attribute doesn't exist for the
+ * associated target or type is not an array
+ *
+ * @return std::array
+ *
+ * @retval Content and dimension varies, see xml file where the
+ * attribute's type is set
+ */
+#ifdef __HOSTBOOT_MODULE
+ template<const ATTRIBUTE_ID A>
+ typename AttributeTraits<A>::TypeStdArr getAttrAsStdArr() const;
+#endif
+
+ /**
* @brief Tries to set the target's specified attribute value
*
* Attempts to set the target's specified attribute value. It
@@ -298,6 +349,34 @@ class Target
typename AttributeTraits<A>::Type const& i_attrValue);
/**
+ *
+ * @brief Tries to set the target's specified std::array attribute value
+ *
+ * A special trySetAttr function for setting the attribute values
+ * of the attributes which support std::array.
+ * It returns false if the specified attribute does not exist for the
+ * associated target, true otherwise.
+ *
+ * @param[in] i_attrValue Value of the attribute
+ *
+ * @pre Target service must be initialized
+ *
+ * @post Target's attribute value updated (if it exists), and caller
+ * notified whether the update occurred or not.
+ *
+ * @return bool indicating whether the specified attribute was updated
+ * or not
+ *
+ * @retval true Attribute updated
+ * @retval false Attribute not updated
+ */
+#ifdef __HOSTBOOT_MODULE
+ template<const ATTRIBUTE_ID A>
+ bool trySetAttr(
+ typename AttributeTraits<A>::TypeStdArr const& i_attrValue);
+#endif
+
+ /**
* @brief Returns pointer to a mutex attribute associated with the
* target
*
@@ -361,6 +440,23 @@ class Target
void setAttr(typename AttributeTraits<A>::Type const& i_attrValue);
/**
+ * @brief For targets whose attribute value type is an array, set value
+ * from a std::array of any dimension
+ *
+ * @param[in] i_attrValue Value of the attribute
+ *
+ * @pre Target service must be initialized
+ *
+ * @post Target's attribute value updated if it exists and if it
+ * suppports TypeStdArr type, otherwise routine asserts
+ */
+#ifdef __HOSTBOOT_MODULE
+ template<const ATTRIBUTE_ID A>
+ void setAttrFromStdArr(typename AttributeTraits<A>::TypeStdArr const&
+ i_attrValue);
+#endif
+
+ /**
* @brief Perform FFDC for the target instance
*
* @param[out] io_size
@@ -488,7 +584,16 @@ class Target
return _trySetAttr(i_attr, i_size, i_pAttrData);
}
-
+ /**
+ * @brief Returns the target's type as used in a Targeting attribute
+ * tank.
+ *
+ * This target type is associated with an attribute in an attribute
+ * tank and helps identify which target(s) the attribute belongs to
+ *
+ * @return uint32_t The target type
+ */
+ uint32_t getAttrTankTargetType() const;
private: // Private helper interfaces
@@ -713,24 +818,15 @@ class Target
mutex_t*& o_pMutex) const;
/**
- * @brief Returns the target's type as used in a Targeting attribute
- * tank.
- *
- * This target type is associated with an attribute in an attribute
- * tank and helps identify which target(s) the attribute belongs to
- *
- * @return uint32_t The target type
- */
- uint32_t getAttrTankTargetType() const;
-
- /**
* @brief enumeration of assert reasons
*/
enum TargAssertReason
{
SET_ATTR,
+ SET_ATTR_FROM_STD_ARR,
GET_ATTR,
GET_ATTR_AS_STRING,
+ GET_ATTR_AS_STD_ARRAY,
GET_HB_MUTEX_ATTR,
GET_ATTR_TANK_TARGET_POS_DATA,
GET_ATTR_TANK_TARGET_POS_DATA_ATTR,
@@ -865,6 +961,19 @@ bool Target::tryGetAttr(typename AttributeTraits<A>::Type& o_attrValue) const
return _tryGetAttr(A,sizeof(o_attrValue),&o_attrValue);
}
+#ifdef __HOSTBOOT_MODULE
+template<const ATTRIBUTE_ID A>
+bool Target::tryGetAttr(
+ typename AttributeTraits<A>::TypeStdArr& o_attrValue) const
+{
+ if(AttributeTraits<A>::readable == AttributeTraits<A>::readable) { }
+ if(AttributeTraits<A>::notHbMutex == AttributeTraits<A>::notHbMutex) { }
+ if(AttributeTraits<A>::fspAccessible == AttributeTraits<A>::fspAccessible)
+ { }
+ return _tryGetAttr(A, sizeof(o_attrValue), &o_attrValue);
+}
+#endif
+
template<const ATTRIBUTE_ID A>
bool Target::trySetAttr(typename AttributeTraits<A>::Type const& i_attrValue)
{
@@ -886,6 +995,17 @@ bool Target::trySetAttrNotSynced(
return _trySetAttr(A,sizeof(i_attrValue),&i_attrValue);
}
+#ifdef __HOSTBOOT_MODULE
+template<const ATTRIBUTE_ID A>
+bool Target::trySetAttr(typename AttributeTraits<A>::TypeStdArr
+ const& i_attrValue)
+{
+ if(AttributeTraits<A>::writeable == AttributeTraits<A>::writeable) { }
+ if(AttributeTraits<A>::notHbMutex == AttributeTraits<A>::notHbMutex) { }
+ return _trySetAttr(A,sizeof(i_attrValue),&i_attrValue);
+}
+#endif
+
template<const ATTRIBUTE_ID A>
typename AttributeTraits<A>::Type Target::getAttr() const
{
@@ -933,6 +1053,19 @@ void Target::setAttr(typename AttributeTraits<A>::Type const& i_attrValue)
}
}
+#ifdef __HOSTBOOT_MODULE
+template<const ATTRIBUTE_ID A>
+void Target::setAttrFromStdArr(typename AttributeTraits<A>::TypeStdArr const&
+ i_attrValue)
+{
+ bool l_wrote = trySetAttr<A>(i_attrValue);
+ if (unlikely(!l_wrote))
+ {
+ targAssert(SET_ATTR_FROM_STD_ARR, A);
+ }
+}
+#endif
+
template<const ATTRIBUTE_ID A>
mutex_t* Target::getHbMutexAttr() const
{
@@ -978,6 +1111,23 @@ const char* Target::getAttrAsString() const
return attrToString<A>(l_attrValue);
}
+#ifdef __HOSTBOOT_MODULE
+template<const ATTRIBUTE_ID A>
+typename AttributeTraits<A>::TypeStdArr Target::getAttrAsStdArr() const
+{
+ typename AttributeTraits<A>::TypeStdArr l_stdArr;
+
+ bool l_read = tryGetAttr<A>(l_stdArr);
+
+ if (unlikely(!l_read))
+ {
+ targAssert(GET_ATTR_AS_STD_ARRAY, A);
+ }
+
+ return l_stdArr;
+}
+#endif
+
// Function to set various frequency related attributes
/**
* @brief - sets various attributes directly related to the nest frequency.
diff --git a/src/include/usr/targeting/common/targetUtil.H b/src/include/usr/targeting/common/targetUtil.H
new file mode 100644
index 000000000..86a49c8b0
--- /dev/null
+++ b/src/include/usr/targeting/common/targetUtil.H
@@ -0,0 +1,154 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/targeting/common/targetUtil.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+/**
+ * @file
+ *
+ * @brief Defines templates methods that require the use of the
+ * class Target and struct Attribute. Having the methods
+ * in this file helps with circular dependencies issue.
+ */
+
+#ifndef __TARGETING_COMMON_TARGET_UTIL_H
+#define __TARGETING_COMMON_TARGET_UTIL_H
+
+#include <stdint.h> // int16_t, uint8_t
+#include <attributeenums.H> // TARGETING::ATTRIBUTE_ID
+#include <targeting/common/target.H> // Target
+#include <targeting/common/attributeTank.H> // AttributeTank::Attribute
+
+#ifndef STANDALONE_COMPILE
+
+namespace TARGETING
+{
+/**
+ * @brief Returns the target handle's attribute associated with the given
+ * simple type attribute ID.
+ *
+ * @param[in] i_target The target to retrieve the attribute data from
+ * @param[out] o_attribute The attribute data, for the given attribute ID,
+ * if found
+ *
+ * @pre i_target must be a valid target
+ *
+ * @return Attribute data for given attribute ID, if found, else
+ * outgoing attribute will not touched
+ *
+ * @retval true is successful in locating the attribute ID, false otherwise
+ */
+template<const ATTRIBUTE_ID A>
+bool makeAttribute(TargetHandle_t i_target,
+ AttributeTank::Attribute& o_attribute)
+{
+ // Set up the return value to true ... hoping for the best
+ bool retVal(true);
+
+ do
+ {
+ // Some needed variables and their defaults
+ uint16_t l_positon(TARGETING::AttributeTank::ATTR_POS_NA);
+ uint8_t l_unitPositon(AttributeTank::ATTR_UNIT_POS_NA),
+ l_node(AttributeTank::ATTR_NODE_NA);
+
+ // Get the target's position data
+ i_target->getAttrTankTargetPosData(l_positon, l_unitPositon, l_node);
+
+ // Get the target's type and the target's attribute data
+ auto l_targetType = i_target->getAttrTankTargetType();
+ auto l_attributeData = i_target->getAttr<A>();
+
+ // Populate the outgoing Attribute with the data retrieved above
+ o_attribute.setId(A);
+ o_attribute.setTargetType(l_targetType);
+ o_attribute.setPosition(l_positon);
+ o_attribute.setUnitPosition(l_unitPositon);
+ o_attribute.setNode(l_node);
+ o_attribute.setValue(&l_attributeData, sizeof(l_attributeData));
+ } while (0);
+
+ return retVal;
+}; // end makeAttribute
+
+/**
+ * @brief Returns the target handle's attribute associated with the given
+ * complex type attribute ID.
+ *
+ * @param[in] i_target The target to retrieve the attribute data from
+ * @param[out] o_attribute The attribute data, for the given attribute ID,
+ * if found
+ *
+ * @pre i_target must be a valid target
+ *
+ * @return Attribute data for given attribute ID, if found, else
+ * outgoing attribute will not touched
+ *
+ * @retval true is successful in locating the attribute ID, false otherwise
+ */
+template<const ATTRIBUTE_ID A>
+bool makeAttributeStdArr(TargetHandle_t i_target,
+ AttributeTank::Attribute& o_attribute)
+{
+ // Set up the return value to true ... hoping for the best
+ bool retVal(true);
+
+ // Variable to hold the complex type, when found
+ typename AttributeTraits<A>::TypeStdArr l_attributeValue;
+
+ do
+ {
+ // Some needed variables and their defaults
+ uint16_t l_positon(TARGETING::AttributeTank::ATTR_POS_NA);
+ uint8_t l_unitPositon(AttributeTank::ATTR_UNIT_POS_NA),
+ l_node(AttributeTank::ATTR_NODE_NA);
+
+ // Get the target's position data
+ i_target->getAttrTankTargetPosData(l_positon, l_unitPositon, l_node);
+
+ // Get the target's type and the target's attribute data
+ auto l_targetType = i_target->getAttrTankTargetType();
+ bool l_found = i_target->tryGetAttr<A>(l_attributeValue);
+ if (!l_found)
+ {
+ retVal = false;
+ break;
+ }
+
+ // Populate the outgoing Attribute with the data retrieved above
+ o_attribute.setId(A);
+ o_attribute.setTargetType(l_targetType);
+ o_attribute.setPosition(l_positon);
+ o_attribute.setUnitPosition(l_unitPositon);
+ o_attribute.setNode(l_node);
+ o_attribute.setValue(&l_attributeValue, sizeof(l_attributeValue));
+ } while (0);
+
+ return retVal;
+}; // end makeAttributeStdArr
+
+}; // end namespace TARGETING
+
+#endif // end STANDALONE_COMPILE
+
+#endif // end __TARGETING_COMMON_TARGET_UTIL_H
diff --git a/src/include/usr/targeting/common/trace.H b/src/include/usr/targeting/common/trace.H
index bf42dd625..4376b56d7 100644
--- a/src/include/usr/targeting/common/trace.H
+++ b/src/include/usr/targeting/common/trace.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -41,7 +41,6 @@
// Other includes
#include <targeting/adapters/traceadapter.H>
#ifdef __HOSTBOOT_MODULE
-#include <config.h>
#endif
#define TARG_LOC TARG_NAMESPACE TARG_CLASS TARG_FN ": "
diff --git a/src/include/usr/targeting/common/util.H b/src/include/usr/targeting/common/util.H
index 6f0fcb307..ba41445c1 100644
--- a/src/include/usr/targeting/common/util.H
+++ b/src/include/usr/targeting/common/util.H
@@ -102,6 +102,15 @@ namespace UTIL
P9N23_P9C13_NATIVE_MODE_MINIMUM = 0x04,
P9N23_P9C13_NATIVE_SMF_RUGBY_FAVOR_SECURITY = 0x04,
P9N23_P9C13_NATIVE_SMF_RUGBY_FAVOR_PERFORMANCE = 0x05,
+
+ // Axone modes (same as DD2.3 native mode)
+ P9A_RUGBY_FAVOR_SECURITY = 0x04,
+ P9A_RUGBY_FAVOR_PERFORMANCE = 0x05,
+ // The _LOWER numbered values are equivalent to the higher
+ // values but they exist to maintain compatibility with
+ // Nimbus DD2.3 settings.
+ P9A_RUGBY_FAVOR_SECURITY_LOWER = 0x00,
+ P9A_RUGBY_FAVOR_PERFORMANCE_LOWER = 0x01,
} Risk_level;
}
diff --git a/src/include/usr/runtime/rt_targeting.H b/src/include/usr/targeting/runtime/rt_targeting.H
index 9070dbc88..c94b871a9 100644
--- a/src/include/usr/runtime/rt_targeting.H
+++ b/src/include/usr/targeting/runtime/rt_targeting.H
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/include/usr/runtime/rt_targeting.H $ */
+/* $Source: src/include/usr/targeting/runtime/rt_targeting.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -26,6 +26,7 @@
#define __RT_TARGETING_H
#include <errl/errlentry.H>
+#include <targeting/common/hbrt_target.H>
namespace TARGETING
{
@@ -34,7 +35,6 @@ namespace TARGETING
namespace RT_TARG
{
- typedef uint64_t rtChipId_t;
enum
{
@@ -43,15 +43,6 @@ namespace RT_TARG
};
- /**
- * @brief Convert a TARGETING::Target to an unit ID that can be used
- * in calls to the runtime host
- * @param[in] The HB TARGETING::Target
- * @param[out] Sapphire target id
- * @return an error handle on error
- */
- errlHndl_t getRtTarget(const TARGETING::Target* i_target,
- rtChipId_t &o_targetId);
/**
* @brief Convert a runtime chip_id (target) into a TARGETING::Target
@@ -59,7 +50,7 @@ namespace RT_TARG
* @param[out] The TARGETING::Target pointer
* @return error log handle on error else NULL
*/
- errlHndl_t getHbTarget(rtChipId_t i_rt_chip_id,
+ errlHndl_t getHbTarget(TARGETING::rtChipId_t i_rt_chip_id,
TARGETING::Target *& o_target);
/**
diff --git a/src/include/usr/util/impl/threadpool.H b/src/include/usr/util/impl/threadpool.H
index 84ee9afd7..5ad530057 100644
--- a/src/include/usr/util/impl/threadpool.H
+++ b/src/include/usr/util/impl/threadpool.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -38,6 +40,7 @@
#include <algorithm>
#include <sys/sync.h>
#include <sys/task.h>
+#include <errl/errlentry.H>
namespace Util
{
@@ -82,7 +85,11 @@ namespace __Util_ThreadPool_Impl
/** Simple constructor, call __init to avoid the in-charge and
* not-in-charge construction costs. */
- ThreadPoolImpl() { __init(); };
+ ThreadPoolImpl(bool i_checkChildRc = true) :
+ iv_checkChildRc(i_checkChildRc)
+ {
+ __init();
+ };
protected:
/** Initialize the object. */
@@ -105,7 +112,7 @@ namespace __Util_ThreadPool_Impl
*/
void __start(start_fn_t fn, void* instance);
/** Stop the thread-pool. */
- void __shutdown();
+ errlHndl_t __shutdown();
/** Outstanding work-list. */
worklist_t iv_worklist;
@@ -119,6 +126,7 @@ namespace __Util_ThreadPool_Impl
std::list<tid_t> iv_children;
/** State of object. */
bool iv_shutdown;
+ bool iv_checkChildRc;
};
diff --git a/src/include/usr/util/runtime/rt_fwnotify.H b/src/include/usr/util/runtime/rt_fwnotify.H
new file mode 100644
index 000000000..1f6bc7efb
--- /dev/null
+++ b/src/include/usr/util/runtime/rt_fwnotify.H
@@ -0,0 +1,45 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/util/runtime/rt_fwnotify.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2010,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __RUNTIME_FWNOTIFY_H
+#define __RUNTIME_FWNOTIFY_H
+
+#include <runtime/interface.h>
+
+/**
+ * @brief Perform an NVDIMM operation
+ * @param[in] nvDimmOp - A struct that contains the operation(s) to perform
+ * and a flag indicating whether to perform operation
+ * on all processors or a given single processor.
+ * @Note The operations below are in the order of which they should be
+ * performed. If a new operation is added, make sure it inserted in the
+ * correct order.
+ * The current order is: disarm -> disable encryption -> remove keys ->
+ * enable encryption -> arm
+ **/
+int doNvDimmOperation(const hostInterfaces::nvdimm_operation_t& nvDimmOp);
+
+
+
+#endif // __RUNTIME_FWNOTIFY_H
diff --git a/src/include/usr/util/threadpool.H b/src/include/usr/util/threadpool.H
index f96e0b916..43fdeba7a 100644
--- a/src/include/usr/util/threadpool.H
+++ b/src/include/usr/util/threadpool.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -58,6 +58,7 @@
#include <stdint.h>
#include <util/traits/has_lessthan.H>
#include <util/impl/threadpool.H>
+#include <errl/errlentry.H>
namespace Util
{
@@ -87,7 +88,10 @@ class ThreadPool : public Util::__Util_ThreadPool_Impl::ThreadPoolImpl
{
public:
/** Basic Constructor. Initialize ThreadPool. */
- ThreadPool() : Util::__Util_ThreadPool_Impl::ThreadPoolImpl() { };
+ ThreadPool(bool i_checkChildRc = true) :
+ Util::__Util_ThreadPool_Impl::ThreadPoolImpl(i_checkChildRc)
+ {
+ };
/** Basic Destructor. Ensures pool is properly shut down. */
~ThreadPool() { shutdown(); };
@@ -98,12 +102,20 @@ class ThreadPool : public Util::__Util_ThreadPool_Impl::ThreadPoolImpl
__start(reinterpret_cast<start_fn_t>(&run), this);
};
/** @brief Completes outstanding work and destroys worker threads.
+ * Returns an error log when any child task crashes when
+ * iv_checkChildRc is set.
*
* @note This function will block until all work is completed and
* worker threads are destroyed.
+ *
+ * @return nullptr if all child tasks finished (child status
+ * checking disabled);
+ * nullptr if all child tasks finished successfully, or a
+ * pointer to error log otherwise (child status checking
+ * enabled).
*/
- void shutdown()
- { __shutdown(); };
+ errlHndl_t shutdown()
+ { return __shutdown(); };
/** @brief Insert a work item onto the thread-pool's queue.
*
diff --git a/src/include/usr/util/util_reasoncodes.H b/src/include/usr/util/util_reasoncodes.H
index 17ea0edfc..1f8146baf 100644
--- a/src/include/usr/util/util_reasoncodes.H
+++ b/src/include/usr/util/util_reasoncodes.H
@@ -53,6 +53,7 @@ namespace Util
UTIL_MOD_GET_OBUS_PLL_BUCKET = 0x14, // UtilCommonAttr::getObusPllBucket
UTIL_LIDMGR_CSTOR = 0x15, // UtilLidMgr::UtilLidMgr
UTIL_MCL_PROCESS_SINGLE_COMP = 0x16, // UtilLidMgr::processSingleComponent
+ UTIL_MOD_TP_SHUTDOWN = 0x17, // Util::__Util_ThreadPool_Impl::ThreadPoolImpl::__shutdown
};
enum ReasonCode
@@ -85,6 +86,7 @@ namespace Util
UTIL_ERC_NO_MATCHING_FREQ = UTIL_COMP_ID | 0x1B,
UTIL_LIDMGR_INVAL_LID_REQUEST = UTIL_COMP_ID | 0x1C,
UTIL_LIDMGR_INVAL_COMP = UTIL_COMP_ID | 0x1D,
+ UTIL_RC_CHILD_TASK_FAILED = UTIL_COMP_ID | 0x1E,
};
};
diff --git a/src/include/usr/util/utillidmgr.H b/src/include/usr/util/utillidmgr.H
index e78eba133..bd1c587c0 100644
--- a/src/include/usr/util/utillidmgr.H
+++ b/src/include/usr/util/utillidmgr.H
@@ -63,6 +63,10 @@ enum LidId
TARGETING_BINARY_LIDID = 0x81e00630,
NVDIMM_16GB_LIDID = 0x81e00640,
NVDIMM_32GB_LIDID = 0x81e00641,
+ NVDIMM_16GB_BPM_FW_LIDID = 0x81e00642,
+ NVDIMM_32GB_BPM_FW_LIDID = 0x81e00643,
+ NVDIMM_16GB_BPM_CONFIG_LIDID = 0x81e00644,
+ NVDIMM_32GB_BPM_CONFIG_LIDID = 0x81e00645,
UCD_LIDID = 0x81e00650,
INVALID_LIDID = 0xFFFFFFFF
diff --git a/src/include/usr/vmmconst.h b/src/include/usr/vmmconst.h
index b6841eea4..f826f45d2 100644
--- a/src/include/usr/vmmconst.h
+++ b/src/include/usr/vmmconst.h
@@ -31,7 +31,6 @@
*/
#include <limits.h>
-#include <config.h>
/**
* Segments
@@ -208,9 +207,13 @@ enum BlockPriority
#define VMM_MODULE_VPD_SIZE (512*KILOBYTE) /* must be 64KB aligned */
#define VMM_CENTAUR_VPD_SIZE (256*KILOBYTE) /* must be 64KB aligned */
#define VMM_DIMM_JEDEC_VPD_SIZE (256*KILOBYTE) /* must be 64KB aligned */
+#ifndef CONFIG_SUPPORT_EEPROM_CACHING
#define VMM_RT_VPD_SIZE ( VMM_MODULE_VPD_SIZE + \
VMM_CENTAUR_VPD_SIZE + \
VMM_DIMM_JEDEC_VPD_SIZE )
+#else
+#define VMM_RT_VPD_SIZE (512*KILOBYTE) /* 64KB aligned (size EECACHE section size - ecc) */
+#endif
/** Internode communication area outside of the HB image.
diff --git a/src/include/usr/vpd/spdenums.H b/src/include/usr/vpd/spdenums.H
index a6577ed12..f1dc7aa29 100644
--- a/src/include/usr/vpd/spdenums.H
+++ b/src/include/usr/vpd/spdenums.H
@@ -46,6 +46,19 @@ enum
};
/**
+* @brief Enumerations for common SPD values
+*/
+enum
+{
+ MEM_DDR3 = 0xB,
+ MEM_DDR4 = 0xC,
+ DDR3_SPD_SIZE = 256,
+ DDR4_SPD_SIZE = 512,
+ DDIMM_DDR4_SPD_SIZE = 640,
+ MEM_DDIMM = 0xA
+};
+
+/**
* @brief Enumerations for fields that can be accessed in the SPD
*/
enum
@@ -343,9 +356,15 @@ enum
LRMM_CRC = SPD_FIRST_MOD_SPEC | 0xb4,
SPD_LAST_MOD_SPEC = SPD_FIRST_MOD_SPEC | 0xb5,
+ // Latest DDR SPD specifcations have standard SPD
+ // in the front followed by extendable function
+ // descriptors (EFDs). ENTIRE_SPD will grab everything
+ // ENTIRE_SPD_WITHOUT_EFD will skip getting the EFD info
+ ENTIRE_SPD_WITHOUT_EFD = 0xFFFD,
+ //read entire SPD contents
+ ENTIRE_SPD = 0xFFFE,
// This keyword should be last in the list
// Invalid Keyword
- ENTIRE_SPD = 0xFFFE, //read entire SPD
INVALID_SPD_KEYWORD = 0xFFFF,
};
diff --git a/src/include/usr/vpd/vpd_if.H b/src/include/usr/vpd/vpd_if.H
index 4e63a0965..b649b46ab 100644
--- a/src/include/usr/vpd/vpd_if.H
+++ b/src/include/usr/vpd/vpd_if.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -108,6 +108,21 @@ namespace VPD
errlHndl_t ensureCacheIsInSync ( TARGETING::Target * i_target );
/**
+ * @brief This function checks if the eeprom cache for the target is in
+ * sync with hardware and returns the result in o_isInSync.
+ *
+ * @param[in] i_target Target device
+ * @param[in] i_eepromType Eeprom content type of target device
+ * @param[out] o_isInSync true if part and serial numbers in cache match
+ * hardware. Otherwise, false.
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+ errlHndl_t ensureEepromCacheIsInSync(TARGETING::Target * i_target,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType,
+ bool & o_isInSync);
+
+ /**
* @brief This function invalidates the VPD data in the PNOR cache.
* @param[in] i_target - Target device
* @return errlHndl_t - NULL if successful, otherwise a pointer to the
diff --git a/src/include/usr/vpd/vpdreasoncodes.H b/src/include/usr/vpd/vpdreasoncodes.H
index 8a201c422..9307af7b7 100644
--- a/src/include/usr/vpd/vpdreasoncodes.H
+++ b/src/include/usr/vpd/vpdreasoncodes.H
@@ -99,7 +99,10 @@ enum vpdModuleId
// OCMB SPD
VPD_OCMB_GET_SPD = 0x90,
+ VPD_OCMB_SPD_PERFORM_OP = 0x91,
+ VPD_READ_FROM_EEPROM_SOURCE = 0x92,
+ VPD_GET_MEMTYPE = 0x93,
};
@@ -124,10 +127,10 @@ enum vpdReasonCode
VPD_MEMTYPE_NOT_SUPPORTED = VPD_COMP_ID | 0x0A,
VPD_KEYWORD_NOT_WRITABLE = VPD_COMP_ID | 0x0B,
VPD_NOT_SUPPORTED = VPD_COMP_ID | 0x0C,
- VPD_MOD_SPECIFIC_MISMATCH_UMM = VPD_COMP_ID | 0x0D,
- VPD_MOD_SPECIFIC_MISMATCH_RMM = VPD_COMP_ID | 0x0E,
- VPD_MOD_SPECIFIC_MISMATCH_CMM = VPD_COMP_ID | 0x0F,
- VPD_MOD_SPECIFIC_MISMATCH_LRMM = VPD_COMP_ID | 0x10,
+ VPD_MOD_SPECIFIC_MISMATCH_UMM = VPD_COMP_ID | 0x0D, // Deprecated
+ VPD_MOD_SPECIFIC_MISMATCH_RMM = VPD_COMP_ID | 0x0E, // Deprecated
+ VPD_MOD_SPECIFIC_MISMATCH_CMM = VPD_COMP_ID | 0x0F, // Deprecated
+ VPD_MOD_SPECIFIC_MISMATCH_LRMM = VPD_COMP_ID | 0x10, // Deprecated
VPD_MOD_SPECIFIC_UNSUPPORTED = VPD_COMP_ID | 0x11,
VPD_SIZE_MISMATCH = VPD_COMP_ID | 0x12,
VPD_INVALID_WRITE_METHOD = VPD_COMP_ID | 0x13,
@@ -157,7 +160,7 @@ enum vpdReasonCode
VPD_BAD_REC_NUM = VPD_COMP_ID | 0x3e,
VPD_INVALID_MASTER_I2C_PATH = VPD_COMP_ID | 0x3f,
VPD_NULL_I2C_MASTER = VPD_COMP_ID | 0x40,
- VPD_MOD_SPECIFIC_MISMATCH_DDIMM = VPD_COMP_ID | 0x41,
+ VPD_INVALID_EEPROM_CONTENT_TYPE = VPD_COMP_ID | 0x41,
};
diff --git a/src/kernel/heapmgr.C b/src/kernel/heapmgr.C
index e28da77b1..d905aff88 100644
--- a/src/kernel/heapmgr.C
+++ b/src/kernel/heapmgr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2010,2018 */
+/* Contributors Listed Below - COPYRIGHT 2010,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -31,7 +31,6 @@
#include <util/align.H>
#include <arch/ppc.H>
#include <usr/debugpointers.H>
-#include <config.h>
#ifdef HOSTBOOT_DEBUG
#define SMALL_HEAP_PAGES_TRACKED 64
diff --git a/src/kernel/machchk.C b/src/kernel/machchk.C
index d17c1ff90..73f5831b6 100644
--- a/src/kernel/machchk.C
+++ b/src/kernel/machchk.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -180,7 +180,14 @@ void forceCheckstop()
{
printk( "Forcing a xstop with %p = %.16lX\n",
g_xstopRegPtr, g_xstopRegValue );
- *g_xstopRegPtr = g_xstopRegValue;
+
+ // Per PowerPC ISA :
+ // Store Doubleword Caching Inhibited Indexed
+ // stdcix RS,RA,RB
+ // let the effective address (EA) be the sum(RA|0)+ (RB).
+ // (RS) is stored into the doubleword in storage addressed by EA
+ asm volatile("stdcix %0,0,%1"
+ :: "r" (g_xstopRegValue) , "r" (reinterpret_cast <uint64_t>(g_xstopRegPtr)));
}
else
{
diff --git a/src/kernel/makefile b/src/kernel/makefile
index 211a8b10e..c2f2e0451 100644
--- a/src/kernel/makefile
+++ b/src/kernel/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2010,2018
+# Contributors Listed Below - COPYRIGHT 2010,2019
# [+] International Business Machines Corp.
#
#
@@ -24,6 +24,9 @@
# IBM_PROLOG_END_TAG
ROOTPATH = ../..
+# we need HBB to be small
+HOSTBOOT_PROFILE_NO_INSTRUMENT=1
+
OBJS += start.o
OBJS += kernel.o
OBJS += console.o
diff --git a/src/kernel/misc.C b/src/kernel/misc.C
index 7d19131ef..157d9ba22 100644
--- a/src/kernel/misc.C
+++ b/src/kernel/misc.C
@@ -121,10 +121,11 @@ namespace KernelMisc
}
else
{
- //Determine if P9N/P9C and apply URMOR hack
+ //All variants of P9 need to apply URMOR hack
uint64_t l_urmor_hack = 0x0;
PVR_t l_pvr(getPVR());
- if((l_pvr.chipFamily == PVR_t::P9_ALL))
+ if((l_pvr.chipFamily == PVR_t::P9_ALL)
+ ||((l_pvr.chipFamily == PVR_t::P9_AXONE)))
{
l_urmor_hack = 1;
}
@@ -642,10 +643,23 @@ namespace KernelMisc
l_frame = reinterpret_cast<uint64_t*>(*l_frame);
}
- printk("\n");
- }
+ if (i_task)
+ {
+ printk("\n GPRs for %d:\n", l_tid);
+ for (int i = 0; i < 16; ++i)
+ {
+ printk(" r%-2d = 0x%016lx r%-2d = 0x%016lx\n",
+ i,
+ i_task->context.gprs[i],
+ i + 16,
+ i_task->context.gprs[i + 16]);
+ }
+ }
+
+ printk("\n");
+ }
};
namespace KernelMemState
diff --git a/src/kernel/terminate.C b/src/kernel/terminate.C
index cb70e9be6..308e52b2e 100644
--- a/src/kernel/terminate.C
+++ b/src/kernel/terminate.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,6 +27,7 @@
#include <kernel/hbterminatetypes.H>
#include <kernel/terminate.H>
#include <sys/sync.h>
+#include <arch/ppc.H>
#ifndef BOOTLOADER
#include <stdint.h>
#include <kernel/console.H>
@@ -56,6 +57,9 @@ HB_Descriptor kernel_hbDescriptor =
void terminateExecuteTI()
{
+ // Trigger a hostboot dump in Simics
+ MAGIC_INSTRUCTION(MAGIC_HB_DUMP);
+
// Call the function that actually executes the TI code.
p9_force_attn();
}
@@ -128,4 +132,13 @@ void termSetHbDump(void)
return;
}
+
+void termSetIstep(uint32_t i_istep)
+{
+ // Set istep into progress code word of the SRC
+ kernel_TIDataArea.src.SRCword4 = i_istep;
+ return;
+}
+
+
#endif // BOOTLOADER
diff --git a/src/kernel/vmmmgr.C b/src/kernel/vmmmgr.C
index 553fa3d34..e9e6112e8 100644
--- a/src/kernel/vmmmgr.C
+++ b/src/kernel/vmmmgr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2010,2017 */
+/* Contributors Listed Below - COPYRIGHT 2010,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -32,7 +32,6 @@
#include <kernel/basesegment.H>
#include <kernel/stacksegment.H>
#include <kernel/devicesegment.H>
-#include <config.h>
#include <kernel/bltohbdatamgr.H>
#include <util/align.H>
diff --git a/src/lib/makefile b/src/lib/makefile
index 406d5ead8..adcfb0c2b 100644
--- a/src/lib/makefile
+++ b/src/lib/makefile
@@ -24,6 +24,8 @@
# IBM_PROLOG_END_TAG
ROOTPATH = ../..
+VPATH += ${ROOTPATH}/src/sys/prof
+
OBJS += string.o
OBJS += string_ext.o
OBJS += string_utils.o
@@ -52,6 +54,9 @@ OBJS += tls.o
OBJS += errno.o
OBJS += tlsrt.o
+# Don't care about instrumenting basic library functions
+HOSTBOOT_PROFILE=
+
ifdef HOSTBOOT_MEMORY_LEAKS
COMMONFLAGS += -DHOSTBOOT_MEMORY_LEAKS=1
endif
diff --git a/src/lib/sprintf.C b/src/lib/sprintf.C
index c50ed3966..a8f941448 100644
--- a/src/lib/sprintf.C
+++ b/src/lib/sprintf.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2013,2014 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -28,6 +30,9 @@
namespace Util
{
+// Create a map, to map a numeric value to its character equivalence
+static const char* digits = "0123456789abcdef";
+
struct format_options
{
enum
@@ -70,6 +75,7 @@ struct format_options
TYPE_CHAR,
TYPE_STRING,
TYPE_PTR,
+ TYPE_DOUBLE,
};
types type;
@@ -178,6 +184,10 @@ void parse_format_options(format_options& opt, const char*& fmt)
++fmt;
break;
+ // Although this modifier can be added to a double, "%lf", it is
+ // ignored. The double to string is a very simple implementation,
+ // not meant to be a full blown implementation, but adding the 'l'
+ // will not cause any harm.
case 'l':
if ((opt.length == opt.LEN_LONG) ||
(opt.length == opt.LEN_LONGLONG))
@@ -253,6 +263,14 @@ void parse_format_options(format_options& opt, const char*& fmt)
opt.type = opt.TYPE_PTR;
break;
+ // Considering that the current implementation of doubles is not being
+ // displayed in hexadecimal, there is no need for 'F' in the output
+ // display. Difference between 'f' and 'F' is that F is uppercase and
+ // only useful when displaying hex values.
+ case 'f':
+ opt.type = opt.TYPE_DOUBLE;
+ break;
+
default:
opt.type = opt.TYPE_PERCENT;
}
@@ -295,6 +313,40 @@ size_t display_post_header(ConsoleBufferInterface& func,
return count;
}
+/* @brief Converts a number into it's ASCII string representation
+ *
+ * @param[out] o_stringOutput - The recipient of the converted number to ASCII
+ * @param[in/out] io_stringOutputIndex - The index into buffer o_stringOutput
+ * @pre The io_stringOutputIndex is an index to where the first character
+ * will be placed
+ * @post The io_stringOutputIndex is one index location after the last
+ * placed character
+ * @param[in] i_number - The number to convert to a string.
+ * @param[in] i_base - The base of the number; 10, 8, etc
+ *
+ * @pre i_base must not be 0. Catastrophic results if so
+ */
+void convert_number_to_ascii(char o_stringOutput[],
+ size_t & io_stringOutputIndex,
+ uint64_t i_number,
+ const uint64_t i_base)
+{
+ if (0 == i_number)
+ {
+ // If no number then use zero
+ o_stringOutput[io_stringOutputIndex++] = digits[0];
+ }
+ else
+ {
+ // Convert number to ASCII.
+ while(i_number)
+ {
+ o_stringOutput[io_stringOutputIndex++] = digits[i_number % i_base];
+ i_number /= i_base;
+ }
+ }
+}
+
size_t display_string(ConsoleBufferInterface& func,
const format_options& f, const char* string)
{
@@ -315,7 +367,6 @@ size_t display_string(ConsoleBufferInterface& func,
size_t display_number(ConsoleBufferInterface& func,
const format_options& f, uint64_t number)
{
- static const char* digits = "0123456789abcdef";
size_t count = 0;
char output[64];
@@ -397,15 +448,7 @@ size_t display_number(ConsoleBufferInterface& func,
}
// Convert number to ascii.
- while(number)
- {
- output[len++] = digits[number % base];
- number /= base;
- }
- if (len == 0)
- {
- output[len++] = digits[0];
- }
+ convert_number_to_ascii(output, len, number, base);
// Fix up zero pad.
while(len < f.precision)
@@ -459,6 +502,134 @@ size_t display_number(ConsoleBufferInterface& func,
return count;
}
+/* @brief This is just a rudimentary double to string routine.
+ *
+ * @details This routine takes in a value of type double, converts it
+ * two a string, and writes it to the provided ConsoleBufferInterface.
+ *
+ * @note This is a very simple double to string implementation that will
+ * display the double in a format of NNNN.NNNN in base 10, positive
+ * number only. It is advised to only use a double of the simplest
+ * form: NNNN.NNN. Some complicated forms of a double do not convert
+ * well, example 1.2345e-4 converts to 0.958747220502779 (incorrect),
+ * while 1.2345e+4 converts to 12345.0 (correct). Also working with
+ * doubles can produce imprecise results, example 12334.1469 produces
+ * 12334.146899999999 (technically correct), while 3.14159 produces
+ * 3.14158 (also technically correct).
+ * Also some printf modifiers are not honored such as 'F', 'l', 'L',
+ * etc. 'F' is for uppercase which is irrelevant when dealing with only
+ * base 10. 'l' and 'L' deal with long double. Again this is just a
+ * very simple implementation. Also modifiers 'width.precision' punting
+ * on this as well. Not getting into the minutia of how to display
+ * 1.2345e+4 given print format '%3.2f'.
+ * This algorithm works best with doubles of type NNNN.NNNN and print
+ * format of '%f'.
+ *
+ *
+ * @param[out] o_consoleBufferInterface - The recipient of the double in string
+ * form.
+ * @param[in] i_formatOptions - Formatting options of the double. Currently not
+ * being used. Kept to be consistent with current
+ * interfaces and if someone decides to actually
+ * implement all the formatting options.
+ * @param[in] i_doubleNumber - The double to convert to a string.
+ */
+size_t display_double(ConsoleBufferInterface& o_consoleBufferInterface,
+ const format_options& i_formatOptions,
+ double i_doubleNumber)
+{
+ // Extract the integer part from the double. Example: 3 from 3.1415,
+ // 1 from 1.0, 31258 from 31258.00001, 0 from 0.123, etc
+ uint64_t l_integerPart = static_cast<uint64_t>(i_doubleNumber);
+
+ // Make a copy of the double for manipulation purposes.
+ double l_doubleTemp = i_doubleNumber;
+
+ // Make a copy of the integer part for manipulation purposes.
+ uint64_t l_integerPartTemp = l_integerPart;
+
+ // The double multiplier to move all digits found after the decimal point
+ // to before the decimal point.
+ uint64_t l_doubleMultiplier(1);
+
+ // Determine how many digits are there after the decimal point by taking a
+ // double such as 3.1415 multiply it by 10 to get 31.415. Get a copy of the
+ // integer part (31). Subtract the integer part (31.0) from the current
+ // double (31.415) to get 0.415. If 0.415 is greater than 0.0, then repeat
+ // the process until there are no more digits after the decimal point.
+ // The l_doubleMultiplier will be a factor of 10 that is needed to mutiply
+ // the double to move all digits after the decimal point to before the
+ // decimal point.
+ while ((l_doubleTemp - static_cast<double>(l_integerPartTemp)) > 0.0)
+ {
+ // Increase the multiplier until the value is exactly large enough to
+ // move all digits after the decimal point to before the decimal point.
+ l_doubleMultiplier*=10;
+ // Move 'X' digits after the decimal point to before the decimal point.
+ l_doubleTemp*=10;
+ // Extract the integer part out of the double
+ l_integerPartTemp = static_cast<uint64_t>(l_doubleTemp);
+ }
+
+ // Variable to capture to the digits after the decimal point.
+ uint64_t l_integerPartAfterDecimalPoint(0);
+
+ // If there are digits after the decimal point then extract those digits.
+ if (l_doubleMultiplier > 1)
+ {
+ // Extract the integer part, after the decimal point, by removing the
+ // integer part from the double then multiplying whats left by the
+ // multiplier calculated above.
+ l_integerPartAfterDecimalPoint = (i_doubleNumber -
+ static_cast<double>(l_integerPart)) *
+ l_doubleMultiplier;
+ }
+
+ // Length of the character buffer.
+ size_t l_bufferLength(0);
+
+ // Buffer to hold the double in string form.
+ char l_stringBuffer[64] = { 0 };
+
+ // Default base to 10.
+ const uint64_t l_base(10);
+
+ // Convert integer part, after decimal point, to ASCII.
+ convert_number_to_ascii(l_stringBuffer, l_bufferLength,
+ l_integerPartAfterDecimalPoint, l_base);
+
+ // Add the decimal point
+ l_stringBuffer[l_bufferLength++] = '.';
+
+ // Convert integer part, before decimal point, to ASCII.
+ convert_number_to_ascii(l_stringBuffer, l_bufferLength,
+ l_integerPart, l_base);
+
+ // End the string with a NIL terminator. The l_bufferLength is one index
+ // past the last digit character.
+ l_stringBuffer[l_bufferLength] = 0;
+
+ // Reverse the string for printing, by swapping to the two ends until they
+ // meet in the middle.
+ char* l_beginChar = l_stringBuffer;
+ char* l_endChar = &(l_stringBuffer[l_bufferLength -1]);
+ char l_tempChar;
+ while (l_beginChar < l_endChar)
+ {
+ l_tempChar = *l_beginChar;
+ *l_beginChar = *l_endChar;
+ *l_endChar = l_tempChar;
+ ++l_beginChar;
+ --l_endChar;
+ }
+
+ // Display the double in string form.
+ return display_string(o_consoleBufferInterface,
+ i_formatOptions,
+ l_stringBuffer);
+}
+
+
size_t vasprintf(ConsoleBufferInterface& func, const char* fmt, va_list& args)
{
int count = 0;
@@ -492,6 +663,10 @@ size_t vasprintf(ConsoleBufferInterface& func, const char* fmt, va_list& args)
count += display_string(func, f, va_arg(args,const char*));
break;
+ case format_options::TYPE_DOUBLE:
+ count += display_double(func, f, va_arg(args,double));
+ break;
+
// All the number cases.
default:
{
diff --git a/src/lib/stdio.C b/src/lib/stdio.C
index d61b48cf9..9ed438f78 100644
--- a/src/lib/stdio.C
+++ b/src/lib/stdio.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -31,7 +33,10 @@ class SprintfBuffer : public Util::ConsoleBufferInterface
{
if ('\b' == c)
{
- iv_pos--;
+ if (iv_pos > 0)
+ {
+ iv_pos--;
+ }
}
else if (iv_pos < iv_size)
{
@@ -44,6 +49,19 @@ class SprintfBuffer : public Util::ConsoleBufferInterface
return c;
}
+ void nullTerminate()
+ {
+ if (iv_size > 0)
+ {
+ if (iv_pos >= iv_size)
+ {
+ iv_pos = iv_size - 1;
+ }
+
+ putc('\0');
+ }
+ }
+
explicit SprintfBuffer(char* buf, size_t size = UINT64_MAX) :
iv_pos(0), iv_size(size), iv_buffer(buf) {};
@@ -66,7 +84,7 @@ int sprintf(char *str, const char * format, ...)
size_t count = vasprintf(console, format, args);
va_end(args);
- console.putc('\0');
+ console.nullTerminate();
return count;
}
@@ -81,7 +99,7 @@ int snprintf(char *str, size_t size, const char * format, ...)
size_t count = vasprintf(console, format, args);
va_end(args);
- console.putc('\0');
+ console.nullTerminate();
return count;
}
@@ -92,7 +110,7 @@ int vsprintf(char *str, const char * format, va_list args)
SprintfBuffer console(str);
size_t count = vasprintf(console, format, args);
- console.putc('\0');
+ console.nullTerminate();
return count;
}
@@ -101,6 +119,6 @@ int vsnprintf(char *str, size_t size, const char * format, va_list args)
SprintfBuffer console(str, size);
size_t count = vasprintf(console, format, args);
- console.putc('\0');
+ console.nullTerminate();
return count;
}
diff --git a/src/lib/stdlib.C b/src/lib/stdlib.C
index 21f45fffc..04c70717e 100644
--- a/src/lib/stdlib.C
+++ b/src/lib/stdlib.C
@@ -28,7 +28,6 @@
#include <kernel/heapmgr.H>
#include <kernel/pagemgr.H>
#include <kernel/console.H>
-#include <config.h>
#include <assert.h>
#ifdef HOSTBOOT_MEMORY_LEAKS
diff --git a/src/lib/utilmisc.C b/src/lib/utilmisc.C
index a3771a303..8d53d4c52 100644
--- a/src/lib/utilmisc.C
+++ b/src/lib/utilmisc.C
@@ -31,17 +31,13 @@ namespace Util
bool isSimics() __attribute__((alias("__isSimicsRunning")));
extern "C" bool __isSimicsRunning() NEVER_INLINE;
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wreturn-type"
-
bool __isSimicsRunning()
{
- asm volatile("li 3, 0");
+ long register r3 asm("r3") = 0;
MAGIC_INSTRUCTION(MAGIC_SIMICS_CHECK);
+ return r3;
}
-#pragma GCC diagnostic pop
-
bool isSimicsRunning()
{
static bool simics = isSimics();
diff --git a/src/libc++/makefile b/src/libc++/makefile
index 48ffe5be2..18fb2f852 100644
--- a/src/libc++/makefile
+++ b/src/libc++/makefile
@@ -5,7 +5,9 @@
#
# OpenPOWER HostBoot Project
#
-# COPYRIGHT International Business Machines Corp. 2010,2014
+# Contributors Listed Below - COPYRIGHT 2010,2019
+# [+] International Business Machines Corp.
+#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -22,6 +24,8 @@
# IBM_PROLOG_END_TAG
ROOTPATH = ../..
+HOSTBOOT_PROFILE=
+
OBJS += builtins.o
include ${ROOTPATH}/config.mk
diff --git a/src/makefile b/src/makefile
index 8dc48b9c4..f8343555b 100644
--- a/src/makefile
+++ b/src/makefile
@@ -59,10 +59,6 @@ BASE_OBJECTS += sprintf.o
BASE_OBJECTS += crc32.o
BASE_OBJECTS += utilmisc.o
-ifdef HOSTBOOT_PROFILE
-BASE_OBJECTS += gcov.o
-endif
-
BL_BASE_OBJECTS += bl_builtins.o
BOOTLDR_OBJECTS += bl_start.o
@@ -135,6 +131,9 @@ DIRECT_BOOT_OBJECTS += assert.o
DIRECT_BOOT_OBJECTS += workitem.o
DIRECT_BOOT_OBJECTS += bltohbdatamgr.o
DIRECT_BOOT_OBJECTS += errno.o
+ifdef HOSTBOOT_PROFILE
+DIRECT_BOOT_OBJECTS += gcov.o
+endif
BASE_MODULES += trace
BASE_MODULES += errl
@@ -150,6 +149,11 @@ BASE_MODULES += vfs
BASE_MODULES += $(if $(CONFIG_AST2400) || $(CONFIG_AST2500), sio)
BASE_MODULES += $(if $(CONFIG_CONSOLE),console)
+# This is exported so that gcov knows the list of base modules to
+# exclude from instrumentation. We can't simply export BASE_MODULES or
+# else we get duplicate modules in the list which causes linker errors.
+export BASE_MODULES_GCOV_BLACKLIST:=$(BASE_MODULES)
+
EXTENDED_MODULES += istep06
EXTENDED_MODULES += istep07
EXTENDED_MODULES += istep08
@@ -215,6 +219,8 @@ EXTENDED_MODULES += $(if $(CONFIG_FSP_BUILD),,nvram)
EXTENDED_MODULES += mmio
EXTENDED_MODULES += smf
EXTENDED_MODULES += expaccess
+EXTENDED_MODULES += expupd
+EXTENDED_MODULES += fapiwrap
#***************************************
# Working test modules
@@ -231,7 +237,8 @@ TESTCASE_MODULES += testscan
TESTCASE_MODULES += testsecureboot
TESTCASE_MODULES += testfsiscom
TESTCASE_MODULES += testlpc
-TESTCASE_MODULES += $(if $(CONFIG_HTMGT),testhtmgt)
+#TODO: RTC 213102 to properly add & execute HTMGT test
+#TESTCASE_MODULES += $(if $(CONFIG_HTMGT),testhtmgt)
TESTCASE_MODULES += testinitservice
TESTCASE_MODULES += testfsi
TESTCASE_MODULES += testibscom
@@ -244,7 +251,7 @@ TESTCASE_MODULES += $(if $(CONFIG_VPO_COMPILE),,testmdia)
TESTCASE_MODULES += testpirformat
TESTCASE_MODULES += testi2c
TESTCASE_MODULES += testmbox
-TESTCASE_MODULES += $(if $(or $(CONFIG_EARLY_TESTCASES),${CONFIG_AXONE_BRING_UP}) ,,testrtloader)
+TESTCASE_MODULES += $(if $(CONFIG_EARLY_TESTCASES) ,,testrtloader)
TESTCASE_MODULES += testsbe
TESTCASE_MODULES += testsbeio
TESTCASE_MODULES += testerrl
@@ -257,9 +264,10 @@ TESTCASE_MODULES += $(if $(CONFIG_VPO_COMPILE),,testruntime)
TESTCASE_MODULES += testintr
TESTCASE_MODULES += testfapi2
TESTCASE_MODULES += $(if $(CONFIG_EARLY_TESTCASES) && $(FSP_BUILD) ,,testnvram)
-#TODO RTC: 206800 Investigate why SMF tests fail in Axone
-TESTCASE_MODULES += $(if $(CONFIG_AXONE_BRING_UP),,testsmf)
+TESTCASE_MODULES += testsmf
TESTCASE_MODULES += testexpaccess
+TESTCASE_MODULES += testexpupd
+TESTCASE_MODULES += testmmio
#******************************************************************
#KNOWN ISSUES (I might let these run but there is something wrong)
@@ -281,7 +289,12 @@ RUNTIME_OBJECTS += rt_assert.o
RUNTIME_OBJECTS += rt_vfs.o
RUNTIME_OBJECTS += rt_task.o
RUNTIME_OBJECTS += rt_time.o
-RUNTIME_OBJECTS += ${RUNTIME_COMMON_OBJS}
+RUNTIME_OBJECTS += runtime_utils.o
+ifdef HOSTBOOT_PROFILE
+# we don't instrument runtime because we don't have space, but we
+# still link this in because it uses some object files that need it
+RUNTIME_OBJECTS += gcov.o
+endif
RUNTIME_MODULES += trace_rt
RUNTIME_MODULES += errl_rt
@@ -311,6 +324,12 @@ RUNTIME_MODULES += imageprocs_rt
RUNTIME_MODULES += $(if $(CONFIG_NVDIMM),nvdimm_rt)
RUNTIME_MODULES += mss_rt
RUNTIME_MODULES += expaccess_rt
+RUNTIME_MODULES += mmio_rt
+
+# This is exported so that gcov knows the list of runtime modules to
+# exclude from instrumentation. We can't simply export RUNTIME_MODULES or
+# else we get duplicate modules in the list which causes linker errors.
+export RUNTIME_MODULES_GCOV_BLACKLIST:=$(RUNTIME_MODULES)
RUNTIME_DATA_MODULES +=
@@ -332,7 +351,7 @@ RUNTIME_TESTCASE_MODULES += testtargeting_rt
RUNTIME_TESTCASE_MODULES += testsbeio_rt
RUNTIME_TESTCASE_MODULES += testpm_rt
RUNTIME_TESTCASE_MODULES += testrsvdtracebuf_rt
-# RUNTIME_TESTCASE_MODULES += testexpaccess_rt
+RUNTIME_TESTCASE_MODULES += testexpaccess_rt
RELOCATABLE_IMAGE_LDFLAGS = -pie --export-dynamic
@@ -408,10 +427,10 @@ $(IMGDIR)/hbotStringFile : $(IMAGES)
#20K for bootloader code and data)
#PROCESS: get size of hbibl.bin, sort with respect to 32k (32768),
#then see if last word is 32k. If not, the bootloader image is too big.
+
MAX_BASE_SIZE = 925696
MAX_BTLDR_SIZE = 32768
+
imgsizecheck: ${IMGDIR}/hbicore.bin ${IMGDIR}/hbibl.bin
$(if $(findstring $(shell (stat -c%s ${IMGDIR}/hbicore.bin; echo $(MAX_BASE_SIZE)) | sort -n | tail -n1), $(MAX_BASE_SIZE)),true, @echo ERROR: ${IMGDIR}/hbicore.bin too large. Max allowed size is $(MAX_BASE_SIZE); false)
$(if $(findstring $(shell (stat -c%s ${IMGDIR}/hbibl.bin; echo $(MAX_BTLDR_SIZE)) | sort -n | tail -n1), $(MAX_BTLDR_SIZE)),true, @echo ERROR: ${IMGDIR}/hbibl.bin too large. Max allowed size is $(MAX_BTLDR_SIZE); false)
-
-
diff --git a/src/module.ld b/src/module.ld
index 02239b8d3..38f36719d 100644
--- a/src/module.ld
+++ b/src/module.ld
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2010,2015 */
+/* Contributors Listed Below - COPYRIGHT 2010,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -76,5 +76,6 @@ SECTIONS
/DISCARD/ : {
*(.dtors)
+ *(.dtors.*)
}
}
diff --git a/src/runtime/makefile b/src/runtime/makefile
index 981e00499..407c58a7f 100644
--- a/src/runtime/makefile
+++ b/src/runtime/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2017
+# Contributors Listed Below - COPYRIGHT 2013,2019
# [+] International Business Machines Corp.
#
#
@@ -23,6 +23,12 @@
#
# IBM_PROLOG_END_TAG
HOSTBOOT_RUNTIME = 1
+
+# Profiling the runtime makes it too big, but we should revisit this
+# later after we reduce our memory footprint because it would be good
+# to instrument this too.
+HOSTBOOT_PROFILE=
+
ROOTPATH = ../..
include ../usr/runtime/common/common.mk
VPATH += ../usr/runtime/common
diff --git a/src/runtime/rt_main.C b/src/runtime/rt_main.C
index b8f37e46c..3aa2931e6 100644
--- a/src/runtime/rt_main.C
+++ b/src/runtime/rt_main.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -166,6 +166,11 @@ runtimeInterfaces_t* rt_start(hostInterfaces_t* intf)
// (HTMGT not compiled in by default)
}
+#ifdef CONFIG_NVDIMM
+ // Update hose with current NV_STATUS
+ rtPost->callSendNvStatus();
+#endif
+
// do any version mismatch fixups
rt_version_fixup();
diff --git a/src/securerom/ecverify.C b/src/securerom/ecverify.C
index 6df77df15..7b4b21d25 100644
--- a/src/securerom/ecverify.C
+++ b/src/securerom/ecverify.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -506,20 +506,22 @@ static void bn_mul (bn_t *r, const bn_t *a, const bn_t *b)
a += NWORDS;
for (i=0; i<NWORDS; i++)
{
- asm("mulld %0,%1,%2" //pl = *(--a) * tb
+ --a;
+ asm("mulld %0,%1,%2" //pl = *(a) * tb
: "=r" (pl)
- : "r" (*(--a)), "r" (tb)
+ : "r" (*(a)), "r" (tb)
);
asm("mulhdu %0,%1,%2" //ph = *a * tb
: "=r" (ph)
: "r" (*a), "r" (tb)
);
- asm("addc %1,%5,%4\n" //pl += *(--r)
+ --r;
+ asm("addc %1,%5,%4\n" //pl += *(r)
"addze %2,%6\n" //ph += ca
"addc %0,%5,%7\n" //*r = pl + th
"addze %3,%6" //th = ph + ca
: "=r" (*r), "=r" (pl), "=r" (ph), "=r" (th)
- : "0" (*(--r)), "1" (pl), "2" (ph), "3" (th)
+ : "0" (*(r)), "1" (pl), "2" (ph), "3" (th)
);
}
*(--r) = th;
@@ -674,22 +676,26 @@ static void bn_modred_fast (bn_t *r, bn_t *a)
for (i=0; i<NWORDS-2; i++) {
t1 = *(--ah) << 55;
t2 = *ah >> 9;
- asm("addc %3,%7,%5\n" //t3 = *(--al) + t0;
+ --al;
+ --r;
+ asm("addc %3,%7,%5\n" //t3 = *(al) + t0;
"addze %2,%6\n" //t2 += ca;
- "addc %0,%4,%8\n" //*(--r) = t3 + t1;
+ "addc %0,%4,%8\n" //*(r) = t3 + t1;
"addze %1,%6" //t0 = t2 + ca;
- : "=r" (*(--r)), "=r" (t0), "=r" (t2), "=r" (t3)
- : "3" (t3), "1" (t0), "2" (t2), "r" (*(--al)), "r" (t1)
+ : "=r" (*(r)), "=r" (t0), "=r" (t2), "=r" (t3)
+ : "3" (t3), "1" (t0), "2" (t2), "r" (*(al)), "r" (t1)
);
}
t1 = *(--ah) << 55;
t2 = (*ah >> 9)&BN_PRIME_MSW_MASK;
- asm("addc %3,%7,%5\n" //t3 = *(--al) + t0;
+ --al;
+ --r;
+ asm("addc %3,%7,%5\n" //t3 = *(al) + t0;
"addze %2,%6\n" //t2 += ca;
- "addc %0,%4,%8\n" //*(--r) = t3 + t1;
+ "addc %0,%4,%8\n" //*(r) = t3 + t1;
"addze %1,%6" //t0 = t2 + ca;
- : "=r" (*(--r)), "=r" (t0), "=r" (t2), "=r" (t3)
- : "3" (t3), "1" (t0), "2" (t2), "r" (*(--al)), "r" (t1)
+ : "=r" (*(r)), "=r" (t0), "=r" (t2), "=r" (t3)
+ : "3" (t3), "1" (t0), "2" (t2), "r" (*(al)), "r" (t1)
);
*(--r) = (*(--al)&BN_PRIME_MSW_MASK) + t0;
}
@@ -702,15 +708,17 @@ static void __attribute__((noinline)) bn_modred_slow (bn_t *r)
bn_t t0 = *r >> 9;
*r &= BN_PRIME_MSW_MASK;
r += NWORDS;
+ --r;
asm("addc %0,%1,%2"
: "=r" (*r)
- : "0" (*(--r)), "r" (t0)
+ : "0" (*(r)), "r" (t0)
);
for (i=0; i<NWORDS-1; i++)
{
+ --r;
asm("addze %0,%1"
: "=r" (*r)
- : "0" (*(--r))
+ : "0" (*(r))
);
}
}
diff --git a/src/securerom/makefile b/src/securerom/makefile
index 295330217..925886294 100644
--- a/src/securerom/makefile
+++ b/src/securerom/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2016,2017
+# Contributors Listed Below - COPYRIGHT 2016,2019
# [+] International Business Machines Corp.
#
#
@@ -25,6 +25,8 @@
ROOTPATH = ../..
+HOSTBOOT_PROFILE=
+
COMMONFLAGS += -DBYTE_ORDER=BIG_ENDIAN
COMMONFLAGS += -DBN_POWER64_MUL
COMMONFLAGS += -DBN_POWER64_CMP
diff --git a/src/usr/cxxtest/TestSuite.C b/src/usr/cxxtest/TestSuite.C
index 92feb4886..3b1499889 100755
--- a/src/usr/cxxtest/TestSuite.C
+++ b/src/usr/cxxtest/TestSuite.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -32,7 +32,6 @@
#include <stdarg.h>
#include <arch/ppc.H>
#include <string.h>
-
#include <cxxtest/TestSuite.H>
trace_desc_t *g_trac_test = NULL;
@@ -43,6 +42,9 @@ namespace CxxTest
/******************************************************************************/
// Globals/Constants
/******************************************************************************/
+//This is a list of testcases that are expected to run in a serial manner
+// example: std::vector<const char *> CxxSerialTests{"libtestrtloader.so"};
+std::vector<const char *> CxxSerialTests{"libtesthwas.so"};
//
// TestSuite members
@@ -104,6 +106,43 @@ void doFailTest( )
}
+void sortTests(std::vector<const char *> & i_list,
+ std::vector<const char *> & o_serial_list,
+ std::vector<const char *> & o_parallel_list)
+{
+ o_serial_list.clear();
+ o_serial_list.reserve(32);
+ o_parallel_list.clear();
+ o_parallel_list.reserve(32);
+
+ //Loop through list of all tests
+ for(std::vector<const char *>::const_iterator i = i_list.begin();
+ i != i_list.end(); ++i)
+ {
+ bool is_serial = false;
+
+ for(std::vector<const char *>::const_iterator j = CxxSerialTests.begin();
+ j != CxxSerialTests.end(); ++j)
+ {
+ if (0 == strcmp(*i, *j))
+ {
+ is_serial = true;
+ }
+ }
+
+ if (is_serial)
+ {
+ TRACFCOMP( g_trac_test, "%s is a serial test",*i);
+ o_serial_list.push_back(*i);
+ }
+ else
+ {
+ TRACFCOMP( g_trac_test, "%s is a parallel test",*i);
+ o_parallel_list.push_back(*i);
+ }
+ }
+}
+
/**
* @brief Implement Fail action in unit tests
*
@@ -115,10 +154,11 @@ void doFailTest( )
void doFailTest( const char *filename, uint32_t linenum )
{
- TRACDCOMP( g_trac_test,
+ TRACFCOMP( g_trac_test,
"!!! > Test %s Failed at line %d ",
filename,
linenum );
+
if(g_FailedTests < CXXTEST_FAIL_LIST_SIZE)
{
memcpy(g_FailedTestList[g_FailedTests].failTestFile,
diff --git a/src/usr/cxxtest/cxxtestexec.C b/src/usr/cxxtest/cxxtestexec.C
index 145537f66..b32c661f2 100644
--- a/src/usr/cxxtest/cxxtestexec.C
+++ b/src/usr/cxxtest/cxxtestexec.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -32,7 +32,6 @@
#include <sys/sync.h>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
-#
#include <initservice/taskargs.H>
#include <cxxtest/TestSuite.H>
@@ -46,7 +45,6 @@ namespace CxxTest
// prototype
void cxxinit( errlHndl_t &io_taskRetErrl );
-
trace_desc_t *g_trac_cxxtest = NULL;
TRAC_INIT(&g_trac_cxxtest, CXXTEST_COMP_NAME, KILOBYTE );
@@ -75,6 +73,8 @@ void cxxinit( errlHndl_t &io_taskRetErrl )
} cxxtask;
errlHndl_t l_errl = NULL;
std::vector<const char *> module_list;
+ std::vector<const char *> parallel_module_list;
+ std::vector<const char *> serial_module_list;
std::vector<cxxtask_t> tasks;
tid_t tidrc = 0;
@@ -94,12 +94,16 @@ void cxxinit( errlHndl_t &io_taskRetErrl )
// count up the number of viable modules ahead of time
TRACDCOMP( g_trac_cxxtest, "Counting CxxTestExec modules:" );
+ //Get all modules, then sort into parallel and serial lists
VFS::find_test_modules(module_list);
- // start executing the CxxTest modules
+ CxxTest::sortTests(module_list, serial_module_list, parallel_module_list);
- TRACFCOMP( g_trac_cxxtest, ENTER_MRK "Execute CxxTestExec, totalmodules=%d.",
- module_list.size());
+ // start executing the CxxTest modules
+ TRACFCOMP( g_trac_cxxtest, ENTER_MRK "Execute CxxTestExec, totalparallelmodules=%d, totalserialmodules=%d (overall total:%d)",
+ parallel_module_list.size(),
+ serial_module_list.size(),
+ parallel_module_list.size()+serial_module_list.size());
printkd( "\n Begin CxxTest...\n");
__sync_add_and_fetch(&CxxTest::g_ModulesStarted, 1);
@@ -111,8 +115,58 @@ void cxxinit( errlHndl_t &io_taskRetErrl )
TS_FAIL("Error logs committed previously during IPL.");
}
- for(std::vector<const char *>::const_iterator i = module_list.begin();
- i != module_list.end(); ++i)
+ for(std::vector<const char *>::const_iterator i = serial_module_list.begin();
+ i != serial_module_list.end(); ++i)
+ {
+ __sync_add_and_fetch(&CxxTest::g_ModulesStarted, 1);
+
+ TRACFCOMP( g_trac_cxxtest,
+ "Now executing Serial Test Cases!");
+
+ // load module and call _init()
+ l_errl = VFS::module_load( *i );
+ if ( l_errl )
+ {
+ // vfs could not load a module and returned an errorlog.
+ // commit the errorlog, mark the test failed, and
+ // move on.
+ TS_FAIL( "ERROR: Task %s could not be loaded, committing errorlog",
+ *i );
+ errlCommit( l_errl, CXXTEST_COMP_ID );
+ continue;
+ }
+
+ //First run all serial testcases
+ tidrc = task_exec( *i, NULL );
+ TRACFCOMP( g_trac_cxxtest, "Launched serial task: %s tidrc=%d",
+ *i, tidrc );
+ int status = 0;
+ task_wait_tid(tidrc, &status, NULL);
+
+ if (status != TASK_STATUS_EXITED_CLEAN)
+ {
+ TRACFCOMP( g_trac_cxxtest, "Task %d crashed with status %d.",
+ tidrc, status );
+ if(CxxTest::g_FailedTests < CxxTest::CXXTEST_FAIL_LIST_SIZE)
+ {
+ CxxTest::CxxTestFailedEntry *l_failedEntry =
+ &CxxTest::g_FailedTestList[CxxTest::g_FailedTests];
+ sprintf(l_failedEntry->failTestFile,
+ "%s crashed",
+ *i);
+ l_failedEntry->failTestData = tidrc;
+ }
+ __sync_add_and_fetch(&CxxTest::g_FailedTests, 1);
+ }
+ else
+ {
+ TRACFCOMP( g_trac_cxxtest, "Task %d finished.", tidrc );
+ }
+ }
+
+ //Then run all parallel testcases
+ for(std::vector<const char *>::const_iterator i = parallel_module_list.begin();
+ i != parallel_module_list.end(); ++i)
{
__sync_add_and_fetch(&CxxTest::g_ModulesStarted, 1);
diff --git a/src/usr/diag/attn/common/attnprd.C b/src/usr/diag/attn/common/attnprd.C
index 65f2fafd9..e3f98335a 100644
--- a/src/usr/diag/attn/common/attnprd.C
+++ b/src/usr/diag/attn/common/attnprd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2016 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -41,7 +41,6 @@
#include <errl/errlmanager.H>
// Custom compile configs
-#include <config.h>
#if !defined(__HOSTBOOT_RUNTIME) && defined(CONFIG_ENABLE_CHECKSTOP_ANALYSIS)
#include <prdf/prdfMain_ipl.H>
diff --git a/src/usr/diag/attn/ipl/attn.C b/src/usr/diag/attn/ipl/attn.C
index 7d59a3965..cd8762d49 100644
--- a/src/usr/diag/attn/ipl/attn.C
+++ b/src/usr/diag/attn/ipl/attn.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -44,7 +44,6 @@
#include <targeting/common/utilFilter.H>
// Custom compile configs
-#include <config.h>
#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS
#include "ipl/attnfilereg.H"
diff --git a/src/usr/diag/attn/ipl/attnsvc.C b/src/usr/diag/attn/ipl/attnsvc.C
index 17d87100f..0f4bddbb3 100644
--- a/src/usr/diag/attn/ipl/attnsvc.C
+++ b/src/usr/diag/attn/ipl/attnsvc.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,7 +40,6 @@
#include <initservice/initserviceif.H> // for hostboot TI
// Custom compile configs
-#include <config.h>
using namespace std;
using namespace PRDF;
diff --git a/src/usr/diag/attn/ipl/attnsvc.H b/src/usr/diag/attn/ipl/attnsvc.H
index 8e49fca1f..eabcb2176 100644
--- a/src/usr/diag/attn/ipl/attnsvc.H
+++ b/src/usr/diag/attn/ipl/attnsvc.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,7 +36,6 @@
#include "common/attnsvc_common.H"
// Custom compile configs
-#include <config.h>
namespace ATTN
{
diff --git a/src/usr/diag/attn/runtime/attn_rt.C b/src/usr/diag/attn/runtime/attn_rt.C
index 810e79bbe..92b225c7d 100644
--- a/src/usr/diag/attn/runtime/attn_rt.C
+++ b/src/usr/diag/attn/runtime/attn_rt.C
@@ -28,7 +28,7 @@
#include "common/attnmem.H"
#include "common/attnbits.H"
#include <runtime/interface.h>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <targeting/common/target.H>
#include <targeting/common/targetservice.H>
#include <targeting/common/utilFilter.H>
diff --git a/src/usr/diag/attn/runtime/test/attntestRtAttns.H b/src/usr/diag/attn/runtime/test/attntestRtAttns.H
index 6e22b094e..b2bd1fd8e 100644
--- a/src/usr/diag/attn/runtime/test/attntestRtAttns.H
+++ b/src/usr/diag/attn/runtime/test/attntestRtAttns.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2016 */
+/* Contributors Listed Below - COPYRIGHT 2014,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,7 +38,7 @@
#include "../../common/attntrace.H"
#include "../../common/attntarget.H"
#include <runtime/interface.h>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <targeting/common/targetservice.H>
using namespace ATTN;
@@ -79,8 +79,8 @@ class AttnCheckForRtAttentionsTest : public CxxTest::TestSuite
}
proc = procList[0];
- RT_TARG::rtChipId_t chipId = 0;
- errlHndl_t err = RT_TARG::getRtTarget( proc, chipId );
+ TARGETING::rtChipId_t chipId = 0;
+ errlHndl_t err = TARGETING::getRtTarget( proc, chipId );
if( NULL != err )
{
TS_FAIL("getRtTarget() failed for 0x%08X",
@@ -153,7 +153,7 @@ class AttnCheckForRtAttentionsTest : public CxxTest::TestSuite
break;
}
- RT_TARG::rtChipId_t chipId = 0;
+ TARGETING::rtChipId_t chipId = 0;
errlHndl_t err = RT_TARG::getRtTarget( proc, chipId );
if( NULL != err )
{
diff --git a/src/usr/diag/mdia/makefile b/src/usr/diag/mdia/makefile
index fff17dd96..c6279ee5c 100644
--- a/src/usr/diag/mdia/makefile
+++ b/src/usr/diag/mdia/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2017
+# Contributors Listed Below - COPYRIGHT 2012,2019
# [+] International Business Machines Corp.
#
#
@@ -50,6 +50,11 @@ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/centaur/common/include
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/centaur/procedures/hwp/memory
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/centaur/procedures/hwp/memory/lib/shared
+EXTRAINCDIR += ${ROOTPATH}/src/import/generic/memory/lib/prd/
+EXTRAINCDIR += ${ROOTPATH}/src/import/generic/memory/lib/utils/mcbist/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
+
MODULE = mdia
OBJS += mdiamonitor.o
diff --git a/src/usr/diag/mdia/mdia.C b/src/usr/diag/mdia/mdia.C
index a13f28e59..f75ca1b60 100644
--- a/src/usr/diag/mdia/mdia.C
+++ b/src/usr/diag/mdia/mdia.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -115,14 +115,16 @@ errlHndl_t runStep(const TargetHandleList & i_targetList)
// ensure threads and pools are shutdown when finished
- doStepCleanup(globals);
+ if(nullptr == err)
+ {
+ err = doStepCleanup(globals);
+ }
// If this step completes without the need for a reconfig due to an RCD
// parity error, clear all RCD parity error counters.
ATTR_RECONFIGURE_LOOP_type attr = top->getAttr<ATTR_RECONFIGURE_LOOP>();
if ( 0 == (attr & RECONFIGURE_LOOP_RCD_PARITY_ERROR) )
{
- //TODO RTC 201293 - may need to update this for axone as well
TargetHandleList trgtList; getAllChiplets( trgtList, TYPE_MCA );
for ( auto & trgt : trgtList )
{
@@ -140,13 +142,14 @@ errlHndl_t runStep(const TargetHandleList & i_targetList)
}
-void doStepCleanup(const Globals & i_globals)
+errlHndl_t doStepCleanup(const Globals & i_globals)
{
// stop the state machine
- Singleton<StateMachine>::instance().shutdown();
+ errlHndl_t l_errl = Singleton<StateMachine>::instance().shutdown();
// TODO ... stop the command monitor
+ return l_errl;
}
errlHndl_t processEvent(MaintCommandEvent & i_event)
diff --git a/src/usr/diag/mdia/mdiafwd.H b/src/usr/diag/mdia/mdiafwd.H
index e3395781e..eae069588 100644
--- a/src/usr/diag/mdia/mdiafwd.H
+++ b/src/usr/diag/mdia/mdiafwd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -211,8 +211,10 @@ errlHndl_t getWorkFlow(
* @brief doStepCleanup shut down threads and pools on step exit
*
* @param[in] i_globals contains objects to be cleaned up
+ *
+ * @return nullptr on success; non-nullptr on error
*/
-void doStepCleanup(const Globals & i_globals);
+errlHndl_t doStepCleanup(const Globals & i_globals);
/**
* @brief check if hw state has been changed for an mba
diff --git a/src/usr/diag/mdia/mdiasm.C b/src/usr/diag/mdia/mdiasm.C
index bb1c123cf..ba00de6b0 100644
--- a/src/usr/diag/mdia/mdiasm.C
+++ b/src/usr/diag/mdia/mdiasm.C
@@ -43,12 +43,12 @@
#include <errl/errludlogregister.H>
#include <initservice/istepdispatcherif.H>
#include <ipmi/ipmiwatchdog.H>
-#include <config.h>
#include <initservice/initserviceif.H>
#include <sys/time.h>
#include <p9c_mss_maint_cmds.H>
#include <dimmBadDqBitmapFuncs.H>
#include <sys/misc.h>
+#include <hwp_wrappers.H>
using namespace TARGETING;
using namespace ERRORLOG;
@@ -632,16 +632,17 @@ void StateMachine::processCommandTimeout(const MonitorIDs & i_monitorIDs)
// target type is MCBIST
else if ( TYPE_MCBIST == trgtType )
{
+ #ifndef CONFIG_AXONE
fapi2::Target<fapi2::TARGET_TYPE_MCBIST> fapiMcbist(target);
- FAPI_INVOKE_HWP( err, mss::memdiags::stop, fapiMcbist );
+ FAPI_INVOKE_HWP( err, nim_stop, fapiMcbist );
if ( nullptr != err )
{
- MDIA_ERR("sm: mss::memdiags::stop failed");
+ MDIA_ERR("sm: nim_stop failed");
errlCommit(err, MDIA_COMP_ID);
}
- //mss::memdiags::stop will set the command complete attention so
+ //nim_stop will set the command complete attention so
//we need to clear those
bitMask = ~bitMask;
@@ -654,22 +655,23 @@ void StateMachine::processCommandTimeout(const MonitorIDs & i_monitorIDs)
"0x%08X", firAddr, get_huid(target) );
errlCommit(err, MDIA_COMP_ID);
}
+ #endif
}
// target type is OCMB_CHIP
else if ( TYPE_OCMB_CHIP == trgtType )
{
- /* TODO RTC 201293 uncomment once we have hwp support
+ #ifdef CONFIG_AXONE
fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
fapiOcmb(target);
- FAPI_INVOKE_HWP( err, mss::memdiags::stop, fapiOcmb );
+ FAPI_INVOKE_HWP( err, exp_stop, fapiOcmb );
if ( nullptr != err )
{
- MDIA_ERR("sm: mss::memdiags::stop failed");
+ MDIA_ERR("sm: exp_stop failed");
errlCommit(err, MDIA_COMP_ID);
}
- // mss::memdiags::stop will set the command complete
+ // exp_stop will set the command complete
// attention so we need to clear those
bitMask = ~bitMask;
@@ -682,7 +684,7 @@ void StateMachine::processCommandTimeout(const MonitorIDs & i_monitorIDs)
"0x%08X", firAddr, get_huid(target) );
errlCommit(err, MDIA_COMP_ID);
}
- */
+ #endif
}
// Assert if unsupported type
else
@@ -782,7 +784,15 @@ void StateMachine::setup(const WorkFlowAssocMap & i_list)
p->timeoutCnt = 0;
p->data = NULL;
- p->chipUnit = it->first->getAttr<ATTR_CHIP_UNIT>();
+ if ( TYPE_OCMB_CHIP == it->first->getAttr<ATTR_TYPE>() )
+ {
+ // There is no chip unit attribute for OCMBs, so just use 0
+ p->chipUnit = 0;
+ }
+ else
+ {
+ p->chipUnit = it->first->getAttr<ATTR_CHIP_UNIT>();
+ }
iv_workFlowProperties.push_back(p);
}
@@ -1242,14 +1252,15 @@ errlHndl_t StateMachine::doMaintCommand(WorkFlowProperties & i_wfp)
//target type is MCBIST
else if (TYPE_MCBIST == trgtType)
{
+ #ifndef CONFIG_AXONE
fapi2::Target<fapi2::TARGET_TYPE_MCBIST> fapiMcbist(target);
- mss::mcbist::stop_conditions stopCond;
+ mss::mcbist::stop_conditions<mss::mc_type::NIMBUS> stopCond;
switch(workItem)
{
case START_RANDOM_PATTERN:
- FAPI_INVOKE_HWP( err, mss::memdiags::sf_init, fapiMcbist,
+ FAPI_INVOKE_HWP( err, nim_sf_init, fapiMcbist,
mss::mcbist::PATTERN_RANDOM );
MDIA_FAST("sm: random init %p on: %x", fapiMcbist,
get_huid(target));
@@ -1270,7 +1281,7 @@ errlHndl_t StateMachine::doMaintCommand(WorkFlowProperties & i_wfp)
stopCond.set_pause_on_nce_hard(mss::ON);
}
- FAPI_INVOKE_HWP( err, mss::memdiags::sf_read, fapiMcbist,
+ FAPI_INVOKE_HWP( err, nim_sf_read, fapiMcbist,
stopCond );
MDIA_FAST("sm: scrub %p on: %x", fapiMcbist,
get_huid(target));
@@ -1285,7 +1296,7 @@ errlHndl_t StateMachine::doMaintCommand(WorkFlowProperties & i_wfp)
case START_PATTERN_6:
case START_PATTERN_7:
- FAPI_INVOKE_HWP( err, mss::memdiags::sf_init, fapiMcbist,
+ FAPI_INVOKE_HWP( err, nim_sf_init, fapiMcbist,
workItem );
MDIA_FAST("sm: init %p on: %x", fapiMcbist,
get_huid(target));
@@ -1301,19 +1312,20 @@ errlHndl_t StateMachine::doMaintCommand(WorkFlowProperties & i_wfp)
MDIA_FAST("sm: Running Maint Cmd failed");
i_wfp.data = nullptr;
}
+ #endif
}
// target type is OCMB_CHIP
else if ( TYPE_OCMB_CHIP == trgtType )
{
- /* TODO RTC 201293 - uncomment with hwp support
+ #ifdef CONFIG_AXONE
fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapiOcmb(target);
- mss::mcbist::stop_conditions stopCond;
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER> stopCond;
switch(workItem)
{
case START_RANDOM_PATTERN:
- FAPI_INVOKE_HWP( err, mss::memdiags::sf_init, fapiOcmb,
+ FAPI_INVOKE_HWP( err, exp_sf_init, fapiOcmb,
mss::mcbist::PATTERN_RANDOM );
MDIA_FAST("sm: random init %p on: %x", fapiOcmb,
get_huid(target));
@@ -1334,7 +1346,7 @@ errlHndl_t StateMachine::doMaintCommand(WorkFlowProperties & i_wfp)
stopCond.set_pause_on_nce_hard(mss::ON);
}
- FAPI_INVOKE_HWP( err, mss::memdiags::sf_read, fapiOcmb,
+ FAPI_INVOKE_HWP( err, exp_sf_read, fapiOcmb,
stopCond );
MDIA_FAST( "sm: scrub %p on: %x", fapiOcmb,
get_huid(target) );
@@ -1349,7 +1361,7 @@ errlHndl_t StateMachine::doMaintCommand(WorkFlowProperties & i_wfp)
case START_PATTERN_6:
case START_PATTERN_7:
- FAPI_INVOKE_HWP( err, mss::memdiags::sf_init, fapiOcmb,
+ FAPI_INVOKE_HWP( err, exp_sf_init, fapiOcmb,
workItem );
MDIA_FAST( "sm: init %p on: %x", fapiOcmb,
get_huid(target) );
@@ -1365,7 +1377,7 @@ errlHndl_t StateMachine::doMaintCommand(WorkFlowProperties & i_wfp)
MDIA_FAST("sm: Running Maint Cmd failed");
i_wfp.data = nullptr;
}
- */
+ #endif
}
else
{
@@ -1571,37 +1583,39 @@ bool StateMachine::processMaintCommandEvent(const MaintCommandEvent & i_event)
//target type is MCBIST
else if ( TYPE_MCBIST == trgtType )
{
+ #ifndef CONFIG_AXONE
if(flags & STOP_CMD)
{
MDIA_FAST("sm: stopping command: %p", target);
fapi2::Target<fapi2::TARGET_TYPE_MCBIST> fapiMcbist(target);
- FAPI_INVOKE_HWP( err, mss::memdiags::stop, fapiMcbist );
+ FAPI_INVOKE_HWP( err, nim_stop, fapiMcbist );
if(nullptr != err)
{
- MDIA_ERR("sm: mss::memdiags::stop failed");
+ MDIA_ERR("sm: nim_stop failed");
errlCommit(err, MDIA_COMP_ID);
}
}
+ #endif
}
// target type is OCMB_CHIP
else if ( TYPE_OCMB_CHIP == trgtType )
{
+ #ifdef CONFIG_AXONE
if(flags & STOP_CMD)
{
MDIA_FAST("sm: stopping command: %p", target);
- /* TODO RTC 201293 - reenable with hwp support
fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapiOcmb(target);
- FAPI_INVOKE_HWP( err, mss::memdiags::stop, fapiOcmb );
+ FAPI_INVOKE_HWP( err, exp_stop, fapiOcmb );
if(nullptr != err)
{
- MDIA_ERR("sm: mss::memdiags::stop failed");
+ MDIA_ERR("sm: exp_stop failed");
errlCommit(err, MDIA_COMP_ID);
}
- */
}
+ #endif
}
else
{
@@ -1665,10 +1679,12 @@ void StateMachine::reset()
mutex_unlock(&iv_mutex);
}
-void StateMachine::shutdown()
+errlHndl_t StateMachine::shutdown()
{
mutex_lock(&iv_mutex);
+ errlHndl_t l_errl = nullptr;
+
Util::ThreadPool<WorkItem> * tp = iv_tp;
CommandMonitor * monitor = iv_monitor;
@@ -1684,7 +1700,7 @@ void StateMachine::shutdown()
if(tp)
{
MDIA_FAST("Stopping threadPool...");
- tp->shutdown();
+ l_errl = tp->shutdown();
delete tp;
}
@@ -1696,11 +1712,16 @@ void StateMachine::shutdown()
}
MDIA_FAST("sm: ...shutdown complete");
+ return l_errl;
}
StateMachine::~StateMachine()
{
- shutdown();
+ errlHndl_t l_errl = shutdown();
+ if(l_errl)
+ {
+ errlCommit(l_errl, MDIA_COMP_ID);
+ }
sync_cond_destroy(&iv_cond);
mutex_destroy(&iv_mutex);
diff --git a/src/usr/diag/mdia/mdiasm.H b/src/usr/diag/mdia/mdiasm.H
index 924af567a..55cc8ed74 100644
--- a/src/usr/diag/mdia/mdiasm.H
+++ b/src/usr/diag/mdia/mdiasm.H
@@ -106,8 +106,10 @@ class StateMachine
/**
* @brief shutdown state machine
+ *
+ * @retval nullptr on success; non-nullptr on error
*/
- void shutdown();
+ errlHndl_t shutdown();
/**
* @brief processMaintCommandEvent process maint command event from prd
diff --git a/src/usr/diag/mdia/test/mdiatestmba.H b/src/usr/diag/mdia/test/mdiatestmba.H
index bca85c11d..97360c80a 100644
--- a/src/usr/diag/mdia/test/mdiatestmba.H
+++ b/src/usr/diag/mdia/test/mdiatestmba.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -47,33 +47,43 @@ class MdiaMbaTest : public CxxTest::TestSuite
using namespace MDIA;
using namespace TARGETING;
- TS_TRACE(ENTER_MRK "testGetDiagnosticMode");
+ TS_TRACE( ENTER_MRK "testGetDiagnosticMode" );
- TargetHandleList mbaList;
- getAllChiplets(mbaList, TYPE_MBA);
+ TargetHandleList list;
+ fapi2::TargetType type = getMdiaTargetType();
+ if ( fapi2::TARGET_TYPE_MBA_CHIPLET == type )
+ {
+ TARGETING::getAllChiplets( list, TYPE_MBA );
+ }
+ else if ( fapi2::TARGET_TYPE_MCBIST == type )
+ {
+ TARGETING::getAllChiplets( list, TYPE_MCBIST );
+ }
+ else if ( fapi2::TARGET_TYPE_OCMB_CHIP == type )
+ {
+ TARGETING::getAllChiplets( list, TYPE_OCMB_CHIP );
+ }
- if( !mbaList.empty() )
+ if( !list.empty() )
{
DiagMode mode;
Globals globals;
- TargetHandle_t mba = mbaList[0];
+ TargetHandle_t trgt = list[0];
- errlHndl_t err = getDiagnosticMode(
- globals, mba, mode);
+ errlHndl_t err = getDiagnosticMode( globals, trgt, mode );
if(err)
{
- TS_FAIL("getDiagnosticMode failed "
- "unexpectedly");
+ TS_FAIL( "getDiagnosticMode failed unexpectedly" );
}
if(mode != ONE_PATTERN)
{
- TS_FAIL("mode != ONE_PATTERN");
+ TS_FAIL( "mode != ONE_PATTERN" );
}
}
- TS_TRACE(EXIT_MRK "testGetDiagnosticMode");
+ TS_TRACE( EXIT_MRK "testGetDiagnosticMode" );
}
void testGetWorkFlow(void)
@@ -81,63 +91,74 @@ class MdiaMbaTest : public CxxTest::TestSuite
using namespace MDIA;
using namespace TARGETING;
- TS_TRACE(ENTER_MRK "testGetWorkFlow");
+ TS_TRACE( ENTER_MRK "testGetWorkFlow" );
Globals globals;
- TargetHandle_t mba = 0;
+ TargetHandle_t trgt = 0;
DiagMode mode;
errlHndl_t err = NULL;
- TargetHandleList mbaList;
- getAllChiplets(mbaList, TYPE_MBA);
- if( !mbaList.empty() )
+ TargetHandleList list;
+ fapi2::TargetType type = getMdiaTargetType();
+ if ( fapi2::TARGET_TYPE_MBA_CHIPLET == type )
{
- mba = mbaList[0];
- err = getDiagnosticMode(
- globals, mba, mode);
+ TARGETING::getAllChiplets( list, TYPE_MBA );
+ }
+ else if ( fapi2::TARGET_TYPE_MCBIST == type )
+ {
+ TARGETING::getAllChiplets( list, TYPE_MCBIST );
+ }
+ else if ( fapi2::TARGET_TYPE_OCMB_CHIP == type )
+ {
+ TARGETING::getAllChiplets( list, TYPE_OCMB_CHIP );
+ }
- if(err)
+ if( !list.empty() )
+ {
+ trgt = list[0];
+ err = getDiagnosticMode( globals, trgt, mode );
+
+ if( err )
{
- TS_FAIL("getDiagnosticMode "
- "failed unexpectedly");
+ TS_FAIL( "getDiagnosticMode failed unexpectedly" );
}
- if(mode != ONE_PATTERN)
+ if( mode != ONE_PATTERN )
{
- TS_FAIL("mode != ONE_PATTERN");
+ TS_FAIL( "mode != ONE_PATTERN" );
}
- }
- WorkFlow wf, expected;
+ WorkFlow wf, expected;
- expected.push_back(RESTORE_DRAM_REPAIRS);
- expected.push_back(START_PATTERN_0);
- expected.push_back(START_SCRUB);
- expected.push_back(CLEAR_HW_CHANGED_STATE);
+ expected.push_back( RESTORE_DRAM_REPAIRS );
+ expected.push_back( START_PATTERN_0 );
+ expected.push_back( START_SCRUB );
+ expected.push_back( CLEAR_HW_CHANGED_STATE );
- err = getWorkFlow(mode, wf, globals);
+ err = getWorkFlow( mode, wf, globals );
- if(err)
- {
- TS_FAIL("getWorkFlow failed unexpectedly");
- }
+ if( err )
+ {
+ TS_FAIL( "getWorkFlow failed unexpectedly" );
+ }
- if(wf.size() != expected.size())
- {
- TS_FAIL("incorrect workflow size for init only mode");
- }
+ if( wf.size() != expected.size() )
+ {
+ TS_FAIL( "incorrect workflow size for init only mode" );
+ }
- int64_t index = wf.size();
+ int64_t index = wf.size();
- while(index-- != 0)
- {
- if(wf[index] != expected[index])
+ while( index-- != 0 )
{
- TS_FAIL("workflow entry incorrect or out of order");
+ if( wf[index] != expected[index] )
+ {
+ TS_FAIL( "workflow entry incorrect or out of order" );
+ }
}
}
- TS_TRACE(EXIT_MRK "testGetWorkFlow");
+ TS_TRACE( EXIT_MRK "testGetWorkFlow" );
}
};
#endif
diff --git a/src/usr/diag/prdf/common/framework/config/iipSystem.h b/src/usr/diag/prdf/common/framework/config/iipSystem.h
index ef4ed9322..b1b6ad1f4 100755
--- a/src/usr/diag/prdf/common/framework/config/iipSystem.h
+++ b/src/usr/diag/prdf/common/framework/config/iipSystem.h
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 1996,2018 */
+/* Contributors Listed Below - COPYRIGHT 1996,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -87,9 +87,7 @@
#include <vector>
#include <map>
-#ifndef IIPCONST_H
#include <iipconst.h> //TARGETING::TargetHandle_t, DOMAIN_ID_TYPE
-#endif
#include <iipsdbug.h> // Include file for ATTENTION_TYPE
diff --git a/src/usr/diag/prdf/common/framework/register/iipCaptureData.h b/src/usr/diag/prdf/common/framework/register/iipCaptureData.h
index e65e94d3f..9aae2880c 100755
--- a/src/usr/diag/prdf/common/framework/register/iipCaptureData.h
+++ b/src/usr/diag/prdf/common/framework/register/iipCaptureData.h
@@ -78,9 +78,7 @@
#include <list>
-#ifndef IIPCONST_H
#include <iipconst.h>
-#endif
#include <prdfPlatServices.H>
#include <functional> // @jl04 a Needed for the unary function in new predicate.
diff --git a/src/usr/diag/prdf/common/framework/register/iipErrorRegisterMask.h b/src/usr/diag/prdf/common/framework/register/iipErrorRegisterMask.h
index fb1443df8..af67c68aa 100755
--- a/src/usr/diag/prdf/common/framework/register/iipErrorRegisterMask.h
+++ b/src/usr/diag/prdf/common/framework/register/iipErrorRegisterMask.h
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -70,9 +70,7 @@
#include <iipErrorRegisterFilter.h>
#endif
-#ifndef IIPBITS_H
-#include <iipbits.h>
-#endif
+#include <prdfBitString.H>
namespace PRDF
{
diff --git a/src/usr/diag/prdf/common/framework/register/iipMopRegisterAccess.h b/src/usr/diag/prdf/common/framework/register/iipMopRegisterAccess.h
deleted file mode 100755
index 1e7ad5947..000000000
--- a/src/usr/diag/prdf/common/framework/register/iipMopRegisterAccess.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/diag/prdf/common/framework/register/iipMopRegisterAccess.h $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-#ifndef iipMopRegisterAccess_h
-#define iipMopRegisterAccess_h
-
-// Class Specification *************************************************
-//
-// Class name: MopRegisterAccess
-// Parent class: None.
-//
-// Summary: This class provides access to hardware register via
-// a MOP routine. A single pure virtual function Access()
-// is declared for this purpose.
-//
-// Cardinality: 0
-//
-// Performance/Implementation:
-// Space Complexity: Constant
-// Time Complexity: All member functions constant unless otherwise
-// stated.
-//
-// Usage Examples:
-//
-//
-// void foo(MopRegisterAccess & mra)
-// {
-// BitStringBuffer bitString(80); // 80 bits
-//
-// mra.Access(bitString, READ);
-// ...
-//
-// }
-//
-//
-// End Class Specification *********************************************
-
-// Includes
-#if !defined(IIPCONST_H)
-#include <iipconst.h>
-#endif
-#include <prdfPlatServices.H>
-
-namespace PRDF
-{
-// Forward References
-class BitString;
-
-class MopRegisterAccess
-{
-public:
-
- enum Operation
- {
- READ = 0,
- WRITE = 1
- };
-
- // MopRegisterAccess(void);
- // Function Specification ********************************************
- //
- // Purpose: Initialization
- // Parameters: None.
- // Returns: No value returned.
- // Requirements: None.
- // Promises: All data members are initialized.
- // Exceptions: None.
- // Concurrency: N/A
- // Notes: This constructor is not declared. This compiler generated
- // default definition is sufficient.
- //
- // End Function Specification //////////////////////////////////////
-
- // MopRegisterAccess(const MopRegisterAccess & scr);
- // Function Specification ********************************************
- //
- // Purpose: Copy
- // Parameters: scr: Reference to instance to copy
- // Returns: No value returned.
- // Requirements: None.
- // Promises: All data members will be copied (Deep copy).
- // Exceptions: None.
- // Concurrency: N/A.
- // Notes: This constructor is not declared. This compiler generated
- // default definition is sufficient.
- //
- // End Function Specification ****************************************
-
- virtual ~MopRegisterAccess() {}
-
- // Function Specification ********************************************
- //
- // Purpose: Destruction
- // Parameters: None.
- // Returns: No value returned
- // Requirements: None.
- // Promises: None.
- // Exceptions: None.
- // Concurrency: N/A
- //
- // End Function Specification ****************************************
-
- // MopRegisterAccess & operator=(const MopRegisterAccess & scr);
- // Function Specification ********************************************
- //
- // Purpose: Assigment
- // Parameters: d: Reference to instance to assign from
- // Returns: Reference to this instance
- // Requirements: None.
- // Promises: All data members are assigned to
- // Exceptions: None.
- // Concurrency: N/A.
- // Notes: This assingment operator is not declared. The compiler
- // generated default definition is sufficient.
- //
- // End Function Specification ****************************************
-
- virtual uint32_t Access(BitString & bs,
- uint64_t registerId,
- Operation operation) const = 0;
- // Function Specification ********************************************
- //
- // Purpose: This function reads or writes the hardware according
- // to the specified operation.
- // Parameters: bs: Bit string to retrieve(for write) or store data
- // (from read)
- // registerId: SCR Address or scan offset
- // operation: Indicates either read or write operation
- // Returns: Hardware OPs return code
- // Requirements: bs.Length() == long enough
- // Promises: For read operation, bs is modified to reflect hardware
- // register state
- // Exceptions: None.
- // Concurrency: Nonreentrant.
- // Note: The first bs.Length() bits from the Hardware OPs read
- // are set/reset in bs (from left to right)
- // For a write, the first bs.Length() bits are written
- // to the hardware register with right padded 0's if
- // needed
- //
- // End Function Specification ****************************************
- //Get Ids and count
- virtual const TARGETING::TargetHandle_t * GetChipIds(int & count) const = 0;
- // Function Specification ********************************************
- //
- // Purpose: Access Chip Ids and # of chips to access
- // Parameters: count: Var to return chip count of valid IDs
- // Returns: ptr to Chip ids
- // Requirements: None
- // Promises: None
- // Exceptions: None.
- // Concurrency: Reentrant.
- //
- // End Function Specification ****************************************
-
- private:
-
- };
-
-} // end namespace PRDF
-
-#endif
diff --git a/src/usr/diag/prdf/common/framework/register/iipMopRegisterAccessScanComm.h b/src/usr/diag/prdf/common/framework/register/iipMopRegisterAccessScanComm.h
deleted file mode 100755
index e87d70210..000000000
--- a/src/usr/diag/prdf/common/framework/register/iipMopRegisterAccessScanComm.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/diag/prdf/common/framework/register/iipMopRegisterAccessScanComm.h $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 1996,2017 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-#ifndef iipMopRegisterAccessScanComm_h
-#define iipMopRegisterAccessScanComm_h
-
-// Class Specification *************************************************
-//
-// Class name: MopRegisterAccessScanComm
-// Parent class: MopRegisterAccess.
-//
-// Summary: This class provides access to hardware register data via
-// a MOP Scan Comm routine.
-//
-// Cardinality: 0
-//
-// Performance/Implementation:
-// Space Complexity: Constant
-// Time Complexity: All member functions constant unless otherwise
-// stated.
-//
-// Usage Examples:
-//
-//
-//
-// End Class Specification *********************************************
-
-// Includes
-
-#pragma interface
-
-#ifndef iipMopRegisterAccess_h
-#include <iipMopRegisterAccess.h>
-#endif
-
-namespace PRDF
-{
-
-// Forward References
-class MopRegisterAccessScanComm : public MopRegisterAccess
-{
-public:
-
- // Function Specification ********************************************
- //
- // Purpose: CTOR
- // Parameters: None
- // Returns: No value returned.
- // Requirements: None.
- // Promises: All data members are initialized.
- // Exceptions: None.
- // Concurrency: N/A
- // Note: Multiple chip IDs are for chips that MOPs must
- // access at the same time when performing a Scan
- // Comm operation (ie STINGER & ARROW chips)
- //
- // End Function Specification //////////////////////////////////////
-
- // MopRegisterAccessScanComm(const MopRegisterAccessScanComm & scr);
- // Function Specification ********************************************
- //
- // Purpose: Copy
- // Parameters: scr: Reference to instance to copy
- // Returns: No value returned.
- // Requirements: None.
- // Promises: All data members will be copied (Deep copy).
- // Exceptions: None.
- // Concurrency: N/A.
- // Notes: This constructor is not declared. This compiler generated
- // default definition is sufficient.
- //
- // End Function Specification ****************************************
-
- // virtual ~MopRegisterAccessScanComm(void);
- // Function Specification ********************************************
- //
- // Purpose: Destruction
- // Parameters: None.
- // Returns: No value returned
- // Requirements: None.
- // Promises: None.
- // Exceptions: None.
- // Concurrency: N/A
- // Notes: This destructor is not declared. This compiler generated
- // default definition is sufficient.
- //
- // End Function Specification ****************************************
-
- // MopRegisterAccessScanComm & operator=(const MopRegisterAccessScanComm & scr);
- // Function Specification ********************************************
- //
- // Purpose: Assigment
- // Parameters: d: Reference to instance to assign from
- // Returns: Reference to this instance
- // Requirements: None.
- // Promises: All data members are assigned to
- // Exceptions: None.
- // Concurrency: N/A.
- // Notes: This assingment operator is not declared. The compiler
- // generated default definition is sufficient.
- //
- // End Function Specification ****************************************
-
- virtual uint32_t Access(BitString & bs,
- uint32_t registerId,
- Operation operation) const;
- // Function Specification ********************************************
- //
- // Purpose: This function reads or writes the hardware according
- // to the specified operation.
- // Parameters: bs: Bit string to retrieve(for write) or store data
- // (from read)
- // registerId: ScanComm register address
- // operation: Indicates either read or write operation
- // Returns: Hardware OPs return code
- // Requirements: bs.Length() == long enough
- // Promises: For read operation, bs is modified to reflect hardware
- // register state
- // Exceptions: None.
- // Concurrency: Nonreentrant.
- // Note: The first bs.Length() bits from the Hardware OPs read
- // are set/reset in bs (from left to right)
- // For a write, the first bs.Length() bits are written
- // to the hardware register with right padded 0's if
- // needed
- //
- // End Function Specification ****************************************
-
-
-private: // DATA
-
-};
-
-} // end namespace PRDF
-
-#endif
diff --git a/src/usr/diag/prdf/common/framework/register/iipMopRegisterAccessScanComm.inl b/src/usr/diag/prdf/common/framework/register/iipMopRegisterAccessScanComm.inl
deleted file mode 100755
index ad08084d6..000000000
--- a/src/usr/diag/prdf/common/framework/register/iipMopRegisterAccessScanComm.inl
+++ /dev/null
@@ -1,67 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/diag/prdf/common/framework/register/iipMopRegisterAccessScanComm.inl $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* COPYRIGHT International Business Machines Corp. 1996,2014 */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-// Module Description **************************************************
-//
-// Description: This module provides the inline implementation for the
-// PRD MOP Register Access Scan Comm class.
-//
-// End Module Description **********************************************
-
-namespace PRDF
-{
-
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
-
-//----------------------------------------------------------------------
-// User Types
-//----------------------------------------------------------------------
-
-//----------------------------------------------------------------------
-// Constants
-//----------------------------------------------------------------------
-
-//----------------------------------------------------------------------
-// Macros
-//----------------------------------------------------------------------
-
-//----------------------------------------------------------------------
-// Internal Function Prototypes
-//----------------------------------------------------------------------
-
-//----------------------------------------------------------------------
-// Global Variables
-//----------------------------------------------------------------------
-
-//---------------------------------------------------------------------
-// Member Function Specifications
-//---------------------------------------------------------------------
-
-inline
-MopRegisterAccessScanComm::MopRegisterAccessScanComm(void)
- {
- }
-
-} // end namespace PRDF
diff --git a/src/usr/diag/prdf/common/framework/register/iipscr.C b/src/usr/diag/prdf/common/framework/register/iipscr.C
index d4d7017a2..6834c6415 100755
--- a/src/usr/diag/prdf/common/framework/register/iipscr.C
+++ b/src/usr/diag/prdf/common/framework/register/iipscr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 1997,2017 */
+/* Contributors Listed Below - COPYRIGHT 1997,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -41,7 +41,7 @@
/* Includes */
/*--------------------------------------------------------------------*/
-#include <iipbits.h>
+#include <prdfBitString.H>
#include <iipscr.h>
#include <iipconst.h>
diff --git a/src/usr/diag/prdf/common/framework/register/iipscr.h b/src/usr/diag/prdf/common/framework/register/iipscr.h
index 53c9bfa5a..cd1243dc6 100755
--- a/src/usr/diag/prdf/common/framework/register/iipscr.h
+++ b/src/usr/diag/prdf/common/framework/register/iipscr.h
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -43,7 +43,7 @@
// Includes
//----------------------------------------------------------------------
-#include <iipbits.h>
+#include <prdfBitString.H>
#include <iipconst.h>
#include <iipsdbug.h>
#include <prdfMain.H>
diff --git a/src/usr/diag/prdf/common/framework/register/prdfCaptureData.C b/src/usr/diag/prdf/common/framework/register/prdfCaptureData.C
index 39113507b..5ddb11a4c 100755
--- a/src/usr/diag/prdf/common/framework/register/prdfCaptureData.C
+++ b/src/usr/diag/prdf/common/framework/register/prdfCaptureData.C
@@ -31,7 +31,7 @@
// Includes
//----------------------------------------------------------------------
-#include <iipbits.h>
+#include <prdfBitString.H>
#include <prdfHomRegisterAccess.H> // dg06a
#include <prdfScomRegister.H>
#include <iipchip.h>
diff --git a/src/usr/diag/prdf/common/framework/register/prdfErrorRegister.C b/src/usr/diag/prdf/common/framework/register/prdfErrorRegister.C
index 3244022c7..450a7bc9c 100755
--- a/src/usr/diag/prdf/common/framework/register/prdfErrorRegister.C
+++ b/src/usr/diag/prdf/common/framework/register/prdfErrorRegister.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,7 +40,7 @@
#include <prdfMain.H>
#include <prdfAssert.h>
#include <iipstep.h>
-#include <iipbits.h>
+#include <prdfBitString.H>
#include <iipResolution.h>
#include <iipscr.h>
#include <prdfErrorSignature.H>
diff --git a/src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.C b/src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.C
index a9d2a615a..c7bf802a4 100755
--- a/src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.C
+++ b/src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -30,11 +30,10 @@
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
-#define prdfHomRegisterAccess_C
#include <prdfHomRegisterAccess.H>
#include <prdf_service_codes.H>
-#include <iipbits.h>
+#include <prdfBitString.H>
#include <prdfMain.H>
#include <prdfPlatServices.H>
#include <prdfGlobal.H>
@@ -46,9 +45,6 @@
#include <p9_stop_api.H>
#endif
-#undef prdfHomRegisterAccess_C
-
-
using namespace TARGETING;
namespace PRDF
@@ -117,7 +113,7 @@ void ScomService::setScomAccessor(ScomAccessor & i_ScomAccessor)
uint32_t ScomService::Access(TargetHandle_t i_target,
BitString & bs,
uint64_t registerId,
- MopRegisterAccess::Operation operation) const
+ RegisterAccess::Operation operation) const
{
PRDF_DENTER("ScomService::Access()");
uint32_t rc = SUCCESS;
@@ -136,7 +132,7 @@ uint32_t ScomService::Access(TargetHandle_t i_target,
uint32_t ScomAccessor::Access(TargetHandle_t i_target,
BitString & bs,
uint64_t registerId,
- MopRegisterAccess::Operation operation) const
+ RegisterAccess::Operation operation) const
{
PRDF_DENTER("ScomAccessor::Access()");
@@ -146,7 +142,7 @@ uint32_t ScomAccessor::Access(TargetHandle_t i_target,
{
switch (operation)
{
- case MopRegisterAccess::WRITE:
+ case RegisterAccess::WRITE:
{
rc = PRDF::PlatServices::putScom(i_target, bs, registerId);
@@ -198,7 +194,7 @@ uint32_t ScomAccessor::Access(TargetHandle_t i_target,
break;
}
- case MopRegisterAccess::READ:
+ case RegisterAccess::READ:
bs.clearAll(); // clear all bits
rc = PRDF::PlatServices::getScom(i_target, bs, registerId);
diff --git a/src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.H b/src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.H
index 6426b4ac3..d26f173f6 100755
--- a/src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.H
+++ b/src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -35,7 +35,6 @@
// Includes
//--------------------------------------------------------------------
-#include <iipMopRegisterAccess.h>
#include <vector>
#include <prdfPlatServices.H>
#include <prdfErrlUtil.H>
@@ -47,6 +46,15 @@
namespace PRDF
{
+namespace RegisterAccess
+{
+ enum Operation
+ {
+ READ = 0,
+ WRITE = 1,
+ };
+}
+
class ScomAccessor
{
public:
@@ -75,7 +83,7 @@ class ScomAccessor
virtual uint32_t Access( TARGETING::TargetHandle_t i_target,
BitString & bs,
uint64_t registerId,
- MopRegisterAccess::Operation operation) const;
+ RegisterAccess::Operation operation) const;
private:
@@ -142,7 +150,7 @@ class ScomService
virtual uint32_t Access(TARGETING::TargetHandle_t i_target,
BitString & bs,
uint64_t registerId,
- MopRegisterAccess::Operation operation) const;
+ RegisterAccess::Operation operation) const;
private:
diff --git a/src/usr/diag/prdf/common/framework/register/prdfRegisterCache.H b/src/usr/diag/prdf/common/framework/register/prdfRegisterCache.H
index be34884a3..8d069b3cb 100644
--- a/src/usr/diag/prdf/common/framework/register/prdfRegisterCache.H
+++ b/src/usr/diag/prdf/common/framework/register/prdfRegisterCache.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -29,7 +29,7 @@
/** @file prdfRegisterCache.H */
#include <map>
-#include <iipbits.h>
+#include <prdfBitString.H>
#include <prdfGlobal.H>
#include <prdfScanFacility.H>
#include <prdfScomRegisterAccess.H>
diff --git a/src/usr/diag/prdf/common/framework/register/prdfScomRegister.C b/src/usr/diag/prdf/common/framework/register/prdfScomRegister.C
index 7e4cce81b..f8a445b20 100755
--- a/src/usr/diag/prdf/common/framework/register/prdfScomRegister.C
+++ b/src/usr/diag/prdf/common/framework/register/prdfScomRegister.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,7 +37,7 @@
#include <iipchip.h>
#include <prdfScomRegister.H>
#include <iipconst.h>
-#include <iipbits.h>
+#include <prdfBitString.H>
#include <prdfMain.H>
#include <prdfRasServices.H>
#include <prdfRegisterCache.H>
@@ -155,7 +155,7 @@ uint32_t ScomRegister::ForceRead() const
}
// Read hardware.
- o_rc = Access( readCache(), MopRegisterAccess::READ );
+ o_rc = Access( readCache(), RegisterAccess::READ );
if ( SUCCESS != o_rc )
{
// The read failed. Remove the entry from the cache so a subsequent
@@ -201,7 +201,7 @@ uint32_t ScomRegister::Write()
}
// Write hardware.
- o_rc = Access( readCache(), MopRegisterAccess::WRITE );
+ o_rc = Access( readCache(), RegisterAccess::WRITE );
} while (0);
@@ -213,7 +213,7 @@ uint32_t ScomRegister::Write()
//------------------------------------------------------------------------------
uint32_t ScomRegister::Access( BitString & bs,
- MopRegisterAccess::Operation op ) const
+ RegisterAccess::Operation op ) const
{
int32_t l_rc = SCR_ACCESS_FAILED;
TARGETING::TargetHandle_t i_pchipTarget = getChip()->GetChipHandle();
diff --git a/src/usr/diag/prdf/common/framework/register/prdfScomRegister.H b/src/usr/diag/prdf/common/framework/register/prdfScomRegister.H
index 655f4d523..e3d14a0dc 100755
--- a/src/usr/diag/prdf/common/framework/register/prdfScomRegister.H
+++ b/src/usr/diag/prdf/common/framework/register/prdfScomRegister.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 1996,2017 */
+/* Contributors Listed Below - COPYRIGHT 1996,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,8 +37,8 @@
*/
#include <iipscr.h>
-#include <iipbits.h>
-#include <iipMopRegisterAccess.h>
+#include <prdfBitString.H>
+#include <prdfHomRegisterAccess.H>
#include <prdfTrace.H>
namespace PRDF
@@ -80,6 +80,9 @@ class ScomRegister : public SCAN_COMM_REGISTER_CLASS
iv_operationType( ACCESS_NONE )
{}
+ /** @brief Destructor. */
+ virtual ~ScomRegister() = default;
+
/**
* @brief Returns the pointer to bit string
* @param i_type attention type
@@ -201,7 +204,7 @@ class ScomRegister : public SCAN_COMM_REGISTER_CLASS
* @return [SUCCESS|FAIL]
*/
uint32_t Access( BitString & bs,
- MopRegisterAccess::Operation op )const;
+ RegisterAccess::Operation op )const;
/**
* @brief Returns rulechip pointer associated with the register
diff --git a/src/usr/diag/prdf/common/framework/resolution/prdfCalloutMap.H b/src/usr/diag/prdf/common/framework/resolution/prdfCalloutMap.H
index 7bedec637..269e432cf 100644
--- a/src/usr/diag/prdf/common/framework/resolution/prdfCalloutMap.H
+++ b/src/usr/diag/prdf/common/framework/resolution/prdfCalloutMap.H
@@ -195,7 +195,9 @@ PRDF_TARGET_TYPE_ALIAS( TYPE_MI, TARGETING::TYPE_MI )
PRDF_TARGET_TYPE_ALIAS( TYPE_DMI, TARGETING::TYPE_DMI )
PRDF_TARGET_TYPE_ALIAS( TYPE_MCC, TARGETING::TYPE_MCC )
PRDF_TARGET_TYPE_ALIAS( TYPE_OMIC, TARGETING::TYPE_OMIC )
+PRDF_TARGET_TYPE_ALIAS( TYPE_OMI, TARGETING::TYPE_OMI )
PRDF_TARGET_TYPE_ALIAS( TYPE_OCMB_CHIP, TARGETING::TYPE_OCMB_CHIP )
+PRDF_TARGET_TYPE_ALIAS( TYPE_MEM_PORT, TARGETING::TYPE_MEM_PORT )
PRDF_TARGET_TYPE_ALIAS( TYPE_MEMBUF, TARGETING::TYPE_MEMBUF )
PRDF_TARGET_TYPE_ALIAS( TYPE_L4, TARGETING::TYPE_L4 )
PRDF_TARGET_TYPE_ALIAS( TYPE_MBA, TARGETING::TYPE_MBA )
diff --git a/src/usr/diag/prdf/common/framework/resolution/prdfThresholdResolutions.H b/src/usr/diag/prdf/common/framework/resolution/prdfThresholdResolutions.H
index e412460dc..b61699159 100755
--- a/src/usr/diag/prdf/common/framework/resolution/prdfThresholdResolutions.H
+++ b/src/usr/diag/prdf/common/framework/resolution/prdfThresholdResolutions.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2003,2014 */
+/* Contributors Listed Below - COPYRIGHT 2003,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -100,10 +102,11 @@ class ThresholdResolution : public MaskResolution
enum TimeBase
{
- ONE_SEC = 1,
- ONE_MIN = ONE_SEC * 60,
- ONE_HOUR = ONE_MIN * 60,
- ONE_DAY = ONE_HOUR * 24,
+ ONE_SEC = 1,
+ ONE_MIN = ONE_SEC * 60,
+ ONE_HOUR = ONE_MIN * 60,
+ TEN_HOURS = ONE_HOUR * 10,
+ ONE_DAY = ONE_HOUR * 24,
NONE = 0xffffffff,
};
diff --git a/src/usr/diag/prdf/common/framework/service/iipServiceDataCollector.h b/src/usr/diag/prdf/common/framework/service/iipServiceDataCollector.h
index 704dddf70..e8cdb79a5 100755
--- a/src/usr/diag/prdf/common/framework/service/iipServiceDataCollector.h
+++ b/src/usr/diag/prdf/common/framework/service/iipServiceDataCollector.h
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -628,6 +628,11 @@ public:
void clearMruListGard();
/**
+ * @brief Iterates the MRU list and clears gard for any NVDIMM targets.
+ */
+ void clearNvdimmMruListGard();
+
+ /**
* @brief Iterates the MRU list and returns true if at least on target in
* the list is set to be garded.
* @return True if there is at least one target set to be garded.
diff --git a/src/usr/diag/prdf/common/framework/service/prdfServiceDataCollector.C b/src/usr/diag/prdf/common/framework/service/prdfServiceDataCollector.C
index d9681d66b..731102a26 100755
--- a/src/usr/diag/prdf/common/framework/service/prdfServiceDataCollector.C
+++ b/src/usr/diag/prdf/common/framework/service/prdfServiceDataCollector.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -177,6 +177,88 @@ void ServiceDataCollector::clearMruListGard()
//------------------------------------------------------------------------------
+void ServiceDataCollector::clearNvdimmMruListGard()
+{
+ #define PRDF_FUNC "[ServiceDataCollector::clearNvdimmMruListGard] "
+
+ #ifdef CONFIG_NVDIMM
+ #ifdef __HOSTBOOT_MODULE
+ // Loop through the MRU list.
+ for ( auto & mru : xMruList )
+ {
+ PRDcallout callout = mru.callout;
+ PRDcalloutData::MruType mruType = callout.getType();
+
+ if ( mruType == PRDcalloutData::TYPE_TARGET )
+ {
+ TargetHandle_t trgt = callout.getTarget();
+
+ // If the callout target is an NVDIMM send a message to
+ // PHYP/Hostboot that a save/restore may work, and if we are at
+ // IPL, clear Gard on the NVDIMM.
+ if ( TYPE_DIMM == PlatServices::getTargetType(trgt) &&
+ isNVDIMM(trgt) )
+ {
+ // Send the message to PHYP/Hostboot if a predictive log
+ if ( queryServiceCall() )
+ {
+ uint32_t l_rc = PlatServices::nvdimmNotifyProtChange( trgt,
+ NVDIMM::NVDIMM_RISKY_HW_ERROR );
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_TRAC( PRDF_FUNC "nvdimmNotifyProtChange(0x%08x) "
+ "failed.", PlatServices::getHuid(trgt) );
+ continue;
+ }
+ }
+ #ifndef __HOSTBOOT_RUNTIME
+ // IPL, clear Gard
+ mru.gardState = NO_GARD;
+ #endif
+ }
+ }
+ else if ( mruType == PRDcalloutData::TYPE_MEMMRU )
+ {
+ MemoryMru memMru( callout.flatten() );
+ TargetHandleList dimmList = memMru.getCalloutList();
+
+ for ( auto & dimm : dimmList )
+ {
+ // If the callout target is an NVDIMM send a message to
+ // PHYP/Hostboot that a save/restore may work, and if we are at
+ // IPL, clear Gard on the NVDIMM.
+ if ( TYPE_DIMM == PlatServices::getTargetType(dimm) &&
+ isNVDIMM(dimm) )
+ {
+ // Send the message to PHYP/Hostboot if a predictive log
+ if ( queryServiceCall() )
+ {
+ uint32_t l_rc = PlatServices::nvdimmNotifyProtChange(
+ dimm, NVDIMM::NVDIMM_RISKY_HW_ERROR );
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_TRAC( PRDF_FUNC "nvdimmNotifyProtChange"
+ "(0x%08x) failed.",
+ PlatServices::getHuid(dimm) );
+ continue;
+ }
+ }
+ #ifndef __HOSTBOOT_RUNTIME
+ // IPL, clear Gard
+ mru.gardState = NO_GARD;
+ #endif
+ }
+ }
+ }
+ }
+ #endif // __HOSTBOOT_MODULE
+ #endif // CONFIG_NVDIMM
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
bool ServiceDataCollector::isGardRequested()
{
bool gardRecordExit = false;
diff --git a/src/usr/diag/prdf/common/iipconst.h b/src/usr/diag/prdf/common/iipconst.h
index 07c5ded16..5c71cf8f7 100755
--- a/src/usr/diag/prdf/common/iipconst.h
+++ b/src/usr/diag/prdf/common/iipconst.h
@@ -65,12 +65,13 @@ namespace PRDF
/* Constants */
/*--------------------------------------------------------------------*/
+// Return code constants
#ifndef SUCCESS
-#define SUCCESS 0
+static const int32_t SUCCESS = 0;
#endif
#ifndef FAIL
-#define FAIL -1
+static const int32_t FAIL = -1;
#endif
enum DOMAIN_ID
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_mc.rule b/src/usr/diag/prdf/common/plat/axone/axone_mc.rule
index 4f63011fc..f23fee7d2 100644
--- a/src/usr/diag/prdf/common/plat/axone/axone_mc.rule
+++ b/src/usr/diag/prdf/common/plat/axone/axone_mc.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -141,39 +141,39 @@ chip axone_mc
};
############################################################################
- # P9 MC target MCBISTFIR
+ # P9 MC target MCMISCFIR
############################################################################
- register MCBISTFIR
+ register MCMISCFIR
{
- name "P9 MC target MCBISTFIR";
+ name "P9 MC target MCMISCFIR";
scomaddr 0x07012300;
reset (&, 0x07012301);
mask (|, 0x07012305);
capture group default;
};
- register MCBISTFIR_MASK
+ register MCMISCFIR_MASK
{
- name "P9 MC target MCBISTFIR MASK";
+ name "P9 MC target MCMISCFIR MASK";
scomaddr 0x07012303;
capture group default;
};
- register MCBISTFIR_ACT0
+ register MCMISCFIR_ACT0
{
- name "P9 MC target MCBISTFIR ACT0";
+ name "P9 MC target MCMISCFIR ACT0";
scomaddr 0x07012306;
capture group default;
- capture req nonzero("MCBISTFIR");
+ capture req nonzero("MCMISCFIR");
};
- register MCBISTFIR_ACT1
+ register MCMISCFIR_ACT1
{
- name "P9 MC target MCBISTFIR ACT1";
+ name "P9 MC target MCMISCFIR ACT1";
scomaddr 0x07012307;
capture group default;
- capture req nonzero("MCBISTFIR");
+ capture req nonzero("MCMISCFIR");
};
# Include registers not defined by the xml
@@ -253,9 +253,9 @@ group gMC_CHIPLET_FIR attntype CHECK_STOP, RECOVERABLE
(rMC_CHIPLET_FIR, bit(11)) ? analyzeConnectedMCC3;
/** MC_CHIPLET_FIR[12]
- * Attention from MCBISTFIR
+ * Attention from MCMISCFIR
*/
- (rMC_CHIPLET_FIR, bit(12)) ? analyzeMCBISTFIR;
+ (rMC_CHIPLET_FIR, bit(12)) ? analyzeMCMISCFIR;
/** MC_CHIPLET_FIR[13]
* Attention from IOOMIFIR 0
@@ -358,9 +358,9 @@ group gMC_CHIPLET_UCS_FIR attntype UNIT_CS
(rMC_CHIPLET_UCS_FIR, bit(8)) ? analyzeConnectedMCC3;
/** MC_CHIPLET_UCS_FIR[9]
- * Attention from MCBISTFIR
+ * Attention from MCMISCFIR
*/
- (rMC_CHIPLET_UCS_FIR, bit(9)) ? analyzeMCBISTFIR;
+ (rMC_CHIPLET_UCS_FIR, bit(9)) ? analyzeMCMISCFIR;
/** MC_CHIPLET_UCS_FIR[10]
* Attention from IOOMIFIR 0
@@ -448,9 +448,9 @@ group gMC_CHIPLET_HA_FIR attntype HOST_ATTN
(rMC_CHIPLET_HA_FIR, bit(8)) ? analyzeConnectedMCC3;
/** MC_CHIPLET_HA_FIR[9]
- * Attention from MCBISTFIR
+ * Attention from MCMISCFIR
*/
- (rMC_CHIPLET_HA_FIR, bit(9)) ? analyzeMCBISTFIR;
+ (rMC_CHIPLET_HA_FIR, bit(9)) ? analyzeMCMISCFIR;
};
@@ -563,94 +563,94 @@ group gMC_LFIR
};
################################################################################
-# P9 MC target MCBISTFIR
+# P9 MC target MCMISCFIR
################################################################################
-rule rMCBISTFIR
+rule rMCMISCFIR
{
CHECK_STOP:
- MCBISTFIR & ~MCBISTFIR_MASK & ~MCBISTFIR_ACT0 & ~MCBISTFIR_ACT1;
+ MCMISCFIR & ~MCMISCFIR_MASK & ~MCMISCFIR_ACT0 & ~MCMISCFIR_ACT1;
RECOVERABLE:
- MCBISTFIR & ~MCBISTFIR_MASK & ~MCBISTFIR_ACT0 & MCBISTFIR_ACT1;
+ MCMISCFIR & ~MCMISCFIR_MASK & ~MCMISCFIR_ACT0 & MCMISCFIR_ACT1;
HOST_ATTN:
- MCBISTFIR & ~MCBISTFIR_MASK & MCBISTFIR_ACT0 & ~MCBISTFIR_ACT1;
+ MCMISCFIR & ~MCMISCFIR_MASK & MCMISCFIR_ACT0 & ~MCMISCFIR_ACT1;
UNIT_CS:
- MCBISTFIR & ~MCBISTFIR_MASK & MCBISTFIR_ACT0 & MCBISTFIR_ACT1;
+ MCMISCFIR & ~MCMISCFIR_MASK & MCMISCFIR_ACT0 & MCMISCFIR_ACT1;
};
-group gMCBISTFIR
+group gMCMISCFIR
filter singlebit,
cs_root_cause
{
- /** MCBISTFIR[0]
+ /** MCMISCFIR[0]
* WAT debug bus attn
*/
- (rMCBISTFIR, bit(0)) ? defaultMaskedError;
+ (rMCMISCFIR, bit(0)) ? defaultMaskedError;
- /** MCBISTFIR[1]
+ /** MCMISCFIR[1]
* WAT debug register parity error
*/
- (rMCBISTFIR, bit(1)) ? defaultMaskedError;
+ (rMCMISCFIR, bit(1)) ? defaultMaskedError;
- /** MCBISTFIR[2]
+ /** MCMISCFIR[2]
* SCOM recoverable register parity error
*/
- (rMCBISTFIR, bit(2)) ? defaultMaskedError;
+ (rMCMISCFIR, bit(2)) ? self_th_1;
- /** MCBISTFIR[3]
+ /** MCMISCFIR[3]
* Spare
*/
- (rMCBISTFIR, bit(3)) ? defaultMaskedError;
+ (rMCMISCFIR, bit(3)) ? defaultMaskedError;
- /** MCBISTFIR[4]
+ /** MCMISCFIR[4]
* Chan 0A application interrupt
*/
- (rMCBISTFIR, bit(4)) ? defaultMaskedError;
+ (rMCMISCFIR, bit(4)) ? defaultMaskedError;
- /** MCBISTFIR[5]
+ /** MCMISCFIR[5]
* Chan 0B application interrupt
*/
- (rMCBISTFIR, bit(5)) ? defaultMaskedError;
+ (rMCMISCFIR, bit(5)) ? defaultMaskedError;
- /** MCBISTFIR[6]
+ /** MCMISCFIR[6]
* Chan 1A application interrupt
*/
- (rMCBISTFIR, bit(6)) ? defaultMaskedError;
+ (rMCMISCFIR, bit(6)) ? defaultMaskedError;
- /** MCBISTFIR[7]
+ /** MCMISCFIR[7]
* Chan 1B application interrupt
*/
- (rMCBISTFIR, bit(7)) ? defaultMaskedError;
+ (rMCMISCFIR, bit(7)) ? defaultMaskedError;
- /** MCBISTFIR[8]
+ /** MCMISCFIR[8]
* Chan 2A application interrupt
*/
- (rMCBISTFIR, bit(8)) ? defaultMaskedError;
+ (rMCMISCFIR, bit(8)) ? defaultMaskedError;
- /** MCBISTFIR[9]
+ /** MCMISCFIR[9]
* Chan 2B application interrupt
*/
- (rMCBISTFIR, bit(9)) ? defaultMaskedError;
+ (rMCMISCFIR, bit(9)) ? defaultMaskedError;
- /** MCBISTFIR[10]
+ /** MCMISCFIR[10]
* Chan 3A application interrupt
*/
- (rMCBISTFIR, bit(10)) ? defaultMaskedError;
+ (rMCMISCFIR, bit(10)) ? defaultMaskedError;
- /** MCBISTFIR[11]
+ /** MCMISCFIR[11]
* Chan 3B application interrupt
*/
- (rMCBISTFIR, bit(11)) ? defaultMaskedError;
+ (rMCMISCFIR, bit(11)) ? defaultMaskedError;
- /** MCBISTFIR[12]
+ /** MCMISCFIR[12]
* Internal SCOM error
*/
- (rMCBISTFIR, bit(12)) ? defaultMaskedError;
+ (rMCMISCFIR, bit(12)) ? defaultMaskedError;
- /** MCBISTFIR[13]
+ /** MCMISCFIR[13]
* Internal SCOM error clone
*/
- (rMCBISTFIR, bit(13)) ? defaultMaskedError;
+ (rMCMISCFIR, bit(13)) ? defaultMaskedError;
};
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_mc_actions.rule b/src/usr/diag/prdf/common/plat/axone/axone_mc_actions.rule
index aab2297ef..7c639bf5e 100644
--- a/src/usr/diag/prdf/common/plat/axone/axone_mc_actions.rule
+++ b/src/usr/diag/prdf/common/plat/axone/axone_mc_actions.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2017,2018
+# Contributors Listed Below - COPYRIGHT 2017,2019
# [+] International Business Machines Corp.
#
#
@@ -28,7 +28,7 @@
###############################################################################
actionclass analyzeMC_LFIR { analyze(gMC_LFIR); };
-actionclass analyzeMCBISTFIR { analyze(gMCBISTFIR); };
+actionclass analyzeMCMISCFIR { analyze(gMCMISCFIR); };
###############################################################################
# Analyze connected
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_mc_regs.rule b/src/usr/diag/prdf/common/plat/axone/axone_mc_regs.rule
new file mode 100644
index 000000000..150e6895a
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/axone/axone_mc_regs.rule
@@ -0,0 +1,47 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/diag/prdf/common/plat/axone/axone_mc_regs.rule $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+################################################################################
+# Additional registers for MC target, not defined in XML
+################################################################################
+
+ ############################################################################
+ # PCB Slave Error Regs
+ ############################################################################
+
+ register MC_ERROR_REG
+ {
+ name "MC PCB Slave error reg";
+ scomaddr 0x070F001F;
+ capture group PllFIRs;
+ };
+
+ register MC_CONFIG_REG
+ {
+ name "MC PCB Slave config reg";
+ scomaddr 0x070F001E;
+ capture group PllFIRs;
+ };
+
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_mcc.rule b/src/usr/diag/prdf/common/plat/axone/axone_mcc.rule
index bf632abbb..31f663c77 100644
--- a/src/usr/diag/prdf/common/plat/axone/axone_mcc.rule
+++ b/src/usr/diag/prdf/common/plat/axone/axone_mcc.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -180,22 +180,22 @@ rule rDSTLFIR
group gDSTLFIR
filter singlebit,
- cs_root_cause
+ cs_root_cause(0,4)
{
/** DSTLFIR[0]
* AFU initiated Checkstop on Subchannel A
*/
- (rDSTLFIR, bit(0)) ? defaultMaskedError;
+ (rDSTLFIR, bit(0)) ? analyze_ocmb_chnl0_UERE;
/** DSTLFIR[1]
* AFU initiated Recoverable Attn on Subchannel A
*/
- (rDSTLFIR, bit(1)) ? defaultMaskedError;
+ (rDSTLFIR, bit(1)) ? analyze_ocmb_chnl0;
/** DSTLFIR[2]
* AFU initiated Special Attn on Subchannel A
*/
- (rDSTLFIR, bit(2)) ? defaultMaskedError;
+ (rDSTLFIR, bit(2)) ? analyze_ocmb_chnl0;
/** DSTLFIR[3]
* AFU initiated Application Interrupt Attn on Subchannel A
@@ -205,17 +205,17 @@ group gDSTLFIR
/** DSTLFIR[4]
* AFU initiated Checkstop on Subchannel B
*/
- (rDSTLFIR, bit(4)) ? defaultMaskedError;
+ (rDSTLFIR, bit(4)) ? analyze_ocmb_chnl1_UERE;
/** DSTLFIR[5]
* AFU initiated Recoverable Attn on Subchannel B
*/
- (rDSTLFIR, bit(5)) ? defaultMaskedError;
+ (rDSTLFIR, bit(5)) ? analyze_ocmb_chnl1;
/** DSTLFIR[6]
* AFU initiated Special Attn on Subchannel B
*/
- (rDSTLFIR, bit(6)) ? defaultMaskedError;
+ (rDSTLFIR, bit(6)) ? analyze_ocmb_chnl1;
/** DSTLFIR[7]
* AFU initiated Application Interrupt Attn on Subchannel B
@@ -225,52 +225,52 @@ group gDSTLFIR
/** DSTLFIR[8]
* Async crossing parity error
*/
- (rDSTLFIR, bit(8)) ? defaultMaskedError;
+ (rDSTLFIR, bit(8)) ? self_th_1;
/** DSTLFIR[9]
* Async crossing sequence error
*/
- (rDSTLFIR, bit(9)) ? defaultMaskedError;
+ (rDSTLFIR, bit(9)) ? self_th_1;
/** DSTLFIR[10]
* Config reg recoverable parity error
*/
- (rDSTLFIR, bit(10)) ? defaultMaskedError;
+ (rDSTLFIR, bit(10)) ? self_th_1;
/** DSTLFIR[11]
* Config reg fatal parity error
*/
- (rDSTLFIR, bit(11)) ? defaultMaskedError;
+ (rDSTLFIR, bit(11)) ? self_th_1;
/** DSTLFIR[12]
* Subchannel A counter error
*/
- (rDSTLFIR, bit(12)) ? defaultMaskedError;
+ (rDSTLFIR, bit(12)) ? chnl0_omi_bus_th_1;
/** DSTLFIR[13]
* Subchannel B counter error
*/
- (rDSTLFIR, bit(13)) ? defaultMaskedError;
+ (rDSTLFIR, bit(13)) ? chnl1_omi_bus_th_1;
/** DSTLFIR[14]
* Subchannel A timeout error
*/
- (rDSTLFIR, bit(14)) ? defaultMaskedError;
+ (rDSTLFIR, bit(14)) ? chnl0_omi_bus_th_32_perDay;
/** DSTLFIR[15]
* Subchannel B timeout error
*/
- (rDSTLFIR, bit(15)) ? defaultMaskedError;
+ (rDSTLFIR, bit(15)) ? chnl1_omi_bus_th_32_perDay;
/** DSTLFIR[16]
* Subchannel A buffer overuse error
*/
- (rDSTLFIR, bit(16)) ? defaultMaskedError;
+ (rDSTLFIR, bit(16)) ? chnl0_ocmb_th_1;
/** DSTLFIR[17]
* Subchannel B buffer overuse error
*/
- (rDSTLFIR, bit(17)) ? defaultMaskedError;
+ (rDSTLFIR, bit(17)) ? chnl1_ocmb_th_1;
/** DSTLFIR[18]
* Subchannel A DL link down
@@ -293,14 +293,29 @@ group gDSTLFIR
(rDSTLFIR, bit(21)) ? defaultMaskedError;
/** DSTLFIR[22]
- * Internal SCOM error
+ * DSTLFIR channel timeout on subch A
*/
- (rDSTLFIR, bit(22)) ? defaultMaskedError;
+ (rDSTLFIR, bit(22)) ? chnl0_omi_bus_th_1;
/** DSTLFIR[23]
- * Internal SCOM error clone
+ * DSTLFIR channel timeout on subch B
+ */
+ (rDSTLFIR, bit(23)) ? chnl1_omi_bus_th_1;
+
+ /** DSTLFIR[24:25]
+ * spare
+ */
+ (rDSTLFIR, bit(24|25)) ? defaultMaskedError;
+
+ /** DSTLFIR[26]
+ * Internal SCOM Error
+ */
+ (rDSTLFIR, bit(26)) ? defaultMaskedError;
+
+ /** DSTLFIR[27]
+ * Internal SCOM Error Clone
*/
- (rDSTLFIR, bit(23)) ? defaultMaskedError;
+ (rDSTLFIR, bit(27)) ? defaultMaskedError;
};
@@ -327,22 +342,22 @@ group gUSTLFIR
/** USTLFIR[0]
* Chan A unexpected data error
*/
- (rUSTLFIR, bit(0)) ? defaultMaskedError;
+ (rUSTLFIR, bit(0)) ? chnl0_ocmb_th_1;
/** USTLFIR[1]
* Chan B unexpected data error
*/
- (rUSTLFIR, bit(1)) ? defaultMaskedError;
+ (rUSTLFIR, bit(1)) ? chnl1_ocmb_th_1;
/** USTLFIR[2]
* Chan A invalid template error
*/
- (rUSTLFIR, bit(2)) ? defaultMaskedError;
+ (rUSTLFIR, bit(2)) ? chnl0_ocmb_th_1;
/** USTLFIR[3]
* Chan B invalid template error
*/
- (rUSTLFIR, bit(3)) ? defaultMaskedError;
+ (rUSTLFIR, bit(3)) ? chnl1_ocmb_th_1;
/** USTLFIR[4]
* Chan A half speed mode
@@ -357,12 +372,12 @@ group gUSTLFIR
/** USTLFIR[6]
* WDF buffer CE
*/
- (rUSTLFIR, bit(6)) ? defaultMaskedError;
+ (rUSTLFIR, bit(6)) ? self_th_32perDay;
/** USTLFIR[7]
* WDF buffer UE
*/
- (rUSTLFIR, bit(7)) ? defaultMaskedError;
+ (rUSTLFIR, bit(7)) ? self_th_1;
/** USTLFIR[8]
* WDF buffer SUE
@@ -372,32 +387,32 @@ group gUSTLFIR
/** USTLFIR[9]
* WDF buffer overrun
*/
- (rUSTLFIR, bit(9)) ? defaultMaskedError;
+ (rUSTLFIR, bit(9)) ? self_th_1;
/** USTLFIR[10]
* WDF tag parity error
*/
- (rUSTLFIR, bit(10)) ? defaultMaskedError;
+ (rUSTLFIR, bit(10)) ? self_th_1;
/** USTLFIR[11]
* WDF scom sequencer error
*/
- (rUSTLFIR, bit(11)) ? defaultMaskedError;
+ (rUSTLFIR, bit(11)) ? self_th_1;
/** USTLFIR[12]
* WDF pwctl sequencer error
*/
- (rUSTLFIR, bit(12)) ? defaultMaskedError;
+ (rUSTLFIR, bit(12)) ? self_th_1;
/** USTLFIR[13]
* WDF misc_reg parity error
*/
- (rUSTLFIR, bit(13)) ? defaultMaskedError;
+ (rUSTLFIR, bit(13)) ? self_th_1;
/** USTLFIR[14]
* WDF MCA async error
*/
- (rUSTLFIR, bit(14)) ? defaultMaskedError;
+ (rUSTLFIR, bit(14)) ? self_th_1;
/** USTLFIR[15]
* WDF Data Syndrome NE0
@@ -407,32 +422,32 @@ group gUSTLFIR
/** USTLFIR[16]
* WDF CMT parity error
*/
- (rUSTLFIR, bit(16)) ? defaultMaskedError;
+ (rUSTLFIR, bit(16)) ? self_th_1;
/** USTLFIR[17]
- * TBD
+ * spare
*/
(rUSTLFIR, bit(17)) ? defaultMaskedError;
/** USTLFIR[18]
- * TBD
+ * spare
*/
(rUSTLFIR, bit(18)) ? defaultMaskedError;
/** USTLFIR[19]
- * TBD
+ * Read Buffers overflowed/underflowed
*/
- (rUSTLFIR, bit(19)) ? defaultMaskedError;
+ (rUSTLFIR, bit(19)) ? all_ocmb_and_mcc_th_1;
/** USTLFIR[20]
* WRT Buffer CE
*/
- (rUSTLFIR, bit(20)) ? defaultMaskedError;
+ (rUSTLFIR, bit(20)) ? parent_proc_th_32perDay;
/** USTLFIR[21]
* WRT Buffer UE
*/
- (rUSTLFIR, bit(21)) ? defaultMaskedError;
+ (rUSTLFIR, bit(21)) ? parent_proc_th_1;
/** USTLFIR[22]
* WRT Buffer SUE
@@ -442,12 +457,12 @@ group gUSTLFIR
/** USTLFIR[23]
* WRT scom sequencer error
*/
- (rUSTLFIR, bit(23)) ? defaultMaskedError;
+ (rUSTLFIR, bit(23)) ? self_th_1;
/** USTLFIR[24]
* WRT misc_reg parity error
*/
- (rUSTLFIR, bit(24)) ? defaultMaskedError;
+ (rUSTLFIR, bit(24)) ? self_th_1;
/** USTLFIR[25:26]
* WRT error information spares
@@ -457,22 +472,22 @@ group gUSTLFIR
/** USTLFIR[27]
* Chan A fail response checkstop
*/
- (rUSTLFIR, bit(27)) ? defaultMaskedError;
+ (rUSTLFIR, bit(27)) ? chnl0_ocmb_th_1;
/** USTLFIR[28]
* Chan B fail response checkstop
*/
- (rUSTLFIR, bit(28)) ? defaultMaskedError;
+ (rUSTLFIR, bit(28)) ? chnl1_ocmb_th_1;
/** USTLFIR[29]
* Chan A fail response recoverable
*/
- (rUSTLFIR, bit(29)) ? defaultMaskedError;
+ (rUSTLFIR, bit(29)) ? threshold_and_mask_chnl0_ocmb_th_1;
/** USTLFIR[30]
* Chan B fail response recoverable
*/
- (rUSTLFIR, bit(30)) ? defaultMaskedError;
+ (rUSTLFIR, bit(30)) ? threshold_and_mask_chnl1_ocmb_th_1;
/** USTLFIR[31]
* Chan A lol drop checkstop
@@ -487,72 +502,72 @@ group gUSTLFIR
/** USTLFIR[33]
* Chan A lol drop recoverable
*/
- (rUSTLFIR, bit(33)) ? defaultMaskedError;
+ (rUSTLFIR, bit(33)) ? chnl0_ocmb_H_omi_L_th_1;
/** USTLFIR[34]
* Chan B lol drop recoverable
*/
- (rUSTLFIR, bit(34)) ? defaultMaskedError;
+ (rUSTLFIR, bit(34)) ? chnl1_ocmb_H_omi_L_th_1;
/** USTLFIR[35]
* Chan A flit parity error
*/
- (rUSTLFIR, bit(35)) ? defaultMaskedError;
+ (rUSTLFIR, bit(35)) ? chnl0_omi_th_1;
/** USTLFIR[36]
* Chan B flit parity error
*/
- (rUSTLFIR, bit(36)) ? defaultMaskedError;
+ (rUSTLFIR, bit(36)) ? chnl1_omi_th_1;
/** USTLFIR[37]
* Chan A fatal parity error
*/
- (rUSTLFIR, bit(37)) ? defaultMaskedError;
+ (rUSTLFIR, bit(37)) ? chnl0_omi_th_1;
/** USTLFIR[38]
* Chan B fatal parity error
*/
- (rUSTLFIR, bit(38)) ? defaultMaskedError;
+ (rUSTLFIR, bit(38)) ? chnl1_omi_th_1;
/** USTLFIR[39]
* Chan A more than 2 data flits for template 9
*/
- (rUSTLFIR, bit(39)) ? defaultMaskedError;
+ (rUSTLFIR, bit(39)) ? chnl0_ocmb_th_1;
/** USTLFIR[40]
* Chan B more than 2 data flits for template 9
*/
- (rUSTLFIR, bit(40)) ? defaultMaskedError;
+ (rUSTLFIR, bit(40)) ? chnl1_ocmb_th_1;
/** USTLFIR[41]
* Chan A excess bad data bits
*/
- (rUSTLFIR, bit(41)) ? defaultMaskedError;
+ (rUSTLFIR, bit(41)) ? chnl0_ocmb_th_1;
/** USTLFIR[42]
* Chan B excess bad data bits
*/
- (rUSTLFIR, bit(42)) ? defaultMaskedError;
+ (rUSTLFIR, bit(42)) ? chnl1_ocmb_th_1;
/** USTLFIR[43]
* Chan A memory read data returned in template 0
*/
- (rUSTLFIR, bit(43)) ? defaultMaskedError;
+ (rUSTLFIR, bit(43)) ? chnl0_ocmb_th_1;
/** USTLFIR[44]
* Chan B memory read data returned in template 0
*/
- (rUSTLFIR, bit(44)) ? defaultMaskedError;
+ (rUSTLFIR, bit(44)) ? chnl1_ocmb_th_1;
/** USTLFIR[45]
* Chan A MMIO in lol mode
*/
- (rUSTLFIR, bit(45)) ? defaultMaskedError;
+ (rUSTLFIR, bit(45)) ? chnl0_omi_th_1;
/** USTLFIR[46]
* Chan B MMIO in lol mode
*/
- (rUSTLFIR, bit(46)) ? defaultMaskedError;
+ (rUSTLFIR, bit(46)) ? chnl1_omi_th_1;
/** USTLFIR[47]
* Chan A bad data
@@ -567,62 +582,62 @@ group gUSTLFIR
/** USTLFIR[49]
* Chan A excess data error
*/
- (rUSTLFIR, bit(49)) ? defaultMaskedError;
+ (rUSTLFIR, bit(49)) ? chnl0_ocmb_th_1;
/** USTLFIR[50]
* Chan B excess data error
*/
- (rUSTLFIR, bit(50)) ? defaultMaskedError;
+ (rUSTLFIR, bit(50)) ? chnl1_ocmb_th_1;
/** USTLFIR[51]
* Chan A Bad CRC data not valid error
*/
- (rUSTLFIR, bit(51)) ? defaultMaskedError;
+ (rUSTLFIR, bit(51)) ? chnl0_omi_th_1;
/** USTLFIR[52]
* Chan B Bad CRC data not valid error
*/
- (rUSTLFIR, bit(52)) ? defaultMaskedError;
+ (rUSTLFIR, bit(52)) ? chnl1_omi_th_1;
/** USTLFIR[53]
* Chan A FIFO overflow error
*/
- (rUSTLFIR, bit(53)) ? defaultMaskedError;
+ (rUSTLFIR, bit(53)) ? chnl0_omi_th_1;
/** USTLFIR[54]
* Chan B FIFO overflow error
*/
- (rUSTLFIR, bit(54)) ? defaultMaskedError;
+ (rUSTLFIR, bit(54)) ? chnl1_omi_th_1;
/** USTLFIR[55]
* Chan A invalid cmd error
*/
- (rUSTLFIR, bit(55)) ? defaultMaskedError;
+ (rUSTLFIR, bit(55)) ? chnl0_ocmb_th_1;
/** USTLFIR[56]
* Chan B invalid cmd error
*/
- (rUSTLFIR, bit(56)) ? defaultMaskedError;
+ (rUSTLFIR, bit(56)) ? chnl1_ocmb_th_1;
/** USTLFIR[57]
* Fatal reg parity error
*/
- (rUSTLFIR, bit(57)) ? defaultMaskedError;
+ (rUSTLFIR, bit(57)) ? self_th_1;
/** USTLFIR[58]
* Recoverable reg parity error
*/
- (rUSTLFIR, bit(58)) ? defaultMaskedError;
+ (rUSTLFIR, bit(58)) ? self_th_1;
/** USTLFIR[59]
* Chan A invalid DL DP combo
*/
- (rUSTLFIR, bit(59)) ? defaultMaskedError;
+ (rUSTLFIR, bit(59)) ? chnl0_ocmb_th_1;
/** USTLFIR[60]
* Chan B invalid DL DP combo
*/
- (rUSTLFIR, bit(60)) ? defaultMaskedError;
+ (rUSTLFIR, bit(60)) ? chnl1_ocmb_th_1;
/** USTLFIR[61]
* spare
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_mcc_actions.rule b/src/usr/diag/prdf/common/plat/axone/axone_mcc_actions.rule
index 38edbaaea..e34035165 100644
--- a/src/usr/diag/prdf/common/plat/axone/axone_mcc_actions.rule
+++ b/src/usr/diag/prdf/common/plat/axone/axone_mcc_actions.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -24,9 +24,163 @@
# IBM_PROLOG_END_TAG
################################################################################
+# Callouts
+################################################################################
+
+actionclass chnl0_omi
+{
+ callout(connected(TYPE_OMI,0), MRU_MED);
+};
+
+actionclass chnl1_omi
+{
+ callout(connected(TYPE_OMI,1), MRU_MED);
+};
+
+actionclass chnl0_omi_L
+{
+ callout(connected(TYPE_OMI,0), MRU_LOW);
+};
+
+actionclass chnl1_omi_L
+{
+ callout(connected(TYPE_OMI,1), MRU_LOW);
+};
+
+actionclass chnl0_ocmb
+{
+ callout(connected(TYPE_OCMB_CHIP,0), MRU_MED);
+};
+
+actionclass chnl1_ocmb
+{
+ callout(connected(TYPE_OCMB_CHIP,1), MRU_MED);
+};
+
+actionclass chnl0_omi_bus
+{
+ funccall("omiParentCalloutBusInterfacePlugin_0");
+};
+
+actionclass chnl1_omi_bus
+{
+ funccall("omiParentCalloutBusInterfacePlugin_1");
+};
+
+actionclass chnl0_omi_bus_th_1
+{
+ chnl0_omi_bus;
+ threshold1;
+};
+
+actionclass chnl1_omi_bus_th_1
+{
+ chnl1_omi_bus;
+ threshold1;
+};
+
+actionclass chnl0_omi_bus_th_32_perDay
+{
+ chnl0_omi_bus;
+ threshold32pday;
+};
+
+actionclass chnl1_omi_bus_th_32_perDay
+{
+ chnl1_omi_bus;
+ threshold32pday;
+};
+
+actionclass chnl0_omi_th_1
+{
+ chnl0_omi;
+ threshold1;
+};
+
+actionclass chnl1_omi_th_1
+{
+ chnl1_omi;
+ threshold1;
+};
+
+actionclass chnl0_ocmb_th_1
+{
+ chnl0_ocmb;
+ threshold1;
+};
+
+actionclass chnl1_ocmb_th_1
+{
+ chnl1_ocmb;
+ threshold1;
+};
+
+actionclass all_ocmb_and_mcc_th_1
+{
+ chnl0_ocmb;
+ chnl1_ocmb;
+ calloutSelfMed;
+ threshold1;
+};
+
+actionclass chnl0_ocmb_H_omi_L_th_1
+{
+ chnl0_ocmb;
+ chnl0_omi_L;
+ threshold1;
+};
+
+actionclass chnl1_ocmb_H_omi_L_th_1
+{
+ chnl1_ocmb;
+ chnl1_omi_L;
+ threshold1;
+};
+
+actionclass threshold_and_mask_chnl0_ocmb_th_1
+{
+ threshold_and_mask;
+ chnl0_ocmb;
+ threshold1;
+};
+
+actionclass threshold_and_mask_chnl1_ocmb_th_1
+{
+ threshold_and_mask;
+ chnl1_ocmb;
+ threshold1;
+};
+
+################################################################################
# Analyze groups
################################################################################
actionclass analyzeDSTLFIR { analyze(gDSTLFIR); };
actionclass analyzeUSTLFIR { analyze(gUSTLFIR); };
+################################################################################
+# Analyze connected
+################################################################################
+
+actionclass analyze_ocmb_chnl0
+{
+ try( funccall("checkOcmb_0"), analyze(connected(TYPE_OCMB_CHIP, 0)) );
+};
+
+actionclass analyze_ocmb_chnl1
+{
+ try( funccall("checkOcmb_1"), analyze(connected(TYPE_OCMB_CHIP, 1)) );
+};
+
+actionclass analyze_ocmb_chnl0_UERE
+{
+ SueSource;
+ analyze_ocmb_chnl0;
+};
+
+actionclass analyze_ocmb_chnl1_UERE
+{
+ SueSource;
+ analyze_ocmb_chnl1;
+};
+
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_mcc_regs.rule b/src/usr/diag/prdf/common/plat/axone/axone_mcc_regs.rule
new file mode 100644
index 000000000..001a54e5c
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/axone/axone_mcc_regs.rule
@@ -0,0 +1,80 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/diag/prdf/common/plat/axone/axone_mcc_regs.rule $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+
+###############################################################################
+# Additional registers for mcc, not defined in XML
+###############################################################################
+
+ ###########################################################################
+ # P9 Axone target Channel Fail Config registers
+ ###########################################################################
+
+ register DSTLCFG2
+ {
+ name "P9 Axone DSTL Error Injection Register";
+ scomaddr 0x0701090E;
+ capture group default;
+ };
+
+ register USTLFAILMASK
+ {
+ name "P9 Axone USTL Fail Response Channel Fail Mask";
+ scomaddr 0x07010A13;
+ capture group default;
+ };
+
+ ###########################################################################
+ # P9 Axone target DSTLFIR
+ ###########################################################################
+
+ register DSTLFIR_AND
+ {
+ name "P9 MCC target DSTLFIR atomic AND";
+ scomaddr 0x07010901;
+ capture group never;
+ access write_only;
+ };
+
+ register DSTLFIR_MASK_OR
+ {
+ name "P9 MCC target DSTLFIR MASK atomic OR";
+ scomaddr 0x07010905;
+ capture group never;
+ access write_only;
+ };
+
+ ###########################################################################
+ # P9 Axone target USTLFIR
+ ###########################################################################
+
+ register USTLFIR_MASK_OR
+ {
+ name "P9 MCC target USTLFIR MASK atomic OR";
+ scomaddr 0x07010A05;
+ capture group never;
+ access write_only;
+ };
+
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_mi.rule b/src/usr/diag/prdf/common/plat/axone/axone_mi.rule
index 078163819..56366a7f5 100644
--- a/src/usr/diag/prdf/common/plat/axone/axone_mi.rule
+++ b/src/usr/diag/prdf/common/plat/axone/axone_mi.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -148,27 +148,27 @@ group gMCFIR
/** MCFIR[0]
* MC internal recoverable error
*/
- (rMCFIR, bit(0)) ? defaultMaskedError;
+ (rMCFIR, bit(0)) ? self_th_1;
/** MCFIR[1]
* MC internal non recoverable error
*/
- (rMCFIR, bit(1)) ? defaultMaskedError;
+ (rMCFIR, bit(1)) ? parent_proc_th_1;
/** MCFIR[2]
* Powerbus protocol error
*/
- (rMCFIR, bit(2)) ? defaultMaskedError;
+ (rMCFIR, bit(2)) ? level2_th_1;
/** MCFIR[3]
* Inband bar hit with incorrect ttype
*/
- (rMCFIR, bit(3)) ? defaultMaskedError;
+ (rMCFIR, bit(3)) ? level2_M_self_L_th_1;
/** MCFIR[4]
* Multiple bar
*/
- (rMCFIR, bit(4)) ? defaultMaskedError;
+ (rMCFIR, bit(4)) ? self_th_1;
/** MCFIR[5]
* PB write ECC syndrome NE0
@@ -183,7 +183,7 @@ group gMCFIR
/** MCFIR[8]
* Command list timeout
*/
- (rMCFIR, bit(8)) ? defaultMaskedError;
+ (rMCFIR, bit(8)) ? threshold_and_mask_level2;
/** MCFIR[9:10]
* reserved
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_mi_regs.rule b/src/usr/diag/prdf/common/plat/axone/axone_mi_regs.rule
index 0e47e05a5..d9441d719 100644
--- a/src/usr/diag/prdf/common/plat/axone/axone_mi_regs.rule
+++ b/src/usr/diag/prdf/common/plat/axone/axone_mi_regs.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -48,34 +48,66 @@
capture group default;
};
- register MCFGP
+ register MCFGP0
{
- name "MCFGP";
- scomaddr 0x501080A;
+ name "MCFGP0";
+ scomaddr 0x0501080A;
capture group default;
capture group MirrorConfig;
};
- register MCFGPA
+ register MCFGP1
{
- name "MCFGPA";
+ name "MCFGP1";
scomaddr 0x0501080B;
capture group default;
capture group MirrorConfig;
};
- register MCFGPM
+ register MCFGP0A
{
- name "MCFGPM";
- scomaddr 0x501080C;
+ name "MCFGP0A";
+ scomaddr 0x0501080E;
capture group default;
capture group MirrorConfig;
};
- register MCFGPMA
+ register MCFGP1A
{
- name "MCFGPMA";
- scomaddr 0x0501080D;
+ name "MCFGP1A";
+ scomaddr 0x0501080F;
+ capture group default;
+ capture group MirrorConfig;
+ };
+
+ register MCFGPM0
+ {
+ name "MCFGPM0";
+ scomaddr 0x5010820;
+ capture group default;
+ capture group MirrorConfig;
+ };
+
+ register MCFGPM0A
+ {
+ name "MCFGPM0A";
+ scomaddr 0x05010821;
+ capture group default;
+ capture group MirrorConfig;
+ };
+
+ register MCFGPM1
+ {
+ name "MCFGPM1";
+ scomaddr 0x5010830;
+ capture group default;
+ capture group MirrorConfig;
+ };
+
+ register MCFGPM1A
+ {
+ name "MCFGPM1A";
+ scomaddr 0x05010831;
capture group default;
capture group MirrorConfig;
};
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_npu.rule b/src/usr/diag/prdf/common/plat/axone/axone_npu.rule
index ede5ef5cc..49c71d74a 100644
--- a/src/usr/diag/prdf/common/plat/axone/axone_npu.rule
+++ b/src/usr/diag/prdf/common/plat/axone/axone_npu.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -214,7 +214,7 @@ rule rNPU0FIR
group gNPU0FIR
filter singlebit,
- cs_root_cause(1,2,3,4,5,6,7,9,10,16,18,29,31,42,44)
+ cs_root_cause(1,2,3,4,5,6,7,9,10,16,18,19,25,29,31,40,42,44,45)
{
/** NPU0FIR[0]
* NTL array CE
@@ -354,7 +354,7 @@ group gNPU0FIR
/** NPU0FIR[27]
* Invalid access to secure memory attempted
*/
- (rNPU0FIR, bit(27)) ? defaultMaskedError;
+ (rNPU0FIR, bit(27)) ? self_th_1;
/** NPU0FIR[28]
* spare
@@ -489,12 +489,12 @@ rule rNPU1FIR
group gNPU1FIR
filter singlebit,
- cs_root_cause
+ cs_root_cause(0,2,4,6,8,10,13,14,15,20,22,25,27,29,31,32,33,34,35,37,39,40,41,42,47,49,51,53,55,57)
{
/** NPU1FIR[0]
* NDL Brick0 stall
*/
- (rNPU1FIR, bit(0)) ? defaultMaskedError;
+ (rNPU1FIR, bit(0)) ? self_th_1;
/** NPU1FIR[1]
* NDL Brick0 nostall
@@ -504,7 +504,7 @@ group gNPU1FIR
/** NPU1FIR[2]
* NDL Brick1 stall
*/
- (rNPU1FIR, bit(2)) ? defaultMaskedError;
+ (rNPU1FIR, bit(2)) ? self_th_1;
/** NPU1FIR[3]
* NDL Brick1 nostall
@@ -514,7 +514,7 @@ group gNPU1FIR
/** NPU1FIR[4]
* NDL Brick2 stall
*/
- (rNPU1FIR, bit(4)) ? defaultMaskedError;
+ (rNPU1FIR, bit(4)) ? self_th_1;
/** NPU1FIR[5]
* NDL Brick2 nostall
@@ -524,7 +524,7 @@ group gNPU1FIR
/** NPU1FIR[6]
* NDL Brick3 stall
*/
- (rNPU1FIR, bit(6)) ? defaultMaskedError;
+ (rNPU1FIR, bit(6)) ? self_th_1;
/** NPU1FIR[7]
* NDL Brick3 nostall
@@ -534,7 +534,7 @@ group gNPU1FIR
/** NPU1FIR[8]
* NDL Brick4 stall
*/
- (rNPU1FIR, bit(8)) ? defaultMaskedError;
+ (rNPU1FIR, bit(8)) ? self_th_1;
/** NPU1FIR[9]
* NDL Brick4 nostall
@@ -544,7 +544,7 @@ group gNPU1FIR
/** NPU1FIR[10]
* NDL Brick5 stall
*/
- (rNPU1FIR, bit(10)) ? defaultMaskedError;
+ (rNPU1FIR, bit(10)) ? self_th_1;
/** NPU1FIR[11]
* NDL Brick5 nostall
@@ -554,22 +554,22 @@ group gNPU1FIR
/** NPU1FIR[12]
* MISC Register ring error (ie noack)
*/
- (rNPU1FIR, bit(12)) ? defaultMaskedError;
+ (rNPU1FIR, bit(12)) ? self_th_32perDay;
/** NPU1FIR[13]
- * MISC Parity error from ibr addr regi
+ * MISC Parity error on MISC Cntrl reg
*/
- (rNPU1FIR, bit(13)) ? defaultMaskedError;
+ (rNPU1FIR, bit(13)) ? self_th_1;
/** NPU1FIR[14]
* MISC Parity error on SCOM D/A addr reg
*/
- (rNPU1FIR, bit(14)) ? defaultMaskedError;
+ (rNPU1FIR, bit(14)) ? self_th_1;
/** NPU1FIR[15]
* MISC Parity error on MISC Cntrl reg
*/
- (rNPU1FIR, bit(15)) ? defaultMaskedError;
+ (rNPU1FIR, bit(15)) ? self_th_1;
/** NPU1FIR[16]
* Reserved
@@ -594,7 +594,7 @@ group gNPU1FIR
/** NPU1FIR[20]
* ATS Effective Address hit multiple TCE
*/
- (rNPU1FIR, bit(20)) ? defaultMaskedError;
+ (rNPU1FIR, bit(20)) ? self_th_1;
/** NPU1FIR[21]
* ATS TCE Page access error
@@ -604,72 +604,72 @@ group gNPU1FIR
/** NPU1FIR[22]
* ATS Timeout on TCE tree walk
*/
- (rNPU1FIR, bit(22)) ? defaultMaskedError;
+ (rNPU1FIR, bit(22)) ? self_th_1;
/** NPU1FIR[23]
* ATS Parity error on TCE cache dir array
*/
- (rNPU1FIR, bit(23)) ? defaultMaskedError;
+ (rNPU1FIR, bit(23)) ? self_th_32perDay;
/** NPU1FIR[24]
* ATS Parity error on TCE cache data array
*/
- (rNPU1FIR, bit(24)) ? defaultMaskedError;
+ (rNPU1FIR, bit(24)) ? self_th_32perDay;
/** NPU1FIR[25]
* ATS ECC UE on Effective Address array
*/
- (rNPU1FIR, bit(25)) ? defaultMaskedError;
+ (rNPU1FIR, bit(25)) ? self_th_1;
/** NPU1FIR[26]
* ATS ECC CE on Effective Address array
*/
- (rNPU1FIR, bit(26)) ? defaultMaskedError;
+ (rNPU1FIR, bit(26)) ? self_th_32perDay;
/** NPU1FIR[27]
* ATS ECC UE on TDRmem array
*/
- (rNPU1FIR, bit(27)) ? defaultMaskedError;
+ (rNPU1FIR, bit(27)) ? self_th_1;
/** NPU1FIR[28]
* ATS ECC CE on TDRmem array
*/
- (rNPU1FIR, bit(28)) ? defaultMaskedError;
+ (rNPU1FIR, bit(28)) ? self_th_32perDay;
/** NPU1FIR[29]
* ATS ECC UE on CQ CTL DMA Read
*/
- (rNPU1FIR, bit(29)) ? defaultMaskedError;
+ (rNPU1FIR, bit(29)) ? self_th_1;
/** NPU1FIR[30]
* ATS ECC CE on CQ CTL DMA Read
*/
- (rNPU1FIR, bit(30)) ? defaultMaskedError;
+ (rNPU1FIR, bit(30)) ? self_th_32perDay;
/** NPU1FIR[31]
* ATS Parity error on TVT entry
*/
- (rNPU1FIR, bit(31)) ? defaultMaskedError;
+ (rNPU1FIR, bit(31)) ? self_th_1;
/** NPU1FIR[32]
* ATS Parity err on IODA Address Reg
*/
- (rNPU1FIR, bit(32)) ? defaultMaskedError;
+ (rNPU1FIR, bit(32)) ? self_th_1;
/** NPU1FIR[33]
* ATS Parity error on ATS Control Register
*/
- (rNPU1FIR, bit(33)) ? defaultMaskedError;
+ (rNPU1FIR, bit(33)) ? self_th_1;
/** NPU1FIR[34]
- * ATS Parity error on ATS Timeout Control Register
+ * ATS Parity error on ATS reg
*/
- (rNPU1FIR, bit(34)) ? defaultMaskedError;
+ (rNPU1FIR, bit(34)) ? self_th_1;
/** NPU1FIR[35]
* ATS Invalid IODA Table Select entry
*/
- (rNPU1FIR, bit(35)) ? defaultMaskedError;
+ (rNPU1FIR, bit(35)) ? self_th_1;
/** NPU1FIR[36]
* Reserved
@@ -679,7 +679,7 @@ group gNPU1FIR
/** NPU1FIR[37]
* Kill xlate epoch timeout
*/
- (rNPU1FIR, bit(37)) ? defaultMaskedError;
+ (rNPU1FIR, bit(37)) ? self_th_1;
/** NPU1FIR[38]
* PEE secure SMF not secure
@@ -689,17 +689,32 @@ group gNPU1FIR
/** NPU1FIR[39]
* XSL in suspend mode when OTL sends cmd
*/
- (rNPU1FIR, bit(39)) ? defaultMaskedError;
+ (rNPU1FIR, bit(39)) ? self_th_1;
+
+ /** NPU1FIR[40]
+ * Unsupported page size
+ */
+ (rNPU1FIR, bit(40)) ? self_th_1;
+
+ /** NPU1FIR[41]
+ * Unexpected XLATE release
+ */
+ (rNPU1FIR, bit(41)) ? self_th_1;
+
+ /** NPU1FIR[42]
+ * Kill XLATE done fail
+ */
+ (rNPU1FIR, bit(42)) ? self_th_1;
- /** NPU1FIR[40:46]
+ /** NPU1FIR[43:46]
* Reserved
*/
- (rNPU1FIR, bit(40|41|42|43|44|45|46)) ? defaultMaskedError;
+ (rNPU1FIR, bit(43|44|45|46)) ? defaultMaskedError;
/** NPU1FIR[47]
* NDL Brick6 stall
*/
- (rNPU1FIR, bit(47)) ? defaultMaskedError;
+ (rNPU1FIR, bit(47)) ? self_th_1;
/** NPU1FIR[48]
* NDL Brick6 nostall
@@ -709,7 +724,7 @@ group gNPU1FIR
/** NPU1FIR[49]
* NDL Brick7 stall
*/
- (rNPU1FIR, bit(49)) ? defaultMaskedError;
+ (rNPU1FIR, bit(49)) ? self_th_1;
/** NPU1FIR[50]
* NDL Brick7 nostall
@@ -719,7 +734,7 @@ group gNPU1FIR
/** NPU1FIR[51]
* NDL Brick8 stall
*/
- (rNPU1FIR, bit(51)) ? defaultMaskedError;
+ (rNPU1FIR, bit(51)) ? self_th_1;
/** NPU1FIR[52]
* NDL Brick8 nostall
@@ -729,7 +744,7 @@ group gNPU1FIR
/** NPU1FIR[53]
* NDL Brick9 stall
*/
- (rNPU1FIR, bit(53)) ? defaultMaskedError;
+ (rNPU1FIR, bit(53)) ? self_th_1;
/** NPU1FIR[54]
* NDL Brick9 nostall
@@ -739,7 +754,7 @@ group gNPU1FIR
/** NPU1FIR[55]
* NDL Brick10 stall
*/
- (rNPU1FIR, bit(55)) ? defaultMaskedError;
+ (rNPU1FIR, bit(55)) ? self_th_1;
/** NPU1FIR[56]
* NDL Brick10 nostall
@@ -749,7 +764,7 @@ group gNPU1FIR
/** NPU1FIR[57]
* NDL Brick11 stall
*/
- (rNPU1FIR, bit(57)) ? defaultMaskedError;
+ (rNPU1FIR, bit(57)) ? self_th_1;
/** NPU1FIR[58]
* NDL Brick11 nostall
@@ -762,22 +777,22 @@ group gNPU1FIR
(rNPU1FIR, bit(59)) ? defaultMaskedError;
/** NPU1FIR[60]
- * MISC SCOM ring 0 sat 0 signaled internal FSM err
+ * Misc SCOM ring 0 sat 0 signalled internal FSM error
*/
(rNPU1FIR, bit(60)) ? defaultMaskedError;
/** NPU1FIR[61]
- * MISC SCOM ring 0 sat 1 signaled internal FSM err
+ * Misc SCOM ring 0 sat 1 signalled internal FSM error
*/
(rNPU1FIR, bit(61)) ? defaultMaskedError;
/** NPU1FIR[62]
- * Scom Error
+ * scom error
*/
(rNPU1FIR, bit(62)) ? defaultMaskedError;
/** NPU1FIR[63]
- * Scom Error
+ * scom error
*/
(rNPU1FIR, bit(63)) ? defaultMaskedError;
@@ -799,7 +814,7 @@ rule rNPU2FIR
group gNPU2FIR
filter singlebit,
- cs_root_cause
+ cs_root_cause(4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,21,22,23,24,25,26,27,28,29,30,31,36,37,38,39,40,41,42,43,45,47,48,50,51,52)
{
/** NPU2FIR[0]
* OTL Brick2 translation fault
@@ -824,145 +839,145 @@ group gNPU2FIR
/** NPU2FIR[4]
* OTL TL credit ctr overflow
*/
- (rNPU2FIR, bit(4)) ? defaultMaskedError;
+ (rNPU2FIR, bit(4)) ? self_th_1;
/** NPU2FIR[5]
* OTL RX acTag invalid
*/
- (rNPU2FIR, bit(5)) ? defaultMaskedError;
+ (rNPU2FIR, bit(5)) ? self_th_1;
/** NPU2FIR[6]
* OTL RX acTag points to an invalid entry.
*/
- (rNPU2FIR, bit(6)) ? defaultMaskedError;
+ (rNPU2FIR, bit(6)) ? self_th_1;
/** NPU2FIR[7]
* OTL RX reserved opcode used.
*/
- (rNPU2FIR, bit(7)) ? defaultMaskedError;
+ (rNPU2FIR, bit(7)) ? self_th_1;
/** NPU2FIR[8]
* OTL RX rtn_tl_credit cmd outside slot0.
*/
- (rNPU2FIR, bit(8)) ? defaultMaskedError;
+ (rNPU2FIR, bit(8)) ? self_th_1;
/** NPU2FIR[9]
* OTL RX bad opcode and template combo
*/
- (rNPU2FIR, bit(9)) ? defaultMaskedError;
+ (rNPU2FIR, bit(9)) ? self_th_1;
/** NPU2FIR[10]
* OTL RX unsupported template format.
*/
- (rNPU2FIR, bit(10)) ? defaultMaskedError;
+ (rNPU2FIR, bit(10)) ? self_th_1;
/** NPU2FIR[11]
* OTL RX bad template x00 format.
*/
- (rNPU2FIR, bit(11)) ? defaultMaskedError;
+ (rNPU2FIR, bit(11)) ? self_th_1;
/** NPU2FIR[12]
* OTL RX control flit overrun.
*/
- (rNPU2FIR, bit(12)) ? defaultMaskedError;
+ (rNPU2FIR, bit(12)) ? self_th_1;
/** NPU2FIR[13]
* OTL RX unexpected data flit.
*/
- (rNPU2FIR, bit(13)) ? defaultMaskedError;
+ (rNPU2FIR, bit(13)) ? self_th_1;
/** NPU2FIR[14]
* OTL RX DL link down.
*/
- (rNPU2FIR, bit(14)) ? defaultMaskedError;
+ (rNPU2FIR, bit(14)) ? self_th_1;
/** NPU2FIR[15]
* OTL RX bad data received on command.
*/
- (rNPU2FIR, bit(15)) ? defaultMaskedError;
+ (rNPU2FIR, bit(15)) ? self_th_1;
/** NPU2FIR[16]
* OTL RX bad data received on response.
*/
- (rNPU2FIR, bit(16)) ? defaultMaskedError;
+ (rNPU2FIR, bit(16)) ? self_th_1;
/** NPU2FIR[17]
* OTL RX AP response not allowed
*/
- (rNPU2FIR, bit(17)) ? defaultMaskedError;
+ (rNPU2FIR, bit(17)) ? self_th_1;
/** NPU2FIR[18]
* OR of all OTL parity errors.
*/
- (rNPU2FIR, bit(18)) ? defaultMaskedError;
+ (rNPU2FIR, bit(18)) ? self_th_1;
/** NPU2FIR[19]
* OR of all OTL ECC CE errors.
*/
- (rNPU2FIR, bit(19)) ? defaultMaskedError;
+ (rNPU2FIR, bit(19)) ? self_th_32perDay;
/** NPU2FIR[20]
* OR of all OTL ECC UE errors.
*/
- (rNPU2FIR, bit(20)) ? defaultMaskedError;
+ (rNPU2FIR, bit(20)) ? self_th_1;
/** NPU2FIR[21]
* RXO OP Errors.
*/
- (rNPU2FIR, bit(21)) ? defaultMaskedError;
+ (rNPU2FIR, bit(21)) ? self_th_1;
/** NPU2FIR[22]
* RXO Internal Errors.
*/
- (rNPU2FIR, bit(22)) ? defaultMaskedError;
+ (rNPU2FIR, bit(22)) ? self_th_1;
/** NPU2FIR[23]
* OTL RXI fifo overrun.
*/
- (rNPU2FIR, bit(23)) ? defaultMaskedError;
+ (rNPU2FIR, bit(23)) ? self_th_1;
/** NPU2FIR[24]
* OTL RXI ctrl flit data run len invalid.
*/
- (rNPU2FIR, bit(24)) ? defaultMaskedError;
+ (rNPU2FIR, bit(24)) ? self_th_1;
/** NPU2FIR[25]
* OTL RXI opcode specifies dL=0b00.
*/
- (rNPU2FIR, bit(25)) ? defaultMaskedError;
+ (rNPU2FIR, bit(25)) ? self_th_1;
/** NPU2FIR[26]
* OTL RXI bad data received vc2
*/
- (rNPU2FIR, bit(26)) ? defaultMaskedError;
+ (rNPU2FIR, bit(26)) ? self_th_1;
/** NPU2FIR[27]
* OTL RXI dcp2 fifo overrun
*/
- (rNPU2FIR, bit(27)) ? defaultMaskedError;
+ (rNPU2FIR, bit(27)) ? self_th_1;
/** NPU2FIR[28]
* OTL RXI vc1 fifo overrun
*/
- (rNPU2FIR, bit(28)) ? defaultMaskedError;
+ (rNPU2FIR, bit(28)) ? self_th_1;
/** NPU2FIR[29]
* OTL RXI vc2 fifo overrun
*/
- (rNPU2FIR, bit(29)) ? defaultMaskedError;
+ (rNPU2FIR, bit(29)) ? self_th_1;
/** NPU2FIR[30]
- * Reserved
+ * OTL RXI Data link not supported
*/
- (rNPU2FIR, bit(30)) ? defaultMaskedError;
+ (rNPU2FIR, bit(30)) ? self_th_1;
/** NPU2FIR[31]
* OTL TXI opcode error
*/
- (rNPU2FIR, bit(31)) ? defaultMaskedError;
+ (rNPU2FIR, bit(31)) ? self_th_1;
/** NPU2FIR[32]
- * Malformed packet error type 4
+ * OTL RXI reserved field not equal to 0
*/
(rNPU2FIR, bit(32)) ? defaultMaskedError;
@@ -974,42 +989,42 @@ group gNPU2FIR
/** NPU2FIR[36]
* MMIO invalidate while one in progress.
*/
- (rNPU2FIR, bit(36)) ? defaultMaskedError;
+ (rNPU2FIR, bit(36)) ? self_th_1;
/** NPU2FIR[37]
* Unexpected ITAG on itag completion pt 0
*/
- (rNPU2FIR, bit(37)) ? defaultMaskedError;
+ (rNPU2FIR, bit(37)) ? self_th_1;
/** NPU2FIR[38]
* Unexpected ITAG on itag completion pt 1
*/
- (rNPU2FIR, bit(38)) ? defaultMaskedError;
+ (rNPU2FIR, bit(38)) ? self_th_1;
/** NPU2FIR[39]
* Unexpected Read PEE completion.
*/
- (rNPU2FIR, bit(39)) ? defaultMaskedError;
+ (rNPU2FIR, bit(39)) ? self_th_1;
/** NPU2FIR[40]
* Unexpected Checkout response.
*/
- (rNPU2FIR, bit(40)) ? defaultMaskedError;
+ (rNPU2FIR, bit(40)) ? self_th_1;
/** NPU2FIR[41]
* Translation request but SPAP is invalid.
*/
- (rNPU2FIR, bit(41)) ? defaultMaskedError;
+ (rNPU2FIR, bit(41)) ? self_th_1;
/** NPU2FIR[42]
* Read a PEE which was not valid.
*/
- (rNPU2FIR, bit(42)) ? defaultMaskedError;
+ (rNPU2FIR, bit(42)) ? self_th_1;
/** NPU2FIR[43]
* Bloom filter protection error.
*/
- (rNPU2FIR, bit(43)) ? defaultMaskedError;
+ (rNPU2FIR, bit(43)) ? self_th_1;
/** NPU2FIR[44]
* Translation request to non-valid TA
@@ -1017,44 +1032,44 @@ group gNPU2FIR
(rNPU2FIR, bit(44)) ? defaultMaskedError;
/** NPU2FIR[45]
- * TA Translation request to an invalid TA
+ * TA translation request to an invalid TA
*/
- (rNPU2FIR, bit(45)) ? defaultMaskedError;
+ (rNPU2FIR, bit(45)) ? self_th_1;
/** NPU2FIR[46]
* correctable array error (SBE).
*/
- (rNPU2FIR, bit(46)) ? defaultMaskedError;
+ (rNPU2FIR, bit(46)) ? self_th_32perDay;
/** NPU2FIR[47]
* array error (UE or parity).
*/
- (rNPU2FIR, bit(47)) ? defaultMaskedError;
+ (rNPU2FIR, bit(47)) ? self_th_1;
/** NPU2FIR[48]
* S/TLBI buffer overflow.
*/
- (rNPU2FIR, bit(48)) ? defaultMaskedError;
+ (rNPU2FIR, bit(48)) ? self_th_1;
/** NPU2FIR[49]
* SBE CE on Pb cout rsp or PEE read data.
*/
- (rNPU2FIR, bit(49)) ? defaultMaskedError;
+ (rNPU2FIR, bit(49)) ? self_th_32perDay;
/** NPU2FIR[50]
* UE on Pb cut rsp or PEE read data.
*/
- (rNPU2FIR, bit(50)) ? defaultMaskedError;
+ (rNPU2FIR, bit(50)) ? self_th_1;
/** NPU2FIR[51]
* SUE on Pb chkout rsp or Pb PEE rd data.
*/
- (rNPU2FIR, bit(51)) ? defaultMaskedError;
+ (rNPU2FIR, bit(51)) ? self_th_1;
/** NPU2FIR[52]
- * PA mem_hit when bar mode is nonzero
+ * PA mem hit when bar mode is nonzero
*/
- (rNPU2FIR, bit(52)) ? defaultMaskedError;
+ (rNPU2FIR, bit(52)) ? self_th_1;
/** NPU2FIR[53]
* XSL Reserved, macro bit 17.
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_obus.rule b/src/usr/diag/prdf/common/plat/axone/axone_obus.rule
index a079fac59..1a346c417 100644
--- a/src/usr/diag/prdf/common/plat/axone/axone_obus.rule
+++ b/src/usr/diag/prdf/common/plat/axone/axone_obus.rule
@@ -469,12 +469,12 @@ group gIOOLFIR
/** IOOLFIR[8]
* link0 nak received
*/
- (rIOOLFIR, bit(8)) ? defaultMaskedError;
+ (rIOOLFIR, bit(8)) ? threshold_and_mask_self_non_smp_only;
/** IOOLFIR[9]
* link1 nak received
*/
- (rIOOLFIR, bit(9)) ? defaultMaskedError;
+ (rIOOLFIR, bit(9)) ? threshold_and_mask_self_non_smp_only;
/** IOOLFIR[10]
* link0 replay buffer full
@@ -499,22 +499,22 @@ group gIOOLFIR
/** IOOLFIR[14]
* link0 sl ecc correctable
*/
- (rIOOLFIR, bit(14)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(14)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[15]
* link1 sl ecc correctable
*/
- (rIOOLFIR, bit(15)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(15)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[16]
* link0 sl ecc ue
*/
- (rIOOLFIR, bit(16)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(16)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[17]
* link1 sl ecc ue
*/
- (rIOOLFIR, bit(17)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(17)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[18]
* link0 retrain threshold
@@ -597,12 +597,12 @@ group gIOOLFIR
(rIOOLFIR, bit(33)) ? defaultMaskedError;
/** IOOLFIR[34]
- * link0 num replay
+ * link0 num replay or no forward progress
*/
(rIOOLFIR, bit(34)) ? defaultMaskedError;
/** IOOLFIR[35]
- * link1 num replay
+ * link1 num replay or no forward progress
*/
(rIOOLFIR, bit(35)) ? defaultMaskedError;
@@ -619,12 +619,12 @@ group gIOOLFIR
/** IOOLFIR[38]
* link0 prbs select error
*/
- (rIOOLFIR, bit(38)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(38)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[39]
* link1 prbs select error
*/
- (rIOOLFIR, bit(39)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(39)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[40]
* link0 tcomplete bad
@@ -639,102 +639,102 @@ group gIOOLFIR
/** IOOLFIR[42]
* link0 no spare lane available
*/
- (rIOOLFIR, bit(42)) ? obusSmpCallout_L0;
+ (rIOOLFIR, bit(42)) ? obusSmpCallout_L0_smp_only;
/** IOOLFIR[43]
* link1 no spare lane available
*/
- (rIOOLFIR, bit(43)) ? obusSmpCallout_L1;
+ (rIOOLFIR, bit(43)) ? obusSmpCallout_L1_smp_only;
/** IOOLFIR[44]
- * link0 spare done
+ * link0 spare done or degraded mode
*/
- (rIOOLFIR, bit(44)) ? obusSmpCallout_th32_L0;
+ (rIOOLFIR, bit(44)) ? spare_lane_degraded_mode_L0;
/** IOOLFIR[45]
- * link1 spare done
+ * link1 spare done or degraded mode
*/
- (rIOOLFIR, bit(45)) ? obusSmpCallout_th32_L1;
+ (rIOOLFIR, bit(45)) ? spare_lane_degraded_mode_L1;
/** IOOLFIR[46]
* link0 too many crc errors
*/
- (rIOOLFIR, bit(46)) ? obusSmpCallout_L0;
+ (rIOOLFIR, bit(46)) ? obusSmpCallout_L0_smp_only;
/** IOOLFIR[47]
* link1 too many crc errors
*/
- (rIOOLFIR, bit(47)) ? obusSmpCallout_L1;
+ (rIOOLFIR, bit(47)) ? obusSmpCallout_L1_smp_only;
/** IOOLFIR[48]
- * link0 npu error
+ * link0 npu error or orx otx dlx errors
*/
(rIOOLFIR, bit(48)) ? threshold_and_mask_self;
/** IOOLFIR[49]
- * link1 npu error
+ * link1 npu error or orx otx dlx errors
*/
(rIOOLFIR, bit(49)) ? threshold_and_mask_self;
/** IOOLFIR[50]
* linkx npu error
*/
- (rIOOLFIR, bit(50)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(50)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[51]
* osc switch
*/
- (rIOOLFIR, bit(51)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(51)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[52]
* link0 correctable array error
*/
- (rIOOLFIR, bit(52)) ? obusSmpCallout_th32_L0;
+ (rIOOLFIR, bit(52)) ? self_th_32perDay;
/** IOOLFIR[53]
* link1 correctable array error
*/
- (rIOOLFIR, bit(53)) ? obusSmpCallout_th32_L1;
+ (rIOOLFIR, bit(53)) ? self_th_32perDay;
/** IOOLFIR[54]
* link0 uncorrectable array error
*/
- (rIOOLFIR, bit(54)) ? obusSmpFailure_L0;
+ (rIOOLFIR, bit(54)) ? self_th_1;
/** IOOLFIR[55]
* link1 uncorrectable array error
*/
- (rIOOLFIR, bit(55)) ? obusSmpFailure_L1;
+ (rIOOLFIR, bit(55)) ? self_th_1;
/** IOOLFIR[56]
* link0 training failed
*/
- (rIOOLFIR, bit(56)) ? obusSmpFailure_L0;
+ (rIOOLFIR, bit(56)) ? training_failure_L0;
/** IOOLFIR[57]
* link1 training failed
*/
- (rIOOLFIR, bit(57)) ? obusSmpFailure_L1;
+ (rIOOLFIR, bit(57)) ? training_failure_L1;
/** IOOLFIR[58]
* link0 unrecoverable error
*/
- (rIOOLFIR, bit(58)) ? obusSmpFailure_L0;
+ (rIOOLFIR, bit(58)) ? unrecoverable_error_L0;
/** IOOLFIR[59]
* link1 unrecoverable error
*/
- (rIOOLFIR, bit(59)) ? obusSmpFailure_L1;
+ (rIOOLFIR, bit(59)) ? unrecoverable_error_L1;
/** IOOLFIR[60]
* link0 internal error
*/
- (rIOOLFIR, bit(60)) ? obusSmpFailure_L0;
+ (rIOOLFIR, bit(60)) ? internal_error_L0;
/** IOOLFIR[61]
* link1 internal error
*/
- (rIOOLFIR, bit(61)) ? obusSmpFailure_L1;
+ (rIOOLFIR, bit(61)) ? internal_error_L1;
/** IOOLFIR[62]
* fir scom err dup
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_omic.rule b/src/usr/diag/prdf/common/plat/axone/axone_omic.rule
index 09ed59f2d..7b26f7a3a 100644
--- a/src/usr/diag/prdf/common/plat/axone/axone_omic.rule
+++ b/src/usr/diag/prdf/common/plat/axone/axone_omic.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2020
# [+] International Business Machines Corp.
#
#
@@ -196,8 +196,10 @@ rule rOMIC
};
group gOMIC attntype CHECK_STOP, RECOVERABLE, UNIT_CS, HOST_ATTN
- filter singlebit
+ filter priority(2,0,1)
{
+ # We need to prioritize analysis to the OMIDLFIR here because of potential
+ # Channel Fail attentions in that FIR that will be reported as RECOVERABLE.
(rOMIC, bit(0)) ? analyzeIOOMIFIR;
(rOMIC, bit(1)) ? analyzeMCPPEFIR;
(rOMIC, bit(2)) ? analyzeOMIDLFIR;
@@ -226,17 +228,17 @@ group gIOOMIFIR
/** IOOMIFIR[0]
* RX invalid state or parity error
*/
- (rIOOMIFIR, bit(0)) ? defaultMaskedError;
+ (rIOOMIFIR, bit(0)) ? self_th_1;
/** IOOMIFIR[1]
* TX invalid state or parity error
*/
- (rIOOMIFIR, bit(1)) ? defaultMaskedError;
+ (rIOOMIFIR, bit(1)) ? self_th_1;
/** IOOMIFIR[2]
* GCR hang error
*/
- (rIOOMIFIR, bit(2)) ? defaultMaskedError;
+ (rIOOMIFIR, bit(2)) ? self_th_1;
/** IOOMIFIR[3:47]
* Unused
@@ -359,306 +361,306 @@ rule rOMIDLFIR
};
group gOMIDLFIR
- filter singlebit,
- cs_root_cause
+ filter priority(0,20,40),
+ cs_root_cause(0,20,40)
{
/** OMIDLFIR[0]
- * DL0 fatal error
+ * OMI-DL0 fatal error
*/
- (rOMIDLFIR, bit(0)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(0)) ? dl0_fatal_error;
/** OMIDLFIR[1]
- * DL0 data UE
+ * OMI-DL0 UE on data flit
*/
- (rOMIDLFIR, bit(1)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(1)) ? dl0_omi_th_1;
/** OMIDLFIR[2]
- * DL0 flit CE
+ * OMI-DL0 CE on TL flit
*/
- (rOMIDLFIR, bit(2)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(2)) ? dl0_omi_th_32perDay;
/** OMIDLFIR[3]
- * DL0 CRC error
+ * OMI-DL0 detected a CRC error
*/
(rOMIDLFIR, bit(3)) ? defaultMaskedError;
/** OMIDLFIR[4]
- * DL0 nack
+ * OMI-DL0 received a nack
*/
(rOMIDLFIR, bit(4)) ? defaultMaskedError;
/** OMIDLFIR[5]
- * DL0 X4 mode
+ * OMI-DL0 running in degraded mode
*/
- (rOMIDLFIR, bit(5)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(5)) ? dl0_omi_bus_th_1;
/** OMIDLFIR[6]
- * DL0 EDPL
+ * OMI-DL0 parity error detection on a lane
*/
(rOMIDLFIR, bit(6)) ? defaultMaskedError;
/** OMIDLFIR[7]
- * DL0 timeout
+ * OMI-DL0 retrained due to no forward progress
*/
- (rOMIDLFIR, bit(7)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(7)) ? dl0_omi_bus_th_32perDay;
/** OMIDLFIR[8]
- * DL0 remote retrain
+ * OMI-DL0 remote side initiated a retrain
*/
(rOMIDLFIR, bit(8)) ? defaultMaskedError;
/** OMIDLFIR[9]
- * DL0 error retrain
+ * OMI-DL0 retrain due to internal error or software initiated
*/
- (rOMIDLFIR, bit(9)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(9)) ? dl0_omi_bus_th_32perDay;
/** OMIDLFIR[10]
- * DL0 EDPL retrain
+ * OMI-DL0 threshold reached
*/
- (rOMIDLFIR, bit(10)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(10)) ? dl0_omi_bus_th_32perDay;
/** OMIDLFIR[11]
- * DL0 trained
+ * OMI-DL0 trained
*/
(rOMIDLFIR, bit(11)) ? defaultMaskedError;
/** OMIDLFIR[12]
- * DL0 endpoint bit 0
+ * OMI-DL0 endpoint error bit 0
*/
(rOMIDLFIR, bit(12)) ? defaultMaskedError;
/** OMIDLFIR[13]
- * DL0 endpoint bit 1
+ * OMI-DL0 endpoint error bit 1
*/
(rOMIDLFIR, bit(13)) ? defaultMaskedError;
/** OMIDLFIR[14]
- * DL0 endpoint bit 2
+ * OMI-DL0 endpoint error bit 2
*/
(rOMIDLFIR, bit(14)) ? defaultMaskedError;
/** OMIDLFIR[15]
- * DL0 endpoint bit 3
+ * OMI-DL0 endpoint error bit 3
*/
(rOMIDLFIR, bit(15)) ? defaultMaskedError;
/** OMIDLFIR[16]
- * DL0 endpoint bit 4
+ * OMI-DL0 endpoint error bit 4
*/
(rOMIDLFIR, bit(16)) ? defaultMaskedError;
/** OMIDLFIR[17]
- * DL0 endpoint bit 5
+ * OMI-DL0 endpoint error bit 5
*/
(rOMIDLFIR, bit(17)) ? defaultMaskedError;
/** OMIDLFIR[18]
- * DL0 endpoint bit 6
+ * OMI-DL0 endpoint error bit 6
*/
(rOMIDLFIR, bit(18)) ? defaultMaskedError;
/** OMIDLFIR[19]
- * DL0 endpoint bit 7
+ * OMI-DL0 endpoint error bit 7
*/
(rOMIDLFIR, bit(19)) ? defaultMaskedError;
/** OMIDLFIR[20]
- * DL1 fatal error
+ * OMI-DL1 fatal error
*/
- (rOMIDLFIR, bit(20)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(20)) ? dl1_fatal_error;
/** OMIDLFIR[21]
- * DL1 data UE
+ * OMI-DL1 UE on data flit
*/
- (rOMIDLFIR, bit(21)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(21)) ? dl1_omi_th_1;
/** OMIDLFIR[22]
- * DL1 flit CE
+ * OMI-DL1 CE on TL flit
*/
- (rOMIDLFIR, bit(22)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(22)) ? dl1_omi_th_32perDay;
/** OMIDLFIR[23]
- * DL1 CRC error
+ * OMI-DL1 detected a CRC error
*/
(rOMIDLFIR, bit(23)) ? defaultMaskedError;
/** OMIDLFIR[24]
- * DL1 nack
+ * OMI-DL1 received a nack
*/
(rOMIDLFIR, bit(24)) ? defaultMaskedError;
/** OMIDLFIR[25]
- * DL1 X4 mode
+ * OMI-DL1 running in degraded mode
*/
- (rOMIDLFIR, bit(25)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(25)) ? dl1_omi_bus_th_1;
/** OMIDLFIR[26]
- * DL1 EDPL
+ * OMI-DL1 parity error detection on a lane
*/
(rOMIDLFIR, bit(26)) ? defaultMaskedError;
/** OMIDLFIR[27]
- * DL1 timeout
+ * OMI-DL1 retrained due to no forward progress
*/
- (rOMIDLFIR, bit(27)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(27)) ? dl1_omi_bus_th_32perDay;
/** OMIDLFIR[28]
- * DL1 remote retrain
+ * OMI-DL1 remote side initiated a retrain
*/
(rOMIDLFIR, bit(28)) ? defaultMaskedError;
/** OMIDLFIR[29]
- * DL1 error retrain
+ * OMI-DL1 retrain due to internal error or software initiated
*/
- (rOMIDLFIR, bit(29)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(29)) ? dl1_omi_bus_th_32perDay;
/** OMIDLFIR[30]
- * DL1 EDPL retrain
+ * OMI-DL1 threshold reached
*/
- (rOMIDLFIR, bit(30)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(30)) ? dl1_omi_bus_th_32perDay;
/** OMIDLFIR[31]
- * DL1 trained
+ * OMI-DL1 trained
*/
(rOMIDLFIR, bit(31)) ? defaultMaskedError;
/** OMIDLFIR[32]
- * DL1 endpoint bit 0
+ * OMI-DL1 endpoint error bit 0
*/
(rOMIDLFIR, bit(32)) ? defaultMaskedError;
/** OMIDLFIR[33]
- * DL1 endpoint bit 1
+ * OMI-DL1 endpoint error bit 1
*/
(rOMIDLFIR, bit(33)) ? defaultMaskedError;
/** OMIDLFIR[34]
- * DL1 endpoint bit 2
+ * OMI-DL1 endpoint error bit 2
*/
(rOMIDLFIR, bit(34)) ? defaultMaskedError;
/** OMIDLFIR[35]
- * DL1 endpoint bit 3
+ * OMI-DL1 endpoint error bit 3
*/
(rOMIDLFIR, bit(35)) ? defaultMaskedError;
/** OMIDLFIR[36]
- * DL1 endpoint bit 4
+ * OMI-DL1 endpoint error bit 4
*/
(rOMIDLFIR, bit(36)) ? defaultMaskedError;
/** OMIDLFIR[37]
- * DL1 endpoint bit 5
+ * OMI-DL1 endpoint error bit 5
*/
(rOMIDLFIR, bit(37)) ? defaultMaskedError;
/** OMIDLFIR[38]
- * DL1 endpoint bit 6
+ * OMI-DL1 endpoint error bit 6
*/
(rOMIDLFIR, bit(38)) ? defaultMaskedError;
/** OMIDLFIR[39]
- * DL1 endpoint bit 7
+ * OMI-DL1 endpoint error bit 7
*/
(rOMIDLFIR, bit(39)) ? defaultMaskedError;
/** OMIDLFIR[40]
- * DL2 fatal error
+ * OMI-DL2 fatal error
*/
- (rOMIDLFIR, bit(40)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(40)) ? dl2_fatal_error;
/** OMIDLFIR[41]
- * DL2 data UE
+ * OMI-DL2 UE on data flit
*/
- (rOMIDLFIR, bit(41)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(41)) ? dl2_omi_th_1;
/** OMIDLFIR[42]
- * DL2 flit CE
+ * OMI-DL2 CE on TL flit
*/
- (rOMIDLFIR, bit(42)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(42)) ? dl2_omi_th_32perDay;
/** OMIDLFIR[43]
- * DL2 CRC error
+ * OMI-DL2 detected a CRC error
*/
(rOMIDLFIR, bit(43)) ? defaultMaskedError;
/** OMIDLFIR[44]
- * DL2 nack
+ * OMI-DL2 received a nack
*/
(rOMIDLFIR, bit(44)) ? defaultMaskedError;
/** OMIDLFIR[45]
- * DL2 X4 mode
+ * OMI-DL2 running in degraded mode
*/
- (rOMIDLFIR, bit(45)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(45)) ? dl2_omi_bus_th_1;
/** OMIDLFIR[46]
- * DL2 EDPL
+ * OMI-DL2 parity error detection on a lane
*/
(rOMIDLFIR, bit(46)) ? defaultMaskedError;
/** OMIDLFIR[47]
- * DL2 timeout
+ * OMI-DL2 retrained due to no forward progress
*/
- (rOMIDLFIR, bit(47)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(47)) ? dl2_omi_bus_th_32perDay;
/** OMIDLFIR[48]
- * DL2 remote retrain
+ * OMI-DL2 remote side initiated a retrain
*/
(rOMIDLFIR, bit(48)) ? defaultMaskedError;
/** OMIDLFIR[49]
- * DL2 error retrain
+ * OMI-DL2 retrain due to internal error or software initiated
*/
- (rOMIDLFIR, bit(49)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(49)) ? dl2_omi_bus_th_32perDay;
/** OMIDLFIR[50]
- * DL2 EDPL retrain
+ * OMI-DL2 threshold reached
*/
- (rOMIDLFIR, bit(50)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(50)) ? dl2_omi_bus_th_32perDay;
/** OMIDLFIR[51]
- * DL2 trained
+ * OMI-DL2 trained
*/
(rOMIDLFIR, bit(51)) ? defaultMaskedError;
/** OMIDLFIR[52]
- * DL2 endpoint bit 0
+ * OMI-DL2 endpoint error bit 0
*/
(rOMIDLFIR, bit(52)) ? defaultMaskedError;
/** OMIDLFIR[53]
- * DL2 endpoint bit 1
+ * OMI-DL2 endpoint error bit 1
*/
(rOMIDLFIR, bit(53)) ? defaultMaskedError;
/** OMIDLFIR[54]
- * DL2 endpoint bit 2
+ * OMI-DL2 endpoint error bit 2
*/
(rOMIDLFIR, bit(54)) ? defaultMaskedError;
/** OMIDLFIR[55]
- * DL2 endpoint bit 3
+ * OMI-DL2 endpoint error bit 3
*/
(rOMIDLFIR, bit(55)) ? defaultMaskedError;
/** OMIDLFIR[56]
- * DL2 endpoint bit 4
+ * OMI-DL2 endpoint error bit 4
*/
(rOMIDLFIR, bit(56)) ? defaultMaskedError;
/** OMIDLFIR[57]
- * DL2 endpoint bit 5
+ * OMI-DL2 endpoint error bit 5
*/
(rOMIDLFIR, bit(57)) ? defaultMaskedError;
/** OMIDLFIR[58]
- * DL2 endpoint bit 6
+ * OMI-DL2 endpoint error bit 6
*/
(rOMIDLFIR, bit(58)) ? defaultMaskedError;
/** OMIDLFIR[59]
- * DL2 endpoint bit 7
+ * OMI-DL2 endpoint error bit 7
*/
(rOMIDLFIR, bit(59)) ? defaultMaskedError;
@@ -667,6 +669,21 @@ group gOMIDLFIR
*/
(rOMIDLFIR, bit(60)) ? defaultMaskedError;
+ /** OMIDLFIR[61]
+ * reserved
+ */
+ (rOMIDLFIR, bit(61)) ? defaultMaskedError;
+
+ /** OMIDLFIR[62]
+ * LFIR internal parity error
+ */
+ (rOMIDLFIR, bit(62)) ? defaultMaskedError;
+
+ /** OMIDLFIR[63]
+ * SCOM Satellite Error
+ */
+ (rOMIDLFIR, bit(63)) ? defaultMaskedError;
+
};
##############################################################################
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_omic_actions.rule b/src/usr/diag/prdf/common/plat/axone/axone_omic_actions.rule
index ecb6626a8..dbf563b47 100644
--- a/src/usr/diag/prdf/common/plat/axone/axone_omic_actions.rule
+++ b/src/usr/diag/prdf/common/plat/axone/axone_omic_actions.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -24,6 +24,133 @@
# IBM_PROLOG_END_TAG
################################################################################
+# OMIC Actions #
+################################################################################
+
+actionclass dl0_omi
+{
+ callout(connected(TYPE_OMI,0), MRU_MED);
+};
+
+actionclass dl1_omi
+{
+ callout(connected(TYPE_OMI,1), MRU_MED);
+};
+
+actionclass dl2_omi
+{
+ callout(connected(TYPE_OMI,2), MRU_MED);
+};
+
+actionclass dl0_omi_bus
+{
+ funccall("omiParentCalloutBusInterfacePlugin_0");
+};
+
+actionclass dl1_omi_bus
+{
+ funccall("omiParentCalloutBusInterfacePlugin_1");
+};
+
+actionclass dl2_omi_bus
+{
+ funccall("omiParentCalloutBusInterfacePlugin_2");
+};
+
+/** OMI-DL0 Fatal Error */
+actionclass dl0_fatal_error
+{
+ try( funccall("DlFatalError_0"), dl0_omi_bus );
+ threshold1;
+};
+
+/** OMI-DL1 Fatal Error */
+actionclass dl1_fatal_error
+{
+ try( funccall("DlFatalError_1"), dl1_omi_bus );
+ threshold1;
+};
+
+/** OMI-DL2 Fatal Error */
+actionclass dl2_fatal_error
+{
+ try( funccall("DlFatalError_2"), dl2_omi_bus );
+ threshold1;
+};
+
+actionclass dl0_omi_th_1
+{
+ dl0_omi;
+ threshold1;
+};
+
+actionclass dl1_omi_th_1
+{
+ dl1_omi;
+ threshold1;
+};
+
+actionclass dl2_omi_th_1
+{
+ dl2_omi;
+ threshold1;
+};
+
+actionclass dl0_omi_th_32perDay
+{
+ dl0_omi;
+ threshold32pday;
+};
+
+actionclass dl1_omi_th_32perDay
+{
+ dl1_omi;
+ threshold32pday;
+};
+
+actionclass dl2_omi_th_32perDay
+{
+ dl2_omi;
+ threshold32pday;
+};
+
+actionclass dl0_omi_bus_th_1
+{
+ dl0_omi_bus;
+ threshold1;
+};
+
+actionclass dl1_omi_bus_th_1
+{
+ dl1_omi_bus;
+ threshold1;
+};
+
+actionclass dl2_omi_bus_th_1
+{
+ dl2_omi_bus;
+ threshold1;
+};
+
+actionclass dl0_omi_bus_th_32perDay
+{
+ dl0_omi_bus;
+ threshold1;
+};
+
+actionclass dl1_omi_bus_th_32perDay
+{
+ dl1_omi_bus;
+ threshold1;
+};
+
+actionclass dl2_omi_bus_th_32perDay
+{
+ dl2_omi_bus;
+ threshold1;
+};
+
+################################################################################
# Analyze groups
################################################################################
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_omic_regs.rule b/src/usr/diag/prdf/common/plat/axone/axone_omic_regs.rule
new file mode 100644
index 000000000..e698652a6
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/axone/axone_omic_regs.rule
@@ -0,0 +1,62 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/diag/prdf/common/plat/axone/axone_omic_regs.rule $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+###############################################################################
+# Additional registers for omic, not defined in XML
+###############################################################################
+
+
+ ###########################################################################
+ # P9 Axone target OMIDLFIR
+ ###########################################################################
+
+ register OMIDLFIR_MASK_OR
+ {
+ name "P9 OMIC target OMIDLFIR MASK atomic OR";
+ scomaddr 0x07013345;
+ capture group never;
+ access write_only;
+ };
+
+ register DL0_ERROR_HOLD
+ {
+ name "P9 Axone target DL0 Error Hold Register";
+ scomaddr 0x07013353;
+ capture group default;
+ };
+
+ register DL1_ERROR_HOLD
+ {
+ name "P9 Axone target DL1 Error Hold Register";
+ scomaddr 0x07013363;
+ capture group default;
+ };
+
+ register DL2_ERROR_HOLD
+ {
+ name "P9 Axone target DL2 Error Hold Register";
+ scomaddr 0x07013373;
+ capture group default;
+ };
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_phb.rule b/src/usr/diag/prdf/common/plat/axone/axone_phb.rule
index 844739ee2..1c5bb566d 100644
--- a/src/usr/diag/prdf/common/plat/axone/axone_phb.rule
+++ b/src/usr/diag/prdf/common/plat/axone/axone_phb.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -212,7 +212,7 @@ group gPHBNFIR
/** PHBNFIR[0]
* BAR Parity Error
*/
- (rPHBNFIR, bit(0)) ? self_th_1;
+ (rPHBNFIR, bit(0)) ? parent_proc_th_1;
/** PHBNFIR[1]
* Parity Errors on Registers besides BAR
@@ -252,12 +252,12 @@ group gPHBNFIR
/** PHBNFIR[8]
* Register Array Parity Error
*/
- (rPHBNFIR, bit(8)) ? self_th_1;
+ (rPHBNFIR, bit(8)) ? parent_proc_th_1;
/** PHBNFIR[9]
* Power Bus Interface Parity Error
*/
- (rPHBNFIR, bit(9)) ? self_th_1;
+ (rPHBNFIR, bit(9)) ? parent_proc_th_1;
/** PHBNFIR[10]
* Power Bus Data Hang
@@ -297,7 +297,7 @@ group gPHBNFIR
/** PHBNFIR[17]
* Hardware Error
*/
- (rPHBNFIR, bit(17)) ? self_th_1;
+ (rPHBNFIR, bit(17)) ? parent_proc_th_1;
/** PHBNFIR[18]
* Unsolicited Power Bus Data
diff --git a/src/usr/diag/prdf/common/plat/axone/axone_proc.rule b/src/usr/diag/prdf/common/plat/axone/axone_proc.rule
index c37c103be..b936106e2 100644
--- a/src/usr/diag/prdf/common/plat/axone/axone_proc.rule
+++ b/src/usr/diag/prdf/common/plat/axone/axone_proc.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -950,42 +950,6 @@ chip axone_proc
};
############################################################################
- # P9 chip ENHCAFIR
- ############################################################################
-
- register ENHCAFIR
- {
- name "P9 chip ENHCAFIR";
- scomaddr 0x05012940;
- reset (&, 0x05012941);
- mask (|, 0x05012945);
- capture group default;
- };
-
- register ENHCAFIR_MASK
- {
- name "P9 chip ENHCAFIR MASK";
- scomaddr 0x05012943;
- capture group default;
- };
-
- register ENHCAFIR_ACT0
- {
- name "P9 chip ENHCAFIR ACT0";
- scomaddr 0x05012946;
- capture group default;
- capture req nonzero("ENHCAFIR");
- };
-
- register ENHCAFIR_ACT1
- {
- name "P9 chip ENHCAFIR ACT1";
- scomaddr 0x05012947;
- capture group default;
- capture req nonzero("ENHCAFIR");
- };
-
- ############################################################################
# P9 chip PBAMFIR
############################################################################
@@ -2758,7 +2722,7 @@ group gNXCQFIR
/** NXCQFIR[19]
* Uncorrectable error on ERAT arrays
*/
- (rNXCQFIR, bit(19)) ? nx_th_32perDay;
+ (rNXCQFIR, bit(19)) ? nx_th_1;
/** NXCQFIR[20]
* SUE on ERAT arrays
@@ -4077,14 +4041,14 @@ group gN3_CHIPLET_FIR
(rN3_CHIPLET_FIR, bit(14)) ? analyzePBPPEFIR;
/** N3_CHIPLET_FIR[15]
- * Attention from PBIOEFIR
+ * Attention from PBIOOFIR
*/
- (rN3_CHIPLET_FIR, bit(15)) ? analyzePBIOEFIR;
+ (rN3_CHIPLET_FIR, bit(15)) ? analyzePBIOOFIR;
/** N3_CHIPLET_FIR[16]
- * Attention from PBIOOFIR
+ * Attention from NPU0FIR 1
*/
- (rN3_CHIPLET_FIR, bit(16)) ? analyzePBIOOFIR;
+ (rN3_CHIPLET_FIR, bit(16)) ? analyzeConnectedNPU1;
/** N3_CHIPLET_FIR[17]
* Attention from INTCQFIR
@@ -4106,15 +4070,10 @@ group gN3_CHIPLET_FIR
*/
(rN3_CHIPLET_FIR, bit(20)) ? analyzePBAMFIR;
- /** N3_CHIPLET_FIR[21]
- * Attention from NPU0FIR 1
- */
- (rN3_CHIPLET_FIR, bit(21)) ? analyzeConnectedNPU1;
-
/** N3_CHIPLET_FIR[22]
- * Attention from ENHCAFIR
+ * Attention from PBIOEFIR
*/
- (rN3_CHIPLET_FIR, bit(22)) ? analyzeENHCAFIR;
+ (rN3_CHIPLET_FIR, bit(22)) ? analyzePBIOEFIR;
/** N3_CHIPLET_FIR[23]
* Attention from NPU2FIR 0
@@ -5145,144 +5104,6 @@ group gPSIHBFIR
};
################################################################################
-# P9 chip ENHCAFIR
-################################################################################
-
-rule rENHCAFIR
-{
- CHECK_STOP:
- ENHCAFIR & ~ENHCAFIR_MASK & ~ENHCAFIR_ACT0 & ~ENHCAFIR_ACT1;
- RECOVERABLE:
- ENHCAFIR & ~ENHCAFIR_MASK & ~ENHCAFIR_ACT0 & ENHCAFIR_ACT1;
-};
-
-group gENHCAFIR
- filter singlebit,
- cs_root_cause
-{
- /** ENHCAFIR[0]
- * PB0 data UE
- */
- (rENHCAFIR, bit(0)) ? defaultMaskedError;
-
- /** ENHCAFIR[1]
- * PB0 data SUE
- */
- (rENHCAFIR, bit(1)) ? defaultMaskedError;
-
- /** ENHCAFIR[2]
- * PB0 data ue
- */
- (rENHCAFIR, bit(2)) ? defaultMaskedError;
-
- /** ENHCAFIR[3]
- * spare
- */
- (rENHCAFIR, bit(3)) ? defaultMaskedError;
-
- /** ENHCAFIR[4]
- * Castout Drop Counter Full
- */
- (rENHCAFIR, bit(4)) ? defaultMaskedError;
-
- /** ENHCAFIR[5]
- * Data Hang Detect
- */
- (rENHCAFIR, bit(5)) ? defaultMaskedError;
-
- /** ENHCAFIR[6]
- * Unexpected data or cresp
- */
- (rENHCAFIR, bit(6)) ? defaultMaskedError;
-
- /** ENHCAFIR[7]
- * Internal Error
- */
- (rENHCAFIR, bit(7)) ? defaultMaskedError;
-
- /** ENHCAFIR[8]
- * ADU checkstop error from power bus data
- */
- (rENHCAFIR, bit(8)) ? defaultMaskedError;
-
- /** ENHCAFIR[9]
- * ADU checkstop error from alter display
- */
- (rENHCAFIR, bit(9)) ? defaultMaskedError;
-
- /** ENHCAFIR[10]
- * ADU checkstop error from xsco m
- */
- (rENHCAFIR, bit(10)) ? defaultMaskedError;
-
- /** ENHCAFIR[11]
- * ADU checkstop from power bus cmd
- */
- (rENHCAFIR, bit(11)) ? defaultMaskedError;
-
- /** ENHCAFIR[12]
- * ADU checkstop error from power bus send
- */
- (rENHCAFIR, bit(12)) ? defaultMaskedError;
-
- /** ENHCAFIR[13]
- * ADU checkstop from power bus receive
- */
- (rENHCAFIR, bit(13)) ? defaultMaskedError;
-
- /** ENHCAFIR[14]
- * ADU recoverable error from pb data
- */
- (rENHCAFIR, bit(14)) ? defaultMaskedError;
-
- /** ENHCAFIR[15]
- * ADU recoverable error from alter display
- */
- (rENHCAFIR, bit(15)) ? defaultMaskedError;
-
- /** ENHCAFIR[16]
- * ADU recoverable error from xscom
- */
- (rENHCAFIR, bit(16)) ? defaultMaskedError;
-
- /** ENHCAFIR[17]
- * ADU recoverable from power bus cmd
- */
- (rENHCAFIR, bit(17)) ? defaultMaskedError;
-
- /** ENHCAFIR[18]
- * ADU recoverable error from pb send
- */
- (rENHCAFIR, bit(18)) ? defaultMaskedError;
-
- /** ENHCAFIR[19]
- * ADU recoverable error from pb receive
- */
- (rENHCAFIR, bit(19)) ? defaultMaskedError;
-
- /** ENHCAFIR[20]
- * NHTM scom error
- */
- (rENHCAFIR, bit(20)) ? defaultMaskedError;
-
- /** ENHCAFIR[21]
- * spare
- */
- (rENHCAFIR, bit(21)) ? defaultMaskedError;
-
- /** ENHCAFIR[22]
- * scom error
- */
- (rENHCAFIR, bit(22)) ? defaultMaskedError;
-
- /** ENHCAFIR[23]
- * scom error
- */
- (rENHCAFIR, bit(23)) ? defaultMaskedError;
-
-};
-
-################################################################################
# P9 chip PBAMFIR
################################################################################
diff --git a/src/usr/diag/prdf/common/plat/axone/prdfMccPlugins.C b/src/usr/diag/prdf/common/plat/axone/prdfMccPlugins.C
new file mode 100644
index 000000000..804418717
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/axone/prdfMccPlugins.C
@@ -0,0 +1,142 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/plat/axone/prdfMccPlugins.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+// Framework includes
+#include <iipServiceDataCollector.h>
+#include <prdfExtensibleChip.H>
+#include <prdfPluginMap.H>
+
+// Platform includes
+#include <prdfMemUtils.H>
+#include <prdfPlatServices.H>
+#include <prdfMemExtraSig.H>
+
+using namespace TARGETING;
+
+namespace PRDF
+{
+
+using namespace PlatServices;
+
+namespace axone_mcc
+{
+
+//##############################################################################
+//
+// Special plugins
+//
+//##############################################################################
+
+/**
+ * @brief Analysis code that is called before the main analyze() function.
+ * @param i_chip A MCC chip.
+ * @param io_sc The step code data struct.
+ * @param o_analyzed True if analysis is done on this chip, false otherwise.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+int32_t PreAnalysis( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_analyzed )
+{
+ // Check for a channel failure before analyzing this chip.
+ o_analyzed = MemUtils::analyzeChnlFail<TYPE_MCC>( i_chip, io_sc );
+
+ return SUCCESS;
+}
+PRDF_PLUGIN_DEFINE( axone_mcc, PreAnalysis );
+
+/**
+ * @brief Plugin function called after analysis is complete but before PRD
+ * exits.
+ * @param i_chip A MCC chip.
+ * @param io_sc The step code data struct.
+ * @note This is especially useful for any analysis that still needs to be
+ * done after the framework clears the FIR bits that were at attention.
+ * @return SUCCESS.
+ */
+int32_t PostAnalysis( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc )
+{
+ // If there was a channel failure some cleanup is required to ensure
+ // there are no more attentions from this channel.
+ MemUtils::cleanupChnlFail<TYPE_MCC>( i_chip, io_sc );
+
+ return SUCCESS;
+}
+PRDF_PLUGIN_DEFINE( axone_mcc, PostAnalysis );
+
+//##############################################################################
+//
+// DSTLFIR
+//
+//##############################################################################
+
+/**
+ * @brief Plugin function called to avoid analyzing to a checkstop on an OCMB.
+ * @param i_chip A MCC chip.
+ * @param io_sc The step code data struct.
+ * @param i_pos Position of the OMI/OCMB relative to the MCC.
+ * @return SUCCESS if the primary attn is CS, else PRD_SCAN_COMM_REGISTER_ZERO.
+ */
+int32_t checkOcmb( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc,
+ uint8_t i_pos )
+{
+ int32_t rc = PRD_SCAN_COMM_REGISTER_ZERO;
+
+ #ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS
+ // We do not have support for the OCMB in the checkstop analysis path.
+ // As such, we will simply indicate there is an attention from the OCMB and
+ // add second level support and both sides of the bus as callouts.
+ if ( CHECK_STOP == io_sc.service_data->getPrimaryAttnType() )
+ {
+ TargetHandle_t omi = getConnectedChild( i_chip->getTrgt(), TYPE_OMI,
+ i_pos );
+ ExtensibleChip * ocmb = getConnectedChild( i_chip, TYPE_OCMB_CHIP,
+ i_pos );
+
+ io_sc.service_data->SetCallout( LEVEL2_SUPPORT, MRU_MED, NO_GARD );
+ io_sc.service_data->SetCallout( omi, MRU_LOW, NO_GARD );
+ io_sc.service_data->SetCallout( ocmb->getTrgt(), MRU_LOW, NO_GARD );
+
+ rc = SUCCESS;
+ }
+ #endif
+
+ return rc;
+}
+
+#define CHECK_OCMB_PLUGIN( POS ) \
+int32_t checkOcmb_##POS( ExtensibleChip * i_chip, \
+ STEP_CODE_DATA_STRUCT & io_sc ) \
+{ \
+ return checkOcmb( i_chip, io_sc, POS ); \
+} \
+PRDF_PLUGIN_DEFINE( axone_mcc, checkOcmb_##POS );
+
+CHECK_OCMB_PLUGIN( 0 );
+CHECK_OCMB_PLUGIN( 1 );
+
+} // end namespace axone_mcc
+
+} // end namespace PRDF
+
diff --git a/src/usr/diag/prdf/common/plat/axone/prdfOmicPlugins.C b/src/usr/diag/prdf/common/plat/axone/prdfOmicPlugins.C
new file mode 100644
index 000000000..f6ea182b9
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/axone/prdfOmicPlugins.C
@@ -0,0 +1,173 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/plat/axone/prdfOmicPlugins.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+// Framework includes
+#include <iipServiceDataCollector.h>
+#include <prdfExtensibleChip.H>
+#include <prdfPluginMap.H>
+
+// Platform includes
+#include <prdfMemUtils.H>
+#include <prdfPlatServices.H>
+
+using namespace TARGETING;
+
+namespace PRDF
+{
+
+using namespace PlatServices;
+
+namespace axone_omic
+{
+
+//##############################################################################
+//
+// Special plugins
+//
+//##############################################################################
+
+/**
+ * @brief Analysis code that is called before the main analyze() function.
+ * @param i_chip An OMIC chip.
+ * @param io_sc The step code data struct.
+ * @param o_analyzed True if analysis is done on this chip, false otherwise.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+int32_t PreAnalysis( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_analyzed )
+{
+ // Check for a channel failure before analyzing this chip.
+ o_analyzed = MemUtils::analyzeChnlFail<TYPE_OMIC>( i_chip, io_sc );
+
+ return SUCCESS;
+}
+PRDF_PLUGIN_DEFINE( axone_omic, PreAnalysis );
+
+/**
+ * @brief Plugin function called after analysis is complete but before PRD
+ * exits.
+ * @param i_chip An OMIC chip.
+ * @param io_sc The step code data struct.
+ * @note This is especially useful for any analysis that still needs to be
+ * done after the framework clears the FIR bits that were at attention.
+ * @return SUCCESS.
+ */
+int32_t PostAnalysis( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc )
+{
+ // If there was a channel failure some cleanup is required to ensure
+ // there are no more attentions from this channel.
+ MemUtils::cleanupChnlFail<TYPE_OMIC>( i_chip, io_sc );
+
+ return SUCCESS;
+}
+PRDF_PLUGIN_DEFINE( axone_omic, PostAnalysis );
+
+//##############################################################################
+//
+// OMIDLFIR
+//
+//##############################################################################
+
+/**
+ * @brief OMIDLFIR[0|20|40] - OMI-DL Fatal Error
+ * @param i_chip An OMIC chip.
+ * @param io_sc The step code data struct.
+ * @param i_dl The DL relative to the OMIC.
+ * @return PRD_SCAN_COMM_REGISTER_ZERO for the bus callout, else SUCCESS
+ */
+int32_t DlFatalError( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc,
+ uint8_t i_dl )
+{
+ #define PRDF_FUNC "[axone_omic::DlFatalError] "
+
+ int32_t rc = SUCCESS;
+
+ do
+ {
+ // Note: The OMIDLFIR can't actually be set up to report UNIT_CS
+ // attentions, instead, as a workaround, the relevant channel fail
+ // bits will be set as recoverable bits and we will manually set
+ // the attention types to UNIT_CS in our handling of these errors.
+ io_sc.service_data->setPrimaryAttnType( UNIT_CS );
+
+ char reg[64];
+ sprintf( reg, "DL%d_ERROR_HOLD", i_dl );
+
+ // Check DL#_ERROR_HOLD[52:63] to determine callout
+ SCAN_COMM_REGISTER_CLASS * dl_error_hold = i_chip->getRegister( reg );
+
+ if ( SUCCESS != dl_error_hold->Read() )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() Failed on DL%d_ERROR_HOLD: "
+ "i_chip=0x%08x", i_dl, i_chip->getHuid() );
+ break;
+ }
+
+ if ( dl_error_hold->IsBitSet(53) ||
+ dl_error_hold->IsBitSet(55) ||
+ dl_error_hold->IsBitSet(57) ||
+ dl_error_hold->IsBitSet(58) ||
+ dl_error_hold->IsBitSet(59) ||
+ dl_error_hold->IsBitSet(60) ||
+ dl_error_hold->IsBitSet(62) ||
+ dl_error_hold->IsBitSet(63) )
+ {
+ // Get and callout the OMI target
+ TargetHandle_t omi = getConnectedChild( i_chip->getTrgt(), TYPE_OMI,
+ i_dl );
+ io_sc.service_data->SetCallout( omi );
+ }
+ else if ( dl_error_hold->IsBitSet(54) ||
+ dl_error_hold->IsBitSet(56) ||
+ dl_error_hold->IsBitSet(61) )
+ {
+ // callout the OMI target, the OMI bus, and the OCMB
+ // Return PRD_SCAN_COMM_REGISTER_ZERO so the rule code makes
+ // the appropriate callout.
+ rc = PRD_SCAN_COMM_REGISTER_ZERO;
+ }
+
+ }while(0);
+
+ return rc;
+
+ #undef PRDF_FUNC
+}
+
+#define DL_FATAL_ERROR_PLUGIN( POS ) \
+int32_t DlFatalError_##POS( ExtensibleChip * i_chip, \
+ STEP_CODE_DATA_STRUCT & io_sc ) \
+{ \
+ return DlFatalError( i_chip, io_sc, POS ); \
+} \
+PRDF_PLUGIN_DEFINE( axone_omic, DlFatalError_##POS );
+
+DL_FATAL_ERROR_PLUGIN( 0 );
+DL_FATAL_ERROR_PLUGIN( 1 );
+DL_FATAL_ERROR_PLUGIN( 2 );
+
+} // end namespace axone_omic
+
+} // end namespace PRDF
diff --git a/src/usr/diag/prdf/common/plat/axone/prdf_plat_axone.mk b/src/usr/diag/prdf/common/plat/axone/prdf_plat_axone.mk
index ea76f9121..24acb5bb6 100644
--- a/src/usr/diag/prdf/common/plat/axone/prdf_plat_axone.mk
+++ b/src/usr/diag/prdf/common/plat/axone/prdf_plat_axone.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2016,2018
+# Contributors Listed Below - COPYRIGHT 2016,2019
# [+] International Business Machines Corp.
#
#
@@ -37,5 +37,7 @@ prd_incpath += ${PRD_SRC_PATH}/common/plat/axone
# Object files common to both FSP and Hostboot
################################################################################
-# plat/cumulus/ (rule plugin related)
+# plat/axone/ (rule plugin related)
+prd_rule_plugin += prdfMccPlugins.o
+prd_rule_plugin += prdfOmicPlugins.o
diff --git a/src/usr/diag/prdf/common/plat/cumulus/cumulus_mc_regs.rule b/src/usr/diag/prdf/common/plat/cumulus/cumulus_mc_regs.rule
index 50a0170c2..027a0c08c 100644
--- a/src/usr/diag/prdf/common/plat/cumulus/cumulus_mc_regs.rule
+++ b/src/usr/diag/prdf/common/plat/cumulus/cumulus_mc_regs.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -50,3 +50,20 @@
capture group default;
};
+ ############################################################################
+ # PCB Slave Error Regs
+ ############################################################################
+
+ register MC_ERROR_REG
+ {
+ name "MC PCB Slave error reg";
+ scomaddr 0x070F001F;
+ capture group PllFIRs;
+ };
+
+ register MC_CONFIG_REG
+ {
+ name "MC PCB Slave config reg";
+ scomaddr 0x070F001E;
+ capture group PllFIRs;
+ };
diff --git a/src/usr/diag/prdf/common/plat/cumulus/cumulus_obus.rule b/src/usr/diag/prdf/common/plat/cumulus/cumulus_obus.rule
index 8c950bbc7..7275e26a3 100644
--- a/src/usr/diag/prdf/common/plat/cumulus/cumulus_obus.rule
+++ b/src/usr/diag/prdf/common/plat/cumulus/cumulus_obus.rule
@@ -469,12 +469,12 @@ group gIOOLFIR
/** IOOLFIR[8]
* link0 nak received
*/
- (rIOOLFIR, bit(8)) ? defaultMaskedError;
+ (rIOOLFIR, bit(8)) ? threshold_and_mask_self_non_smp_only;
/** IOOLFIR[9]
* link1 nak received
*/
- (rIOOLFIR, bit(9)) ? defaultMaskedError;
+ (rIOOLFIR, bit(9)) ? threshold_and_mask_self_non_smp_only;
/** IOOLFIR[10]
* link0 replay buffer full
@@ -499,22 +499,22 @@ group gIOOLFIR
/** IOOLFIR[14]
* link0 sl ecc correctable
*/
- (rIOOLFIR, bit(14)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(14)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[15]
* link1 sl ecc correctable
*/
- (rIOOLFIR, bit(15)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(15)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[16]
* link0 sl ecc ue
*/
- (rIOOLFIR, bit(16)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(16)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[17]
* link1 sl ecc ue
*/
- (rIOOLFIR, bit(17)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(17)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[18]
* link0 retrain threshold
@@ -597,12 +597,12 @@ group gIOOLFIR
(rIOOLFIR, bit(33)) ? defaultMaskedError;
/** IOOLFIR[34]
- * link0 num replay
+ * link0 num replay or no forward progress
*/
(rIOOLFIR, bit(34)) ? defaultMaskedError;
/** IOOLFIR[35]
- * link1 num replay
+ * link1 num replay or no forward progress
*/
(rIOOLFIR, bit(35)) ? defaultMaskedError;
@@ -619,12 +619,12 @@ group gIOOLFIR
/** IOOLFIR[38]
* link0 prbs select error
*/
- (rIOOLFIR, bit(38)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(38)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[39]
* link1 prbs select error
*/
- (rIOOLFIR, bit(39)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(39)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[40]
* link0 tcomplete bad
@@ -639,102 +639,102 @@ group gIOOLFIR
/** IOOLFIR[42]
* link0 no spare lane available
*/
- (rIOOLFIR, bit(42)) ? obusSmpCallout_L0;
+ (rIOOLFIR, bit(42)) ? obusSmpCallout_L0_smp_only;
/** IOOLFIR[43]
* link1 no spare lane available
*/
- (rIOOLFIR, bit(43)) ? obusSmpCallout_L1;
+ (rIOOLFIR, bit(43)) ? obusSmpCallout_L1_smp_only;
/** IOOLFIR[44]
- * link0 spare done
+ * link0 spare done or degraded mode
*/
- (rIOOLFIR, bit(44)) ? obusSmpCallout_th32_L0;
+ (rIOOLFIR, bit(44)) ? spare_lane_degraded_mode_L0;
/** IOOLFIR[45]
- * link1 spare done
+ * link1 spare done or degraded mode
*/
- (rIOOLFIR, bit(45)) ? obusSmpCallout_th32_L1;
+ (rIOOLFIR, bit(45)) ? spare_lane_degraded_mode_L1;
/** IOOLFIR[46]
* link0 too many crc errors
*/
- (rIOOLFIR, bit(46)) ? obusSmpCallout_L0;
+ (rIOOLFIR, bit(46)) ? obusSmpCallout_L0_smp_only;
/** IOOLFIR[47]
* link1 too many crc errors
*/
- (rIOOLFIR, bit(47)) ? obusSmpCallout_L1;
+ (rIOOLFIR, bit(47)) ? obusSmpCallout_L1_smp_only;
/** IOOLFIR[48]
- * link0 npu error
+ * link0 npu error or orx otx dlx errors
*/
(rIOOLFIR, bit(48)) ? threshold_and_mask_self;
/** IOOLFIR[49]
- * link1 npu error
+ * link1 npu error or orx otx dlx errors
*/
(rIOOLFIR, bit(49)) ? threshold_and_mask_self;
/** IOOLFIR[50]
* linkx npu error
*/
- (rIOOLFIR, bit(50)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(50)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[51]
* osc switch
*/
- (rIOOLFIR, bit(51)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(51)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[52]
* link0 correctable array error
*/
- (rIOOLFIR, bit(52)) ? obusSmpCallout_th32_L0;
+ (rIOOLFIR, bit(52)) ? self_th_32perDay;
/** IOOLFIR[53]
* link1 correctable array error
*/
- (rIOOLFIR, bit(53)) ? obusSmpCallout_th32_L1;
+ (rIOOLFIR, bit(53)) ? self_th_32perDay;
/** IOOLFIR[54]
* link0 uncorrectable array error
*/
- (rIOOLFIR, bit(54)) ? obusSmpFailure_L0;
+ (rIOOLFIR, bit(54)) ? self_th_1;
/** IOOLFIR[55]
* link1 uncorrectable array error
*/
- (rIOOLFIR, bit(55)) ? obusSmpFailure_L1;
+ (rIOOLFIR, bit(55)) ? self_th_1;
/** IOOLFIR[56]
* link0 training failed
*/
- (rIOOLFIR, bit(56)) ? obusSmpFailure_L0;
+ (rIOOLFIR, bit(56)) ? training_failure_L0;
/** IOOLFIR[57]
* link1 training failed
*/
- (rIOOLFIR, bit(57)) ? obusSmpFailure_L1;
+ (rIOOLFIR, bit(57)) ? training_failure_L1;
/** IOOLFIR[58]
* link0 unrecoverable error
*/
- (rIOOLFIR, bit(58)) ? obusSmpFailure_L0;
+ (rIOOLFIR, bit(58)) ? unrecoverable_error_L0;
/** IOOLFIR[59]
* link1 unrecoverable error
*/
- (rIOOLFIR, bit(59)) ? obusSmpFailure_L1;
+ (rIOOLFIR, bit(59)) ? unrecoverable_error_L1;
/** IOOLFIR[60]
* link0 internal error
*/
- (rIOOLFIR, bit(60)) ? obusSmpFailure_L0;
+ (rIOOLFIR, bit(60)) ? internal_error_L0;
/** IOOLFIR[61]
* link1 internal error
*/
- (rIOOLFIR, bit(61)) ? obusSmpFailure_L1;
+ (rIOOLFIR, bit(61)) ? internal_error_L1;
/** IOOLFIR[62]
* fir scom err dup
diff --git a/src/usr/diag/prdf/common/plat/cumulus/cumulus_phb.rule b/src/usr/diag/prdf/common/plat/cumulus/cumulus_phb.rule
index 9c8dcce38..88c917458 100644
--- a/src/usr/diag/prdf/common/plat/cumulus/cumulus_phb.rule
+++ b/src/usr/diag/prdf/common/plat/cumulus/cumulus_phb.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2016,2018
+# Contributors Listed Below - COPYRIGHT 2016,2019
# [+] International Business Machines Corp.
#
#
@@ -212,7 +212,7 @@ group gPHBNFIR
/** PHBNFIR[0]
* BAR Parity Error
*/
- (rPHBNFIR, bit(0)) ? self_th_1;
+ (rPHBNFIR, bit(0)) ? parent_proc_th_1;
/** PHBNFIR[1]
* Parity Errors on Registers besides BAR
@@ -252,12 +252,12 @@ group gPHBNFIR
/** PHBNFIR[8]
* Register Array Parity Error
*/
- (rPHBNFIR, bit(8)) ? self_th_1;
+ (rPHBNFIR, bit(8)) ? parent_proc_th_1;
/** PHBNFIR[9]
* Power Bus Interface Parity Error
*/
- (rPHBNFIR, bit(9)) ? self_th_1;
+ (rPHBNFIR, bit(9)) ? parent_proc_th_1;
/** PHBNFIR[10]
* Power Bus Data Hang
@@ -297,7 +297,7 @@ group gPHBNFIR
/** PHBNFIR[17]
* Hardware Error
*/
- (rPHBNFIR, bit(17)) ? self_th_1;
+ (rPHBNFIR, bit(17)) ? parent_proc_th_1;
/** PHBNFIR[18]
* Unsolicited Power Bus Data
diff --git a/src/usr/diag/prdf/common/plat/cumulus/cumulus_proc.rule b/src/usr/diag/prdf/common/plat/cumulus/cumulus_proc.rule
index 187cd2a44..ae8e6bb80 100644
--- a/src/usr/diag/prdf/common/plat/cumulus/cumulus_proc.rule
+++ b/src/usr/diag/prdf/common/plat/cumulus/cumulus_proc.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2016,2018
+# Contributors Listed Below - COPYRIGHT 2016,2019
# [+] International Business Machines Corp.
#
#
@@ -2893,7 +2893,7 @@ group gNXCQFIR
/** NXCQFIR[19]
* Uncorrectable error on ERAT arrays
*/
- (rNXCQFIR, bit(19)) ? nx_th_32perDay;
+ (rNXCQFIR, bit(19)) ? nx_th_1;
/** NXCQFIR[20]
* SUE on ERAT arrays
diff --git a/src/usr/diag/prdf/common/plat/cumulus/cumulus_proc_actions.rule b/src/usr/diag/prdf/common/plat/cumulus/cumulus_proc_actions.rule
index 26d62e95f..91298d653 100644
--- a/src/usr/diag/prdf/common/plat/cumulus/cumulus_proc_actions.rule
+++ b/src/usr/diag/prdf/common/plat/cumulus/cumulus_proc_actions.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -23,6 +23,12 @@
#
# IBM_PROLOG_END_TAG
+################################################################################
+# Analyze
+################################################################################
+
+actionclass analyzeENHCAFIR { analyze(gENHCAFIR); };
+
###############################################################################
# Analyze connected
###############################################################################
diff --git a/src/usr/diag/prdf/common/plat/explorer/explorer_ocmb.rule b/src/usr/diag/prdf/common/plat/explorer/explorer_ocmb.rule
index 1abd08c96..c1e5c15a8 100644
--- a/src/usr/diag/prdf/common/plat/explorer/explorer_ocmb.rule
+++ b/src/usr/diag/prdf/common/plat/explorer/explorer_ocmb.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -44,82 +44,82 @@ chip explorer_ocmb
#############################################################################
############################################################################
- # MB Chiplet FIR
+ # OCMB Chiplet FIR
############################################################################
- register MB_CHIPLET_CS_FIR
+ register OCMB_CHIPLET_CS_FIR
{
- name "MB Chiplet Checkstop FIR";
+ name "OCMB Chiplet Checkstop FIR";
scomaddr 0x08040000;
capture group default;
};
- register MB_CHIPLET_RE_FIR
+ register OCMB_CHIPLET_RE_FIR
{
- name "MB Chiplet Recoverable FIR";
+ name "OCMB Chiplet Recoverable FIR";
scomaddr 0x08040001;
capture group default;
};
- register MB_CHIPLET_FIR_MASK
+ register OCMB_CHIPLET_FIR_MASK
{
- name "MB Chiplet FIR MASK";
+ name "OCMB Chiplet FIR MASK";
scomaddr 0x08040002;
capture group default;
};
############################################################################
- # MB Chiplet Special Attention FIR
+ # OCMB Chiplet Special Attention FIR
############################################################################
- register MB_CHIPLET_SPA_FIR
+ register OCMB_CHIPLET_SPA_FIR
{
- name "MB Chiplet Special Attention FIR";
+ name "OCMB Chiplet Special Attention FIR";
scomaddr 0x08040004;
capture group default;
};
- register MB_CHIPLET_SPA_FIR_MASK
+ register OCMB_CHIPLET_SPA_FIR_MASK
{
- name "MB Chiplet Special Attention FIR MASK";
+ name "OCMB Chiplet Special Attention FIR MASK";
scomaddr 0x08040007;
capture group default;
};
############################################################################
- # Explorer chip MB_LFIR
+ # Explorer chip OCMB_LFIR
############################################################################
- register MB_LFIR
+ register OCMB_LFIR
{
- name "Explorer chip MB_LFIR";
+ name "Explorer chip OCMB_LFIR";
scomaddr 0x0804000a;
reset (&, 0x0804000b);
mask (|, 0x0804000f);
capture group default;
};
- register MB_LFIR_MASK
+ register OCMB_LFIR_MASK
{
- name "Explorer chip MB_LFIR MASK";
+ name "Explorer chip OCMB_LFIR MASK";
scomaddr 0x0804000d;
capture group default;
};
- register MB_LFIR_ACT0
+ register OCMB_LFIR_ACT0
{
- name "Explorer chip MB_LFIR ACT0";
+ name "Explorer chip OCMB_LFIR ACT0";
scomaddr 0x08040010;
capture group default;
- capture req nonzero("MB_LFIR");
+ capture req nonzero("OCMB_LFIR");
};
- register MB_LFIR_ACT1
+ register OCMB_LFIR_ACT1
{
- name "Explorer chip MB_LFIR ACT1";
+ name "Explorer chip OCMB_LFIR ACT1";
scomaddr 0x08040011;
capture group default;
- capture req nonzero("MB_LFIR");
+ capture req nonzero("OCMB_LFIR");
};
############################################################################
@@ -355,174 +355,261 @@ chip explorer_ocmb
##############################################################################
################################################################################
-# MB Chiplet FIR
+# OCMB Chiplet FIR
################################################################################
-rule rMB_CHIPLET_FIR
+rule rOCMB_CHIPLET_FIR
{
UNIT_CS:
- MB_CHIPLET_CS_FIR & ~MB_CHIPLET_FIR_MASK & `1fffffffffffffff`;
+ OCMB_CHIPLET_CS_FIR & ~OCMB_CHIPLET_FIR_MASK & `1fffffffffffffff`;
RECOVERABLE:
- (MB_CHIPLET_RE_FIR >> 2) & ~MB_CHIPLET_FIR_MASK & `1fffffffffffffff`;
+ (OCMB_CHIPLET_RE_FIR >> 2) & ~OCMB_CHIPLET_FIR_MASK & `1fffffffffffffff`;
};
-group gMB_CHIPLET_FIR attntype CHECK_STOP, RECOVERABLE
+# NOTE: RDFFIR[14|34] are possible side effects of OCMB_LFIR[38], as such,
+# OCMB_LFIR must be analyzed first for correct handling. If changes are
+# made so the RDFFIR is analyzed first, additional changes to the handling
+# of those bits will be required.
+group gOCMB_CHIPLET_FIR attntype UNIT_CS, RECOVERABLE
filter singlebit
{
- /** MB_CHIPLET_FIR[3]
- * Attention from MB_LFIR
+ /** OCMB_CHIPLET_FIR[3]
+ * Attention from OCMB_LFIR
*/
- (rMB_CHIPLET_FIR, bit(3)) ? analyzeMB_LFIR;
+ (rOCMB_CHIPLET_FIR, bit(3)) ? analyzeOCMB_LFIR;
- /** MB_CHIPLET_FIR[4]
+ /** OCMB_CHIPLET_FIR[4]
* Attention from MMIOFIR
*/
- (rMB_CHIPLET_FIR, bit(4)) ? analyzeMMIOFIR;
+ (rOCMB_CHIPLET_FIR, bit(4)) ? analyzeMMIOFIR;
- /** MB_CHIPLET_FIR[7]
+ /** OCMB_CHIPLET_FIR[7]
* Attention from SRQFIR
*/
- (rMB_CHIPLET_FIR, bit(7)) ? analyzeSRQFIR;
+ (rOCMB_CHIPLET_FIR, bit(7)) ? analyzeSRQFIR;
- /** MB_CHIPLET_FIR[8]
+ /** OCMB_CHIPLET_FIR[8]
* Attention from MCBISTFIR
*/
- (rMB_CHIPLET_FIR, bit(8)) ? analyzeMCBISTFIR;
+ (rOCMB_CHIPLET_FIR, bit(8)) ? analyzeMCBISTFIR;
- /** MB_CHIPLET_FIR[9]
+ /** OCMB_CHIPLET_FIR[9]
* Attention from RDFFIR
*/
- (rMB_CHIPLET_FIR, bit(9)) ? analyzeRDFFIR;
+ (rOCMB_CHIPLET_FIR, bit(9)) ? analyzeRDFFIR;
- /** MB_CHIPLET_FIR[11]
+ /** OCMB_CHIPLET_FIR[11]
* Attention from TLXFIR
*/
- (rMB_CHIPLET_FIR, bit(11)) ? analyzeTLXFIR;
+ (rOCMB_CHIPLET_FIR, bit(11)) ? analyzeTLXFIR;
- /** MB_CHIPLET_FIR[12]
+ /** OCMB_CHIPLET_FIR[12]
* Attention from OMIDLFIR
*/
- (rMB_CHIPLET_FIR, bit(12)) ? analyzeOMIDLFIR;
+ (rOCMB_CHIPLET_FIR, bit(12)) ? analyzeOMIDLFIR;
};
################################################################################
-# MB Chiplet Special Attention FIR
+# OCMB Chiplet Special Attention FIR
################################################################################
-rule rMB_CHIPLET_SPA_FIR
+rule rOCMB_CHIPLET_SPA_FIR
{
HOST_ATTN:
- MB_CHIPLET_SPA_FIR & ~MB_CHIPLET_SPA_FIR_MASK;
+ OCMB_CHIPLET_SPA_FIR & ~OCMB_CHIPLET_SPA_FIR_MASK;
};
-group gMB_CHIPLET_SPA_FIR attntype HOST_ATTN
+group gOCMB_CHIPLET_SPA_FIR attntype HOST_ATTN
filter singlebit
{
- /** MB_CHIPLET_SPA_FIR[1]
+ /** OCMB_CHIPLET_SPA_FIR[1]
* Attention from MMIOFIR
*/
- (rMB_CHIPLET_SPA_FIR, bit(1)) ? analyzeMMIOFIR;
+ (rOCMB_CHIPLET_SPA_FIR, bit(1)) ? analyzeMMIOFIR;
- /** MB_CHIPLET_SPA_FIR[4]
+ /** OCMB_CHIPLET_SPA_FIR[4]
* Attention from SRQFIR
*/
- (rMB_CHIPLET_SPA_FIR, bit(4)) ? analyzeSRQFIR;
+ (rOCMB_CHIPLET_SPA_FIR, bit(4)) ? analyzeSRQFIR;
- /** MB_CHIPLET_SPA_FIR[5]
+ /** OCMB_CHIPLET_SPA_FIR[5]
* Attention from MCBISTFIR
*/
- (rMB_CHIPLET_SPA_FIR, bit(5)) ? analyzeMCBISTFIR;
+ (rOCMB_CHIPLET_SPA_FIR, bit(5)) ? analyzeMCBISTFIR;
- /** MB_CHIPLET_SPA_FIR[6]
+ /** OCMB_CHIPLET_SPA_FIR[6]
* Attention from RDFFIR
*/
- (rMB_CHIPLET_SPA_FIR, bit(6)) ? analyzeRDFFIR;
+ (rOCMB_CHIPLET_SPA_FIR, bit(6)) ? analyzeRDFFIR;
- /** MB_CHIPLET_SPA_FIR[8]
+ /** OCMB_CHIPLET_SPA_FIR[8]
* Attention from TLXFIR
*/
- (rMB_CHIPLET_SPA_FIR, bit(8)) ? analyzeTLXFIR;
+ (rOCMB_CHIPLET_SPA_FIR, bit(8)) ? analyzeTLXFIR;
- /** MB_CHIPLET_SPA_FIR[9]
+ /** OCMB_CHIPLET_SPA_FIR[9]
* Attention from OMIDLFIR
*/
- (rMB_CHIPLET_SPA_FIR, bit(9)) ? analyzeOMIDLFIR;
+ (rOCMB_CHIPLET_SPA_FIR, bit(9)) ? analyzeOMIDLFIR;
};
################################################################################
-# Explorer chip MB_LFIR
+# Explorer chip OCMB_LFIR
################################################################################
-rule rMB_LFIR
+rule rOCMB_LFIR
{
UNIT_CS:
- MB_LFIR & ~MB_LFIR_MASK & ~MB_LFIR_ACT0 & ~MB_LFIR_ACT1;
+ OCMB_LFIR & ~OCMB_LFIR_MASK & ~OCMB_LFIR_ACT0 & ~OCMB_LFIR_ACT1;
RECOVERABLE:
- MB_LFIR & ~MB_LFIR_MASK & ~MB_LFIR_ACT0 & MB_LFIR_ACT1;
- HOST_ATTN:
- MB_LFIR & ~MB_LFIR_MASK & MB_LFIR_ACT0 & ~MB_LFIR_ACT1;
+ OCMB_LFIR & ~OCMB_LFIR_MASK & ~OCMB_LFIR_ACT0 & OCMB_LFIR_ACT1;
};
-group gMB_LFIR
+group gOCMB_LFIR
filter singlebit,
cs_root_cause
{
- /** MB_LFIR[0]
+ /** OCMB_LFIR[0]
* CFIR access PCB error
*/
- (rMB_LFIR, bit(0)) ? defaultMaskedError;
+ (rOCMB_LFIR, bit(0)) ? self_th_32perDay;
- /** MB_LFIR[1]
+ /** OCMB_LFIR[1]
* CFIR internal parity error
*/
- (rMB_LFIR, bit(1)) ? defaultMaskedError;
+ (rOCMB_LFIR, bit(1)) ? self_th_32perDay;
- /** MB_LFIR[2]
+ /** OCMB_LFIR[2]
* LFIR internal parity error
*/
- (rMB_LFIR, bit(2)) ? defaultMaskedError;
+ (rOCMB_LFIR, bit(2)) ? self_th_32perDay;
- /** MB_LFIR[3]
+ /** OCMB_LFIR[3]
* Debug scom satellite error
*/
- (rMB_LFIR, bit(3)) ? defaultMaskedError;
+ (rOCMB_LFIR, bit(3)) ? defaultMaskedError;
- /** MB_LFIR[4]
+ /** OCMB_LFIR[4]
* PSCOM Logic: PCB Access Error
*/
- (rMB_LFIR, bit(4)) ? defaultMaskedError;
+ (rOCMB_LFIR, bit(4)) ? defaultMaskedError;
- /** MB_LFIR[5]
+ /** OCMB_LFIR[5]
* PSCOM Logic: Summarized internal errors
*/
- (rMB_LFIR, bit(5)) ? defaultMaskedError;
+ (rOCMB_LFIR, bit(5)) ? defaultMaskedError;
- /** MB_LFIR[6]
+ /** OCMB_LFIR[6]
* Trace Logic : Scom Satellite Error - Trace0
*/
- (rMB_LFIR, bit(6)) ? defaultMaskedError;
+ (rOCMB_LFIR, bit(6)) ? defaultMaskedError;
- /** MB_LFIR[7]
+ /** OCMB_LFIR[7]
* Trace Logic : Scom Satellite Error - Trace1
*/
- (rMB_LFIR, bit(7)) ? defaultMaskedError;
+ (rOCMB_LFIR, bit(7)) ? defaultMaskedError;
- /** MB_LFIR[8]
- * unused
+ /** OCMB_LFIR[8]
+ * PIB2GIF parity error on FSM or Registers
*/
- (rMB_LFIR, bit(8)) ? defaultMaskedError;
+ (rOCMB_LFIR, bit(8)) ? self_th_32perDay;
- /** MB_LFIR[9]
+ /** OCMB_LFIR[9]
* MSG access PCB error
*/
- (rMB_LFIR, bit(9)) ? defaultMaskedError;
+ (rOCMB_LFIR, bit(9)) ? defaultMaskedError;
+
+ /** OCMB_LFIR[10:18]
+ * unused
+ */
+ (rOCMB_LFIR, bit(10|11|12|13|14|15|16|17|18)) ? defaultMaskedError;
+
+ /** OCMB_LFIR[19]
+ * DLL IRQ
+ */
+ (rOCMB_LFIR, bit(19)) ? defaultMaskedError;
+
+ /** OCMB_LFIR[20]
+ * Watchdog timer interrupt
+ */
+ (rOCMB_LFIR, bit(20)) ? self_th_1;
+
+ /** OCMB_LFIR[21]
+ * internal temp sensor tripped a threshold
+ */
+ (rOCMB_LFIR, bit(21)) ? defaultMaskedError;
+
+ /** OCMB_LFIR[22]
+ * GPBC_FATAL_ERROR
+ */
+ (rOCMB_LFIR, bit(22)) ? self_th_1;
+
+ /** OCMB_LFIR[23]
+ * GPBC_NON_FATAL_ERROR
+ */
+ (rOCMB_LFIR, bit(23)) ? self_th_1;
+
+ /** OCMB_LFIR[24]
+ * early power off warning
+ */
+ (rOCMB_LFIR, bit(24)) ? defaultMaskedError;
+
+ /** OCMB_LFIR[25]
+ * TOP fatal interrupts
+ */
+ (rOCMB_LFIR, bit(25)) ? self_th_1;
+
+ /** OCMB_LFIR[26]
+ * TOP non fatal interrupts
+ */
+ (rOCMB_LFIR, bit(26)) ? level2_M_self_L_th_1;
+
+ /** OCMB_LFIR[27:34]
+ * Interrupt from OPSe to OCMB
+ */
+ (rOCMB_LFIR, bit(27|28|29|30|31|32|33|34)) ? defaultMaskedError;
+
+ /** OCMB_LFIR[35]
+ * DDR thermal event
+ */
+ (rOCMB_LFIR, bit(35)) ? defaultMaskedError;
+
+ /** OCMB_LFIR[36]
+ * DDR4 PHY fatal
+ */
+ (rOCMB_LFIR, bit(36)) ? self_th_1;
+
+ /** OCMB_LFIR[37]
+ * DDR4 PHY non fatal
+ */
+ (rOCMB_LFIR, bit(37)) ? self_th_32perDay;
+
+ /** OCMB_LFIR[38]
+ * DDR4 PHY interrupt
+ */
+ (rOCMB_LFIR, bit(38)) ? ddr4_phy_interrupt;
- /** MB_LFIR[10:62]
- * bits from the microsemi message register (0 to 52)
+ /** OCMB_LFIR[39:46]
+ * foxhound fatal
*/
- (rMB_LFIR, bit(10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62)) ? defaultMaskedError;
+ (rOCMB_LFIR, bit(39|40|41|42|43|44|45|46)) ? foxhound_fatal;
+
+ /** OCMB_LFIR[47:54]
+ * foxhound non fatal
+ */
+ (rOCMB_LFIR, bit(47|48|49|50|51|52|53|54)) ? defaultMaskedError;
+
+ /** OCMB_LFIR[55:62]
+ * foxhound serdes interrupt
+ */
+ (rOCMB_LFIR, bit(55|56|57|58|59|60|61|62)) ? defaultMaskedError;
+
+ /** OCMB_LFIR[63]
+ * GIF2PCB parity error on FSM or Registers
+ */
+ (rOCMB_LFIR, bit(63)) ? self_th_32perDay;
};
@@ -557,27 +644,27 @@ group gMMIOFIR
/** MMIOFIR[2]
* SCOM err
*/
- (rMMIOFIR, bit(2)) ? defaultMaskedError;
+ (rMMIOFIR, bit(2)) ? self_th_32perDay;
/** MMIOFIR[3]
- * FSM err
+ * FSM perr
*/
- (rMMIOFIR, bit(3)) ? defaultMaskedError;
+ (rMMIOFIR, bit(3)) ? self_th_1;
/** MMIOFIR[4]
* FIFO overflow
*/
- (rMMIOFIR, bit(4)) ? defaultMaskedError;
+ (rMMIOFIR, bit(4)) ? self_th_1;
/** MMIOFIR[5]
* Ctl reg parity err
*/
- (rMMIOFIR, bit(5)) ? defaultMaskedError;
+ (rMMIOFIR, bit(5)) ? self_th_1;
/** MMIOFIR[6]
* Info reg parity error
*/
- (rMMIOFIR, bit(6)) ? defaultMaskedError;
+ (rMMIOFIR, bit(6)) ? self_th_1;
/** MMIOFIR[7]
* SNSC both starts err
@@ -622,22 +709,22 @@ rule rSRQFIR
group gSRQFIR
filter singlebit,
- cs_root_cause
+ cs_root_cause(18)
{
/** SRQFIR[0]
* SRQ recoverable error
*/
- (rSRQFIR, bit(0)) ? defaultMaskedError;
+ (rSRQFIR, bit(0)) ? mem_port_th_1;
/** SRQFIR[1]
* SRQ nonrecoverable error
*/
- (rSRQFIR, bit(1)) ? defaultMaskedError;
+ (rSRQFIR, bit(1)) ? mem_port_th_1;
/** SRQFIR[2]
* Refresh overrun
*/
- (rSRQFIR, bit(2)) ? defaultMaskedError;
+ (rSRQFIR, bit(2)) ? mem_port_th_32perDay;
/** SRQFIR[3]
* WAT error
@@ -647,12 +734,12 @@ group gSRQFIR
/** SRQFIR[4]
* RCD parity error
*/
- (rSRQFIR, bit(4)) ? defaultMaskedError;
+ (rSRQFIR, bit(4)) ? srq_rcd_parity_error;
/** SRQFIR[5]
* MCB logic error
*/
- (rSRQFIR, bit(5)) ? defaultMaskedError;
+ (rSRQFIR, bit(5)) ? mem_port_th_1;
/** SRQFIR[6]
* Emergency throttle
@@ -662,7 +749,7 @@ group gSRQFIR
/** SRQFIR[7]
* NCF MCB parity error
*/
- (rSRQFIR, bit(7)) ? defaultMaskedError;
+ (rSRQFIR, bit(7)) ? mem_port_th_1;
/** SRQFIR[8]
* DDR MBA event n
@@ -672,82 +759,82 @@ group gSRQFIR
/** SRQFIR[9]
* WRQ RRQ hang err
*/
- (rSRQFIR, bit(9)) ? defaultMaskedError;
+ (rSRQFIR, bit(9)) ? mem_port_th_1;
/** SRQFIR[10]
* SM one hot error
*/
- (rSRQFIR, bit(10)) ? defaultMaskedError;
+ (rSRQFIR, bit(10)) ? mem_port_th_1;
/** SRQFIR[11]
* Reg parity error
*/
- (rSRQFIR, bit(11)) ? defaultMaskedError;
+ (rSRQFIR, bit(11)) ? mem_port_th_1;
/** SRQFIR[12]
* Cmd parity error
*/
- (rSRQFIR, bit(12)) ? defaultMaskedError;
+ (rSRQFIR, bit(12)) ? mem_port_th_1;
/** SRQFIR[13]
* Port fail
*/
- (rSRQFIR, bit(13)) ? defaultMaskedError;
+ (rSRQFIR, bit(13)) ? mem_port_failure;
/** SRQFIR[14]
- * Spare
+ * informational register parity error bit
*/
- (rSRQFIR, bit(14)) ? defaultMaskedError;
+ (rSRQFIR, bit(14)) ? threshold_and_mask_mem_port;
/** SRQFIR[15]
* Debug parity error
*/
- (rSRQFIR, bit(15)) ? defaultMaskedError;
+ (rSRQFIR, bit(15)) ? threshold_and_mask_mem_port;
/** SRQFIR[16]
* WDF unrecoverable mainline error
*/
- (rSRQFIR, bit(16)) ? defaultMaskedError;
+ (rSRQFIR, bit(16)) ? mem_port_th_1;
/** SRQFIR[17]
* WDF mmio error
*/
- (rSRQFIR, bit(17)) ? defaultMaskedError;
+ (rSRQFIR, bit(17)) ? mem_port_th_1;
/** SRQFIR[18]
* WDF array UE on mainline operations (SUE put in mem)
*/
- (rSRQFIR, bit(18)) ? defaultMaskedError;
+ (rSRQFIR, bit(18)) ? mem_port_th_1_UERE;
/** SRQFIR[19]
* WDF mainline dataflow error (SUE not reliably put in mem)
*/
- (rSRQFIR, bit(19)) ? defaultMaskedError;
+ (rSRQFIR, bit(19)) ? mem_port_th_1;
/** SRQFIR[20]
* WDF scom register parity err, affecting mainline config
*/
- (rSRQFIR, bit(20)) ? defaultMaskedError;
+ (rSRQFIR, bit(20)) ? mem_port_th_1;
/** SRQFIR[21]
* WDF scom register parity err, affecting scom ops only
*/
- (rSRQFIR, bit(21)) ? defaultMaskedError;
+ (rSRQFIR, bit(21)) ? mem_port_th_1;
/** SRQFIR[22]
* WDF SCOM fsm parity error
*/
- (rSRQFIR, bit(22)) ? defaultMaskedError;
+ (rSRQFIR, bit(22)) ? mem_port_th_1;
/** SRQFIR[23]
* WDF write buffer array CE
*/
- (rSRQFIR, bit(23)) ? defaultMaskedError;
+ (rSRQFIR, bit(23)) ? mem_port_th_32perDay;
/** SRQFIR[24]
* NCF UE
*/
- (rSRQFIR, bit(24)) ? defaultMaskedError;
+ (rSRQFIR, bit(24)) ? mem_port_th_1;
/** SRQFIR[25]
* TBD
@@ -757,17 +844,17 @@ group gSRQFIR
/** SRQFIR[26]
* NCF logic error
*/
- (rSRQFIR, bit(26)) ? defaultMaskedError;
+ (rSRQFIR, bit(26)) ? mem_port_th_1;
/** SRQFIR[27]
* NCF parity error
*/
- (rSRQFIR, bit(27)) ? defaultMaskedError;
+ (rSRQFIR, bit(27)) ? mem_port_th_1;
/** SRQFIR[28]
* NCF correctable error
*/
- (rSRQFIR, bit(28)) ? defaultMaskedError;
+ (rSRQFIR, bit(28)) ? mem_port_th_32perDay;
/** SRQFIR[29]
* Internal scom error
@@ -807,17 +894,17 @@ group gMCBISTFIR
/** MCBISTFIR[1]
* Command address timeout
*/
- (rMCBISTFIR, bit(1)) ? defaultMaskedError;
+ (rMCBISTFIR, bit(1)) ? self_th_1;
/** MCBISTFIR[2]
* Internal FSM error
*/
- (rMCBISTFIR, bit(2)) ? defaultMaskedError;
+ (rMCBISTFIR, bit(2)) ? self_th_1;
/** MCBISTFIR[3]
* MCBIST broadcast out of sync
*/
- (rMCBISTFIR, bit(3)) ? defaultMaskedError;
+ (rMCBISTFIR, bit(3)) ? self_th_1;
/** MCBISTFIR[4]
* MCBIST data error
@@ -852,7 +939,7 @@ group gMCBISTFIR
/** MCBISTFIR[10]
* MCBIST program complete
*/
- (rMCBISTFIR, bit(10)) ? defaultMaskedError;
+ (rMCBISTFIR, bit(10)) ? mcbist_program_complete;
/** MCBISTFIR[11]
* MCBIST CCS subtest done
@@ -865,14 +952,14 @@ group gMCBISTFIR
(rMCBISTFIR, bit(12)) ? defaultMaskedError;
/** MCBISTFIR[13]
- * SCOM recoverable reg parity error
+ * SCOM recoverable register parity error
*/
- (rMCBISTFIR, bit(13)) ? defaultMaskedError;
+ (rMCBISTFIR, bit(13)) ? self_th_1;
/** MCBISTFIR[14]
* SCOM fatal reg parity error
*/
- (rMCBISTFIR, bit(14)) ? defaultMaskedError;
+ (rMCBISTFIR, bit(14)) ? self_th_1;
/** MCBISTFIR[15]
* SCOM WAT and debug reg parity error
@@ -917,57 +1004,57 @@ rule rRDFFIR
group gRDFFIR
filter singlebit,
- cs_root_cause
+ cs_root_cause(14,15,17,35,37)
{
/** RDFFIR[0]
* Mainline read MPE on rank 0
*/
- (rRDFFIR, bit(0)) ? defaultMaskedError;
+ (rRDFFIR, bit(0)) ? verify_chip_mark_0;
/** RDFFIR[1]
* Mainline read MPE on rank 1
*/
- (rRDFFIR, bit(1)) ? defaultMaskedError;
+ (rRDFFIR, bit(1)) ? verify_chip_mark_1;
/** RDFFIR[2]
* Mainline read MPE on rank 2
*/
- (rRDFFIR, bit(2)) ? defaultMaskedError;
+ (rRDFFIR, bit(2)) ? verify_chip_mark_2;
/** RDFFIR[3]
- * Maineline read MPE on rank 3
+ * Mainline read MPE on rank 3
*/
- (rRDFFIR, bit(3)) ? defaultMaskedError;
+ (rRDFFIR, bit(3)) ? verify_chip_mark_3;
/** RDFFIR[4]
* Mainline read MPE on rank 4
*/
- (rRDFFIR, bit(4)) ? defaultMaskedError;
+ (rRDFFIR, bit(4)) ? verify_chip_mark_4;
/** RDFFIR[5]
* Mainline read MPE on rank 5
*/
- (rRDFFIR, bit(5)) ? defaultMaskedError;
+ (rRDFFIR, bit(5)) ? verify_chip_mark_5;
/** RDFFIR[6]
* Mainline read MPE on rank 6
*/
- (rRDFFIR, bit(6)) ? defaultMaskedError;
+ (rRDFFIR, bit(6)) ? verify_chip_mark_6;
/** RDFFIR[7]
* Mainline read MPE on rank 7
*/
- (rRDFFIR, bit(7)) ? defaultMaskedError;
+ (rRDFFIR, bit(7)) ? verify_chip_mark_7;
/** RDFFIR[8]
* Mainline read NCE
*/
- (rRDFFIR, bit(8)) ? defaultMaskedError;
+ (rRDFFIR, bit(8)) ? mainline_nce_tce_handling;
/** RDFFIR[9]
* Mainline read TCE
*/
- (rRDFFIR, bit(9)) ? defaultMaskedError;
+ (rRDFFIR, bit(9)) ? mainline_nce_tce_handling;
/** RDFFIR[10]
* Mainline read SCE
@@ -987,27 +1074,27 @@ group gRDFFIR
/** RDFFIR[13]
* Mainline read AUE
*/
- (rRDFFIR, bit(13)) ? defaultMaskedError;
+ (rRDFFIR, bit(13)) ? mainline_aue_iaue_handling;
/** RDFFIR[14]
* Mainline read UE
*/
- (rRDFFIR, bit(14)) ? defaultMaskedError;
+ (rRDFFIR, bit(14)) ? mainline_ue_handling_UERE;
/** RDFFIR[15]
* Mainline read RCD
*/
- (rRDFFIR, bit(15)) ? defaultMaskedError;
+ (rRDFFIR, bit(15)) ? rdf_rcd_parity_error_UERE;
/** RDFFIR[16]
* Mainline read IAUE
*/
- (rRDFFIR, bit(16)) ? defaultMaskedError;
+ (rRDFFIR, bit(16)) ? mainline_aue_iaue_handling;
/** RDFFIR[17]
* Mainline read IUE
*/
- (rRDFFIR, bit(17)) ? defaultMaskedError;
+ (rRDFFIR, bit(17)) ? mainline_iue_handling;
/** RDFFIR[18]
* Mainline read IRCD
@@ -1017,7 +1104,7 @@ group gRDFFIR
/** RDFFIR[19]
* Mainline read IMPE
*/
- (rRDFFIR, bit(19)) ? defaultMaskedError;
+ (rRDFFIR, bit(19)) ? memory_impe_handling;
/** RDFFIR[20:27]
* Maintenance MPE
@@ -1052,7 +1139,7 @@ group gRDFFIR
/** RDFFIR[33]
* Maintenance AUE
*/
- (rRDFFIR, bit(33)) ? defaultMaskedError;
+ (rRDFFIR, bit(33)) ? maintenance_aue_handling;
/** RDFFIR[34]
* Maintenance UE
@@ -1062,72 +1149,72 @@ group gRDFFIR
/** RDFFIR[35]
* Maintenance RCD
*/
- (rRDFFIR, bit(35)) ? defaultMaskedError;
+ (rRDFFIR, bit(35)) ? rdf_rcd_parity_error_UERE;
/** RDFFIR[36]
* Maintenance IAUE
*/
- (rRDFFIR, bit(36)) ? defaultMaskedError;
+ (rRDFFIR, bit(36)) ? maintenance_iaue_handling;
/** RDFFIR[37]
* Maintenance IUE
*/
- (rRDFFIR, bit(37)) ? defaultMaskedError;
+ (rRDFFIR, bit(37)) ? maintenance_iue_handling;
/** RDFFIR[38]
- * Maintenance IRCD
+ * Maintenance IRCD
*/
(rRDFFIR, bit(38)) ? defaultMaskedError;
/** RDFFIR[39]
* Maintenance IMPE
*/
- (rRDFFIR, bit(39)) ? defaultMaskedError;
+ (rRDFFIR, bit(39)) ? memory_impe_handling;
/** RDFFIR[40]
* RDDATA valid error
*/
- (rRDFFIR, bit(40)) ? defaultMaskedError;
+ (rRDFFIR, bit(40)) ? mem_port_th_32perDay;
/** RDFFIR[41]
* SCOM status register parity error
*/
- (rRDFFIR, bit(41)) ? defaultMaskedError;
+ (rRDFFIR, bit(41)) ? threshold_and_mask_mem_port;
/** RDFFIR[42]
* SCOM recoverable register parity error
*/
- (rRDFFIR, bit(42)) ? defaultMaskedError;
+ (rRDFFIR, bit(42)) ? mem_port_th_1;
/** RDFFIR[43]
* SCOM unrecoverable register parity error
*/
- (rRDFFIR, bit(43)) ? defaultMaskedError;
+ (rRDFFIR, bit(43)) ? mem_port_th_1;
/** RDFFIR[44]
* ECC corrector internal parity error
*/
- (rRDFFIR, bit(44)) ? defaultMaskedError;
+ (rRDFFIR, bit(44)) ? mem_port_th_1;
/** RDFFIR[45]
* Rd Buff ECC CHK Cor CE DW0 Detected
*/
- (rRDFFIR, bit(45)) ? defaultMaskedError;
+ (rRDFFIR, bit(45)) ? mem_port_th_32perDay;
/** RDFFIR[46]
* Rd Buff ECC CHK Cor CE DW1 Detected
*/
- (rRDFFIR, bit(46)) ? defaultMaskedError;
+ (rRDFFIR, bit(46)) ? mem_port_th_32perDay;
/** RDFFIR[47]
* Rd Buff ECC CHK Cor UE DW0 Detected
*/
- (rRDFFIR, bit(47)) ? defaultMaskedError;
+ (rRDFFIR, bit(47)) ? mem_port_th_1;
/** RDFFIR[48]
* Rd Buff ECC CHK Cor UE DW1 Detected
*/
- (rRDFFIR, bit(48)) ? defaultMaskedError;
+ (rRDFFIR, bit(48)) ? mem_port_th_1;
/** RDFFIR[49:59]
* Reserved
@@ -1177,67 +1264,67 @@ group gTLXFIR
/** TLXFIR[0]
* Info reg parity error
*/
- (rTLXFIR, bit(0)) ? defaultMaskedError;
+ (rTLXFIR, bit(0)) ? threshold_and_mask_self;
/** TLXFIR[1]
* Ctrl reg parity error
*/
- (rTLXFIR, bit(1)) ? defaultMaskedError;
+ (rTLXFIR, bit(1)) ? self_th_1;
/** TLXFIR[2]
* TLX VC0 return credit counter overflow
*/
- (rTLXFIR, bit(2)) ? defaultMaskedError;
+ (rTLXFIR, bit(2)) ? omi_bus_th_1;
/** TLXFIR[3]
* TLX VC1 return credit counter overflow
*/
- (rTLXFIR, bit(3)) ? defaultMaskedError;
+ (rTLXFIR, bit(3)) ? omi_bus_th_1;
/** TLXFIR[4]
* TLX dcp0 return credit counter overflow
*/
- (rTLXFIR, bit(4)) ? defaultMaskedError;
+ (rTLXFIR, bit(4)) ? omi_bus_th_1;
/** TLXFIR[5]
* TLX dcp1 return credit counter overflow
*/
- (rTLXFIR, bit(5)) ? defaultMaskedError;
+ (rTLXFIR, bit(5)) ? omi_bus_th_1;
/** TLXFIR[6]
* TLX credit management block error
*/
- (rTLXFIR, bit(6)) ? defaultMaskedError;
+ (rTLXFIR, bit(6)) ? self_th_1;
/** TLXFIR[7]
* TLX credit management block parity error
*/
- (rTLXFIR, bit(7)) ? defaultMaskedError;
+ (rTLXFIR, bit(7)) ? self_th_1;
/** TLXFIR[8]
* TLXT fatal parity error
*/
- (rTLXFIR, bit(8)) ? defaultMaskedError;
+ (rTLXFIR, bit(8)) ? self_th_1;
/** TLXFIR[9]
* TLXT recoverable error
*/
- (rTLXFIR, bit(9)) ? defaultMaskedError;
+ (rTLXFIR, bit(9)) ? analyzeTLXERR1;
/** TLXFIR[10]
* TLXT configuration error
*/
- (rTLXFIR, bit(10)) ? defaultMaskedError;
+ (rTLXFIR, bit(10)) ? level2_M_self_L_th_1;
/** TLXFIR[11]
* TLXT informational parity error
*/
- (rTLXFIR, bit(11)) ? defaultMaskedError;
+ (rTLXFIR, bit(11)) ? self_th_1;
/** TLXFIR[12]
* TLXT hard error
*/
- (rTLXFIR, bit(12)) ? defaultMaskedError;
+ (rTLXFIR, bit(12)) ? self_th_1;
/** TLXFIR[13:15]
* Reserved
@@ -1257,47 +1344,47 @@ group gTLXFIR
/** TLXFIR[18]
* OC malformed
*/
- (rTLXFIR, bit(18)) ? defaultMaskedError;
+ (rTLXFIR, bit(18)) ? omi_bus_th_1;
/** TLXFIR[19]
* OC protocol error
*/
- (rTLXFIR, bit(19)) ? defaultMaskedError;
+ (rTLXFIR, bit(19)) ? omi_th_1;
/** TLXFIR[20]
* Address translate error
*/
- (rTLXFIR, bit(20)) ? defaultMaskedError;
+ (rTLXFIR, bit(20)) ? self_th_1;
/** TLXFIR[21]
* Metadata unc or data parity error
*/
- (rTLXFIR, bit(21)) ? defaultMaskedError;
+ (rTLXFIR, bit(21)) ? self_th_1;
/** TLXFIR[22]
* OC unsupported group 2
*/
- (rTLXFIR, bit(22)) ? defaultMaskedError;
+ (rTLXFIR, bit(22)) ? omi_bus_th_1;
/** TLXFIR[23]
* OC unsupported group 1
*/
- (rTLXFIR, bit(23)) ? defaultMaskedError;
+ (rTLXFIR, bit(23)) ? omi_bus_th_1;
/** TLXFIR[24]
* Bit flip control error
*/
- (rTLXFIR, bit(24)) ? defaultMaskedError;
+ (rTLXFIR, bit(24)) ? self_th_1;
/** TLXFIR[25]
* Control HW error
*/
- (rTLXFIR, bit(25)) ? defaultMaskedError;
+ (rTLXFIR, bit(25)) ? self_th_1;
/** TLXFIR[26]
* ECC corrected and others
*/
- (rTLXFIR, bit(26)) ? defaultMaskedError;
+ (rTLXFIR, bit(26)) ? self_th_32perDay;
/** TLXFIR[27]
* Trace stop
@@ -1316,6 +1403,37 @@ group gTLXFIR
};
+rule rTLX_ERR1_REPORT
+{
+ RECOVERABLE:
+ TLX_ERR1_REPORT & ~TLX_ERR1_REPORT_MASK;
+};
+
+group gTLX_ERR1_REPORT
+ filter singlebit,
+ cs_root_cause
+{
+ /** TLX_ERR1_REPORT[37]
+ * TLXT FIFO CE
+ */
+ (rTLXFIR, bit(37)) ? self_th_32perDay;
+
+ /** TLX_ERR1_REPORT[39]
+ * Unexpected Interrupt Response
+ */
+ (rTLXFIR, bit(39)) ? parent_proc_th_32perDay;
+
+ /** TLX_ERR1_REPORT[40]
+ * BDI Poisoned
+ */
+ (rTLXFIR, bit(40)) ? self_th_1;
+
+ /** TLX_ERR1_REPORT[41]
+ * TLXT Metadata UE
+ */
+ (rTLXFIR, bit(41)) ? self_th_1;
+};
+
################################################################################
# Explorer chip OMIDLFIR
################################################################################
@@ -1335,112 +1453,112 @@ group gOMIDLFIR
cs_root_cause
{
/** OMIDLFIR[0]
- * DL0 fatal error
+ * OMI-DL0 fatal error
*/
- (rOMIDLFIR, bit(0)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(0)) ? dl_fatal_error;
/** OMIDLFIR[1]
- * Dl0 data UE
+ * OMI-DL0 UE on data flit
*/
- (rOMIDLFIR, bit(1)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(1)) ? self_th_1;
/** OMIDLFIR[2]
- * Dl0 flit CE
+ * OMI-DL0 CE on TL flit
*/
- (rOMIDLFIR, bit(2)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(2)) ? self_th_32perDay;
/** OMIDLFIR[3]
- * Dl0 CRC error
+ * OMI-DL0 detected a CRC error
*/
(rOMIDLFIR, bit(3)) ? defaultMaskedError;
/** OMIDLFIR[4]
- * DL0 nack
+ * OMI-DL0 received a nack
*/
(rOMIDLFIR, bit(4)) ? defaultMaskedError;
/** OMIDLFIR[5]
- * DL0 X4 mode
+ * OMI-DL0 running in degraded mode
*/
- (rOMIDLFIR, bit(5)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(5)) ? omi_bus_th_1;
/** OMIDLFIR[6]
- * DL0 EDPL
+ * OMI-DL0 parity error detection on a lane
*/
(rOMIDLFIR, bit(6)) ? defaultMaskedError;
/** OMIDLFIR[7]
- * DL0 timeout
+ * OMI-DL0 retrained due to no forward progress
*/
- (rOMIDLFIR, bit(7)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(7)) ? omi_bus_th_32perDay;
/** OMIDLFIR[8]
- * DL0 remote retrain
+ * OMI-DL0 remote side initiated a retrain
*/
(rOMIDLFIR, bit(8)) ? defaultMaskedError;
/** OMIDLFIR[9]
- * DL0 error retrain
+ * OMI-DL0 retrain due to internal error or software initiated
*/
- (rOMIDLFIR, bit(9)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(9)) ? omi_bus_th_32perDay;
/** OMIDLFIR[10]
- * DL0 EDPL retrain
+ * OMI-DL0 threshold reached
*/
- (rOMIDLFIR, bit(10)) ? defaultMaskedError;
+ (rOMIDLFIR, bit(10)) ? omi_bus_th_32perDay;
/** OMIDLFIR[11]
- * DL0 trained
+ * OMI-DL0 trained
*/
(rOMIDLFIR, bit(11)) ? defaultMaskedError;
/** OMIDLFIR[12]
- * DL0 endpoint bit 0
+ * OMI-DL0 endpoint error bit 0
*/
(rOMIDLFIR, bit(12)) ? defaultMaskedError;
/** OMIDLFIR[13]
- * DL0 endpoint bit 1
+ * OMI-DL0 endpoint error bit 1
*/
(rOMIDLFIR, bit(13)) ? defaultMaskedError;
/** OMIDLFIR[14]
- * DL0 endpoint bit 2
+ * OMI-DL0 endpoint error bit 2
*/
(rOMIDLFIR, bit(14)) ? defaultMaskedError;
/** OMIDLFIR[15]
- * DL0 endpoint bit 3
+ * OMI-DL0 endpoint error bit 3
*/
(rOMIDLFIR, bit(15)) ? defaultMaskedError;
/** OMIDLFIR[16]
- * DL0 endpoint bit 4
+ * OMI-DL0 endpoint error bit 4
*/
(rOMIDLFIR, bit(16)) ? defaultMaskedError;
/** OMIDLFIR[17]
- * DL0 endpoint bit 5
+ * OMI-DL0 endpoint error bit 5
*/
(rOMIDLFIR, bit(17)) ? defaultMaskedError;
/** OMIDLFIR[18]
- * DL0 endpoint bit 6
+ * OMI-DL0 endpoint error bit 6
*/
(rOMIDLFIR, bit(18)) ? defaultMaskedError;
/** OMIDLFIR[19]
- * DL0 endpoint bit 7
+ * OMI-DL0 endpoint error bit 7
*/
(rOMIDLFIR, bit(19)) ? defaultMaskedError;
/** OMIDLFIR[20:39]
- * DL1 reserved
+ * OMI-DL1 reserved
*/
(rOMIDLFIR, bit(20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39)) ? defaultMaskedError;
/** OMIDLFIR[40:59]
- * DL2 reserved
+ * OMI-DL2 reserved
*/
(rOMIDLFIR, bit(40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59)) ? defaultMaskedError;
@@ -1449,6 +1567,21 @@ group gOMIDLFIR
*/
(rOMIDLFIR, bit(60)) ? defaultMaskedError;
+ /** OMIDLFIR[61]
+ * reserved
+ */
+ (rOMIDLFIR, bit(61)) ? defaultMaskedError;
+
+ /** OMIDLFIR[62]
+ * LFIR internal parity error
+ */
+ (rOMIDLFIR, bit(62)) ? defaultMaskedError;
+
+ /** OMIDLFIR[63]
+ * SCOM Satellite Error
+ */
+ (rOMIDLFIR, bit(63)) ? defaultMaskedError;
+
};
##############################################################################
@@ -1463,6 +1596,5 @@ group gOMIDLFIR
##############################################################################
# Include the actions defined for this target
-.include "p9_common_actions.rule";
.include "explorer_ocmb_actions.rule";
diff --git a/src/usr/diag/prdf/common/plat/explorer/explorer_ocmb_actions.rule b/src/usr/diag/prdf/common/plat/explorer/explorer_ocmb_actions.rule
index 023821b0d..d5b6e3fad 100644
--- a/src/usr/diag/prdf/common/plat/explorer/explorer_ocmb_actions.rule
+++ b/src/usr/diag/prdf/common/plat/explorer/explorer_ocmb_actions.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -55,22 +55,12 @@ actionclass threshold32pday
threshold( field(32 / day) );
};
-################################################################################
-# Threshold and Mask policy
-################################################################################
-
-/**
- * Threshold 32/day (field) and 1 (mnfg). Do not predictively callout on
- * threshold in the field, instead just mask.
- */
-actionclass threshold_and_mask
+/** Threshold of 5 per day */
+actionclass threshold5pday
{
- threshold32pday;
- funccall("ClearServiceCallFlag");
+ threshold( field(5 / day) );
};
-actionclass threshold_and_mask_self { calloutSelfMed; threshold_and_mask; };
-
################################################################################
# Special Flags #
################################################################################
@@ -99,6 +89,50 @@ actionclass callout2ndLvlMed
actionclass calloutSelfLowNoGard
{ callout(MRU_LOW, NO_GARD); };
+actionclass level2_M_self_L
+{
+ callout2ndLvlMed;
+ calloutSelfLow;
+};
+
+actionclass omi
+{
+ callout(connected(TYPE_OMI), MRU_MED);
+};
+
+actionclass omi_bus
+{
+ calloutSelfMedA;
+ callout(connected(TYPE_OMI), MRU_MEDA);
+ funccall("calloutBusInterfacePlugin");
+};
+
+actionclass mem_port
+{
+ callout(connected(TYPE_MEM_PORT,0), MRU_MED);
+};
+
+actionclass mem_port_L
+{
+ callout(connected(TYPE_MEM_PORT,0), MRU_LOW);
+};
+
+actionclass all_dimm_H
+{
+ funccall("CalloutAttachedDimmsHigh");
+};
+
+actionclass all_dimm_H_memport_L
+{
+ all_dimm_H;
+ mem_port_L;
+};
+
+actionclass parent_proc
+{
+ callout(connected(TYPE_PROC), MRU_MED);
+};
+
################################################################################
# Callouts with thresholds #
################################################################################
@@ -109,15 +143,15 @@ actionclass self_th_1
threshold1;
};
-actionclass self_th_5perHour
+actionclass self_th_32perDay
{
calloutSelfMed;
- threshold5phour;
+ threshold32pday;
};
-actionclass self_th_32perDay
+actionclass parent_proc_th_32perDay
{
- calloutSelfMed;
+ parent_proc;
threshold32pday;
};
@@ -127,12 +161,83 @@ actionclass level2_th_1
threshold1;
};
+actionclass level2_th_32perDay
+{
+ callout2ndLvlMed;
+ threshold32pday;
+};
+
+actionclass level2_M_self_L_th_1
+{
+ level2_M_self_L;
+ threshold1;
+};
+
+actionclass omi_th_1
+{
+ omi;
+ threshold1;
+};
+
+actionclass omi_bus_th_1
+{
+ omi_bus;
+ threshold1;
+};
+
+actionclass omi_bus_th_32perDay
+{
+ omi_bus;
+ threshold32pday;
+};
+
+actionclass mem_port_th_1
+{
+ mem_port;
+ threshold1;
+};
+
+actionclass mem_port_th_32perDay
+{
+ mem_port;
+ threshold32pday;
+};
+
+################################################################################
+# Special #
+################################################################################
+
+/**
+ * Threshold 32/day (field) and 1 (mnfg). Do not predictively callout on
+ * threshold in the field, instead just mask.
+ */
+actionclass threshold_and_mask
+{
+ threshold32pday;
+ funccall("ClearServiceCallFlag");
+};
+
+actionclass threshold_and_mask_self { calloutSelfMed; threshold_and_mask; };
+
+actionclass threshold_and_mask_level2
+{
+ level2_th_32perDay;
+ threshold_and_mask;
+};
+
+actionclass threshold_and_mask_mem_port
+{
+ mem_port_th_32perDay;
+ threshold_and_mask;
+};
+
################################################################################
# Callouts with flags #
################################################################################
-actionclass self_th_1_UERE { self_th_1; SueSource; };
-actionclass level2_th_1_UERE { level2_th_1; SueSource; };
+actionclass self_th_1_UERE { self_th_1; SueSource; };
+actionclass level2_th_1_UERE { level2_th_1; SueSource; };
+actionclass mem_port_th_1_UERE { mem_port_th_1; SueSource; };
################################################################################
# Default callouts #
@@ -153,14 +258,166 @@ actionclass TBDDefaultCallout
};
################################################################################
+# OCMB Actions #
+################################################################################
+
+/** DDR4 PHY Interrupt */
+actionclass ddr4_phy_interrupt
+{
+ calloutSelfHigh;
+ threshold5pday;
+ funccall("Ddr4PhyInterrupt");
+};
+
+/** Foxhound Fatal */
+actionclass foxhound_fatal
+{
+ funccall("FoxhoundFatal");
+ threshold1;
+};
+
+/** OMI-DL Fatal Error */
+actionclass dl_fatal_error
+{
+ try( funccall("DlFatalError"), omi_bus );
+ threshold1;
+};
+
+/** MCBIST program complete */
+actionclass mcbist_program_complete
+{
+ funccall("McbistCmdComplete");
+};
+
+/** Verify Chip Mark */
+actionclass verify_chip_mark_0 { funccall("AnalyzeFetchMpe_0"); };
+actionclass verify_chip_mark_1 { funccall("AnalyzeFetchMpe_1"); };
+actionclass verify_chip_mark_2 { funccall("AnalyzeFetchMpe_2"); };
+actionclass verify_chip_mark_3 { funccall("AnalyzeFetchMpe_3"); };
+actionclass verify_chip_mark_4 { funccall("AnalyzeFetchMpe_4"); };
+actionclass verify_chip_mark_5 { funccall("AnalyzeFetchMpe_5"); };
+actionclass verify_chip_mark_6 { funccall("AnalyzeFetchMpe_6"); };
+actionclass verify_chip_mark_7 { funccall("AnalyzeFetchMpe_7"); };
+
+/** Mainline NCE/TCE handling */
+actionclass mainline_nce_tce_handling
+{
+ funccall("AnalyzeFetchNceTce");
+};
+
+/** Handle Mainline AUEs/IAUEs */
+actionclass mainline_aue_iaue_handling
+{
+ funccall("AnalyzeFetchAueIaue");
+ mem_port_L;
+ threshold1;
+};
+
+/** Mainline UE handling */
+actionclass mainline_ue_handling
+{
+ threshold( field(33 / 30 min ) ); # To prevent flooding. Will be unmasked
+ # when background scrubbing resumes after
+ # targeted diagnostics is complete.
+ funccall("AnalyzeFetchUe");
+};
+
+actionclass mainline_ue_handling_UERE
+{
+ SueSource;
+ mainline_ue_handling;
+};
+
+/** Handle Mainline IUEs */
+actionclass mainline_iue_handling
+{
+ # An IUE itself is not a SUE source, however, a threshold of IUEs will
+ # trigger a port failure, which will generate SUEs. The port failure could
+ # also crash the machine so we want to make sure this bit is flagged as an
+ # SUE just in case it is needed in the checkstop analysis.
+ SueSource;
+ # Thresholding done in the plugin
+ funccall("AnalyzeMainlineIue");
+};
+
+/** Handle Maintenance IUEs */
+actionclass maintenance_iue_handling
+{
+ # An IUE itself is not a SUE source, however, a threshold of IUEs will
+ # trigger a port failure, which will generate SUEs. The port failure could
+ # also crash the machine so we want to make sure this bit is flagged as an
+ # SUE just in case it is needed in the checkstop analysis.
+ SueSource;
+ # Thresholding done in the plugin
+ funccall("AnalyzeMaintIue");
+};
+
+actionclass memory_impe_handling
+{
+ funccall("AnalyzeImpe");
+};
+
+/** Handle Maintenance AUEs */
+actionclass maintenance_aue_handling
+{
+ funccall("AnalyzeMaintAue");
+ mem_port_L;
+ threshold1;
+};
+
+/** Handle Maintenance IAUEs */
+actionclass maintenance_iaue_handling
+{
+ all_dimm_H_memport_L;
+ threshold1;
+};
+
+/** RDF RCD Parity Error */
+actionclass rdf_rcd_parity_error
+{
+ funccall("RdfRcdParityError");
+ threshold1;
+};
+
+actionclass rdf_rcd_parity_error_UERE
+{
+ rdf_rcd_parity_error;
+ SueSource;
+};
+
+/** SRQ RCD Parity Error */
+actionclass srq_rcd_parity_error
+{
+ all_dimm_H_memport_L;
+ threshold32pday;
+};
+
+actionclass srq_rcd_parity_error_UERE
+{
+ srq_rcd_parity_error;
+ SueSource;
+};
+
+actionclass mem_port_failure
+{
+ all_dimm_H_memport_L;
+ threshold1; # Threshold 1
+};
+
+################################################################################
# Analyze groups
################################################################################
-actionclass analyzeMB_LFIR { analyze(gMB_LFIR); };
+actionclass analyzeOCMB_LFIR { analyze(gOCMB_LFIR); };
actionclass analyzeMMIOFIR { analyze(gMMIOFIR); };
actionclass analyzeSRQFIR { analyze(gSRQFIR); };
actionclass analyzeMCBISTFIR { analyze(gMCBISTFIR); };
actionclass analyzeRDFFIR { analyze(gRDFFIR); };
actionclass analyzeTLXFIR { analyze(gTLXFIR); };
+actionclass analyzeTLXERR1
+{
+ analyze(gTLX_ERR1_REPORT);
+ funccall("clearAndMaskTlxtRe");
+};
actionclass analyzeOMIDLFIR { analyze(gOMIDLFIR); };
diff --git a/src/usr/diag/prdf/common/plat/explorer/explorer_ocmb_regs.rule b/src/usr/diag/prdf/common/plat/explorer/explorer_ocmb_regs.rule
index a4a526124..c2205f2dd 100644
--- a/src/usr/diag/prdf/common/plat/explorer/explorer_ocmb_regs.rule
+++ b/src/usr/diag/prdf/common/plat/explorer/explorer_ocmb_regs.rule
@@ -223,3 +223,259 @@
capture group never;
access write_only;
};
+
+ ############################################################################
+ # P9 Hardware Mark Stores
+ ############################################################################
+
+ register HW_MS0
+ {
+ name "P9 Hardware Mark Store rank 0";
+ scomaddr 0x08011C10;
+ capture group default;
+ };
+
+ register HW_MS1
+ {
+ name "P9 Hardware Mark Store rank 1";
+ scomaddr 0x08011C11;
+ capture group default;
+ };
+
+ register HW_MS2
+ {
+ name "P9 Hardware Mark Store rank 2";
+ scomaddr 0x08011C12;
+ capture group default;
+ };
+
+ register HW_MS3
+ {
+ name "P9 Hardware Mark Store rank 3";
+ scomaddr 0x08011C13;
+ capture group default;
+ };
+
+ register HW_MS4
+ {
+ name "P9 Hardware Mark Store rank 4";
+ scomaddr 0x08011C14;
+ capture group default;
+ };
+
+ register HW_MS5
+ {
+ name "P9 Hardware Mark Store rank 5";
+ scomaddr 0x08011C15;
+ capture group default;
+ };
+
+ register HW_MS6
+ {
+ name "P9 Hardware Mark Store rank 6";
+ scomaddr 0x08011C16;
+ capture group default;
+ };
+
+ register HW_MS7
+ {
+ name "P9 Hardware Mark Store rank 7";
+ scomaddr 0x08011C17;
+ capture group default;
+ };
+
+ ############################################################################
+ # P9 Firmware Mark Stores
+ ############################################################################
+
+ register FW_MS0
+ {
+ name "P9 Firmware Mark Store 0";
+ scomaddr 0x08011C18;
+ capture group default;
+ };
+
+ register FW_MS1
+ {
+ name "P9 Firmware Mark Store 1";
+ scomaddr 0x08011C19;
+ capture group default;
+ };
+
+ register FW_MS2
+ {
+ name "P9 Firmware Mark Store 2";
+ scomaddr 0x08011C1A;
+ capture group default;
+ };
+
+ register FW_MS3
+ {
+ name "P9 Firmware Mark Store 3";
+ scomaddr 0x08011C1B;
+ capture group default;
+ };
+
+ register FW_MS4
+ {
+ name "P9 Firmware Mark Store 4";
+ scomaddr 0x08011C1C;
+ capture group default;
+ };
+
+ register FW_MS5
+ {
+ name "P9 Firmware Mark Store 5";
+ scomaddr 0x08011C1D;
+ capture group default;
+ };
+
+ register FW_MS6
+ {
+ name "P9 Firmware Mark Store 6";
+ scomaddr 0x08011C1E;
+ capture group default;
+ };
+
+ register FW_MS7
+ {
+ name "P9 Firmware Mark Store 7";
+ scomaddr 0x08011C1F;
+ capture group default;
+ };
+
+ ###########################################################################
+ # P9 OCMB target OMIDLFIR
+ ###########################################################################
+
+ register DL0_ERROR_HOLD
+ {
+ name "P9 OCMB target DL0 Error Hold Register";
+ scomaddr 0x08012813;
+ capture group default;
+ };
+
+ ###########################################################################
+ # P9 OCMB target TLXFIR
+ ###########################################################################
+
+ register TLXFIR_AND
+ {
+ name "Explorer chip TLXFIR AND";
+ scomaddr 0x08012401;
+ capture group never;
+ access write_only;
+ };
+
+ register TLXFIR_MASK_OR
+ {
+ name "Explorer chip TLXFIR MASK OR";
+ scomaddr 0x08012405;
+ capture group never;
+ access write_only;
+ };
+
+ register TLX_ERR1_REPORT
+ {
+ name "P9 OCMB target TLX Error Report Register";
+ scomaddr 0x0801241D;
+ reset (&, 0x0801241D);
+ mask (|, 0x08012415);
+ capture group default;
+ };
+
+ register TLX_ERR1_REPORT_MASK
+ {
+ name "P9 OCMB target TLX Error Report Register Mask";
+ scomaddr 0x08012415;
+ capture group default;
+ };
+
+ ############################################################################
+ # Explorer ECC Address Registers
+ ############################################################################
+
+ register MBNCER
+ {
+ name "Explorer Mainline NCE Address Trap Register";
+ scomaddr 0x0801186A;
+ capture group default;
+ };
+
+ register MBRCER
+ {
+ name "Explorer Mainline RCE Address Trap Register";
+ scomaddr 0x0801186B;
+ capture group default;
+ };
+
+ register MBMPER
+ {
+ name "Explorer Mainline MPE Address Trap Register";
+ scomaddr 0x0801186C;
+ capture group default;
+ };
+
+ register MBUER
+ {
+ name "Explorer Mainline UE Address Trap Register";
+ scomaddr 0x0801186D;
+ capture group default;
+ };
+
+ register MBAUER
+ {
+ name "Explorer Mainline AUE Address Trap Register";
+ scomaddr 0x0801186E;
+ capture group default;
+ };
+
+ ############################################################################
+ # Misc
+ ############################################################################
+
+ register FARB0
+ {
+ name "MB_SIM.SRQ.MBA_FARB0Q";
+ scomaddr 0x08011415;
+ capture group default;
+ };
+
+ register EXP_MSR
+ {
+ name "Explorer Mark Shadow Register";
+ scomaddr 0x08011C0C;
+ capture group default;
+ };
+
+ register MC_ADDR_TRANS
+ {
+ name "P9 OCMB target address translation register0";
+ scomaddr 0x0801186F;
+ capture group default;
+ };
+
+ register MC_ADDR_TRANS1
+ {
+ name "P9 OCMB target address translation register1";
+ scomaddr 0x08011870;
+ capture group default;
+ };
+
+ register MC_ADDR_TRANS2
+ {
+ name "P9 OCMB target address translation register2";
+ scomaddr 0x08011871;
+ capture group default;
+ };
+
+ ############################################################################
+ # Interrupt status register
+ ############################################################################
+
+ register INTER_STATUS_REG
+ {
+ name "TPTOP.PIB.PCBMS.INTERRUPT_TYPE_REG";
+ scomaddr 0x000F001A;
+ capture group default;
+ };
diff --git a/src/usr/diag/prdf/common/plat/explorer/prdfExplorerPlugins_common.C b/src/usr/diag/prdf/common/plat/explorer/prdfExplorerPlugins_common.C
new file mode 100644
index 000000000..de385aab9
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/explorer/prdfExplorerPlugins_common.C
@@ -0,0 +1,574 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/plat/explorer/prdfExplorerPlugins_common.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+// Framework includes
+#include <iipServiceDataCollector.h>
+#include <prdfExtensibleChip.H>
+#include <prdfPluginMap.H>
+
+// Platform includes
+#include <prdfMemDbUtils.H>
+#include <prdfMemEccAnalysis.H>
+#include <prdfMemUtils.H>
+#include <prdfPlatServices.H>
+
+using namespace TARGETING;
+
+namespace PRDF
+{
+
+using namespace PlatServices;
+
+namespace explorer_ocmb
+{
+
+//##############################################################################
+//
+// Special plugins
+//
+//##############################################################################
+
+/**
+ * @brief Plugin that initializes the data bundle.
+ * @param i_chip An OCMB chip.
+ * @return SUCCESS
+ */
+int32_t Initialize( ExtensibleChip * i_chip )
+{
+ i_chip->getDataBundle() = new OcmbDataBundle( i_chip );
+ return SUCCESS;
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, Initialize );
+
+/**
+ * @brief Plugin function called after analysis is complete but before PRD
+ * exits.
+ * @param i_chip An OCMB chip.
+ * @param io_sc The step code data struct.
+ * @note This is especially useful for any analysis that still needs to be
+ * done after the framework clears the FIR bits that were at attention.
+ * @return SUCCESS.
+ */
+int32_t PostAnalysis( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[explorer_ocmb::PostAnalysis] "
+
+ #ifdef __HOSTBOOT_RUNTIME
+
+ // If the IUE threshold in our data bundle has been reached, we trigger
+ // a port fail. Once we trigger the port fail, the system may crash
+ // right away. Since PRD is running in the hypervisor, it is possible we
+ // may not get the error log. To better our chances, we trigger the port
+ // fail here after the error log has been committed.
+ if ( MemEcc::queryIueTh<TYPE_OCMB_CHIP>(i_chip, io_sc) )
+ {
+ if ( SUCCESS != MemEcc::triggerPortFail<TYPE_OCMB_CHIP>(i_chip) )
+ {
+ PRDF_ERR( PRDF_FUNC "triggerPortFail(0x%08x) failed",
+ i_chip->getHuid() );
+ }
+ }
+
+ #endif // __HOSTBOOT_RUNTIME
+
+ // Cleanup processor FIR bits on the other side of the channel.
+ MemUtils::cleanupChnlAttns<TYPE_OCMB_CHIP>( i_chip, io_sc );
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, PostAnalysis );
+
+
+//##############################################################################
+//
+// OCMB_LFIR
+//
+//##############################################################################
+
+/**
+ * @brief OCMB_LFIR[38] - DDR4 PHY interrupt
+ * @param i_chip An OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return SUCCESS
+ */
+int32_t Ddr4PhyInterrupt( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[explorer_ocmb::Ddr4PhyInterrupt] "
+
+ SCAN_COMM_REGISTER_CLASS * rdffir = i_chip->getRegister( "RDFFIR" );
+
+ // If Mainline UE (RDFFIR[14]) or Maint UE (RDFFIR[34]) are on at the same
+ // time as this:
+ if ( rdffir->IsBitSet(14) || rdffir->IsBitSet(34) )
+ {
+ // callout Explorer on 1st
+ io_sc.service_data->SetThresholdMaskId(0);
+
+ // mask maint and mainline UE which are assumed to be side-effects
+ SCAN_COMM_REGISTER_CLASS * rdffir_mask_or =
+ i_chip->getRegister( "RDFFIR_MASK_OR" );
+
+ rdffir_mask_or->SetBit(14);
+ rdffir_mask_or->SetBit(34);
+
+ if ( SUCCESS != rdffir_mask_or->Write() )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() failed on RDFFIR_MASK_OR: 0x%08x",
+ i_chip->getHuid() );
+ }
+ }
+ else
+ {
+ //TODO RTC 200583
+ // callout Explorer on threshold (5/day)
+ // NOTE: in this case we will have to clear both hw driven checkers
+ // manually before clearing the FIR
+ }
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, Ddr4PhyInterrupt );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief OCMB_LFIR[39:46] - Foxhound Fatal
+ * @param i_chip An OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return SUCCESS
+ */
+int32_t FoxhoundFatal( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[explorer_ocmb::FoxhoundFatal] "
+
+ //TODO RTC 200583
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, FoxhoundFatal );
+
+//##############################################################################
+//
+// OMIDLFIR
+//
+//##############################################################################
+
+/**
+ * @brief OMIDLFIR[0] - OMI-DL0 Fatal Error
+ * @param i_chip An OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return PRD_SCAN_COMM_REGISTER_ZERO for the bus callout, else SUCCESS
+ */
+int32_t DlFatalError( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[explorer_ocmb::DlFatalError] "
+
+ int32_t rc = SUCCESS;
+
+ do
+ {
+ // Check DL0_ERROR_HOLD[52:63] to determine callout
+ SCAN_COMM_REGISTER_CLASS * dl0_error_hold =
+ i_chip->getRegister( "DL0_ERROR_HOLD" );
+
+ if ( SUCCESS != dl0_error_hold->Read() )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() Failed on DL0_ERROR_HOLD: "
+ "i_chip=0x%08x", i_chip->getHuid() );
+ break;
+ }
+
+ if ( dl0_error_hold->IsBitSet(53) ||
+ dl0_error_hold->IsBitSet(55) ||
+ dl0_error_hold->IsBitSet(57) ||
+ dl0_error_hold->IsBitSet(58) ||
+ dl0_error_hold->IsBitSet(59) ||
+ dl0_error_hold->IsBitSet(60) ||
+ dl0_error_hold->IsBitSet(62) ||
+ dl0_error_hold->IsBitSet(63) )
+ {
+ // callout OCMB
+ io_sc.service_data->SetCallout( i_chip->getTrgt() );
+ }
+ else if ( dl0_error_hold->IsBitSet(54) ||
+ dl0_error_hold->IsBitSet(56) ||
+ dl0_error_hold->IsBitSet(61) )
+ {
+ // callout the OMI target, the OMI bus, and the OCMB.
+ // Return PRD_SCAN_COMM_REGISTER_ZERO so the rule code knows to
+ // make the correct callout.
+ rc = PRD_SCAN_COMM_REGISTER_ZERO;
+ }
+
+ }while(0);
+
+ return rc;
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, DlFatalError );
+
+//##############################################################################
+//
+// RDFFIR
+//
+//##############################################################################
+
+/**
+ * @brief Adds all attached DIMMs at HIGH priority.
+ * @param i_chip An OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return SUCCESS
+ */
+int32_t CalloutAttachedDimmsHigh( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ for ( auto & dimm : getConnected(i_chip->getTrgt(), TYPE_DIMM) )
+ io_sc.service_data->SetCallout( dimm, MRU_HIGH );
+
+ return SUCCESS; // nothing to return to rule code
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, CalloutAttachedDimmsHigh );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief RDF RCD Parity Error
+ * @param i_chip An OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return SUCCESS
+ */
+int32_t RdfRcdParityError( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[explorer_ocmb::RdfRcdParityError] "
+
+ do
+ {
+ SCAN_COMM_REGISTER_CLASS * rdffir = i_chip->getRegister( "RDFFIR" );
+ if ( SUCCESS != rdffir->Read() )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() Failed on RDFFIR: "
+ "i_chip=0x%08x", i_chip->getHuid() );
+ break;
+ }
+
+ // If RDFFIR[40] on at the same time, this is 'missing rddata valid'
+ // case, which returns SUE
+ if ( rdffir->IsBitSet(40) )
+ {
+ // callout MEM_PORT on 1st occurrence
+ TargetHandle_t memPort =
+ getConnectedChild( i_chip->getTrgt(), TYPE_MEM_PORT, 0 );
+ io_sc.service_data->SetCallout( memPort );
+ }
+ // Else this is 'confirmed RCD parity error' case
+ else
+ {
+ // callout DIMM high priority, MEM_PORT low on 1st occurrence
+ CalloutAttachedDimmsHigh( i_chip, io_sc );
+ TargetHandle_t memPort =
+ getConnectedChild( i_chip->getTrgt(), TYPE_MEM_PORT, 0 );
+ io_sc.service_data->SetCallout( memPort, MRU_LOW );
+ }
+
+ // Mask bit 40 as well
+ SCAN_COMM_REGISTER_CLASS * rdffir_mask_or =
+ i_chip->getRegister( "RDFFIR_MASK_OR" );
+
+ rdffir_mask_or->SetBit(40);
+ if ( SUCCESS != rdffir_mask_or->Write() )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() Failed on RDFFIR_MASK_OR: "
+ "i_chip=0x%08x", i_chip->getHuid() );
+ break;
+ }
+
+ }while(0);
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, RdfRcdParityError );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief RDFFIR[0:7] - Mainline MPE.
+ * @param i_chip OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return SUCCESS
+ */
+#define PLUGIN_FETCH_MPE_ERROR( RANK ) \
+int32_t AnalyzeFetchMpe_##RANK( ExtensibleChip * i_chip, \
+ STEP_CODE_DATA_STRUCT & io_sc ) \
+{ \
+ MemRank rank ( RANK ); \
+ MemEcc::analyzeFetchMpe<TYPE_OCMB_CHIP>( i_chip, rank, io_sc ); \
+ return SUCCESS; \
+} \
+PRDF_PLUGIN_DEFINE( explorer_ocmb, AnalyzeFetchMpe_##RANK );
+
+PLUGIN_FETCH_MPE_ERROR( 0 )
+PLUGIN_FETCH_MPE_ERROR( 1 )
+PLUGIN_FETCH_MPE_ERROR( 2 )
+PLUGIN_FETCH_MPE_ERROR( 3 )
+PLUGIN_FETCH_MPE_ERROR( 4 )
+PLUGIN_FETCH_MPE_ERROR( 5 )
+PLUGIN_FETCH_MPE_ERROR( 6 )
+PLUGIN_FETCH_MPE_ERROR( 7 )
+
+#undef PLUGIN_FETCH_MPE_ERROR
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief RDFFIR[8:9] - Mainline NCE and/or TCE.
+ * @param i_chip OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return SUCCESS
+ */
+int32_t AnalyzeFetchNceTce( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ MemEcc::analyzeFetchNceTce<TYPE_OCMB_CHIP>( i_chip, io_sc );
+ return SUCCESS; // nothing to return to rule code
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, AnalyzeFetchNceTce );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief RDFFIR[14] - Mainline UE.
+ * @param i_chip OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return SUCCESS
+ */
+int32_t AnalyzeFetchUe( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ MemEcc::analyzeFetchUe<TYPE_OCMB_CHIP>( i_chip, io_sc );
+ return SUCCESS; // nothing to return to rule code
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, AnalyzeFetchUe );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief RDFFIR[17] - Mainline read IUE.
+ * @param i_chip OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return PRD_NO_CLEAR_FIR_BITS if IUE threshold is reached, else SUCCESS.
+ */
+int32_t AnalyzeMainlineIue( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ int32_t rc = SUCCESS;
+ MemEcc::analyzeMainlineIue<TYPE_OCMB_CHIP>( i_chip, io_sc );
+
+ #ifdef __HOSTBOOT_MODULE
+
+ if ( MemEcc::queryIueTh<TYPE_OCMB_CHIP>(i_chip, io_sc) )
+ rc = PRD_NO_CLEAR_FIR_BITS;
+
+ #endif
+
+ return rc; // nothing to return to rule code
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, AnalyzeMainlineIue );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief RDFFIR[37] - Maint IUE.
+ * @param i_chip OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return PRD_NO_CLEAR_FIR_BITS if IUE threshold is reached, else SUCCESS.
+ */
+int32_t AnalyzeMaintIue( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ int32_t rc = SUCCESS;
+ MemEcc::analyzeMaintIue<TYPE_OCMB_CHIP>( i_chip, io_sc );
+
+ #ifdef __HOSTBOOT_MODULE
+
+ if ( MemEcc::queryIueTh<TYPE_OCMB_CHIP>(i_chip, io_sc) )
+ rc = PRD_NO_CLEAR_FIR_BITS;
+
+ #endif
+
+ return rc; // nothing to return to rule code
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, AnalyzeMaintIue );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief RDFFIR[19,39] - Mainline and Maint IMPE
+ * @param i_chip OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return SUCCESS
+ */
+int32_t AnalyzeImpe( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc )
+{
+ MemEcc::analyzeImpe<TYPE_OCMB_CHIP>( i_chip, io_sc );
+ return SUCCESS; // nothing to return to rule code
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, AnalyzeImpe );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief RDFFIR[13,16] - Mainline AUE and IAUE
+ * @param i_chip OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return SUCCESS
+ */
+int32_t AnalyzeFetchAueIaue( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[explorer_ocmb::AnalyzeFetchAueIaue] "
+
+ MemAddr addr;
+ if ( SUCCESS != getMemReadAddr<TYPE_OCMB_CHIP>(i_chip,
+ MemAddr::READ_AUE_ADDR,
+ addr) )
+ {
+ PRDF_ERR( PRDF_FUNC "getMemReadAddr(0x%08x,READ_AUE_ADDR) failed",
+ i_chip->getHuid() );
+ }
+ else
+ {
+ MemRank rank = addr.getRank();
+ MemoryMru mm { i_chip->getTrgt(), rank, MemoryMruData::CALLOUT_RANK };
+ io_sc.service_data->SetCallout( mm, MRU_HIGH );
+ }
+
+ return SUCCESS; // nothing to return to rule code
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, AnalyzeFetchAueIaue );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief RDFFIR[33] - Maintenance AUE
+ * @param i_chip OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return SUCCESS
+ */
+int32_t AnalyzeMaintAue( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[explorer_ocmb::AnalyzeMaintAue] "
+
+ MemAddr addr;
+ if ( SUCCESS != getMemMaintAddr<TYPE_OCMB_CHIP>(i_chip, addr) )
+ {
+ PRDF_ERR( PRDF_FUNC "getMemMaintAddr(0x%08x) failed",
+ i_chip->getHuid() );
+ }
+ else
+ {
+ MemRank rank = addr.getRank();
+ MemoryMru mm { i_chip->getTrgt(), rank, MemoryMruData::CALLOUT_RANK };
+ io_sc.service_data->SetCallout( mm, MRU_HIGH );
+ }
+
+ return SUCCESS; // nothing to return to rule code
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, AnalyzeMaintAue );
+
+
+//##############################################################################
+//
+// TLXFIR
+//
+//##############################################################################
+
+/**
+ * @brief Clear/Mask TLXFIR[9]
+ * @param i_chip An OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return SUCCESS
+ */
+int32_t clearAndMaskTlxtRe( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[explorer_ocmb::clearAndMaskTlxtRe] "
+
+ do
+ {
+ // If we are at threshold, mask TLXFIR[9].
+ if ( io_sc.service_data->IsAtThreshold() )
+ {
+ SCAN_COMM_REGISTER_CLASS * tlxfir_mask_or =
+ i_chip->getRegister( "TLXFIR_MASK_OR" );
+
+ tlxfir_mask_or->SetBit(9);
+ if ( SUCCESS != tlxfir_mask_or->Write() )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() Failed on TLXFIR_MASK_OR: "
+ "i_chip=0x%08x", i_chip->getHuid() );
+ break;
+ }
+ }
+
+ // Clear TLXFIR[9]
+ SCAN_COMM_REGISTER_CLASS * tlxfir_and =
+ i_chip->getRegister( "TLXFIR_AND" );
+ tlxfir_and->setAllBits();
+
+ tlxfir_and->ClearBit(9);
+ if ( SUCCESS != tlxfir_and->Write() )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() Failed on TLXFIR_AND: "
+ "i_chip=0x%08x", i_chip->getHuid() );
+ break;
+ }
+ }while(0);
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, clearAndMaskTlxtRe );
+
+} // end namespace explorer_ocmb
+
+} // end namespace PRDF
+
diff --git a/src/usr/diag/prdf/common/plat/explorer/prdf_plat_explorer.mk b/src/usr/diag/prdf/common/plat/explorer/prdf_plat_explorer.mk
new file mode 100644
index 000000000..b79d5cc30
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/explorer/prdf_plat_explorer.mk
@@ -0,0 +1,39 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/diag/prdf/common/plat/explorer/prdf_plat_explorer.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+################################################################################
+# Paths common to both FSP and Hostboot
+################################################################################
+
+prd_vpath += ${PRD_SRC_PATH}/common/plat/explorer
+
+prd_incpath += ${PRD_SRC_PATH}/common/plat/explorer
+
+################################################################################
+# Object files common to both FSP and Hostboot
+################################################################################
+
+# rule plugin related
+prd_rule_plugin += prdfExplorerPlugins_common.o
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemAddress.C b/src/usr/diag/prdf/common/plat/mem/prdfMemAddress.C
index 1227afeb8..654b39ba0 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemAddress.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemAddress.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -46,8 +46,8 @@ using namespace PlatServices;
// Class MemAddr
//------------------------------------------------------------------------------
-template<>
-MemAddr MemAddr::fromReadAddr<TYPE_MCBIST>( uint64_t i_addr )
+template<TARGETING::TYPE T>
+MemAddr MemAddr::fromReadAddr( uint64_t i_addr )
{
uint64_t mrnk = (i_addr >> 59) & 0x7; // 2: 4
uint64_t srnk = (i_addr >> 56) & 0x7; // 5: 7
@@ -58,6 +58,12 @@ MemAddr MemAddr::fromReadAddr<TYPE_MCBIST>( uint64_t i_addr )
return MemAddr( MemRank(mrnk, srnk), bnk, row, col );
}
+template
+MemAddr MemAddr::fromReadAddr<TYPE_MCBIST>( uint64_t i_addr );
+template
+MemAddr MemAddr::fromReadAddr<TYPE_OCMB_CHIP>( uint64_t i_addr );
+
+
template<>
MemAddr MemAddr::fromReadAddr<TYPE_MEMBUF>( uint64_t i_addr )
{
@@ -73,8 +79,8 @@ MemAddr MemAddr::fromReadAddr<TYPE_MEMBUF>( uint64_t i_addr )
return MemAddr( MemRank(mrnk, srnk), bnk, row, col );
}
-template<>
-MemAddr MemAddr::fromMaintAddr<TYPE_MCBIST>( uint64_t i_addr )
+template<TARGETING::TYPE T>
+MemAddr MemAddr::fromMaintAddr( uint64_t i_addr )
{
uint64_t rslct = (i_addr >> 59) & 0x3; // 3: 4
uint64_t srnk = (i_addr >> 56) & 0x7; // 5: 7
@@ -88,6 +94,12 @@ MemAddr MemAddr::fromMaintAddr<TYPE_MCBIST>( uint64_t i_addr )
return MemAddr( MemRank(mrnk, srnk), bnk, row, col );
}
+template
+MemAddr MemAddr::fromMaintAddr<TYPE_MCBIST>( uint64_t i_addr );
+template
+MemAddr MemAddr::fromMaintAddr<TYPE_OCMB_CHIP>( uint64_t i_addr );
+
+
template<>
MemAddr MemAddr::fromMaintAddr<TYPE_MBA>( uint64_t i_addr )
{
@@ -169,6 +181,53 @@ uint32_t getMemReadAddr<TYPE_MCBIST>( ExtensibleChip * i_chip, uint32_t i_pos,
//------------------------------------------------------------------------------
template<>
+uint32_t getMemReadAddr<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ MemAddr::ReadReg i_reg,
+ MemAddr & o_addr )
+{
+ #define PRDF_FUNC "[getMemReadAddr<TYPE_OCMB_CHIP>] "
+
+ uint32_t o_rc = SUCCESS;
+
+ // Check parameters
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+
+ // Get the register string.
+ const char * reg_str = "";
+ switch ( i_reg )
+ {
+ case MemAddr::READ_NCE_ADDR: reg_str = "MBNCER"; break;
+ case MemAddr::READ_RCE_ADDR: reg_str = "MBRCER"; break;
+ case MemAddr::READ_MPE_ADDR: reg_str = "MBMPER"; break;
+ case MemAddr::READ_UE_ADDR : reg_str = "MBUER" ; break;
+ case MemAddr::READ_AUE_ADDR: reg_str = "MBAUER"; break;
+ default: PRDF_ASSERT( false );
+ }
+
+ // Read the address register
+ SCAN_COMM_REGISTER_CLASS * reg = i_chip->getRegister( reg_str );
+ o_rc = reg->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() failed on %s: i_chip=0x%08x",
+ reg_str, i_chip->getHuid() );
+ }
+ else
+ {
+ // Get the address object.
+ uint64_t addr = reg->GetBitFieldJustified( 0, 64 );
+ o_addr = MemAddr::fromReadAddr<TYPE_OCMB_CHIP>( addr );
+ }
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<>
uint32_t getMemReadAddr<TYPE_MEMBUF>( ExtensibleChip * i_chip, uint32_t i_pos,
MemAddr::ReadReg i_reg, MemAddr & o_addr )
{
@@ -247,15 +306,14 @@ uint32_t getMemReadAddr<TYPE_MBA>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
-template<>
-uint32_t getMemMaintAddr<TYPE_MCBIST>( ExtensibleChip * i_chip,
- MemAddr & o_addr )
+template<TARGETING::TYPE T>
+uint32_t getMemMaintAddr( ExtensibleChip * i_chip, MemAddr & o_addr )
{
- #define PRDF_FUNC "[getMemMaintAddr<TYPE_MCBIST>] "
+ #define PRDF_FUNC "[getMemMaintAddr<T>] "
// Check parameters
PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MCBIST == i_chip->getType() );
+ PRDF_ASSERT( T == i_chip->getType() );
// Read the address register
SCAN_COMM_REGISTER_CLASS * reg = i_chip->getRegister( "MCBMCAT" );
@@ -269,7 +327,7 @@ uint32_t getMemMaintAddr<TYPE_MCBIST>( ExtensibleChip * i_chip,
{
// Get the address object.
uint64_t addr = reg->GetBitFieldJustified( 0, 64 );
- o_addr = MemAddr::fromMaintAddr<TYPE_MCBIST>( addr );
+ o_addr = MemAddr::fromMaintAddr<T>( addr );
}
return o_rc;
@@ -277,6 +335,13 @@ uint32_t getMemMaintAddr<TYPE_MCBIST>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
+template
+uint32_t getMemMaintAddr<TYPE_MCBIST>( ExtensibleChip * i_chip,
+ MemAddr & o_addr );
+template
+uint32_t getMemMaintAddr<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ MemAddr & o_addr );
+
//------------------------------------------------------------------------------
template<>
@@ -389,8 +454,9 @@ uint32_t getMemMaintEndAddr<TYPE_MBA>( ExtensibleChip * i_chip,
#ifdef __HOSTBOOT_MODULE
-uint32_t getMcbistMaintPort( ExtensibleChip * i_mcbChip,
- std::vector<ExtensibleChip *> & o_mcaList )
+template<>
+uint32_t getMcbistMaintPort<TYPE_MCBIST>( ExtensibleChip * i_mcbChip,
+ ExtensibleChipList & o_mcaList )
{
#define PRDF_FUNC "[getMcbistMaintPort] "
@@ -402,9 +468,9 @@ uint32_t getMcbistMaintPort( ExtensibleChip * i_mcbChip,
o_mcaList.clear();
- SCAN_COMM_REGISTER_CLASS * mcbagra = i_mcbChip->getRegister( "MCBAGRA" );
- SCAN_COMM_REGISTER_CLASS * mcbmcat = i_mcbChip->getRegister( "MCBMCAT" );
- SCAN_COMM_REGISTER_CLASS * mcb_cntl = i_mcbChip->getRegister( "MCB_CNTL" );
+ SCAN_COMM_REGISTER_CLASS * mcbagra = i_mcbChip->getRegister( "MCBAGRA" );
+ SCAN_COMM_REGISTER_CLASS * mcbmcat = i_mcbChip->getRegister( "MCBMCAT" );
+ SCAN_COMM_REGISTER_CLASS * mcb_cntl = i_mcbChip->getRegister( "MCB_CNTL" );
do
{
@@ -446,7 +512,7 @@ uint32_t getMcbistMaintPort( ExtensibleChip * i_mcbChip,
}
// Get MCAs from all targeted ports.
- for ( uint8_t p = 0; p < 4; p++ )
+ for ( uint8_t p = 0; p < MAX_MCA_PER_MCBIST; p++ )
{
if ( 0 == (portMask & (0x8 >> p)) ) continue;
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemAddress.H b/src/usr/diag/prdf/common/plat/mem/prdfMemAddress.H
index 8dc192672..f5120b3b5 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemAddress.H
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemAddress.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -167,7 +167,7 @@ uint32_t getMemReadAddr( ExtensibleChip * i_chip, uint32_t i_pos,
/**
* @brief Reads the specified mainline memory read address from hardware.
- * @param i_chip MCA or MBA.
+ * @param i_chip MCA, MBA, or OCMB.
* @param i_reg The target address register.
* @param o_addr The returned address from hardware.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
@@ -189,7 +189,7 @@ uint32_t getMemReadAddr( ExtensibleChip * i_chip, MemAddr::ReadReg i_reg,
* mode or not. Therefore, users must call getMcbistMaintPort() to get the port
* information.
*
- * @param i_chip An MBA or MCBIST chip.
+ * @param i_chip An MBA, MCBIST, or OCMB chip.
* @param o_addr The returned address from hardware.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
@@ -228,11 +228,12 @@ uint32_t getMemMaintEndAddr( ExtensibleChip * i_chip, MemAddr & o_addr );
*
* @note Only supported for MCBIST.
* @param i_mcbChip An MCBIST chip.
- * @param o_mcaList A list of all MCAs targeted by the command.
+ * @param o_portList A list of all MCAs targeted by the command.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
+template<TARGETING::TYPE T>
uint32_t getMcbistMaintPort( ExtensibleChip * i_mcbChip,
- std::vector<ExtensibleChip *> & o_mcaList );
+ ExtensibleChipList & o_portList );
#endif
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C b/src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C
index ebef7ae29..4d55c7c50 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C
@@ -39,6 +39,7 @@
#include <prdfCenMbaDataBundle.H>
#include <prdfPlatServices.H>
#include <prdfP9McaDataBundle.H>
+#include <prdfOcmbDataBundle.H>
#include <prdfMemRowRepair.H>
@@ -65,8 +66,16 @@ void addExtMemMruData( const MemoryMru & i_memMru, errlHndl_t io_errl )
{
TargetHandle_t trgt = i_memMru.getTrgt();
- // Get the DRAM width.
- extMemMru.isX4Dram = isDramWidthX4( trgt ) ? 1 : 0;
+ if ( TYPE_OCMB_CHIP == getTargetType(trgt) )
+ {
+ TargetHandle_t dimm = getConnectedDimm( trgt, i_memMru.getRank() );
+ extMemMru.isX4Dram = isDramWidthX4( dimm ) ? 1 : 0;
+ }
+ else
+ {
+ // Get the DRAM width.
+ extMemMru.isX4Dram = isDramWidthX4( trgt ) ? 1 : 0;
+ }
// Get the DIMM type.
if ( TYPE_MBA == getTargetType(trgt) )
@@ -97,9 +106,9 @@ void addExtMemMruData( const MemoryMru & i_memMru, errlHndl_t io_errl )
{
getDimmDqAttr<TYPE_DIMM>(partList[0], extMemMru.dqMapping);
}
- else if ( TYPE_MEM_PORT == getTargetType(trgt) )
+ else if ( TYPE_OCMB_CHIP == getTargetType(trgt) )
{
- getDimmDqAttr<TYPE_MEM_PORT>( trgt, extMemMru.dqMapping );
+ getDimmDqAttr<TYPE_OCMB_CHIP>( trgt, extMemMru.dqMapping );
}
else
{
@@ -172,7 +181,6 @@ void captureDramRepairsData( TARGETING::TargetHandle_t i_trgt,
if( CEN_VPD_DIMM_SPARE_NO_SPARE != spareConfig )
data.header.isSpareDram = true;
-
// Iterate all ranks to get DRAM repair data
for ( auto & rank : masterRanks )
{
@@ -220,8 +228,11 @@ void captureDramRepairsData( TARGETING::TargetHandle_t i_trgt,
if ( data.rankDataList.size() > 0 )
{
data.header.rankCount = data.rankDataList.size();
- data.header.isEccSp = ( isDramWidthX4( i_trgt ) &&
- (TYPE_MBA == getTargetType(i_trgt)) );
+ data.header.isEccSp = false;
+ if ( TYPE_MBA == getTargetType(i_trgt) )
+ {
+ data.header.isEccSp = isDramWidthX4( i_trgt );
+ }
UtilMem dramStream;
dramStream << data;
@@ -459,6 +470,33 @@ void captureIueCounts<McaDataBundle*>( TARGETING::TargetHandle_t i_trgt,
//------------------------------------------------------------------------------
template<>
+void captureIueCounts<OcmbDataBundle*>( TARGETING::TargetHandle_t i_trgt,
+ OcmbDataBundle * i_db,
+ CaptureData & io_cd )
+{
+ #ifdef __HOSTBOOT_MODULE
+
+ uint8_t sz_capData = i_db->iv_iueTh.size()*2;
+ uint8_t capData[sz_capData] = {};
+ uint8_t idx = 0;
+
+ for ( auto & th_pair : i_db->iv_iueTh )
+ {
+ capData[idx] = th_pair.first;
+ capData[idx+1] = th_pair.second.getCount();
+ idx += 2;
+ }
+
+ // Add data to capture data.
+ BitString bs ( sz_capData*8, (CPU_WORD *) &capData );
+ io_cd.Add( i_trgt, Util::hashString("IUE_COUNTS"), bs );
+
+ #endif
+}
+
+//------------------------------------------------------------------------------
+
+template<>
void addEccData<TYPE_MCA>( ExtensibleChip * i_chip,
STEP_CODE_DATA_STRUCT & io_sc )
{
@@ -497,6 +535,33 @@ void addEccData<TYPE_MCBIST>( ExtensibleChip * i_chip,
}
template<>
+void addEccData<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+
+ CaptureData & cd = io_sc.service_data->GetCaptureData();
+ OcmbDataBundle * db = getOcmbDataBundle( i_chip );
+
+ TargetHandle_t ocmbTrgt = i_chip->getTrgt();
+
+ // Add DRAM repairs data from hardware.
+ captureDramRepairsData<TYPE_OCMB_CHIP>( ocmbTrgt, cd );
+
+ // Add DRAM repairs data from VPD.
+ captureDramRepairsVpd<TYPE_OCMB_CHIP>( ocmbTrgt, cd );
+
+ // Add IUE counts to capture data.
+ captureIueCounts<OcmbDataBundle*>( ocmbTrgt, db, cd );
+
+ // Add CE table to capture data.
+ db->iv_ceTable.addCapData( cd );
+
+ // Add UE table to capture data.
+ db->iv_ueTable.addCapData( cd );
+}
+
+template<>
void addEccData<TYPE_MBA>( ExtensibleChip * i_chip,
STEP_CODE_DATA_STRUCT & io_sc )
{
@@ -558,6 +623,22 @@ void addEccData<TYPE_MBA>( TargetHandle_t i_trgt, errlHndl_t io_errl )
ErrDataService::AddCapData( cd, io_errl );
}
+template<>
+void addEccData<TYPE_OCMB_CHIP>( TargetHandle_t i_trgt,
+ errlHndl_t io_errl )
+{
+ PRDF_ASSERT( TYPE_OCMB_CHIP == getTargetType(i_trgt) );
+
+ CaptureData cd;
+
+ // Add DRAM repairs data from hardware.
+ captureDramRepairsData<TYPE_OCMB_CHIP>( i_trgt, cd );
+
+ // Add DRAM repairs data from VPD.
+ captureDramRepairsVpd<TYPE_OCMB_CHIP>( i_trgt, cd );
+
+ ErrDataService::AddCapData( cd, io_errl );
+}
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemCeTable.C b/src/usr/diag/prdf/common/plat/mem/prdfMemCeTable.C
index 16645586b..799e32e67 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemCeTable.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemCeTable.C
@@ -281,7 +281,7 @@ void MemCeTable<T>::addCapData( CaptureData & io_cd )
// Avoid linker errors with the template.
template class MemCeTable<TYPE_MCA>;
template class MemCeTable<TYPE_MBA>;
-template class MemCeTable<TYPE_MEM_PORT>;
+template class MemCeTable<TYPE_OCMB_CHIP>;
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemDbUtils.H b/src/usr/diag/prdf/common/plat/mem/prdfMemDbUtils.H
index 7605a82fa..80586976e 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemDbUtils.H
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemDbUtils.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -28,6 +28,8 @@
#include <prdfCenMbaDataBundle.H>
#include <prdfP9McaDataBundle.H>
+#include <prdfOcmbDataBundle.H>
+#include <prdfTargetServices.H>
namespace PRDF
{
@@ -62,6 +64,16 @@ uint32_t addCeTableEntry<TARGETING::TYPE_MCA>( ExtensibleChip * i_chip,
}
template<> inline
+uint32_t addCeTableEntry<TARGETING::TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemAddr & i_addr,
+ const MemSymbol & i_symbol,
+ bool i_isHard )
+{
+ return getOcmbDataBundle(i_chip)->iv_ceTable.addEntry( i_addr, i_symbol,
+ i_isHard );
+}
+
+template<> inline
uint32_t addCeTableEntry<TARGETING::TYPE_MBA>( ExtensibleChip * i_chip,
const MemAddr & i_addr,
const MemSymbol & i_symbol,
@@ -91,6 +103,14 @@ void addUeTableEntry<TARGETING::TYPE_MCA>( ExtensibleChip * i_chip,
}
template<> inline
+void addUeTableEntry<TARGETING::TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ UE_TABLE::Type i_type,
+ const MemAddr & i_addr )
+{
+ getOcmbDataBundle(i_chip)->iv_ueTable.addEntry( i_type, i_addr );
+}
+
+template<> inline
void addUeTableEntry<TARGETING::TYPE_MBA>( ExtensibleChip * i_chip,
UE_TABLE::Type i_type,
const MemAddr & i_addr )
@@ -118,6 +138,14 @@ void resetEccFfdc<TARGETING::TYPE_MCA>( ExtensibleChip * i_chip,
}
template<> inline
+void resetEccFfdc<TARGETING::TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ AddrRangeType i_type )
+{
+ getOcmbDataBundle(i_chip)->iv_ceTable.deactivateRank( i_rank, i_type );
+}
+
+template<> inline
void resetEccFfdc<TARGETING::TYPE_MBA>( ExtensibleChip * i_chip,
const MemRank & i_rank,
AddrRangeType i_type )
@@ -134,7 +162,7 @@ void resetEccFfdc<TARGETING::TYPE_MBA>( ExtensibleChip * i_chip,
/**
* @brief Generic wrapper to push a TdEntry to the Targeted Diagnostics queue.
- * @param i_chip MCA or MBA.
+ * @param i_chip MCA, MBA, or MEM_PORT.
* @param i_entry The new TdEntry.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
@@ -155,6 +183,13 @@ void pushToQueue<TARGETING::TYPE_MBA>( ExtensibleChip * i_chip,
getMbaDataBundle(i_chip)->getTdCtlr()->pushToQueue( i_entry );
}
+template<> inline
+void pushToQueue<TARGETING::TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ TdEntry * i_entry )
+{
+ getOcmbDataBundle(i_chip)->getTdCtlr()->pushToQueue( i_entry );
+}
+
#endif // Hostboot IPL/Runtime
//##############################################################################
@@ -179,6 +214,13 @@ MemIplCeStats<TARGETING::TYPE_MCA> * getIplCeStats( ExtensibleChip * i_chip )
}
template<> inline
+MemIplCeStats<TARGETING::TYPE_OCMB_CHIP> * getIplCeStats(
+ ExtensibleChip * i_chip )
+{
+ return getOcmbDataBundle(i_chip)->getIplCeStats();
+}
+
+template<> inline
MemIplCeStats<TARGETING::TYPE_MBA> * getIplCeStats( ExtensibleChip * i_chip )
{
return getMbaDataBundle(i_chip)->getIplCeStats();
@@ -211,6 +253,13 @@ uint32_t handleTdEvent<TARGETING::TYPE_MCA>( ExtensibleChip * i_chip,
}
template<> inline
+uint32_t handleTdEvent<TARGETING::TYPE_OCMB_CHIP>(ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc)
+{
+ return getOcmbDataBundle(i_chip)->getTdCtlr()->handleTdEvent( io_sc );
+}
+
+template<> inline
uint32_t handleTdEvent<TARGETING::TYPE_MBA>( ExtensibleChip * i_chip,
STEP_CODE_DATA_STRUCT & io_sc )
{
@@ -242,6 +291,16 @@ void banTps<TARGETING::TYPE_MBA>( ExtensibleChip * i_chip,
getMbaDataBundle(i_chip)->getTdCtlr()->banTps( i_chip, i_rank );
}
+template<> inline
+void banTps<TARGETING::TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank )
+{
+ // Ban TPS on this rank.
+ getOcmbDataBundle(i_chip)->getTdCtlr()->banTps( i_chip, i_rank );
+ // Permanently mask mainline NCEs and TCEs because of the TPS ban.
+ getOcmbDataBundle(i_chip)->iv_maskMainlineNceTce = true;
+}
+
#endif // Hostboot Runtime only
} // end namespace MemDbUtils
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.C b/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.C
index 308e25dab..5db522818 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.C
@@ -450,6 +450,9 @@ std::vector<MemSymbol> MemDqBitmap::getSymbolList( uint8_t i_portSlct )
case TYPE_MEM_PORT:
symbol = dq2Symbol<TYPE_MEM_PORT>( dq, i_portSlct );
break;
+ case TYPE_OCMB_CHIP:
+ symbol = dq2Symbol<TYPE_OCMB_CHIP>(dq, i_portSlct);
+ break;
default:
PRDF_ERR( "Invalid trgt type" );
PRDF_ASSERT( false );
@@ -700,7 +703,7 @@ uint32_t MemDqBitmap::setEccSpare( uint8_t i_pins )
// Utility Functions
//##############################################################################
-uint32_t setDramInVpd( ExtensibleChip * i_chip, const MemRank & i_rank,
+uint32_t setDramInVpd( TargetHandle_t i_trgt, const MemRank & i_rank,
MemSymbol i_symbol )
{
#define PRDF_FUNC "[MemDqBitmap::__setDramInVpd] "
@@ -709,14 +712,12 @@ uint32_t setDramInVpd( ExtensibleChip * i_chip, const MemRank & i_rank,
do
{
- TARGETING::TargetHandle_t trgt = i_chip->getTrgt();
-
MemDqBitmap dqBitmap;
- o_rc = getBadDqBitmap( trgt, i_rank, dqBitmap );
+ o_rc = getBadDqBitmap( i_trgt, i_rank, dqBitmap );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getBadDqBitmap(0x%08x, 0x%02x) failed.",
- getHuid(trgt), i_rank.getKey() );
+ getHuid(i_trgt), i_rank.getKey() );
break;
}
@@ -727,11 +728,11 @@ uint32_t setDramInVpd( ExtensibleChip * i_chip, const MemRank & i_rank,
break;
}
- o_rc = setBadDqBitmap( trgt, i_rank, dqBitmap );
+ o_rc = setBadDqBitmap( i_trgt, i_rank, dqBitmap );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "setBadDqBitmap(0x%08x, 0x%02x) failed.",
- getHuid(trgt), i_rank.getKey() );
+ getHuid(i_trgt), i_rank.getKey() );
break;
}
}while(0);
@@ -743,7 +744,7 @@ uint32_t setDramInVpd( ExtensibleChip * i_chip, const MemRank & i_rank,
//------------------------------------------------------------------------------
-uint32_t clearDramInVpd( ExtensibleChip * i_chip, const MemRank & i_rank,
+uint32_t clearDramInVpd( TargetHandle_t i_trgt, const MemRank & i_rank,
MemSymbol i_symbol )
{
#define PRDF_FUNC "[MemDqBitmap::__clearDramInVpd] "
@@ -752,14 +753,12 @@ uint32_t clearDramInVpd( ExtensibleChip * i_chip, const MemRank & i_rank,
do
{
- TARGETING::TargetHandle_t trgt = i_chip->getTrgt();
-
MemDqBitmap dqBitmap;
- o_rc = getBadDqBitmap( trgt, i_rank, dqBitmap );
+ o_rc = getBadDqBitmap( i_trgt, i_rank, dqBitmap );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getBadDqBitmap(0x%08x, 0x%02x) failed.",
- getHuid(trgt), i_rank.getKey() );
+ getHuid(i_trgt), i_rank.getKey() );
break;
}
@@ -770,11 +769,11 @@ uint32_t clearDramInVpd( ExtensibleChip * i_chip, const MemRank & i_rank,
break;
}
- o_rc = setBadDqBitmap( trgt, i_rank, dqBitmap );
+ o_rc = setBadDqBitmap( i_trgt, i_rank, dqBitmap );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "setBadDqBitmap(0x%08x, 0x%02x) failed.",
- getHuid(trgt), i_rank.getKey() );
+ getHuid(i_trgt), i_rank.getKey() );
break;
}
}while(0);
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.H b/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.H
index b407d9835..c3648dbc5 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.H
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.H
@@ -73,7 +73,22 @@ class MemDqBitmap
/** @brief Constructor from components */
MemDqBitmap( TARGETING::TargetHandle_t i_trgt, const MemRank & i_rank,
BitmapData i_d ) : iv_trgt(i_trgt), iv_rank(i_rank),
- iv_x4Dram(PlatServices::isDramWidthX4(i_trgt)), iv_data(i_d){}
+ iv_x4Dram(true), iv_data(i_d)
+ {
+ if ( TARGETING::TYPE_MEM_PORT == PlatServices::getTargetType(iv_trgt) ||
+ TARGETING::TYPE_OCMB_CHIP ==
+ PlatServices::getTargetType(iv_trgt) )
+ {
+ // TODO RTC 210072 - Support multiple ports
+ TARGETING::TargetHandle_t dimm =
+ PlatServices::getConnectedDimm( iv_trgt, iv_rank );
+ iv_x4Dram = PlatServices::isDramWidthX4( dimm );
+ }
+ else
+ {
+ iv_x4Dram = PlatServices::isDramWidthX4( iv_trgt );
+ }
+ }
public: // functions
@@ -224,7 +239,7 @@ class MemDqBitmap
private: // instance variables
- TARGETING::TargetHandle_t iv_trgt; ///< Target MBA/MCA/MEM_PORT
+ TARGETING::TargetHandle_t iv_trgt; ///< Target MBA/MCA/MEM_PORT/OCMB_CHIP
MemRank iv_rank; ///< Target rank
bool iv_x4Dram; ///< TRUE if iv_trgt uses x4 DRAMs
@@ -238,20 +253,21 @@ class MemDqBitmap
/**
* @brief Sets the inputted dram in DRAM repairs VPD.
- * @param i_chip MBA or MCA chip.
+ * @param i_trgt MBA, MCA, MEM_PORT, or OCMB chip.
* @param i_rank Target rank.
* @return Non-SUCCESS if an internal function fails. SUCCESS otherwise.
*/
-uint32_t setDramInVpd( ExtensibleChip * i_chip, const MemRank & i_rank,
+uint32_t setDramInVpd( TARGETING::TargetHandle_t i_trgt, const MemRank & i_rank,
MemSymbol i_symbol );
/**
* @brief Clears the inputted dram in DRAM repairs VPD.
- * @param i_chip MBA or MCA chip.
+ * @param i_trgt MBA, MCA, MEM_PORT, or OCMB chip.
* @param i_rank Target rank.
* @return Non-SUCCESS if an internal function fails. SUCCESS otherwise.
*/
-uint32_t clearDramInVpd( ExtensibleChip * i_chip, const MemRank & i_rank,
+uint32_t clearDramInVpd( TARGETING::TargetHandle_t i_trgt,
+ const MemRank & i_rank,
MemSymbol i_symbol );
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C
index 9869a8c08..f206a074e 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C
@@ -127,6 +127,87 @@ uint32_t handleMemUe<TYPE_MCA>( ExtensibleChip * i_chip, const MemAddr & i_addr,
i_chip->getHuid(), i_type );
break;
}
+
+ #ifdef __HOSTBOOT_RUNTIME
+ // Increment the UE counter and store the rank we're on, resetting
+ // the UE and CE counts if we have stopped on a new rank.
+ ExtensibleChip * mcb = getConnectedParent( i_chip, TYPE_MCBIST );
+ McbistDataBundle * mcbdb = getMcbistDataBundle(mcb);
+ if ( mcbdb->iv_ceUeRank != i_addr.getRank() )
+ {
+ mcbdb->iv_ceStopCounter.reset();
+ mcbdb->iv_ueStopCounter.reset();
+ }
+ mcbdb->iv_ueStopCounter.inc( io_sc );
+ mcbdb->iv_ceUeRank = i_addr.getRank();
+ #endif
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+template<>
+uint32_t handleMemUe<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemAddr & i_addr,
+ UE_TABLE::Type i_type,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[MemEcc::handleMemUe<TYPE_OCMB_CHIP>] "
+
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ // First check to see if this is a side-effect UE.
+ SCAN_COMM_REGISTER_CLASS * fir = i_chip->getRegister("OCMB_LFIR");
+ o_rc = fir->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() failed on OCMB_LFIR: i_chip=0x%08x",
+ i_chip->getHuid() );
+ break;
+ }
+
+ // Check OCMB_LFIR[38] to determine if this is a side-effect.
+ if ( fir->IsBitSet(38) )
+ {
+ // This is a side-effect. Callout the OCMB.
+ PRDF_TRAC( PRDF_FUNC "Memory UE is side-effect of DDRPHY error" );
+ io_sc.service_data->SetCallout( i_chip->getTrgt() );
+ io_sc.service_data->setServiceCall();
+ }
+ else
+ {
+ // Handle the memory UE.
+ o_rc = __handleMemUe<TYPE_OCMB_CHIP>( i_chip, i_addr, i_type,
+ io_sc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "__handleMemUe(0x%08x,%d) failed",
+ i_chip->getHuid(), i_type );
+ break;
+ }
+
+ #ifdef __HOSTBOOT_RUNTIME
+ // Increment the UE counter and store the rank we're on, resetting
+ // the UE and CE counts if we have stopped on a new rank.
+ OcmbDataBundle * ocmbdb = getOcmbDataBundle(i_chip);
+ if ( ocmbdb->iv_ceUeRank != i_addr.getRank() )
+ {
+ ocmbdb->iv_ceStopCounter.reset();
+ ocmbdb->iv_ueStopCounter.reset();
+ }
+ ocmbdb->iv_ueStopCounter.inc( io_sc );
+ ocmbdb->iv_ceUeRank = i_addr.getRank();
+ #endif
+
}
} while (0);
@@ -328,6 +409,52 @@ uint32_t maskMemPort<TYPE_MCA>( ExtensibleChip * i_chip )
#undef PRDF_FUNC
}
+template<>
+uint32_t maskMemPort<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
+{
+ #define PRDF_FUNC "[MemEcc::maskMemPort<TYPE_OCMB_CHIP>] "
+
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ // Mask all FIRs on the OCMB in the chiplet FIRs.
+ SCAN_COMM_REGISTER_CLASS * chipletMask =
+ i_chip->getRegister("OCMB_CHIPLET_FIR_MASK");
+ SCAN_COMM_REGISTER_CLASS * chipletSpaMask =
+ i_chip->getRegister("OCMB_CHIPLET_SPA_FIR_MASK");
+
+ chipletMask->setAllBits();
+ chipletSpaMask->setAllBits();
+
+ o_rc = chipletMask->Write() | chipletSpaMask->Write();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() failed on 0x%08x", i_chip->getHuid() );
+ break;
+ }
+
+ #ifdef __HOSTBOOT_RUNTIME
+
+ // Dynamically deallocate the port.
+ if ( SUCCESS != MemDealloc::port<TYPE_OCMB_CHIP>( i_chip ) )
+ {
+ PRDF_ERR( PRDF_FUNC "MemDealloc::port<TYPE_OCMB_CHIP>(0x%08x) "
+ "failed", i_chip->getHuid() );
+ }
+
+ #endif
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
#endif // __HOSTBOOT_MODULE
//------------------------------------------------------------------------------
@@ -390,6 +517,62 @@ uint32_t triggerPortFail<TYPE_MCA>( ExtensibleChip * i_chip )
#undef PRDF_FUNC
}
+template<>
+uint32_t triggerPortFail<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
+{
+ #define PRDF_FUNC "[MemEcc::triggerPortFail<TYPE_OCMB_CHIP>] "
+
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+
+ uint32_t o_rc = SUCCESS;
+
+ OcmbDataBundle * db = getOcmbDataBundle( i_chip );
+
+ do
+ {
+ // trigger a port fail
+ // set FARB0[59] - MBA_FARB0Q_CFG_INJECT_PARITY_ERR_CONSTANT and
+ // FARB0[40] - MBA_FARB0Q_CFG_INJECT_PARITY_ERR_ADDR5
+ SCAN_COMM_REGISTER_CLASS * farb0 = i_chip->getRegister("FARB0");
+
+ o_rc = farb0->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() FARB0 failed: i_chip=0x%08x",
+ i_chip->getHuid() );
+ break;
+ }
+
+ farb0->SetBit(59);
+ farb0->SetBit(40);
+
+ o_rc = farb0->Write();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() FARB0 failed: i_chip=0x%08x",
+ i_chip->getHuid() );
+ break;
+ }
+
+ // reset thresholds to prevent issuing multiple port failures on
+ // the same port
+ for ( auto & resetTh : db->iv_iueTh )
+ {
+ resetTh.second.reset();
+ }
+
+ db->iv_iuePortFail = true;
+
+ break;
+ }while(0);
+
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
#endif // __HOSTBOOT_RUNTIME
//------------------------------------------------------------------------------
@@ -420,6 +603,30 @@ bool queryIueTh<TYPE_MCA>( ExtensibleChip * i_chip,
return iueAtTh;
}
+template<>
+bool queryIueTh<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+
+ bool iueAtTh = false;
+
+ OcmbDataBundle * db = getOcmbDataBundle( i_chip );
+
+ // Loop through all our thresholds
+ for ( auto & th : db->iv_iueTh )
+ {
+ // If threshold reached
+ if ( th.second.thReached(io_sc) )
+ {
+ iueAtTh = true;
+ }
+ }
+
+ return iueAtTh;
+}
+
#endif
//------------------------------------------------------------------------------
@@ -493,6 +700,11 @@ template
uint32_t handleMpe<TYPE_MBA>( ExtensibleChip * i_chip, const MemAddr & i_addr,
UE_TABLE::Type i_type,
STEP_CODE_DATA_STRUCT & io_sc );
+template
+uint32_t handleMpe<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemAddr & i_addr,
+ UE_TABLE::Type i_type,
+ STEP_CODE_DATA_STRUCT & io_sc );
//------------------------------------------------------------------------------
@@ -581,6 +793,10 @@ template
uint32_t analyzeFetchMpe<TYPE_MBA>( ExtensibleChip * i_chip,
const MemRank & i_rank,
STEP_CODE_DATA_STRUCT & io_sc );
+template
+uint32_t analyzeFetchMpe<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ STEP_CODE_DATA_STRUCT & io_sc );
//------------------------------------------------------------------------------
@@ -794,6 +1010,9 @@ uint32_t analyzeFetchNceTce<TYPE_MCA>( ExtensibleChip * i_chip,
template
uint32_t analyzeFetchNceTce<TYPE_MBA>( ExtensibleChip * i_chip,
STEP_CODE_DATA_STRUCT & io_sc );
+template
+uint32_t analyzeFetchNceTce<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc );
//------------------------------------------------------------------------------
@@ -871,6 +1090,9 @@ uint32_t analyzeFetchUe<TYPE_MCA>( ExtensibleChip * i_chip,
template
uint32_t analyzeFetchUe<TYPE_MBA>( ExtensibleChip * i_chip,
STEP_CODE_DATA_STRUCT & io_sc );
+template
+uint32_t analyzeFetchUe<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc );
//------------------------------------------------------------------------------
@@ -955,16 +1177,97 @@ uint32_t handleMemIue<TYPE_MCA>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
-//------------------------------------------------------------------------------
-
template<>
-uint32_t analyzeMainlineIue<TYPE_MCA>( ExtensibleChip * i_chip,
+uint32_t handleMemIue<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
STEP_CODE_DATA_STRUCT & io_sc )
{
+ #define PRDF_FUNC "[MemEcc::handleMemIue] "
+
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+
+ uint32_t o_rc = SUCCESS;
+
+ // Add the DIMM to the callout list.
+ MemoryMru mm { i_chip->getTrgt(), i_rank, MemoryMruData::CALLOUT_RANK };
+ io_sc.service_data->SetCallout( mm );
+
+ #ifdef __HOSTBOOT_MODULE
+
+ do
+ {
+ // Nothing else to do if handling a system checkstop.
+ if ( CHECK_STOP == io_sc.service_data->getPrimaryAttnType() ) break;
+
+ // Get the data bundle from chip.
+ OcmbDataBundle * db = getOcmbDataBundle( i_chip );
+
+ // If we have already caused a port fail, mask the IUE bits.
+ if ( true == db->iv_iuePortFail )
+ {
+ SCAN_COMM_REGISTER_CLASS * mask_or =
+ i_chip->getRegister("RDFFIR_MASK_OR");
+
+ mask_or->SetBit(17);
+ mask_or->SetBit(37);
+
+ o_rc = mask_or->Write();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() failed on 0x%08x",
+ i_chip->getHuid() );
+ break;
+ }
+ }
+
+ // Get the DIMM select.
+ uint8_t ds = i_rank.getDimmSlct();
+
+ // Initialize threshold if it doesn't exist yet.
+ if ( 0 == db->iv_iueTh.count(ds) )
+ {
+ db->iv_iueTh[ds] = TimeBasedThreshold( getIueTh() );
+ }
+
+ // Increment the count and check if at threshold.
+ if ( db->iv_iueTh[ds].inc(io_sc) )
+ {
+ // Make the error log predictive.
+ io_sc.service_data->setServiceCall();
+
+ // The port fail will be triggered in the PostAnalysis plugin after
+ // the error log has been committed.
+
+ // Mask off the entire port to avoid collateral.
+ o_rc = MemEcc::maskMemPort<TYPE_OCMB_CHIP>( i_chip );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "MemEcc::maskMemPort(0x%08x) failed",
+ i_chip->getHuid() );
+ break;
+ }
+ }
+
+ } while (0);
+
+ #endif // __HOSTBOOT_MODULE
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<TARGETING::TYPE T>
+uint32_t analyzeMainlineIue( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
#define PRDF_FUNC "[MemEcc::analyzeMainlineIue] "
PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MCA == i_chip->getType() );
+ PRDF_ASSERT( T == i_chip->getType() );
uint32_t o_rc = SUCCESS;
@@ -974,7 +1277,7 @@ uint32_t analyzeMainlineIue<TYPE_MCA>( ExtensibleChip * i_chip,
// not likely that we will have two independent failure modes at the
// same time. So we just assume the address is correct.
MemAddr addr;
- o_rc = getMemReadAddr<TYPE_MCA>( i_chip, MemAddr::READ_RCE_ADDR, addr );
+ o_rc = getMemReadAddr<T>( i_chip, MemAddr::READ_RCE_ADDR, addr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemReadAddr(0x%08x, READ_RCE_ADDR) failed",
@@ -983,7 +1286,7 @@ uint32_t analyzeMainlineIue<TYPE_MCA>( ExtensibleChip * i_chip,
}
MemRank rank = addr.getRank();
- o_rc = handleMemIue<TYPE_MCA>( i_chip, rank, io_sc );
+ o_rc = handleMemIue<T>( i_chip, rank, io_sc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "handleMemIue(0x%08x,m%ds%d) failed",
@@ -998,16 +1301,23 @@ uint32_t analyzeMainlineIue<TYPE_MCA>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
+template
+uint32_t analyzeMainlineIue<TYPE_MCA>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc );
+template
+uint32_t analyzeMainlineIue<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc );
+
//------------------------------------------------------------------------------
-template<>
-uint32_t analyzeMaintIue<TYPE_MCA>( ExtensibleChip * i_chip,
- STEP_CODE_DATA_STRUCT & io_sc )
+template<TARGETING::TYPE T>
+uint32_t analyzeMaintIue( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
{
#define PRDF_FUNC "[MemEcc::analyzeMaintIue] "
PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MCA == i_chip->getType() );
+ PRDF_ASSERT( T == i_chip->getType() );
uint32_t o_rc = SUCCESS;
@@ -1015,7 +1325,7 @@ uint32_t analyzeMaintIue<TYPE_MCA>( ExtensibleChip * i_chip,
{
// Use the current address in the MCBMCAT.
MemAddr addr;
- o_rc = getMemMaintAddr<TYPE_MCA>( i_chip, addr );
+ o_rc = getMemMaintAddr<T>( i_chip, addr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemMaintAddr(0x%08x) failed",
@@ -1024,7 +1334,7 @@ uint32_t analyzeMaintIue<TYPE_MCA>( ExtensibleChip * i_chip,
}
MemRank rank = addr.getRank();
- o_rc = handleMemIue<TYPE_MCA>( i_chip, rank, io_sc );
+ o_rc = handleMemIue<T>( i_chip, rank, io_sc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "handleMemIue(0x%08x,m%ds%d) failed",
@@ -1039,6 +1349,13 @@ uint32_t analyzeMaintIue<TYPE_MCA>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
+template
+uint32_t analyzeMaintIue<TYPE_MCA>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc );
+template
+uint32_t analyzeMaintIue<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc );
+
//------------------------------------------------------------------------------
template<>
@@ -1152,6 +1469,117 @@ uint32_t analyzeImpe<TYPE_MCA>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
+template<>
+uint32_t analyzeImpe<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+
+ #define PRDF_FUNC "[MemEcc::analyzeImpe] "
+
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ // get the mark shadow register
+ SCAN_COMM_REGISTER_CLASS * msr = i_chip->getRegister("EXP_MSR");
+
+ o_rc = msr->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() failed on EXP_MSR: i_chip=0x%08x",
+ i_chip->getHuid() );
+ break;
+ }
+
+ TargetHandle_t trgt = i_chip->getTrgt();
+
+ // get galois field code - bits 8:15 of MSR
+ uint8_t galois = msr->GetBitFieldJustified( 8, 8 );
+
+ // get rank - bits 16:18 of MSR
+ uint8_t mrnk = msr->GetBitFieldJustified( 16, 3 );
+ MemRank rank( mrnk );
+
+ // get symbol and DRAM
+ MemSymbol symbol = MemSymbol::fromGalois( trgt, rank, galois );
+ if ( !symbol.isValid() )
+ {
+ PRDF_ERR( PRDF_FUNC "Galois 0x%02x from EXP_MSR is invalid: 0x%08x,"
+ "0x%02x", galois, i_chip->getHuid(), rank.getKey() );
+ o_rc = FAIL;
+ break;
+ }
+
+ // Add the DIMM to the callout list
+ MemoryMru memmru( trgt, rank, MemoryMruData::CALLOUT_RANK );
+ io_sc.service_data->SetCallout( memmru );
+
+ #ifdef __HOSTBOOT_MODULE
+ // get data bundle from chip
+ OcmbDataBundle * db = getOcmbDataBundle( i_chip );
+ uint8_t dram = symbol.getDram();
+
+ // Increment the count and check threshold.
+ if ( db->getImpeThresholdCounter()->inc(rank, dram, io_sc) )
+ {
+ // Make the error log predictive if DRAM Repairs are disabled or if
+ // the number of DRAMs on this rank with IMPEs has reached threshold
+ if ( areDramRepairsDisabled() ||
+ db->getImpeThresholdCounter()->queryDrams(rank, dram, io_sc) )
+ {
+ io_sc.service_data->setServiceCall();
+ }
+ else // Otherwise, place a chip mark on the failing DRAM.
+ {
+ MemMark chipMark( trgt, rank, galois );
+ o_rc = MarkStore::writeChipMark<TYPE_OCMB_CHIP>( i_chip, rank,
+ chipMark );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "writeChipMark(0x%08x,0x%02x) failed",
+ i_chip->getHuid(), rank.getKey() );
+ break;
+ }
+
+ o_rc = MarkStore::chipMarkCleanup<TYPE_OCMB_CHIP>( i_chip, rank,
+ io_sc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "chipMarkCleanup(0x%08x,0x%02x) failed",
+ i_chip->getHuid(), rank.getKey() );
+ break;
+ }
+ }
+ }
+
+ // If a predictive callout is made, mask both mainline and maintenance
+ // attentions.
+ if ( io_sc.service_data->queryServiceCall() )
+ {
+ SCAN_COMM_REGISTER_CLASS * mask
+ = i_chip->getRegister( "RDFFIR_MASK_OR" );
+ mask->SetBit(19); // mainline
+ mask->SetBit(39); // maintenance
+ o_rc = mask->Write();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() failed on RDFFIR_MASK_OR: "
+ "0x%08x", i_chip->getHuid() );
+ break;
+ }
+ }
+ #endif // __HOSTBOOT_MODULE
+
+ } while (0);
+
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
//------------------------------------------------------------------------------
template<>
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H
index 735ae436f..0fd71dd8b 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -51,7 +51,7 @@ namespace MemEcc
* @brief Adds the memory CE to the callout list and CE table. Will also issue
* dynamic memory deallocation when appropriate. Returns true if TPS is
* required.
- * @param i_chip MCA or MBA.
+ * @param i_chip MCA, MBA, or OCMB.
* @param i_addr Failed address.
* @param i_symbol Failed symbol.
* @param o_doTps True if TPS is required. False otherwise.
@@ -74,7 +74,7 @@ uint32_t handleMemCe( ExtensibleChip * i_chip, const MemAddr & i_addr,
* of the DIMMs, the UE table will not be updated and no dynamic memory
* deallocation.
*
- * @param i_chip MCA or MBA.
+ * @param i_chip MCA, OCMB, or MBA.
* @param i_addr Failed address.
* @param i_type The type of UE.
* @param io_sc The step code data struct.
@@ -96,7 +96,7 @@ uint32_t handleMemUe( ExtensibleChip * i_chip, const MemAddr & i_addr,
* the port failure is issued in the PostAnalysis plugin after the error log has
* been committed.
*
- * @param i_chip MCA chip.
+ * @param i_chip MCA or OCMB chip.
* @param i_rank Rank containing the IUE.
* @param io_sc The step code data struct.
* @return Non-SUCCESS if an interal function fails, SUCCESS otherwise.
@@ -107,7 +107,7 @@ uint32_t handleMemIue( ExtensibleChip * i_chip, const MemRank & i_rank,
/**
* @brief Handles a MPE attention.
- * @param i_chip MCA or MBA.
+ * @param i_chip MCA, OCMB, or MBA.
* @param i_addr Failed address.
* @param i_type The type of UE.
* @param io_sc The step code data struct.
@@ -119,7 +119,7 @@ uint32_t handleMpe( ExtensibleChip * i_chip, const MemAddr & i_addr,
/**
* @brief Handles a MPE attention.
- * @param i_chip MCA or MBA.
+ * @param i_chip MCA, OCMB, or MBA.
* @param i_rank Target rank.
* @param i_type The type of UE.
* @param io_sc The step code data struct.
@@ -135,7 +135,7 @@ uint32_t handleMpe( ExtensibleChip * i_chip, const MemRank & i_rank,
/**
* @brief Analyzes a fetch MPE attention.
- * @param i_chip MCA or MBA.
+ * @param i_chip MCA, OCMB, or MBA.
* @param i_rank Target rank.
* @param io_sc The step code data struct.
* @return Non-SUCCESS if an interal function fails, SUCCESS otherwise.
@@ -146,7 +146,7 @@ uint32_t analyzeFetchMpe( ExtensibleChip * i_chip, const MemRank & i_rank,
/**
* @brief Analyzes a fetch NCE/TCE attention.
- * @param i_chip MCA or MBA.
+ * @param i_chip MCA, OCMB, or MBA.
* @param io_sc The step code data struct.
* @return Non-SUCCESS if an interal function fails, SUCCESS otherwise.
*/
@@ -156,7 +156,7 @@ uint32_t analyzeFetchNceTce( ExtensibleChip * i_chip,
/**
* @brief Analyzes a fetch UE attention.
- * @param i_chip MCA or MBA.
+ * @param i_chip MCA, OCMB, or MBA.
* @param io_sc The step code data struct.
* @return Non-SUCCESS if an interal function fails, SUCCESS otherwise.
*/
@@ -166,7 +166,7 @@ uint32_t analyzeFetchUe( ExtensibleChip * i_chip,
/**
* @brief Analyzes a fetch mainline IUE attention.
- * @param i_chip MCA or MBA.
+ * @param i_chip MCA, OCMB, or MBA.
* @param io_sc The step code data struct.
* @return Non-SUCCESS if an interal function fails, SUCCESS otherwise.
*/
@@ -177,7 +177,7 @@ uint32_t analyzeMainlineIue( ExtensibleChip * i_chip,
/**
* @brief Analyzes a fetch maint IUE attention.
- * @param i_chip MCA or MBA.
+ * @param i_chip MCA, OCMB, or MBA.
* @param io_sc The step code data struct.
* @return Non-SUCCESS if an interal function fails, SUCCESS otherwise.
*/
@@ -187,7 +187,7 @@ uint32_t analyzeMaintIue( ExtensibleChip * i_chip,
/**
* @brief Analyzes a maint or mainline IMPE attention.
- * @param i_chip MCA or MBA.
+ * @param i_chip MCA, OCMB, or MBA.
* @param io_sc The step code data struct.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
@@ -208,7 +208,7 @@ uint32_t analyzeFetchRcePue( ExtensibleChip * i_chip,
/**
* @brief Will trigger a port fail.
- * @param i_chip MCA chip
+ * @param i_chip MCA/OCMB chip
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise
*/
template<TARGETING::TYPE T>
@@ -221,7 +221,7 @@ uint32_t triggerPortFail( ExtensibleChip * i_chip );
/**
* @brief Will query the data bundle and return if the IUE threshold has been
* reached.
- * @param i_chip MCA chip
+ * @param i_chip MCA/OCMB chip
* @param io_sc The step code data struct.
* @return True if IUE threshold is reached, false if not.
*/
@@ -231,7 +231,7 @@ bool queryIueTh( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc );
/**
* @brief Will mask off an entire memory port. At runtime will issue dynamic
* memory deallocation of the port.
- * @param i_chip MCA chip
+ * @param i_chip MCA/OCMB chip
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise
*/
template<TARGETING::TYPE T>
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemExtraSig.H b/src/usr/diag/prdf/common/plat/mem/prdfMemExtraSig.H
index 08b79922e..7bcf0e573 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemExtraSig.H
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemExtraSig.H
@@ -88,7 +88,7 @@ PRDR_ERROR_SIGNATURE(VttLost, 0xffff0084, "", "NVDIMM VTT Lost");
PRDR_ERROR_SIGNATURE(NotSelfRefr, 0xffff0085, "", "NVDIMM Dram Not Self Refresh");
PRDR_ERROR_SIGNATURE(CtrlHwErr, 0xffff0086, "", "NVDIMM Controller Hardware Error");
PRDR_ERROR_SIGNATURE(NvmCtrlErr, 0xffff0087, "", "NVDIMM NVM Controller Error");
-PRDR_ERROR_SIGNATURE(NvmLifeErr, 0xffff0088, "", "NVDIMM NVM Lifetime Error");
+PRDR_ERROR_SIGNATURE(NvmLifeErr, 0xffff0088, "", "NVDIMM Final NVM Lifetime Error");
PRDR_ERROR_SIGNATURE(InsuffEnergy, 0xffff0089, "", "NVDIMM Not enough energy for CSAVE");
PRDR_ERROR_SIGNATURE(InvFwErr, 0xffff008A, "", "NVDIMM Invalid Firmware Error");
@@ -98,8 +98,22 @@ PRDR_ERROR_SIGNATURE(EsPolNotSet, 0xffff008D, "", "NVDIMM Energy Source Policy
PRDR_ERROR_SIGNATURE(EsHwFail, 0xffff008E, "", "NVDIMM Energy Source Hardware Fail");
PRDR_ERROR_SIGNATURE(EsHlthAssess, 0xffff008F, "", "NVDIMM Energy Source Health Assessment Error");
-PRDR_ERROR_SIGNATURE(EsLifeErr, 0xffff0090, "", "NVDIMM Energy Source Lifetime Error");
-PRDR_ERROR_SIGNATURE(EsTmpErr, 0xffff0091, "", "NVDIMM Energy Source Temp Error");
+PRDR_ERROR_SIGNATURE(EsLifeErr, 0xffff0090, "", "NVDIMM Final Energy Source Lifetime Error");
+PRDR_ERROR_SIGNATURE(EsTmpErrHigh, 0xffff0091, "", "NVDIMM Energy Source Temperature Error - High Temp Threshold");
+PRDR_ERROR_SIGNATURE(EsTmpErrLow, 0xffff0092, "", "NVDIMM Energy Source Temperature Error - Low Temp Threshold");
+
+PRDR_ERROR_SIGNATURE(NvmLifeWarn1, 0xffff0093, "", "NVDIMM First NVM Lifetime Warning");
+PRDR_ERROR_SIGNATURE(NvmLifeWarn2, 0xffff0094, "", "NVDIMM Second NVM Lifetime Warning");
+PRDR_ERROR_SIGNATURE(EsLifeWarn1, 0xffff0095, "", "NVDIMM First Energy Source Lifetime Warning");
+PRDR_ERROR_SIGNATURE(EsLifeWarn2, 0xffff0096, "", "NVDIMM Second Energy Source Lifetime Warning");
+PRDR_ERROR_SIGNATURE(EsTmpWarnHigh, 0xffff0097, "", "NVDIMM Energy Source Temperature Warning - High Temp Threshold");
+PRDR_ERROR_SIGNATURE(EsTmpWarnLow, 0xffff0098, "", "NVDIMM Energy Source Temperature Warning - Low Temp Threshold");
+PRDR_ERROR_SIGNATURE(BelowWarnTh, 0xffff0099, "", "NVDIMM Below Warning Threshold");
+PRDR_ERROR_SIGNATURE(IntNvdimmErr, 0xffff009A, "", "NVDIMM Intermittent error");
+PRDR_ERROR_SIGNATURE(NotifStatErr, 0xffff009B, "", "NVDIMM Set Event Notification Status Error");
+PRDR_ERROR_SIGNATURE(FirEvntGone, 0xffff009C, "", "NVDIMM Event Triggering the FIR no longer present");
+PRDR_ERROR_SIGNATURE(EsTmpWarnFa, 0xffff009D, "", "NVDIMM Energy Source Temperature Warning - False Alarm");
+PRDR_ERROR_SIGNATURE(EsTmpErrFa, 0xffff009E, "", "NVDIMM Energy Source Temperature Error - False Alarm");
#endif // __prdfMemExtraSig_H
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C b/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C
index 83bff1876..e43d844c4 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C
@@ -46,7 +46,7 @@ namespace MarkStore
{
//##############################################################################
-// Utilities to read/write markstore (MCA)
+// Utilities to read/write markstore
//##############################################################################
// - We have the ability to set chip marks via the FWMSx registers, but there
@@ -62,15 +62,19 @@ namespace MarkStore
// mark per master rank. This matches the P8 behavior. This could be improved
// upon later if we have the time, but doubtful.
// - Summary:
-// - Chip marks will use HWMS0-7 registers (0x07010AD0-0x07010AD7).
-// - Symbol marks will use FWMS0-7 registers (0x07010AD8-0x07010ADF).
+// - Chip marks will use HWMS0-7 registers:
+// Nimbus: (0x07010AD0-0x07010AD7)
+// Axone: (0x08011C10-0x08011C17)
+// - Symbol marks will use FWMS0-7 registers:
+// Nimbus: (0x07010AD8-0x07010ADF)
+// Axone: (0x08011C18-0x08011C1F)
// - Each register maps to master ranks 0-7.
-template<>
-uint32_t readChipMark<TYPE_MCA>( ExtensibleChip * i_chip,
- const MemRank & i_rank, MemMark & o_mark )
+template<TARGETING::TYPE T>
+uint32_t readChipMark( ExtensibleChip * i_chip, const MemRank & i_rank,
+ MemMark & o_mark )
{
- #define PRDF_FUNC "[readChipMark<TYPE_MCA>] "
+ #define PRDF_FUNC "[readChipMark<T>] "
uint32_t o_rc = SUCCESS;
o_mark = MemMark(); // ensure invalid
@@ -110,14 +114,21 @@ uint32_t readChipMark<TYPE_MCA>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
+template
+uint32_t readChipMark<TYPE_MCA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank, MemMark & o_mark );
+template
+uint32_t readChipMark<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ MemMark & o_mark );
+
//------------------------------------------------------------------------------
-template<>
-uint32_t writeChipMark<TYPE_MCA>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- const MemMark & i_mark )
+template<TARGETING::TYPE T>
+uint32_t writeChipMark( ExtensibleChip * i_chip, const MemRank & i_rank,
+ const MemMark & i_mark )
{
- #define PRDF_FUNC "[writeChipMark<TYPE_MCA>] "
+ #define PRDF_FUNC "[writeChipMark<T>] "
PRDF_ASSERT( i_mark.isValid() );
@@ -153,13 +164,21 @@ uint32_t writeChipMark<TYPE_MCA>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
+template
+uint32_t writeChipMark<TYPE_MCA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ const MemMark & i_mark );
+template
+uint32_t writeChipMark<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ const MemMark & i_mark );
+
//------------------------------------------------------------------------------
-template<>
-uint32_t clearChipMark<TYPE_MCA>( ExtensibleChip * i_chip,
- const MemRank & i_rank )
+template<TARGETING::TYPE T>
+uint32_t clearChipMark( ExtensibleChip * i_chip, const MemRank & i_rank )
{
- #define PRDF_FUNC "[clearChipMark<TYPE_MCA>] "
+ #define PRDF_FUNC "[clearChipMark<T>] "
uint32_t o_rc = SUCCESS;
@@ -185,13 +204,20 @@ uint32_t clearChipMark<TYPE_MCA>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
+template
+uint32_t clearChipMark<TYPE_MCA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank );
+template
+uint32_t clearChipMark<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank );
+
//------------------------------------------------------------------------------
-template<>
-uint32_t readSymbolMark<TYPE_MCA>( ExtensibleChip * i_chip,
- const MemRank & i_rank, MemMark & o_mark )
+template<TARGETING::TYPE T>
+uint32_t readSymbolMark( ExtensibleChip * i_chip,
+ const MemRank & i_rank, MemMark & o_mark )
{
- #define PRDF_FUNC "[readSymbolMark<TYPE_MCA>] "
+ #define PRDF_FUNC "[readSymbolMark<T>] "
uint32_t o_rc = SUCCESS;
o_mark = MemMark(); // ensure invalid
@@ -247,14 +273,21 @@ uint32_t readSymbolMark<TYPE_MCA>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
+template
+uint32_t readSymbolMark<TYPE_MCA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank, MemMark & o_mark );
+template
+uint32_t readSymbolMark<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ MemMark & o_mark );
+
//------------------------------------------------------------------------------
-template<>
-uint32_t writeSymbolMark<TYPE_MCA>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- const MemMark & i_mark )
+template<TARGETING::TYPE T>
+uint32_t writeSymbolMark( ExtensibleChip * i_chip, const MemRank & i_rank,
+ const MemMark & i_mark )
{
- #define PRDF_FUNC "[writeSymbolMark<TYPE_MCA>] "
+ #define PRDF_FUNC "[writeSymbolMark<T>] "
PRDF_ASSERT( i_mark.isValid() );
@@ -294,36 +327,47 @@ uint32_t writeSymbolMark<TYPE_MCA>( ExtensibleChip * i_chip,
msName, i_chip->getHuid() );
}
- // Nimbus symbol mark performance workaround
- // When a symbol mark is placed at runtime
- #ifdef __HOSTBOOT_RUNTIME
+ // Nimbus only symbol mark performance workaround
+ if ( T == TYPE_MCA )
+ {
+ // When a symbol mark is placed at runtime
+ #ifdef __HOSTBOOT_RUNTIME
- // Trigger WAT logic to 'disable bypass'
- // Get the ECC Debug/WAT Control register
- SCAN_COMM_REGISTER_CLASS * dbgr = i_chip->getRegister( "DBGR" );
+ // Trigger WAT logic to 'disable bypass'
+ // Get the ECC Debug/WAT Control register
+ SCAN_COMM_REGISTER_CLASS * dbgr = i_chip->getRegister( "DBGR" );
- // Set DBGR[8] = 0b1
- dbgr->SetBit( 8 );
- o_rc = dbgr->Write();
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "Write() failed on DBGR: mca=0x%08x",
- i_chip->getHuid() );
+ // Set DBGR[8] = 0b1
+ dbgr->SetBit( 8 );
+ o_rc = dbgr->Write();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() failed on DBGR: mca=0x%08x",
+ i_chip->getHuid() );
+ }
+ #endif
}
- #endif
return o_rc;
#undef PRDF_FUNC
}
+template
+uint32_t writeSymbolMark<TYPE_MCA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ const MemMark & i_mark );
+template
+uint32_t writeSymbolMark<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ const MemMark & i_mark );
+
//------------------------------------------------------------------------------
-template<>
-uint32_t clearSymbolMark<TYPE_MCA>( ExtensibleChip * i_chip,
- const MemRank & i_rank )
+template<TARGETING::TYPE T>
+uint32_t clearSymbolMark( ExtensibleChip * i_chip, const MemRank & i_rank )
{
- #define PRDF_FUNC "[clearSymbolMark<TYPE_MCA>] "
+ #define PRDF_FUNC "[clearSymbolMark<T>] "
uint32_t o_rc = SUCCESS;
@@ -349,6 +393,13 @@ uint32_t clearSymbolMark<TYPE_MCA>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
+template
+uint32_t clearSymbolMark<TYPE_MCA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank );
+template
+uint32_t clearSymbolMark<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank );
+
//##############################################################################
// Utilities to read/write markstore (MBA)
//##############################################################################
@@ -958,7 +1009,7 @@ void __addCallout( ExtensibleChip * i_chip, const MemRank & i_rank,
//------------------------------------------------------------------------------
template<TARGETING::TYPE T>
-uint32_t __addRowRepairCallout( ExtensibleChip * i_chip,
+uint32_t __addRowRepairCallout( TargetHandle_t i_trgt,
const MemRank & i_rank,
STEP_CODE_DATA_STRUCT & io_sc )
{
@@ -967,7 +1018,7 @@ uint32_t __addRowRepairCallout( ExtensibleChip * i_chip,
uint32_t o_rc = SUCCESS;
// Get the dimms on this rank on either port.
- TargetHandleList dimmList = getConnectedDimms( i_chip->getTrgt(), i_rank );
+ TargetHandleList dimmList = getConnectedDimms( i_trgt, i_rank );
// Check for row repairs on each dimm.
for ( auto const & dimm : dimmList )
@@ -1073,8 +1124,8 @@ uint32_t __applyRasPolicies<TYPE_MBA>( ExtensibleChip * i_chip,
__addCallout( i_chip, i_rank, ecc, io_sc );
// Add the row repairs to the callout list if they exist
- o_rc = __addRowRepairCallout<TARGETING::TYPE_MBA>( i_chip, i_rank,
- io_sc );
+ o_rc = __addRowRepairCallout<TARGETING::TYPE_MBA>(
+ i_chip->getTrgt(), i_rank, io_sc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "__addRowRepairCallout(0x%08x,0x%02x) "
@@ -1136,6 +1187,125 @@ uint32_t __applyRasPolicies<TYPE_MBA>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
+template<>
+uint32_t __applyRasPolicies<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ const MemMark & i_chipMark,
+ const MemMark & i_symMark,
+ TdEntry * & o_dsdEvent,
+ bool & o_allRepairsUsed )
+{
+ #define PRDF_FUNC "[__applyRasPolicies<TYPE_OCMB_CHIP>] "
+
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ const uint8_t ps = i_chipMark.getSymbol().getPortSlct();
+ const uint8_t dram = i_chipMark.getSymbol().getDram();
+
+ TargetHandle_t memPort = getConnectedChild( i_chip->getTrgt(),
+ TYPE_MEM_PORT, ps );
+
+ TargetHandle_t dimmTrgt = getConnectedDimm( memPort, i_rank, ps );
+
+ const bool isX4 = isDramWidthX4( dimmTrgt );
+
+ // Determine if DRAM sparing is enabled.
+ bool isEnabled = false;
+ o_rc = isDramSparingEnabled<TYPE_MEM_PORT>( memPort, i_rank, ps,
+ isEnabled );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "isDramSparingEnabled() failed." );
+ break;
+ }
+
+ if ( isEnabled )
+ {
+ // Sparing is enabled. Get the current spares in hardware.
+ MemSymbol sp0, sp1, ecc;
+ o_rc = mssGetSteerMux<TARGETING::TYPE_OCMB_CHIP>( i_chip->getTrgt(),
+ i_rank, sp0, sp1,
+ ecc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "mssGetSteerMux(0x%08x,0x%02x) failed",
+ i_chip->getHuid(), i_rank.getKey() );
+ break;
+ }
+
+ // Add the spares to the callout list if they exist.
+ __addCallout( i_chip, i_rank, sp0, io_sc );
+ __addCallout( i_chip, i_rank, sp1, io_sc );
+ __addCallout( i_chip, i_rank, ecc, io_sc );
+
+ // Add the row repairs to the callout list if they exist
+ o_rc = __addRowRepairCallout<TARGETING::TYPE_OCMB_CHIP>( memPort,
+ i_rank,
+ io_sc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "__addRowRepairCallout(0x%08x,0x%02x) "
+ "failed.", i_chip->getHuid(), i_rank.getKey() );
+ break;
+ }
+
+ // If the chip mark is on a spare then the spare is bad and hardware
+ // can not steer it to another DRAM even if one is available (e.g.
+ // the ECC spare). In this this case, make error log predictive.
+ if ( ( (0 == ps) && sp0.isValid() && (dram == sp0.getDram()) ) ||
+ ( (1 == ps) && sp1.isValid() && (dram == sp1.getDram()) ) ||
+ ( isX4 && ecc.isValid() && (dram == ecc.getDram()) ) )
+ {
+ o_allRepairsUsed = true;
+ io_sc.service_data->setSignature( i_chip->getHuid(),
+ PRDFSIG_VcmBadSpare );
+ break; // Nothing more to do.
+ }
+
+ // Certain DIMMs may have had spares intentially made unavailable by
+ // the manufacturer. Check the VPD for available spares.
+ bool spAvail, eccAvail;
+ o_rc = isSpareAvailable<TYPE_MEM_PORT>( memPort, i_rank,
+ ps, spAvail, eccAvail );
+ if ( spAvail )
+ {
+ // A spare DRAM is available.
+ o_dsdEvent = new DsdEvent<TYPE_OCMB_CHIP>{ i_chip, i_rank,
+ i_chipMark };
+ }
+ else if ( eccAvail )
+ {
+ // The ECC spare is available.
+ o_dsdEvent = new DsdEvent<TYPE_OCMB_CHIP>{ i_chip, i_rank,
+ i_chipMark, true };
+ }
+ else
+ {
+ // Chip mark is in place and sparing is not possible.
+ o_allRepairsUsed = true;
+ io_sc.service_data->setSignature( i_chip->getHuid(),
+ PRDFSIG_AllDramRepairs );
+ }
+ }
+ // There is no DRAM sparing so simply check if both the chip and symbol
+ // mark have been used.
+ else if ( i_chipMark.isValid() && i_symMark.isValid() )
+ {
+ o_allRepairsUsed = true;
+ io_sc.service_data->setSignature( i_chip->getHuid(),
+ PRDFSIG_AllDramRepairs );
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
//------------------------------------------------------------------------------
template<TARGETING::TYPE T>
@@ -1220,6 +1390,9 @@ uint32_t applyRasPolicies( ExtensibleChip * i_chip, const MemRank & i_rank,
{
io_sc.service_data->setServiceCall();
+ // We want to try to avoid garding NVDIMMs, so clear gard for them now.
+ io_sc.service_data->clearNvdimmMruListGard();
+
#ifdef __HOSTBOOT_RUNTIME
// No more repairs left so no point doing any more TPS procedures.
MemDbUtils::banTps<T>( i_chip, i_rank );
@@ -1241,6 +1414,11 @@ uint32_t applyRasPolicies<TYPE_MBA>( ExtensibleChip * i_chip,
const MemRank & i_rank,
STEP_CODE_DATA_STRUCT & io_sc,
TdEntry * & o_dsdEvent );
+template
+uint32_t applyRasPolicies<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ TdEntry * & o_dsdEvent );
//------------------------------------------------------------------------------
@@ -1290,7 +1468,8 @@ uint32_t chipMarkCleanup( ExtensibleChip * i_chip, const MemRank & i_rank,
// Set the chip mark in the DRAM Repairs VPD.
if ( !areDramRepairsDisabled() )
{
- o_rc = setDramInVpd( i_chip, i_rank, chipMark.getSymbol() );
+ o_rc = setDramInVpd( i_chip->getTrgt(), i_rank,
+ chipMark.getSymbol() );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "setDramInVpd(0x%08x,0x%02x) failed",
@@ -1314,6 +1493,10 @@ template
uint32_t chipMarkCleanup<TYPE_MBA>( ExtensibleChip * i_chip,
const MemRank & i_rank,
STEP_CODE_DATA_STRUCT & io_sc );
+template
+uint32_t chipMarkCleanup<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ STEP_CODE_DATA_STRUCT & io_sc );
#endif // not supported on FSP
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemMark.H b/src/usr/diag/prdf/common/plat/mem/prdfMemMark.H
index 2cd28b8dd..86ffa1dc9 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemMark.H
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemMark.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -57,7 +57,7 @@ class MemMark
/**
* @brief Constructor from components.
- * @param i_trgt MBA or MCA target.
+ * @param i_trgt MBA, MCA, or OCMB target.
* @param i_rank The rank this mark is on.
* @param i_galois The Galois field.
*/
@@ -68,7 +68,7 @@ class MemMark
/**
* @brief Constructor from components.
- * @param i_trgt MBA or MCA target.
+ * @param i_trgt MBA, MCA, or OCMB target.
* @param i_rank The rank this mark is on.
* @param i_symbol The symbol representing this mark.
*/
@@ -112,7 +112,7 @@ namespace MarkStore
/**
* @brief Reads markstore and returns the chip mark for the given rank.
- * @param i_chip MBA or MCA chip.
+ * @param i_chip MBA, MCA, or OCMB chip.
* @param i_rank Target rank.
* @param o_mark The returned chip mark.
* @return Non-SUCCESS if an internal function fails. SUCCESS otherwise.
@@ -123,7 +123,7 @@ uint32_t readChipMark( ExtensibleChip * i_chip, const MemRank & i_rank,
/**
* @brief Writes a chip mark into markstore for the given rank.
- * @param i_chip MBA or MCA chip.
+ * @param i_chip MBA, MCA, or OCMB chip.
* @param i_rank Target rank.
* @param i_mark Target chip mark.
* @return Non-SUCCESS if an internal function fails. SUCCESS otherwise.
@@ -134,7 +134,7 @@ uint32_t writeChipMark( ExtensibleChip * i_chip, const MemRank & i_rank,
/**
* @brief Clear chip mark in markstore for the given rank.
- * @param i_chip MBA or MCA chip.
+ * @param i_chip MBA, MCA, or OCMB chip.
* @param i_rank Target rank.
* @return Non-SUCCESS if an internal function fails. SUCCESS otherwise.
*/
@@ -143,7 +143,7 @@ uint32_t clearChipMark( ExtensibleChip * i_chip, const MemRank & i_rank );
/**
* @brief Reads markstore and returns the symbol mark for the given rank.
- * @param i_chip MBA or MCA chip.
+ * @param i_chip MBA, MCA. or OCMB chip.
* @param i_rank Target rank.
* @param o_mark The returned symbol mark.
* @return Non-SUCCESS if an internal function fails. SUCCESS otherwise.
@@ -154,7 +154,7 @@ uint32_t readSymbolMark( ExtensibleChip * i_chip, const MemRank & i_rank,
/**
* @brief Writes a symbol mark into markstore for the given rank.
- * @param i_chip MBA or MCA chip.
+ * @param i_chip MBA, MCA, or OCMB chip.
* @param i_rank Target rank.
* @param i_mark Target symbol mark.
* @return Non-SUCCESS if an internal function fails. SUCCESS otherwise.
@@ -165,7 +165,7 @@ uint32_t writeSymbolMark( ExtensibleChip * i_chip, const MemRank & i_rank,
/**
* @brief Clear symbol mark in markstore for the given rank.
- * @param i_chip MBA or MCA chip.
+ * @param i_chip MBA, MCA. or OCMB chip.
* @param i_rank Target rank.
* @return Non-SUCCESS if an internal function fails. SUCCESS otherwise.
*/
@@ -187,7 +187,7 @@ uint32_t clearSymbolMark( ExtensibleChip * i_chip, const MemRank & i_rank );
* repairs have been used.
* - Returns a new DsdEvent if DRAM sparing is available.
*
- * @param i_chip MBA or MCA chip.
+ * @param i_chip MBA, MCA, or OCMB chip.
* @param i_rank Target rank.
* @param io_sc The step code data struct.
* @param o_dsdEvent A new DsdEvent if DRAM sparing is available. Otherwise,
@@ -211,7 +211,7 @@ uint32_t applyRasPolicies( ExtensibleChip * i_chip, const MemRank & i_rank,
* - Sets the DRAM in the DRAM Repair VPD if DRAM repairs.
* - Adds a DSD procedure to the TD queue if a DRAM spare is available
*
- * @param i_chip MBA or MCA chip.
+ * @param i_chip MBA, MCA, or OCMB chip.
* @param i_rank Target rank.
* @param io_sc The step code data struct.
* @return Non-SUCCESS if an internal function fails. SUCCESS otherwise.
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemRowRepair.C b/src/usr/diag/prdf/common/plat/mem/prdfMemRowRepair.C
index 8ebe6cea8..3ff6cd099 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemRowRepair.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemRowRepair.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -126,6 +126,22 @@ uint32_t getRowRepairData<TYPE_MCA>( TargetHandle_t i_dimm,
o_rowRepair );
}
+template<>
+uint32_t getRowRepairData<TYPE_MEM_PORT>( TargetHandle_t i_dimm,
+ const MemRank & i_rank, MemRowRepair & o_rowRepair )
+{
+ return __getRowRepairData<TYPE_MEM_PORT, fapi2::TARGET_TYPE_MEM_PORT>(
+ i_dimm, i_rank, o_rowRepair );
+}
+
+template<>
+uint32_t getRowRepairData<TYPE_OCMB_CHIP>( TargetHandle_t i_dimm,
+ const MemRank & i_rank, MemRowRepair & o_rowRepair )
+{
+ return __getRowRepairData<TYPE_OCMB_CHIP, fapi2::TARGET_TYPE_OCMB_CHIP>(
+ i_dimm, i_rank, o_rowRepair );
+}
+
//------------------------------------------------------------------------------
template<TARGETING::TYPE T, fapi2::TargetType F>
@@ -190,34 +206,19 @@ uint32_t setRowRepairData<TYPE_MCA>( TargetHandle_t i_dimm,
i_rowRepair );
}
-//------------------------------------------------------------------------------
-
-template<TARGETING::TYPE T>
-void __setRowRepairDataHelper( const MemAddr & i_addr, uint32_t & io_tmp );
-
template<>
-void __setRowRepairDataHelper<TYPE_MBA>( const MemAddr & i_addr,
- uint32_t & io_tmp )
+uint32_t setRowRepairData<TYPE_OCMB_CHIP>( TargetHandle_t i_dimm,
+ const MemRank & i_rank,
+ const MemRowRepair & i_rowRepair )
{
- #ifdef __HOSTBOOT_MODULE
-
- // Bank is stored as MBA "(DDR4): bg1-bg0,b1-b0 (4-bit)" in a MemAddr.
- // bank group - 2 bits (bg1-bg0)
- io_tmp = ( io_tmp << 2 ) | ( (i_addr.getBank() >> 2) & 0x03 );
-
- // bank - 3 bits (b2-b0)
- io_tmp = ( io_tmp << 3 ) | ( i_addr.getBank() & 0x03 );
-
- // Row is stored as "MBA: r17-r0 (18-bit)" in a MemAddr.
- // row - 18 bits (r17-r0)
- io_tmp = ( io_tmp << 18 ) | ( i_addr.getRow() & 0x0003ffff );
-
- #endif // __HOSTBOOT_MODULE
+ return __setRowRepairData<TYPE_OCMB_CHIP, fapi2::TARGET_TYPE_OCMB_CHIP>(
+ i_dimm, i_rank, i_rowRepair );
}
-template<>
-void __setRowRepairDataHelper<TYPE_MCA>( const MemAddr & i_addr,
- uint32_t & io_tmp )
+//------------------------------------------------------------------------------
+
+template<TARGETING::TYPE T>
+void __setRowRepairDataHelper( const MemAddr & i_addr, uint32_t & io_tmp )
{
#ifdef __HOSTBOOT_MODULE
@@ -242,6 +243,32 @@ void __setRowRepairDataHelper<TYPE_MCA>( const MemAddr & i_addr,
#endif // __HOSTBOOT_MODULE
}
+template
+void __setRowRepairDataHelper<TYPE_MCA>( const MemAddr & i_addr,
+ uint32_t & io_tmp );
+template
+void __setRowRepairDataHelper<TYPE_OCMB_CHIP>( const MemAddr & i_addr,
+ uint32_t & io_tmp );
+
+template<>
+void __setRowRepairDataHelper<TYPE_MBA>( const MemAddr & i_addr,
+ uint32_t & io_tmp )
+{
+ #ifdef __HOSTBOOT_MODULE
+
+ // Bank is stored as MBA "(DDR4): bg1-bg0,b1-b0 (4-bit)" in a MemAddr.
+ // bank group - 2 bits (bg1-bg0)
+ io_tmp = ( io_tmp << 2 ) | ( (i_addr.getBank() >> 2) & 0x03 );
+
+ // bank - 3 bits (b2-b0)
+ io_tmp = ( io_tmp << 3 ) | ( i_addr.getBank() & 0x03 );
+
+ // Row is stored as "MBA: r17-r0 (18-bit)" in a MemAddr.
+ // row - 18 bits (r17-r0)
+ io_tmp = ( io_tmp << 18 ) | ( i_addr.getRow() & 0x0003ffff );
+
+ #endif // __HOSTBOOT_MODULE
+}
//------------------------------------------------------------------------------
@@ -297,7 +324,7 @@ uint32_t setRowRepairData( TargetHandle_t i_dimm,
MemRowRepair l_rowRepair( i_dimm, i_rank, l_data );
- o_rc = setRowRepairData<TYPE_MBA>( i_dimm, i_rank, l_rowRepair );
+ o_rc = setRowRepairData<T>( i_dimm, i_rank, l_rowRepair );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "setRowRepairData() failed" );
@@ -323,6 +350,11 @@ uint32_t setRowRepairData<TYPE_MCA>( TargetHandle_t i_dimm,
const MemRank & i_rank,
const MemAddr & i_addr,
uint8_t i_dram );
+template
+uint32_t setRowRepairData<TYPE_OCMB_CHIP>( TargetHandle_t i_dimm,
+ const MemRank & i_rank,
+ const MemAddr & i_addr,
+ uint8_t i_dram );
//------------------------------------------------------------------------------
@@ -362,6 +394,9 @@ uint32_t clearRowRepairData<TYPE_MBA>( TargetHandle_t i_dimm,
template
uint32_t clearRowRepairData<TYPE_MCA>( TargetHandle_t i_dimm,
const MemRank & i_rank );
+template
+uint32_t clearRowRepairData<TYPE_OCMB_CHIP>( TargetHandle_t i_dimm,
+ const MemRank & i_rank );
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.C b/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.C
index 561c11dda..d58d6a177 100755
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.C
@@ -53,7 +53,7 @@ MemSymbol::MemSymbol( TARGETING::TargetHandle_t i_trgt, const MemRank & i_rank,
PRDF_ASSERT( nullptr != i_trgt );
PRDF_ASSERT( TYPE_MBA == getTargetType(i_trgt) ||
TYPE_MCA == getTargetType(i_trgt) ||
- TYPE_MEM_PORT == getTargetType(i_trgt) );
+ TYPE_OCMB_CHIP == getTargetType(i_trgt) );
// Allowing an invalid symbol. Use isValid() to check validity.
PRDF_ASSERT( i_pins <= CEN_SYMBOL::BOTH_SYMBOL_DQS );
}
@@ -83,9 +83,9 @@ MemSymbol MemSymbol::fromGalois( TargetHandle_t i_trgt, const MemRank & i_rank,
if ( 0 != (i_mask & 0xaa) ) pins |= EVEN_SYMBOL_DQ;
if ( 0 != (i_mask & 0x55) ) pins |= ODD_SYMBOL_DQ;
}
- else if ( TYPE_MCA == trgtType || TYPE_MEM_PORT == trgtType )
+ else if ( TYPE_MCA == trgtType || TYPE_OCMB_CHIP == trgtType )
{
- // 1 pin for MCA/MEM_PORT.
+ // 1 pin for MCA/TYPE_OCMB_CHIP.
if ( 0 != (i_mask & 0xff) ) pins |= ODD_SYMBOL_DQ;
}
else
@@ -112,9 +112,9 @@ uint8_t MemSymbol::getDq() const
{
dq = symbol2Dq<TYPE_MCA>( iv_symbol );
}
- else if ( TYPE_MEM_PORT == trgtType )
+ else if ( TYPE_OCMB_CHIP == trgtType )
{
- dq = symbol2Dq<TYPE_MEM_PORT>( iv_symbol );
+ dq = symbol2Dq<TYPE_OCMB_CHIP>( iv_symbol );
}
else
{
@@ -140,9 +140,9 @@ uint8_t MemSymbol::getPortSlct() const
{
portSlct = symbol2PortSlct<TYPE_MCA>( iv_symbol );
}
- else if ( TYPE_MEM_PORT == trgtType )
+ else if ( TYPE_OCMB_CHIP == trgtType )
{
- portSlct = symbol2PortSlct<TYPE_MEM_PORT>( iv_symbol );
+ portSlct = symbol2PortSlct<TYPE_OCMB_CHIP>( iv_symbol );
}
else
{
@@ -159,22 +159,26 @@ uint8_t MemSymbol::getDram() const
{
uint8_t dram = 0;
TYPE trgtType = getTargetType( iv_trgt );
- bool isX4 = isDramWidthX4( iv_trgt );
+ bool isX4 = true;
if ( TYPE_MBA == trgtType )
{
+ isX4 = isDramWidthX4( iv_trgt );
dram = isX4 ? symbol2Nibble<TYPE_MBA>( iv_symbol )
: symbol2Byte <TYPE_MBA>( iv_symbol );
}
else if ( TYPE_MCA == trgtType )
{
+ isX4 = isDramWidthX4( iv_trgt );
dram = isX4 ? symbol2Nibble<TYPE_MCA>( iv_symbol )
: symbol2Byte <TYPE_MCA>( iv_symbol );
}
- else if ( TYPE_MEM_PORT == trgtType )
+ else if ( TYPE_OCMB_CHIP == trgtType )
{
- dram = isX4 ? symbol2Nibble<TYPE_MEM_PORT>( iv_symbol )
- : symbol2Byte <TYPE_MEM_PORT>( iv_symbol );
+ TargetHandle_t dimm = getConnectedDimm(iv_trgt, iv_rank, getPortSlct());
+ isX4 = isDramWidthX4( dimm );
+ dram = isX4 ? symbol2Nibble<TYPE_OCMB_CHIP>( iv_symbol )
+ : symbol2Byte <TYPE_OCMB_CHIP>( iv_symbol );
}
else
{
@@ -200,14 +204,24 @@ uint8_t MemSymbol::getDramRelCenDqs() const
const uint8_t X4_DRAM_SPARE_UPPER = 19;
const uint8_t X8_DRAM_SPARE = 9;
+ bool isX4 = true;
+ if ( TYPE_OCMB_CHIP == getTargetType(iv_trgt) )
+ {
+ TargetHandle_t dimm = getConnectedDimm(iv_trgt, iv_rank, getPortSlct());
+ isX4 = isDramWidthX4( dimm );
+ }
+ else
+ {
+ isX4 = isDramWidthX4( iv_trgt );
+ }
- uint8_t l_dramWidth = ( isDramWidthX4(iv_trgt) ) ? 4 : 8;
+ uint8_t l_dramWidth = ( isX4 ) ? 4 : 8;
uint8_t l_dram = getDq() / l_dramWidth; // (x8: 0-9, x4: 0-19)
// Adjust for spares
if ( isDramSpared() )
{
- if ( isDramWidthX4(iv_trgt) )
+ if ( isX4 )
{
uint8_t l_bit = getDq() % DQS_PER_BYTE;
l_dram = ( l_bit < 4 ) ? X4_DRAM_SPARE_LOWER : X4_DRAM_SPARE_UPPER;
@@ -219,7 +233,7 @@ uint8_t MemSymbol::getDramRelCenDqs() const
}
else if ( isEccSpared() )
{
- l_dram = ( isDramWidthX4(iv_trgt) ) ? X4_ECC_SPARE : X8_ECC_SPARE;
+ l_dram = ( isX4 ) ? X4_ECC_SPARE : X8_ECC_SPARE;
}
return l_dram;
@@ -231,7 +245,16 @@ uint8_t MemSymbol::getDramRelCenDqs() const
uint8_t MemSymbol::getDramPins() const
{
TYPE trgtType = getTargetType( iv_trgt );
- bool isX4 = isDramWidthX4( iv_trgt );
+ bool isX4 = true;
+ if ( TYPE_OCMB_CHIP == trgtType )
+ {
+ TargetHandle_t dimm = getConnectedDimm(iv_trgt, iv_rank, getPortSlct());
+ isX4 = isDramWidthX4( dimm );
+ }
+ else
+ {
+ isX4 = isDramWidthX4( iv_trgt );
+ }
uint32_t dps = 0;
uint32_t spd = 0;
@@ -241,7 +264,7 @@ uint8_t MemSymbol::getDramPins() const
dps = MBA_DQS_PER_SYMBOL;
spd = isX4 ? MBA_SYMBOLS_PER_NIBBLE : MBA_SYMBOLS_PER_BYTE;
}
- else if ( TYPE_MCA == trgtType || TYPE_MEM_PORT == trgtType )
+ else if ( TYPE_MCA == trgtType || TYPE_OCMB_CHIP == trgtType )
{
dps = MEM_DQS_PER_SYMBOL;
spd = isX4 ? MEM_SYMBOLS_PER_NIBBLE : MEM_SYMBOLS_PER_BYTE;
@@ -261,7 +284,16 @@ uint8_t MemSymbol::getDramSymbol() const
{
uint8_t dramSymbol = SYMBOLS_PER_RANK;
TYPE trgtType = getTargetType( iv_trgt );
- bool isX4 = isDramWidthX4( iv_trgt );
+ bool isX4 = true;
+ if ( TYPE_OCMB_CHIP == trgtType )
+ {
+ TargetHandle_t dimm = getConnectedDimm(iv_trgt, iv_rank, getPortSlct());
+ isX4 = isDramWidthX4( dimm );
+ }
+ else
+ {
+ isX4 = isDramWidthX4( iv_trgt );
+ }
uint8_t dram = getDram();
if ( TYPE_MBA == trgtType )
@@ -274,10 +306,10 @@ uint8_t MemSymbol::getDramSymbol() const
dramSymbol = isX4 ? nibble2Symbol<TYPE_MCA>( dram )
: byte2Symbol <TYPE_MCA>( dram );
}
- else if ( TYPE_MEM_PORT == trgtType )
+ else if ( TYPE_OCMB_CHIP == trgtType )
{
- dramSymbol = isX4 ? nibble2Symbol<TYPE_MEM_PORT>( dram )
- : byte2Symbol <TYPE_MEM_PORT>( dram );
+ dramSymbol = isX4 ? nibble2Symbol<TYPE_OCMB_CHIP>( dram )
+ : byte2Symbol <TYPE_OCMB_CHIP>( dram );
}
else
{
@@ -435,16 +467,16 @@ uint32_t getMemReadSymbol<TYPE_MBA>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
template<>
-uint32_t getMemReadSymbol<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- MemSymbol & o_sym1,
- MemSymbol & o_sym2 )
+uint32_t getMemReadSymbol<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ MemSymbol & o_sym1,
+ MemSymbol & o_sym2 )
{
- #define PRDF_FUNC "[getMemReadSymbol<TYPE_MEM_PORT>] "
+ #define PRDF_FUNC "[getMemReadSymbol<TYPE_OCMB_CHIP>] "
// Check parameters
PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
uint32_t o_rc = SUCCESS;
@@ -453,14 +485,12 @@ uint32_t getMemReadSymbol<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
do
{
// Get the NCE/TCE galois and mask from hardware.
- ExtensibleChip * ocmbChip = getConnectedParent(i_chip, TYPE_OCMB_CHIP);
-
- SCAN_COMM_REGISTER_CLASS * reg = ocmbChip->getRegister("MBSEVR0");
+ SCAN_COMM_REGISTER_CLASS * reg = i_chip->getRegister("MBSEVR0");
o_rc = reg->Read();
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "Read() failed on MBSEVR0: "
- "ocmbChip=0x%08x", ocmbChip->getHuid() );
+ "i_chip=0x%08x", i_chip->getHuid() );
break;
}
@@ -480,8 +510,8 @@ uint32_t getMemReadSymbol<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
tceGalois, tceMask );
MemSymbol sp0, sp1, ecc;
- o_rc = mssGetSteerMux<TYPE_MEM_PORT>( i_chip->getTrgt(), i_rank,
- sp0, sp1, ecc );
+ o_rc = mssGetSteerMux<TYPE_OCMB_CHIP>( i_chip->getTrgt(), i_rank,
+ sp0, sp1, ecc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "mssGetSteerMux() failed. HUID: 0x%08x "
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.H b/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.H
index c16972fd8..00b0c7cfd 100755
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.H
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.H
@@ -79,7 +79,7 @@ class MemSymbol
/**
* @brief Creates a MemSymbol from a symbol.
- * @param i_trgt MBA, MCA, or MEM_PORT target.
+ * @param i_trgt MBA, MCA, or OCMB_CHIP target.
* @param i_rank The rank this symbol is on.
* @param i_symbol The input symbol.
* @param i_pins See enum DqMask.
@@ -95,7 +95,7 @@ class MemSymbol
/**
* @brief Creates a MemSymbol from a Galois field.
- * @param i_trgt MBA, MCA, or MEM_PORT target.
+ * @param i_trgt MBA, MCA, or OCMB_CHIP target.
* @param i_rank The rank this symbol is on.
* @param i_galois The Galois field.
* @param i_mask The bit mask.
@@ -122,7 +122,7 @@ class MemSymbol
MemRank getRank() const { return iv_rank; };
/** @return The port select for this symbol. Only relevant on MBA. Will
- * always return 0 for MCA and MEM_PORT. */
+ * always return 0 for MCA and OCMB. */
uint8_t getPortSlct() const;
/** @return The DRAM index for this symbol. */
@@ -218,7 +218,7 @@ class MemSymbol
/**
* @brief Reads the memory NCE/TCE vector trap register from hardware.
- * @param i_chip MCA, MBA, or MEM_PORT.
+ * @param i_chip MCA, MBA, or OCMB_CHIP.
* @param i_rank The rank this symbol is on.
* @param o_sym1 The first symbol. Should always be valid for both NCE/TCE.
* @param o_sym2 The second symbol. Only valid for TCEs.
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemThresholds.C b/src/usr/diag/prdf/common/plat/mem/prdfMemThresholds.C
index f6403f219..f9c73b739 100755
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemThresholds.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemThresholds.C
@@ -173,7 +173,8 @@ void getMnfgMemCeTh( ExtensibleChip * i_chip, const MemRank & i_rank,
else
{
// Get DRAM size
- uint8_t size = MemUtils::getDramSize<T>( i_chip, i_rank.getDimmSlct() );
+ uint8_t size = MemUtils::getDramSize<T>( i_chip->getTrgt(),
+ i_rank.getDimmSlct() );
// Get number of ranks per DIMM select.
uint8_t rankCount = getNumRanksPerDimm<T>( i_chip->getTrgt(),
@@ -209,7 +210,7 @@ void getMnfgMemCeTh<TYPE_MBA>( ExtensibleChip * i_chip, const MemRank & i_rank,
uint32_t & o_cePerDimm );
template
-void getMnfgMemCeTh<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
+void getMnfgMemCeTh<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
const MemRank & i_rank, uint32_t & o_cePerDram, uint32_t & o_cePerRank,
uint32_t & o_cePerDimm );
@@ -236,14 +237,8 @@ uint32_t getScrubCeThreshold( ExtensibleChip * i_chip, const MemRank & i_rank )
// need these templates to avoid linker errors
template
-uint32_t getScrubCeThreshold<TYPE_MCA>( ExtensibleChip * i_chip,
- const MemRank & i_rank );
-template
uint32_t getScrubCeThreshold<TYPE_MBA>( ExtensibleChip * i_chip,
const MemRank & i_rank );
-template
-uint32_t getScrubCeThreshold<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- const MemRank & i_rank );
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemUtils.C b/src/usr/diag/prdf/common/plat/mem/prdfMemUtils.C
index 744e55e69..64677f1ae 100755
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemUtils.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemUtils.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2019 */
+/* Contributors Listed Below - COPYRIGHT 2013,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -31,11 +31,14 @@
// Framework includes
#include <iipServiceDataCollector.h>
+#include <iipSystem.h>
#include <prdfExtensibleChip.H>
+#include <prdfGlobal_common.H>
#include <UtilHash.H>
// Platform includes
#include <prdfCenMbaDataBundle.H>
+#include <prdfOcmbDataBundle.H>
#include <prdfCenMembufDataBundle.H>
#include <prdfCenMembufExtraSig.H>
#include <prdfMemSymbol.H>
@@ -224,12 +227,12 @@ int32_t collectCeStats<TYPE_MCA>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
template<>
-int32_t collectCeStats<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- MaintSymbols & o_maintStats,
- MemSymbol & o_chipMark, uint8_t i_thr )
+int32_t collectCeStats<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ MaintSymbols & o_maintStats,
+ MemSymbol & o_chipMark, uint8_t i_thr )
{
- #define PRDF_FUNC "[MemUtils::collectCeStats<TYPE_MEM_PORT>] "
+ #define PRDF_FUNC "[MemUtils::collectCeStats<TYPE_OCMB_CHIP>] "
int32_t o_rc = SUCCESS;
o_chipMark = MemSymbol(); // Initially invalid.
@@ -238,10 +241,13 @@ int32_t collectCeStats<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
{
PRDF_ASSERT( 0 != i_thr );
- TargetHandle_t memPortTrgt = i_chip->getTrgt();
- ExtensibleChip * ocmbChip = getConnectedParent(i_chip, TYPE_OCMB_CHIP);
+ TargetHandle_t ocmbTrgt = i_chip->getTrgt();
- const bool isX4 = isDramWidthX4(memPortTrgt);
+ // TODO RTC 210072 - support for multiple ports
+ TargetHandle_t memPortTrgt = getConnectedChild( ocmbTrgt,
+ TYPE_MEM_PORT, 0 );
+ TargetHandle_t dimm = getConnectedDimm( memPortTrgt, i_rank );
+ const bool isX4 = isDramWidthX4( dimm );
// Use this map to keep track of the total counts per DRAM.
DramCountMap dramCounts;
@@ -252,7 +258,7 @@ int32_t collectCeStats<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
for ( uint8_t regIdx = 0; regIdx < CE_REGS_PER_PORT; regIdx++ )
{
reg_str = ocmbCeStatReg[regIdx];
- reg = ocmbChip->getRegister( reg_str );
+ reg = i_chip->getRegister( reg_str );
o_rc = reg->Read();
if ( SUCCESS != o_rc )
@@ -272,8 +278,8 @@ int32_t collectCeStats<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
uint8_t sym = baseSymbol + i;
PRDF_ASSERT( sym < SYMBOLS_PER_RANK );
- uint8_t dram = isX4 ? symbol2Nibble<TYPE_MEM_PORT>( sym )
- : symbol2Byte <TYPE_MEM_PORT>( sym );
+ uint8_t dram = isX4 ? symbol2Nibble<TYPE_OCMB_CHIP>( sym )
+ : symbol2Byte <TYPE_OCMB_CHIP>( sym );
// Keep track of the total DRAM counts.
dramCounts[dram].totalCount += count;
@@ -286,7 +292,7 @@ int32_t collectCeStats<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
dramCounts[dram].symbolCount++;
SymbolData symData;
- symData.symbol = MemSymbol::fromSymbol( memPortTrgt, i_rank,
+ symData.symbol = MemSymbol::fromSymbol( ocmbTrgt, i_rank,
sym, CEN_SYMBOL::ODD_SYMBOL_DQ );
if ( !symData.symbol.isValid() )
{
@@ -329,11 +335,11 @@ int32_t collectCeStats<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
if ( 0 != highestCount )
{
- uint8_t sym = isX4 ? nibble2Symbol<TYPE_MEM_PORT>( highestDram )
- : byte2Symbol <TYPE_MEM_PORT>( highestDram );
+ uint8_t sym = isX4 ? nibble2Symbol<TYPE_OCMB_CHIP>( highestDram )
+ : byte2Symbol <TYPE_OCMB_CHIP>( highestDram );
PRDF_ASSERT( sym < SYMBOLS_PER_RANK );
- o_chipMark = MemSymbol::fromSymbol( memPortTrgt, i_rank, sym );
+ o_chipMark = MemSymbol::fromSymbol( ocmbTrgt, i_rank, sym );
}
} while(0);
@@ -514,19 +520,18 @@ int32_t collectCeStats<TYPE_MBA>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
template<>
-uint8_t getDramSize<TYPE_MCA>(ExtensibleChip *i_chip, uint8_t i_dimmSlct)
+uint8_t getDramSize<TYPE_MCA>( TargetHandle_t i_trgt, uint8_t i_dimmSlct )
{
#define PRDF_FUNC "[MemUtils::getDramSize] "
- PRDF_ASSERT( TYPE_MCA == i_chip->getType() );
+ PRDF_ASSERT( TYPE_MCA == getTargetType(i_trgt) );
PRDF_ASSERT( i_dimmSlct < DIMM_SLCT_PER_PORT );
- TargetHandle_t mcaTrgt = i_chip->getTrgt();
- TargetHandle_t mcsTrgt = getConnectedParent( mcaTrgt, TYPE_MCS );
+ TargetHandle_t mcsTrgt = getConnectedParent( i_trgt, TYPE_MCS );
PRDF_ASSERT( nullptr != mcsTrgt );
- uint8_t mcaRelPos = i_chip->getPos() % MAX_MCA_PER_MCS;
+ uint8_t mcaRelPos = getTargetPosition(i_trgt) % MAX_MCA_PER_MCS;
uint8_t tmp[MAX_MCA_PER_MCS][DIMM_SLCT_PER_PORT];
@@ -542,19 +547,22 @@ uint8_t getDramSize<TYPE_MCA>(ExtensibleChip *i_chip, uint8_t i_dimmSlct)
}
template<>
-uint8_t getDramSize<TYPE_MBA>(ExtensibleChip *i_chip, uint8_t i_dimmSlct)
+uint8_t getDramSize<TYPE_MBA>( TargetHandle_t i_trgt, uint8_t i_dimmSlct )
{
#define PRDF_FUNC "[MemUtils::getDramSize] "
- PRDF_ASSERT( TYPE_MBA == i_chip->getType() );
+ PRDF_ASSERT( TYPE_MBA == getTargetType(i_trgt) );
uint8_t o_size = 0;
do
{
- ExtensibleChip * membufChip = getConnectedParent(i_chip, TYPE_MEMBUF);
+ TargetHandle_t membuf = getConnectedParent(i_trgt, TYPE_MEMBUF);
+ ExtensibleChip * membufChip =
+ (ExtensibleChip*)systemPtr->GetChip(membuf);
+ PRDF_ASSERT( nullptr != membufChip );
- uint32_t pos = i_chip->getPos();
+ uint32_t pos = getTargetPosition(i_trgt);
const char * reg_str = (0 == pos) ? "MBA0_MBAXCR" : "MBA1_MBAXCR";
SCAN_COMM_REGISTER_CLASS * reg = membufChip->getRegister( reg_str );
@@ -562,7 +570,7 @@ uint8_t getDramSize<TYPE_MBA>(ExtensibleChip *i_chip, uint8_t i_dimmSlct)
if ( SUCCESS != rc )
{
PRDF_ERR( PRDF_FUNC "Read() failed on %s. Target=0x%08x",
- reg_str, i_chip->getHuid() );
+ reg_str, getHuid(i_trgt) );
break;
}
@@ -579,18 +587,16 @@ uint8_t getDramSize<TYPE_MBA>(ExtensibleChip *i_chip, uint8_t i_dimmSlct)
}
template<>
-uint8_t getDramSize<TYPE_MEM_PORT>(ExtensibleChip *i_chip, uint8_t i_dimmSlct)
+uint8_t getDramSize<TYPE_MEM_PORT>( TargetHandle_t i_trgt, uint8_t i_dimmSlct )
{
#define PRDF_FUNC "[MemUtils::getDramSize] "
- PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
+ PRDF_ASSERT( TYPE_MEM_PORT == getTargetType(i_trgt) );
PRDF_ASSERT( i_dimmSlct < DIMM_SLCT_PER_PORT );
- TargetHandle_t memPortTrgt = i_chip->getTrgt();
-
uint8_t tmp[DIMM_SLCT_PER_PORT];
- if ( !memPortTrgt->tryGetAttr<TARGETING::ATTR_MEM_EFF_DRAM_DENSITY>(tmp) )
+ if ( !i_trgt->tryGetAttr<TARGETING::ATTR_MEM_EFF_DRAM_DENSITY>(tmp) )
{
PRDF_ERR( PRDF_FUNC "Failed to get ATTR_MEM_EFF_DRAM_DENSITY" );
PRDF_ASSERT( false );
@@ -601,6 +607,25 @@ uint8_t getDramSize<TYPE_MEM_PORT>(ExtensibleChip *i_chip, uint8_t i_dimmSlct)
#undef PRDF_FUNC
}
+template<>
+uint8_t getDramSize<TYPE_OCMB_CHIP>( TargetHandle_t i_trgt, uint8_t i_dimmSlct )
+{
+ #define PRDF_FUNC "[MemUtils::getDramSize] "
+
+ PRDF_ASSERT( TYPE_OCMB_CHIP == getTargetType(i_trgt) );
+ PRDF_ASSERT( i_dimmSlct < DIMM_SLCT_PER_PORT );
+
+ // TODO RTC 210072 - Explorer only has one port, however, multiple ports
+ // will be supported in the future. Updates will need to be made here so we
+ // can get the relevant port.
+
+ TargetHandle_t memPort = getConnectedChild( i_trgt, TYPE_MEM_PORT, 0 );
+
+ return getDramSize<TYPE_MEM_PORT>( memPort, i_dimmSlct );
+
+ #undef PRDF_FUNC
+}
+
//------------------------------------------------------------------------------
template<>
@@ -639,6 +664,34 @@ void cleanupChnlAttns<TYPE_MEMBUF>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
+template<>
+void cleanupChnlAttns<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[MemUtils::cleanupChnlAttns] "
+
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+
+ // No cleanup if this is a checkstop attention.
+ if ( CHECK_STOP == io_sc.service_data->getPrimaryAttnType() ) return;
+
+ #ifdef __HOSTBOOT_MODULE // only do cleanup in Hostboot, no-op in FSP
+
+ // Clear the associated FIR bits for all attention types. DSTLFIR[0:7]
+ ExtensibleChip * mcc = getConnectedParent( i_chip, TYPE_MCC );
+
+ SCAN_COMM_REGISTER_CLASS * reg = mcc->getRegister( "DSTLFIR_AND" );
+
+ reg->setAllBits();
+ reg->SetBitFieldJustified( 0, 8, 0 );
+ reg->Write();
+
+ #endif // Hostboot only
+
+ #undef PRDF_FUNC
+}
+
//------------------------------------------------------------------------------
template<TARGETING::TYPE T>
@@ -1288,6 +1341,361 @@ bool analyzeChnlFail<TYPE_MC>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
+bool __queryUcsOmic( ExtensibleChip * i_omic, ExtensibleChip * i_mcc,
+ TargetHandle_t i_omi )
+{
+ PRDF_ASSERT( nullptr != i_omic );
+ PRDF_ASSERT( nullptr != i_mcc );
+ PRDF_ASSERT( nullptr != i_omi );
+ PRDF_ASSERT( TYPE_OMIC == i_omic->getType() );
+ PRDF_ASSERT( TYPE_MCC == i_mcc->getType() );
+ PRDF_ASSERT( TYPE_OMI == getTargetType(i_omi) );
+
+ bool o_activeAttn = false;
+
+ do
+ {
+ // Get the DSTLCFG2 register to check whether channel fail is enabled
+ // NOTE: DSTLCFG2[22] = 0b0 to enable chnl fail for subchannel A
+ // NOTE: DSTLCFG2[23] = 0b0 to enable chnl fail for subchannel B
+ SCAN_COMM_REGISTER_CLASS * cnfg = i_mcc->getRegister( "DSTLCFG2" );
+
+ // Get the position of the inputted OMI relative to the parent MCC (0-1)
+ // to determine which channel we need to check.
+ uint8_t omiPosRelMcc = getTargetPosition(i_omi) % MAX_OMI_PER_MCC;
+
+ // If channel fail isn't configured, no need to continue.
+ if ( cnfg->IsBitSet(22 + omiPosRelMcc) ) break;
+
+ // Check the OMIDLFIR for UCS (relevant bits: 0,20,40)
+ SCAN_COMM_REGISTER_CLASS * fir = i_omic->getRegister("OMIDLFIR");
+ SCAN_COMM_REGISTER_CLASS * mask = i_omic->getRegister("OMIDLFIR_MASK");
+ SCAN_COMM_REGISTER_CLASS * act0 = i_omic->getRegister("OMIDLFIR_ACT0");
+ SCAN_COMM_REGISTER_CLASS * act1 = i_omic->getRegister("OMIDLFIR_ACT1");
+
+ if ( SUCCESS == ( fir->Read() | mask->Read() |
+ act0->Read() | act1->Read() ) )
+ {
+ // Get the position of the inputted OMI relative to the parent
+ // OMIC (0-2). We'll need to use ATTR_OMI_DL_GROUP_POS for this.
+ uint8_t omiPosRelOmic = i_omi->getAttr<ATTR_OMI_DL_GROUP_POS>();
+
+ // Get the bit offset for the bit relevant to the inputted OMI.
+ // 0 : OMI-DL 0
+ // 20: OMI-DL 1
+ // 40: OMI-DL 2
+ uint8_t bitOff = omiPosRelOmic * 20;
+
+ // Check if there is a UNIT_CS for the relevant bits in the OMIDLFIR
+ // Note: The OMIDLFIR can't actually be set up to report UNIT_CS
+ // attentions, instead, as a workaround, the relevant channel fail
+ // bits will be set as recoverable bits and we will manually set
+ // the attention types to UNIT_CS in our handling of those errors.
+ if ( fir->IsBitSet(bitOff) && !mask->IsBitSet(bitOff) &&
+ !act0->IsBitSet(bitOff) && act1->IsBitSet(bitOff) )
+ {
+ o_activeAttn = true;
+ }
+ }
+ }while(0);
+
+ return o_activeAttn;
+}
+
+bool __queryUcsMcc( ExtensibleChip * i_mcc, TargetHandle_t i_omi )
+{
+ PRDF_ASSERT( nullptr != i_mcc );
+ PRDF_ASSERT( nullptr != i_omi );
+ PRDF_ASSERT( TYPE_MCC == i_mcc->getType() );
+ PRDF_ASSERT( TYPE_OMI == getTargetType(i_omi) );
+
+ bool o_activeAttn = false;
+
+ // Get the position of the inputted OMI relative to the parent MCC (0-1)
+ // to determine which channel we need to check.
+ uint8_t omiPos = getTargetPosition(i_omi) % MAX_OMI_PER_MCC;
+
+ // Maps of the DSTLFIR UCS bits to their relevant channel fail
+ // configuration bit in DSTLCFG2. Ex: {12,28} = DSTLFIR[12], DSTLCFG2[28]
+ // NOTE: there is a separate map for each subchannel.
+ const std::map<uint8_t,uint8_t> dstlfirMapChanA =
+ { {12,28}, {16,30}, {22,24} };
+
+ const std::map<uint8_t,uint8_t> dstlfirMapChanB =
+ { {13,29}, {17,31}, {23,25} };
+
+ // Check the DSTLFIR for UCS
+ SCAN_COMM_REGISTER_CLASS * fir = i_mcc->getRegister( "DSTLFIR" );
+ SCAN_COMM_REGISTER_CLASS * mask = i_mcc->getRegister( "DSTLFIR_MASK" );
+ SCAN_COMM_REGISTER_CLASS * act0 = i_mcc->getRegister( "DSTLFIR_ACT0" );
+ SCAN_COMM_REGISTER_CLASS * act1 = i_mcc->getRegister( "DSTLFIR_ACT1" );
+ SCAN_COMM_REGISTER_CLASS * cnfg = i_mcc->getRegister( "DSTLCFG2" );
+
+ if ( SUCCESS == (fir->Read() | mask->Read() | act0->Read() | act1->Read() |
+ cnfg->Read()) )
+ {
+ // Get which relevant channel we need to check.
+ std::map<uint8_t,uint8_t> dstlfirMap;
+ dstlfirMap = (0 == omiPos) ? dstlfirMapChanA : dstlfirMapChanB;
+
+ for ( auto const & bits : dstlfirMap )
+ {
+ uint8_t firBit = bits.first;
+ uint8_t cnfgBit = bits.second;
+
+ // NOTE: Channel fail is enabled if the config bit is set to 0b0
+ if ( !cnfg->IsBitSet(cnfgBit) && fir->IsBitSet(firBit) &&
+ !mask->IsBitSet(firBit) && act0->IsBitSet(firBit) &&
+ act1->IsBitSet(firBit) )
+ {
+ o_activeAttn = true;
+ }
+ }
+ }
+
+ // Maps of the USTLFIR UCS bits to their relevant channel fail
+ // config bit in USTLFAILMASK. Ex: {0,54} = USTLFIR[0], USTLFAILMASK[54]
+ // NOTE: there is a separate map for each subchannel.
+ const std::map<uint8_t,uint8_t> ustlfirMapChanA =
+ { { 0,54}, { 2,48}, {27,56}, {35,49}, {37,50}, {39,51}, {41,52}, {43,53},
+ {49,55}, {51,50}, {53,50}, {55,48}, {59,56} };
+ const std::map<uint8_t,uint8_t> ustlfirMapChanB =
+ { { 1,54}, { 3,48}, {28,56}, {36,49}, {38,50}, {40,51}, {42,52}, {44,53},
+ {50,55}, {52,50}, {54,50}, {56,48}, {60,56} };
+
+ // Check the USTLFIR for UCS
+ fir = i_mcc->getRegister( "USTLFIR" );
+ mask = i_mcc->getRegister( "USTLFIR_MASK" );
+ act0 = i_mcc->getRegister( "USTLFIR_ACT0" );
+ act1 = i_mcc->getRegister( "USTLFIR_ACT1" );
+ cnfg = i_mcc->getRegister( "USTLFAILMASK" );
+
+ if ( SUCCESS == (fir->Read() | mask->Read() | act0->Read() | act1->Read() |
+ cnfg->Read()) )
+ {
+ // Get which relevant channel we need to check.
+ std::map<uint8_t,uint8_t> ustlfirMap;
+ ustlfirMap = (0 == omiPos) ? ustlfirMapChanA : ustlfirMapChanB;
+
+ for ( auto const & bits : ustlfirMap )
+ {
+ uint8_t firBit = bits.first;
+ uint8_t cnfgBit = bits.second;
+
+ // NOTE: Channel fail is enabled if the config bit is set to 0b0
+ if ( !cnfg->IsBitSet(cnfgBit) && fir->IsBitSet(firBit) &&
+ !mask->IsBitSet(firBit) && act0->IsBitSet(firBit) &&
+ act1->IsBitSet(firBit) )
+ {
+ o_activeAttn = true;
+ }
+ }
+ }
+
+ return o_activeAttn;
+}
+
+bool __queryUcsOcmb( ExtensibleChip * i_ocmb )
+{
+ PRDF_ASSERT( nullptr != i_ocmb );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_ocmb->getType() );
+
+ bool o_activeAttn = false;
+
+ // We can't use the GLOBAL_CS_FIR. It will not clear automatically when a
+ // channel has failed because the hardware clocks have stopped. Also, since
+ // it is a virtual register there really is no way to clear it. Fortunately
+ // we have the INTER_STATUS_REG that will tell us if there is an active
+ // attention. Note that we clear this register as part of the channel
+ // failure cleanup. So we can rely on this register to determine if there is
+ // a new channel failure.
+
+ SCAN_COMM_REGISTER_CLASS * fir = i_ocmb->getRegister("INTER_STATUS_REG");
+
+ if ( SUCCESS == fir->Read() )
+ {
+ o_activeAttn = fir->IsBitSet(2); // Checkstop bit.
+ }
+
+ return o_activeAttn;
+}
+
+//------------------------------------------------------------------------------
+
+template<TARGETING::TYPE T>
+bool __analyzeChnlFail( TargetHandle_t i_trgt,
+ STEP_CODE_DATA_STRUCT & io_sc );
+
+template<>
+bool __analyzeChnlFail<TYPE_OMI>( TargetHandle_t i_omi,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[MemUtils::__analyzeChnlFail<TYPE_OMI>] "
+
+ PRDF_ASSERT( nullptr != i_omi );
+ PRDF_ASSERT( TYPE_OMI == getTargetType(i_omi) );
+
+ uint32_t o_analyzed = false;
+
+ do
+ {
+ // Skip if currently analyzing a host attention. This is a required for
+ // a rare scenario when a channel failure occurs after PRD is called to
+ // handle the host attention.
+ if ( HOST_ATTN == io_sc.service_data->getPrimaryAttnType() ) break;
+
+ // Get the needed ExtensibleChips for analysis
+ TargetHandle_t ocmb = getConnectedChild( i_omi, TYPE_OCMB_CHIP, 0 );
+ ExtensibleChip * ocmbChip = (ExtensibleChip *)systemPtr->GetChip(ocmb);
+
+ TargetHandle_t omic = getConnectedParent( i_omi, TYPE_OMIC );
+ ExtensibleChip * omicChip = (ExtensibleChip *)systemPtr->GetChip(omic);
+
+ TargetHandle_t mcc = getConnectedParent( i_omi, TYPE_MCC );
+ ExtensibleChip * mccChip = (ExtensibleChip *)systemPtr->GetChip(mcc);
+
+ // Do an initial query for channel fail attentions from the targets.
+ // This is to check whether we actually have an active channel fail
+ // attention before checking whether it is a side effect of some
+ // recoverable attention or not.
+ if ( !__queryUcsOmic(omicChip, mccChip, i_omi) &&
+ !__queryUcsMcc(mccChip, i_omi) &&
+ !__queryUcsOcmb(ocmbChip) )
+ {
+ // If no channel fail attentions found, just break out.
+ break;
+ }
+
+ // There was a channel fail found, so take the following actions.
+
+ // Set the MEM_CHNL_FAIL flag in the SDC to indicate a channel failure
+ // has been detected and there is no need to check again.
+ io_sc.service_data->setMemChnlFail();
+
+ // Make the error log predictive and set threshold.
+ io_sc.service_data->setFlag( ServiceDataCollector::SERVICE_CALL );
+ io_sc.service_data->setFlag( ServiceDataCollector::AT_THRESHOLD );
+
+ // Channel failures will always send SUEs.
+ io_sc.service_data->setFlag( ServiceDataCollector::UERE );
+
+ // Indicate cleanup is required on this channel.
+ getOcmbDataBundle(ocmbChip)->iv_doChnlFailCleanup = true;
+
+ // Check for recoverable attentions that could have a channel failure
+ // as a side effect. These include: N/A
+ // TODO RTC 243518 -requires more input from the test team to determine
+
+ // Check OMIC for unit checkstops
+ if ( __queryUcsOmic( omicChip, mccChip, i_omi ) )
+ {
+ // Analyze UNIT_CS on the OMIC chip
+ // Note: The OMIDLFIR can't actually be set up to report UNIT_CS
+ // attentions, instead, as a workaround, the relevant channel fail
+ // bits will be set as recoverable bits and we will manually set
+ // the attention types to UNIT_CS in our handling of those errors.
+ if ( SUCCESS == omicChip->Analyze(io_sc, RECOVERABLE) )
+ {
+ o_analyzed = true;
+ break;
+ }
+ }
+
+ // Check MCC for unit checkstops
+ if ( __queryUcsMcc( mccChip, i_omi ) )
+ {
+ // Analyze UNIT_CS on the MCC chip
+ if ( SUCCESS == mccChip->Analyze(io_sc, UNIT_CS) )
+ {
+ o_analyzed = true;
+ break;
+ }
+ }
+
+ // Check OCMB for unit checkstops
+ if ( __queryUcsOcmb( ocmbChip ) )
+ {
+ // Analyze UNIT_CS on the OCMB chip
+ if ( SUCCESS == ocmbChip->Analyze(io_sc, UNIT_CS) )
+ {
+ o_analyzed = true;
+ break;
+ }
+
+ }
+ PRDF_INF( PRDF_FUNC "Failed channel detected on 0x%08x, but no active "
+ "attentions found", getHuid(i_omi) );
+ }while(0);
+
+ return o_analyzed;
+
+ #undef PRDF_FUNC
+}
+
+template<>
+bool analyzeChnlFail<TYPE_MCC>( ExtensibleChip * i_mcc,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ PRDF_ASSERT( nullptr != i_mcc );
+ PRDF_ASSERT( TYPE_MCC == i_mcc->getType() );
+
+ uint32_t o_analyzed = false;
+
+ if ( !io_sc.service_data->isMemChnlFail() )
+ {
+ // Loop through all the connected OMIs
+ for ( auto & omi : getConnected(i_mcc->getTrgt(), TYPE_OMI) )
+ {
+ o_analyzed = __analyzeChnlFail<TYPE_OMI>( omi, io_sc );
+ if ( o_analyzed ) break;
+ }
+ }
+
+ return o_analyzed;
+}
+
+template<>
+bool analyzeChnlFail<TYPE_OMIC>( ExtensibleChip * i_omic,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ PRDF_ASSERT( nullptr != i_omic );
+ PRDF_ASSERT( TYPE_OMIC == i_omic->getType() );
+
+ uint32_t o_analyzed = false;
+
+ if ( !io_sc.service_data->isMemChnlFail() )
+ {
+ // Loop through all the connected OMIs
+ for ( auto & omi : getConnected(i_omic->getTrgt(), TYPE_OMI) )
+ {
+ o_analyzed = __analyzeChnlFail<TYPE_OMI>( omi, io_sc );
+ if ( o_analyzed ) break;
+ }
+ }
+
+ return o_analyzed;
+}
+
+template<>
+bool analyzeChnlFail<TYPE_OCMB_CHIP>( ExtensibleChip * i_ocmb,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ PRDF_ASSERT( nullptr != i_ocmb );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_ocmb->getType() );
+
+ uint32_t o_analyzed = false;
+
+ if ( !io_sc.service_data->isMemChnlFail() )
+ {
+ TargetHandle_t omi = getConnectedParent( i_ocmb->getTrgt(), TYPE_OMI );
+ o_analyzed = __analyzeChnlFail<TYPE_OMI>( omi, io_sc );
+ }
+
+ return o_analyzed;
+}
+
+//------------------------------------------------------------------------------
+
template<TARGETING::TYPE T1, TARGETING::TYPE T2, TARGETING::TYPE T3>
void __cleanupChnlFail( ExtensibleChip * i_chip1, ExtensibleChip * i_chip2,
ExtensibleChip * i_chip3,
@@ -1415,6 +1823,158 @@ void cleanupChnlFail<TYPE_MEMBUF>( ExtensibleChip * i_chip,
cleanupChnlFail<TYPE_DMI>( dmiChip, io_sc );
}
+template<TARGETING::TYPE T>
+void __cleanupChnlFail( TargetHandle_t i_trgt, STEP_CODE_DATA_STRUCT & io_sc );
+
+template<>
+void __cleanupChnlFail<TYPE_OMI>( TargetHandle_t i_omi,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[MemUtils::__cleanupChnlFail] "
+
+ PRDF_ASSERT( nullptr != i_omi );
+ PRDF_ASSERT( TYPE_OMI == getTargetType(i_omi) );
+
+ do
+ {
+ // No cleanup if this is a checkstop attention.
+ if ( CHECK_STOP == io_sc.service_data->getPrimaryAttnType() ) break;
+
+ TargetHandle_t ocmb = getConnectedChild(i_omi, TYPE_OCMB_CHIP, 0);
+ ExtensibleChip * ocmbChip = (ExtensibleChip *)systemPtr->GetChip(ocmb);
+
+ // Check if cleanup is still required or has already been done.
+ if ( !getOcmbDataBundle(ocmbChip)->iv_doChnlFailCleanup ) break;
+
+ // Cleanup is complete and no longer required on this channel.
+ getOcmbDataBundle(ocmbChip)->iv_doChnlFailCleanup = false;
+
+ #ifdef __HOSTBOOT_MODULE // only do cleanup in Hostboot, no-op in FSP
+
+ TargetHandle_t omic = getConnectedParent( i_omi, TYPE_OMIC );
+ ExtensibleChip * omicChip = (ExtensibleChip *)systemPtr->GetChip(omic);
+
+ TargetHandle_t mcc = getConnectedParent( i_omi, TYPE_MCC );
+ ExtensibleChip * mccChip = (ExtensibleChip *)systemPtr->GetChip(mcc);
+
+ // Get the OMI position relative to the OMIC (0,1,2) and the MCC (0,1)
+ uint8_t omiPosRelOmic = i_omi->getAttr<ATTR_OMI_DL_GROUP_POS>();
+ uint8_t omiPosRelMcc = getTargetPosition(i_omi) % MAX_OMI_PER_MCC;
+
+ // Note that this is a clean up function. If there are any SCOM errors
+ // we will just move on and try the rest.
+ SCAN_COMM_REGISTER_CLASS * reg = nullptr;
+
+ // Mask off attentions from the OMIDLFIR in the OMIC based on the
+ // OMI position. 0-19, 20-39, 40-59
+ reg = omicChip->getRegister( "OMIDLFIR_MASK_OR" );
+ reg->SetBitFieldJustified( (omiPosRelOmic * 20), 20, 0xfffff );
+ reg->Write();
+
+ // Mask off attentions from the DSTLFIR and USTLFIR in the MCC based on
+ // the OMI position.
+ // DSTLFIR Generic Bits: 8,9,10,11,24,25,26,27
+ uint64_t mask = 0x00f000f000000000ull;
+ if ( 0 == omiPosRelMcc )
+ {
+ // DSTLFIR Subchannel A Bits: 0,1,2,3,12,14,16,18,20,22
+ mask |= 0xf00aaa0000000000ull;
+ }
+ else
+ {
+ // DSTLFIR Subchannel B Bits: 4,5,6,7,13,15,17,19,21,23
+ mask |= 0x0f05550000000000ull;
+ }
+ reg = mccChip->getRegister( "DSTLFIR_MASK_OR" );
+ reg->SetBitFieldJustified( 0, 64, mask );
+ reg->Write();
+
+ // USTLFIR Generic Bits: 6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,
+ // 22,23,24,25,26,57,58,61,62,63
+ mask = 0x03ffffe000000067ull;
+ if ( 0 == omiPosRelMcc )
+ {
+ // USTLFIR Subchannel A Bits: 0,2,4,27,29,31,33,35,37,39,41,43,45,
+ // 47,49,51,53,55,59
+ mask |= 0xa800001555555510ull;
+ }
+ else
+ {
+ // USTLFIR Subchannel B Bits: 1,3,5,28,30,32,34,36,38,40,42,44,46,
+ // 48,50,52,54,56,60
+ mask |= 0x5400000aaaaaaa88ull;
+ }
+ reg = mccChip->getRegister( "USTLFIR_MASK_OR" );
+ reg->SetBitFieldJustified( 0, 64, mask );
+ reg->Write();
+
+ // Mask off all attentions from the chiplet FIRs in the OCMB
+ reg = ocmbChip->getRegister( "OCMB_CHIPLET_FIR_MASK" );
+ reg->setAllBits(); // Blindly mask everything
+ reg->Write();
+
+
+ // To ensure FSP ATTN doesn't think there is an active attention on this
+ // OCMB, manually clear the interrupt status register.
+ reg = ocmbChip->getRegister( "INTER_STATUS_REG" );
+ reg->clearAllBits(); // Blindly clear everything
+ reg->Write();
+
+ // During runtime, send a dynamic memory deallocation message.
+ // During Memory Diagnostics, tell MDIA to stop pattern tests.
+ #ifdef __HOSTBOOT_RUNTIME
+ MemDealloc::port<TYPE_OCMB_CHIP>( ocmbChip );
+ #else
+ if ( isInMdiaMode() )
+ {
+ mdiaSendEventMsg( ocmb, MDIA::STOP_TESTING );
+ }
+ #endif
+
+ #endif // Hostboot only
+
+ }while(0);
+
+ #undef PRDF_FUNC
+}
+
+template<>
+void cleanupChnlFail<TYPE_MCC>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_MCC == i_chip->getType() );
+
+ for ( auto & omi : getConnected(i_chip->getTrgt(), TYPE_OMI) )
+ {
+ __cleanupChnlFail<TYPE_OMI>( omi, io_sc );
+ }
+}
+
+template<>
+void cleanupChnlFail<TYPE_OMIC>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_OMIC == i_chip->getType() );
+
+ for ( auto & omi : getConnected(i_chip->getTrgt(), TYPE_OMI) )
+ {
+ __cleanupChnlFail<TYPE_OMI>( omi, io_sc );
+ }
+}
+
+template<>
+void cleanupChnlFail<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+
+ TargetHandle_t omi = getConnectedParent( i_chip->getTrgt(), TYPE_OMI );
+ __cleanupChnlFail<TYPE_OMI>( omi, io_sc );
+}
+
//------------------------------------------------------------------------------
uint64_t reverseBits( uint64_t i_val, uint64_t i_numBits )
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemUtils.H b/src/usr/diag/prdf/common/plat/mem/prdfMemUtils.H
index 9759cd010..39a6051fe 100755
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemUtils.H
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemUtils.H
@@ -102,12 +102,12 @@ int32_t collectCeStats( ExtensibleChip * i_chip, const MemRank & i_rank,
/**
* @brief Gets DRAM size for an MBA, MCA, or MEM_PORT.
- * @param i_chip MBA, MCA, or MEM_PORT chip.
+ * @param i_trgt MBA, MCA, or MEM_PORT target.
* @param i_dimmSlct DIMM select. Optional for MBA chip.
* @return size for a DRAM
*/
template<TARGETING::TYPE T>
-uint8_t getDramSize( ExtensibleChip * i_chip, uint8_t i_dimmSlct = 0 );
+uint8_t getDramSize( TARGETING::TargetHandle_t i_trgt, uint8_t i_dimmSlct = 0 );
/**
* @brief determines the type of Centaur based raw card associated with MBA.
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemoryMru.C b/src/usr/diag/prdf/common/plat/mem/prdfMemoryMru.C
index bb911847e..4cd596514 100755
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemoryMru.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemoryMru.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -70,42 +70,78 @@ MemoryMru::MemoryMru( uint32_t i_memMru ) :
PRDF_ASSERT( false );
}
- // If our target is MBA, get the chnlPos from the membuf
- if ( 0 == iv_memMruMeld.s.isMca )
+ // If our target is MCA
+ if ( 1 == iv_memMruMeld.s.isMca )
{
- TargetHandle_t membuf = getConnectedChild( proc, TYPE_MEMBUF,
+ iv_target = getConnectedChild( proc, TYPE_MCA,
iv_memMruMeld.s.chnlPos );
- if ( NULL == membuf )
+ if ( NULL == iv_target )
{
- PRDF_ERR( PRDF_FUNC "Could not find functional membuf "
+ PRDF_ERR( PRDF_FUNC "Could not find functional mca "
"attached to proc 0x%08X at pos: %u", getHuid( proc ),
iv_memMruMeld.s.chnlPos );
PRDF_ASSERT( false );
}
+ }
+ // If our target is OCMB
+ else if ( 1 == iv_memMruMeld.s.isOcmb )
+ {
+ // chnlPos specifies the position of the MCC relative to the proc
+ TargetHandle_t mcc = getConnectedChild( proc, TYPE_MCC,
+ iv_memMruMeld.s.chnlPos );
+ if ( nullptr == mcc )
+ {
+ PRDF_ERR( PRDF_FUNC "Could not find functional mcc attached to "
+ "proc 0x%08x at pos: %u", getHuid(proc),
+ iv_memMruMeld.s.chnlPos );
+ PRDF_ASSERT( false );
+ }
- iv_target = getConnectedChild( membuf, TYPE_MBA,
- iv_memMruMeld.s.mbaPos );
- if ( NULL == iv_target )
+ // mbaPos specifies the position of the OMI relative to the MCC
+ TargetHandle_t omi = getConnectedChild( mcc, TYPE_OMI,
+ iv_memMruMeld.s.mbaPos );
+ if ( nullptr == omi )
{
- PRDF_ERR( PRDF_FUNC "Could not find functional mba attached "
- "to 0x%08X at pos: %u", getHuid( membuf ),
- iv_memMruMeld.s.mbaPos );
+ PRDF_ERR( PRDF_FUNC "Could not find functional omi attached to "
+ "mcc 0x%08x at pos: %u", getHuid(mcc),
+ iv_memMruMeld.s.mbaPos );
+ PRDF_ASSERT( false );
+ }
+
+ // There is only one OCMB attached per OMI
+ iv_target = getConnectedChild( omi, TYPE_OCMB_CHIP, 0 );
+ if ( nullptr == iv_target )
+ {
+ PRDF_ERR( PRDF_FUNC "Could not find functional ocmb attached to "
+ "omi 0x%08x", getHuid(mcc) );
PRDF_ASSERT( false );
}
+
+
}
+ // If our target is MBA, get the chnlPos from the membuf
else
{
- iv_target = getConnectedChild( proc, TYPE_MCA,
+ TargetHandle_t membuf = getConnectedChild( proc, TYPE_MEMBUF,
iv_memMruMeld.s.chnlPos );
- if ( NULL == iv_target )
+ if ( nullptr == membuf )
{
- PRDF_ERR( PRDF_FUNC "Could not find functional mca "
+ PRDF_ERR( PRDF_FUNC "Could not find functional membuf "
"attached to proc 0x%08X at pos: %u", getHuid( proc ),
iv_memMruMeld.s.chnlPos );
PRDF_ASSERT( false );
}
- }
+ iv_target = getConnectedChild( membuf, TYPE_MBA,
+ iv_memMruMeld.s.mbaPos );
+ if ( nullptr == iv_target )
+ {
+ PRDF_ERR( PRDF_FUNC "Could not find functional mba attached "
+ "to 0x%08X at pos: %u", getHuid( membuf ),
+ iv_memMruMeld.s.mbaPos );
+ PRDF_ASSERT( false );
+ }
+ }
// Get the rank
iv_rank = MemRank( iv_memMruMeld.s.mrank, iv_memMruMeld.s.srank );
@@ -247,7 +283,8 @@ TargetHandleList MemoryMru::getCalloutList() const
}
}
}
- else if ( TARGETING::TYPE_MCA == getTargetType(iv_target) )
+ else if ( TARGETING::TYPE_MCA == getTargetType(iv_target) ||
+ TARGETING::TYPE_OCMB_CHIP == getTargetType(iv_target) )
{
if ( CALLOUT_ALL_MEM == iv_special )
{
@@ -304,6 +341,11 @@ void MemoryMru::getCommonVars()
{
proc = getConnectedParent( iv_target, TYPE_PROC );
}
+ else if ( TYPE_OCMB_CHIP == trgtType )
+ {
+ TargetHandle_t mcc = getConnectedParent( iv_target, TYPE_MCC );
+ proc = getConnectedParent( mcc, TYPE_PROC );
+ }
else
{
PRDF_ERR( PRDF_FUNC "Invalid target type" );
@@ -323,11 +365,27 @@ void MemoryMru::getCommonVars()
}
// If our target is an MCA, then chnlPos will specify the MCA position
// and mbaPos will be an unused field
- else
+ else if ( TYPE_MCA == getTargetType(iv_target) )
{
iv_memMruMeld.s.isMca = 1;
iv_memMruMeld.s.chnlPos = getTargetPosition( iv_target );
}
+ // If our target is an OCMB, then chnlPos will specify the MCC position and
+ // mbaPos will specify the OMI position.
+ else if ( TYPE_OCMB_CHIP == getTargetType(iv_target) )
+ {
+ TargetHandle_t omi = getConnectedParent( iv_target, TYPE_OMI );
+ TargetHandle_t mcc = getConnectedParent( omi, TYPE_MCC );
+
+ iv_memMruMeld.s.isOcmb = 1;
+ iv_memMruMeld.s.chnlPos = getTargetPosition(mcc) % MAX_MCC_PER_PROC;
+ iv_memMruMeld.s.mbaPos = getTargetPosition(omi) % MAX_OMI_PER_MCC;
+ }
+ else
+ {
+ PRDF_ERR( PRDF_FUNC "Invalid target type" );
+ PRDF_ASSERT(false);
+ }
iv_memMruMeld.s.nodePos = getTargetPosition( node );
iv_memMruMeld.s.procPos = getTargetPosition( proc );
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfOcmbDataBundle.H b/src/usr/diag/prdf/common/plat/mem/prdfOcmbDataBundle.H
new file mode 100644
index 000000000..75d7dd53e
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/mem/prdfOcmbDataBundle.H
@@ -0,0 +1,247 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/plat/mem/prdfOcmbDataBundle.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __prdfOcmbDataBundle_H
+#define __prdfOcmbDataBundle_H
+
+/** @file prdfOcmbDataBundle.H
+ * @brief Contains the data bundle for a P9 OCMB_CHIP object.
+ */
+
+// Framework includes
+#include <prdfExtensibleChip.H>
+
+// Platform includes
+#include <prdfPlatServices.H>
+#include <prdfMemCeTable.H>
+#include <prdfMemUeTable.H>
+
+#ifdef __HOSTBOOT_MODULE
+
+#include <prdfMemScrubUtils.H>
+#include <prdfMemTdFalseAlarm.H>
+#include <prdfMemThresholds.H>
+#include <prdfMemTdCtlr.H>
+
+#ifndef __HOSTBOOT_RUNTIME
+#include <prdfMemIplCeStats.H>
+#endif
+
+#endif // __HOSTBOOT_MODULE
+
+namespace PRDF
+{
+
+/** @brief P9 OCMB data bundle. */
+class OcmbDataBundle : public DataBundle
+{
+ public: // functions
+
+ /**
+ * @brief Constructor.
+ * @param i_ocmbChip The OCMB chip.
+ */
+ explicit OcmbDataBundle( ExtensibleChip * i_ocmbChip ) :
+ iv_chip(i_ocmbChip), iv_ceTable(i_ocmbChip), iv_ueTable(i_ocmbChip)
+ {}
+
+ /** @brief Destructor. */
+ ~OcmbDataBundle()
+ {
+ #ifdef __HOSTBOOT_MODULE
+ #ifdef __HOSTBOOT_RUNTIME
+ delete iv_vcmFalseAlarmCounter;
+ delete iv_tpsFalseAlarmCounter;
+ #else // IPL only
+ delete iv_iplCeStats;
+ #endif
+ delete iv_tdCtlr; iv_tdCtlr = nullptr;
+ #endif // __HOSTBOOT_MODULE
+ }
+
+ // Don't allow copy or assignment.
+ OcmbDataBundle( const OcmbDataBundle & ) = delete;
+ const OcmbDataBundle & operator=( const OcmbDataBundle & ) = delete;
+
+ #ifdef __HOSTBOOT_MODULE
+
+ /** @return The Targeted Diagnostics controller. */
+ MemTdCtlr<TARGETING::TYPE_OCMB_CHIP> * getTdCtlr()
+ {
+ if ( nullptr == iv_tdCtlr )
+ {
+ iv_tdCtlr = new MemTdCtlr<TARGETING::TYPE_OCMB_CHIP>{iv_chip};
+ }
+
+ return iv_tdCtlr;
+ }
+
+ /** @return The IMPE threshold counter. */
+ VcmFalseAlarm * getImpeThresholdCounter()
+ {
+ if ( nullptr == iv_impeThresholdCounter )
+ {
+ iv_impeThresholdCounter = new VcmFalseAlarm(
+ TimeBasedThreshold { getImpeTh() } );
+ }
+
+ return iv_impeThresholdCounter;
+ }
+
+ #ifdef __HOSTBOOT_RUNTIME
+
+ /** @return The VCM false alarm counter. */
+ VcmFalseAlarm * getVcmFalseAlarmCounter()
+ {
+ if ( nullptr == iv_vcmFalseAlarmCounter )
+ {
+ iv_vcmFalseAlarmCounter = new VcmFalseAlarm(
+ TimeBasedThreshold { 4, ThresholdResolution::ONE_DAY } );
+ }
+
+ return iv_vcmFalseAlarmCounter;
+ }
+
+ /** @return The TPS false alarm counter. */
+ TpsFalseAlarm * getTpsFalseAlarmCounter()
+ {
+ if ( nullptr == iv_tpsFalseAlarmCounter )
+ {
+ iv_tpsFalseAlarmCounter = new TpsFalseAlarm(
+ TimeBasedThreshold{ 3, ThresholdResolution::ONE_DAY } );
+ }
+
+ return iv_tpsFalseAlarmCounter;
+ }
+
+ #else // IPL only
+
+ /** @return The IPL CE statistics object. */
+ MemIplCeStats<TARGETING::TYPE_OCMB_CHIP> * getIplCeStats()
+ {
+ if ( nullptr == iv_iplCeStats )
+ {
+ iv_iplCeStats =
+ new MemIplCeStats<TARGETING::TYPE_OCMB_CHIP>( iv_chip );
+ }
+
+ return iv_iplCeStats;
+ }
+
+ #endif
+
+ #endif // __HOSTBOOT_MODULE
+
+ private: // instance variables
+
+ /** The OCMB chip associated with this data bundle. */
+ ExtensibleChip * const iv_chip;
+
+ #ifdef __HOSTBOOT_MODULE
+
+ /** The Targeted Diagnostics controller. */
+ MemTdCtlr<TARGETING::TYPE_OCMB_CHIP> * iv_tdCtlr = nullptr;
+
+ /** IMPE threshold counter. */
+ VcmFalseAlarm * iv_impeThresholdCounter = nullptr;
+
+ #endif // __HOSTBOOT_MODULE
+
+ public: // instance variables
+
+ MemCeTable<TARGETING::TYPE_OCMB_CHIP> iv_ceTable; ///< CE table for FFDC
+ MemUeTable iv_ueTable; ///< UE table for FFDC
+
+ /** If there is a channel failure detected on this bus, there will be some
+ * required cleanup after analysis to mask off all further attentions from
+ * the bus. A channel failure could occur on either side of the bus and it
+ * is possible the cleanup function could be called in multiple
+ * PostAnalysis plugins depending on where the channel failure occurred.
+ * Since we only want to do one cleanup, we will use this variable to
+ * indicate if a cleanup is still required or has already been done. */
+ bool iv_doChnlFailCleanup = false;
+
+ #ifdef __HOSTBOOT_MODULE
+
+ /** Threshold table for RCD parity errors. */
+ TimeBasedThreshold iv_rcdParityTh = TimeBasedThreshold( getRcdParityTh() );
+
+ /** Threshold table for IUEs. Threshold per DIMM */
+ std::map<uint8_t, TimeBasedThreshold> iv_iueTh;
+
+ /** Bool to indicate if we've triggered a port fail because of IUEs. */
+ bool iv_iuePortFail = false;
+
+ #ifdef __HOSTBOOT_RUNTIME
+
+ /** VCM false alarm counter. */
+ VcmFalseAlarm * iv_vcmFalseAlarmCounter = nullptr;
+
+ /** TPS false alarm counter. */
+ TpsFalseAlarm * iv_tpsFalseAlarmCounter = nullptr;
+
+ /** Set to true if mainline NCEs and TCEs should be permanently masked. This
+ * is checked at the end of targeted diagnostics before background
+ * scrubbing is resumed. */
+ bool iv_maskMainlineNceTce = false;
+
+ // These are used to limit the number of times a scrub command will stop
+ // on a UE or CE on a rank. This is to prevent potential flooding of
+ // maintenance UEs or CEs. The threshold will be 16 per rank for each.
+ TimeBasedThreshold iv_ueStopCounter =
+ TimeBasedThreshold( 16, ThresholdResolution::TEN_HOURS );
+ TimeBasedThreshold iv_ceStopCounter =
+ TimeBasedThreshold( 16, ThresholdResolution::TEN_HOURS );;
+
+ // If we stop on a UE or a CE, we will need to store the rank that the
+ // error is on so that we can clear our respective thresholds if the
+ // next error we stop on is on a different rank.
+ MemRank iv_ceUeRank;
+
+ #else // IPL only
+
+ /** MNFG IPL CE statistics. */
+ MemIplCeStats<TARGETING::TYPE_OCMB_CHIP> * iv_iplCeStats = nullptr;
+
+ #endif
+
+ #endif // __HOSTBOOT_MODULE
+
+};
+
+/**
+ * @brief Wrapper function for the OcmbDataBundle.
+ * @param i_ocmbChip The OCMB chip.
+ * @return This MBA's data bundle.
+ */
+inline OcmbDataBundle * getOcmbDataBundle( ExtensibleChip * i_ocmbChip )
+{
+ return static_cast<OcmbDataBundle *>(i_ocmbChip->getDataBundle());
+}
+
+} // end namespace PRDF
+
+#endif // __prdfOcmbDataBundle_H
+
diff --git a/src/usr/diag/prdf/common/plat/mem/prdf_plat_mem.mk b/src/usr/diag/prdf/common/plat/mem/prdf_plat_mem.mk
index 087214ece..2ea0712d3 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdf_plat_mem.mk
+++ b/src/usr/diag/prdf/common/plat/mem/prdf_plat_mem.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2016,2018
+# Contributors Listed Below - COPYRIGHT 2016,2019
# [+] International Business Machines Corp.
#
#
@@ -51,6 +51,7 @@ prd_obj += prdfMemoryMru.o
prd_obj += prdfMemUeTable.o
prd_obj += prdfMemUtils.o
prd_obj += prdfMemThresholds.o
+prd_obj += prdfP9OcmbChipDomain.o
# rule plugin related
prd_rule_plugin += prdfP9Mca_common.o
diff --git a/src/usr/diag/prdf/common/plat/nimbus/nimbus_mca.rule b/src/usr/diag/prdf/common/plat/nimbus/nimbus_mca.rule
index eea254545..d1a6bc290 100644
--- a/src/usr/diag/prdf/common/plat/nimbus/nimbus_mca.rule
+++ b/src/usr/diag/prdf/common/plat/nimbus/nimbus_mca.rule
@@ -241,7 +241,7 @@ group gMCACALFIR
/** MCACALFIR[0]
* A MBA recoverable error has occurred.
*/
- (rMCACALFIR, bit(0)) ? self_th_1;
+ (rMCACALFIR, bit(0)) ? nvdimm_self_th_1;
/** MCACALFIR[1]
* MBA Nonrecoverable Error
@@ -251,7 +251,7 @@ group gMCACALFIR
/** MCACALFIR[2]
* Excessive refreshes to a single rank.
*/
- (rMCACALFIR, bit(2)) ? self_th_32perDay;
+ (rMCACALFIR, bit(2)) ? nvdimm_self_th_32perDay;
/** MCACALFIR[3]
* Err detected in the MBA debug WAT logic
@@ -266,7 +266,7 @@ group gMCACALFIR
/** MCACALFIR[5]
* Calibration complete indication xout
*/
- (rMCACALFIR, bit(5)) ? self_th_32perDay;
+ (rMCACALFIR, bit(5)) ? nvdimm_self_th_32perDay;
/** MCACALFIR[6]
* Emergency Throttle
@@ -279,7 +279,7 @@ group gMCACALFIR
(rMCACALFIR, bit(7)) ? self_th_1;
/** MCACALFIR[8]
- * event_n active on DDR interface
+ * Active NVDIMM Attention
*/
(rMCACALFIR, bit(8)) ? analyzeNvdimms;
@@ -533,7 +533,7 @@ group gMCAECCFIR
/** MCAECCFIR[42]
* SCOM_PARITY_CLASS_RECOVERABLE
*/
- (rMCAECCFIR, bit(42)) ? self_th_1;
+ (rMCAECCFIR, bit(42)) ? nvdimm_self_th_1;
/** MCAECCFIR[43]
* SCOM_PARITY_CLASS_UNRECOVERABLE
@@ -548,7 +548,7 @@ group gMCAECCFIR
/** MCAECCFIR[45]
* WRITE_RMW_CE
*/
- (rMCAECCFIR, bit(45)) ? self_th_32perDay;
+ (rMCAECCFIR, bit(45)) ? nvdimm_self_th_32perDay;
/** MCAECCFIR[46]
* WRITE_RMW_UE
@@ -686,12 +686,12 @@ group gDDRPHYFIR
/** DDRPHYFIR[60]
* Register PE 4 bit impact
*/
- (rDDRPHYFIR, bit(60)) ? self_th_1;
+ (rDDRPHYFIR, bit(60)) ? nvdimm_self_th_1;
/** DDRPHYFIR[61]
* Register PE 1 bit impact
*/
- (rDDRPHYFIR, bit(61)) ? self_th_1;
+ (rDDRPHYFIR, bit(61)) ? nvdimm_self_th_1;
};
diff --git a/src/usr/diag/prdf/common/plat/nimbus/nimbus_mca_actions.rule b/src/usr/diag/prdf/common/plat/nimbus/nimbus_mca_actions.rule
index da3a73f82..6d5ab9018 100644
--- a/src/usr/diag/prdf/common/plat/nimbus/nimbus_mca_actions.rule
+++ b/src/usr/diag/prdf/common/plat/nimbus/nimbus_mca_actions.rule
@@ -70,6 +70,7 @@ actionclass rcd_parity_error
calloutSelfLowNoGard; # Self LOW
# Thresholding done in plugin
funccall("RcdParityError"); # Run TPS on TH for all MCA ranks
+ funccall("ClearNvdimmGardState"); # Clear gard for NVDIMMs
};
/** Handle Mainline IUEs */
@@ -125,7 +126,7 @@ actionclass maintenance_iaue_handling
/** MCA/UE algroithm, threshold 5 per day */
actionclass mca_ue_algorithm_th_5perDay
{
- calloutSelfMed;
+ try( funccall("CheckForNvdimms"), calloutSelfMed );
threshold5pday;
funccall("mcaUeAlgorithm"); # must be called last
};
@@ -133,12 +134,29 @@ actionclass mca_ue_algorithm_th_5perDay
/** MCA/UE algroithm, threshold 1 */
actionclass mca_ue_algorithm_th_1
{
- calloutSelfMed;
+ try( funccall("CheckForNvdimms"), calloutSelfMed );
threshold1;
funccall("mcaUeAlgorithm"); # must be called last
};
################################################################################
+# NVDIMM callouts #
+################################################################################
+
+# Simple callouts that will avoid gard for NVDIMMs at IPL
+actionclass nvdimm_self_th_1
+{
+ try( funccall("CheckForNvdimms"), calloutSelfMed );
+ threshold1;
+};
+
+actionclass nvdimm_self_th_32perDay
+{
+ try( funccall("CheckForNvdimms"), calloutSelfMed );
+ threshold32pday;
+};
+
+################################################################################
# Analyze groups
################################################################################
diff --git a/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcbist.rule b/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcbist.rule
index 1f61719a7..0a3301e2a 100644
--- a/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcbist.rule
+++ b/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcbist.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2016,2018
+# Contributors Listed Below - COPYRIGHT 2016,2019
# [+] International Business Machines Corp.
#
#
@@ -599,7 +599,7 @@ group gMCBISTFIR
/** MCBISTFIR[13]
* SCOM_RECOVERABLE_REG_PE
*/
- (rMCBISTFIR, bit(13)) ? self_th_1;
+ (rMCBISTFIR, bit(13)) ? nvdimm_self_th_1;
/** MCBISTFIR[14]
* SCOM_FATAL_REG_PE
diff --git a/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcbist_actions.rule b/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcbist_actions.rule
index 9b2127f3f..11d499e30 100644
--- a/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcbist_actions.rule
+++ b/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcbist_actions.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2016,2018
+# Contributors Listed Below - COPYRIGHT 2016,2019
# [+] International Business Machines Corp.
#
#
@@ -36,6 +36,17 @@ actionclass command_addr_timeout
funccall("commandAddrTimeout");
};
+################################################################################
+# NVDIMM callouts #
+################################################################################
+
+# Simple callouts that will avoid gard for NVDIMMs at IPL
+actionclass nvdimm_self_th_1
+{
+ try( funccall("CheckForNvdimms"), calloutSelfMed );
+ threshold1;
+};
+
###############################################################################
# Analyze groups
###############################################################################
diff --git a/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcs.rule b/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcs.rule
index 71a0342ab..987d68afb 100644
--- a/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcs.rule
+++ b/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcs.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2016,2018
+# Contributors Listed Below - COPYRIGHT 2016,2019
# [+] International Business Machines Corp.
#
#
@@ -148,7 +148,7 @@ group gMCFIR
/** MCFIR[0]
* mc internal recoverable eror
*/
- (rMCFIR, bit(0)) ? self_th_1;
+ (rMCFIR, bit(0)) ? nvdimm_self_th_1;
/** MCFIR[1]
* mc internal non recovervable error
diff --git a/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcs_actions.rule b/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcs_actions.rule
index 1497cdccb..35339ccc6 100644
--- a/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcs_actions.rule
+++ b/src/usr/diag/prdf/common/plat/nimbus/nimbus_mcs_actions.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -24,6 +24,17 @@
# IBM_PROLOG_END_TAG
################################################################################
+# NVDIMM callouts #
+################################################################################
+
+# Simple callouts that will avoid gard for NVDIMMs at IPL
+actionclass nvdimm_self_th_1
+{
+ try( funccall("CheckForNvdimms"), calloutSelfMed );
+ threshold1;
+};
+
+################################################################################
# Analyze groups
################################################################################
diff --git a/src/usr/diag/prdf/common/plat/nimbus/nimbus_obus.rule b/src/usr/diag/prdf/common/plat/nimbus/nimbus_obus.rule
index a4ce0d02d..790537acf 100644
--- a/src/usr/diag/prdf/common/plat/nimbus/nimbus_obus.rule
+++ b/src/usr/diag/prdf/common/plat/nimbus/nimbus_obus.rule
@@ -469,12 +469,12 @@ group gIOOLFIR
/** IOOLFIR[8]
* link0 nak received
*/
- (rIOOLFIR, bit(8)) ? defaultMaskedError;
+ (rIOOLFIR, bit(8)) ? threshold_and_mask_self_non_smp_only;
/** IOOLFIR[9]
* link1 nak received
*/
- (rIOOLFIR, bit(9)) ? defaultMaskedError;
+ (rIOOLFIR, bit(9)) ? threshold_and_mask_self_non_smp_only;
/** IOOLFIR[10]
* link0 replay buffer full
@@ -499,22 +499,22 @@ group gIOOLFIR
/** IOOLFIR[14]
* link0 sl ecc correctable
*/
- (rIOOLFIR, bit(14)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(14)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[15]
* link1 sl ecc correctable
*/
- (rIOOLFIR, bit(15)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(15)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[16]
* link0 sl ecc ue
*/
- (rIOOLFIR, bit(16)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(16)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[17]
* link1 sl ecc ue
*/
- (rIOOLFIR, bit(17)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(17)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[18]
* link0 retrain threshold
@@ -597,12 +597,12 @@ group gIOOLFIR
(rIOOLFIR, bit(33)) ? defaultMaskedError;
/** IOOLFIR[34]
- * link0 num replay
+ * link0 num replay or no forward progress
*/
(rIOOLFIR, bit(34)) ? defaultMaskedError;
/** IOOLFIR[35]
- * link1 num replay
+ * link1 num replay or no forward progress
*/
(rIOOLFIR, bit(35)) ? defaultMaskedError;
@@ -619,12 +619,12 @@ group gIOOLFIR
/** IOOLFIR[38]
* link0 prbs select error
*/
- (rIOOLFIR, bit(38)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(38)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[39]
* link1 prbs select error
*/
- (rIOOLFIR, bit(39)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(39)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[40]
* link0 tcomplete bad
@@ -639,102 +639,102 @@ group gIOOLFIR
/** IOOLFIR[42]
* link0 no spare lane available
*/
- (rIOOLFIR, bit(42)) ? obusSmpCallout_L0;
+ (rIOOLFIR, bit(42)) ? obusSmpCallout_L0_smp_only;
/** IOOLFIR[43]
* link1 no spare lane available
*/
- (rIOOLFIR, bit(43)) ? obusSmpCallout_L1;
+ (rIOOLFIR, bit(43)) ? obusSmpCallout_L1_smp_only;
/** IOOLFIR[44]
- * link0 spare done
+ * link0 spare done or degraded mode
*/
- (rIOOLFIR, bit(44)) ? obusSmpCallout_th32_L0;
+ (rIOOLFIR, bit(44)) ? spare_lane_degraded_mode_L0;
/** IOOLFIR[45]
- * link1 spare done
+ * link1 spare done or degraded mode
*/
- (rIOOLFIR, bit(45)) ? obusSmpCallout_th32_L1;
+ (rIOOLFIR, bit(45)) ? spare_lane_degraded_mode_L1;
/** IOOLFIR[46]
* link0 too many crc errors
*/
- (rIOOLFIR, bit(46)) ? obusSmpCallout_L0;
+ (rIOOLFIR, bit(46)) ? obusSmpCallout_L0_smp_only;
/** IOOLFIR[47]
* link1 too many crc errors
*/
- (rIOOLFIR, bit(47)) ? obusSmpCallout_L1;
+ (rIOOLFIR, bit(47)) ? obusSmpCallout_L1_smp_only;
/** IOOLFIR[48]
- * link0 npu error
+ * link0 npu error or orx otx dlx errors
*/
(rIOOLFIR, bit(48)) ? threshold_and_mask_self;
/** IOOLFIR[49]
- * link1 npu error
+ * link1 npu error or orx otx dlx errors
*/
(rIOOLFIR, bit(49)) ? threshold_and_mask_self;
/** IOOLFIR[50]
* linkx npu error
*/
- (rIOOLFIR, bit(50)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(50)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[51]
* osc switch
*/
- (rIOOLFIR, bit(51)) ? threshold_and_mask_self;
+ (rIOOLFIR, bit(51)) ? threshold_and_mask_self_smp_only;
/** IOOLFIR[52]
* link0 correctable array error
*/
- (rIOOLFIR, bit(52)) ? obusSmpCallout_th32_L0;
+ (rIOOLFIR, bit(52)) ? self_th_32perDay;
/** IOOLFIR[53]
* link1 correctable array error
*/
- (rIOOLFIR, bit(53)) ? obusSmpCallout_th32_L1;
+ (rIOOLFIR, bit(53)) ? self_th_32perDay;
/** IOOLFIR[54]
* link0 uncorrectable array error
*/
- (rIOOLFIR, bit(54)) ? obusSmpFailure_L0;
+ (rIOOLFIR, bit(54)) ? self_th_1;
/** IOOLFIR[55]
* link1 uncorrectable array error
*/
- (rIOOLFIR, bit(55)) ? obusSmpFailure_L1;
+ (rIOOLFIR, bit(55)) ? self_th_1;
/** IOOLFIR[56]
* link0 training failed
*/
- (rIOOLFIR, bit(56)) ? obusSmpFailure_L0;
+ (rIOOLFIR, bit(56)) ? training_failure_L0;
/** IOOLFIR[57]
* link1 training failed
*/
- (rIOOLFIR, bit(57)) ? obusSmpFailure_L1;
+ (rIOOLFIR, bit(57)) ? training_failure_L1;
/** IOOLFIR[58]
* link0 unrecoverable error
*/
- (rIOOLFIR, bit(58)) ? obusSmpFailure_L0;
+ (rIOOLFIR, bit(58)) ? unrecoverable_error_L0;
/** IOOLFIR[59]
* link1 unrecoverable error
*/
- (rIOOLFIR, bit(59)) ? obusSmpFailure_L1;
+ (rIOOLFIR, bit(59)) ? unrecoverable_error_L1;
/** IOOLFIR[60]
* link0 internal error
*/
- (rIOOLFIR, bit(60)) ? obusSmpFailure_L0;
+ (rIOOLFIR, bit(60)) ? internal_error_L0;
/** IOOLFIR[61]
* link1 internal error
*/
- (rIOOLFIR, bit(61)) ? obusSmpFailure_L1;
+ (rIOOLFIR, bit(61)) ? internal_error_L1;
/** IOOLFIR[62]
* fir scom err dup
diff --git a/src/usr/diag/prdf/common/plat/nimbus/nimbus_proc.rule b/src/usr/diag/prdf/common/plat/nimbus/nimbus_proc.rule
index 6ac3bc5a1..6712a5977 100644
--- a/src/usr/diag/prdf/common/plat/nimbus/nimbus_proc.rule
+++ b/src/usr/diag/prdf/common/plat/nimbus/nimbus_proc.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2016,2018
+# Contributors Listed Below - COPYRIGHT 2016,2019
# [+] International Business Machines Corp.
#
#
@@ -2872,7 +2872,7 @@ group gNXCQFIR
/** NXCQFIR[19]
* Uncorrectable error on ERAT arrays
*/
- (rNXCQFIR, bit(19)) ? nx_th_32perDay;
+ (rNXCQFIR, bit(19)) ? nx_th_1;
/** NXCQFIR[20]
* SUE on ERAT arrays
diff --git a/src/usr/diag/prdf/common/plat/nimbus/nimbus_proc_actions.rule b/src/usr/diag/prdf/common/plat/nimbus/nimbus_proc_actions.rule
index 826308710..1960da53b 100644
--- a/src/usr/diag/prdf/common/plat/nimbus/nimbus_proc_actions.rule
+++ b/src/usr/diag/prdf/common/plat/nimbus/nimbus_proc_actions.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -23,9 +23,15 @@
#
# IBM_PROLOG_END_TAG
-###############################################################################
+################################################################################
+# Analyze
+################################################################################
+
+actionclass analyzeENHCAFIR { analyze(gENHCAFIR); };
+
+################################################################################
# Analyze connected
-###############################################################################
+################################################################################
actionclass analyzeConnectedMCBIST0 { analyze(connected(TYPE_MCBIST, 0)); };
actionclass analyzeConnectedMCBIST1 { analyze(connected(TYPE_MCBIST, 1)); };
diff --git a/src/usr/diag/prdf/common/plat/p9/p9_common_actions.rule b/src/usr/diag/prdf/common/plat/p9/p9_common_actions.rule
index 669d3e5b5..2e7e32869 100644
--- a/src/usr/diag/prdf/common/plat/p9/p9_common_actions.rule
+++ b/src/usr/diag/prdf/common/plat/p9/p9_common_actions.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2016,2018
+# Contributors Listed Below - COPYRIGHT 2016,2019
# [+] International Business Machines Corp.
#
#
@@ -208,6 +208,12 @@ actionclass parent_proc_th_1
threshold1;
};
+actionclass parent_proc_th_32perDay
+{
+ callout(connected(TYPE_PROC), MRU_MED);
+ threshold32pday;
+};
+
actionclass level2_M_proc_L_th_1
{
callout2ndLvlMed;
@@ -273,4 +279,3 @@ actionclass chip_to_chip
calloutSelfMed;
threshold1;
};
-
diff --git a/src/usr/diag/prdf/common/plat/p9/p9_common_obus_actions.rule b/src/usr/diag/prdf/common/plat/p9/p9_common_obus_actions.rule
index 6590bb122..700e87649 100644
--- a/src/usr/diag/prdf/common/plat/p9/p9_common_obus_actions.rule
+++ b/src/usr/diag/prdf/common/plat/p9/p9_common_obus_actions.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -88,6 +88,150 @@ actionclass obusSmpFailure_L1
threshold1;
};
+actionclass smp_masked
+{
+ # If SMP mode, does defaultMaskedError action and returns SUCCESS.
+ # Otherwise, returns PRD_SCAN_COMM_REGISTER_ZERO.
+ funccall( "smp_masked" ); # If SMP mode
+};
+
+actionclass non_smp_masked
+{
+ # If NOT in SMP mode, does defaultMaskedError action and returns SUCCESS.
+ # Otherwise, returns PRD_SCAN_COMM_REGISTER_ZERO.
+ funccall( "non_smp_masked" );
+};
+
+actionclass non_smp_callout_bus_th_1
+{
+ # NOTE: We cannot put the threshold action in this actionclass because it
+ # will affect the SMP action in the try() statement. Therefore, the
+ # plugin must handle the thresholding if in non-SMP mode.
+
+ # If NOT in SMP mode:
+ # - calls out this OBUS
+ # - indicates the probably may be somewhere between this OBUS and whatever
+ # is on the other side (which we know nothing about)
+ # - sets threshold
+ # - sets service call
+ # - returns SUCCESS
+ # Otherwise
+ # - returns PRD_SCAN_COMM_REGISTER_ZERO
+ funccall( "non_smp_callout_bus_th_1" );
+};
+
+actionclass non_smp_callout_lvl2_th_1
+{
+ # NOTE: We cannot put the threshold action in this actionclass because it
+ # will affect the SMP action in the try() statement. Therefore, the
+ # plugin must handle the thresholding if in non-SMP mode.
+
+ # If NOT in SMP mode:
+ # - calls out level 2 support
+ # - sets threshold
+ # - sets service call
+ # - returns SUCCESS
+ # Otherwise
+ # - returns PRD_SCAN_COMM_REGISTER_ZERO
+ funccall( "non_smp_callout_lvl2_th_1" );
+};
+
+actionclass non_smp_callout_self_th_32perDay
+{
+ threshold32pday; # This is ok because it is greater than threshold1.
+
+ # If NOT in SMP mode:
+ # - calls out this OBUS
+ # - returns SUCCESS
+ # Otherwise
+ # - returns PRD_SCAN_COMM_REGISTER_ZERO
+ funccall( "non_smp_callout_self" );
+};
+
+actionclass threshold_and_mask_self_non_smp_only
+{
+ # SMP: masked
+ # Non-SMP: threshold_and_mask_self
+ try ( smp_masked, threshold_and_mask_self );
+};
+
+actionclass threshold_and_mask_self_smp_only
+{
+ # SMP: threshold_and_mask_self
+ # Non-SMP: masked
+ try ( non_smp_masked, threshold_and_mask_self );
+};
+
+actionclass obusSmpCallout_L0_smp_only
+{
+ # SMP: obusSmpCallout_L0
+ # Non-SMP: masked
+ try ( non_smp_masked, obusSmpCallout_L0 );
+};
+
+actionclass obusSmpCallout_L1_smp_only
+{
+ # SMP: obusSmpCallout_L1
+ # Non-SMP: masked
+ try ( non_smp_masked, obusSmpCallout_L1 );
+};
+
+actionclass spare_lane_degraded_mode_L0
+{
+ # SMP: obusSmpCallout_th32_L0 (lane spare)
+ # Non-SMP: non_smp_callout_bus_th_1 (degraded mode)
+ try ( non_smp_callout_bus_th_1, obusSmpCallout_th32_L0 );
+};
+
+actionclass spare_lane_degraded_mode_L1
+{
+ # SMP: obusSmpCallout_th32_L1 (lane spare)
+ # Non-SMP: non_smp_callout_bus_th_1 (degraded mode)
+ try ( non_smp_callout_bus_th_1, obusSmpCallout_th32_L1 );
+};
+
+actionclass training_failure_L0
+{
+ # SMP: obusSmpFailure_L0
+ # Non-SMP: non_smp_callout_lvl2_th_1
+ try ( non_smp_callout_lvl2_th_1, obusSmpFailure_L0 );
+};
+
+actionclass training_failure_L1
+{
+ # SMP: obusSmpFailure_L1
+ # Non-SMP: non_smp_callout_lvl2_th_1
+ try ( non_smp_callout_lvl2_th_1, obusSmpFailure_L1 );
+};
+
+actionclass unrecoverable_error_L0
+{
+ # SMP: obusSmpFailure_L0
+ # Non-SMP: non_smp_callout_bus_th_1
+ try ( non_smp_callout_bus_th_1, obusSmpFailure_L0 );
+};
+
+actionclass unrecoverable_error_L1
+{
+ # SMP: obusSmpFailure_L1
+ # Non-SMP: non_smp_callout_bus_th_1
+ try ( non_smp_callout_bus_th_1, obusSmpFailure_L1 );
+};
+
+actionclass internal_error_L0
+{
+ # SMP: obusSmpFailure_L0
+ # Non-SMP: non_smp_callout_self_th_32perDay
+ try ( non_smp_callout_self_th_32perDay, obusSmpFailure_L0 );
+};
+
+actionclass internal_error_L1
+{
+ # SMP: obusSmpFailure_L1
+ # Non-SMP: non_smp_callout_self_th_32perDay
+ try ( non_smp_callout_self_th_32perDay, obusSmpFailure_L1 );
+};
+
###############################################################################
# Analyze groups
###############################################################################
diff --git a/src/usr/diag/prdf/common/plat/p9/p9_common_obus_regs.rule b/src/usr/diag/prdf/common/plat/p9/p9_common_obus_regs.rule
index 461fbc664..bc25fba5d 100644
--- a/src/usr/diag/prdf/common/plat/p9/p9_common_obus_regs.rule
+++ b/src/usr/diag/prdf/common/plat/p9/p9_common_obus_regs.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2016,2018
+# Contributors Listed Below - COPYRIGHT 2016,2019
# [+] International Business Machines Corp.
#
#
@@ -85,6 +85,13 @@
capture group default;
};
+ register MISC_ERROR_STATUS
+ {
+ name "P9 OBUS target Misc Error Status register";
+ scomaddr 0x09010829;
+ capture group default;
+ };
+
############################################################################
# P9 OBUS targets for cable FFDC
# One additional reg (IOOLFIR) is in default group
diff --git a/src/usr/diag/prdf/common/plat/p9/p9_common_proc_actions.rule b/src/usr/diag/prdf/common/plat/p9/p9_common_proc_actions.rule
index aacf978bd..e5700c34b 100644
--- a/src/usr/diag/prdf/common/plat/p9/p9_common_proc_actions.rule
+++ b/src/usr/diag/prdf/common/plat/p9/p9_common_proc_actions.rule
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2017,2018
+# Contributors Listed Below - COPYRIGHT 2017,2019
# [+] International Business Machines Corp.
#
#
@@ -670,7 +670,6 @@ actionclass analyzePBIOOFIR { analyze(gPBIOOFIR ); };
actionclass analyzePBAFIR { analyze(gPBAFIR ); };
actionclass analyzePSIHBFIR { analyze(gPSIHBFIR ); };
actionclass analyzePBAMFIR { analyze(gPBAMFIR ); };
-actionclass analyzeENHCAFIR { analyze(gENHCAFIR ); };
actionclass analyzeXB_LFIR { analyze(gXB_LFIR ); };
actionclass analyzeXBPPEFIR { analyze(gXBPPEFIR ); };
diff --git a/src/usr/diag/prdf/common/plat/p9/prdfCommonPlugins.C b/src/usr/diag/prdf/common/plat/p9/prdfCommonPlugins.C
index ece3fc1a8..730f99f09 100644
--- a/src/usr/diag/prdf/common/plat/p9/prdfCommonPlugins.C
+++ b/src/usr/diag/prdf/common/plat/p9/prdfCommonPlugins.C
@@ -127,6 +127,88 @@ PRDF_PLUGIN_DEFINE_NS(nimbus_proc, CommonPlugins, ClearServiceCallFlag_mnfgInfo
PRDF_PLUGIN_DEFINE_NS(cumulus_proc, CommonPlugins, ClearServiceCallFlag_mnfgInfo);
PRDF_PLUGIN_DEFINE_NS(axone_proc, CommonPlugins, ClearServiceCallFlag_mnfgInfo);
+/**
+ * @brief Will change the gard state of any NVDIMMs in the callout list to
+ * NO_GARD.
+ * @param i_chip The chip.
+ * @param io_sc The step code data struct.
+ * @returns SUCCESS
+ */
+int32_t ClearNvdimmGardState( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #ifdef __HOSTBOOT_MODULE
+
+ // Call the sdc to clear the NVDIMM mru list.
+ io_sc.service_data->clearNvdimmMruListGard();
+
+ #endif
+
+ return SUCCESS;
+}
+PRDF_PLUGIN_DEFINE_NS(nimbus_mca, CommonPlugins, ClearNvdimmGardState);
+
+/**
+ * @brief Will check if any of the DIMMs connected to this chip are NVDIMMs
+ * and send a message to PHYP/Hostboot that save/restore may work. If
+ * we are at IPL, we will callout self no gard instead of garding.
+ * @param i_chip The chip of the DIMM parent.
+ * @param io_sc The step code data struct.
+ * @returns SUCCESS if NVDIMMs found at IPL, PRD_SCAN_COMM_REGISTER_ZERO if not.
+ */
+int32_t CheckForNvdimms( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ int32_t rc = PRD_SCAN_COMM_REGISTER_ZERO;
+
+ #ifdef CONFIG_NVDIMM
+ #ifdef __HOSTBOOT_MODULE
+
+ TargetHandleList dimmList = getConnected( i_chip->getTrgt(), TYPE_DIMM );
+
+ // Always loop through all the dimms so we send the
+ // nvdimmNotifyProtChange message for all the NVDIMMs on the target.
+ for ( auto & dimm : dimmList )
+ {
+ // If the callout target is an NVDIMM send a message to
+ // PHYP/Hostboot that a save/restore may work, and if we are at
+ // IPL, do not gard the target.
+ if ( isNVDIMM(dimm) )
+ {
+ // Send the message to PHYP/Hostboot
+ uint32_t l_rc = PlatServices::nvdimmNotifyProtChange( dimm,
+ NVDIMM::NVDIMM_RISKY_HW_ERROR );
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_TRAC( "CheckForNvdimms: nvdimmNotifyProtChange(0x%08x)"
+ " failed.", PlatServices::getHuid(dimm) );
+ continue;
+ }
+
+ #ifndef __HOSTBOOT_RUNTIME
+ // IPL
+ // We will callout self, no gard. No need for another self callout
+ // from the rule code, so return SUCCESS.
+ rc = SUCCESS;
+ #endif
+ }
+ }
+
+ if ( SUCCESS == rc )
+ {
+ // Callout self, no gard
+ io_sc.service_data->SetCallout( i_chip->getTrgt(), MRU_MED, NO_GARD );
+ }
+
+ #endif // __HOSTBOOT_MODULE
+ #endif // CONFIG_NVDIMM
+
+ return rc;
+}
+PRDF_PLUGIN_DEFINE_NS(nimbus_mcs, CommonPlugins, CheckForNvdimms);
+PRDF_PLUGIN_DEFINE_NS(nimbus_mca, CommonPlugins, CheckForNvdimms);
+PRDF_PLUGIN_DEFINE_NS(nimbus_mcbist, CommonPlugins, CheckForNvdimms);
+
} // namespace CommonPlugins ends
}// namespace PRDF ends
diff --git a/src/usr/diag/prdf/common/plat/p9/prdfLaneRepair.C b/src/usr/diag/prdf/common/plat/p9/prdfLaneRepair.C
index 6cb4e6535..6ad889fd5 100644
--- a/src/usr/diag/prdf/common/plat/p9/prdfLaneRepair.C
+++ b/src/usr/diag/prdf/common/plat/p9/prdfLaneRepair.C
@@ -75,6 +75,16 @@ TargetHandle_t getTxBusEndPt( TargetHandle_t i_rxTrgt)
// grab connected DMI parent
o_txTrgt = getConnectedParent( i_rxTrgt, TYPE_DMI );
}
+ else if ( TYPE_OMI == busType )
+ {
+ // Get connected child OCMB (one OCMB per OMI)
+ o_txTrgt = getConnectedChild( i_rxTrgt, TYPE_OCMB_CHIP, 0 );
+ }
+ else if ( TYPE_OCMB_CHIP == busType )
+ {
+ // Get connected parent OMI
+ o_txTrgt = getConnectedParent( i_rxTrgt, TYPE_OMI );
+ }
PRDF_ASSERT(nullptr != o_txTrgt);
return o_txTrgt;
@@ -310,38 +320,6 @@ int32_t __handleLaneRepairEvent( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
-template<>
-int32_t __handleLaneRepairEvent<TYPE_OBUS, TYPE_OBUS>( ExtensibleChip * i_chip,
- STEP_CODE_DATA_STRUCT & i_sc,
- bool i_spareDeployed )
-{
- TargetHandle_t rxBusTgt = i_chip->getTrgt();
-
- // Make predictive on first occurrence in MFG
- if ( isLaneRepairDisabled<TYPE_OBUS>() )
- {
- i_sc.service_data->setServiceCall();
- }
-
- // RTC 174485
- // Need HWPs for this. Just callout bus interface for now.
- if ( obusInSmpMode(rxBusTgt) )
- {
- calloutBusInterface( i_chip, i_sc, MRU_LOW );
- i_sc.service_data->setServiceCall();
- }
- else
- {
- PRDF_ERR( "__handleLaneRepairEvent: Lane repair only supported "
- "in SMP mode obus: 0x%08x", getHuid(rxBusTgt) );
- i_sc.service_data->SetCallout( LEVEL2_SUPPORT, MRU_MED, NO_GARD );
- i_sc.service_data->SetCallout( SP_CODE, MRU_MED, NO_GARD );
- i_sc.service_data->setServiceCall();
- }
- return SUCCESS;
-}
-
-
int32_t handleLaneRepairEvent( ExtensibleChip * i_chip,
STEP_CODE_DATA_STRUCT & i_sc,
bool i_spareDeployed )
@@ -350,10 +328,6 @@ int32_t handleLaneRepairEvent( ExtensibleChip * i_chip,
TYPE trgtType = getTargetType(i_chip->getTrgt());
switch (trgtType)
{
- case TYPE_OBUS:
- rc = __handleLaneRepairEvent<TYPE_OBUS,TYPE_OBUS>( i_chip, i_sc,
- i_spareDeployed );
- break;
case TYPE_XBUS:
rc = __handleLaneRepairEvent<TYPE_XBUS,TYPE_XBUS>( i_chip, i_sc,
i_spareDeployed );
@@ -729,6 +703,8 @@ void obus_clearMaskFail( errlHndl_t &io_errl, TargetHandle_t &i_rxTrgt,
PRDF_ASSERT( NULL != i_txTrgt );
PRDF_ASSERT( NULL != io_errl );
+#ifdef __HOSTBOOT_MODULE // register writes not allowed on FSP
+
uint32_t l_rc = SUCCESS;
ExtensibleChip *l_rxChip =
(ExtensibleChip *)systemPtr->GetChip( i_rxTrgt );
@@ -790,6 +766,8 @@ void obus_clearMaskFail( errlHndl_t &io_errl, TargetHandle_t &i_rxTrgt,
} while (0);
+#endif // __HOSTBOOT_MODULE
+
} // end obus_clearMaskFail
@@ -924,7 +902,7 @@ PRDF_PLUGIN_DEFINE_NS( cumulus_proc, LaneRepair, captureSmpObus3 );
PRDF_PLUGIN_DEFINE_NS( nimbus_proc, LaneRepair, captureSmpObus3 );
PRDF_PLUGIN_DEFINE_NS( axone_proc, LaneRepair, captureSmpObus3 );
-int32_t calloutBusInterface( ExtensibleChip * i_chip,
+int32_t calloutBusInterface( TargetHandle_t i_rxTrgt,
STEP_CODE_DATA_STRUCT & i_sc,
PRDpriority i_priority )
{
@@ -934,10 +912,9 @@ int32_t calloutBusInterface( ExtensibleChip * i_chip,
do {
// Get both endpoints
- TargetHandle_t rxTrgt = i_chip->getTrgt();
- TYPE rxType = getTargetType(rxTrgt);
+ TYPE rxType = getTargetType(i_rxTrgt);
- if ( rxType == TYPE_OBUS && !obusInSmpMode( rxTrgt ) )
+ if ( rxType == TYPE_OBUS && !obusInSmpMode( i_rxTrgt ) )
{
// There is no support in hostboot for calling out the other end of
// an NV or openCAPI bus. By design, any FIR bits associated with
@@ -945,7 +922,7 @@ int32_t calloutBusInterface( ExtensibleChip * i_chip,
// action. So if we hit this case, just make a default callout.
PRDF_ERR( PRDF_FUNC "Lane repair only supported in SMP mode "
- "obus: 0x%08x", getHuid(rxTrgt) );
+ "obus: 0x%08x", getHuid(i_rxTrgt) );
i_sc.service_data->SetCallout( LEVEL2_SUPPORT, MRU_MED, NO_GARD );
i_sc.service_data->SetCallout( SP_CODE, MRU_MED, NO_GARD );
@@ -953,11 +930,11 @@ int32_t calloutBusInterface( ExtensibleChip * i_chip,
break;
}
- TargetHandle_t txTrgt = getTxBusEndPt(rxTrgt);
+ TargetHandle_t txTrgt = getTxBusEndPt(i_rxTrgt);
TYPE txType = getTargetType(txTrgt);
// Add the endpoint target callouts
- i_sc.service_data->SetCallout( rxTrgt, MRU_MEDA );
+ i_sc.service_data->SetCallout( i_rxTrgt, MRU_MEDA );
i_sc.service_data->SetCallout( txTrgt, MRU_MEDA);
// Get the HWAS bus type.
@@ -975,6 +952,11 @@ int32_t calloutBusInterface( ExtensibleChip * i_chip,
{
hwasType = HWAS::DMI_BUS_TYPE;
}
+ else if ( (TYPE_OMI == rxType && TYPE_OCMB_CHIP == txType) ||
+ (TYPE_OCMB_CHIP == rxType && TYPE_OMI == txType) )
+ {
+ hwasType = HWAS::OMI_BUS_TYPE;
+ }
else
{
PRDF_ASSERT( false );
@@ -990,7 +972,7 @@ int32_t calloutBusInterface( ExtensibleChip * i_chip,
}
// Callout this bus interface.
- PRDF_ADD_BUS_CALLOUT( errl, rxTrgt, txTrgt, hwasType, i_priority );
+ PRDF_ADD_BUS_CALLOUT( errl, i_rxTrgt, txTrgt, hwasType, i_priority );
} while(0);
@@ -1020,9 +1002,6 @@ int32_t spareDeployed( ExtensibleChip * i_chip,
PRDF_PLUGIN_DEFINE_NS( nimbus_xbus, LaneRepair, spareDeployed );
PRDF_PLUGIN_DEFINE_NS( cumulus_xbus, LaneRepair, spareDeployed );
PRDF_PLUGIN_DEFINE_NS( axone_xbus, LaneRepair, spareDeployed );
-PRDF_PLUGIN_DEFINE_NS( nimbus_obus, LaneRepair, spareDeployed );
-PRDF_PLUGIN_DEFINE_NS( cumulus_obus, LaneRepair, spareDeployed );
-PRDF_PLUGIN_DEFINE_NS( axone_obus, LaneRepair, spareDeployed );
PRDF_PLUGIN_DEFINE_NS( centaur_membuf, LaneRepair, spareDeployed );
/**
@@ -1042,9 +1021,6 @@ int32_t maxSparesExceeded( ExtensibleChip * i_chip,
PRDF_PLUGIN_DEFINE_NS( nimbus_xbus, LaneRepair, maxSparesExceeded );
PRDF_PLUGIN_DEFINE_NS( cumulus_xbus, LaneRepair, maxSparesExceeded );
PRDF_PLUGIN_DEFINE_NS( axone_xbus, LaneRepair, maxSparesExceeded );
-PRDF_PLUGIN_DEFINE_NS( nimbus_obus, LaneRepair, maxSparesExceeded );
-PRDF_PLUGIN_DEFINE_NS( cumulus_obus, LaneRepair, maxSparesExceeded );
-PRDF_PLUGIN_DEFINE_NS( axone_obus, LaneRepair, maxSparesExceeded );
PRDF_PLUGIN_DEFINE_NS( centaur_membuf, LaneRepair, maxSparesExceeded );
/**
@@ -1064,9 +1040,6 @@ int32_t tooManyBusErrors( ExtensibleChip * i_chip,
PRDF_PLUGIN_DEFINE_NS( nimbus_xbus, LaneRepair, tooManyBusErrors );
PRDF_PLUGIN_DEFINE_NS( cumulus_xbus, LaneRepair, tooManyBusErrors );
PRDF_PLUGIN_DEFINE_NS( axone_xbus, LaneRepair, tooManyBusErrors );
-PRDF_PLUGIN_DEFINE_NS( nimbus_obus, LaneRepair, tooManyBusErrors );
-PRDF_PLUGIN_DEFINE_NS( cumulus_obus, LaneRepair, tooManyBusErrors );
-PRDF_PLUGIN_DEFINE_NS( axone_obus, LaneRepair, tooManyBusErrors );
PRDF_PLUGIN_DEFINE_NS( centaur_membuf, LaneRepair, tooManyBusErrors );
/**
@@ -1078,18 +1051,53 @@ PRDF_PLUGIN_DEFINE_NS( centaur_membuf, LaneRepair, tooManyBusErrors );
int32_t calloutBusInterfacePlugin( ExtensibleChip * i_chip,
STEP_CODE_DATA_STRUCT & io_sc )
{
- calloutBusInterface(i_chip, io_sc, MRU_LOW);
+ calloutBusInterface(i_chip->getTrgt(), io_sc, MRU_LOW);
return SUCCESS;
}
PRDF_PLUGIN_DEFINE_NS( nimbus_xbus, LaneRepair, calloutBusInterfacePlugin );
PRDF_PLUGIN_DEFINE_NS( cumulus_xbus, LaneRepair, calloutBusInterfacePlugin );
PRDF_PLUGIN_DEFINE_NS( axone_xbus, LaneRepair, calloutBusInterfacePlugin );
-PRDF_PLUGIN_DEFINE_NS( nimbus_obus, LaneRepair, calloutBusInterfacePlugin );
-PRDF_PLUGIN_DEFINE_NS( cumulus_obus, LaneRepair, calloutBusInterfacePlugin );
-PRDF_PLUGIN_DEFINE_NS( axone_obus, LaneRepair, calloutBusInterfacePlugin );
+PRDF_PLUGIN_DEFINE_NS( explorer_ocmb, LaneRepair, calloutBusInterfacePlugin );
PRDF_PLUGIN_DEFINE_NS( cumulus_dmi, LaneRepair, calloutBusInterfacePlugin );
PRDF_PLUGIN_DEFINE_NS( centaur_membuf, LaneRepair, calloutBusInterfacePlugin );
+/**
+ * @brief Add callouts for a BUS interface inputting an OMIC or MCC target
+ * @param i_chip OMIC/MCC chip
+ * @param io_sc Step code data struct.
+ * @param i_pos The position of the OMI relative to the OMIC/MCC.
+ * @return SUCCESS always
+ */
+
+int32_t omiParentCalloutBusInterfacePlugin( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ uint8_t i_pos )
+{
+ TargetHandle_t omi = getConnectedChild(i_chip->getTrgt(), TYPE_OMI, i_pos);
+ TargetHandle_t ocmb = getConnectedChild( omi, TYPE_OCMB_CHIP, 0 );
+
+ // Callout both ends of the bus as well (OMI and OCMB)
+ io_sc.service_data->SetCallout( omi, MRU_MEDA );
+ io_sc.service_data->SetCallout( ocmb, MRU_MEDA );
+
+ calloutBusInterface(omi, io_sc, MRU_LOW);
+ return SUCCESS;
+}
+
+#define OMI_PARENT_CALL_BUS_PLUGIN( POS ) \
+int32_t omiParentCalloutBusInterfacePlugin_##POS( ExtensibleChip * i_chip, \
+ STEP_CODE_DATA_STRUCT & io_sc ) \
+{ \
+ return omiParentCalloutBusInterfacePlugin( i_chip, io_sc, POS ); \
+} \
+PRDF_PLUGIN_DEFINE_NS( axone_omic, LaneRepair, \
+ omiParentCalloutBusInterfacePlugin_##POS );\
+PRDF_PLUGIN_DEFINE_NS( axone_mcc, LaneRepair, \
+ omiParentCalloutBusInterfacePlugin_##POS );
+
+OMI_PARENT_CALL_BUS_PLUGIN( 0 );
+OMI_PARENT_CALL_BUS_PLUGIN( 1 );
+OMI_PARENT_CALL_BUS_PLUGIN( 2 );
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/common/plat/p9/prdfLaneRepair.H b/src/usr/diag/prdf/common/plat/p9/prdfLaneRepair.H
index afc834e29..3f5a3f33c 100644
--- a/src/usr/diag/prdf/common/plat/p9/prdfLaneRepair.H
+++ b/src/usr/diag/prdf/common/plat/p9/prdfLaneRepair.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -56,12 +56,12 @@ int32_t handleLaneRepairEvent (ExtensibleChip * i_chip,
/**
* @brief Will add target bus interface endpoints and all parts in between the
* endpoints to the global error log in RasServices.
- * @param i_chip RX-side chip of bus interface
- * @param i_sc The step code data struct.
+ * @param i_rxTrgt RX-side target of bus interface
+ * @param i_sc The step code data struct.
* @param i_priority Callout priority (default MRU_LOW).
* @return Non-SUCCESS if an internal function fails. SUCCESS otherwise.
*/
-int32_t calloutBusInterface( ExtensibleChip * i_chip,
+int32_t calloutBusInterface( TARGETING::TargetHandle_t i_rxTrgt,
STEP_CODE_DATA_STRUCT & i_sc,
PRDpriority i_priority = MRU_LOW );
diff --git a/src/usr/diag/prdf/common/plat/p9/prdfP9Configurator.C b/src/usr/diag/prdf/common/plat/p9/prdfP9Configurator.C
index e37cffcd3..7c3033dc2 100755
--- a/src/usr/diag/prdf/common/plat/p9/prdfP9Configurator.C
+++ b/src/usr/diag/prdf/common/plat/p9/prdfP9Configurator.C
@@ -243,7 +243,7 @@ errlHndl_t PlatConfigurator::addDomainChips( TARGETING::TYPE i_type,
{
errlHndl_t errl = nullptr;
- std::map<TARGETING::MODEL, std::map<TARGETING::TYPE, const char *>> fnMap =
+ std::map<uint32_t, std::map<TARGETING::TYPE, const char *>> fnMap =
{
{ MODEL_NIMBUS, { { TYPE_PROC, nimbus_proc },
{ TYPE_EQ, nimbus_eq },
@@ -285,7 +285,14 @@ errlHndl_t PlatConfigurator::addDomainChips( TARGETING::TYPE i_type,
{ TYPE_MI, axone_mi },
{ TYPE_MCC, axone_mcc },
{ TYPE_OMIC, axone_omic }, } },
- { MODEL_EXPLORER, { { TYPE_OCMB_CHIP, explorer_ocmb }, } },
+ #ifdef __HOSTBOOT_MODULE
+ { POWER_CHIPID::EXPLORER_16, { { TYPE_OCMB_CHIP, explorer_ocmb }, } },
+ #endif
+ // OCMB is not supported on FSP, however we need support here for the
+ // MODEL_OCMB model for our simulator to work.
+ #ifdef ESW_SIM_COMPILE
+ { MODEL_OCMB, { { TYPE_OCMB_CHIP, explorer_ocmb }, } },
+ #endif
};
// Get references to factory objects.
@@ -299,7 +306,19 @@ errlHndl_t PlatConfigurator::addDomainChips( TARGETING::TYPE i_type,
// Iterate all the targets for this type and add to given domain.
for ( const auto & trgt : getFunctionalTargetList(i_type) )
{
- TARGETING::MODEL model = getChipModel( trgt );
+ uint32_t model = getChipModel( trgt );
+
+ #ifdef __HOSTBOOT_MODULE
+ // Special case for OCMBs (hostboot only issue for P9).
+ if ( MODEL_OCMB == model )
+ {
+ // Use the chip ID instead of model.
+ model = getChipId( trgt );
+
+ // Skip Gemini OCMBs. They can exist, but PRD won't support them.
+ if ( POWER_CHIPID::GEMINI_16 == model ) continue;
+ }
+ #endif
// Ensure this model is supported.
if ( fnMap.end() == fnMap.find(model) )
@@ -350,8 +369,6 @@ errlHndl_t PlatConfigurator::addDomainChips( TARGETING::TYPE i_type,
scanFac, resFac );
break;
- // TODO RTC 199020 - add the pll domains for axone
-
default: ;
}
}
diff --git a/src/usr/diag/prdf/common/plat/p9/prdfP9Obus.C b/src/usr/diag/prdf/common/plat/p9/prdfP9Obus.C
new file mode 100644
index 000000000..6117c6edc
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/p9/prdfP9Obus.C
@@ -0,0 +1,193 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/plat/p9/prdfP9Obus.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+
+// Framework includes
+#include <iipServiceDataCollector.h>
+#include <prdfExtensibleChip.H>
+#include <prdfPluginMap.H>
+
+// Platform includes
+#include <prdfPlatServices.H>
+
+using namespace TARGETING;
+
+namespace PRDF
+{
+
+using namespace PlatServices;
+
+namespace obus
+{
+
+//##############################################################################
+//
+// IOOLFIR
+//
+//##############################################################################
+
+/**
+ * @brief If OBUS is in SMP mode, does defaultMaskedError actions and returns
+ * SUCCESS. Otherwise, returns PRD_SCAN_COMM_REGISTER_ZERO.
+ */
+int32_t smp_masked( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc )
+{
+ if ( obusInSmpMode(i_chip->getTrgt()) )
+ {
+ // SMP mode: This attention should be masked.
+ io_sc.service_data->SetCallout( LEVEL2_SUPPORT, MRU_MED, NO_GARD );
+ io_sc.service_data->setFlag( ServiceDataCollector::AT_THRESHOLD );
+ io_sc.service_data->setFlag( ServiceDataCollector::SERVICE_CALL );
+ return SUCCESS;
+ }
+ else
+ {
+ // Non-SMP mode: Try some other action.
+ return PRD_SCAN_COMM_REGISTER_ZERO;
+ }
+}
+PRDF_PLUGIN_DEFINE_NS( nimbus_obus, obus, smp_masked );
+PRDF_PLUGIN_DEFINE_NS( cumulus_obus, obus, smp_masked );
+PRDF_PLUGIN_DEFINE_NS( axone_obus, obus, smp_masked );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief If OBUS is NOT in SMP mode, does defaultMaskedError actions and
+ * returns SUCCESS. Otherwise, returns PRD_SCAN_COMM_REGISTER_ZERO.
+ */
+int32_t non_smp_masked( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc )
+{
+ if ( obusInSmpMode(i_chip->getTrgt()) )
+ {
+ // SMP mode: Try some other action.
+ return PRD_SCAN_COMM_REGISTER_ZERO;
+ }
+ else
+ {
+ // Non-SMP mode: This attention should be masked.
+ io_sc.service_data->SetCallout( LEVEL2_SUPPORT, MRU_MED, NO_GARD );
+ io_sc.service_data->setFlag( ServiceDataCollector::AT_THRESHOLD );
+ io_sc.service_data->setFlag( ServiceDataCollector::SERVICE_CALL );
+ return SUCCESS;
+ }
+}
+PRDF_PLUGIN_DEFINE_NS( nimbus_obus, obus, non_smp_masked );
+PRDF_PLUGIN_DEFINE_NS( cumulus_obus, obus, non_smp_masked );
+PRDF_PLUGIN_DEFINE_NS( axone_obus, obus, non_smp_masked );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief If OBUS is NOT in SMP mode, calls out this bus on first occurrence and
+ * returns SUCCESS. Otherwise, returns PRD_SCAN_COMM_REGISTER_ZERO.
+ */
+int32_t non_smp_callout_bus_th_1( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ if ( obusInSmpMode(i_chip->getTrgt()) )
+ {
+ // SMP mode: Try some other action.
+ return PRD_SCAN_COMM_REGISTER_ZERO;
+ }
+ else
+ {
+ // Non-SMP mode: Callout this bus. Note that Hostboot does not know what
+ // is on the other side of this bus and does not have any control over
+ // garding/deconfiguring. Therefore, we cannot gard since we will never
+ // know if the other side of the bus has been replaced. Also, there is
+ // a small probability that the fault could be between the two
+ // endpoints. Usually, we would do a procedure callout or call some HWP
+ // that would take care of the "everything in between" scenario.
+ // However, there is no existing mechanism. For now callout level 2
+ // support at low priority.
+ io_sc.service_data->SetCallout( i_chip->getTrgt(), MRU_MED, NO_GARD );
+ io_sc.service_data->SetCallout( LEVEL2_SUPPORT, MRU_LOW, NO_GARD );
+ io_sc.service_data->setFlag( ServiceDataCollector::AT_THRESHOLD );
+ io_sc.service_data->setFlag( ServiceDataCollector::SERVICE_CALL );
+ return SUCCESS;
+ }
+}
+PRDF_PLUGIN_DEFINE_NS( nimbus_obus, obus, non_smp_callout_bus_th_1 );
+PRDF_PLUGIN_DEFINE_NS( cumulus_obus, obus, non_smp_callout_bus_th_1 );
+PRDF_PLUGIN_DEFINE_NS( axone_obus, obus, non_smp_callout_bus_th_1 );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief If OBUS is NOT in SMP mode, calls out level 2 support on first
+ * occurrence and returns SUCCESS. Otherwise, returns
+ * PRD_SCAN_COMM_REGISTER_ZERO.
+ */
+int32_t non_smp_callout_lvl2_th_1( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ if ( obusInSmpMode(i_chip->getTrgt()) )
+ {
+ // SMP mode: Try some other action.
+ return PRD_SCAN_COMM_REGISTER_ZERO;
+ }
+ else
+ {
+ // Non-SMP mode: Callout this bus on first occurrence.
+ io_sc.service_data->SetCallout( LEVEL2_SUPPORT, MRU_MED, NO_GARD );
+ io_sc.service_data->setFlag( ServiceDataCollector::AT_THRESHOLD );
+ io_sc.service_data->setFlag( ServiceDataCollector::SERVICE_CALL );
+ return SUCCESS;
+ }
+}
+PRDF_PLUGIN_DEFINE_NS( nimbus_obus, obus, non_smp_callout_lvl2_th_1 );
+PRDF_PLUGIN_DEFINE_NS( cumulus_obus, obus, non_smp_callout_lvl2_th_1 );
+PRDF_PLUGIN_DEFINE_NS( axone_obus, obus, non_smp_callout_lvl2_th_1 );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief If OBUS is NOT in SMP mode, calls out this OBUS target and returns
+ * SUCCESS. Otherwise, returns PRD_SCAN_COMM_REGISTER_ZERO.
+ */
+int32_t non_smp_callout_self( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ if ( obusInSmpMode(i_chip->getTrgt()) )
+ {
+ // SMP mode: Try some other action.
+ return PRD_SCAN_COMM_REGISTER_ZERO;
+ }
+ else
+ {
+ // Non-SMP mode: Callout this OBUS target.
+ io_sc.service_data->SetCallout( i_chip->getTrgt() );
+ return SUCCESS;
+ }
+}
+PRDF_PLUGIN_DEFINE_NS( nimbus_obus, obus, non_smp_callout_self );
+PRDF_PLUGIN_DEFINE_NS( cumulus_obus, obus, non_smp_callout_self );
+PRDF_PLUGIN_DEFINE_NS( axone_obus, obus, non_smp_callout_self );
+
+} // end namespace obus
+
+} // end namespace PRDF
+
diff --git a/src/usr/diag/prdf/common/plat/p9/prdfP9OcmbChipDomain.C b/src/usr/diag/prdf/common/plat/p9/prdfP9OcmbChipDomain.C
new file mode 100644
index 000000000..2f6c25646
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/p9/prdfP9OcmbChipDomain.C
@@ -0,0 +1,78 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/plat/p9/prdfP9OcmbChipDomain.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+/**
+ * @file prdfP9OcmbChipDomain.C
+ * @brief chip Plug-in code for OCMB domain
+ */
+
+#include <prdfP9OcmbChipDomain.H>
+
+// Framework includes
+#include <prdfExtensibleChip.H>
+#include <prdfPlatServices.H>
+#include <prdfTrace.H>
+#include <prdfOcmbDataBundle.H>
+
+using namespace TARGETING;
+
+namespace PRDF
+{
+
+using namespace PlatServices;
+
+#ifdef __HOSTBOOT_RUNTIME
+void OcmbChipDomain::handleRrFo()
+{
+ #define PRDF_FUNC "[OcmbChipDomain::handleRrFo] "
+
+ do
+ {
+ uint32_t domainSize = GetSize();
+ // Iterate all OCMBs in the domain.
+ for ( uint32_t i = 0; i < domainSize; ++i )
+ {
+ RuleChip * ocmbChip = LookUp(i);
+
+ // Start background scrub if required.
+ OcmbDataBundle * ocmbdb = getOcmbDataBundle( ocmbChip );
+ int32_t l_rc = ocmbdb->getTdCtlr()->handleRrFo();
+ if ( SUCCESS != l_rc )
+ {
+ // Let us not fail here. If problem is contained within an OCMB
+ // we will discover it again during normal TD procedures.
+ PRDF_ERR( PRDF_FUNC "handleRrFo() failed: OCMB=0x%08x",
+ ocmbChip->GetId() );
+ continue; // Keep going.
+ }
+ }
+
+ } while (0);
+
+ #undef PRDF_FUNC
+}
+#endif
+
+} // end namespace PRDF
diff --git a/src/usr/diag/prdf/common/plat/p9/prdfP9OcmbChipDomain.H b/src/usr/diag/prdf/common/plat/p9/prdfP9OcmbChipDomain.H
index 5546d9453..9f5776cac 100644
--- a/src/usr/diag/prdf/common/plat/p9/prdfP9OcmbChipDomain.H
+++ b/src/usr/diag/prdf/common/plat/p9/prdfP9OcmbChipDomain.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -54,6 +54,16 @@ class OcmbChipDomain : public RuleChipDomain
virtual bool Query( ATTENTION_TYPE i_attnType )
{ return false; }
+ #ifdef __HOSTBOOT_RUNTIME
+
+ /**
+ * @brief Starts memory background scrubbing or VCM procedure for OCMB
+ * during R/R and F/O if required.
+ */
+ void handleRrFo();
+
+ #endif
+
};
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/common/plat/p9/prdf_plat_p9.mk b/src/usr/diag/prdf/common/plat/p9/prdf_plat_p9.mk
index cb69cad14..64092650f 100644
--- a/src/usr/diag/prdf/common/plat/p9/prdf_plat_p9.mk
+++ b/src/usr/diag/prdf/common/plat/p9/prdf_plat_p9.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2016,2018
+# Contributors Listed Below - COPYRIGHT 2016,2019
# [+] International Business Machines Corp.
#
#
@@ -56,4 +56,5 @@ prd_rule_plugin += prdfP9Eq.o
prd_rule_plugin += prdfP9TodPlugins.o
prd_rule_plugin += prdfP9Dmi_common.o
prd_rule_plugin += prdfP9Mc_common.o
+prd_rule_plugin += prdfP9Obus.o
diff --git a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C
index f99427d61..5cabaedc8 100644
--- a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C
+++ b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C
@@ -48,7 +48,6 @@
#include <p9_io_xbus_pdwn_lanes.H>
#include <p9_io_xbus_clear_firs.H>
#include <p9_io_erepairAccessorHwpFuncs.H>
-#include <config.h>
#include <p9_io_cen_read_erepair.H>
#include <p9_io_cen_pdwn_lanes.H>
#include <p9_io_dmi_read_erepair.H>
@@ -695,6 +694,10 @@ uint32_t getBadDqBitmap( TargetHandle_t i_trgt, const MemRank & i_rank,
o_rc = __getBadDqBitmap<fapi2::TARGET_TYPE_MEM_PORT>( i_trgt,
i_rank, o_bitmap );
break;
+ case TYPE_OCMB_CHIP:
+ o_rc = __getBadDqBitmap<fapi2::TARGET_TYPE_OCMB_CHIP>( i_trgt,
+ i_rank, o_bitmap );
+ break;
default:
PRDF_ERR( PRDF_FUNC "Invalid trgt type" );
o_rc = FAIL;
@@ -777,6 +780,10 @@ uint32_t setBadDqBitmap( TargetHandle_t i_trgt, const MemRank & i_rank,
o_rc = __setBadDqBitmap<fapi2::TARGET_TYPE_MEM_PORT>( i_trgt,
i_rank, i_bitmap );
break;
+ case TYPE_OCMB_CHIP:
+ o_rc = __setBadDqBitmap<fapi2::TARGET_TYPE_OCMB_CHIP>( i_trgt,
+ i_rank, i_bitmap );
+ break;
default:
PRDF_ERR( PRDF_FUNC "Invalid trgt type" );
o_rc = FAIL;
@@ -872,6 +879,17 @@ void getDimmDqAttr<TYPE_MEM_PORT>( TargetHandle_t i_target,
} // end function getDimmDqAttr
template<>
+void getDimmDqAttr<TYPE_OCMB_CHIP>( TargetHandle_t i_target,
+ uint8_t (&o_dqMapPtr)[DQS_PER_DIMM] )
+{
+ PRDF_ASSERT( TYPE_OCMB_CHIP == getTargetType(i_target) );
+
+ // TODO RTC 210072 - Support for multiple ports per OCMB
+ TargetHandle_t memPort = getConnectedChild( i_target, TYPE_MEM_PORT, 0 );
+ getDimmDqAttr<TYPE_MEM_PORT>( memPort, o_dqMapPtr );
+}
+
+template<>
void getDimmDqAttr<TYPE_DIMM>( TargetHandle_t i_target,
uint8_t (&o_dqMapPtr)[DQS_PER_DIMM] )
{
@@ -947,15 +965,15 @@ int32_t mssGetSteerMux<TYPE_MBA>( TargetHandle_t i_mba, const MemRank & i_rank,
}
template<>
-int32_t mssGetSteerMux<TYPE_MEM_PORT>( TargetHandle_t i_memPort,
- const MemRank & i_rank,
- MemSymbol & o_port0Spare,
- MemSymbol & o_port1Spare,
- MemSymbol & o_eccSpare )
+int32_t mssGetSteerMux<TYPE_OCMB_CHIP>( TargetHandle_t i_ocmb,
+ const MemRank & i_rank,
+ MemSymbol & o_port0Spare,
+ MemSymbol & o_port1Spare,
+ MemSymbol & o_eccSpare )
{
int32_t o_rc = SUCCESS;
- /* TODO RTC 207273 - sparing support
+ /* TODO RTC 199032 - sparing support
// called by FSP code so can't just move to hostboot side
#ifdef __HOSTBOOT_MODULE
@@ -963,7 +981,7 @@ int32_t mssGetSteerMux<TYPE_MEM_PORT>( TargetHandle_t i_memPort,
uint8_t port0Spare, port1Spare, eccSpare;
- fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> fapiPort(i_memPort);
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapiPort(i_ocmb);
FAPI_INVOKE_HWP( errl, mss_check_steering, fapiPort,
i_rank.getMaster(), port0Spare, port1Spare, eccSpare );
@@ -971,15 +989,15 @@ int32_t mssGetSteerMux<TYPE_MEM_PORT>( TargetHandle_t i_memPort,
{
PRDF_ERR( "[PlatServices::mssGetSteerMux] mss_check_steering() "
"failed. HUID: 0x%08x rank: %d",
- getHuid(i_memPort), i_rank.getMaster() );
+ getHuid(i_ocmb), i_rank.getMaster() );
PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
o_rc = FAIL;
}
else
{
- o_port0Spare = MemSymbol::fromSymbol( i_memPort, i_rank, port0Spare );
- o_port1Spare = MemSymbol::fromSymbol( i_memPort, i_rank, port1Spare );
- o_eccSpare = MemSymbol::fromSymbol( i_memPort, i_rank, eccSpare );
+ o_port0Spare = MemSymbol::fromSymbol( i_ocmb, i_rank, port0Spare );
+ o_port1Spare = MemSymbol::fromSymbol( i_ocmb, i_rank, port1Spare );
+ o_eccSpare = MemSymbol::fromSymbol( i_ocmb, i_rank, eccSpare );
}
#endif
*/
@@ -1020,20 +1038,22 @@ int32_t mssSetSteerMux<TYPE_MBA>( TargetHandle_t i_mba, const MemRank & i_rank,
}
template<>
-int32_t mssSetSteerMux<TYPE_MEM_PORT>( TargetHandle_t i_memPort,
+int32_t mssSetSteerMux<TYPE_OCMB_CHIP>( TargetHandle_t i_memPort,
const MemRank & i_rank, const MemSymbol & i_symbol, bool i_x4EccSpare )
{
int32_t o_rc = SUCCESS;
- /* TODO RTC 207273 - sparing support
+ /* TODO RTC 199032 - sparing support
#ifdef __HOSTBOOT_MODULE
errlHndl_t errl = NULL;
fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> fapiPort(i_memPort);
+ TargetHandle_t dimm = getConnectedDimm( i_memPort, i_rank,
+ i_symbol.getPortSlct() );
uint8_t l_dramSymbol = PARSERUTILS::dram2Symbol<TYPE_MBA>(
i_symbol.getDram(),
- isDramWidthX4(i_memPort) );
+ isDramWidthX4(dimm) );
FAPI_INVOKE_HWP( errl, mss_do_steering, fapiPort,
i_rank.getMaster(), l_dramSymbol,
@@ -1105,7 +1125,9 @@ int32_t getDimmSpareConfig<TYPE_MEM_PORT>( TargetHandle_t i_memPort,
bool isFullByte = ( ENUM_ATTR_MEM_EFF_DIMM_SPARE_FULL_BYTE ==
o_spareConfig );
- bool isX4Dram = isDramWidthX4(i_memPort);
+
+ TargetHandle_t dimm = getConnectedDimm( i_memPort, i_rank, i_ps );
+ bool isX4Dram = isDramWidthX4(dimm);
if ( ( isX4Dram && isFullByte ) || ( !isX4Dram && !isFullByte ) )
{
@@ -1122,6 +1144,15 @@ int32_t getDimmSpareConfig<TYPE_MEM_PORT>( TargetHandle_t i_memPort,
}
template<>
+int32_t getDimmSpareConfig<TYPE_OCMB_CHIP>( TargetHandle_t i_ocmb,
+ MemRank i_rank, uint8_t i_ps, uint8_t & o_spareConfig )
+{
+ TargetHandle_t memPort = getConnectedChild( i_ocmb, TYPE_MEM_PORT, i_ps );
+ return getDimmSpareConfig<TYPE_MEM_PORT>( memPort, i_rank, i_ps,
+ o_spareConfig );
+}
+
+template<>
int32_t getDimmSpareConfig<TYPE_MBA>( TargetHandle_t i_mba, MemRank i_rank,
uint8_t i_ps, uint8_t & o_spareConfig )
{
@@ -1207,7 +1238,8 @@ uint32_t isDramSparingEnabled<TYPE_MEM_PORT>( TARGETING::TargetHandle_t i_trgt,
do
{
- const bool isX4 = isDramWidthX4( i_trgt );
+ TargetHandle_t dimm = getConnectedDimm( i_trgt, i_rank, i_ps );
+ const bool isX4 = isDramWidthX4( dimm );
if ( isX4 )
{
// Always an ECC spare in x4 mode.
@@ -1216,9 +1248,7 @@ uint32_t isDramSparingEnabled<TYPE_MEM_PORT>( TARGETING::TargetHandle_t i_trgt,
}
// Check for any DRAM spares.
- // TODO RTC 207273 - no TARGETING support for attr yet
- //uint8_t cnfg = TARGETING::MEM_EFF_DIMM_SPARE_NO_SPARE;
- uint8_t cnfg = 0;
+ uint8_t cnfg = TARGETING::MEM_EFF_DIMM_SPARE_NO_SPARE;
o_rc = getDimmSpareConfig<TYPE_MEM_PORT>( i_trgt, i_rank, i_ps, cnfg );
if ( SUCCESS != o_rc )
{
@@ -1226,9 +1256,7 @@ uint32_t isDramSparingEnabled<TYPE_MEM_PORT>( TARGETING::TargetHandle_t i_trgt,
"failed", getHuid(i_trgt), i_rank.getKey(), i_ps );
break;
}
- // TODO RTC 207273 - no TARGETING support for attr yet
- //o_spareEnable = (TARGETING::MEM_EFF_DIMM_SPARE_NO_SPARE; != cnfg);
- o_spareEnable = (0 != cnfg);
+ o_spareEnable = (TARGETING::MEM_EFF_DIMM_SPARE_NO_SPARE != cnfg);
}while(0);
@@ -1303,12 +1331,22 @@ uint32_t isSpareAvailable( TARGETING::TargetHandle_t i_trgt, MemRank i_rank,
if ( !dramSparingEnabled ) break;
// Get the current spares in hardware
+ TargetHandle_t steerTrgt = i_trgt;
MemSymbol sp0, sp1, ecc;
- o_rc = mssGetSteerMux<T>( i_trgt, i_rank, sp0, sp1, ecc );
+ if ( TYPE_MEM_PORT == T )
+ {
+ steerTrgt = getConnectedParent( i_trgt, TYPE_OCMB_CHIP );
+ o_rc = mssGetSteerMux<TYPE_OCMB_CHIP>( steerTrgt, i_rank, sp0, sp1,
+ ecc );
+ }
+ else
+ {
+ o_rc = mssGetSteerMux<T>( steerTrgt, i_rank, sp0, sp1, ecc );
+ }
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "mssGetSteerMux(0x%08x,0x%02x) failed",
- getHuid(i_trgt), i_rank.getKey() );
+ getHuid(steerTrgt), i_rank.getKey() );
break;
}
@@ -1353,6 +1391,10 @@ template
uint32_t isSpareAvailable<TYPE_MBA>( TARGETING::TargetHandle_t i_trgt,
MemRank i_rank, uint8_t i_ps, bool & o_spAvail, bool & o_eccAvail );
+template
+uint32_t isSpareAvailable<TYPE_MEM_PORT>( TARGETING::TargetHandle_t i_trgt,
+ MemRank i_rank, uint8_t i_ps, bool & o_spAvail, bool & o_eccAvail );
+
//------------------------------------------------------------------------------
template<>
diff --git a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H
index 5d41d96e0..203703b42 100755
--- a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H
+++ b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H
@@ -193,7 +193,7 @@ bool obusInSmpMode(TARGETING::TargetHandle_t obusTgt);
/**
* @brief Reads the bad DQ bitmap attribute for both ports of the target rank.
- * @param i_trgt A MCA/MBA/MEM_PORT target.
+ * @param i_trgt A MCA/MBA/MEM_PORT/OCMB_CHIP target.
* @param i_rank Target rank.
* @param o_bitmap DQ bitmap container.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
@@ -203,7 +203,7 @@ uint32_t getBadDqBitmap( TARGETING::TargetHandle_t i_trgt,
/**
* @brief Writes the bad DQ bitmap attribute for both ports of the target rank.
- * @param i_trgt A MCA/MBA/MEM_PORT target.
+ * @param i_trgt A MCA/MBA/MEM_PORT/OCMB_CHIP target.
* @param i_rank Target rank.
* @param i_bitmap DQ bitmap container.
* @note This is a no-op if DRAM Repairs are disabled in manufacturing.
@@ -215,7 +215,7 @@ uint32_t setBadDqBitmap( TARGETING::TargetHandle_t i_trgt,
/**
* @brief Clears the bad DQ bitmap attribute for all ports of the target rank.
- * @param i_trgt A MCA/MBA/MEM_PORT target.
+ * @param i_trgt A MCA/MBA/MEM_PORT/OCMB_CHIP target.
* @param i_rank Target rank.
* @note This is a no-op if DRAM Repairs are disabled in manufacturing.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
diff --git a/src/usr/diag/prdf/common/plat/prdfRasServices_common.C b/src/usr/diag/prdf/common/plat/prdfRasServices_common.C
index 3f9ba2322..2742286b3 100755
--- a/src/usr/diag/prdf/common/plat/prdfRasServices_common.C
+++ b/src/usr/diag/prdf/common/plat/prdfRasServices_common.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -891,12 +891,21 @@ void ErrDataService::deallocateDimms( const SDC_MRU_LIST & i_mruList )
for ( SDC_MRU_LIST::const_iterator it = i_mruList.begin();
it != i_mruList.end(); ++it )
{
+
PRDcallout thiscallout = it->callout;
if ( PRDcalloutData::TYPE_TARGET == thiscallout.getType() )
{
TargetHandle_t calloutTgt = thiscallout.getTarget();
TYPE tgtType = getTargetType( calloutTgt );
+ #ifdef CONFIG_NVDIMM
+ // If the MRU's gard policy is set to NO_GARD, skip it.
+ if ( NO_GARD == it->gardState && isNVDIMM(calloutTgt) )
+ {
+ continue;
+ }
+ #endif
+
if ( TYPE_L4 == tgtType )
{
calloutTgt = getConnectedParent( calloutTgt, TYPE_MEMBUF );
@@ -932,7 +941,17 @@ void ErrDataService::deallocateDimms( const SDC_MRU_LIST & i_mruList )
dimm != dimms.end(); ++dimm )
{
if ( TYPE_DIMM == getTargetType(*dimm) )
+ {
+ #ifdef CONFIG_NVDIMM
+ // If the MRU's gard policy is set to NO_GARD, skip it.
+ if ( NO_GARD == it->gardState && isNVDIMM(*dimm) )
+ {
+ continue;
+ }
+ #endif
+
dimmList.push_back(*dimm);
+ }
}
}
}
diff --git a/src/usr/diag/prdf/common/plat/prdfTargetServices.C b/src/usr/diag/prdf/common/plat/prdfTargetServices.C
index 65f8b9cdc..d34c980ad 100755
--- a/src/usr/diag/prdf/common/plat/prdfTargetServices.C
+++ b/src/usr/diag/prdf/common/plat/prdfTargetServices.C
@@ -365,6 +365,20 @@ TARGETING::MODEL getChipModel( TARGETING::TargetHandle_t i_trgt )
//------------------------------------------------------------------------------
+#ifdef __HOSTBOOT_MODULE
+uint32_t getChipId( TARGETING::TargetHandle_t i_trgt )
+{
+ PRDF_ASSERT( NULL != i_trgt );
+
+ TargetHandle_t parent = getParentChip( i_trgt );
+ PRDF_ASSERT( NULL != parent );
+
+ return parent->getAttr<ATTR_CHIP_ID>();
+}
+#endif
+
+//------------------------------------------------------------------------------
+
uint8_t getChipLevel( TARGETING::TargetHandle_t i_trgt )
{
PRDF_ASSERT( NULL != i_trgt );
@@ -566,6 +580,7 @@ TargetService::ASSOCIATION_TYPE getAssociationType( TargetHandle_t i_target,
{ TYPE_MC, TYPE_PROC, TargetService::PARENT_BY_AFFINITY },
{ TYPE_MC, TYPE_MI, TargetService::CHILD_BY_AFFINITY },
{ TYPE_MC, TYPE_OMIC, TargetService::CHILD_BY_AFFINITY },
+ { TYPE_MC, TYPE_MCC, TargetService::CHILD_BY_AFFINITY },
{ TYPE_MC, TYPE_DMI, TargetService::CHILD_BY_AFFINITY },
{ TYPE_MC, TYPE_DIMM, TargetService::CHILD_BY_AFFINITY },
@@ -579,13 +594,16 @@ TargetService::ASSOCIATION_TYPE getAssociationType( TargetHandle_t i_target,
{ TYPE_OMIC, TYPE_OMI, TargetService::CHILD_BY_AFFINITY },
{ TYPE_MCC, TYPE_PROC, TargetService::PARENT_BY_AFFINITY },
+ { TYPE_MCC, TYPE_MC, TargetService::PARENT_BY_AFFINITY },
{ TYPE_MCC, TYPE_MI, TargetService::PARENT_BY_AFFINITY },
{ TYPE_MCC, TYPE_OMI, TargetService::CHILD_BY_AFFINITY },
+ { TYPE_MCC, TYPE_OCMB_CHIP, TargetService::CHILD_BY_AFFINITY },
{ TYPE_OMI, TYPE_OMIC, TargetService::PARENT_BY_AFFINITY },
{ TYPE_OMI, TYPE_MCC, TargetService::PARENT_BY_AFFINITY },
{ TYPE_OMI, TYPE_OCMB_CHIP, TargetService::CHILD_BY_AFFINITY },
+ { TYPE_OCMB_CHIP, TYPE_MCC, TargetService::PARENT_BY_AFFINITY },
{ TYPE_OCMB_CHIP, TYPE_OMI, TargetService::PARENT_BY_AFFINITY },
{ TYPE_OCMB_CHIP, TYPE_MEM_PORT,TargetService::CHILD_BY_AFFINITY },
{ TYPE_OCMB_CHIP, TYPE_DIMM, TargetService::CHILD_BY_AFFINITY },
@@ -648,14 +666,30 @@ TargetHandleList getConnAssoc( TargetHandle_t i_target, TYPE i_connType,
TargetHandleList o_list; // Default empty list
- // Match any class, specified type, and functional.
- PredicateCTM predType( CLASS_NA, i_connType );
- PredicateIsFunctional predFunc;
- PredicatePostfixExpr predAnd;
- predAnd.push(&predType).push(&predFunc).And();
+ TYPE trgtType = getTargetType( i_target );
- targetService().getAssociated( o_list, i_target, i_assocType,
- TargetService::ALL, &predAnd );
+ // OMIC -> OMI and vice versa require special handling.
+ if ( TYPE_OMIC == trgtType && TYPE_OMI == i_connType )
+ {
+ getChildOmiTargetsByState( o_list, i_target, CLASS_NA, TYPE_OMI,
+ UTIL_FILTER_FUNCTIONAL );
+ }
+ else if ( TYPE_OMI == trgtType && TYPE_OMIC == i_connType )
+ {
+ getParentOmicTargetsByState( o_list, i_target, CLASS_NA, TYPE_OMIC,
+ UTIL_FILTER_FUNCTIONAL );
+ }
+ else
+ {
+ // Match any class, specified type, and functional.
+ PredicateCTM predType( CLASS_NA, i_connType );
+ PredicateIsFunctional predFunc;
+ PredicatePostfixExpr predAnd;
+ predAnd.push(&predType).push(&predFunc).And();
+
+ targetService().getAssociated( o_list, i_target, i_assocType,
+ TargetService::ALL, &predAnd );
+ }
// Sort by target position.
std::sort( o_list.begin(), o_list.end(),
@@ -866,6 +900,17 @@ TargetHandle_t getConnectedChild( TargetHandle_t i_target, TYPE i_connType,
(i_connPos == (miPos % MAX_MI_PER_MC));
} );
}
+ else if ( TYPE_MC == trgtType && TYPE_MCC == i_connType )
+ {
+ // i_connPos is position relative to MC (0-3)
+ itr = std::find_if( list.begin(), list.end(),
+ [&](const TargetHandle_t & t)
+ {
+ uint32_t mccPos = getTargetPosition(t);
+ return (trgtPos == (mccPos / MAX_MCC_PER_MC)) &&
+ (i_connPos == (mccPos % MAX_MCC_PER_MC));
+ } );
+ }
else if ( TYPE_MC == trgtType && TYPE_DMI == i_connType )
{
// i_connPos is position relative to MC (0-3)
@@ -929,6 +974,17 @@ TargetHandle_t getConnectedChild( TargetHandle_t i_target, TYPE i_connType,
(i_connPos == (omiPos % MAX_OMI_PER_MCC));
} );
}
+ else if ( TYPE_MCC == trgtType && TYPE_OCMB_CHIP == i_connType )
+ {
+ // i_connPos is position relative to MCC (0-1)
+ itr = std::find_if( list.begin(), list.end(),
+ [&](const TargetHandle_t & t)
+ {
+ uint32_t ocmbPos = getTargetPosition(t);
+ return (trgtPos == (ocmbPos / MAX_OCMB_PER_MCC)) &&
+ (i_connPos == (ocmbPos % MAX_OCMB_PER_MCC));
+ } );
+ }
else if ( TYPE_MC == trgtType && TYPE_OMIC == i_connType )
{
// i_connPos is position relative to MC (0-2)
@@ -943,13 +999,17 @@ TargetHandle_t getConnectedChild( TargetHandle_t i_target, TYPE i_connType,
else if ( TYPE_OMIC == trgtType && TYPE_OMI == i_connType )
{
// i_connPos is position relative to OMIC (0-2)
- itr = std::find_if( list.begin(), list.end(),
- [&](const TargetHandle_t & t)
- {
- uint32_t omiPos = getTargetPosition(t);
- return (trgtPos == (omiPos / MAX_OMI_PER_OMIC)) &&
- (i_connPos == (omiPos % MAX_OMI_PER_OMIC));
- } );
+ for ( TargetHandleList::iterator trgtIt = list.begin();
+ trgtIt != list.end(); trgtIt++ )
+ {
+ uint8_t omiPos = 0;
+ if ( (*trgtIt)->tryGetAttr<ATTR_OMI_DL_GROUP_POS>(omiPos) &&
+ (i_connPos == omiPos) )
+ {
+ itr = trgtIt;
+ break;
+ }
+ }
}
else if ( TYPE_PROC == trgtType && TYPE_NPU == i_connType )
{
@@ -991,7 +1051,12 @@ ExtensibleChipList getConnected( ExtensibleChip * i_chip, TYPE i_connType )
TargetHandleList list = getConnected( i_chip->getTrgt(), i_connType );
for ( auto & trgt : list )
{
- o_list.push_back( (ExtensibleChip *)systemPtr->GetChip(trgt) );
+ // Check to make sure that if we have a non-null Target, we also
+ // get back a non-null ExtensibleChip.
+ ExtensibleChip * chip = (ExtensibleChip *)systemPtr->GetChip(trgt);
+ PRDF_ASSERT( nullptr != chip );
+
+ o_list.push_back( chip );
}
return o_list;
@@ -1007,7 +1072,12 @@ ExtensibleChip * getConnectedParent( ExtensibleChip * i_child,
TargetHandle_t trgt = getConnectedParent( i_child->getTrgt(),
i_parentType );
- return (ExtensibleChip *)systemPtr->GetChip( trgt );
+ // Check to make sure that if we have a non-null Target, we also
+ // get back a non-null ExtensibleChip.
+ ExtensibleChip * chip = (ExtensibleChip *)systemPtr->GetChip( trgt );
+ PRDF_ASSERT( nullptr != chip );
+
+ return chip;
}
//------------------------------------------------------------------------------
@@ -1026,6 +1096,10 @@ ExtensibleChip * getConnectedChild( ExtensibleChip * i_parent,
if ( nullptr != trgt )
{
o_child = (ExtensibleChip *)systemPtr->GetChip( trgt );
+
+ // Check to make sure that if we have a non-null Target, we also
+ // get back a non-null ExtensibleChip.
+ PRDF_ASSERT( nullptr != o_child );
}
return o_child;
@@ -1471,7 +1545,9 @@ bool isDramWidthX4( TargetHandle_t i_trgt )
bool o_dramWidthX4 = false;
PRDF_ASSERT( nullptr != i_trgt );
- //uint8_t dramWidths = 0;
+ uint8_t dramWidths[MAX_DIMM_PER_PORT];
+ uint8_t dimmSlct = 0;
+ TargetHandle_t memPort = nullptr;
switch ( getTargetType(i_trgt) )
{
@@ -1485,12 +1561,17 @@ bool isDramWidthX4( TargetHandle_t i_trgt )
break;
case TYPE_DIMM:
- // TODO RTC 207273 - attribute not in TARGETING code yet
- //TargetHandle_t memPort = getConnectedParent(i_trgt, TYPE_MEM_PORT);
- //dramWidths = memPort->getAttr<ATTR_MEM_EFF_DRAM_WIDTH>();
- //uint8_t dimmSlct = getDimmSlct( i_trgt );
- //o_dramWidthX4 =
- // (fapi2::ENUM_ATTR_MEM_EFF_DRAM_WIDTH_X4 == dramWidths[dimmSlct]);
+ memPort = getConnectedParent(i_trgt, TYPE_MEM_PORT);
+ if ( !memPort->tryGetAttr<ATTR_MEM_EFF_DRAM_WIDTH>(dramWidths) )
+ {
+ PRDF_ERR( "isDramWidthX4: Unable to access "
+ "ATTR_MEM_EFF_DRAM_WIDTH i_trgt=0x%08x.",
+ getHuid(memPort) );
+ PRDF_ASSERT( false );
+ }
+ dimmSlct = getDimmSlct( i_trgt );
+ o_dramWidthX4 =
+ (TARGETING::MEM_EFF_DRAM_WIDTH_X4 == dramWidths[dimmSlct]);
break;
default:
@@ -1538,15 +1619,12 @@ void __getMasterRanks( TargetHandle_t i_trgt, std::vector<MemRank> & o_ranks,
}
else if ( MODEL_AXONE == l_procModel )
{
- PRDF_ERR( PRDF_FUNC "Axone attribute not supported yet" );
- /* TODO RTC 207273 - no targeting support for attr yet
if ( !i_trgt->tryGetAttr<ATTR_MEM_EFF_DIMM_RANKS_CONFIGED>(info[0]) )
{
PRDF_ERR( PRDF_FUNC "tryGetAttr<ATTR_MEM_EFF_DIMM_RANKS_CONFIGED> "
"failed: i_trgt=0x%08x", getHuid(i_trgt) );
PRDF_ASSERT( false ); // attribute does not exist for target
}
- */
}
else
{
@@ -1605,17 +1683,21 @@ void getMasterRanks<TYPE_MBA>( TargetHandle_t i_trgt,
}
template<>
-void getMasterRanks<TYPE_MEM_PORT>( TargetHandle_t i_trgt,
- std::vector<MemRank> & o_ranks,
- uint8_t i_ds )
-{
- __getMasterRanks<TYPE_MEM_PORT>( i_trgt, o_ranks, 0, i_ds );
+void getMasterRanks<TYPE_OCMB_CHIP>( TargetHandle_t i_trgt,
+ std::vector<MemRank> & o_ranks,
+ uint8_t i_ds )
+{
+ // TODO RTC 210072 - Explorer only has one port, however, multiple ports
+ // will be supported in the future. Updates will need to be made here so we
+ // can get the relevant port.
+ TargetHandle_t memPort = getConnectedChild( i_trgt, TYPE_MEM_PORT, 0 );
+ __getMasterRanks<TYPE_MEM_PORT>( memPort, o_ranks, 0, i_ds );
}
//------------------------------------------------------------------------------
template<TARGETING::TYPE T>
-void __getSlaveRanks( TargetHandle_t i_trgt, std::vector<MemRank> & o_ranks,
+void getSlaveRanks( TargetHandle_t i_trgt, std::vector<MemRank> & o_ranks,
uint8_t i_ds )
{
PRDF_ASSERT( nullptr != i_trgt );
@@ -1656,29 +1738,18 @@ void __getSlaveRanks( TargetHandle_t i_trgt, std::vector<MemRank> & o_ranks,
}
}
-template<>
+template
void getSlaveRanks<TYPE_MCA>( TargetHandle_t i_trgt,
std::vector<MemRank> & o_ranks,
- uint8_t i_ds )
-{
- __getSlaveRanks<TYPE_MCA>( i_trgt, o_ranks, i_ds );
-}
-
-template<>
+ uint8_t i_ds );
+template
void getSlaveRanks<TYPE_MBA>( TargetHandle_t i_trgt,
std::vector<MemRank> & o_ranks,
- uint8_t i_ds )
-{
- __getSlaveRanks<TYPE_MBA>( i_trgt, o_ranks, i_ds );
-}
-
-template<>
-void getSlaveRanks<TYPE_MEM_PORT>( TargetHandle_t i_trgt,
- std::vector<MemRank> & o_ranks,
- uint8_t i_ds )
-{
- __getSlaveRanks<TYPE_MEM_PORT>( i_trgt, o_ranks, i_ds );
-}
+ uint8_t i_ds );
+template
+void getSlaveRanks<TYPE_OCMB_CHIP>( TargetHandle_t i_trgt,
+ std::vector<MemRank> & o_ranks,
+ uint8_t i_ds );
//------------------------------------------------------------------------------
@@ -1774,12 +1845,15 @@ uint8_t getNumMasterRanksPerDimm<TYPE_MBA>( TargetHandle_t i_trgt,
}
template<>
-uint8_t getNumMasterRanksPerDimm<TYPE_MEM_PORT>( TargetHandle_t i_trgt,
- uint8_t i_ds )
-{
- return __getNumMasterRanksPerDimm<TYPE_MEM_PORT>( i_trgt, 0, i_ds );
+uint8_t getNumMasterRanksPerDimm<TYPE_OCMB_CHIP>( TargetHandle_t i_trgt,
+ uint8_t i_ds )
+{
+ // TODO RTC 210072 - Explorer only has one port, however, multiple ports
+ // will be supported in the future. Updates will need to be made here so we
+ // can get the relevant port.
+ TargetHandle_t memPort = getConnectedChild( i_trgt, TYPE_MEM_PORT, 0 );
+ return __getNumMasterRanksPerDimm<TYPE_MEM_PORT>( memPort, 0, i_ds );
}
-
//------------------------------------------------------------------------------
template<TARGETING::TYPE T>
@@ -1822,10 +1896,10 @@ uint8_t __getNumRanksPerDimm( TargetHandle_t i_trgt,
}
else if ( MODEL_AXONE == l_procModel )
{
- ATTR_MEM_EFF_NUM_RANKS_PER_DIMM_type attr;
- if ( !i_trgt->tryGetAttr<ATTR_MEM_EFF_NUM_RANKS_PER_DIMM>(attr) )
+ ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM_type attr;
+ if ( !i_trgt->tryGetAttr<ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM>(attr) )
{
- PRDF_ERR( PRDF_FUNC "tryGetAttr<ATTR_MEM_EFF_NUM_RANKS_PER_DIMM> "
+ PRDF_ERR( PRDF_FUNC "tryGetAttr<ATTR_MEM_EFF_LOGICAL_RANKS_PER_DIMM> "
"failed: i_trgt=0x%08x", getHuid(i_trgt) );
PRDF_ASSERT( false ); // attribute does not exist for target
}
@@ -1869,9 +1943,13 @@ uint8_t getNumRanksPerDimm<TYPE_MBA>( TargetHandle_t i_trgt, uint8_t i_ds )
}
template<>
-uint8_t getNumRanksPerDimm<TYPE_MEM_PORT>( TargetHandle_t i_trgt, uint8_t i_ds )
+uint8_t getNumRanksPerDimm<TYPE_OCMB_CHIP>(TargetHandle_t i_trgt, uint8_t i_ds)
{
- return __getNumRanksPerDimm<TYPE_MEM_PORT>( i_trgt, 0, i_ds );
+ // TODO RTC 210072 - Explorer only has one port, however, multiple ports
+ // will be supported in the future. Updates will need to be made here so we
+ // can get the relevant port.
+ TargetHandle_t memPort = getConnectedChild( i_trgt, TYPE_MEM_PORT, 0 );
+ return __getNumRanksPerDimm<TYPE_MEM_PORT>( memPort, 0, i_ds );
}
//##############################################################################
diff --git a/src/usr/diag/prdf/common/plat/prdfTargetServices.H b/src/usr/diag/prdf/common/plat/prdfTargetServices.H
index 8793e8c61..34af865d7 100755
--- a/src/usr/diag/prdf/common/plat/prdfTargetServices.H
+++ b/src/usr/diag/prdf/common/plat/prdfTargetServices.H
@@ -42,6 +42,10 @@
#include <targeting/common/target.H>
#include <prdfParserEnums.H>
+#ifdef __HOSTBOOT_MODULE
+ #include <chipids.H>
+#endif
+
//------------------------------------------------------------------------------
namespace PRDF
@@ -145,6 +149,20 @@ TARGETING::CLASS getTargetClass( TARGETING::TargetHandle_t i_target );
*/
TARGETING::MODEL getChipModel( TARGETING::TargetHandle_t i_trgt );
+#ifdef __HOSTBOOT_MODULE
+
+// NOTE: This should be used instead of getChipModel() because of the case of
+// MODEL_OCMB, where we need the chip ID to distinguish between Explorer
+// and Gemini.
+
+/**
+ * @param i_trgt A chip target or any unit target within the chip.
+ * @return The chip ID.
+ */
+uint32_t getChipId( TARGETING::TargetHandle_t i_trgt );
+
+#endif
+
/**
* @param i_trgt A chip target or any unit target within the chip.
* @return The level (EC level) of a chip.
@@ -293,7 +311,7 @@ TARGETING::TargetHandle_t getConnectedPeerTarget(
TARGETING::TargetHandle_t i_tgt);
/**
- * @param i_trgt The target MBA, MCA, or MEM_PORT.
+ * @param i_trgt The target MBA, MCA, OCMB_CHIP, or MEM_PORT.
* @param i_rank The target rank.
* @return A list of DIMMs connected to the target and rank.
*/
@@ -301,10 +319,10 @@ TARGETING::TargetHandleList getConnectedDimms( TARGETING::TargetHandle_t i_trgt,
const MemRank & i_rank );
/**
- * @param i_trgt The target MBA, MCA, or MEM_PORT.
+ * @param i_trgt The target MBA, MCA, OCMB_CHIP, or MEM_PORT.
* @param i_rank The target rank.
- * @param i_port Port select, only needed for MBA. MCA and MEM_PORT are
- * targets equivalent to the port already.
+ * @param i_port Port select, only needed for MBA and OCMB_CHIP. MCA and
+ * MEM_PORT are targets equivalent to the port already.
* @return The DIMM connected to the target and rank on a port.
*/
TARGETING::TargetHandle_t getConnectedDimm( TARGETING::TargetHandle_t i_trgt,
@@ -434,7 +452,7 @@ uint8_t getColNumConfig( TARGETING::TargetHandle_t i_trgt );
/**
* @brief Returns a sorted list of configured master ranks for an MCA or MBA.
- * @param i_trgt MCA, MBA, or MEM_PORT target.
+ * @param i_trgt MCA, MBA, or OCMB_CHIP target.
* @param o_ranks The returned list.
* @param i_ds When used, this function will only return the list of ranks
* for the target DIMM select. Otherwise, the default is to
@@ -450,7 +468,7 @@ void getMasterRanks( TARGETING::TargetHandle_t i_trgt,
/**
* @brief Returns a sorted list of configured slave ranks for an MCA or MBA.
- * @param i_trgt MCA, MBA, or MEM_PORT target.
+ * @param i_trgt MCA, MBA, or OCMB_CHIP target.
* @param o_ranks The returned list.
* @param i_ds When used, this function will only return the list of ranks
* for the target DIMM select. Otherwise, the default is to
@@ -466,7 +484,7 @@ void getSlaveRanks( TARGETING::TargetHandle_t i_trgt,
/**
* @brief Obtains the number of master ranks per DIMM select.
- * @param i_trgt MCA, MBA, or MEM_PORT target.
+ * @param i_trgt MCA, MBA, or OCMB_CHIP target.
* @param i_ds DIMM select.
* @return Total number of master ranks configured per DIMM select.
*/
@@ -477,7 +495,7 @@ uint8_t getNumMasterRanksPerDimm( TARGETING::TargetHandle_t i_trgt,
/**
* @brief Obtains the total number of ranks (including slave ranks) per DIMM
* select.
- * @param i_trgt MCA, MBA, or MEM_PORT target.
+ * @param i_trgt MCA, MBA, or OCMB_CHIP target.
* @param i_ds DIMM select.
* @return Total number of ranks configured per DIMM select.
*/
diff --git a/src/usr/diag/prdf/common/plugins/prdfLogParse_common.C b/src/usr/diag/prdf/common/plugins/prdfLogParse_common.C
index c6cd47d0b..08aa11600 100644
--- a/src/usr/diag/prdf/common/plugins/prdfLogParse_common.C
+++ b/src/usr/diag/prdf/common/plugins/prdfLogParse_common.C
@@ -237,6 +237,18 @@ void getTargetInfo( HUID i_chipId, TARGETING::TYPE & o_targetType,
l_node, l_chip, l_chiplet );
break;
+ case TYPE_OCMB_CHIP:
+ snprintf( o_chipName, i_sz_chipName, "ocmb(n%dp%d)",
+ l_node, l_chip );
+ break;
+
+ case TYPE_MEM_PORT:
+ l_chip = l_chip / MAX_PORT_PER_OCMB;
+ l_chiplet = l_chiplet % MAX_PORT_PER_OCMB;
+ snprintf( o_chipName, i_sz_chipName, "memport(n%dp%dc%d)",
+ l_node, l_chip, l_chiplet );
+ break;
+
case TYPE_MCS:
l_chip = l_chip / MAX_MCS_PER_PROC;
l_chiplet = l_chiplet % MAX_MCS_PER_PROC;
@@ -286,6 +298,13 @@ void getTargetInfo( HUID i_chipId, TARGETING::TYPE & o_targetType,
l_node, l_chip, l_chiplet );
break;
+ case TYPE_OMI:
+ l_chip = l_chip / MAX_OMI_PER_PROC;
+ l_chiplet = l_chiplet % MAX_OMI_PER_PROC;
+ snprintf( o_chipName, i_sz_chipName, "omi(n%dp%dc%d)",
+ l_node, l_chip, l_chiplet );
+ break;
+
case TYPE_MEMBUF:
snprintf( o_chipName, i_sz_chipName, "mb(n%dp%d)",
l_node, l_chip );
diff --git a/src/usr/diag/prdf/common/plugins/prdfMemLogParse.C b/src/usr/diag/prdf/common/plugins/prdfMemLogParse.C
index 390178f6e..1518319d1 100644
--- a/src/usr/diag/prdf/common/plugins/prdfMemLogParse.C
+++ b/src/usr/diag/prdf/common/plugins/prdfMemLogParse.C
@@ -2848,17 +2848,22 @@ void initMemMruStrings( MemoryMruData::MemMruMeld i_mm, bool & o_addDramSite,
memset( o_header, '\0', HEADER_SIZE );
memset( o_data, '\0', DATA_SIZE );
- // Get the position info (default MCA).
- const char * compStr = "mca";
+ // Get the position info (default MBA).
+
+ const char * compStr = "mba";
uint8_t nodePos = i_mm.s.nodePos;
- uint8_t chipPos = i_mm.s.procPos;
- uint8_t compPos = i_mm.s.chnlPos;
+ uint8_t chipPos = (i_mm.s.procPos << 3) | i_mm.s.chnlPos;
+ uint8_t compPos = i_mm.s.mbaPos;
- if ( !i_mm.s.isMca ) // MBA
+ if ( i_mm.s.isMca ) // MCA
+ {
+ compStr = "mca";
+ chipPos = i_mm.s.procPos;
+ compPos = i_mm.s.chnlPos;
+ }
+ else if ( i_mm.s.isOcmb ) // OCMB
{
- compStr = "mba";
- chipPos = (i_mm.s.procPos << 3) | i_mm.s.chnlPos;
- compPos = i_mm.s.mbaPos;
+ compStr = "ocmb";
}
// Build the header string.
@@ -2953,13 +2958,13 @@ void addDramSiteString( const MemoryMruData::ExtendedData & i_extMemMru,
}
}
}
- else // IS DIMMs
+ else // Dram site locations not supported
{
// Add DQ info.
char tmp[DATA_SIZE] = { '\0' };
strcat( io_data, "DQ:" );
- if ( mm.s.isMca ) // MCA
+ if ( mm.s.isMca || mm.s.isOcmb ) // MCA, OCMB
{
// There is only one DQ per symbol.
snprintf( tmp, DATA_SIZE, "%d", i_extMemMru.dqMapping[dqIdx] );
diff --git a/src/usr/diag/prdf/common/plugins/prdfMemoryMruData.H b/src/usr/diag/prdf/common/plugins/prdfMemoryMruData.H
index a9a4498d3..f2fdaff26 100644
--- a/src/usr/diag/prdf/common/plugins/prdfMemoryMruData.H
+++ b/src/usr/diag/prdf/common/plugins/prdfMemoryMruData.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -88,6 +88,10 @@ union MemMruMeld
// version field so that the error log parser know which format to
// used.
+ // NOTE: For OCMBs, specified by the isOcmb field, chnlPos will specify
+ // the MCC position within the proc and mbaPos will specify the
+ // OMI position within the channel.
+
#if !( __BYTE_ORDER == __LITTLE_ENDIAN )
uint32_t valid : 1; ///< Used to indicate nothing failed while
@@ -106,13 +110,15 @@ union MemMruMeld
uint32_t eccSpared : 1; ///< True if symbol is on ECC DRAM
uint32_t srank : 3; ///< Slave rank (0-7)
// If isMca is specified, then chnlPos above will specify the MCA pos
- // and the mbaPos field will be unused
+ // and the mbaPos field will be unused. See above note for OCMB usage.
uint32_t isMca : 1; ///< True if MCA is used as opposed to MBA
- uint32_t unused : 3; ///< 3 Bits currently unused
+ uint32_t isOcmb : 1; ///< True if OCMB is used
+ uint32_t unused : 2; ///< 2 Bits currently unused
#else
// Need to reverse this to make the uint32_t look right in the
// simulator.
- uint32_t unused : 3;
+ uint32_t unused : 2;
+ uint32_t isOcmb : 1;
uint32_t isMca : 1;
uint32_t srank : 3;
uint32_t eccSpared : 1;
diff --git a/src/usr/diag/prdf/common/plugins/prdfParserEnums.H b/src/usr/diag/prdf/common/plugins/prdfParserEnums.H
index af346e57b..1001e185f 100644
--- a/src/usr/diag/prdf/common/plugins/prdfParserEnums.H
+++ b/src/usr/diag/prdf/common/plugins/prdfParserEnums.H
@@ -109,8 +109,14 @@ enum PositionBounds
MAX_OMI_PER_MCC = 2,
MAX_OMI_PER_OMIC = 3,
+ MAX_OMI_PER_MC = 8,
+ MAX_OMI_PER_PROC = MAX_OMI_PER_MC * MAX_MC_PER_PROC,
MAX_OCMB_PER_OMI = 1,
+ MAX_OCMB_PER_MCC = MAX_OCMB_PER_OMI * MAX_OMI_PER_MCC,
+
+ // TODO RTC 210072 - Support multiple ports
+ MAX_PORT_PER_OCMB = 1,
MAX_SUB_PORT = 2,
diff --git a/src/usr/diag/prdf/common/plugins/prdfParserUtils.C b/src/usr/diag/prdf/common/plugins/prdfParserUtils.C
index 9d2233e75..2f9bdb458 100644
--- a/src/usr/diag/prdf/common/plugins/prdfParserUtils.C
+++ b/src/usr/diag/prdf/common/plugins/prdfParserUtils.C
@@ -87,9 +87,9 @@ uint8_t symbol2Dq<TARGETING::TYPE_MCA>( uint8_t i_symbol )
//------------------------------------------------------------------------------
template<>
-uint8_t symbol2Dq<TARGETING::TYPE_MEM_PORT>( uint8_t i_symbol )
+uint8_t symbol2Dq<TARGETING::TYPE_OCMB_CHIP>( uint8_t i_symbol )
{
- // MEM_PORT case is identical to MCA
+ // OCMB_CHIP case is identical to MCA
return symbol2Dq<TARGETING::TYPE_MCA>(i_symbol);
}
@@ -122,10 +122,12 @@ uint8_t symbol2PortSlct<TARGETING::TYPE_MCA>( uint8_t i_symbol )
//------------------------------------------------------------------------------
template<>
-uint8_t symbol2PortSlct<TARGETING::TYPE_MEM_PORT>( uint8_t i_symbol )
+uint8_t symbol2PortSlct<TARGETING::TYPE_OCMB_CHIP>( uint8_t i_symbol )
{
- // Port select does not exist on MEM_PORT. Always return 0 so that code will
- // continue to work.
+ // TODO RTC 210072 - Explorer only has one port, as such we can just
+ // return 0. However, multiple ports will be supported in the future,
+ // We'll need to figure out how to convert the symbol to a port select for
+ // OCMB at that time.
return 0;
}
@@ -149,8 +151,8 @@ uint8_t dq2Symbol<TARGETING::TYPE_MBA>( uint8_t i_dq, uint8_t i_ps )
//------------------------------------------------------------------------------
-template<>
-uint8_t dq2Symbol<TARGETING::TYPE_MCA>( uint8_t i_dq, uint8_t i_ps )
+template<TARGETING::TYPE T>
+uint8_t dq2Symbol( uint8_t i_dq, uint8_t i_ps )
{
uint8_t symbol = SYMBOLS_PER_RANK;
@@ -175,14 +177,12 @@ uint8_t dq2Symbol<TARGETING::TYPE_MCA>( uint8_t i_dq, uint8_t i_ps )
return symbol;
}
-//------------------------------------------------------------------------------
-
-template<>
-uint8_t dq2Symbol<TARGETING::TYPE_MEM_PORT>( uint8_t i_dq, uint8_t i_ps )
-{
- // MEM_PORT case is identical to MCA
- return dq2Symbol<TARGETING::TYPE_MCA>( i_dq, i_ps );
-}
+template
+uint8_t dq2Symbol<TARGETING::TYPE_MCA>( uint8_t i_dq, uint8_t i_ps );
+template
+uint8_t dq2Symbol<TARGETING::TYPE_MEM_PORT>( uint8_t i_dq, uint8_t i_ps );
+template
+uint8_t dq2Symbol<TARGETING::TYPE_OCMB_CHIP>( uint8_t i_dq, uint8_t i_ps );
//------------------------------------------------------------------------------
@@ -218,9 +218,9 @@ uint8_t nibble2Symbol<TARGETING::TYPE_MCA>( uint8_t i_x4Dram )
//------------------------------------------------------------------------------
template<>
-uint8_t nibble2Symbol<TARGETING::TYPE_MEM_PORT>( uint8_t i_x4Dram )
+uint8_t nibble2Symbol<TARGETING::TYPE_OCMB_CHIP>( uint8_t i_x4Dram )
{
- // MEM_PORT case is identical to MCA
+ // OCMB_CHIP case is identical to MCA
return nibble2Symbol<TARGETING::TYPE_MCA>(i_x4Dram);
}
@@ -258,9 +258,9 @@ uint8_t byte2Symbol<TARGETING::TYPE_MCA>( uint8_t i_x8Dram )
//------------------------------------------------------------------------------
template<>
-uint8_t byte2Symbol<TARGETING::TYPE_MEM_PORT>( uint8_t i_x8Dram )
+uint8_t byte2Symbol<TARGETING::TYPE_OCMB_CHIP>( uint8_t i_x8Dram )
{
- // MEM_PORT case is identical to MCA
+ // OCMB_CHIP case is identical to MCA
return byte2Symbol<TARGETING::TYPE_MCA>(i_x8Dram);
}
@@ -286,9 +286,9 @@ uint8_t symbol2Nibble<TARGETING::TYPE_MCA>( uint8_t i_symbol )
//------------------------------------------------------------------------------
template<>
-uint8_t symbol2Nibble<TARGETING::TYPE_MEM_PORT>( uint8_t i_symbol )
+uint8_t symbol2Nibble<TARGETING::TYPE_OCMB_CHIP>( uint8_t i_symbol )
{
- // MEM_PORT case is identical to MCA
+ // OCMB_CHIP case is identical to MCA
return symbol2Nibble<TARGETING::TYPE_MCA>(i_symbol);
}
@@ -314,9 +314,9 @@ uint8_t symbol2Byte<TARGETING::TYPE_MCA>( uint8_t i_symbol )
//------------------------------------------------------------------------------
template<>
-uint8_t symbol2Byte<TARGETING::TYPE_MEM_PORT>( uint8_t i_symbol )
+uint8_t symbol2Byte<TARGETING::TYPE_OCMB_CHIP>( uint8_t i_symbol )
{
- // MEM_PORT case is identical to MCA
+ // OCMB_CHIP case is identical to MCA
return symbol2Byte<TARGETING::TYPE_MCA>(i_symbol);
}
diff --git a/src/usr/diag/prdf/common/prdfMain_common.C b/src/usr/diag/prdf/common/prdfMain_common.C
index fd23cf4d1..09cfe2212 100755
--- a/src/usr/diag/prdf/common/prdfMain_common.C
+++ b/src/usr/diag/prdf/common/prdfMain_common.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -47,6 +47,7 @@
#ifdef __HOSTBOOT_RUNTIME
#include <prdfP9McbistDomain.H>
+#include <prdfP9OcmbChipDomain.H>
#include <prdfCenMbaDomain.H>
#endif
@@ -172,6 +173,10 @@ errlHndl_t noLock_initialize()
{
((MbaDomain *)systemPtr->GetDomain(MBA_DOMAIN))->handleRrFo();
}
+ else if ( MODEL_AXONE == procModel )
+ {
+ ((OcmbChipDomain *)systemPtr->GetDomain(OCMB_DOMAIN))->handleRrFo();
+ }
else
{
PRDF_ERR( PRDF_FUNC "Master PROC model %d not supported", procModel );
diff --git a/src/usr/diag/prdf/common/util/iipbits.h b/src/usr/diag/prdf/common/util/iipbits.h
deleted file mode 100755
index 7b02e52f3..000000000
--- a/src/usr/diag/prdf/common/util/iipbits.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/diag/prdf/common/util/iipbits.h $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* COPYRIGHT International Business Machines Corp. 1993,2014 */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-#include<prdfBitString.H>
diff --git a/src/usr/diag/prdf/framework/prdfFileRegisterAccess.C b/src/usr/diag/prdf/framework/prdfFileRegisterAccess.C
index dfdaabf9c..ed5d3ec0d 100755
--- a/src/usr/diag/prdf/framework/prdfFileRegisterAccess.C
+++ b/src/usr/diag/prdf/framework/prdfFileRegisterAccess.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,7 +37,7 @@ uint32_t FileScomAccessor::Access(
TargetHandle_t i_target,
BitString & bs,
uint64_t registerId,
- MopRegisterAccess::Operation operation) const
+ RegisterAccess::Operation operation) const
{
#define PRDF_FUNC "[FileScomAccessor::Access()] "
@@ -48,13 +48,13 @@ uint32_t FileScomAccessor::Access(
switch (operation)
{
- case MopRegisterAccess::WRITE:
+ case RegisterAccess::WRITE:
// TODO: RTC 62076 move BitString class to 64-bit
data = (((uint64_t)bs.getFieldJustify( 0, 32)) << 32) |
((uint64_t)bs.getFieldJustify(32, 32));
firData.putScom( i_target, registerId, data);
break;
- case MopRegisterAccess::READ:
+ case RegisterAccess::READ:
firData.getScom( i_target, registerId, data);
// TODO: RTC 62076 move BitString class to 64-bit
bs.setFieldJustify( 0, 32, data >> 32);
diff --git a/src/usr/diag/prdf/framework/prdfFileRegisterAccess.H b/src/usr/diag/prdf/framework/prdfFileRegisterAccess.H
index 61d255e8a..84b749a58 100755
--- a/src/usr/diag/prdf/framework/prdfFileRegisterAccess.H
+++ b/src/usr/diag/prdf/framework/prdfFileRegisterAccess.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -71,7 +71,7 @@ class FileScomAccessor : public ScomAccessor
virtual uint32_t Access(TARGETING::TargetHandle_t i_target,
BitString & bs,
uint64_t registerId,
- MopRegisterAccess::Operation operation) const;
+ RegisterAccess::Operation operation) const;
};
} // End namespace PRDF
diff --git a/src/usr/diag/prdf/makefile b/src/usr/diag/prdf/makefile
index ed8b7c1ce..8fda714ed 100755
--- a/src/usr/diag/prdf/makefile
+++ b/src/usr/diag/prdf/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2018
+# Contributors Listed Below - COPYRIGHT 2012,2019
# [+] International Business Machines Corp.
#
#
@@ -39,13 +39,16 @@ include prdf_hb_only.mk # Will define PRD_SRC_PATH and PRD_INC_PATH
include common/prdf_common_fsp_and_hb.mk
include common/framework/prdf_framework.mk
include common/plat/p9/prdf_plat_p9.mk
+include common/plat/axone/prdf_plat_axone.mk
include common/plat/cen/prdf_plat_cen.mk
include common/plat/mem/prdf_plat_mem.mk
include common/plat/centaur/prdf_plat_centaur.mk
include common/plat/cumulus/prdf_plat_cumulus.mk
include common/plat/nimbus/prdf_plat_nimbus.mk
+include common/plat/explorer/prdf_plat_explorer.mk
include plat/cen/prdf_plat_cen_hb_only.mk
include plat/mem/prdf_plat_mem_hb_only.mk
+include plat/explorer/prdf_plat_explorer_hb_only.mk
include plat/p9/prdf_plat_p9_hb_only.mk
VPATH += ${prd_vpath}
diff --git a/src/usr/diag/prdf/occ_firdata/prdfWriteHomerFirData.C b/src/usr/diag/prdf/occ_firdata/prdfWriteHomerFirData.C
index d3b8a72ee..2e9b6f963 100644
--- a/src/usr/diag/prdf/occ_firdata/prdfWriteHomerFirData.C
+++ b/src/usr/diag/prdf/occ_firdata/prdfWriteHomerFirData.C
@@ -621,28 +621,11 @@ void getAddresses( TrgtMap_t & io_targMap )
0x07013340, // OMIDLFIR
};
- io_targMap[TRGT_OCMB][REG_GLBL] =
+ io_targMap[TRGT_OMIC][REG_REG] =
{
- 0x08040000, // MB_CHIPLET_CS_FIR
- 0x08040001, // MB_CHIPLET_RE_FIR
- 0x08040004, // MB_CHIPLET_SPA_FIR
- };
-
- io_targMap[TRGT_OCMB][REG_FIR] =
- {
- 0x0804000a, // MB_LFIR
- 0x08010870, // MMIOFIR
- 0x08011400, // SRQFIR
- 0x08011800, // MCBISTFIR
- 0x08011c00, // RDFFIR
- 0x08012400, // TLXFIR
- 0x08012800, // OMIDLFIR
- };
-
- io_targMap[TRGT_OCMB][REG_REG] =
- {
- 0x08040002, // MB_CHIPLET_FIR_MASK
- 0x08040007, // MB_CHIPLET_SPA_FIR_MASK
+ 0x07013353, // DL0_ERROR_HOLD
+ 0x07013363, // DL1_ERROR_HOLD
+ 0x07013373, // DL2_ERROR_HOLD
};
// EC level handling will be done with a
@@ -721,15 +704,22 @@ void __initChipInfo( TargetHandle_t i_chip, HOMER_ChipType_t i_chipModel,
uint32_t chipPos = getTargetPosition( i_chip );
PRDF_ASSERT( chipPos < i_maxChipsPerNode );
- // Get the chip FSI address.
- FSI::FsiLinkInfo_t fsiInfo;
- FSI::getFsiLinkInfo( i_chip, fsiInfo );
-
// Fill in the HOMER chip info.
o_chipInfo.hChipType = HOMER_getChip( i_chipModel );
o_chipInfo.hChipType.chipPos = chipPos;
- o_chipInfo.hChipType.fsiBaseAddr = fsiInfo.baseAddr;
o_chipInfo.hChipType.chipEcLevel = i_chip->getAttr<ATTR_EC>();
+
+ if( HOMER_CHIP_EXPLORER == i_chipModel )
+ {
+ //@todo - RTC:201781 - Add i2c information
+ }
+ else
+ {
+ // Get the chip FSI address.
+ FSI::FsiLinkInfo_t fsiInfo;
+ FSI::getFsiLinkInfo( i_chip, fsiInfo );
+ o_chipInfo.hChipType.fsiBaseAddr = fsiInfo.baseAddr;
+ }
}
// Returns a right justified config mask of the unit
@@ -942,20 +932,26 @@ errlHndl_t getHwConfig( std::vector<HOMER_ChipInfo_t> & o_chipInfVector,
// Iterate all of the OCMB chips.
for ( auto & ocmb : getFunctionalTargetList(TYPE_OCMB_CHIP) )
{
- // Get the chip model type.
- HOMER_ChipType_t modelType = HOMER_CHIP_INVALID;
- switch ( getChipModel(ocmb) )
+ // Get the OCMB chip type.
+ HOMER_ChipType_t ocmbType = HOMER_CHIP_INVALID;
+ switch ( getChipId(ocmb) )
{
- case MODEL_EXPLORER: modelType = HOMER_CHIP_EXPLORER; break;
+ case POWER_CHIPID::GEMINI_16:
+ // Skip Gemini OCMBs. They can exist, but PRD won't support
+ // them (set invalid).
+ ocmbType = HOMER_CHIP_INVALID; break;
+ case POWER_CHIPID::EXPLORER_16:
+ ocmbType = HOMER_CHIP_EXPLORER; break;
default:
- PRDF_ERR( FUNC "Unsupported chip model %d on 0x%08x",
- modelType, getHuid(ocmb) );
+ PRDF_ERR( FUNC "Unsupported chip ID 0x%08x on 0x%08x",
+ getChipId(ocmb), getHuid(ocmb) );
PRDF_ASSERT( false );
}
+ if ( HOMER_CHIP_INVALID == ocmbType ) continue;
// Init the chip info.
HOMER_ChipInfo_t ci;
- __initChipInfo( ocmb, modelType, MAX_OCMB_PER_NODE, ci );
+ __initChipInfo( ocmb, ocmbType, MAX_OCMB_PER_NODE, ci );
// NOTE: Explorer does not have any unit data.
diff --git a/src/usr/diag/prdf/plat/explorer/prdfExplorerPlugins.C b/src/usr/diag/prdf/plat/explorer/prdfExplorerPlugins.C
new file mode 100644
index 000000000..4a8dba1a2
--- /dev/null
+++ b/src/usr/diag/prdf/plat/explorer/prdfExplorerPlugins.C
@@ -0,0 +1,89 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/plat/explorer/prdfExplorerPlugins.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+// Framework includes
+#include <iipServiceDataCollector.h>
+#include <prdfExtensibleChip.H>
+#include <prdfPluginMap.H>
+
+// Platform includes
+#include <prdfMemDbUtils.H>
+#include <prdfMemEccAnalysis.H>
+//#include <prdfOcmbDataBundle.H>
+#include <prdfPlatServices.H>
+
+using namespace TARGETING;
+
+namespace PRDF
+{
+
+using namespace PlatServices;
+
+namespace explorer_ocmb
+{
+
+//##############################################################################
+//
+// MCBISTFIR
+//
+//##############################################################################
+
+/**
+ * @brief MCBISTFIR[10] - MCBIST Command Complete.
+ * @param i_chip An OCMB chip.
+ * @param io_sc The step code data struct.
+ * @return SUCCESS
+ */
+int32_t McbistCmdComplete( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[explorer_ocmb::McbistCmdComplete] "
+
+ return SUCCESS;
+
+ // Tell the TD controller there was a command complete attention.
+ OcmbDataBundle * db = getOcmbDataBundle( i_chip );
+ if ( SUCCESS != db->getTdCtlr()->handleCmdComplete(io_sc) )
+ {
+ // Something failed. It is possible the command complete attention has
+ // not been cleared. Make the rule code do it.
+ return SUCCESS;
+ }
+ else
+ {
+ // Everything was successful. Whether we started a new command or told
+ // MDIA to do it, the command complete bit has already been cleared.
+ // Don't do it again.
+ return PRD_NO_CLEAR_FIR_BITS;
+ }
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( explorer_ocmb, McbistCmdComplete );
+
+} // end namespace explorer_ocmb
+
+} // end namespace PRDF
+
diff --git a/src/usr/diag/prdf/plat/explorer/prdf_plat_explorer_hb_only.mk b/src/usr/diag/prdf/plat/explorer/prdf_plat_explorer_hb_only.mk
new file mode 100644
index 000000000..ee1464d3e
--- /dev/null
+++ b/src/usr/diag/prdf/plat/explorer/prdf_plat_explorer_hb_only.mk
@@ -0,0 +1,42 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/diag/prdf/plat/explorer/prdf_plat_explorer_hb_only.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+# NOTE: PRD_SRC_PATH and PRD_INC_PATH must be defined before including this file
+
+################################################################################
+# Paths common to both IPL and runtime
+################################################################################
+
+prd_vpath += ${PRD_SRC_PATH}/plat/explorer
+
+prd_incpath += ${PRD_SRC_PATH}/plat/explorer
+
+################################################################################
+# Hostboot only object files common to both IPL and runtime
+################################################################################
+
+# plat/mem/ (rule plugin related)
+prd_rule_plugin += prdfExplorerPlugins.o
+
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemDsd.H b/src/usr/diag/prdf/plat/mem/prdfMemDsd.H
index 5990a902e..063e92775 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemDsd.H
+++ b/src/usr/diag/prdf/plat/mem/prdfMemDsd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -47,7 +47,7 @@ class DsdEvent : public TdEntry
/**
* @brief Constructor
- * @param i_chip MCA or MBA.
+ * @param i_chip MCA, MBA, or OCMB.
* @param i_rank Rank reporting chip mark.
*/
DsdEvent<T>( ExtensibleChip * i_chip, const MemRank & i_rank,
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemDsd_ipl.C b/src/usr/diag/prdf/plat/mem/prdfMemDsd_ipl.C
index 70a6be7f2..9dbaeeb3c 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemDsd_ipl.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemDsd_ipl.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -30,6 +30,8 @@
#include <prdfMemDqBitmap.H>
#include <prdfMemDsd.H>
+#include <hwp_wrappers.H>
+
using namespace TARGETING;
namespace PRDF
@@ -37,18 +39,12 @@ namespace PRDF
using namespace PlatServices;
-//##############################################################################
-//
-// Specializations for MBA
-//
-//##############################################################################
-
-template<>
-uint32_t DsdEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns,
- STEP_CODE_DATA_STRUCT & io_sc,
- bool & o_done )
+template<TARGETING::TYPE T>
+uint32_t DsdEvent<T>::checkEcc( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done )
{
- #define PRDF_FUNC "[DsdEvent<TYPE_MBA>::checkEcc] "
+ #define PRDF_FUNC "[DsdEvent<T>::checkEcc] "
uint32_t o_rc = SUCCESS;
@@ -71,7 +67,7 @@ uint32_t DsdEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns,
// At this point we don't actually have an address for the UE. The
// best we can do is get the address in which the command stopped.
MemAddr addr;
- o_rc = getMemMaintAddr<TYPE_MBA>( iv_chip, addr );
+ o_rc = getMemMaintAddr<T>( iv_chip, addr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemMaintAddr(0x%08x) failed",
@@ -79,8 +75,8 @@ uint32_t DsdEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns,
break;
}
- o_rc = MemEcc::handleMemUe<TYPE_MBA>( iv_chip, addr,
- UE_TABLE::SCRUB_UE, io_sc );
+ o_rc = MemEcc::handleMemUe<T>( iv_chip, addr,
+ UE_TABLE::SCRUB_UE, io_sc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "handleMemUe(0x%08x,0x%02x) failed",
@@ -101,12 +97,12 @@ uint32_t DsdEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns,
//------------------------------------------------------------------------------
-template<>
-uint32_t DsdEvent<TYPE_MBA>::verifySpare( const uint32_t & i_eccAttns,
- STEP_CODE_DATA_STRUCT & io_sc,
- bool & o_done )
+template<TARGETING::TYPE T>
+uint32_t DsdEvent<T>::verifySpare( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done )
{
- #define PRDF_FUNC "[DsdEvent<TYPE_MBA>::verifySpare] "
+ #define PRDF_FUNC "[DsdEvent<T>::verifySpare] "
uint32_t o_rc = SUCCESS;
@@ -166,7 +162,7 @@ uint32_t DsdEvent<TYPE_MBA>::verifySpare( const uint32_t & i_eccAttns,
PRDFSIG_DsdDramSpared );
// Remove the chip mark.
- o_rc = MarkStore::clearChipMark<TYPE_MBA>( iv_chip, iv_rank );
+ o_rc = MarkStore::clearChipMark<T>( iv_chip, iv_rank );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "clearChipMark(0x%08x,0x%02x) failed",
@@ -190,7 +186,7 @@ uint32_t DsdEvent<TYPE_MBA>::verifySpare( const uint32_t & i_eccAttns,
template<>
uint32_t DsdEvent<TYPE_MBA>::startCmd()
{
- #define PRDF_FUNC "[DsdEvent::startCmd] "
+ #define PRDF_FUNC "[DsdEvent<TYPE_MBA>::startCmd] "
uint32_t o_rc = SUCCESS;
@@ -231,7 +227,54 @@ uint32_t DsdEvent<TYPE_MBA>::startCmd()
//------------------------------------------------------------------------------
template<>
-uint32_t DsdEvent<TYPE_MBA>::startNextPhase( STEP_CODE_DATA_STRUCT & io_sc )
+uint32_t DsdEvent<TYPE_OCMB_CHIP>::startCmd()
+{
+ #define PRDF_FUNC "[DsdEvent<TYPE_OCMB_CHIP>::startCmd] "
+
+ uint32_t o_rc = SUCCESS;
+
+ #ifdef CONFIG_AXONE
+
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER> stopCond;
+
+ switch ( iv_phase )
+ {
+ case TD_PHASE_1:
+ // Start the steer cleanup procedure on this master rank.
+ o_rc = startTdSteerCleanup<TYPE_OCMB_CHIP>( iv_chip, iv_rank,
+ MASTER_RANK, stopCond );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "startTdSteerCleanup(0x%08x,0x%2x) failed",
+ iv_chip->getHuid(), getKey() );
+ }
+ break;
+
+ case TD_PHASE_2:
+ // Start the superfast read procedure on this master rank.
+ o_rc = startTdSfRead<TYPE_OCMB_CHIP>( iv_chip, iv_rank, MASTER_RANK,
+ stopCond );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "startTdSfRead(0x%08x,0x%2x) failed",
+ iv_chip->getHuid(), getKey() );
+ }
+ break;
+
+ default: PRDF_ASSERT( false ); // invalid phase
+ }
+
+ #endif
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<TARGETING::TYPE T>
+uint32_t DsdEvent<T>::startNextPhase( STEP_CODE_DATA_STRUCT & io_sc )
{
uint32_t signature = 0;
@@ -260,5 +303,9 @@ uint32_t DsdEvent<TYPE_MBA>::startNextPhase( STEP_CODE_DATA_STRUCT & io_sc )
//------------------------------------------------------------------------------
+// Avoid linker errors with the template.
+template class DsdEvent<TYPE_MBA>;
+template class DsdEvent<TYPE_OCMB_CHIP>;
+
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemDsd_rt.C b/src/usr/diag/prdf/plat/mem/prdfMemDsd_rt.C
index 42b7eb9fc..1478a666d 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemDsd_rt.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemDsd_rt.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -29,6 +29,8 @@
#include <prdfCenMbaExtraSig.H>
#include <prdfMemDsd.H>
+#include <hwp_wrappers.H>
+
using namespace TARGETING;
namespace PRDF
@@ -36,18 +38,12 @@ namespace PRDF
using namespace PlatServices;
-//##############################################################################
-//
-// Specializations for MBA
-//
-//##############################################################################
-
-template<>
-uint32_t DsdEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns,
- STEP_CODE_DATA_STRUCT & io_sc,
- bool & o_done )
+template<TARGETING::TYPE T>
+uint32_t DsdEvent<T>::checkEcc( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done )
{
- #define PRDF_FUNC "[DsdEvent<TYPE_MBA>::checkEcc] "
+ #define PRDF_FUNC "[DsdEvent<T>::checkEcc] "
uint32_t o_rc = SUCCESS;
@@ -64,7 +60,7 @@ uint32_t DsdEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns,
// At this point we don't actually have an address for the UE. The
// best we can do is get the address in which the command stopped.
MemAddr addr;
- o_rc = getMemMaintAddr<TYPE_MBA>( iv_chip, addr );
+ o_rc = getMemMaintAddr<T>( iv_chip, addr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemMaintAddr(0x%08x) failed",
@@ -72,8 +68,8 @@ uint32_t DsdEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns,
break;
}
- o_rc = MemEcc::handleMemUe<TYPE_MBA>( iv_chip, addr,
- UE_TABLE::SCRUB_UE, io_sc );
+ o_rc = MemEcc::handleMemUe<T>( iv_chip, addr,
+ UE_TABLE::SCRUB_UE, io_sc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "handleMemUe(0x%08x,0x%02x) failed",
@@ -83,7 +79,7 @@ uint32_t DsdEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns,
// Because of the UE, any further TPS requests will likely have no
// effect. So ban all subsequent requests.
- MemDbUtils::banTps<TYPE_MBA>( iv_chip, addr.getRank() );
+ MemDbUtils::banTps<T>( iv_chip, addr.getRank() );
// Leave the mark in place and abort this procedure.
o_done = true; break;
@@ -114,12 +110,12 @@ uint32_t DsdEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns,
//------------------------------------------------------------------------------
-template<>
-uint32_t DsdEvent<TYPE_MBA>::verifySpare( const uint32_t & i_eccAttns,
- STEP_CODE_DATA_STRUCT & io_sc,
- bool & o_done )
+template<TARGETING::TYPE T>
+uint32_t DsdEvent<T>::verifySpare( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done )
{
- #define PRDF_FUNC "[DsdEvent<TYPE_MBA>::verifySpare] "
+ #define PRDF_FUNC "[DsdEvent<T>::verifySpare] "
uint32_t o_rc = SUCCESS;
@@ -134,7 +130,7 @@ uint32_t DsdEvent<TYPE_MBA>::verifySpare( const uint32_t & i_eccAttns,
// error (i.e. a UE).
bool lastAddr = false;
- o_rc = didCmdStopOnLastAddr<TYPE_MBA>( iv_chip, MASTER_RANK, lastAddr );
+ o_rc = didCmdStopOnLastAddr<T>( iv_chip, MASTER_RANK, lastAddr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "didCmdStopOnLastAddr(0x%08x) failed",
@@ -155,7 +151,7 @@ uint32_t DsdEvent<TYPE_MBA>::verifySpare( const uint32_t & i_eccAttns,
io_sc.service_data->setSignature( iv_chip->getHuid(),
PRDFSIG_DsdDramSpared );
// Remove the chip mark.
- o_rc = MarkStore::clearChipMark<TYPE_MBA>( iv_chip, iv_rank );
+ o_rc = MarkStore::clearChipMark<T>( iv_chip, iv_rank );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "clearChipMark(0x%08x,0x%02x) failed",
@@ -179,7 +175,7 @@ uint32_t DsdEvent<TYPE_MBA>::verifySpare( const uint32_t & i_eccAttns,
template<>
uint32_t DsdEvent<TYPE_MBA>::startCmd()
{
- #define PRDF_FUNC "[DsdEvent::startCmd] "
+ #define PRDF_FUNC "[DsdEvent<TYPE_MBA>::startCmd] "
uint32_t o_rc = SUCCESS;
@@ -224,7 +220,38 @@ uint32_t DsdEvent<TYPE_MBA>::startCmd()
//------------------------------------------------------------------------------
template<>
-uint32_t DsdEvent<TYPE_MBA>::startNextPhase( STEP_CODE_DATA_STRUCT & io_sc )
+uint32_t DsdEvent<TYPE_OCMB_CHIP>::startCmd()
+{
+ #define PRDF_FUNC "[DsdEvent<TYPE_OCMB_CHIP>::startCmd] "
+
+ uint32_t o_rc = SUCCESS;
+
+ #ifdef CONFIG_AXONE
+
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER> stopCond;
+
+ stopCond.set_pause_on_ue(mss::ON);
+
+ // Start the time based scrub procedure on this master rank.
+ o_rc = startTdScrub<TYPE_OCMB_CHIP>( iv_chip, iv_rank, MASTER_RANK,
+ stopCond );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "startTdScrub(0x%08x,0x%2x) failed",
+ iv_chip->getHuid(), getKey() );
+ }
+
+ #endif
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<TARGETING::TYPE T>
+uint32_t DsdEvent<T>::startNextPhase( STEP_CODE_DATA_STRUCT & io_sc )
{
uint32_t signature = 0;
@@ -258,5 +285,9 @@ uint32_t DsdEvent<TYPE_MBA>::startNextPhase( STEP_CODE_DATA_STRUCT & io_sc )
//------------------------------------------------------------------------------
+// Avoid linker errors with the template.
+template class DsdEvent<TYPE_MBA>;
+template class DsdEvent<TYPE_OCMB_CHIP>;
+
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C b/src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C
index 41b0de3ea..40653ee09 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -64,7 +64,7 @@ bool isEnabled()
!isMfgAvpEnabled() && !isMfgHdatAvpEnabled() );
}
-int32_t __getAddrConfig( ExtensibleChip * i_mcaChip, uint8_t i_dslct,
+int32_t __getAddrConfig( ExtensibleChip * i_chip, uint8_t i_dslct,
bool & o_twoDimmConfig, uint8_t & o_mrnkBits,
uint8_t & o_srnkBits, uint8_t & o_extraRowBits )
{
@@ -72,12 +72,12 @@ int32_t __getAddrConfig( ExtensibleChip * i_mcaChip, uint8_t i_dslct,
int32_t o_rc = SUCCESS;
- SCAN_COMM_REGISTER_CLASS * reg = i_mcaChip->getRegister( "MC_ADDR_TRANS" );
+ SCAN_COMM_REGISTER_CLASS * reg = i_chip->getRegister( "MC_ADDR_TRANS" );
o_rc = reg->Read();
if ( SUCCESS != o_rc )
{
- PRDF_ERR( PRDF_FUNC "Read failed on MC_ADDR_TRANS: i_mcaChip=0x%08x",
- i_mcaChip->getHuid() );
+ PRDF_ERR( PRDF_FUNC "Read failed on MC_ADDR_TRANS: i_chip=0x%08x",
+ i_chip->getHuid() );
return o_rc;
}
@@ -98,8 +98,8 @@ int32_t __getAddrConfig( ExtensibleChip * i_mcaChip, uint8_t i_dslct,
// for some reason B2 is valid, there is definitely a bug.
if ( reg->IsBitSet(i_dslct ? 28:12) )
{
- PRDF_ERR( PRDF_FUNC "B2 enabled in MC_ADDR_TRANS: i_mcaChip=0x%08x "
- "i_dslct=%d", i_mcaChip->getHuid(), i_dslct );
+ PRDF_ERR( PRDF_FUNC "B2 enabled in MC_ADDR_TRANS: i_chip=0x%08x "
+ "i_dslct=%d", i_chip->getHuid(), i_dslct );
return FAIL;
}
@@ -386,7 +386,7 @@ int32_t __getPortAddr<TYPE_MCA>( ExtensibleChip * i_chip, MemAddr i_addr,
// Local vars for address fields
uint64_t col = reverseBits(i_addr.getCol(), 7); // C9 C8 C7 C6 C5 C4 C3
uint64_t row = reverseBits(i_addr.getRow(), 18); // R17 R16 R15 .. R1 R0
- uint64_t bnk = i_addr.getBank(); // BG0 BG1 B0 B1 B2
+ uint64_t bnk = i_addr.getBank(); // B0 B1 B2 BG0 BG1
uint64_t srnk = i_addr.getRank().getSlave(); // S0 S1 S2
uint64_t mrnk = i_addr.getRank().getRankSlct(); // M0 M1
uint64_t dslct = i_addr.getRank().getDimmSlct(); // D
@@ -473,6 +473,266 @@ int32_t __getPortAddr<TYPE_MCA>( ExtensibleChip * i_chip, MemAddr i_addr,
return o_rc;
}
+void __adjustCapiAddrBitPos( uint8_t & io_bitPos )
+{
+ // Note: the translation bitmaps are all 5 bits that are defined
+ // consistently as:
+ // 00000 = CAPI_Address(5)
+ // 00001 = CAPI_Address(6)
+ // 00010 = CAPI_Address(7)
+ // ...
+ // 01010 = CAPI_Address(15)
+ // 01011 = CAPI_Address(31)
+ // 01100 = CAPI_Address(32)
+ // ...
+ // 10011 = CAPI_Address(39)
+ // So the value from the regs can be converted to the CAPI address bit pos
+ // by adding 5 if the value is less than or equal to 10, or by adding 20
+ // if it is above 10.
+
+ if ( io_bitPos <= 10 )
+ {
+ io_bitPos += 5;
+ }
+ else
+ {
+ io_bitPos += 20;
+ }
+}
+
+template <>
+int32_t __getPortAddr<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip, MemAddr i_addr,
+ uint64_t & o_addr )
+{
+ #define PRDF_FUNC "[MemDealloc::__getPortAddr<TYPE_OCMB_CHIP>] "
+
+ int32_t o_rc = SUCCESS;
+
+ o_addr = 0;
+
+ // Local vars for address fields
+ uint64_t col = reverseBits(i_addr.getCol(), 7); // C9 C8 C7 C6 C5 C4 C3
+ uint64_t row = reverseBits(i_addr.getRow(), 18); // R17 R16 R15 .. R1 R0
+ uint64_t bnk = i_addr.getBank(); // B0 B1 B2 BG0 BG1
+ uint64_t srnk = i_addr.getRank().getSlave(); // S0 S1 S2
+ uint64_t mrnk = i_addr.getRank().getRankSlct(); // M0 M1
+ uint64_t dslct = i_addr.getRank().getDimmSlct(); // D
+
+ // Determine if a two DIMM config is used. Also, determine how many
+ // mrank (M0-M1), srnk (S0-S2), or extra row (R17-R15) bits are used.
+ bool twoDimmConfig;
+ uint8_t mrnkBits, srnkBits, extraRowBits;
+ o_rc = __getAddrConfig( i_chip, dslct, twoDimmConfig, mrnkBits, srnkBits,
+ extraRowBits );
+ if ( SUCCESS != o_rc ) return o_rc;
+
+ // Mask off the non-configured bits. If this address came from hardware,
+ // this would not be a problem. However, the get_mrank_range() and
+ // get_srank_range() HWPS got lazy just set the entire fields and did not
+ // take into account the actual bit ranges.
+ mrnk = __maskBits( mrnk, mrnkBits );
+ srnk = __maskBits( srnk, srnkBits );
+ row = __maskBits( row, 15 + extraRowBits );
+
+ // Insert the needed bits based on the config defined in the MC Address
+ // Translation Registers.
+
+ uint8_t bitPos = 0;
+
+ // Split the row into its components.
+ uint8_t r17 = (row & 0x20000) >> 17;
+ uint8_t r16 = (row & 0x10000) >> 16;
+ uint8_t r15 = (row & 0x08000) >> 15;
+ uint16_t r14_r0 = (row & 0x07fff);
+
+ // Split the master rank and slave rank into their components
+ uint8_t m0 = (mrnk & 0x2) >> 1;
+ uint8_t m1 = (mrnk & 0x1);
+
+ uint8_t s0 = (srnk & 0x4) >> 2;
+ uint8_t s1 = (srnk & 0x2) >> 1;
+ uint8_t s2 = (srnk & 0x1);
+
+ // Split the column into its components
+ uint8_t c9 = (col & 0x40) >> 6;
+ uint8_t c8 = (col & 0x20) >> 5;
+ uint8_t c7 = (col & 0x10) >> 4;
+ uint8_t c6 = (col & 0x08) >> 3;
+ uint8_t c5 = (col & 0x04) >> 2;
+ uint8_t c4 = (col & 0x02) >> 1;
+ uint8_t c3 = (col & 0x01);
+
+ // Split the bank and bank group into their components
+ // Note: B2 is not used for OCMB
+ uint8_t b0 = (bnk & 0x10) >> 4;
+ uint8_t b1 = (bnk & 0x08) >> 3;
+
+ uint8_t bg0 = (bnk & 0x2) >> 1;
+ uint8_t bg1 = (bnk & 0x1);
+
+ // Row bits 14:0 are always at CAPI addr position 30:16
+ o_addr |= (r14_r0 << 16);
+
+ // Check MC_ADDR_TRANS0 register for bit positions
+ SCAN_COMM_REGISTER_CLASS * reg = i_chip->getRegister( "MC_ADDR_TRANS" );
+ o_rc = reg->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read failed on MC_ADDR_TRANS: i_chip=0x%08x",
+ i_chip->getHuid() );
+ return o_rc;
+ }
+
+ // If the DIMM select is valid, insert that bit
+ if ( twoDimmConfig )
+ {
+ // DIMM bitmap: MC_ADDR_TRANS0[33:37]
+ bitPos = reg->GetBitFieldJustified( 33, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (dslct << bitPos);
+ }
+
+ // Insert any of the master rank bits that are valid
+ switch( mrnkBits )
+ {
+ case 2:
+ // Master rank 0 bitmap: MC_ADDR_TRANS0[38:42]
+ bitPos = reg->GetBitFieldJustified( 38, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (m0 << bitPos);
+ case 1:
+ // Master rank 1 bitmap: MC_ADDR_TRANS0[43:47]
+ bitPos = reg->GetBitFieldJustified( 43, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (m1 << bitPos);
+ break;
+ }
+
+ // Insert any extra row bits (17:15) that are valid
+ switch ( extraRowBits )
+ {
+ case 3:
+ // Row 17 bitmap: MC_ADDR_TRANS0[49:53]
+ bitPos = reg->GetBitFieldJustified( 49, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (r17 << bitPos);
+ case 2:
+ // Row 16 bitmap: MC_ADDR_TRANS0[54:58]
+ bitPos = reg->GetBitFieldJustified( 54, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (r16 << bitPos);
+ case 1:
+ // Row 15 bitmap: MC_ADDR_TRANS0[59:63]
+ bitPos = reg->GetBitFieldJustified( 59, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (r15 << bitPos);
+ break;
+ }
+
+ // Check MC_ADDR_TRANS1 register for bit positions
+ reg = i_chip->getRegister( "MC_ADDR_TRANS1" );
+ o_rc = reg->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read failed on MC_ADDR_TRANS1: i_chip=0x%08x",
+ i_chip->getHuid() );
+ return o_rc;
+ }
+
+ // Insert any of the slave rank bits that are valid
+ switch ( srnkBits )
+ {
+ case 3:
+ // Slave rank 0 bitmap: MC_ADDR_TRANS1[3:7]
+ bitPos = reg->GetBitFieldJustified( 3, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (s0 << bitPos);
+ case 2:
+ // Slave rank 1 bitmap: MC_ADDR_TRANS1[11:15]
+ bitPos = reg->GetBitFieldJustified( 11, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (s1 << bitPos);
+ case 1:
+ // Slave rank 2 bitmap: MC_ADDR_TRANS1[19:23]
+ bitPos = reg->GetBitFieldJustified( 19, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (s2 << bitPos);
+ break;
+ }
+
+ // Column 3 bitmap: MC_ADDR_TRANS1[30:34]
+ bitPos = reg->GetBitFieldJustified( 30, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (c3 << bitPos);
+
+ // Column 4 bitmap: MC_ADDR_TRANS1[35:39]
+ bitPos = reg->GetBitFieldJustified( 35, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (c4 << bitPos);
+
+ // Column 5 bitmap: MC_ADDR_TRANS1[43:47]
+ bitPos = reg->GetBitFieldJustified( 43, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (c5 << bitPos);
+
+ // Column 6 bitmap: MC_ADDR_TRANS1[51:55]
+ bitPos = reg->GetBitFieldJustified( 51, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (c6 << bitPos);
+
+ // Column 7 bitmap: MC_ADDR_TRANS1[59:63]
+ bitPos = reg->GetBitFieldJustified( 59, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (c7 << bitPos);
+
+ // Check MC_ADDR_TRANS2 register for bit positions
+ reg = i_chip->getRegister( "MC_ADDR_TRANS2" );
+ o_rc = reg->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read failed on MC_ADDR_TRANS2: i_chip=0x%08x",
+ i_chip->getHuid() );
+ return o_rc;
+ }
+
+ // Column 8 bitmap: MC_ADDR_TRANS2[3:7]
+ bitPos = reg->GetBitFieldJustified( 3, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (c8 << bitPos);
+
+ // Column 9 bitmap: MC_ADDR_TRANS2[11:15]
+ bitPos = reg->GetBitFieldJustified( 11, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (c9 << bitPos);
+
+ // Bank 0 bitmap: MC_ADDR_TRANS2[19:23]
+ bitPos = reg->GetBitFieldJustified( 19, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (b0 << bitPos );
+
+ // Bank 1 bitmap: MC_ADDR_TRANS2[27:31]
+ bitPos = reg->GetBitFieldJustified( 27, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (b1 << bitPos);
+
+ // Bank 2 bitmap: MC_ADDR_TRANS2[35:39]
+ // Note: Bank2 not used for OCMB
+
+ // Bank group 0 bitmap: MC_ADDR_TRANS2[43:47]
+ bitPos = reg->GetBitFieldJustified( 43, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (bg0 << bitPos);
+
+ // Bank group 1 bitmap: MC_ADDR_TRANS2[51:55]
+ bitPos = reg->GetBitFieldJustified( 51, 5 );
+ __adjustCapiAddrBitPos( bitPos );
+ o_addr |= (bg1 << bitPos);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
template <>
int32_t __getPortAddr<TYPE_MBA>( ExtensibleChip * i_chip, MemAddr i_addr,
uint64_t & o_addr )
@@ -566,12 +826,12 @@ int32_t __getPortAddr<TYPE_MBA>( ExtensibleChip * i_chip, MemAddr i_addr,
//------------------------------------------------------------------------------
template<TYPE T>
-void __getGrpPrms( ExtensibleChip * i_chip, uint8_t o_portPos,
+void __getGrpPrms( ExtensibleChip * i_chip, uint8_t & o_portPos,
SCAN_COMM_REGISTER_CLASS * &o_mcfgp,
SCAN_COMM_REGISTER_CLASS * &o_mcfgpm );
template<>
-void __getGrpPrms<TYPE_MCA>( ExtensibleChip * i_chip, uint8_t o_portPos,
+void __getGrpPrms<TYPE_MCA>( ExtensibleChip * i_chip, uint8_t & o_portPos,
SCAN_COMM_REGISTER_CLASS * &o_mcfgp,
SCAN_COMM_REGISTER_CLASS * &o_mcfgpm )
{
@@ -585,7 +845,33 @@ void __getGrpPrms<TYPE_MCA>( ExtensibleChip * i_chip, uint8_t o_portPos,
}
template<>
-void __getGrpPrms<TYPE_MBA>( ExtensibleChip * i_chip, uint8_t o_portPos,
+void __getGrpPrms<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip, uint8_t & o_portPos,
+ SCAN_COMM_REGISTER_CLASS * &o_mcfgp,
+ SCAN_COMM_REGISTER_CLASS * &o_mcfgpm )
+{
+ // Get the connected parent MI;
+ ExtensibleChip * mcc = getConnectedParent( i_chip, TYPE_MCC );
+ ExtensibleChip * mi = getConnectedParent( mcc, TYPE_MI );
+
+ // TODO RTC 210072 - support for multiple ports
+ o_portPos = 0;
+
+ // Get the position of the MCC relative to the MI (0:1)
+ uint8_t chnlPos = mcc->getPos() % MAX_MCC_PER_MI;
+
+ char mcfgpName[64];
+ sprintf( mcfgpName, "MCFGP%d", chnlPos );
+
+ char mcfgpmName[64];
+ sprintf( mcfgpmName, "MCFGPM%d", chnlPos );
+
+ o_mcfgp = mi->getRegister( mcfgpName );
+ o_mcfgpm = mi->getRegister( mcfgpmName );
+
+}
+
+template<>
+void __getGrpPrms<TYPE_MBA>( ExtensibleChip * i_chip, uint8_t & o_portPos,
SCAN_COMM_REGISTER_CLASS * &o_mcfgp,
SCAN_COMM_REGISTER_CLASS * &o_mcfgpm )
{
@@ -686,12 +972,67 @@ uint32_t __getGrpInfo( ExtensibleChip * i_chip, uint64_t & o_grpChnls,
#undef PRDF_FUNC
}
+template<>
+uint32_t __getGrpInfo<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ uint64_t & o_grpChnls,
+ uint64_t & o_grpId, uint64_t & o_grpSize,
+ uint64_t & o_grpBar )
+{
+ #define PRDF_FUNC "[MemDealloc::__getGrpInfo] "
+
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ // Get portPos and MCFGP/M registers
+ uint8_t portPos = 0xFF;
+ SCAN_COMM_REGISTER_CLASS * mcfgp = nullptr;
+ SCAN_COMM_REGISTER_CLASS * mcfgpm = nullptr;
+ __getGrpPrms<TYPE_OCMB_CHIP>( i_chip, portPos, mcfgp, mcfgpm );
+
+ o_rc = mcfgp->Read(); if ( SUCCESS != o_rc ) break;
+
+ // Get the number of channels in this group: MCFGP[40:42]
+ uint8_t mcGrpCnfg = mcfgp->GetBitFieldJustified( 40, 3 );
+ switch ( mcGrpCnfg )
+ {
+ case 0: o_grpChnls = 8; break; // 8MCS
+ case 1: o_grpChnls = 1; break; // 1MCS
+ case 2: o_grpChnls = 2; break; // 2MCS
+ case 3: o_grpChnls = 3; break; // 3MCS
+ case 4: o_grpChnls = 4; break; // 4MCS
+ case 5: o_grpChnls = 6; break; // 6MCS
+ default:
+ PRDF_ERR( PRDF_FUNC "Invalid MC channels per group value: 0x%x "
+ "on 0x%08x", mcGrpCnfg, i_chip->getHuid() );
+ o_rc = FAIL;
+ }
+ if ( SUCCESS != o_rc ) break;
+
+ // Get the group ID and group size.
+ o_grpId = mcfgp->GetBitFieldJustified( 43, 3 ); // MCFGP[43:45]
+ o_grpSize = mcfgp->GetBitFieldJustified( 25, 15 ); // MCFGP[25:39]
+
+ // TODO RTC 210072 - support for multiple ports, see generic handling
+
+ // Get the base address (BAR).
+ // Channel 0 is always from the MCFGP.
+ o_grpBar = mcfgp->GetBitFieldJustified(1, 24); // MCFGP[1:24]
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
//------------------------------------------------------------------------------
-uint32_t __insertGrpId( uint64_t & io_addr, uint64_t i_grpChnls,
- uint64_t i_grpId )
+template <TYPE T>
+uint32_t __insertGrpId( ExtensibleChip * i_chip, uint64_t & io_addr,
+ uint64_t i_grpChnls, uint64_t i_grpId )
{
- #define PRDF_FUNC "[MemDealloc::__insertGrpId] "
+ #define PRDF_FUNC "[MemDealloc::__insertGrpId<T>] "
uint32_t o_rc = SUCCESS;
@@ -742,6 +1083,108 @@ uint32_t __insertGrpId( uint64_t & io_addr, uint64_t i_grpChnls,
#undef PRDF_FUNC
}
+template<>
+uint32_t __insertGrpId<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ uint64_t & io_addr, uint64_t i_grpChnls,
+ uint64_t i_grpId )
+{
+ #define PRDF_FUNC "[MemDealloc::__insertGrpId<TYPE_OCMB_CHIP>] "
+
+ uint32_t o_rc = SUCCESS;
+
+ uint64_t upper33 = io_addr & 0xFFFFFFFF80ull;
+ uint64_t lower7 = io_addr & 0x000000007full;
+
+ bool subChanAEnable = false;
+ bool subChanBEnable = false;
+ bool bothSubChansEnabled = false;
+
+ ExtensibleChip * mcc = getConnectedParent( i_chip, TYPE_MCC );
+
+ // Check both subchannels whether we can get the connected OCMB to
+ // determine whether they are enabled.
+ // Check for subchannel A
+ ExtensibleChip * subchanA = getConnectedChild( mcc, TYPE_OCMB_CHIP, 0 );
+ if ( nullptr != subchanA ) subChanAEnable = true;
+
+ // Check for subchannel B
+ ExtensibleChip * subchanB = getConnectedChild( mcc, TYPE_OCMB_CHIP, 1 );
+ if ( nullptr != subchanB ) subChanBEnable = true;
+
+ // Check if both subchannels were enabled
+ if ( subChanAEnable && subChanBEnable ) bothSubChansEnabled = true;
+
+ // If both subchannels are enabled, bit 56 of the address will contain the
+ // subchannel select bit.
+ if ( bothSubChansEnabled )
+ {
+ uint8_t ocmbChnl = i_chip->getPos() % MAX_OCMB_PER_MCC; // 0:1
+ uint8_t bitInsert = 0;
+
+ switch ( i_grpChnls )
+ {
+ case 1: // insert 1 bit for subchannel select
+ case 3:
+ case 6:
+ bitInsert = ( ocmbChnl & 0x1 );
+ io_addr = (upper33 << 1) | (bitInsert << 7) | lower7;
+ break;
+
+ case 2: // insert 1 bit for subchannel select and 1 bit for grpId
+ bitInsert = ( ((i_grpId & 0x1) << 1) | (ocmbChnl & 0x1) );
+ io_addr = (upper33 << 2) | (bitInsert << 7) | lower7;
+ break;
+
+ case 4: // insert 1 bit for subchannel select and 2 bits for grpId
+ bitInsert = ( ((i_grpId & 0x3) << 1) | (ocmbChnl & 0x1) );
+ io_addr = (upper33 << 3) | (bitInsert << 7) | lower7;
+ break;
+
+ case 8: // insert 1 bit for subchannel select and 3 bits for grpId
+ bitInsert = ( ((i_grpId & 0x7) << 1) | (ocmbChnl & 0x1) );
+ io_addr = (upper33 << 4) | (bitInsert << 7) | lower7;
+ break;
+
+ default:
+ PRDF_ERR( PRDF_FUNC "Invalid MC channels per group value %d",
+ i_grpChnls );
+ o_rc = FAIL;
+ }
+ }
+ else
+ {
+ switch ( i_grpChnls )
+ {
+ case 1: // no shifting
+ case 3:
+ case 6:
+ break;
+
+ case 2: // insert 1 bit
+ io_addr = (upper33 << 1) | ((i_grpId & 0x1) << 7) | lower7;
+ break;
+
+ case 4: // insert 2 bits
+ io_addr = (upper33 << 2) | ((i_grpId & 0x3) << 7) | lower7;
+ break;
+
+ case 8: // insert 3 bits
+ io_addr = (upper33 << 3) | ((i_grpId & 0x7) << 7) | lower7;
+ break;
+
+ default:
+ PRDF_ERR( PRDF_FUNC "Invalid MC channels per group value %d",
+ i_grpChnls );
+ o_rc = FAIL;
+ }
+ }
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+
+}
+
//------------------------------------------------------------------------------
// The hardware uses a mod3 hashing algorithm to calculate which memory channel
@@ -849,7 +1292,7 @@ void __addBar( uint64_t & io_addr, uint64_t i_grpBar )
template<TYPE T>
uint32_t getSystemAddr( ExtensibleChip * i_chip, MemAddr i_addr,
- uint64_t & o_addr )
+ uint64_t & o_addr )
{
#define PRDF_FUNC "[MemDealloc::getSystemAddr] "
@@ -867,7 +1310,7 @@ uint32_t getSystemAddr( ExtensibleChip * i_chip, MemAddr i_addr,
if ( SUCCESS != o_rc ) break;
// Insert the group ID.
- o_rc = __insertGrpId( o_addr, grpChnls, grpId );
+ o_rc = __insertGrpId<T>( i_chip, o_addr, grpChnls, grpId );
if ( SUCCESS != o_rc ) break;
// Notes on 3 and 6 channel per group configs:
@@ -915,8 +1358,8 @@ uint32_t getSystemAddrRange( ExtensibleChip * i_chip,
if ( SUCCESS != o_rc ) break;
// Insert the group ID.
- o_rc = __insertGrpId( o_saddr, grpChnls, grpId );
- o_rc |= __insertGrpId( o_eaddr, grpChnls, grpId );
+ o_rc = __insertGrpId<T>( i_chip, o_saddr, grpChnls, grpId );
+ o_rc |= __insertGrpId<T>( i_chip, o_eaddr, grpChnls, grpId );
if ( SUCCESS != o_rc ) break;
// Notes on 3 and 6 channel per group configs:
@@ -975,6 +1418,7 @@ int32_t page( ExtensibleChip * i_chip, MemAddr i_addr )
}
template int32_t page<TYPE_MCA>( ExtensibleChip * i_chip, MemAddr i_addr );
template int32_t page<TYPE_MBA>( ExtensibleChip * i_chip, MemAddr i_addr );
+template int32_t page<TYPE_OCMB_CHIP>(ExtensibleChip * i_chip, MemAddr i_addr);
//------------------------------------------------------------------------------
@@ -1025,6 +1469,7 @@ int32_t rank( ExtensibleChip * i_chip, MemRank i_rank )
}
template int32_t rank<TYPE_MCA>( ExtensibleChip * i_chip, MemRank i_rank );
template int32_t rank<TYPE_MBA>( ExtensibleChip * i_chip, MemRank i_rank );
+template int32_t rank<TYPE_OCMB_CHIP>(ExtensibleChip * i_chip, MemRank i_rank);
//------------------------------------------------------------------------------
@@ -1074,6 +1519,7 @@ int32_t port( ExtensibleChip * i_chip )
}
template int32_t port<TYPE_MCA>( ExtensibleChip * i_chip );
template int32_t port<TYPE_MBA>( ExtensibleChip * i_chip );
+template int32_t port<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip );
//------------------------------------------------------------------------------
@@ -1236,6 +1682,22 @@ int32_t dimmList( TargetHandleList & i_dimmList )
sendPredDeallocRequest( ssAddr, seAddr );
PRDF_TRAC( PRDF_FUNC "Predictive dealloc for start addr: 0x%016llx "
"end addr: 0x%016llx", ssAddr, seAddr );
+
+ #ifdef CONFIG_NVDIMM
+ // If the DIMM is an NVDIMM, send a message to PHYP that a save/restore
+ // may work.
+ if ( isNVDIMM(*it) )
+ {
+ uint32_t l_rc = PlatServices::nvdimmNotifyProtChange( *it,
+ NVDIMM::NVDIMM_RISKY_HW_ERROR );
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_TRAC( PRDF_FUNC "nvdimmNotifyProtChange(0x%08x) "
+ "failed.", getHuid(*it) );
+ continue;
+ }
+ }
+ #endif
}
return o_rc;
@@ -1278,6 +1740,14 @@ int32_t dimmList( TargetHandleList & i_dimmList )
break;
}
+ // Third, check for OCMBs.
+ list = getConnected( dimmTrgt, TYPE_OCMB_CHIP );
+ if ( !list.empty() )
+ {
+ o_rc = dimmList<TYPE_OCMB_CHIP>( i_dimmList );
+ break;
+ }
+
// If we get here we did not find a supported target.
PRDF_ERR( PRDF_FUNC "Unsupported connected parent to dimm 0x%08x",
getHuid(dimmTrgt) );
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemIplCeStats.C b/src/usr/diag/prdf/plat/mem/prdfMemIplCeStats.C
index 869aa92e8..b257d0874 100755
--- a/src/usr/diag/prdf/plat/mem/prdfMemIplCeStats.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemIplCeStats.C
@@ -83,8 +83,8 @@ void MemIplCeStats<TYPE_MCA>::banAnalysis( uint8_t i_dimmSlct,
//------------------------------------------------------------------------------
template<>
-void MemIplCeStats<TYPE_MEM_PORT>::banAnalysis( uint8_t i_dimmSlct,
- uint8_t i_portSlct )
+void MemIplCeStats<TYPE_OCMB_CHIP>::banAnalysis( uint8_t i_dimmSlct,
+ uint8_t i_portSlct )
{
PRDF_ASSERT( i_dimmSlct < MAX_DIMM_PER_PORT );
PRDF_ASSERT( 0 == i_portSlct );
@@ -117,9 +117,9 @@ void MemIplCeStats<TYPE_MCA>::banAnalysis( uint8_t i_dimmSlct )
//------------------------------------------------------------------------------
template<>
-void MemIplCeStats<TYPE_MEM_PORT>::banAnalysis( uint8_t i_dimmSlct )
+void MemIplCeStats<TYPE_OCMB_CHIP>::banAnalysis( uint8_t i_dimmSlct )
{
- // Only one DIMM per DIMM select on MEM_PORT.
+ // Only one DIMM per DIMM select on OCMB_CHIP.
banAnalysis( i_dimmSlct, 0 );
}
@@ -481,6 +481,6 @@ void MemIplCeStats<T>::addMruAndCommitErrl( const MemoryMru & i_memmru,
// need these templates to avoid linker errors
template class MemIplCeStats<TYPE_MCA>;
template class MemIplCeStats<TYPE_MBA>;
-template class MemIplCeStats<TYPE_MEM_PORT>;
+template class MemIplCeStats<TYPE_OCMB_CHIP>;
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C b/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C
index 5351b842a..bececfa21 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -106,17 +106,6 @@ uint32_t clearCmdCompleteAttn<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
}
template<>
-uint32_t clearCmdCompleteAttn<TYPE_MEM_PORT>( ExtensibleChip * i_chip )
-{
- PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
-
- ExtensibleChip * ocmbChip = getConnectedParent( i_chip, TYPE_OCMB_CHIP );
-
- return clearCmdCompleteAttn<TYPE_OCMB_CHIP>( ocmbChip );
-}
-
-template<>
uint32_t clearCmdCompleteAttn<TYPE_MBA>( ExtensibleChip * i_chip )
{
// Clear MBASPA[0,8].
@@ -194,17 +183,6 @@ uint32_t clearEccCounters<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
}
template<>
-uint32_t clearEccCounters<TYPE_MEM_PORT>( ExtensibleChip * i_chip )
-{
- PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
-
- ExtensibleChip * ocmbChip = getConnectedParent( i_chip, TYPE_OCMB_CHIP );
-
- return clearEccCounters<TYPE_OCMB_CHIP>( ocmbChip );
-}
-
-template<>
uint32_t clearEccCounters<TYPE_MBA>( ExtensibleChip * i_chip )
{
PRDF_ASSERT( nullptr != i_chip );
@@ -306,17 +284,6 @@ uint32_t clearEccFirs<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
}
template<>
-uint32_t clearEccFirs<TYPE_MEM_PORT>( ExtensibleChip * i_chip )
-{
- PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
-
- ExtensibleChip * ocmbChip = getConnectedParent( i_chip, TYPE_OCMB_CHIP );
-
- return clearEccFirs<TYPE_OCMB_CHIP>( ocmbChip );
-}
-
-template<>
uint32_t clearEccFirs<TYPE_MBA>( ExtensibleChip * i_chip )
{
uint32_t o_rc = SUCCESS;
@@ -409,22 +376,20 @@ uint32_t checkEccFirs<TYPE_MCA>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
template<>
-uint32_t checkEccFirs<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- uint32_t & o_eccAttns )
+uint32_t checkEccFirs<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ uint32_t & o_eccAttns )
{
- #define PRDF_FUNC "[checkEccFirs<TYPE_MEM_PORT>] "
+ #define PRDF_FUNC "[checkEccFirs<TYPE_OCMB_CHIP>] "
uint32_t o_rc = SUCCESS;
o_eccAttns = MAINT_NO_ERROR;
PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
-
- ExtensibleChip * ocmbChip = getConnectedParent( i_chip, TYPE_OCMB_CHIP );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
- SCAN_COMM_REGISTER_CLASS * rdffir = ocmbChip->getRegister( "RDFFIR" );
- SCAN_COMM_REGISTER_CLASS * mcbistfir = ocmbChip->getRegister( "MCBISTFIR" );
+ SCAN_COMM_REGISTER_CLASS * rdffir = i_chip->getRegister( "RDFFIR" );
+ SCAN_COMM_REGISTER_CLASS * mcbistfir = i_chip->getRegister( "MCBISTFIR" );
do
{
@@ -453,7 +418,7 @@ uint32_t checkEccFirs<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "Read() failed on MCBISTFIR: mcbChip=0x%08x",
- ocmbChip->getHuid() );
+ i_chip->getHuid() );
break;
}
@@ -733,11 +698,11 @@ uint32_t setBgScrubThresholds<TYPE_MBA>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
-template<>
-uint32_t didCmdStopOnLastAddr<TYPE_MBA>( ExtensibleChip * i_chip,
- AddrRangeType i_rangeType,
- bool & o_stoppedOnLastAddr,
- bool i_rowRepair )
+template<TARGETING::TYPE T>
+uint32_t didCmdStopOnLastAddr( ExtensibleChip * i_chip,
+ AddrRangeType i_rangeType,
+ bool & o_stoppedOnLastAddr,
+ bool i_rowRepair )
{
#define PRDF_FUNC "[didCmdStopOnLastAddr] "
@@ -749,7 +714,7 @@ uint32_t didCmdStopOnLastAddr<TYPE_MBA>( ExtensibleChip * i_chip,
{
// Get the current address.
MemAddr curAddr;
- o_rc = getMemMaintAddr<TYPE_MBA>( i_chip, curAddr );
+ o_rc = getMemMaintAddr<T>( i_chip, curAddr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemMaintAddr(0x%08x) failed",
@@ -759,7 +724,7 @@ uint32_t didCmdStopOnLastAddr<TYPE_MBA>( ExtensibleChip * i_chip,
// Get the end address of the current rank.
MemAddr junk, endAddr;
- o_rc = getMemAddrRange<TYPE_MBA>( i_chip, curAddr.getRank(), junk,
+ o_rc = getMemAddrRange<T>( i_chip, curAddr.getRank(), junk,
endAddr, i_rangeType );
if ( SUCCESS != o_rc )
{
@@ -784,7 +749,16 @@ uint32_t didCmdStopOnLastAddr<TYPE_MBA>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
-
+template
+uint32_t didCmdStopOnLastAddr<TYPE_MBA>( ExtensibleChip * i_chip,
+ AddrRangeType i_rangeType,
+ bool & o_stoppedOnLastAddr,
+ bool i_rowRepair );
+template
+uint32_t didCmdStopOnLastAddr<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ AddrRangeType i_rangeType,
+ bool & o_stoppedOnLastAddr,
+ bool i_rowRepair );
//------------------------------------------------------------------------------
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C
index f86110458..5d310c51b 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -248,8 +248,8 @@ uint32_t __analyzeCmdComplete<TYPE_MCBIST>( ExtensibleChip * i_chip,
do
{
// Get all ports in which the command was run.
- std::vector<ExtensibleChip *> portList;
- o_rc = getMcbistMaintPort( i_chip, portList );
+ ExtensibleChipList portList;
+ o_rc = getMcbistMaintPort<TYPE_MCBIST>( i_chip, portList );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMcbistMaintPort(0x%08x) failed",
@@ -291,6 +291,43 @@ uint32_t __analyzeCmdComplete<TYPE_MCBIST>( ExtensibleChip * i_chip,
}
template<>
+uint32_t __analyzeCmdComplete<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ TdRankListEntry & o_stoppedRank,
+ const MemAddr & i_addr,
+ bool & o_errorsFound,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[__analyzeCmdComplete] "
+
+ uint32_t o_rc = SUCCESS;
+
+ o_errorsFound = false;
+
+ do
+ {
+ // Update iv_stoppedRank.
+ o_stoppedRank = __getStopRank<TYPE_OCMB_CHIP>( i_chip, i_addr );
+
+ // Check the OCMB for ECC errors.
+ bool errorsFound;
+ o_rc = __checkEcc<TYPE_OCMB_CHIP>( i_chip, i_addr, errorsFound, io_sc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "__checkEcc<TYPE_OCMB_CHIP>(0x%08x) failed",
+ i_chip->getHuid() );
+ break;
+ }
+
+ if ( errorsFound ) o_errorsFound = true;
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+template<>
uint32_t __analyzeCmdComplete<TYPE_MBA>( ExtensibleChip * i_chip,
TdRankListEntry & o_stoppedRank,
const MemAddr & i_addr,
@@ -346,7 +383,7 @@ uint32_t MemTdCtlr<T>::analyzeCmdComplete( bool & o_errorsFound,
// of in defaultStep() because a TD procedure could have been run
// before defaultStep() and it is possible that canResumeBgScrub()
// could give as a false positive in that case.
- o_rc = canResumeBgScrub( iv_resumeBgScrub );
+ o_rc = canResumeBgScrub( iv_resumeBgScrub, io_sc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "canResumeBgScrub(0x%08x) failed",
@@ -397,9 +434,15 @@ void MemTdCtlr<T>::collectStateCaptureData( STEP_CODE_DATA_STRUCT & io_sc,
// Get the version to use.
uint8_t version = TD_CTLR_DATA::VERSION_1;
+ bool isNimbus = false;
if ( MODEL_NIMBUS == getChipModel(getMasterProc()) )
{
version = TD_CTLR_DATA::VERSION_2;
+ isNimbus = true;
+ }
+ else if ( MODEL_AXONE == getChipModel(getMasterProc()) )
+ {
+ version = TD_CTLR_DATA::VERSION_2;
}
// Get the IPL state.
@@ -443,6 +486,11 @@ void MemTdCtlr<T>::collectStateCaptureData( STEP_CODE_DATA_STRUCT & io_sc,
if ( TD_CTLR_DATA::VERSION_2 == version )
{
curPort = iv_curProcedure->getChip()->getPos() % MAX_MCA_PER_MCBIST;
+ if ( !isNimbus )
+ {
+ TargetHandle_t portTrgt = iv_curProcedure->getChip()->getTrgt();
+ curPort = portTrgt->getAttr<ATTR_REL_POS>();
+ }
}
}
@@ -475,6 +523,11 @@ void MemTdCtlr<T>::collectStateCaptureData( STEP_CODE_DATA_STRUCT & io_sc,
if ( TD_CTLR_DATA::VERSION_2 == version )
{
itPort = queue[n]->getChip()->getPos() % MAX_MCA_PER_MCBIST;
+ if ( !isNimbus )
+ {
+ TargetHandle_t portTrgt = queue[n]->getChip()->getTrgt();
+ itPort = portTrgt->getAttr<ATTR_REL_POS>();
+ }
}
bsb.setFieldJustify( pos, 3, itMrnk ); pos+=3;
@@ -502,6 +555,7 @@ void MemTdCtlr<T>::collectStateCaptureData( STEP_CODE_DATA_STRUCT & io_sc,
// Avoid linker errors with the template.
template class MemTdCtlr<TYPE_MCBIST>;
template class MemTdCtlr<TYPE_MBA>;
+template class MemTdCtlr<TYPE_OCMB_CHIP>;
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H
index 332109b48..da969e2c1 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -54,14 +54,14 @@ class MemTdCtlr
/**
* @brief Constructor
*
- * This contructor will only be called in the MCBIST or MBA data bundle,
- * which already checks for a valid type.
+ * This contructor will only be called in the MCBIST, MBA, or OCMB data
+ * bundle, which already checks for a valid type.
*
* Need to initialize iv_stoppedRank to a valid entry in iv_rankList. Use
* the last entry in the list so that the 'next' rank is the first entry
* in the list.
*
- * @param i_chip An MCBIST or MBA chip.
+ * @param i_chip An MCBIST, MBA, or OCMB chip.
*/
explicit MemTdCtlr( ExtensibleChip * i_chip ) :
iv_chip( i_chip ), iv_rankList( i_chip ),
@@ -122,7 +122,7 @@ class MemTdCtlr
/**
* @brief Bans TPS on the given rank. Any attempts to add a TPS procedure
* to the queue for this rank will be ignored.
- * @param i_chip MCA or MBA chip.
+ * @param i_chip MCA, MBA, or OCMB chip.
* @param i_rank The target slave rank.
*/
void banTps( ExtensibleChip * i_chip, const MemRank & i_rank )
@@ -294,15 +294,17 @@ class MemTdCtlr
/**
* @param o_canResume True, if background scrubbing can be resumed. False,
* if a new background scrub command must be started.
+ * @param io_sc The step code data struct.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
- uint32_t canResumeBgScrub( bool & o_canResume );
+ uint32_t canResumeBgScrub( bool & o_canResume,
+ STEP_CODE_DATA_STRUCT & io_sc );
#endif
private: // instance variables
- /** An MCBIST or MBA chip associated with this TD controller. */
+ /** An MCBIST, MBA, or OCMB chip associated with this TD controller. */
ExtensibleChip * const iv_chip;
/** The TD queue that contains all of the pending TD procedures. */
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C
index ea04d2964..401a48042 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -160,6 +160,14 @@ bool __mnfgCeCheck<TYPE_MCA>( uint32_t i_eccAttns )
}
template<> inline
+bool __mnfgCeCheck<TYPE_OCMB_CHIP>( uint32_t i_eccAttns )
+{
+ return ( ( 0 != (i_eccAttns & MAINT_HARD_NCE_ETE) ) &&
+ ( (0 != (i_eccAttns & MAINT_NCE)) ||
+ (0 != (i_eccAttns & MAINT_TCE)) ) );
+}
+
+template<> inline
bool __mnfgCeCheck<TYPE_MBA>( uint32_t i_eccAttns )
{
return ( 0 != (i_eccAttns & MAINT_HARD_NCE_ETE) );
@@ -251,12 +259,18 @@ template
uint32_t __checkEcc<TYPE_MBA>( ExtensibleChip * i_chip,
const MemAddr & i_addr, bool & o_errorsFound,
STEP_CODE_DATA_STRUCT & io_sc );
+template
+uint32_t __checkEcc<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemAddr & i_addr,
+ bool & o_errorsFound,
+ STEP_CODE_DATA_STRUCT & io_sc );
//------------------------------------------------------------------------------
// Avoid linker errors with the template.
template class MemTdCtlr<TYPE_MCBIST>;
template class MemTdCtlr<TYPE_MBA>;
+template class MemTdCtlr<TYPE_OCMB_CHIP>;
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_rt.C b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_rt.C
index d52ef2d1d..5565e217f 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_rt.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_rt.C
@@ -107,6 +107,36 @@ void __recaptureRegs<TYPE_MCBIST>( STEP_CODE_DATA_STRUCT & io_sc,
}
template<>
+void __recaptureRegs<TYPE_OCMB_CHIP>( STEP_CODE_DATA_STRUCT & io_sc,
+ ExtensibleChip * i_chip )
+{
+ #define PRDF_FUNC "[__recaptureRegs<TYPE_OCMB_CHIP>] "
+
+ RegDataCache & cache = RegDataCache::getCachedRegisters();
+ CaptureData & cd = io_sc.service_data->GetCaptureData();
+
+ // refresh and recapture the ocmb registers
+ const char * ocmbRegs[] =
+ {
+ "MCBISTFIR", "RDFFIR", "MBSEC0", "MBSEC1", "OCMB_MBSSYMEC0",
+ "OCMB_MBSSYMEC1", "OCMB_MBSSYMEC2", "OCMB_MBSSYMEC3",
+ "OCMB_MBSSYMEC4", "OCMB_MBSSYMEC5", "OCMB_MBSSYMEC6",
+ "OCMB_MBSSYMEC7", "OCMB_MBSSYMEC8", "MBSMSEC", "MCBMCAT",
+ };
+
+ for ( uint32_t i = 0; i < sizeof(ocmbRegs)/sizeof(char*); i++ )
+ {
+ SCAN_COMM_REGISTER_CLASS * reg =
+ i_chip->getRegister( ocmbRegs[i] );
+ cache.flush( i_chip, reg );
+ }
+
+ i_chip->CaptureErrorData( cd, Util::hashString("MaintCmdRegs_ocmb") );
+
+ #undef PRDF_FUNC
+}
+
+template<>
void __recaptureRegs<TYPE_MBA>( STEP_CODE_DATA_STRUCT & io_sc,
ExtensibleChip * i_chip )
{
@@ -283,7 +313,7 @@ uint32_t MemTdCtlr<T>::defaultStep( STEP_CODE_DATA_STRUCT & io_sc )
PRDF_TRAC( PRDF_FUNC "Calling resumeBgScrub<T>(0x%08x)",
iv_chip->getHuid() );
- o_rc = resumeBgScrub<T>( iv_chip );
+ o_rc = resumeBgScrub<T>( iv_chip, io_sc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "resumeBgScrub<T>(0x%08x) failed",
@@ -358,9 +388,48 @@ uint32_t __handleNceEte( ExtensibleChip * i_chip,
uint32_t count = symData.size();
switch ( T )
{
- case TYPE_MCA: PRDF_ASSERT( 1 <= count && count <= 2 ); break;
- case TYPE_MBA: PRDF_ASSERT( 1 == count ); break;
- default: PRDF_ASSERT( false );
+ case TYPE_MCA:
+ {
+ PRDF_ASSERT( 1 <= count && count <= 2 );
+ // Increment the CE counter and store the rank we're on,
+ // reset the UE and CE counts if we have stopped on a new rank.
+ ExtensibleChip * mcb = getConnectedParent(i_chip, TYPE_MCBIST);
+ McbistDataBundle * mcbdb = getMcbistDataBundle(mcb);
+ if ( mcbdb->iv_ceUeRank != i_addr.getRank() )
+ {
+ mcbdb->iv_ceStopCounter.reset();
+ mcbdb->iv_ueStopCounter.reset();
+ }
+ mcbdb->iv_ceStopCounter.inc( io_sc );
+ mcbdb->iv_ceUeRank = i_addr.getRank();
+
+ break;
+ }
+ case TYPE_MBA:
+ {
+ PRDF_ASSERT( 1 == count );
+ break;
+ }
+ case TYPE_OCMB_CHIP:
+ {
+ PRDF_ASSERT( 1 <= count && count <= 2 );
+ // Increment the UE counter and store the rank we're on,
+ // reset the UE and CE counts if we have stopped on a new rank.
+ OcmbDataBundle * ocmbdb = getOcmbDataBundle(i_chip);
+ if ( ocmbdb->iv_ceUeRank != i_addr.getRank() )
+ {
+ ocmbdb->iv_ceStopCounter.reset();
+ ocmbdb->iv_ueStopCounter.reset();
+ }
+ ocmbdb->iv_ceStopCounter.inc( io_sc );
+ ocmbdb->iv_ceUeRank = i_addr.getRank();
+
+ break;
+ }
+ default:
+ {
+ PRDF_ASSERT( false );
+ }
}
for ( auto & d : symData )
@@ -408,6 +477,14 @@ uint32_t __handleSoftInterCeEte<TYPE_MCA>( ExtensibleChip * i_chip,
}
template<>
+uint32_t __handleSoftInterCeEte<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemAddr & i_addr,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ return __handleNceEte<TYPE_OCMB_CHIP>( i_chip, i_addr, io_sc );
+}
+
+template<>
uint32_t __handleSoftInterCeEte<TYPE_MBA>( ExtensibleChip * i_chip,
const MemAddr & i_addr,
STEP_CODE_DATA_STRUCT & io_sc )
@@ -480,6 +557,52 @@ uint32_t __handleRceEte<TYPE_MCA>( ExtensibleChip * i_chip,
}
template<>
+uint32_t __handleRceEte<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ bool & o_errorsFound,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[__handleRceEte] "
+
+ uint32_t o_rc = SUCCESS;
+
+ // Should only get this attention in MNFG mode.
+ PRDF_ASSERT( mfgMode() );
+
+ do
+ {
+ // The RCE ETE attention could be from IUE, IMPE, or IRCD. Need to check
+ // RDFFIR[37] to determine if there was at least one IUE.
+ SCAN_COMM_REGISTER_CLASS * fir = i_chip->getRegister( "RDFFIR" );
+ o_rc = fir->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() failed on RDFFIR: i_chip=0x%08x",
+ i_chip->getHuid() );
+ break;
+ }
+ if ( !fir->IsBitSet(37) ) break; // nothing else to do
+
+ // Handle the IUE.
+ o_errorsFound = true;
+ io_sc.service_data->AddSignatureList( i_chip->getTrgt(),
+ PRDFSIG_MaintIUE );
+ o_rc = MemEcc::handleMemIue<TYPE_OCMB_CHIP>( i_chip, i_rank, io_sc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "analyzeMaintIue(0x%08x) failed",
+ i_chip->getHuid() );
+ break;
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+template<>
uint32_t __handleRceEte<TYPE_MBA>( ExtensibleChip * i_chip,
const MemRank & i_rank, bool & o_errorsFound,
STEP_CODE_DATA_STRUCT & io_sc )
@@ -698,6 +821,11 @@ template
uint32_t __checkEcc<TYPE_MBA>( ExtensibleChip * i_chip,
const MemAddr & i_addr, bool & o_errorsFound,
STEP_CODE_DATA_STRUCT & io_sc );
+template
+uint32_t __checkEcc<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemAddr & i_addr,
+ bool & o_errorsFound,
+ STEP_CODE_DATA_STRUCT & io_sc );
//------------------------------------------------------------------------------
@@ -786,6 +914,76 @@ uint32_t MemTdCtlr<TYPE_MCBIST>::unmaskEccAttns()
//------------------------------------------------------------------------------
template<>
+uint32_t MemTdCtlr<TYPE_OCMB_CHIP>::maskEccAttns()
+{
+ #define PRDF_FUNC "[MemTdCtlr<TYPE_OCMB_CHIP>::maskEccAttns] "
+
+ uint32_t o_rc = SUCCESS;
+
+ SCAN_COMM_REGISTER_CLASS * mask = iv_chip->getRegister( "RDFFIR_MASK_OR" );
+
+ mask->clearAllBits();
+ mask->SetBit(8); // Mainline read NCE
+ mask->SetBit(9); // Mainline read TCE
+
+ o_rc = mask->Write();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() failed on RDFFIR_MASK_OR" );
+ }
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<>
+uint32_t MemTdCtlr<TYPE_OCMB_CHIP>::unmaskEccAttns()
+{
+ #define PRDF_FUNC "[MemTdCtlr<TYPE_OCMB_CHIP>::unmaskEccAttns] "
+
+ uint32_t o_rc = SUCCESS;
+
+ // Memory CEs were masked at the beginning of the TD procedure, so
+ // clear and unmask them. Also, it is possible that memory UEs have
+ // thresholded so clear and unmask them as well.
+
+ SCAN_COMM_REGISTER_CLASS * fir = iv_chip->getRegister( "RDFFIR_AND" );
+ SCAN_COMM_REGISTER_CLASS * mask = iv_chip->getRegister( "RDFFIR_MASK_AND" );
+
+ fir->setAllBits(); mask->setAllBits();
+
+ // Do not unmask NCE and TCE attentions if they have been permanently
+ // masked due to certain TPS conditions.
+ if ( !(getOcmbDataBundle(iv_chip)->iv_maskMainlineNceTce) )
+ {
+ fir->ClearBit(8); mask->ClearBit(8); // Mainline read NCE
+ fir->ClearBit(9); mask->ClearBit(9); // Mainline read TCE
+ }
+ fir->ClearBit(14); mask->ClearBit(14); // Mainline read UE
+
+ o_rc = fir->Write();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() failed on RDFFIR_AND" );
+ }
+
+ o_rc = mask->Write();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() failed on RDFFIR_MASK_AND" );
+ }
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<>
uint32_t MemTdCtlr<TYPE_MBA>::maskEccAttns()
{
#define PRDF_FUNC "[MemTdCtlr<TYPE_MBA>::maskEccAttns] "
@@ -887,6 +1085,13 @@ SCAN_COMM_REGISTER_CLASS * __getEccFirAnd<TYPE_MCA>( ExtensibleChip * i_chip )
}
template<>
+SCAN_COMM_REGISTER_CLASS * __getEccFirAnd<TYPE_OCMB_CHIP>(
+ ExtensibleChip * i_chip )
+{
+ return i_chip->getRegister( "RDFFIR_AND" );
+}
+
+template<>
SCAN_COMM_REGISTER_CLASS * __getEccFirAnd<TYPE_MBA>( ExtensibleChip * i_chip )
{
ExtensibleChip * membChip = getConnectedParent( i_chip, TYPE_MEMBUF );
@@ -1009,6 +1214,45 @@ uint32_t MemTdCtlr<TYPE_MCBIST>::initialize()
}
template<>
+uint32_t MemTdCtlr<TYPE_OCMB_CHIP>::initialize()
+{
+ #define PRDF_FUNC "[MemTdCtlr<TYPE_OCMB_CHIP>::initialize] "
+
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ if ( iv_initialized ) break; // nothing to do
+
+ // Unmask the fetch attentions just in case there were masked during a
+ // TD procedure prior to a reset/reload.
+ o_rc = unmaskEccAttns();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "unmaskEccAttns() failed" );
+ break;
+ }
+
+ // Find all unverified chip marks.
+ o_rc = __findChipMarks<TYPE_OCMB_CHIP>( iv_rankList );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "__findChipMarks() failed on 0x%08x",
+ iv_chip->getHuid() );
+ break;
+ }
+
+ // At this point, the TD controller is initialized.
+ iv_initialized = true;
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+template<>
uint32_t MemTdCtlr<TYPE_MBA>::initialize()
{
#define PRDF_FUNC "[MemTdCtlr<TYPE_MBA>::initialize] "
@@ -1162,6 +1406,118 @@ uint32_t MemTdCtlr<TYPE_MCBIST>::handleRrFo()
//------------------------------------------------------------------------------
template<>
+uint32_t MemTdCtlr<TYPE_OCMB_CHIP>::handleRrFo()
+{
+ #define PRDF_FUNC "[MemTdCtlr<TYPE_OCMB_CHIP>::handleRrFo] "
+
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ // Check if maintenance command complete attention is set.
+ SCAN_COMM_REGISTER_CLASS * mcbistfir =
+ iv_chip->getRegister("MCBISTFIR");
+ o_rc = mcbistfir->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() failed on MCBISTFIR");
+ break;
+ }
+
+ // If there is a command complete attention, nothing to do, break out.
+ if ( mcbistfir->IsBitSet(10) )
+ break;
+
+
+ // Check if a command is not running.
+ // If bit 0 of MCB_CNTLSTAT is on, a mcbist run is in progress.
+ SCAN_COMM_REGISTER_CLASS * mcb_cntlstat =
+ iv_chip->getRegister("MCB_CNTLSTAT");
+ o_rc = mcb_cntlstat->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() failed on MCB_CNTLSTAT" );
+ break;
+ }
+
+ // If a command is not running, set command complete attn, break.
+ if ( !mcb_cntlstat->IsBitSet(0) )
+ {
+ SCAN_COMM_REGISTER_CLASS * mcbistfir_or =
+ iv_chip->getRegister("MCBISTFIR_OR");
+ mcbistfir_or->SetBit( 10 );
+
+ mcbistfir_or->Write();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() failed on MCBISTFIR_OR" );
+ }
+ break;
+ }
+
+ // Check if there are unverified chip marks.
+ std::vector<TdRankListEntry> vectorList = iv_rankList.getList();
+
+ for ( auto & entry : vectorList )
+ {
+ ExtensibleChip * ocmbChip = entry.getChip();
+ MemRank rank = entry.getRank();
+
+ // Get the chip mark
+ MemMark chipMark;
+ o_rc = MarkStore::readChipMark<TYPE_OCMB_CHIP>( ocmbChip, rank,
+ chipMark );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "readChipMark<TYPE_OCMB_CHIP>(0x%08x,%d) "
+ "failed", ocmbChip->getHuid(), rank.getMaster() );
+ break;
+ }
+
+ if ( !chipMark.isValid() ) continue; // no chip mark present
+
+ // Get the DQ Bitmap data.
+ MemDqBitmap dqBitmap;
+
+ o_rc = getBadDqBitmap( ocmbChip->getTrgt(), rank, dqBitmap );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "getBadDqBitmap(0x%08x, %d)",
+ ocmbChip->getHuid(), rank.getMaster() );
+ break;
+ }
+
+ // Check if the chip mark is verified or not.
+ bool cmVerified = false;
+ o_rc = dqBitmap.isChipMark( chipMark.getSymbol(), cmVerified );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "dqBitmap.isChipMark failed." );
+ break;
+ }
+
+ // If there are any unverified chip marks, stop the command, break.
+ if ( !cmVerified )
+ {
+ o_rc = stopBgScrub<TYPE_OCMB_CHIP>( iv_chip );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "stopBgScrub<TYPE_OCMB_CHIP>(0x%08x) "
+ "failed", iv_chip->getHuid() );
+ }
+ break;
+ }
+ }
+
+ } while (0);
+
+ return o_rc;
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<>
uint32_t MemTdCtlr<TYPE_MBA>::handleRrFo()
{
#define PRDF_FUNC "[MemTdCtlr<TYPE_MBA>::handleRrFo] "
@@ -1289,7 +1645,8 @@ uint32_t MemTdCtlr<TYPE_MBA>::handleRrFo()
//------------------------------------------------------------------------------
template<>
-uint32_t MemTdCtlr<TYPE_MCBIST>::canResumeBgScrub( bool & o_canResume )
+uint32_t MemTdCtlr<TYPE_MCBIST>::canResumeBgScrub( bool & o_canResume,
+ STEP_CODE_DATA_STRUCT & io_sc )
{
#define PRDF_FUNC "[MemTdCtlr<TYPE_MCBIST>::canResumeBgScrub] "
@@ -1305,21 +1662,124 @@ uint32_t MemTdCtlr<TYPE_MCBIST>::canResumeBgScrub( bool & o_canResume )
// can use the stop conditions, which should be unique for background scrub,
// to determine if it has been configured.
- SCAN_COMM_REGISTER_CLASS * reg = iv_chip->getRegister( "MBSTR" );
- o_rc = reg->Read();
- if ( SUCCESS != o_rc )
+ do
{
- PRDF_ERR( PRDF_FUNC "Read() failed on MBSTR: iv_chip=0x%08x",
- iv_chip->getHuid() );
- }
- else if ( 0xf != reg->GetBitFieldJustified(0,4) && // NCE int TH
- 0xf != reg->GetBitFieldJustified(4,4) && // NCE soft TH
- 0xf != reg->GetBitFieldJustified(8,4) && // NCE hard TH
- reg->IsBitSet(34) && // pause on MPE
- reg->IsBitSet(35) ) // pause on UE
+ SCAN_COMM_REGISTER_CLASS * reg = iv_chip->getRegister( "MBSTR" );
+ o_rc = reg->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() failed on MBSTR: iv_chip=0x%08x",
+ iv_chip->getHuid() );
+ break;
+ }
+ // Note: The stop conditions for background scrubbing can now be
+ // variable depending on whether we have hit threshold for the number
+ // of UEs or CEs that we have stopped on on a rank.
+
+ // If we haven't hit CE or UE threshold, check the CE stop conditions
+ if ( !getMcbistDataBundle(iv_chip)->iv_ceStopCounter.thReached(io_sc) &&
+ !getMcbistDataBundle(iv_chip)->iv_ueStopCounter.thReached(io_sc) )
+ {
+ // If the stop conditions aren't set, just break out.
+ if ( !(0xf != reg->GetBitFieldJustified(0,4) && // NCE int TH
+ 0xf != reg->GetBitFieldJustified(4,4) && // NCE soft TH
+ 0xf != reg->GetBitFieldJustified(8,4)) ) // NCE hard TH
+ {
+ break;
+ }
+
+ }
+
+ // If we haven't hit UE threshold yet, check the UE stop condition
+ if ( !getMcbistDataBundle(iv_chip)->iv_ueStopCounter.thReached(io_sc) )
+ {
+ // If the stop condition isn't set, just break out
+ if ( !reg->IsBitSet(35) ) // pause on UE
+ {
+ break;
+ }
+ }
+
+ // Need to check the stop on mpe stop condition regardless of whether
+ // we hit the UE or CE threshold.
+ if ( reg->IsBitSet(34) ) // pause on MPE
+ {
+ // If we reach here, all the stop conditions are set for background
+ // scrub, so we can resume.
+ o_canResume = true;
+ }
+ }while(0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+template<>
+uint32_t MemTdCtlr<TYPE_OCMB_CHIP>::canResumeBgScrub( bool & o_canResume,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[MemTdCtlr<TYPE_OCMB_CHIP>::canResumeBgScrub] "
+
+ uint32_t o_rc = SUCCESS;
+
+ o_canResume = false;
+
+ // It is possible that we were running a TD procedure and the PRD service
+ // was reset. Therefore, we must check if background scrubbing was actually
+ // configured. There really is not a good way of doing this. A scrub command
+ // is a scrub command the only difference is the speed. Unfortunately, that
+ // speed can change depending on how the hardware team tunes it. For now, we
+ // can use the stop conditions, which should be unique for background scrub,
+ // to determine if it has been configured.
+
+ do
{
- o_canResume = true;
- }
+ SCAN_COMM_REGISTER_CLASS * reg = iv_chip->getRegister( "MBSTR" );
+ o_rc = reg->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() failed on MBSTR: iv_chip=0x%08x",
+ iv_chip->getHuid() );
+ break;
+ }
+ // Note: The stop conditions for background scrubbing can now be
+ // variable depending on whether we have hit threshold for the number
+ // of UEs or CEs that we have stopped on on a rank.
+
+ // If we haven't hit CE or UE threshold, check the CE stop conditions
+ if ( !getOcmbDataBundle(iv_chip)->iv_ceStopCounter.thReached(io_sc) &&
+ !getOcmbDataBundle(iv_chip)->iv_ueStopCounter.thReached(io_sc) )
+ {
+ // If the stop conditions aren't set, just break out.
+ if ( !(0xf != reg->GetBitFieldJustified(0,4) && // NCE int TH
+ 0xf != reg->GetBitFieldJustified(4,4) && // NCE soft TH
+ 0xf != reg->GetBitFieldJustified(8,4)) ) // NCE hard TH
+ {
+ break;
+ }
+
+ }
+
+ // If we haven't hit UE threshold yet, check the UE stop condition
+ if ( !getOcmbDataBundle(iv_chip)->iv_ueStopCounter.thReached(io_sc) )
+ {
+ // If the stop condition isn't set, just break out
+ if ( !reg->IsBitSet(35) ) // pause on UE
+ {
+ break;
+ }
+ }
+
+ // Need to check the stop on mpe stop condition regardless of whether
+ // we hit the UE or CE threshold.
+ if ( reg->IsBitSet(34) ) // pause on MPE
+ {
+ // If we reach here, all the stop conditions are set for background
+ // scrub, so we can resume.
+ o_canResume = true;
+ }
+ }while(0);
return o_rc;
@@ -1327,7 +1787,8 @@ uint32_t MemTdCtlr<TYPE_MCBIST>::canResumeBgScrub( bool & o_canResume )
}
template<>
-uint32_t MemTdCtlr<TYPE_MBA>::canResumeBgScrub( bool & o_canResume )
+uint32_t MemTdCtlr<TYPE_MBA>::canResumeBgScrub( bool & o_canResume,
+ STEP_CODE_DATA_STRUCT & io_sc )
{
#define PRDF_FUNC "[MemTdCtlr<TYPE_MBA>::canResumeBgScrub] "
@@ -1365,6 +1826,7 @@ uint32_t MemTdCtlr<TYPE_MBA>::canResumeBgScrub( bool & o_canResume )
// Avoid linker errors with the template.
template class MemTdCtlr<TYPE_MCBIST>;
template class MemTdCtlr<TYPE_MBA>;
+template class MemTdCtlr<TYPE_OCMB_CHIP>;
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdRankList.H b/src/usr/diag/prdf/plat/mem/prdfMemTdRankList.H
index e61389ea2..2e833a12a 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTdRankList.H
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTdRankList.H
@@ -80,8 +80,8 @@ class TdRankListEntry
private:
- ExtensibleChip * iv_chip = nullptr; ///< MCA, MBA, or MEM_PORT chip.
- MemRank iv_rank = MemRank(0); ///< Any rank on the MCA/MBA/MEM_PORT
+ ExtensibleChip * iv_chip = nullptr; ///< MCA, MBA, or OCMB chip.
+ MemRank iv_rank = MemRank(0); ///< Any rank on the MCA/MBA/OCMB
};
/**
@@ -95,7 +95,7 @@ class TdRankList
/**
* @brief Constructor.
- * @param MCBIST or MBA chip.
+ * @param MCBIST, OCMB, or MBA chip.
*/
explicit TdRankList( ExtensibleChip * i_chip );
@@ -191,17 +191,13 @@ inline TdRankList<TARGETING::TYPE_OCMB_CHIP>::TdRankList(
PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
- ExtensibleChipList memPortChipList = getConnected( i_chip, TYPE_MEM_PORT );
- for ( auto & memPortChip : memPortChipList )
- {
- std::vector<MemRank> rankList;
- getSlaveRanks<TYPE_MEM_PORT>( memPortChip->getTrgt(), rankList );
- PRDF_ASSERT( !rankList.empty() ); // target configured with no ranks
+ std::vector<MemRank> rankList;
+ getSlaveRanks<TYPE_OCMB_CHIP>( i_chip->getTrgt(), rankList );
+ PRDF_ASSERT( !rankList.empty() ); // target configured with no ranks
- for ( auto & rank : rankList )
- {
- iv_list.push_back( TdRankListEntry(memPortChip, rank) );
- }
+ for ( auto & rank : rankList )
+ {
+ iv_list.push_back( TdRankListEntry(i_chip, rank) );
}
}
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C b/src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C
index de3e62e23..64eb74648 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,6 +36,8 @@
#include <prdfP9McaExtraSig.H>
#include <prdfPlatServices.H>
+#include <hwp_wrappers.H>
+
using namespace TARGETING;
namespace PRDF
@@ -125,6 +127,12 @@ bool __iueCheck<TYPE_MCA>( uint32_t i_eccAttns )
}
template<> inline
+bool __iueCheck<TYPE_OCMB_CHIP>( uint32_t i_eccAttns )
+{
+ return ( 0 != (i_eccAttns & MAINT_IUE) );
+}
+
+template<> inline
bool __iueCheck<TYPE_MBA>( uint32_t i_eccAttns )
{
// IUES are reported via RCE ETE on Centaur
@@ -252,13 +260,15 @@ uint32_t TpsEvent<TYPE_MCA>::startCmd()
uint32_t o_rc = SUCCESS;
+ #ifndef CONFIG_AXONE
+
// We don't need to set any stop-on-error conditions or thresholds for
// soft/inter/hard CEs during Memory Diagnostics. The design is to let the
// command continue to the end of the rank and we do diagnostics on the
// CE counts found in the per-symbol counters. Therefore, all we need to do
// is tell the hardware which CE types to count.
- mss::mcbist::stop_conditions stopCond;
+ mss::mcbist::stop_conditions<mss::mc_type::NIMBUS> stopCond;
switch ( iv_phase )
{
@@ -284,6 +294,8 @@ uint32_t TpsEvent<TYPE_MCA>::startCmd()
iv_chip->getHuid(), getKey() );
}
+ #endif
+
return o_rc;
#undef PRDF_FUNC
@@ -362,11 +374,66 @@ uint32_t TpsEvent<TYPE_MBA>::startCmd()
#undef PRDF_FUNC
}
+//##############################################################################
+//
+// Specializations for OCMB
+//
+//##############################################################################
+
+template<>
+uint32_t TpsEvent<TYPE_OCMB_CHIP>::startCmd()
+{
+ #define PRDF_FUNC "[TpsEvent::startCmd] "
+
+ uint32_t o_rc = SUCCESS;
+
+ #ifdef CONFIG_AXONE
+
+ // We don't need to set any stop-on-error conditions or thresholds for
+ // soft/inter/hard CEs during Memory Diagnostics. The design is to let the
+ // command continue to the end of the rank and we do diagnostics on the
+ // CE counts found in the per-symbol counters. Therefore, all we need to do
+ // is tell the hardware which CE types to count.
+
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER> stopCond;
+
+ switch ( iv_phase )
+ {
+ case TD_PHASE_1:
+ // Set the per symbol counters to count only soft/inter CEs.
+ stopCond.set_nce_soft_symbol_count_enable( mss::ON);
+ stopCond.set_nce_inter_symbol_count_enable(mss::ON);
+ break;
+
+ case TD_PHASE_2:
+ // Set the per symbol counters to count only hard CEs.
+ stopCond.set_nce_hard_symbol_count_enable(mss::ON);
+ break;
+
+ default: PRDF_ASSERT( false ); // invalid phase
+ }
+
+ // Start the time based scrub procedure on this slave rank.
+ o_rc = startTdScrub<TYPE_OCMB_CHIP>(iv_chip, iv_rank, SLAVE_RANK, stopCond);
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "startTdScrub(0x%08x,0x%2x) failed",
+ iv_chip->getHuid(), getKey() );
+ }
+
+ #endif
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
//------------------------------------------------------------------------------
// Avoid linker errors with the template.
template class TpsEvent<TYPE_MCA>;
template class TpsEvent<TYPE_MBA>;
+template class TpsEvent<TYPE_OCMB_CHIP>;
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTps_rt.C b/src/usr/diag/prdf/plat/mem/prdfMemTps_rt.C
index 187b9b28d..8b3b220c6 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTps_rt.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTps_rt.C
@@ -37,6 +37,8 @@
#include <prdfP9McaExtraSig.H>
#include <prdfTargetServices.H>
+#include <hwp_wrappers.H>
+
using namespace TARGETING;
namespace PRDF
@@ -54,6 +56,13 @@ static const char *mcbCeStatReg[CE_REGS_PER_PORT] =
"MCB_MBSSYMEC6", "MCB_MBSSYMEC7", "MCB_MBSSYMEC8"
};
+static const char *ocmbCeStatReg[CE_REGS_PER_PORT] =
+ {
+ "OCMB_MBSSYMEC0", "OCMB_MBSSYMEC1", "OCMB_MBSSYMEC2",
+ "OCMB_MBSSYMEC3", "OCMB_MBSSYMEC4", "OCMB_MBSSYMEC5",
+ "OCMB_MBSSYMEC6", "OCMB_MBSSYMEC7", "OCMB_MBSSYMEC8"
+ };
+
//------------------------------------------------------------------------------
template <TARGETING::TYPE T>
@@ -66,6 +75,13 @@ TpsFalseAlarm * __getTpsFalseAlarmCounter<TYPE_MCA>( ExtensibleChip * i_chip )
}
template<>
+TpsFalseAlarm * __getTpsFalseAlarmCounter<TYPE_OCMB_CHIP>(
+ ExtensibleChip * i_chip )
+{
+ return getOcmbDataBundle(i_chip)->getTpsFalseAlarmCounter();
+}
+
+template<>
TpsFalseAlarm * __getTpsFalseAlarmCounter<TYPE_MBA>( ExtensibleChip * i_chip )
{
return getMbaDataBundle(i_chip)->getTpsFalseAlarmCounter();
@@ -73,6 +89,23 @@ TpsFalseAlarm * __getTpsFalseAlarmCounter<TYPE_MBA>( ExtensibleChip * i_chip )
//------------------------------------------------------------------------------
+template <TARGETING::TYPE T>
+void __maskMainlineNceTces( ExtensibleChip * i_chip );
+
+template<>
+void __maskMainlineNceTces<TYPE_MCA>( ExtensibleChip * i_chip )
+{
+ getMcaDataBundle(i_chip)->iv_maskMainlineNceTce = true;
+}
+
+template<>
+void __maskMainlineNceTces<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
+{
+ getOcmbDataBundle(i_chip)->iv_maskMainlineNceTce = true;
+}
+
+//------------------------------------------------------------------------------
+
template<TARGETING::TYPE T>
void __getNextPhase( ExtensibleChip * i_chip, const MemRank & i_rank,
STEP_CODE_DATA_STRUCT & io_sc,
@@ -98,12 +131,7 @@ void __getNextPhase( ExtensibleChip * i_chip, const MemRank & i_rank,
//------------------------------------------------------------------------------
template<TARGETING::TYPE T>
-bool __badDqCount( MemUtils::MaintSymbols i_nibbleStats,
- CeCount & io_badDqCount );
-
-template<>
-bool __badDqCount<TYPE_MCA>( MemUtils::MaintSymbols i_nibbleStats,
- CeCount & io_badDqCount )
+bool __badDqCount(MemUtils::MaintSymbols i_nibbleStats, CeCount & io_badDqCount)
{
bool badDqFound = false;
@@ -142,11 +170,7 @@ bool __badDqCount<TYPE_MCA>( MemUtils::MaintSymbols i_nibbleStats,
template<TARGETING::TYPE T>
bool __badChipCount( MemUtils::MaintSymbols i_nibbleStats,
- CeCount & io_badChipCount );
-
-template<>
-bool __badChipCount<TYPE_MCA>( MemUtils::MaintSymbols i_nibbleStats,
- CeCount & io_badChipCount )
+ CeCount & io_badChipCount )
{
bool badChipFound = false;
uint8_t nonZeroCount = 0;
@@ -191,11 +215,7 @@ bool __badChipCount<TYPE_MCA>( MemUtils::MaintSymbols i_nibbleStats,
template<TARGETING::TYPE T>
void __sumAboveOneCount( MemUtils::MaintSymbols i_nibbleStats,
- CeCount & io_sumAboveOneCount );
-
-template<>
-void __sumAboveOneCount<TYPE_MCA>( MemUtils::MaintSymbols i_nibbleStats,
- CeCount & io_sumAboveOneCount )
+ CeCount & io_sumAboveOneCount )
{
uint8_t sum = 0;
MemUtils::MaintSymbols symList;
@@ -226,11 +246,7 @@ void __sumAboveOneCount<TYPE_MCA>( MemUtils::MaintSymbols i_nibbleStats,
template<TARGETING::TYPE T>
void __singleSymbolCount( MemUtils::MaintSymbols i_nibbleStats,
- CeCount & io_singleSymCount );
-
-template<>
-void __singleSymbolCount<TYPE_MCA>( MemUtils::MaintSymbols i_nibbleStats,
- CeCount & io_singleSymCount )
+ CeCount & io_singleSymCount )
{
uint8_t count = 0;
bool multNonZeroSyms = false;
@@ -315,12 +331,12 @@ uint32_t __updateVpdSumAboveOne( CeCount i_sumAboveOneCount,
//------------------------------------------------------------------------------
-template <>
-uint32_t TpsEvent<TYPE_MCA>::analyzeEccErrors( const uint32_t & i_eccAttns,
- STEP_CODE_DATA_STRUCT & io_sc,
- bool & o_done )
+template <TARGETING::TYPE T>
+uint32_t TpsEvent<T>::analyzeEccErrors( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done )
{
- #define PRDF_FUNC "[TpsEvent<TYPE_MCA>::analyzeEccErrors] "
+ #define PRDF_FUNC "[TpsEvent<T>::analyzeEccErrors] "
uint32_t o_rc = SUCCESS;
@@ -338,7 +354,7 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeEccErrors( const uint32_t & i_eccAttns,
// At this point we don't actually have an address for the UE. The
// best we can do is get the address in which the command stopped.
MemAddr addr;
- o_rc = getMemMaintAddr<TYPE_MCA>( iv_chip, addr );
+ o_rc = getMemMaintAddr<T>( iv_chip, addr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemMaintAddr(0x%08x) failed",
@@ -346,8 +362,8 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeEccErrors( const uint32_t & i_eccAttns,
break;
}
- o_rc = MemEcc::handleMemUe<TYPE_MCA>( iv_chip, addr,
- UE_TABLE::SCRUB_UE, io_sc );
+ o_rc = MemEcc::handleMemUe<T>( iv_chip, addr,
+ UE_TABLE::SCRUB_UE, io_sc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "handleMemUe(0x%08x,0x%02x) failed",
@@ -357,7 +373,7 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeEccErrors( const uint32_t & i_eccAttns,
// Because of the UE, any further TPS requests will likely have no
// effect. So ban all subsequent requests.
- MemDbUtils::banTps<TYPE_MCA>( iv_chip, addr.getRank() );
+ MemDbUtils::banTps<T>( iv_chip, addr.getRank() );
// Abort this procedure because additional repairs will likely
// not help (also avoids complication of having UE and MPE at
@@ -371,7 +387,7 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeEccErrors( const uint32_t & i_eccAttns,
io_sc.service_data->setSignature( iv_chip->getHuid(),
PRDFSIG_MaintIUE );
- o_rc = MemEcc::handleMemIue<TYPE_MCA>( iv_chip, iv_rank, io_sc );
+ o_rc = MemEcc::handleMemIue<T>( iv_chip, iv_rank, io_sc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "handleMemIue(0x%08x,0x%02x) failed",
@@ -397,8 +413,8 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeEccErrors( const uint32_t & i_eccAttns,
io_sc.service_data->setSignature( iv_chip->getHuid(),
PRDFSIG_MaintMPE );
- o_rc = MemEcc::handleMpe<TYPE_MCA>( iv_chip, iv_rank,
- UE_TABLE::SCRUB_MPE, io_sc );
+ o_rc = MemEcc::handleMpe<T>( iv_chip, iv_rank,
+ UE_TABLE::SCRUB_MPE, io_sc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "handleMpe<T>(0x%08x, 0x%02x) failed",
@@ -419,36 +435,51 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeEccErrors( const uint32_t & i_eccAttns,
}
+template
+uint32_t TpsEvent<TYPE_MCA>::analyzeEccErrors( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done );
+template
+uint32_t TpsEvent<TYPE_OCMB_CHIP>::analyzeEccErrors(const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done);
+
//------------------------------------------------------------------------------
-template<>
-uint32_t TpsEvent<TYPE_MCA>::handleFalseAlarm( STEP_CODE_DATA_STRUCT & io_sc )
+template<TARGETING::TYPE T>
+uint32_t TpsEvent<T>::handleFalseAlarm( STEP_CODE_DATA_STRUCT & io_sc )
{
io_sc.service_data->setSignature( iv_chip->getHuid(),
PRDFSIG_TpsFalseAlarm );
// Increase false alarm counter and check threshold.
- if ( __getTpsFalseAlarmCounter<TYPE_MCA>(iv_chip)->inc( iv_rank, io_sc) )
+ if ( __getTpsFalseAlarmCounter<T>(iv_chip)->inc( iv_rank, io_sc) )
{
io_sc.service_data->setSignature( iv_chip->getHuid(),
PRDFSIG_TpsFalseAlarmTH );
// Permanently mask mainline NCEs and TCEs
- getMcaDataBundle(iv_chip)->iv_maskMainlineNceTce = true;
+ __maskMainlineNceTces<T>( iv_chip );
}
return SUCCESS;
}
+template
+uint32_t TpsEvent<TYPE_MCA>::handleFalseAlarm( STEP_CODE_DATA_STRUCT & io_sc );
+template
+uint32_t TpsEvent<TYPE_OCMB_CHIP>::handleFalseAlarm(
+ STEP_CODE_DATA_STRUCT & io_sc );
+
//------------------------------------------------------------------------------
-template<>
-uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
+template<TARGETING::TYPE T>
+uint32_t TpsEvent<T>::analyzeCeSymbolCounts( CeCount i_badDqCount,
CeCount i_badChipCount, CeCount i_sumAboveOneCount,
CeCount i_singleSymCount, STEP_CODE_DATA_STRUCT & io_sc )
{
- #define PRDF_FUNC "[TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts] "
+ #define PRDF_FUNC "[TpsEvent<T>::analyzeCeSymbolCounts] "
uint32_t o_rc = SUCCESS;
@@ -457,33 +488,33 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
bool tpsFalseAlarm = false;
// Get the Bad DQ Bitmap.
- TargetHandle_t mcaTrgt = iv_chip->getTrgt();
+ TargetHandle_t trgt = iv_chip->getTrgt();
MemDqBitmap dqBitmap;
- o_rc = getBadDqBitmap( mcaTrgt, iv_rank, dqBitmap );
+ o_rc = getBadDqBitmap( trgt, iv_rank, dqBitmap );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getBadDqBitmap(0x%08x, 0x%02x) failed",
- getHuid(mcaTrgt), iv_rank.getKey() );
+ getHuid(trgt), iv_rank.getKey() );
break;
}
// Get the symbol mark.
MemMark symMark;
- o_rc = MarkStore::readSymbolMark<TYPE_MCA>( iv_chip, iv_rank, symMark );
+ o_rc = MarkStore::readSymbolMark<T>( iv_chip, iv_rank, symMark );
if ( SUCCESS != o_rc )
{
- PRDF_ERR( PRDF_FUNC "readSymbolMark<TYPE_MCA>(0x%08x, 0x%02x) "
+ PRDF_ERR( PRDF_FUNC "readSymbolMark<T>(0x%08x, 0x%02x) "
"failed", iv_chip->getHuid(), iv_rank.getKey() );
break;
}
// Get the chip mark.
MemMark chipMark;
- o_rc = MarkStore::readChipMark<TYPE_MCA>( iv_chip, iv_rank, chipMark );
+ o_rc = MarkStore::readChipMark<T>( iv_chip, iv_rank, chipMark );
if ( SUCCESS != o_rc )
{
- PRDF_ERR( PRDF_FUNC "readChipMark<TYPE_MCA>(0x%08x, 0x%02x) "
+ PRDF_ERR( PRDF_FUNC "readChipMark<T>(0x%08x, 0x%02x) "
"failed", iv_chip->getHuid(), iv_rank.getKey() );
break;
}
@@ -512,9 +543,9 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
// TCE. Both are still correctable after a symbol mark
// is placed.
// Place a symbol mark on this bad DQ.
- MemMark newSymMark( mcaTrgt, iv_rank,
+ MemMark newSymMark( trgt, iv_rank,
i_badDqCount.symList[0].symbol );
- o_rc = MarkStore::writeSymbolMark<TYPE_MCA>( iv_chip,
+ o_rc = MarkStore::writeSymbolMark<T>( iv_chip,
iv_rank, newSymMark );
if ( SUCCESS != o_rc )
{
@@ -552,7 +583,7 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
io_sc.service_data->setServiceCall();
// Permanently mask mainline NCEs and TCEs.
- getMcaDataBundle(iv_chip)->iv_maskMainlineNceTce = true;
+ __maskMainlineNceTces<T>( iv_chip );
}
}
else
@@ -566,7 +597,7 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
else if ( 2 == i_badDqCount.count && 0 == i_badChipCount.count )
{
// Permanently mask mainline NCEs and TCEs.
- getMcaDataBundle(iv_chip)->iv_maskMainlineNceTce = true;
+ __maskMainlineNceTces<T>( iv_chip );
// If the symbol mark is available.
if ( !symMark.isValid() )
@@ -587,9 +618,9 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
highSym = sym;
}
- MemMark newSymMark( mcaTrgt, iv_rank,
+ MemMark newSymMark( trgt, iv_rank,
highSym.symbol );
- o_rc = MarkStore::writeSymbolMark<TYPE_MCA>( iv_chip,
+ o_rc = MarkStore::writeSymbolMark<T>( iv_chip,
iv_rank, newSymMark );
if ( SUCCESS != o_rc )
{
@@ -669,10 +700,10 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
// This means we have only one more potential bad DQ, which
// is still correctable after a chip mark is placed.
// Place a chip mark on this bad chip.
- MemMark newChipMark( mcaTrgt, iv_rank,
+ MemMark newChipMark( trgt, iv_rank,
i_badChipCount.symList[0].symbol );
- o_rc = MarkStore::writeChipMark<TYPE_MCA>( iv_chip, iv_rank,
- newChipMark );
+ o_rc = MarkStore::writeChipMark<T>( iv_chip, iv_rank,
+ newChipMark );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "writeChipMark(0x%08x,0x%02x) "
@@ -708,7 +739,7 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
io_sc.service_data->setServiceCall();
// Permanently mask mainline NCEs and TCEs
- getMcaDataBundle(iv_chip)->iv_maskMainlineNceTce = true;
+ __maskMainlineNceTces<T>( iv_chip );
}
}
else
@@ -731,7 +762,7 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
io_sc.service_data->setServiceCall();
// Permanently mask mainline NCEs and TCEs
- getMcaDataBundle(iv_chip)->iv_maskMainlineNceTce = true;
+ __maskMainlineNceTces<T>( iv_chip );
}
// If the chip mark is available.
if ( !chipMark.isValid() )
@@ -742,10 +773,10 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
// This means we have no more potential bad DQ or bad chips
// since we can't correct those after chip mark is placed.
// Place a chip mark on the bad chip.
- MemMark newChipMark( mcaTrgt, iv_rank,
+ MemMark newChipMark( trgt, iv_rank,
i_badChipCount.symList[0].symbol );
- o_rc = MarkStore::writeChipMark<TYPE_MCA>( iv_chip, iv_rank,
- newChipMark );
+ o_rc = MarkStore::writeChipMark<T>( iv_chip, iv_rank,
+ newChipMark );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "writeChipMark(0x%08x,0x%02x) "
@@ -763,8 +794,8 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
// this chip mark, we need to clear the symbol mark now
// instead of at the end of the function to make room
// for the additional symbol mark.
- o_rc = MarkStore::clearSymbolMark<TYPE_MCA>( iv_chip,
- iv_rank );
+ o_rc = MarkStore::clearSymbolMark<T>( iv_chip,
+ iv_rank );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "MarkStore::clearSymbolMark("
@@ -810,7 +841,7 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
io_sc.service_data->setServiceCall();
// Permanently mask mainline NCEs and TCEs.
- getMcaDataBundle(iv_chip)->iv_maskMainlineNceTce = true;
+ __maskMainlineNceTces<T>( iv_chip );
}
}
// If the symbol mark is available.
@@ -822,9 +853,9 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
// This means we have no more potential bad DQ or bad chips
// since we can't correct those after symbol mark is placed.
// Place a symbol mark on this bad DQ.
- MemMark newSymMark( mcaTrgt, iv_rank,
+ MemMark newSymMark( trgt, iv_rank,
i_badDqCount.symList[0].symbol );
- o_rc = MarkStore::writeSymbolMark<TYPE_MCA>( iv_chip,
+ o_rc = MarkStore::writeSymbolMark<T>( iv_chip,
iv_rank, newSymMark );
if ( SUCCESS != o_rc )
{
@@ -865,7 +896,7 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
io_sc.service_data->setServiceCall();
// Permanently mask mainline NCEs and TCEs.
- getMcaDataBundle(iv_chip)->iv_maskMainlineNceTce = true;
+ __maskMainlineNceTces<T>( iv_chip );
}
}
@@ -888,7 +919,7 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
io_sc.service_data->setServiceCall();
// Permanently mask mainline NCEs and TCEs.
- getMcaDataBundle(iv_chip)->iv_maskMainlineNceTce = true;
+ __maskMainlineNceTces<T>( iv_chip );
}
// If analysis resulted in a false alarm.
@@ -903,18 +934,18 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
}
// Write any updates to VPD.
- o_rc = setBadDqBitmap( mcaTrgt, iv_rank, dqBitmap );
+ o_rc = setBadDqBitmap( trgt, iv_rank, dqBitmap );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "setBadDqBitmap(0x%08x, 0x%02x) failed",
- getHuid(mcaTrgt), iv_rank.getKey() );
+ getHuid(trgt), iv_rank.getKey() );
break;
}
// We may have placed a chip mark so do any necessary cleanup. This must
// be called after writing the bad DQ bitmap because the this function
// will also write it if necessary.
- o_rc = MarkStore::chipMarkCleanup<TYPE_MCA>( iv_chip, iv_rank, io_sc );
+ o_rc = MarkStore::chipMarkCleanup<T>( iv_chip, iv_rank, io_sc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "MarkStore::chipMarkCleanup(0x%08x,0x%02x) "
@@ -929,6 +960,15 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
#undef PRDF_FUNC
}
+template
+uint32_t TpsEvent<TYPE_MCA>::analyzeCeSymbolCounts( CeCount i_badDqCount,
+ CeCount i_badChipCount, CeCount i_sumAboveOneCount,
+ CeCount i_singleSymCount, STEP_CODE_DATA_STRUCT & io_sc );
+template
+uint32_t TpsEvent<TYPE_OCMB_CHIP>::analyzeCeSymbolCounts( CeCount i_badDqCount,
+ CeCount i_badChipCount, CeCount i_sumAboveOneCount,
+ CeCount i_singleSymCount, STEP_CODE_DATA_STRUCT & io_sc );
+
//------------------------------------------------------------------------------
template<>
@@ -1031,11 +1071,110 @@ uint32_t TpsEvent<TYPE_MCA>::getSymbolCeCounts( CeCount & io_badDqCount,
//------------------------------------------------------------------------------
-template <>
-uint32_t TpsEvent<TYPE_MCA>::analyzeCeStats( STEP_CODE_DATA_STRUCT & io_sc,
- bool & o_done )
+template<>
+uint32_t TpsEvent<TYPE_OCMB_CHIP>::getSymbolCeCounts( CeCount & io_badDqCount,
+ CeCount & io_badChipCount, CeCount & io_sumAboveOneCount,
+ CeCount & io_singleSymCount, STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[TpsEvent<TYPE_OCMB_CHIP>::getSymbolCeCounts] "
+
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ // Get the Bad DQ Bitmap.
+ TargetHandle_t ocmbTrgt = iv_chip->getTrgt();
+ MemDqBitmap dqBitmap;
+
+ o_rc = getBadDqBitmap( ocmbTrgt, iv_rank, dqBitmap );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "getBadDqBitmap(0x%08x,%d) failed",
+ getHuid(ocmbTrgt), iv_rank.getMaster() );
+ break;
+ }
+ std::vector<MemSymbol> bmSymList = dqBitmap.getSymbolList();
+
+ const char * reg_str = nullptr;
+ SCAN_COMM_REGISTER_CLASS * reg = nullptr;
+
+ for ( uint8_t regIdx = 0; regIdx < CE_REGS_PER_PORT; regIdx++ )
+ {
+ reg_str = ocmbCeStatReg[regIdx];
+ reg = iv_chip->getRegister( reg_str );
+
+ o_rc = reg->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() failed on %s.", reg_str );
+ break;
+ }
+ uint8_t baseSymbol = SYMBOLS_PER_CE_REG * regIdx;
+
+ for ( uint8_t i = 0; i < SYMBOLS_PER_CE_REG;
+ i += MEM_SYMBOLS_PER_NIBBLE )
+ {
+ MemUtils::MaintSymbols nibbleStats;
+
+ // Get a nibble's worth of symbols.
+ for ( uint8_t n = 0; n < MEM_SYMBOLS_PER_NIBBLE; n++ )
+ {
+ uint8_t sym = baseSymbol + (i+n);
+ PRDF_ASSERT( sym < SYMBOLS_PER_RANK );
+
+ MemUtils::SymbolData symData;
+ symData.symbol = MemSymbol::fromSymbol( ocmbTrgt, iv_rank,
+ sym, CEN_SYMBOL::ODD_SYMBOL_DQ );
+ if ( !symData.symbol.isValid() )
+ {
+ PRDF_ERR( PRDF_FUNC "MemSymbol() failed: symbol=%d",
+ sym );
+ o_rc = FAIL;
+ break;
+ }
+
+ // Any symbol set in the DRAM repairs VPD will have an
+ // automatic CE count of 0xFF
+ if ( std::find( bmSymList.begin(), bmSymList.end(),
+ symData.symbol ) != bmSymList.end() )
+ symData.count = 0xFF;
+ else
+ symData.count = reg->GetBitFieldJustified(((i+n)*8), 8);
+
+ nibbleStats.push_back( symData );
+
+ // Add all symbols with non-zero counts to the callout list.
+ if ( symData.count != 0 )
+ {
+ MemoryMru mm { ocmbTrgt, iv_rank, symData.symbol };
+ io_sc.service_data->SetCallout( mm );
+ }
+ }
+ if ( SUCCESS != o_rc ) break;
+
+ // Analyze the nibble of symbols.
+ __analyzeNibbleSyms<TYPE_OCMB_CHIP>( nibbleStats, io_badDqCount,
+ io_badChipCount, io_sumAboveOneCount, io_singleSymCount );
+
+ }
+ if ( SUCCESS != o_rc ) break;
+ }
+
+ }while(0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+
+}
+
+//------------------------------------------------------------------------------
+
+template <TARGETING::TYPE T>
+uint32_t TpsEvent<T>::analyzeCeStats( STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done )
{
- #define PRDF_FUNC "[TpsEvent<TYPE_MCA>::analyzeCeStats] "
+ #define PRDF_FUNC "[TpsEvent<T>::analyzeCeStats] "
uint32_t o_rc = SUCCESS;
@@ -1086,11 +1225,18 @@ uint32_t TpsEvent<TYPE_MCA>::analyzeCeStats( STEP_CODE_DATA_STRUCT & io_sc,
}
+template
+uint32_t TpsEvent<TYPE_MCA>::analyzeCeStats( STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done );
+template
+uint32_t TpsEvent<TYPE_OCMB_CHIP>::analyzeCeStats(STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done);
+
//------------------------------------------------------------------------------
-template<>
-uint32_t TpsEvent<TYPE_MCA>::analyzePhase( STEP_CODE_DATA_STRUCT & io_sc,
- bool & o_done )
+template<TARGETING::TYPE T>
+uint32_t TpsEvent<T>::analyzePhase( STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done )
{
#define PRDF_FUNC "[TpsEvent::analyzePhase] "
@@ -1102,11 +1248,11 @@ uint32_t TpsEvent<TYPE_MCA>::analyzePhase( STEP_CODE_DATA_STRUCT & io_sc,
// Analyze Ecc Attentions
uint32_t eccAttns;
- o_rc = checkEccFirs<TYPE_MCA>( iv_chip, eccAttns );
+ o_rc = checkEccFirs<T>( iv_chip, eccAttns );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "checkEccFirs(0x%08x) failed",
- iv_chip->getHuid() );
+ iv_chip->getHuid() );
break;
}
@@ -1135,7 +1281,7 @@ uint32_t TpsEvent<TYPE_MCA>::analyzePhase( STEP_CODE_DATA_STRUCT & io_sc,
if ( (SUCCESS == o_rc) && o_done )
{
// Clear the ECC FFDC for this master rank.
- MemDbUtils::resetEccFfdc<TYPE_MCA>( iv_chip, iv_rank, SLAVE_RANK );
+ MemDbUtils::resetEccFfdc<T>( iv_chip, iv_rank, SLAVE_RANK );
}
return o_rc;
@@ -1143,6 +1289,36 @@ uint32_t TpsEvent<TYPE_MCA>::analyzePhase( STEP_CODE_DATA_STRUCT & io_sc,
#undef PRDF_FUNC
}
+template
+uint32_t TpsEvent<TYPE_MCA>::analyzePhase( STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done );
+template
+uint32_t TpsEvent<TYPE_OCMB_CHIP>::analyzePhase( STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done );
+
+//------------------------------------------------------------------------------
+
+template<TARGETING::TYPE T>
+uint32_t TpsEvent<T>::startNextPhase( STEP_CODE_DATA_STRUCT & io_sc )
+{
+ uint32_t signature = 0;
+
+ __getNextPhase<T>( iv_chip, iv_rank, io_sc, iv_phase, signature );
+
+ PRDF_TRAC( "[TpsEvent] Starting TPS Phase %d: 0x%08x,0x%02x",
+ iv_phase, iv_chip->getHuid(), getKey() );
+
+ io_sc.service_data->AddSignatureList( iv_chip->getTrgt(), signature );
+
+ return startCmd();
+}
+
+template
+uint32_t TpsEvent<TYPE_MCA>::startNextPhase( STEP_CODE_DATA_STRUCT & io_sc );
+template
+uint32_t TpsEvent<TYPE_OCMB_CHIP>::startNextPhase(
+ STEP_CODE_DATA_STRUCT & io_sc );
+
//##############################################################################
//
// Specializations for MCA
@@ -1156,13 +1332,15 @@ uint32_t TpsEvent<TYPE_MCA>::startCmd()
uint32_t o_rc = SUCCESS;
+ #ifndef CONFIG_AXONE
+
// We don't need to set any stop-on-error conditions or thresholds for
// soft/inter/hard CEs at runtime. The design is to let the command continue
// to the end of the rank and we do diagnostics on the CE counts found in
// the per-symbol counters. Therefore, all we need to do is tell the
// hardware which CE types to count.
- mss::mcbist::stop_conditions stopCond;
+ mss::mcbist::stop_conditions<mss::mc_type::NIMBUS> stopCond;
switch ( iv_phase )
{
@@ -1190,26 +1368,67 @@ uint32_t TpsEvent<TYPE_MCA>::startCmd()
iv_chip->getHuid(), getKey() );
}
+ #endif
+
return o_rc;
#undef PRDF_FUNC
}
-//------------------------------------------------------------------------------
+//##############################################################################
+//
+// Specializations for OCMB
+//
+//##############################################################################
template<>
-uint32_t TpsEvent<TYPE_MCA>::startNextPhase( STEP_CODE_DATA_STRUCT & io_sc )
+uint32_t TpsEvent<TYPE_OCMB_CHIP>::startCmd()
{
- uint32_t signature = 0;
+ #define PRDF_FUNC "[TpsEvent::startCmd] "
- __getNextPhase<TYPE_MCA>( iv_chip, iv_rank, io_sc, iv_phase, signature );
+ uint32_t o_rc = SUCCESS;
- PRDF_TRAC( "[TpsEvent] Starting TPS Phase %d: 0x%08x,0x%02x",
- iv_phase, iv_chip->getHuid(), getKey() );
+ #ifdef CONFIG_AXONE
- io_sc.service_data->AddSignatureList( iv_chip->getTrgt(), signature );
+ // We don't need to set any stop-on-error conditions or thresholds for
+ // soft/inter/hard CEs at runtime. The design is to let the command continue
+ // to the end of the rank and we do diagnostics on the CE counts found in
+ // the per-symbol counters. Therefore, all we need to do is tell the
+ // hardware which CE types to count.
- return startCmd();
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER> stopCond;
+
+ switch ( iv_phase )
+ {
+ case TD_PHASE_1:
+ // Set the per symbol counters to count only hard CEs.
+ stopCond.set_nce_hard_symbol_count_enable(mss::ON);
+ break;
+
+ case TD_PHASE_2:
+ // Since there are not enough hard CEs to trigger a symbol mark, set
+ // the per symbol counters to count all CE types.
+ stopCond.set_nce_soft_symbol_count_enable( mss::ON);
+ stopCond.set_nce_inter_symbol_count_enable(mss::ON);
+ stopCond.set_nce_hard_symbol_count_enable( mss::ON);
+ break;
+
+ default: PRDF_ASSERT( false ); // invalid phase
+ }
+
+ // Start the time based scrub procedure on this slave rank.
+ o_rc = startTdScrub<TYPE_OCMB_CHIP>(iv_chip, iv_rank, SLAVE_RANK, stopCond);
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "startTdScrub(0x%08x,0x%2x) failed",
+ iv_chip->getHuid(), getKey() );
+ }
+
+ #endif
+
+ return o_rc;
+
+ #undef PRDF_FUNC
}
//##############################################################################
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm.C b/src/usr/diag/prdf/plat/mem/prdfMemVcm.C
index 8c3c4480a..784306baf 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemVcm.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemVcm.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -30,6 +30,8 @@
// Platform includes
#include <prdfCenMbaExtraSig.H>
+#include <hwp_wrappers.H>
+
using namespace TARGETING;
namespace PRDF
@@ -39,41 +41,16 @@ using namespace PlatServices;
//##############################################################################
//
-// Specializations for MCA
+// Generic Specializations
//
//##############################################################################
-template<>
-uint32_t VcmEvent<TYPE_MCA>::startCmd()
+template<TARGETING::TYPE T>
+uint32_t VcmEvent<T>::handlePhaseComplete( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done )
{
- #define PRDF_FUNC "[VcmEvent::startCmd] "
-
- uint32_t o_rc = SUCCESS;
-
- // No stop conditions.
- mss::mcbist::stop_conditions stopCond;
-
- // Start the time based scrub procedure on this master rank.
- o_rc = startTdScrub<TYPE_MCA>( iv_chip, iv_rank, MASTER_RANK, stopCond );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "startTdScrub(0x%08x,0x%2x) failed",
- iv_chip->getHuid(), getKey() );
- }
-
- return o_rc;
-
- #undef PRDF_FUNC
-}
-
-//------------------------------------------------------------------------------
-
-template<>
-uint32_t VcmEvent<TYPE_MCA>::handlePhaseComplete( const uint32_t & i_eccAttns,
- STEP_CODE_DATA_STRUCT & io_sc,
- bool & o_done )
-{
- #define PRDF_FUNC "[VcmEvent<TYPE_MCA>::handlePhaseComplete] "
+ #define PRDF_FUNC "[VcmEvent<T>::handlePhaseComplete] "
uint32_t o_rc = SUCCESS;
@@ -100,6 +77,49 @@ uint32_t VcmEvent<TYPE_MCA>::handlePhaseComplete( const uint32_t & i_eccAttns,
#undef PRDF_FUNC
}
+template
+uint32_t VcmEvent<TYPE_MCA>::handlePhaseComplete( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done );
+template
+uint32_t VcmEvent<TYPE_OCMB_CHIP>::handlePhaseComplete(
+ const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done );
+
+//##############################################################################
+//
+// Specializations for MCA
+//
+//##############################################################################
+
+template<>
+uint32_t VcmEvent<TYPE_MCA>::startCmd()
+{
+ #define PRDF_FUNC "[VcmEvent::startCmd] "
+
+ uint32_t o_rc = SUCCESS;
+
+ #ifndef CONFIG_AXONE
+
+ // No stop conditions.
+ mss::mcbist::stop_conditions<mss::mc_type::NIMBUS> stopCond;
+
+ // Start the time based scrub procedure on this master rank.
+ o_rc = startTdScrub<TYPE_MCA>( iv_chip, iv_rank, MASTER_RANK, stopCond );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "startTdScrub(0x%08x,0x%2x) failed",
+ iv_chip->getHuid(), getKey() );
+ }
+
+ #endif
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
//##############################################################################
//
// Specializations for MBA
@@ -448,6 +468,40 @@ uint32_t VcmEvent<TYPE_MBA>::handlePhaseComplete( const uint32_t & i_eccAttns,
#undef PRDF_FUNC
}
+//##############################################################################
+//
+// Specializations for OCMB
+//
+//##############################################################################
+
+template<>
+uint32_t VcmEvent<TYPE_OCMB_CHIP>::startCmd()
+{
+ #define PRDF_FUNC "[VcmEvent::startCmd] "
+
+ uint32_t o_rc = SUCCESS;
+
+ #ifdef CONFIG_AXONE
+
+ // No stop conditions.
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER> stopCond;
+
+ // Start the time based scrub procedure on this master rank.
+ o_rc = startTdScrub<TYPE_OCMB_CHIP>( iv_chip, iv_rank, MASTER_RANK,
+ stopCond );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "startTdScrub(0x%08x,0x%2x) failed",
+ iv_chip->getHuid(), getKey() );
+ }
+
+ #endif
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
//------------------------------------------------------------------------------
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm.H b/src/usr/diag/prdf/plat/mem/prdfMemVcm.H
index b319f910b..c712d6aa3 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemVcm.H
+++ b/src/usr/diag/prdf/plat/mem/prdfMemVcm.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -342,6 +342,9 @@ class VcmEvent : public TdEntry
#ifdef __HOSTBOOT_RUNTIME
template<>
uint32_t VcmEvent<TARGETING::TYPE_MCA>::cleanup(STEP_CODE_DATA_STRUCT & io_sc);
+template<>
+uint32_t VcmEvent<TARGETING::TYPE_OCMB_CHIP>::cleanup(
+ STEP_CODE_DATA_STRUCT & io_sc);
#endif
template<>
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C b/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C
index 26ef1d727..5ffa9a84b 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -92,6 +92,12 @@ bool __iueCheck<TYPE_MCA>( uint32_t i_eccAttns )
}
template<> inline
+bool __iueCheck<TYPE_OCMB_CHIP>( uint32_t i_eccAttns )
+{
+ return ( 0 != (i_eccAttns & MAINT_IUE) );
+}
+
+template<> inline
bool __iueCheck<TYPE_MBA>( uint32_t i_eccAttns )
{
// IUES are reported via RCE ETE on Centaur
@@ -218,6 +224,7 @@ uint32_t VcmEvent<TYPE_MBA>::startCmd()
// Avoid linker errors with the template.
template class VcmEvent<TYPE_MCA>;
template class VcmEvent<TYPE_MBA>;
+template class VcmEvent<TYPE_OCMB_CHIP>;
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C b/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C
index ca4de8e5a..e64227996 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -55,6 +55,12 @@ VcmFalseAlarm * __getFalseAlarmCounter<TYPE_MCA>( ExtensibleChip * i_chip )
}
template<>
+VcmFalseAlarm * __getFalseAlarmCounter<TYPE_OCMB_CHIP>(ExtensibleChip * i_chip)
+{
+ return getOcmbDataBundle(i_chip)->getVcmFalseAlarmCounter();
+}
+
+template<>
VcmFalseAlarm * __getFalseAlarmCounter<TYPE_MBA>( ExtensibleChip * i_chip )
{
return getMbaDataBundle(i_chip)->getVcmFalseAlarmCounter();
@@ -62,16 +68,16 @@ VcmFalseAlarm * __getFalseAlarmCounter<TYPE_MBA>( ExtensibleChip * i_chip )
//##############################################################################
//
-// Specializations for MCA
+// Generic Specializations
//
//##############################################################################
-template<>
-uint32_t VcmEvent<TYPE_MCA>::checkEcc( const uint32_t & i_eccAttns,
- STEP_CODE_DATA_STRUCT & io_sc,
- bool & o_done )
+template<TARGETING::TYPE T>
+uint32_t VcmEvent<T>::checkEcc( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done )
{
- #define PRDF_FUNC "[VcmEvent<TYPE_MCA>::checkEcc] "
+ #define PRDF_FUNC "[VcmEvent<T>::checkEcc] "
uint32_t o_rc = SUCCESS;
@@ -88,7 +94,7 @@ uint32_t VcmEvent<TYPE_MCA>::checkEcc( const uint32_t & i_eccAttns,
// At this point we don't actually have an address for the UE. The
// best we can do is get the address in which the command stopped.
MemAddr addr;
- o_rc = getMemMaintAddr<TYPE_MCA>( iv_chip, addr );
+ o_rc = getMemMaintAddr<T>( iv_chip, addr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemMaintAddr(0x%08x) failed",
@@ -96,7 +102,7 @@ uint32_t VcmEvent<TYPE_MCA>::checkEcc( const uint32_t & i_eccAttns,
break;
}
- o_rc = MemEcc::handleMemUe<TYPE_MCA>( iv_chip, addr,
+ o_rc = MemEcc::handleMemUe<T>( iv_chip, addr,
UE_TABLE::SCRUB_UE, io_sc );
if ( SUCCESS != o_rc )
{
@@ -107,7 +113,7 @@ uint32_t VcmEvent<TYPE_MCA>::checkEcc( const uint32_t & i_eccAttns,
// Because of the UE, any further TPS requests will likely have no
// effect. So ban all subsequent requests.
- MemDbUtils::banTps<TYPE_MCA>( iv_chip, addr.getRank() );
+ MemDbUtils::banTps<T>( iv_chip, addr.getRank() );
// Leave the mark in place and abort this procedure.
o_done = true; break;
@@ -118,7 +124,7 @@ uint32_t VcmEvent<TYPE_MCA>::checkEcc( const uint32_t & i_eccAttns,
io_sc.service_data->setSignature( iv_chip->getHuid(),
PRDFSIG_MaintIUE );
- o_rc = MemEcc::handleMemIue<TYPE_MCA>( iv_chip, iv_rank, io_sc );
+ o_rc = MemEcc::handleMemIue<T>( iv_chip, iv_rank, io_sc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "handleMemIue(0x%08x,0x%02x) failed",
@@ -143,6 +149,14 @@ uint32_t VcmEvent<TYPE_MCA>::checkEcc( const uint32_t & i_eccAttns,
#undef PRDF_FUNC
}
+template
+uint32_t VcmEvent<TYPE_MCA>::checkEcc( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done );
+template
+uint32_t VcmEvent<TYPE_OCMB_CHIP>::checkEcc( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done );
//------------------------------------------------------------------------------
@@ -180,6 +194,41 @@ uint32_t VcmEvent<TYPE_MCA>::cleanup( STEP_CODE_DATA_STRUCT & io_sc )
#undef PRDF_FUNC
}
+template<>
+uint32_t VcmEvent<TYPE_OCMB_CHIP>::cleanup( STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[VcmEvent::cleanup] "
+
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ o_rc = MarkStore::chipMarkCleanup<TYPE_OCMB_CHIP>( iv_chip, iv_rank,
+ io_sc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "chipMarkCleanup(0x%08x,0x%02x) failed",
+ iv_chip->getHuid(), iv_rank.getKey() );
+ break;
+ }
+
+ // The cleanup() function is called by both verified() and falseAlarm().
+ // In either case, the error log should be predictive if there has been
+ // a least one false alarm on any DRAM on this rank other than this
+ // DRAM. This is required on Nimbus because of two symbol correction,
+ // which does not exist on Centaur.
+ VcmFalseAlarm * faCntr =__getFalseAlarmCounter<TYPE_OCMB_CHIP>(iv_chip);
+ uint8_t dram = iv_mark.getSymbol().getDram();
+ if ( faCntr->queryDrams(iv_rank, dram, io_sc) )
+ io_sc.service_data->setServiceCall();
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
//##############################################################################
//
// Specializations for MBA
@@ -386,6 +435,7 @@ uint32_t VcmEvent<T>::falseAlarm( STEP_CODE_DATA_STRUCT & io_sc )
// Avoid linker errors with the template.
template class VcmEvent<TYPE_MCA>;
template class VcmEvent<TYPE_MBA>;
+template class VcmEvent<TYPE_OCMB_CHIP>;
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/plat/mem/prdfP9Mca.C b/src/usr/diag/prdf/plat/mem/prdfP9Mca.C
index 5f7efa274..fac29fce3 100644
--- a/src/usr/diag/prdf/plat/mem/prdfP9Mca.C
+++ b/src/usr/diag/prdf/plat/mem/prdfP9Mca.C
@@ -27,7 +27,6 @@
#include <iipServiceDataCollector.h>
#include <prdfExtensibleChip.H>
#include <prdfPluginMap.H>
-#include <isteps/nvdimm/nvdimm.H>
// Platform includes
#include <prdfMemDbUtils.H>
@@ -38,6 +37,10 @@
#include <prdfMemTps.H>
#endif
+#ifdef CONFIG_NVDIMM
+ #include <nvdimm.H>
+#endif
+
using namespace TARGETING;
namespace PRDF
@@ -296,18 +299,9 @@ PRDF_PLUGIN_DEFINE( nimbus_mca, MemPortFailure );
//
//##############################################################################
+#ifdef CONFIG_NVDIMM
#ifdef __HOSTBOOT_RUNTIME
-enum nvdimmRegOffset
-{
- NVDIMM_MGT_CMD1 = 0x041,
- MODULE_HEALTH = 0x0A0,
- MODULE_HEALTH_STATUS0 = 0x0A1,
- MODULE_HEALTH_STATUS1 = 0x0A2,
- ERROR_THRESHOLD_STATUS = 0x0A5,
- WARNING_THRESHOLD_STATUS = 0x0A7,
-};
-
/**
* @brief Gets a map list of which bits are set from a uint8_t bit list (7:0)
* @param i_data uint8_t bit list (7:0)
@@ -349,6 +343,7 @@ uint32_t __addBpmCallout( TargetHandle_t i_dimm,
break;
}
+ // addPartCallout will default to GARD_NULL, NO_DECONFIG
mainErrl->addPartCallout( i_dimm, HWAS::BPM_PART_TYPE,
i_priority );
@@ -362,10 +357,12 @@ uint32_t __addBpmCallout( TargetHandle_t i_dimm,
/**
* @brief Adds a callout of the cable connecting an NVDIMM to its
* backup power module (BPM)
+ * @param i_dimm The target dimm.
* @param i_priority The callout priority.
* @return FAIL if unable to get the global error log, else SUCCESS
*/
-uint32_t __addNvdimmCableCallout( HWAS::callOutPriority i_priority )
+uint32_t __addNvdimmCableCallout( TargetHandle_t i_dimm,
+ HWAS::callOutPriority i_priority )
{
#define PRDF_FUNC "[__addNvdimmCableCallout] "
@@ -382,7 +379,9 @@ uint32_t __addNvdimmCableCallout( HWAS::callOutPriority i_priority )
break;
}
- mainErrl->addProcedureCallout( HWAS::EPUB_PRC_NVDIMM_ERR, i_priority );
+ // addPartCallout will default to GARD_NULL, NO_DECONFIG
+ mainErrl->addPartCallout( i_dimm, HWAS::BPM_CABLE_PART_TYPE,
+ i_priority );
}while(0);
@@ -391,21 +390,45 @@ uint32_t __addNvdimmCableCallout( HWAS::callOutPriority i_priority )
#undef PRDF_FUNC
}
+/**
+ * @brief If a previous error has been found, add a signature to the
+ * multi-signature list, else set the primary signature.
+ * @param io_sc The step code data struct.
+ * @param i_trgt The target.
+ * @param i_errFound Whether an error has already been found or not.
+ * @param i_sig The signature to be set.
+ */
+void __addSignature( STEP_CODE_DATA_STRUCT & io_sc, TargetHandle_t i_trgt,
+ bool i_errFound, uint32_t i_sig )
+{
+ if ( i_errFound )
+ {
+ io_sc.service_data->AddSignatureList( i_trgt, i_sig );
+ }
+ else
+ {
+ io_sc.service_data->setSignature( getHuid(i_trgt), i_sig );
+ }
+}
/**
* @brief Analyze NVDIMM Health Status0 Register for errors
- * @param io_sc The step code data struct.
- * @param i_dimm The target dimm.
+ * @param io_sc The step code data struct.
+ * @param i_dimm The target dimm.
+ * @param io_errFound Whether an error has already been found or not.
* @return FAIL if unable to read register, else SUCCESS
*/
-uint32_t __analyzeHealthStatus0Reg( STEP_CODE_DATA_STRUCT & io_sc,
- TargetHandle_t i_dimm )
+uint32_t __analyzeHealthStatus0Reg(STEP_CODE_DATA_STRUCT & io_sc,
+ TargetHandle_t i_dimm, bool & io_errFound)
{
#define PRDF_FUNC "[__analyzeHealthStatus0Reg] "
uint32_t o_rc = SUCCESS;
uint8_t data = 0;
+ // Get MCA, for signatures
+ TargetHandle_t mca = getConnectedParent( i_dimm, TYPE_MCA );
+
do
{
// NVDIMM health status registers size = 1 byte
@@ -413,7 +436,7 @@ uint32_t __analyzeHealthStatus0Reg( STEP_CODE_DATA_STRUCT & io_sc,
// Read the Health Status0 Register (0xA1) 7:0
errlHndl_t errl = deviceRead( i_dimm, &data, NVDIMM_SIZE,
- DEVICE_NVDIMM_ADDRESS(MODULE_HEALTH_STATUS0) );
+ DEVICE_NVDIMM_ADDRESS(NVDIMM::i2cReg::MODULE_HEALTH_STATUS0) );
if ( errl )
{
PRDF_ERR( PRDF_FUNC "Failed to read Health Status0 Register. "
@@ -427,58 +450,66 @@ uint32_t __analyzeHealthStatus0Reg( STEP_CODE_DATA_STRUCT & io_sc,
// BIT 0: Voltage Regulator Fail
if ( bitList.count(0) )
{
- io_sc.service_data->AddSignatureList( i_dimm, PRDFSIG_VoltRegFail );
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_VoltRegFail );
// Callout NVDIMM on 1st, no gard
- io_sc.service_data->SetCallout( i_dimm, MRU_HIGH, NO_GARD );
+ io_sc.service_data->SetCallout( i_dimm, MRU_MED, NO_GARD );
+ io_errFound = true;
}
// BIT 1: VDD Lost
if ( bitList.count(1) )
{
- io_sc.service_data->AddSignatureList( i_dimm, PRDFSIG_VddLost );
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_VddLost );
// Callout NVDIMM on 1st, no gard
- io_sc.service_data->SetCallout( i_dimm, MRU_HIGH, NO_GARD );
+ io_sc.service_data->SetCallout( i_dimm, MRU_MED, NO_GARD );
+ io_errFound = true;
}
// BIT 2: VPP Lost
if ( bitList.count(2) )
{
- io_sc.service_data->AddSignatureList( i_dimm, PRDFSIG_VppLost );
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_VppLost );
// Callout NVDIMM on 1st, no gard
- io_sc.service_data->SetCallout( i_dimm, MRU_HIGH, NO_GARD );
+ io_sc.service_data->SetCallout( i_dimm, MRU_MED, NO_GARD );
+ io_errFound = true;
}
// BIT 3: VTT Lost
if ( bitList.count(3) )
{
- io_sc.service_data->AddSignatureList( i_dimm, PRDFSIG_VttLost );
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_VttLost );
// Callout NVDIMM on 1st, no gard
- io_sc.service_data->SetCallout( i_dimm, MRU_HIGH, NO_GARD );
+ io_sc.service_data->SetCallout( i_dimm, MRU_MED, NO_GARD );
+ io_errFound = true;
}
// BIT 4: DRAM not Self Refresh
if ( bitList.count(4) )
{
- io_sc.service_data->AddSignatureList( i_dimm, PRDFSIG_NotSelfRefr );
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_NotSelfRefr );
// Callout NVDIMM on 1st, no gard
- io_sc.service_data->SetCallout( i_dimm, MRU_HIGH, NO_GARD );
+ io_sc.service_data->SetCallout( i_dimm, MRU_MED, NO_GARD );
+ io_errFound = true;
}
// BIT 5: Controller HW Error
if ( bitList.count(5) )
{
- io_sc.service_data->AddSignatureList( i_dimm, PRDFSIG_CtrlHwErr );
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_CtrlHwErr );
// Callout NVDIMM on 1st, no gard
- io_sc.service_data->SetCallout( i_dimm, MRU_HIGH, NO_GARD );
+ io_sc.service_data->SetCallout( i_dimm, MRU_MED, NO_GARD );
+ io_errFound = true;
}
// BIT 6: NVM Controller Error
if ( bitList.count(6) )
{
- io_sc.service_data->AddSignatureList( i_dimm, PRDFSIG_NvmCtrlErr );
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_NvmCtrlErr );
// Callout NVDIMM on 1st, no gard
- io_sc.service_data->SetCallout( i_dimm, MRU_HIGH, NO_GARD );
+ io_sc.service_data->SetCallout( i_dimm, MRU_MED, NO_GARD );
+ io_errFound = true;
}
// BIT 7: NVM Lifetime Error
if ( bitList.count(7) )
{
- io_sc.service_data->AddSignatureList( i_dimm, PRDFSIG_NvmLifeErr );
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_NvmLifeErr );
// Callout NVDIMM on 1st, no gard
- io_sc.service_data->SetCallout( i_dimm, MRU_HIGH, NO_GARD );
+ io_sc.service_data->SetCallout( i_dimm, MRU_MED, NO_GARD );
+ io_errFound = true;
}
}while(0);
@@ -491,18 +522,22 @@ uint32_t __analyzeHealthStatus0Reg( STEP_CODE_DATA_STRUCT & io_sc,
/**
* @brief Analyze NVDIMM Health Status1 Register for errors
- * @param io_sc The step code data struct.
- * @param i_dimm The target dimm.
+ * @param io_sc The step code data struct.
+ * @param i_dimm The target dimm.
+ * @param io_errFound Whether an error has already been found or not.
* @return FAIL if unable to read register, else SUCCESS
*/
uint32_t __analyzeHealthStatus1Reg( STEP_CODE_DATA_STRUCT & io_sc,
- TargetHandle_t i_dimm )
+ TargetHandle_t i_dimm, bool & io_errFound )
{
#define PRDF_FUNC "[__analyzeHealthStatus1Reg] "
uint32_t o_rc = SUCCESS;
uint8_t data = 0;
+ // Get MCA, for signatures
+ TargetHandle_t mca = getConnectedParent( i_dimm, TYPE_MCA );
+
do
{
// NVDIMM health status registers size = 1 byte
@@ -510,7 +545,7 @@ uint32_t __analyzeHealthStatus1Reg( STEP_CODE_DATA_STRUCT & io_sc,
// Read the Health Status1 Register (0xA2) 7:0
errlHndl_t errl = deviceRead( i_dimm, &data, NVDIMM_SIZE,
- DEVICE_NVDIMM_ADDRESS(MODULE_HEALTH_STATUS1) );
+ DEVICE_NVDIMM_ADDRESS(NVDIMM::i2cReg::MODULE_HEALTH_STATUS1) );
if ( errl )
{
PRDF_ERR( PRDF_FUNC "Failed to read Health Status1 Register. "
@@ -524,83 +559,90 @@ uint32_t __analyzeHealthStatus1Reg( STEP_CODE_DATA_STRUCT & io_sc,
// BIT 0: Insufficient Energy
if ( bitList.count(0) )
{
- io_sc.service_data->AddSignatureList(i_dimm, PRDFSIG_InsuffEnergy);
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_InsuffEnergy );
// Callout BPM (backup power module) high, cable high
o_rc = __addBpmCallout( i_dimm, HWAS::SRCI_PRIORITY_HIGH );
if ( SUCCESS != o_rc ) break;
- o_rc = __addNvdimmCableCallout( HWAS::SRCI_PRIORITY_HIGH );
+ o_rc = __addNvdimmCableCallout( i_dimm, HWAS::SRCI_PRIORITY_HIGH );
if ( SUCCESS != o_rc ) break;
// Callout NVDIMM low, no gard
io_sc.service_data->SetCallout( i_dimm, MRU_LOW, NO_GARD );
+ io_errFound = true;
}
// BIT 1: Invalid Firmware
if ( bitList.count(1) )
{
- io_sc.service_data->AddSignatureList( i_dimm, PRDFSIG_InvFwErr );
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_InvFwErr );
// Callout NVDIMM on 1st, no gard
- io_sc.service_data->SetCallout( i_dimm, MRU_HIGH, NO_GARD );
+ io_sc.service_data->SetCallout( i_dimm, MRU_MED, NO_GARD );
+ io_errFound = true;
}
// BIT 2: Configuration Data Error
if ( bitList.count(2) )
{
- io_sc.service_data->AddSignatureList( i_dimm, PRDFSIG_CnfgDataErr );
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_CnfgDataErr );
// Callout NVDIMM on 1st, no gard
- io_sc.service_data->SetCallout( i_dimm, MRU_HIGH, NO_GARD );
+ io_sc.service_data->SetCallout( i_dimm, MRU_MED, NO_GARD );
+ io_errFound = true;
}
// BIT 3: No Energy Source
if ( bitList.count(3) )
{
- io_sc.service_data->AddSignatureList(i_dimm, PRDFSIG_NoEsPres);
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_NoEsPres );
// Callout BPM (backup power module) high, cable high
o_rc = __addBpmCallout( i_dimm, HWAS::SRCI_PRIORITY_HIGH );
if ( SUCCESS != o_rc ) break;
- o_rc = __addNvdimmCableCallout( HWAS::SRCI_PRIORITY_HIGH );
+ o_rc = __addNvdimmCableCallout( i_dimm, HWAS::SRCI_PRIORITY_HIGH );
if ( SUCCESS != o_rc ) break;
// Callout NVDIMM low, no gard
io_sc.service_data->SetCallout( i_dimm, MRU_LOW, NO_GARD );
+ io_errFound = true;
}
// BIT 4: Energy Policy Not Set
if ( bitList.count(4) )
{
- io_sc.service_data->AddSignatureList( i_dimm, PRDFSIG_EsPolNotSet );
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_EsPolNotSet );
// Callout FW (Level2 Support) High
io_sc.service_data->SetCallout( LEVEL2_SUPPORT, MRU_HIGH, NO_GARD );
// Callout NVDIMM low on 1st, no gard
io_sc.service_data->SetCallout( i_dimm, MRU_LOW, NO_GARD );
+ io_errFound = true;
}
// BIT 5: Energy Source HW Error
if ( bitList.count(5) )
{
- io_sc.service_data->AddSignatureList ( i_dimm, PRDFSIG_EsHwFail );
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_EsHwFail );
// Callout BPM (backup power module) high, cable high
o_rc = __addBpmCallout( i_dimm, HWAS::SRCI_PRIORITY_HIGH );
if ( SUCCESS != o_rc ) break;
- o_rc = __addNvdimmCableCallout( HWAS::SRCI_PRIORITY_HIGH );
+ o_rc = __addNvdimmCableCallout( i_dimm, HWAS::SRCI_PRIORITY_HIGH );
if ( SUCCESS != o_rc ) break;
// Callout NVDIMM low, no gard
io_sc.service_data->SetCallout( i_dimm, MRU_LOW, NO_GARD );
+ io_errFound = true;
}
// BIT 6: Energy Source Health Assessment Error
if ( bitList.count(6) )
{
- io_sc.service_data->AddSignatureList(i_dimm, PRDFSIG_EsHlthAssess);
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_EsHlthAssess);
// Callout BPM (backup power module) high, cable high
o_rc = __addBpmCallout( i_dimm, HWAS::SRCI_PRIORITY_HIGH );
if ( SUCCESS != o_rc ) break;
- o_rc = __addNvdimmCableCallout( HWAS::SRCI_PRIORITY_HIGH );
+ o_rc = __addNvdimmCableCallout( i_dimm, HWAS::SRCI_PRIORITY_HIGH );
if ( SUCCESS != o_rc ) break;
// Callout NVDIMM low, no gard
io_sc.service_data->SetCallout( i_dimm, MRU_LOW, NO_GARD );
+ io_errFound = true;
}
// BIT 7: Reserved
@@ -613,18 +655,105 @@ uint32_t __analyzeHealthStatus1Reg( STEP_CODE_DATA_STRUCT & io_sc,
}
/**
+ * @brief Reads and merges the data from two ES_TEMP registers to get the
+ * correct temperature format.
+ * @param i_dimm The target nvdimm.
+ * @param i_tempMsbReg The address of the register that contains the most
+ * significant byte of the temperature data.
+ * @param i_tempLsbReg The address of the register that contains the least
+ * significant byte of the temperature data.
+ * @param o_tempData The 16 bit temperature data.
+ * @return FAIL if unable to read register, else SUCCESS
+ */
+uint32_t __readTemp( TargetHandle_t i_dimm, uint16_t i_tempMsbReg,
+ uint16_t i_tempLsbReg, uint16_t & o_tempData )
+{
+ #define PRDF_FUNC "[__readTemp] "
+
+ /*
+ * -NOTE: Example showing how to read the temperature format:
+ * ES_TEMP1 = 0x03 (MSB: bits 15-8)
+ * ES_TEMP0 = 0x48 (LSB: bits 7-0)
+ *
+ * 0x0348 = 0000 0011 0100 1000 = 52.5 C
+ *
+ * -NOTE: bit definition:
+ * [15:13]Reserved
+ * [12]Sign 0 = positive, 1 = negative; 0°C should be expressed as positive
+ * [11] 128°C
+ * [10] 64°C
+ * [9] 32°C
+ * [8] 16°C
+ * [7] 8°C
+ * [6] 4°C
+ * [5] 2°C
+ * [4] 1°C
+ * [3] 0.5°C
+ * [2] 0.25°C
+ * [1] 0.125°C Optional for temp fields; not used for temp th fields
+ * [0]0.0625°C Optional for temp fields; not used for temp th fields
+ */
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ // NVDIMM health status registers size = 1 byte
+ size_t NVDIMM_SIZE = 1;
+ uint8_t msbData = 0;
+ uint8_t lsbData = 0;
+
+ // Read the two inputted temperature registers.
+ errlHndl_t errl = deviceRead( i_dimm, &msbData, NVDIMM_SIZE,
+ DEVICE_NVDIMM_ADDRESS(i_tempMsbReg) );
+ if ( errl )
+ {
+ PRDF_ERR( PRDF_FUNC "Failed to read ES Temperature MSB Register. "
+ "HUID: 0x%08x", getHuid(i_dimm) );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL;
+ break;
+ }
+
+ errl = deviceRead( i_dimm, &lsbData, NVDIMM_SIZE,
+ DEVICE_NVDIMM_ADDRESS(i_tempLsbReg) );
+ if ( errl )
+ {
+ PRDF_ERR( PRDF_FUNC "Failed to read ES Temperature LSB Register. "
+ "HUID: 0x%08x", getHuid(i_dimm) );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL;
+ break;
+ }
+
+ o_tempData = ((uint16_t)msbData << 8) | lsbData;
+
+ }while(0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+/**
* @brief Analyze NVDIMM Error Threshold Status Register for errors
- * @param io_sc The step code data struct.
- * @param i_dimm The target dimm.
+ * @param io_sc The step code data struct.
+ * @param i_dimm The target dimm.
+ * @param io_errFound Whether an error has already been found or not.
+ * @param o_esTempErr A flag for whether we hit an ES TEMP error or not.
* @return FAIL if unable to read register, else SUCCESS
*/
uint32_t __analyzeErrorThrStatusReg( STEP_CODE_DATA_STRUCT & io_sc,
- TargetHandle_t i_dimm )
+ TargetHandle_t i_dimm, bool & io_errFound,
+ bool & o_esTempErr )
{
#define PRDF_FUNC "[__analyzeErrorThrStatusReg] "
uint32_t o_rc = SUCCESS;
uint8_t data = 0;
+ o_esTempErr = false;
+
+ // Get MCA, for signatures
+ TargetHandle_t mca = getConnectedParent( i_dimm, TYPE_MCA );
do
{
@@ -633,7 +762,7 @@ uint32_t __analyzeErrorThrStatusReg( STEP_CODE_DATA_STRUCT & io_sc,
// Read the Error Threshold Status Register (0xA5) 7:0
errlHndl_t errl = deviceRead( i_dimm, &data, NVDIMM_SIZE,
- DEVICE_NVDIMM_ADDRESS(ERROR_THRESHOLD_STATUS) );
+ DEVICE_NVDIMM_ADDRESS(NVDIMM::i2cReg::ERROR_THRESHOLD_STATUS) );
if ( errl )
{
PRDF_ERR( PRDF_FUNC "Failed to read Error Threshold Status Reg. "
@@ -648,7 +777,7 @@ uint32_t __analyzeErrorThrStatusReg( STEP_CODE_DATA_STRUCT & io_sc,
// BIT 1: ES Lifetime Error
if ( bitList.count(1) )
{
- io_sc.service_data->AddSignatureList ( i_dimm, PRDFSIG_EsLifeErr );
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_EsLifeErr );
// Callout BPM (backup power module) high
o_rc = __addBpmCallout( i_dimm, HWAS::SRCI_PRIORITY_HIGH );
@@ -656,11 +785,60 @@ uint32_t __analyzeErrorThrStatusReg( STEP_CODE_DATA_STRUCT & io_sc,
// Callout NVDIMM low, no gard
io_sc.service_data->SetCallout( i_dimm, MRU_LOW, NO_GARD );
+ io_errFound = true;
}
// BIT 2: ES Temperature Error
if ( bitList.count(2) )
{
- io_sc.service_data->AddSignatureList( i_dimm, PRDFSIG_EsTmpErr );
+ // Sleep two seconds to avoid exiting PRD analysis faster than the
+ // ES_TEMP sample rate.
+ PlatServices::milliSleep( 2, 0 );
+
+ // Read the ES_TEMP and ES_TEMP_ERROR_HIGH_THRESHOLD values
+ uint16_t msbEsTempReg = NVDIMM::i2cReg::ES_TEMP1;
+ uint16_t lsbEsTempReg = NVDIMM::i2cReg::ES_TEMP0;
+ uint16_t esTemp = 0;
+ o_rc = __readTemp( i_dimm, msbEsTempReg, lsbEsTempReg, esTemp );
+ if ( SUCCESS != o_rc ) break;
+
+ uint16_t msbThReg = NVDIMM::i2cReg::ES_TEMP_ERROR_HIGH_THRESHOLD1;
+ uint16_t lsbThReg = NVDIMM::i2cReg::ES_TEMP_ERROR_HIGH_THRESHOLD0;
+ uint16_t esTempHighTh = 0;
+ o_rc = __readTemp( i_dimm, msbThReg, lsbThReg, esTempHighTh );
+ if ( SUCCESS != o_rc ) break;
+
+ msbThReg = NVDIMM::i2cReg::ES_TEMP_ERROR_LOW_THRESHOLD1;
+ lsbThReg = NVDIMM::i2cReg::ES_TEMP_ERROR_LOW_THRESHOLD0;
+ uint16_t esTempLowTh = 0;
+ o_rc = __readTemp( i_dimm, msbThReg, lsbThReg, esTempLowTh );
+ if ( SUCCESS != o_rc ) break;
+
+ // Check to see if the ES_TEMP is negative (bit 12)
+ bool esTempNeg = false;
+ if ( esTemp & 0x1000 ) esTempNeg = true;
+
+ // If ES_TEMP is equal or above ES_TEMP_ERROR_HIGH_THRESHOLD
+ // Just in case ES_TEMP has moved before we read it out, we'll add
+ // a 2°C margin when comparing to the threshold.
+ if ( (esTemp >= (esTempHighTh - 0x0020)) && !esTempNeg )
+ {
+ __addSignature( io_sc, mca, io_errFound,
+ PRDFSIG_EsTmpErrHigh );
+ }
+ // Else check if the error hit the low threshold, again with the
+ // same 2°C margin.
+ else if ( (esTemp <= (esTempLowTh + 0x0020)) || esTempNeg )
+ {
+ __addSignature( io_sc, mca, io_errFound,
+ PRDFSIG_EsTmpErrLow );
+ }
+ // Else the temperature must have gone back to a normal value, so
+ // we will label this as a false alarm case.
+ else
+ {
+ __addSignature( io_sc, mca, io_errFound,
+ PRDFSIG_EsTmpErrFa );
+ }
// Callout BPM (backup power module) high
o_rc = __addBpmCallout( i_dimm, HWAS::SRCI_PRIORITY_HIGH );
@@ -668,6 +846,9 @@ uint32_t __analyzeErrorThrStatusReg( STEP_CODE_DATA_STRUCT & io_sc,
// Callout NVDIMM low, no gard
io_sc.service_data->SetCallout( i_dimm, MRU_LOW, NO_GARD );
+
+ o_esTempErr = true;
+ io_errFound = true;
}
// BIT 3:7: Reserved
@@ -680,6 +861,419 @@ uint32_t __analyzeErrorThrStatusReg( STEP_CODE_DATA_STRUCT & io_sc,
}
/**
+ * @brief Adjusts the warning threshold so that future warnings are allowed
+ * to report.
+ * @param io_sc The step code data struct.
+ * @param i_dimm The target nvdimm.
+ * @param i_warnThReg The address of the relevant warning threshold register.
+ * @param i_errThReg The address of the relevant error threshold register.
+ * @param o_firstWarn Flag if this is the first warning of this type.
+ * @param o_statusErr Flag to tell if we found an error from checking the
+ * notification status register.
+ * @return FAIL if unable to read register, else SUCCESS
+ */
+uint32_t __adjustThreshold( STEP_CODE_DATA_STRUCT & io_sc,
+ TargetHandle_t i_dimm, uint16_t i_warnThReg,
+ uint16_t i_errThReg, bool & o_firstWarn,
+ bool & o_statusErr )
+{
+ #define PRDF_FUNC "[__adjustThreshold] "
+
+ uint32_t o_rc = SUCCESS;
+ uint16_t notifCmdReg = NVDIMM::i2cReg::SET_EVENT_NOTIFICATION_CMD;
+ uint16_t notifStatusReg = NVDIMM::i2cReg::SET_EVENT_NOTIFICATION_STATUS;
+ o_firstWarn = false;
+ o_statusErr = false;
+
+ do
+ {
+ // NVDIMM health status registers size = 1 byte
+ size_t NVDIMM_SIZE = 1;
+
+ // Read the corresponding warning threshold
+ uint8_t warnTh = 0;
+ errlHndl_t errl = deviceRead( i_dimm, &warnTh, NVDIMM_SIZE,
+ DEVICE_NVDIMM_ADDRESS(i_warnThReg) );
+ if ( errl )
+ {
+ PRDF_ERR( PRDF_FUNC "Failed to read Warning Threshold Reg. HUID: "
+ "0x%08x", getHuid(i_dimm) );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL;
+ break;
+ }
+
+ // Read the corresponding error threshold
+ uint8_t errTh = 0;
+ errl = deviceRead( i_dimm, &errTh, NVDIMM_SIZE,
+ DEVICE_NVDIMM_ADDRESS(i_errThReg) );
+ if ( errl )
+ {
+ PRDF_ERR( PRDF_FUNC "Failed to read Error Threshold Reg. HUID: "
+ "0x%08x", getHuid(i_dimm) );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL;
+ break;
+ }
+
+ // If the warning threshold is not set to the error threshold+1,
+ // move the threshold.
+ if ( warnTh != (errTh+1) )
+ {
+ o_firstWarn = true;
+
+ // SET_EVENT_NOTIFICATION_CMD is a write only register that is
+ // used to change the SET_EVENT_NOTIFICATION_STATUS register.
+ // The only bits within it that are used are bits 0 and 1, as such
+ // we can safely set the rest to 0. It is defined as:
+ // [0]: Persistency Notification
+ // [1]: Warning Threshold Notification
+ // [2]: Obsolete
+ // [3]: Firmware Activation Notification (Not Used)
+ // [4:7]: Reserved
+
+ // Clear SET_EVENT_NOTIFICATION_CMD bit 1 and keep bit 0 set
+ uint8_t notifCmd = 0x01;
+ errl = deviceWrite( i_dimm, &notifCmd, NVDIMM_SIZE,
+ DEVICE_NVDIMM_ADDRESS(notifCmdReg) );
+ if ( errl )
+ {
+ PRDF_ERR( PRDF_FUNC "Failed to clear Set Event Notification "
+ "Cmd Reg. HUID: 0x%08x", getHuid(i_dimm) );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL;
+ break;
+ }
+
+ // Check SET_EVENT_NOTIFICATION_STATUS to ensure everything is set
+ // as we expect and we don't see any errors.
+ uint8_t notifStat = 0;
+ errl = deviceRead( i_dimm, &notifStat, NVDIMM_SIZE,
+ DEVICE_NVDIMM_ADDRESS(notifStatusReg) );
+ if ( errl )
+ {
+ PRDF_ERR( PRDF_FUNC "Failed to read Set Event Notification "
+ "Status Reg. HUID: 0x%08x", getHuid(i_dimm) );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL;
+ break;
+ }
+ std::map<uint8_t,bool> bitList = __nvdimmGetActiveBits( notifStat );
+
+ // if Bit [1]: SET_EVENT_NOTIFICATION_ERROR = 1
+ // or Bit [2]: PERSISTENCY_ENABLED = 0
+ // or Bit [3]: WARNING_THRESHOLD_ENABLED = 1
+ if ( bitList.count(1) || !bitList.count(2) || bitList.count(3) )
+ {
+ o_statusErr = true;
+
+ // Make the log predictive and mask the fir
+ io_sc.service_data->SetThresholdMaskId(0);
+
+ // Callout the NVDIMM, no gard
+ io_sc.service_data->SetCallout( i_dimm, MRU_MED, NO_GARD );
+
+ // Send message to PHYP that save/restore may work
+ o_rc = PlatServices::nvdimmNotifyProtChange( i_dimm,
+ NVDIMM::NVDIMM_RISKY_HW_ERROR );
+ if ( SUCCESS != o_rc ) break;
+
+ break;
+ }
+
+
+ // Set the warning threshold to error threshold + 1
+ warnTh = errTh+1;
+ errl = deviceWrite( i_dimm, &warnTh, NVDIMM_SIZE,
+ DEVICE_NVDIMM_ADDRESS(i_warnThReg) );
+ if ( errl )
+ {
+ PRDF_ERR( PRDF_FUNC "Failed to write Warning Threshold Reg. "
+ "HUID: 0x%08x", getHuid(i_dimm) );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL;
+ break;
+ }
+
+ // Set SET_EVENT_NOTIFICATION_CMD bit 1 and keep bit 0 set
+ notifCmd = 0x03;
+ errl = deviceWrite( i_dimm, &notifCmd, NVDIMM_SIZE,
+ DEVICE_NVDIMM_ADDRESS(notifCmdReg) );
+ if ( errl )
+ {
+ PRDF_ERR( PRDF_FUNC "Failed to write Set Event Notification "
+ "Cmd Reg. HUID: 0x%08x", getHuid(i_dimm) );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL;
+ break;
+ }
+
+ // Recheck SET_EVENT_NOTIFICATION_STATUS to ensure everything is set
+ // as we expect and we don't see any errors.
+ errl = deviceRead( i_dimm, &notifStat, NVDIMM_SIZE,
+ DEVICE_NVDIMM_ADDRESS(notifStatusReg) );
+ if ( errl )
+ {
+ PRDF_ERR( PRDF_FUNC "Failed to read Set Event Notification "
+ "Status Reg. HUID: 0x%08x", getHuid(i_dimm) );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL;
+ break;
+ }
+ bitList = __nvdimmGetActiveBits( notifStat );
+
+ // if Bit [1]: SET_EVENT_NOTIFICATION_ERROR = 1
+ // or Bit [2]: PERSISTENCY_ENABLED = 0
+ // or Bit [3]: WARNING_THRESHOLD_ENABLED = 0
+ if ( bitList.count(1) || !bitList.count(2) || !bitList.count(3) )
+ {
+ o_statusErr = true;
+
+ // Make the log predictive and mask the fir
+ io_sc.service_data->SetThresholdMaskId(0);
+
+ // Callout the NVDIMM, no gard
+ io_sc.service_data->SetCallout( i_dimm, MRU_MED, NO_GARD );
+
+ // Send message to PHYP that save/restore may work
+ o_rc = PlatServices::nvdimmNotifyProtChange( i_dimm,
+ NVDIMM::NVDIMM_RISKY_HW_ERROR );
+ if ( SUCCESS != o_rc ) break;
+
+ break;
+ }
+ }
+ // Note: moving the threshold should clear the warning from
+ // WARNING_THRESHOLD_STATUS, which allows future warnings to report.
+
+ }while(0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+/**
+ * @brief Analyze NVDIMM Warning Threshold Status Register for errors
+ * @param io_sc The step code data struct.
+ * @param i_dimm The target dimm.
+ * @param io_errFound Whether an error has already been found or not.
+ * @return FAIL if unable to read register, else SUCCESS
+ */
+uint32_t __analyzeWarningThrStatusReg(STEP_CODE_DATA_STRUCT & io_sc,
+ TargetHandle_t i_dimm, bool & io_errFound)
+{
+ #define PRDF_FUNC "[__analyzeWarningThrStatusReg] "
+
+ uint32_t o_rc = SUCCESS;
+ uint8_t data = 0;
+
+ // Get MCA, for signatures
+ TargetHandle_t mca = getConnectedParent( i_dimm, TYPE_MCA );
+
+ do
+ {
+ // NVDIMM health status registers size = 1 byte
+ size_t NVDIMM_SIZE = 1;
+
+ // Read the Warning Threshold Status Register (0xA7) 7:0
+ errlHndl_t errl = deviceRead( i_dimm, &data, NVDIMM_SIZE,
+ DEVICE_NVDIMM_ADDRESS(NVDIMM::i2cReg::WARNING_THRESHOLD_STATUS) );
+ if ( errl )
+ {
+ PRDF_ERR( PRDF_FUNC "Failed to read Warning Threshold Status Reg. "
+ "HUID: 0x%08x", getHuid(i_dimm) );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL;
+ break;
+ }
+ std::map<uint8_t,bool> bitList = __nvdimmGetActiveBits( data );
+
+ // Analyze Bit 2 First
+ // BIT 2: ES_TEMP_WARNING
+ if ( bitList.count(2) )
+ {
+ // Sleep two seconds to avoid exiting PRD analysis faster than the
+ // ES_TEMP sample rate.
+ PlatServices::milliSleep( 2, 0 );
+
+ // Read the ES_TEMP and ES_TEMP_WARNING_HIGH_THRESHOLD values
+ uint16_t msbEsTempReg = NVDIMM::i2cReg::ES_TEMP1;
+ uint16_t lsbEsTempReg = NVDIMM::i2cReg::ES_TEMP0;
+ uint16_t esTemp = 0;
+ o_rc = __readTemp( i_dimm, msbEsTempReg, lsbEsTempReg, esTemp );
+ if ( SUCCESS != o_rc ) break;
+
+ uint16_t msbThReg = NVDIMM::i2cReg::ES_TEMP_WARNING_HIGH_THRESHOLD1;
+ uint16_t lsbThReg = NVDIMM::i2cReg::ES_TEMP_WARNING_HIGH_THRESHOLD0;
+ uint16_t esTempHighTh = 0;
+ o_rc = __readTemp( i_dimm, msbThReg, lsbThReg, esTempHighTh );
+ if ( SUCCESS != o_rc ) break;
+
+ msbThReg = NVDIMM::i2cReg::ES_TEMP_WARNING_LOW_THRESHOLD1;
+ lsbThReg = NVDIMM::i2cReg::ES_TEMP_WARNING_LOW_THRESHOLD0;
+ uint16_t esTempLowTh = 0;
+ o_rc = __readTemp( i_dimm, msbThReg, lsbThReg, esTempLowTh );
+ if ( SUCCESS != o_rc ) break;
+
+ // Check to see if the ES_TEMP is negative (bit 12)
+ bool esTempNeg = false;
+ if ( esTemp & 0x1000 ) esTempNeg = true;
+
+ // If ES_TEMP is equal or above ES_TEMP_WARNING_HIGH_THRESHOLD
+ // Just in case ES_TEMP has moved before we read it out, we'll add
+ // a 2°C margin when comparing to the threshold.
+ if ( (esTemp >= (esTempHighTh - 0x0020)) && !esTempNeg )
+ {
+ __addSignature( io_sc, mca, io_errFound,
+ PRDFSIG_EsTmpWarnHigh );
+ }
+ // Else check if the warning hit the low threshold, again with the
+ // same 2°C margin.
+ else if ( (esTemp <= (esTempLowTh + 0x0020)) || esTempNeg )
+ {
+ __addSignature( io_sc, mca, io_errFound,
+ PRDFSIG_EsTmpWarnLow );
+ }
+ // Else the temperature must have gone back to a normal value, so
+ // we will label this as a false alarm case.
+ else
+ {
+ __addSignature( io_sc, mca, io_errFound,
+ PRDFSIG_EsTmpWarnFa );
+ }
+
+ // Callout BPM (backup power module) high
+ o_rc = __addBpmCallout( i_dimm, HWAS::SRCI_PRIORITY_HIGH );
+ if ( SUCCESS != o_rc ) break;
+
+ // Callout NVDIMM low, no gard
+ io_sc.service_data->SetCallout( i_dimm, MRU_LOW, NO_GARD );
+
+ // Because of the possibility of intermittent ES temperature
+ // false alarm readings, we will keep the log hidden. If there is
+ // an actual ES temperature problem, we assume we will continue
+ // to be called to handle the temperature warning and hit threshold.
+
+ // Only send the save/restore message to PHYP if we hit threshold.
+ if ( io_sc.service_data->IsAtThreshold() )
+ {
+ // Send message to PHYP that save/restore may work
+ o_rc = PlatServices::nvdimmNotifyProtChange( i_dimm,
+ NVDIMM::NVDIMM_RISKY_HW_ERROR );
+ if ( SUCCESS != o_rc ) break;
+ }
+
+ io_errFound = true;
+ }
+ // BIT 0: NVM_LIFETIME_WARNING
+ if ( bitList.count(0) )
+ {
+ // Adjust warning threshold.
+ uint16_t warnThReg = NVDIMM::i2cReg::NVM_LIFETIME_WARNING_THRESHOLD;
+ uint16_t errThReg = NVDIMM::i2cReg::NVM_LIFETIME_ERROR_THRESHOLD;
+ bool firstWarn = false;
+ bool statusErr = false;
+ o_rc = __adjustThreshold( io_sc, i_dimm, warnThReg, errThReg,
+ firstWarn, statusErr );
+ if ( SUCCESS != o_rc ) break;
+
+ // Make the log predictive, but do not mask the FIR
+ io_sc.service_data->setServiceCall();
+
+ // If we got a set event notification status error, add the
+ // signature for that before adding the signature for the warning.
+ // Also do not take our normal callout action since we already will
+ // have called out the NVDIMM because of the status error.
+ if ( statusErr )
+ {
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_NotifStatErr );
+
+ // Need to set io_errFound here so the warning signature is
+ // added to the multi-signature list instead of as the primary
+ // signature.
+ io_errFound = true;
+ }
+ else
+ {
+ // Callout NVDIMM on 1st, no gard
+ io_sc.service_data->SetCallout( i_dimm, MRU_MED, NO_GARD );
+ }
+
+ // Update signature depending on whether this is the first or second
+ // warning of this type.
+ if ( firstWarn )
+ {
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_NvmLifeWarn1 );
+ }
+ else
+ {
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_NvmLifeWarn2 );
+ }
+
+
+ io_errFound = true;
+ }
+ // BIT 1: ES_LIFETIME_WARNING
+ if ( bitList.count(1) )
+ {
+ // Adjust warning threshold.
+ uint16_t warnThReg = NVDIMM::i2cReg::ES_LIFETIME_WARNING_THRESHOLD;
+ uint16_t errThReg = NVDIMM::i2cReg::ES_LIFETIME_ERROR_THRESHOLD;
+ bool firstWarn = false;
+ bool statusErr = false;
+ o_rc = __adjustThreshold( io_sc, i_dimm, warnThReg, errThReg,
+ firstWarn, statusErr );
+ if ( SUCCESS != o_rc ) break;
+
+ // Make the log predictive, but do not mask the FIR
+ io_sc.service_data->setServiceCall();
+
+ // If we got a set event notification status error, add the
+ // signature for that before adding the signature for the warning.
+ // Also do not take our normal callout action since we already will
+ // have called out the NVDIMM because of the status error.
+ if ( statusErr )
+ {
+ __addSignature( io_sc, mca, io_errFound, PRDFSIG_NotifStatErr );
+
+ // Need to set io_errFound here so the warning signature is
+ // added to the multi-signature list instead of as the primary
+ // signature.
+ io_errFound = true;
+ }
+ else
+ {
+ // Callout BPM (backup power module) high
+ o_rc = __addBpmCallout( i_dimm, HWAS::SRCI_PRIORITY_HIGH );
+ if ( SUCCESS != o_rc ) break;
+
+ // Callout NVDIMM low, no gard
+ io_sc.service_data->SetCallout( i_dimm, MRU_LOW, NO_GARD );
+ }
+
+ // Update signature depending on whether this is the first or second
+ // warning of this type.
+ if ( firstWarn )
+ {
+ __addSignature(io_sc, mca, io_errFound, PRDFSIG_EsLifeWarn1);
+ }
+ else
+ {
+ __addSignature(io_sc, mca, io_errFound, PRDFSIG_EsLifeWarn2);
+ }
+
+ io_errFound = true;
+ }
+
+ }while(0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+/**
* @brief De-assert the EVENT_N pin by setting bit 2 in NVDIMM_MGT_CMD1 (0x41)
* @param i_dimm The target dimm.
* @return FAIL if unable to read/write register, else SUCCESS
@@ -698,7 +1292,7 @@ uint32_t __deassertEventN( TargetHandle_t i_dimm )
// Read the NVDIMM_MGT_CMD1 register (0x41) 7:0
errlHndl_t errl = deviceRead( i_dimm, &data, NVDIMM_SIZE,
- DEVICE_NVDIMM_ADDRESS(NVDIMM_MGT_CMD1) );
+ DEVICE_NVDIMM_ADDRESS(NVDIMM::i2cReg::NVDIMM_MGT_CMD1) );
if ( errl )
{
PRDF_ERR( PRDF_FUNC "Failed to read NVDIMM_MGT_CMD1. "
@@ -713,7 +1307,7 @@ uint32_t __deassertEventN( TargetHandle_t i_dimm )
// Write the updated data back to NVDIMM_MGT_CMD1
errl = deviceWrite( i_dimm, &data, NVDIMM_SIZE,
- DEVICE_NVDIMM_ADDRESS(NVDIMM_MGT_CMD1) );
+ DEVICE_NVDIMM_ADDRESS(NVDIMM::i2cReg::NVDIMM_MGT_CMD1) );
if ( errl )
{
PRDF_ERR( PRDF_FUNC "Failed to write NVDIMM_MGT_CMD1. "
@@ -732,6 +1326,7 @@ uint32_t __deassertEventN( TargetHandle_t i_dimm )
}
#endif // HOSTBOOT_RUNTIME
+#endif // CONFIG_NVDIMM
/**
* @brief MCACALFIR[8] - Error from NVDIMM health status registers
@@ -744,13 +1339,28 @@ int32_t AnalyzeNvdimmHealthStatRegs( ExtensibleChip * i_chip,
{
#define PRDF_FUNC "[nimbus_mca::AnalyzeNvdimmHealthStatRegs] "
+ #ifdef CONFIG_NVDIMM
#ifdef __HOSTBOOT_RUNTIME
uint32_t l_rc = SUCCESS;
+ bool errFound = false;
// We need to check both dimms for errors
for ( auto & dimm : getConnected(i_chip->getTrgt(), TYPE_DIMM) )
{
+ // Skip any non-NVDIMMs
+ if ( !isNVDIMM(dimm) ) continue;
+
+ // Add SMART-specific, page 4 registers to FFDC
+ errlHndl_t mainErrl = nullptr;
+ mainErrl = ServiceGeneratorClass::ThisServiceGenerator().getErrl();
+ if ( nullptr == mainErrl )
+ {
+ PRDF_ERR( PRDF_FUNC "Failed to get the global error log." );
+ continue;
+ }
+ PlatServices::nvdimmAddFfdc( dimm, mainErrl );
+
// De-assert the EVENT_N pin by setting bit 2 in NVDIMM_MGT_CMD1
l_rc = __deassertEventN( dimm );
if ( SUCCESS != l_rc ) continue;
@@ -762,7 +1372,7 @@ int32_t AnalyzeNvdimmHealthStatRegs( ExtensibleChip * i_chip,
// Read the Module Health Register (0xA0) 7:0
errlHndl_t errl = deviceRead( dimm, &data, NVDIMM_SIZE,
- DEVICE_NVDIMM_ADDRESS(MODULE_HEALTH) );
+ DEVICE_NVDIMM_ADDRESS(NVDIMM::i2cReg::MODULE_HEALTH) );
if ( errl )
{
PRDF_ERR( PRDF_FUNC "Failed to read Module Health Register. "
@@ -775,6 +1385,30 @@ int32_t AnalyzeNvdimmHealthStatRegs( ExtensibleChip * i_chip,
// BIT 0: Persistency Lost
if ( bitList.count(0) )
{
+ // Analyze Health Status0 Reg, Health Status1 Reg,
+ // and Error Theshold Status Reg
+ l_rc = __analyzeHealthStatus0Reg( io_sc, dimm, errFound );
+ if ( SUCCESS != l_rc ) continue;
+ l_rc = __analyzeHealthStatus1Reg( io_sc, dimm, errFound );
+ if ( SUCCESS != l_rc ) continue;
+ bool esTempErr = false;
+ l_rc = __analyzeErrorThrStatusReg(io_sc, dimm, errFound, esTempErr);
+ if ( SUCCESS != l_rc ) continue;
+
+ // If we hit an ES temperature error and have not yet hit threshold,
+ // then keep the log hidden.
+ if ( esTempErr && !io_sc.service_data->IsAtThreshold() ) continue;
+
+ // If we didn't find any error, then keep the log hidden.
+ if ( !errFound )
+ {
+ io_sc.service_data->setSignature( i_chip->getHuid(),
+ PRDFSIG_FirEvntGone );
+ // Callout NVDIMM
+ io_sc.service_data->SetCallout( dimm, MRU_MED, NO_GARD );
+ continue;
+ }
+
// EVENT_N cannot be retriggered on a new PERSISTENCY_LOST_ERROR
// if a previous PERSISTENCY_LOST_ERROR still exists. Meaning, we
// cannot detect/report multiple errors that happen at different
@@ -782,43 +1416,77 @@ int32_t AnalyzeNvdimmHealthStatRegs( ExtensibleChip * i_chip,
// and make the log predictive.
io_sc.service_data->SetThresholdMaskId(0);
- // Send persistency lost message to PHYP
- l_rc = PlatServices::nvdimmNotifyPhypProtChange( dimm,
- NVDIMM::UNPROTECTED_BECAUSE_ERROR );
+ // Send message to PHYP that save/restore may work
+ l_rc = PlatServices::nvdimmNotifyProtChange( dimm,
+ NVDIMM::NVDIMM_RISKY_HW_ERROR );
if ( SUCCESS != l_rc ) continue;
- // Analyze Health Status0 Reg, Health Status1 Reg,
- // and Error Theshold Status Reg
- l_rc = __analyzeHealthStatus0Reg( io_sc, dimm );
- if ( SUCCESS != l_rc ) continue;
- l_rc = __analyzeHealthStatus1Reg( io_sc, dimm );
- if ( SUCCESS != l_rc ) continue;
- l_rc = __analyzeErrorThrStatusReg( io_sc, dimm );
+ }
+ // BIT 1: Warning Threshold Exceeded
+ else if ( bitList.count(1) )
+ {
+ l_rc = __analyzeWarningThrStatusReg( io_sc, dimm, errFound );
if ( SUCCESS != l_rc ) continue;
+
+ if ( !errFound )
+ {
+ io_sc.service_data->setSignature( i_chip->getHuid(),
+ PRDFSIG_FirEvntGone );
+ // Callout NVDIMM
+ io_sc.service_data->SetCallout( dimm, MRU_MED, NO_GARD );
+ continue;
+ }
}
- // BIT 1: Warning Threshold Exceeded -- ignore
// BIT 2: Persistency Restored
- if ( bitList.count(2) )
+ else if ( bitList.count(2) )
{
// It would be rare to have an intermittent error that comes and
// goes so fast we only see PERSISTENCY_RESTORED and not
// PERSISTENCY_LOST_ERROR. Set predictive on threshold of 32
// per day (rule code handles the thresholding), else just keep
// as a hidden log.
- io_sc.service_data->AddSignatureList( dimm, PRDFSIG_NvdimmPersRes );
+ __addSignature( io_sc, i_chip->getTrgt(), errFound,
+ PRDFSIG_NvdimmPersRes );
+
+ // Callout NVDIMM
+ io_sc.service_data->SetCallout( dimm, MRU_MED, NO_GARD );
+ }
+ // BIT 3: Below Warning Threshold
+ else if ( bitList.count(3) )
+ {
+ // Much like the persistency restored bit above, we don't expect
+ // to see this, so just make a hidden log.
+ __addSignature( io_sc, i_chip->getTrgt(), errFound,
+ PRDFSIG_BelowWarnTh );
+
+ // Callout NVDIMM
+ io_sc.service_data->SetCallout( dimm, MRU_MED, NO_GARD );
+ }
+ // BIT 4: Hardware Failure -- ignore - no logic feeding this
+ // BIT 5: EVENT_N_LOW -- ignore
+ // BIT 6:7: Unused
+
+ // If we reach a threshold on MCACALFIR[8] of 32 per day, we assume
+ // some intermittent error must be triggering the FIR that isn't a
+ // persistency lost error which would cause us to mask. The rule code
+ // handles the actual thresholding here.
+ if ( io_sc.service_data->IsAtThreshold() && !errFound )
+ {
+ io_sc.service_data->setSignature( i_chip->getHuid(),
+ PRDFSIG_IntNvdimmErr );
// callout NVDIMM high, cable high, BPM high, no gard
io_sc.service_data->SetCallout( dimm, MRU_HIGH, NO_GARD );
l_rc = __addBpmCallout( dimm, HWAS::SRCI_PRIORITY_HIGH );
if ( SUCCESS != l_rc ) continue;
- l_rc = __addNvdimmCableCallout( HWAS::SRCI_PRIORITY_HIGH );
+ l_rc = __addNvdimmCableCallout( dimm, HWAS::SRCI_PRIORITY_HIGH );
if ( SUCCESS != l_rc ) continue;
- }
- // BIT 3: Below Warning Threshold -- ignore
- // BIT 4: Hardware Failure -- ignore
- // BIT 5: EVENT_N_LOW -- ignore
- // BIT 6:7: Unused
+ // Send message to PHYP that save/restore may work
+ l_rc = PlatServices::nvdimmNotifyProtChange( dimm,
+ NVDIMM::NVDIMM_RISKY_HW_ERROR );
+ if ( SUCCESS != l_rc ) continue;
+ }
}
#else // IPL only
@@ -826,7 +1494,14 @@ int32_t AnalyzeNvdimmHealthStatRegs( ExtensibleChip * i_chip,
PRDF_ERR( PRDF_FUNC "Unexpected call to analyze NVDIMMs at IPL." );
io_sc.service_data->SetCallout( LEVEL2_SUPPORT, MRU_HIGH, NO_GARD );
- #endif
+ #endif // end runtime vs IPL check
+
+ #else // CONFIG_NVDIMM not defined
+
+ PRDF_ERR( PRDF_FUNC "CONFIG_NVDIMM not defined." );
+ io_sc.service_data->SetCallout( LEVEL2_SUPPORT, MRU_HIGH, NO_GARD );
+
+ #endif // end CONFIG_NVDIMM check
return SUCCESS; // nothing to return to rule code
diff --git a/src/usr/diag/prdf/plat/mem/prdfP9Mcbist.C b/src/usr/diag/prdf/plat/mem/prdfP9Mcbist.C
index 4a4391c0c..0e11b1a86 100644
--- a/src/usr/diag/prdf/plat/mem/prdfP9Mcbist.C
+++ b/src/usr/diag/prdf/plat/mem/prdfP9Mcbist.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -301,9 +301,9 @@ int32_t commandAddrTimeout( ExtensibleChip * i_chip,
// was executed. Restarting the command will likely fail with the same
// issue. Callout and gard all MCAs in which the command was executed.
- std::vector<ExtensibleChip *> mcaList;
+ ExtensibleChipList mcaList;
- if ( SUCCESS != getMcbistMaintPort(i_chip, mcaList) )
+ if ( SUCCESS != getMcbistMaintPort<TYPE_MCBIST>(i_chip, mcaList) )
{
PRDF_ERR( PRDF_FUNC "getMcbistMaintPort(0x%08x) failed",
i_chip->getHuid() );
diff --git a/src/usr/diag/prdf/plat/mem/prdfP9McbistDataBundle.H b/src/usr/diag/prdf/plat/mem/prdfP9McbistDataBundle.H
index 4a284253a..44ef77ec7 100644
--- a/src/usr/diag/prdf/plat/mem/prdfP9McbistDataBundle.H
+++ b/src/usr/diag/prdf/plat/mem/prdfP9McbistDataBundle.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,6 +36,7 @@
// Platform includes
#include <prdfMemTdCtlr.H>
#include <prdfPlatServices.H>
+#include <prdfThresholdUtils.H>
namespace PRDF
{
@@ -81,6 +82,24 @@ class McbistDataBundle : public DataBundle
/** The Targeted Diagnostics controller. */
MemTdCtlr<TARGETING::TYPE_MCBIST> * iv_tdCtlr = nullptr;
+
+ public: // instance variables
+ #ifdef __HOSTBOOT_RUNTIME
+
+ // These are used to limit the number of times a scrub command will stop
+ // on a UE or CE on a rank. This is to prevent potential flooding of
+ // maintenance UEs or CEs. The threshold will be 16 per rank for each.
+ TimeBasedThreshold iv_ueStopCounter =
+ TimeBasedThreshold( 16, ThresholdResolution::TEN_HOURS );
+ TimeBasedThreshold iv_ceStopCounter =
+ TimeBasedThreshold( 16, ThresholdResolution::TEN_HOURS );
+
+ // If we stop on a UE or a CE, we will need to store the rank that the
+ // error is on so that we can clear our respective thresholds if the
+ // next error we stop on is on a different rank.
+ MemRank iv_ceUeRank;
+
+ #endif
};
/**
diff --git a/src/usr/diag/prdf/plat/mem/prdfRestoreDramRepairs.C b/src/usr/diag/prdf/plat/mem/prdfRestoreDramRepairs.C
index ef3a143eb..fc389000a 100644
--- a/src/usr/diag/prdf/plat/mem/prdfRestoreDramRepairs.C
+++ b/src/usr/diag/prdf/plat/mem/prdfRestoreDramRepairs.C
@@ -99,7 +99,7 @@ void commitErrl( errlHndl_t i_errl, TargetHandle_t i_trgt )
template<TARGETING::TYPE T>
void __calloutDimm( errlHndl_t & io_errl, TargetHandle_t i_portTrgt,
- TargetHandle_t i_dimmTrgt )
+ TargetHandle_t i_dimmTrgt, bool i_nvdimmNoGard = false )
{
#define PRDF_FUNC "[RDR::__calloutDimm] "
@@ -109,9 +109,31 @@ void __calloutDimm( errlHndl_t & io_errl, TargetHandle_t i_portTrgt,
PRDF_ASSERT( nullptr != i_dimmTrgt );
PRDF_ASSERT( TYPE_DIMM == getTargetType(i_dimmTrgt) );
- // Callout the DIMM.
+ HWAS::DeconfigEnum deconfigPolicy = HWAS::DELAYED_DECONFIG;
+ HWAS::GARD_ErrorType gardPolicy = HWAS::GARD_Predictive;
+
+ #ifdef CONFIG_NVDIMM
+ // For the "RDR: All repairs used" case, If the DIMM is an NVDIMM, change
+ // the gard and deconfig options to no gard/deconfig and call
+ // nvdimmNotifyProtChange to indicate a save/restore may work.
+ if ( i_nvdimmNoGard )
+ {
+ deconfigPolicy = HWAS::NO_DECONFIG;
+ gardPolicy = HWAS::GARD_NULL;
+
+ uint32_t l_rc = PlatServices::nvdimmNotifyProtChange( i_dimmTrgt,
+ NVDIMM::NVDIMM_RISKY_HW_ERROR );
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_TRAC( PRDF_FUNC "nvdimmNotifyProtChange(0x%08x) "
+ "failed.", PlatServices::getHuid(i_dimmTrgt) );
+ }
+ }
+ #endif
+
io_errl->addHwCallout( i_dimmTrgt, HWAS::SRCI_PRIORITY_HIGH,
- HWAS::DELAYED_DECONFIG, HWAS::GARD_Predictive );
+ deconfigPolicy, gardPolicy );
+
// Clear the VPD on this DIMM. The DIMM has been garded, but it is possible
// the customer will want to ungard the DIMM. Without clearing the VPD, the
@@ -120,16 +142,20 @@ void __calloutDimm( errlHndl_t & io_errl, TargetHandle_t i_portTrgt,
// customer takes the risk of ungarding the DIMM (that they should replace),
// the repairs will need to be rediscovered.
- std::vector<MemRank> ranks;
- getMasterRanks<T>( i_portTrgt, ranks, getDimmSlct(i_dimmTrgt) );
-
- for ( auto & rank : ranks )
+ // Do not clear the VPD if we had an NVDIMM that we avoided garding.
+ if ( !i_nvdimmNoGard )
{
- if ( SUCCESS != clearBadDqBitmap(i_portTrgt, rank) )
+ std::vector<MemRank> ranks;
+ getMasterRanks<T>( i_portTrgt, ranks, getDimmSlct(i_dimmTrgt) );
+
+ for ( auto & rank : ranks )
{
- PRDF_ERR( PRDF_FUNC "clearBadDqBitmap(0x%08x,0x%02x) failed",
- getHuid(i_portTrgt), rank.getKey() );
- continue;
+ if ( SUCCESS != clearBadDqBitmap(i_portTrgt, rank) )
+ {
+ PRDF_ERR( PRDF_FUNC "clearBadDqBitmap(0x%08x,0x%02x) failed",
+ getHuid(i_portTrgt), rank.getKey() );
+ continue;
+ }
}
}
@@ -156,11 +182,7 @@ void commitSoftError( uint32_t i_reasonCode, TargetHandle_t i_trgt,
//------------------------------------------------------------------------------
template<TARGETING::TYPE T>
-bool processRepairedRanks( TargetHandle_t i_trgt, uint8_t i_repairedRankMask );
-
-template<>
-bool processRepairedRanks<TYPE_MCA>( TargetHandle_t i_trgt,
- uint8_t i_repairedRankMask )
+bool processRepairedRanks( TargetHandle_t i_trgt, uint8_t i_repairedRankMask )
{
#define PRDF_FUNC "[processRepairedRanks] "
@@ -179,7 +201,7 @@ bool processRepairedRanks<TYPE_MCA>( TargetHandle_t i_trgt,
// map value has no significance.
std::map<TargetHandle_t, uint32_t> calloutList;
- ExtensibleChip * mcaChip = (ExtensibleChip *)systemPtr->GetChip(i_trgt);
+ ExtensibleChip * chip = (ExtensibleChip *)systemPtr->GetChip(i_trgt);
for ( uint8_t r = 0; r < MASTER_RANKS_PER_PORT; ++r )
{
@@ -191,20 +213,18 @@ bool processRepairedRanks<TYPE_MCA>( TargetHandle_t i_trgt,
MemRank rank ( r );
MemMark cm;
- if ( SUCCESS != MarkStore::readChipMark<TYPE_MCA>( mcaChip, rank,
- cm ) )
+ if ( SUCCESS != MarkStore::readChipMark<T>( chip, rank, cm ) )
{
- PRDF_ERR( PRDF_FUNC "readChipMark<TYPE_MCA>(0x%08x,0x%02x) "
- "failed", mcaChip->getHuid(), rank.getKey() );
+ PRDF_ERR( PRDF_FUNC "readChipMark<T>(0x%08x,0x%02x) "
+ "failed", chip->getHuid(), rank.getKey() );
continue; // skip this rank
}
MemMark sm;
- if ( SUCCESS != MarkStore::readSymbolMark<TYPE_MCA>( mcaChip, rank,
- sm ) )
+ if ( SUCCESS != MarkStore::readSymbolMark<T>( chip, rank, sm ) )
{
- PRDF_ERR( PRDF_FUNC "readSymbolMark<TYPE_MCA>(0x%08x,0x%02x) "
- "failed", mcaChip->getHuid(), rank.getKey() );
+ PRDF_ERR( PRDF_FUNC "readSymbolMark<T>(0x%08x,0x%02x) "
+ "failed", chip->getHuid(), rank.getKey() );
continue; // skip this rank
}
@@ -214,9 +234,8 @@ bool processRepairedRanks<TYPE_MCA>( TargetHandle_t i_trgt,
if ( NULL == errl )
{
- errl = createErrl<TYPE_MCA>( PRDF_DETECTED_FAIL_HARDWARE,
- i_trgt,
- PRDFSIG_RdrRepairsUsed );
+ errl = createErrl<T>( PRDF_DETECTED_FAIL_HARDWARE,
+ i_trgt, PRDFSIG_RdrRepairsUsed );
}
std::vector<MemSymbol> symList;
@@ -246,16 +265,21 @@ bool processRepairedRanks<TYPE_MCA>( TargetHandle_t i_trgt,
// Callout all DIMMs in the map.
for ( auto const & dimm : calloutList )
{
- __calloutDimm<TYPE_MCA>( errl, i_trgt, dimm.first );
+ bool nvdimmNoGard = false;
+ #ifdef CONFIG_NVDIMM
+ if ( isNVDIMM(dimm.first) ) nvdimmNoGard = true;
+ #endif
+
+ __calloutDimm<T>( errl, i_trgt, dimm.first, nvdimmNoGard );
}
// Commit the error log, if needed.
- commitErrl<TYPE_MCA>( errl, i_trgt );
+ commitErrl<T>( errl, i_trgt );
// Commit an additional error log indicating something failed in the
// analysis, if needed.
- commitSoftError<TYPE_MCA>( PRDF_DETECTED_FAIL_SOFTWARE, i_trgt,
- PRDFSIG_RdrInternalFail, analysisErrors );
+ commitSoftError<T>( PRDF_DETECTED_FAIL_SOFTWARE, i_trgt,
+ PRDFSIG_RdrInternalFail, analysisErrors );
}while(0);
return o_calloutMade;
@@ -263,6 +287,14 @@ bool processRepairedRanks<TYPE_MCA>( TargetHandle_t i_trgt,
#undef PRDF_FUNC
}
+
+template
+bool processRepairedRanks<TYPE_MCA>( TargetHandle_t i_trgt,
+ uint8_t i_repairedRankMask );
+template
+bool processRepairedRanks<TYPE_OCMB_CHIP>( TargetHandle_t i_trgt,
+ uint8_t i_repairedRankMask );
+
//------------------------------------------------------------------------------
template<>
@@ -368,7 +400,12 @@ bool processRepairedRanks<TYPE_MBA>( TargetHandle_t i_trgt,
// Callout all DIMMs in the map.
for ( auto const & dimm : calloutList )
{
- __calloutDimm<TYPE_MBA>( errl, i_trgt, dimm.first );
+ bool nvdimmNoGard = false;
+ #ifdef CONFIG_NVDIMM
+ if ( isNVDIMM(dimm.first) ) nvdimmNoGard = true;
+ #endif
+
+ __calloutDimm<TYPE_MBA>(errl, i_trgt, dimm.first, nvdimmNoGard);
}
o_calloutMade = true;
@@ -392,10 +429,7 @@ bool processRepairedRanks<TYPE_MBA>( TargetHandle_t i_trgt,
template<TARGETING::TYPE T>
-bool processBadDimms( TargetHandle_t i_trgt, uint8_t i_badDimmMask );
-
-template<>
-bool processBadDimms<TYPE_MCA>( TargetHandle_t i_trgt, uint8_t i_badDimmMask )
+bool processBadDimms( TargetHandle_t i_trgt, uint8_t i_badDimmMask )
{
#define PRDF_FUNC "[processBadDimms] "
@@ -421,29 +455,35 @@ bool processBadDimms<TYPE_MCA>( TargetHandle_t i_trgt, uint8_t i_badDimmMask )
{
if ( NULL == errl )
{
- errl = createErrl<TYPE_MCA>( PRDF_DETECTED_FAIL_HARDWARE,
- i_trgt, PRDFSIG_RdrRepairUnavail );
+ errl = createErrl<T>( PRDF_DETECTED_FAIL_HARDWARE,
+ i_trgt, PRDFSIG_RdrRepairUnavail );
}
- __calloutDimm<TYPE_MCA>( errl, i_trgt, dimm );
+ __calloutDimm<T>( errl, i_trgt, dimm );
o_calloutMade = true;
}
}
// Commit the error log, if needed.
- commitErrl<TYPE_MCA>( errl, i_trgt );
+ commitErrl<T>( errl, i_trgt );
// Commit an additional error log indicating something failed in the
// analysis, if needed.
- commitSoftError<TYPE_MCA>( PRDF_DETECTED_FAIL_SOFTWARE, i_trgt,
- PRDFSIG_RdrInternalFail, analysisErrors );
+ commitSoftError<T>( PRDF_DETECTED_FAIL_SOFTWARE, i_trgt,
+ PRDFSIG_RdrInternalFail, analysisErrors );
return o_calloutMade;
#undef PRDF_FUNC
}
+template
+bool processBadDimms<TYPE_MCA>( TargetHandle_t i_trgt, uint8_t i_badDimmMask );
+template
+bool processBadDimms<TYPE_OCMB_CHIP>( TargetHandle_t i_trgt,
+ uint8_t i_badDimmMask );
+
//------------------------------------------------------------------------------
template<>
@@ -580,6 +620,25 @@ void deployDramSpares<TYPE_MBA>( TargetHandle_t i_trgt,
}
}
+template<>
+void deployDramSpares<TYPE_OCMB_CHIP>( TargetHandle_t i_trgt,
+ const std::vector<MemRank> & i_ranks )
+{
+ for ( auto & rank : i_ranks )
+ {
+ MemSymbol sym = MemSymbol::fromSymbol( i_trgt, rank, 71 );
+
+ int32_t l_rc = mssSetSteerMux<TYPE_OCMB_CHIP>(i_trgt, rank, sym, false);
+ if ( SUCCESS != l_rc )
+ {
+ // mssSetSteerMux() will print a trace and commit the error log,
+ // however, we need to handle the return code or we get a compile
+ // warning in Hostboot.
+ continue;
+ }
+ }
+}
+
} // end namespace RDR
//------------------------------------------------------------------------------
@@ -680,6 +739,8 @@ template
uint32_t restoreDramRepairs<TYPE_MCA>( TargetHandle_t i_trgt );
template
uint32_t restoreDramRepairs<TYPE_MBA>( TargetHandle_t i_trgt );
+template
+uint32_t restoreDramRepairs<TYPE_OCMB_CHIP>( TargetHandle_t i_trgt );
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices.C b/src/usr/diag/prdf/plat/prdfPlatServices.C
index 8c17c2fd9..0ad247134 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices.C
+++ b/src/usr/diag/prdf/plat/prdfPlatServices.C
@@ -40,6 +40,8 @@
#include <prdfRegisterCache.H>
#include <prdfCenMbaDataBundle.H>
+#include <prdfP9McbistDataBundle.H>
+#include <prdfOcmbDataBundle.H>
#include <prdfMemScrubUtils.H>
#include <iipServiceDataCollector.h>
@@ -50,7 +52,7 @@
#include <time.h>
#include <initservice/initserviceif.H>
#include <devicefw/userif.H>
-#include <iipMopRegisterAccess.h>
+#include <prdfHomRegisterAccess.H>
#include <ibscomreasoncodes.H>
#include <scom/scomreasoncodes.H>
#include <p9_proc_gettracearray.H>
@@ -58,6 +60,13 @@
#include <p9c_mss_maint_cmds.H>
#include <prdfParserUtils.H>
#include <p9c_mss_rowRepairFuncs.H>
+#include <errl/errludlogregister.H>
+
+#include <hwp_wrappers.H>
+
+#ifdef CONFIG_NVDIMM
+#include <nvdimm.H>
+#endif
using namespace TARGETING;
@@ -387,31 +396,31 @@ uint32_t getMemAddrRange<TYPE_MCA>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
template<>
-uint32_t getMemAddrRange<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- mss::mcbist::address & o_startAddr,
- mss::mcbist::address & o_endAddr,
- AddrRangeType i_rangeType )
+uint32_t getMemAddrRange<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ mss::mcbist::address & o_startAddr,
+ mss::mcbist::address & o_endAddr,
+ AddrRangeType i_rangeType )
{
- #define PRDF_FUNC "[PlatServices::getMemAddrRange<TYPE_MEM_PORT>] "
+ #define PRDF_FUNC "[PlatServices::getMemAddrRange<TYPE_OCMB_CHIP>] "
- PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
+ #ifdef CONFIG_AXONE
- /* TODO RTC 207273 - no HWP support yet
- uint32_t port = i_chip->getPos() % MAX_PORT_PER_OCMB;
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+ // TODO RTC 210072 - support for multiple ports
if ( SLAVE_RANK == i_rangeType )
{
FAPI_CALL_HWP_NORETURN( mss::mcbist::address::get_srank_range,
- port, i_rank.getDimmSlct(),
+ 0, i_rank.getDimmSlct(),
i_rank.getRankSlct(), i_rank.getSlave(),
o_startAddr, o_endAddr );
}
else if ( MASTER_RANK == i_rangeType )
{
FAPI_CALL_HWP_NORETURN( mss::mcbist::address::get_mrank_range,
- port, i_rank.getDimmSlct(),
+ 0, i_rank.getDimmSlct(),
i_rank.getRankSlct(), o_startAddr, o_endAddr );
}
else
@@ -419,7 +428,8 @@ uint32_t getMemAddrRange<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
PRDF_ERR( PRDF_FUNC "unsupported range type %d", i_rangeType );
PRDF_ASSERT(false);
}
- */
+
+ #endif
return SUCCESS;
@@ -520,15 +530,15 @@ uint32_t getMemAddrRange<TYPE_MCA>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
template<>
-uint32_t getMemAddrRange<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- MemAddr & o_startAddr,
- MemAddr & o_endAddr,
- AddrRangeType i_rangeType )
+uint32_t getMemAddrRange<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ MemAddr & o_startAddr,
+ MemAddr & o_endAddr,
+ AddrRangeType i_rangeType )
{
mss::mcbist::address saddr, eaddr;
- uint32_t o_rc = getMemAddrRange<TYPE_MEM_PORT>( i_chip, i_rank, saddr,
- eaddr, i_rangeType );
+ uint32_t o_rc = getMemAddrRange<TYPE_OCMB_CHIP>( i_chip, i_rank, saddr,
+ eaddr, i_rangeType );
if ( SUCCESS == o_rc )
{
o_startAddr = __convertMssMcbistAddr( saddr );
@@ -630,16 +640,16 @@ uint32_t getMemAddrRange<TYPE_MCA>( ExtensibleChip * i_chip,
uint8_t i_dimmSlct );
template
-uint32_t getMemAddrRange<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- mss::mcbist::address & o_startAddr,
- mss::mcbist::address & o_endAddr,
- uint8_t i_dimmSlct );
+uint32_t getMemAddrRange<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ mss::mcbist::address & o_startAddr,
+ mss::mcbist::address & o_endAddr,
+ uint8_t i_dimmSlct );
template
-uint32_t getMemAddrRange<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- MemAddr & o_startAddr,
- MemAddr & o_endAddr,
- uint8_t i_dimmSlct );
+uint32_t getMemAddrRange<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ MemAddr & o_startAddr,
+ MemAddr & o_endAddr,
+ uint8_t i_dimmSlct );
//------------------------------------------------------------------------------
@@ -696,17 +706,16 @@ bool isRowRepairEnabled<TYPE_MCA>( ExtensibleChip * i_chip,
}
template<>
-bool isRowRepairEnabled<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- const MemRank & i_rank )
+bool isRowRepairEnabled<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank )
{
- #define PRDF_FUNC "[PlatServices::isRowRepairEnabled<TYPE_MEM_PORT>] "
+ #define PRDF_FUNC "[PlatServices::isRowRepairEnabled<TYPE_OCMB_CHIP>] "
PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
bool o_isEnabled = false;
- /* TODO RTC 207273 - no HWP support yet
do
{
// Don't do row repair if DRAM repairs is disabled.
@@ -732,13 +741,110 @@ bool isRowRepairEnabled<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
}
}while(0);
- */
return o_isEnabled;
#undef PRDF_FUNC
}
+//------------------------------------------------------------------------------
+
+#ifdef CONFIG_NVDIMM
+uint32_t nvdimmNotifyProtChange( TARGETING::TargetHandle_t i_target,
+ const NVDIMM::nvdimm_protection_t i_state )
+{
+ #define PRDF_FUNC "[PlatServices::nvdimmNotifyProtChange] "
+
+ uint32_t o_rc = SUCCESS;
+
+ errlHndl_t errl = NVDIMM::notifyNvdimmProtectionChange( i_target, i_state );
+ if ( nullptr != errl )
+ {
+ PRDF_ERR( PRDF_FUNC "NVDIMM::notifyNvdimmProtectionChange(0x%08x) "
+ "failed.", getHuid(i_target) );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL;
+ }
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+
+}
+
+void nvdimmAddFfdc( TARGETING::TargetHandle_t i_nvdimm, errlHndl_t & io_errl )
+{
+ #define PRDF_FUNC "[PlatServices::nvdimmAddFfdc] "
+ // Add Page 4 Regs and Vendor Log using external Hostboot interfaces.
+ NVDIMM::nvdimmAddPage4Regs( i_nvdimm, io_errl );
+ NVDIMM::nvdimmAddVendorLog( i_nvdimm, io_errl );
+
+ // Add PRD specific registers relevant to runtime NVDIMM analysis.
+ const uint16_t regList[] =
+ {
+ // Module health registers
+ NVDIMM::i2cReg::MODULE_HEALTH,
+ NVDIMM::i2cReg::MODULE_HEALTH_STATUS0,
+ NVDIMM::i2cReg::MODULE_HEALTH_STATUS1,
+
+ // Threshold status registers
+ NVDIMM::i2cReg::ERROR_THRESHOLD_STATUS,
+ NVDIMM::i2cReg::WARNING_THRESHOLD_STATUS,
+
+ // ES_TEMP registers
+ NVDIMM::i2cReg::ES_TEMP0,
+ NVDIMM::i2cReg::ES_TEMP1,
+ NVDIMM::i2cReg::ES_TEMP_WARNING_HIGH_THRESHOLD0,
+ NVDIMM::i2cReg::ES_TEMP_WARNING_HIGH_THRESHOLD1,
+ NVDIMM::i2cReg::ES_TEMP_WARNING_LOW_THRESHOLD0,
+ NVDIMM::i2cReg::ES_TEMP_WARNING_LOW_THRESHOLD1,
+
+ // NVM Lifetime registers
+ NVDIMM::i2cReg::NVM_LIFETIME,
+ NVDIMM::i2cReg::NVM_LIFETIME_ERROR_THRESHOLD,
+ NVDIMM::i2cReg::NVM_LIFETIME_WARNING_THRESHOLD,
+
+ // ES Lifetime registers
+ NVDIMM::i2cReg::ES_LIFETIME,
+ NVDIMM::i2cReg::ES_LIFETIME_ERROR_THRESHOLD,
+ NVDIMM::i2cReg::ES_LIFETIME_WARNING_THRESHOLD,
+
+ // Status registers
+ NVDIMM::i2cReg::ERASE_STATUS,
+ NVDIMM::i2cReg::ARM_STATUS,
+ NVDIMM::i2cReg::SET_EVENT_NOTIFICATION_STATUS,
+ };
+
+ ERRORLOG::ErrlUserDetailsLogRegister regUd( i_nvdimm );
+ for ( auto const & reg : regList )
+ {
+ // NVDIMM register size = 1 byte
+ size_t NVDIMM_SIZE = 1;
+
+ uint8_t data = 0;
+ errlHndl_t errl = deviceRead( i_nvdimm, &data, NVDIMM_SIZE,
+ DEVICE_NVDIMM_ADDRESS(reg) );
+ if ( errl )
+ {
+ PRDF_ERR( PRDF_FUNC "Failed to read register 0x%X on "
+ "NVDIMM HUID: 0x%08x", reg, getHuid(i_nvdimm) );
+ // Don't commit, just delete the error and continue
+ delete errl; errl = nullptr;
+ continue;
+ }
+ // Only add registers that have non-zero data.
+ if ( 0 == data ) continue;
+
+ regUd.addDataBuffer( &data, sizeof(data), DEVICE_NVDIMM_ADDRESS(reg) );
+ }
+
+ regUd.addToLog( io_errl );
+
+ #undef PRDF_FUNC
+}
+
+#endif
+
//##############################################################################
//## Nimbus Maintenance Command wrappers
//##############################################################################
@@ -758,10 +864,16 @@ uint32_t startBgScrub<TYPE_MCA>( ExtensibleChip * i_mcaChip,
ExtensibleChip * mcbChip = getConnectedParent( i_mcaChip, TYPE_MCBIST );
fapi2::Target<fapi2::TARGET_TYPE_MCBIST> fapiTrgt ( mcbChip->getTrgt() );
+ #ifdef __HOSTBOOT_RUNTIME
+ // Starting a new command. Clear the UE and CE scrub stop counters
+ getMcbistDataBundle( mcbChip )->iv_ueStopCounter.reset();
+ getMcbistDataBundle( mcbChip )->iv_ceStopCounter.reset();
+ #endif
+
// Get the stop conditions.
// NOTE: If HBRT_PRD is not configured, we want to use the defaults so that
// background scrubbing never stops.
- mss::mcbist::stop_conditions stopCond;
+ mss::mcbist::stop_conditions<> stopCond;
// AUEs are checkstop attentions. Unfortunately, MCBIST commands do not stop
// when the system checkstops. Therefore, we must set the stop condition for
@@ -851,11 +963,11 @@ uint32_t startBgScrub<TYPE_MCBIST>( ExtensibleChip * i_mcaChip,
//------------------------------------------------------------------------------
+#ifndef CONFIG_AXONE
template<>
uint32_t startTdScrub<TYPE_MCA>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- AddrRangeType i_rangeType,
- mss::mcbist::stop_conditions i_stopCond )
+ const MemRank & i_rank, AddrRangeType i_rangeType,
+ mss::mcbist::stop_conditions<mss::mc_type::NIMBUS> i_stopCond )
{
#define PRDF_FUNC "[PlatServices::startTdScrub<TYPE_MCA>] "
@@ -912,6 +1024,7 @@ uint32_t startTdScrub<TYPE_MCA>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
+#endif
//##############################################################################
//## Centaur Maintenance Command wrappers
@@ -1316,25 +1429,31 @@ uint32_t incMaintAddr<TYPE_MBA>( ExtensibleChip * i_chip,
//##############################################################################
template<>
-uint32_t startBgScrub<TYPE_MEM_PORT>( ExtensibleChip * i_memPort,
- const MemRank & i_rank )
+uint32_t startBgScrub<TYPE_OCMB_CHIP>( ExtensibleChip * i_ocmb,
+ const MemRank & i_rank )
{
- #define PRDF_FUNC "[PlatServices::startBgScrub<TYPE_MEM_PORT>] "
+ #define PRDF_FUNC "[PlatServices::startBgScrub<TYPE_OCMB_CHIP>] "
- PRDF_ASSERT( nullptr != i_memPort );
- PRDF_ASSERT( TYPE_MEM_PORT == i_memPort->getType() );
+ PRDF_ASSERT( nullptr != i_ocmb );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_ocmb->getType() );
uint32_t o_rc = SUCCESS;
- /* TODO RTC 207273 - no HWP support yet
+ #ifdef CONFIG_AXONE
+
// Get the OCMB fapi target
- ExtensibleChip * ocmbChip = getConnectedParent( i_memPort, TYPE_OCMB_CHIP );
- fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapiTrgt (ocmbChip->getTrgt());
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapiTrgt (i_ocmb->getTrgt());
+
+ #ifdef __HOSTBOOT_RUNTIME
+ // Starting a new command. Clear the UE and CE scrub stop counters
+ getOcmbDataBundle( i_ocmb )->iv_ueStopCounter.reset();
+ getOcmbDataBundle( i_ocmb )->iv_ceStopCounter.reset();
+ #endif
// Get the stop conditions.
// NOTE: If HBRT_PRD is not configured, we want to use the defaults so that
// background scrubbing never stops.
- mss::mcbist::stop_conditions stopCond;
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER> stopCond;
// AUEs are checkstop attentions. Unfortunately, MCBIST commands do not stop
// when the system checkstops. Therefore, we must set the stop condition for
@@ -1373,40 +1492,40 @@ uint32_t startBgScrub<TYPE_MEM_PORT>( ExtensibleChip * i_memPort,
{
// Get the first address of the given rank.
mss::mcbist::address saddr, eaddr;
- o_rc = getMemAddrRange<TYPE_MEM_PORT>( i_memPort, i_rank, saddr, eaddr,
- SLAVE_RANK );
+ o_rc = getMemAddrRange<TYPE_OCMB_CHIP>( i_ocmb, i_rank, saddr, eaddr,
+ SLAVE_RANK );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed",
- i_memPort->getHuid(), i_rank.getKey() );
+ i_ocmb->getHuid(), i_rank.getKey() );
break;
}
// Clear all of the counters and maintenance ECC attentions.
- o_rc = prepareNextCmd<TYPE_OCMB_CHIP>( ocmbChip );
+ o_rc = prepareNextCmd<TYPE_OCMB_CHIP>( i_ocmb );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed",
- ocmbChip->getHuid() );
+ i_ocmb->getHuid() );
break;
}
// Start the background scrub command.
errlHndl_t errl = nullptr;
- FAPI_INVOKE_HWP( errl, mss::memdiags::background_scrub, fapiTrgt,
+ FAPI_INVOKE_HWP( errl, exp_background_scrub, fapiTrgt,
stopCond, scrubSpeed, saddr );
if ( nullptr != errl )
{
- PRDF_ERR( PRDF_FUNC "mss::memdiags::background_scrub(0x%08x,%d) "
- "failed", ocmbChip->getHuid(), i_rank.getMaster() );
+ PRDF_ERR( PRDF_FUNC "exp_background_scrub(0x%08x,%d) "
+ "failed", i_ocmb->getHuid(), i_rank.getMaster() );
PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
o_rc = FAIL; break;
}
} while (0);
+ #endif
- */
return o_rc;
#undef PRDF_FUNC
@@ -1414,31 +1533,19 @@ uint32_t startBgScrub<TYPE_MEM_PORT>( ExtensibleChip * i_memPort,
//------------------------------------------------------------------------------
-// This specialization only exists to avoid a lot of extra code in some classes.
-// The input chip must still be a MEM_PORT.
-template<>
-uint32_t startBgScrub<TYPE_OCMB_CHIP>( ExtensibleChip * i_memPort,
- const MemRank & i_rank )
-{
- return startBgScrub<TYPE_MEM_PORT>( i_memPort, i_rank );
-}
-
-//------------------------------------------------------------------------------
-
+#ifdef CONFIG_AXONE
template<>
-uint32_t startTdScrub<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- AddrRangeType i_rangeType,
- mss::mcbist::stop_conditions i_stopCond )
+uint32_t startTdScrub<TYPE_OCMB_CHIP>(ExtensibleChip * i_chip,
+ const MemRank & i_rank, AddrRangeType i_rangeType,
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER> i_stopCond)
{
- #define PRDF_FUNC "[PlatServices::startTdScrub<TYPE_MEM_PORT>] "
+ #define PRDF_FUNC "[PlatServices::startTdScrub<TYPE_OCMB_CHIP>] "
PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
uint32_t o_rc = SUCCESS;
- /* TODO RTC 207273 - no HWP support yet
// Set stop-on-AUE for all target scrubs. See explanation in startBgScrub()
// for the reasons why.
i_stopCond.set_pause_on_aue(mss::ON);
@@ -1447,8 +1554,8 @@ uint32_t startTdScrub<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
{
// Get the address range of the given rank.
mss::mcbist::address saddr, eaddr;
- o_rc = getMemAddrRange<TYPE_MEM_PORT>( i_chip, i_rank, saddr, eaddr,
- i_rangeType );
+ o_rc = getMemAddrRange<TYPE_OCMB_CHIP>( i_chip, i_rank, saddr, eaddr,
+ i_rangeType );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed",
@@ -1457,12 +1564,10 @@ uint32_t startTdScrub<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
}
// Get the OCMB_CHIP fapi target.
- ExtensibleChip * ocmbChip = getConnectedParent(i_chip, TYPE_OCMB_CHIP);
- fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
- fapiTrgt(ocmbChip->getTrgt());
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapiTrgt(i_chip->getTrgt());
// Clear all of the counters and maintenance ECC attentions.
- o_rc = prepareNextCmd<TYPE_OCMB_CHIP>( ocmbChip );
+ o_rc = prepareNextCmd<TYPE_OCMB_CHIP>( i_chip );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed",
@@ -1472,23 +1577,23 @@ uint32_t startTdScrub<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
// Start targeted scrub command.
errlHndl_t errl = nullptr;
- FAPI_INVOKE_HWP( errl, mss::memdiags::targeted_scrub, fapiTrgt,
+ FAPI_INVOKE_HWP( errl, exp_targeted_scrub, fapiTrgt,
i_stopCond, saddr, eaddr, mss::mcbist::NONE );
if ( nullptr != errl )
{
- PRDF_ERR( PRDF_FUNC "mss::memdiags::targeted_scrub(0x%08x,0x%02x) "
- "failed", ocmbChip->getHuid(), i_rank.getKey() );
+ PRDF_ERR( PRDF_FUNC "exp_targeted_scrub(0x%08x,0x%02x) "
+ "failed", i_chip->getHuid(), i_rank.getKey() );
PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
o_rc = FAIL; break;
}
} while (0);
- */
return o_rc;
#undef PRDF_FUNC
}
+#endif
//##############################################################################
//## Core/cache trace array functions
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices.H b/src/usr/diag/prdf/plat/prdfPlatServices.H
index e1710119c..b99c20bed 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices.H
+++ b/src/usr/diag/prdf/plat/prdfPlatServices.H
@@ -53,6 +53,10 @@
#include <prdfBitString.H>
#include <mem/prdfMemRank.H>
+#ifdef CONFIG_NVDIMM
+#include <isteps/nvdimm/nvdimm.H>
+#endif
+
//------------------------------------------------------------------------------
namespace PRDF
@@ -169,6 +173,26 @@ uint32_t getMemAddrRange( ExtensibleChip * i_chip,
template<TARGETING::TYPE T>
bool isRowRepairEnabled( ExtensibleChip * i_chip, const MemRank & i_rank );
+#ifdef CONFIG_NVDIMM
+/**
+ * @brief Notify PHYP/Hostboot of NVDIMM protection status
+ *
+ * @param i_target Processor with NVDIMM
+ * @param i_state Protection state of NVDIMM
+ */
+uint32_t nvdimmNotifyProtChange( TARGETING::TargetHandle_t i_target,
+ const NVDIMM::nvdimm_protection_t i_state );
+
+/**
+ * @brief Add SMART-specific, page 4 NVDIMM registers to the FFDC
+ *
+ * @param i_nvdimm An nvdimm target
+ * @param io_errl Error log to add the FFDC to
+ */
+void nvdimmAddFfdc( TARGETING::TargetHandle_t i_nvdimm, errlHndl_t & io_errl );
+
+#endif
+
//##############################################################################
//## Nimbus/Centaur Maintenance Command wrappers
//##############################################################################
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C
index 21cea0c85..14d1c26ba 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C
+++ b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C
@@ -43,7 +43,8 @@
#include <prdfMfgThresholdMgr.H>
#include <diag/mdia/mdia.H>
-#include <config.h>
+
+#include <hwp_wrappers.H>
using namespace TARGETING;
@@ -211,19 +212,19 @@ uint32_t mssRestoreDramRepairs<TYPE_MBA>( TargetHandle_t i_target,
//------------------------------------------------------------------------------
template<>
-uint32_t mssRestoreDramRepairs<TYPE_MEM_PORT>( TargetHandle_t i_target,
- uint8_t & o_repairedRankMask,
- uint8_t & o_badDimmMask )
+uint32_t mssRestoreDramRepairs<TYPE_OCMB_CHIP>( TargetHandle_t i_target,
+ uint8_t & o_repairedRankMask,
+ uint8_t & o_badDimmMask )
{
uint32_t o_rc = SUCCESS;
- /* TODO RTC 207273 - no HWP support yet
+ /* TODO RTC 199032 - no HWP support yet
errlHndl_t errl = NULL;
fapi2::buffer<uint8_t> tmpRepairedRankMask, tmpBadDimmMask;
FAPI_INVOKE_HWP( errl, mss::restore_repairs,
- fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>( i_target ),
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>( i_target ),
tmpRepairedRankMask, tmpBadDimmMask );
if ( NULL != errl )
@@ -315,7 +316,7 @@ uint32_t startSfRead<TYPE_MCA>( ExtensibleChip * i_mcaChip,
fapi2::Target<fapi2::TARGET_TYPE_MCBIST> fapiTrgt ( mcbChip->getTrgt() );
// Get the stop conditions.
- mss::mcbist::stop_conditions stopCond;
+ mss::mcbist::stop_conditions<> stopCond;
stopCond.set_pause_on_mpe(mss::ON)
.set_pause_on_ue(mss::ON)
.set_pause_on_aue(mss::ON)
@@ -843,41 +844,43 @@ uint32_t resumeTdSteerCleanup<TYPE_MBA>( ExtensibleChip * i_chip,
template<>
bool isBroadcastModeCapable<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
{
- /* TODO RTC 207273 - no HWP support yet
PRDF_ASSERT( nullptr != i_chip );
PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+ mss::states l_ret = mss::states::NO;
+
+ #ifdef CONFIG_AXONE
+
fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapiTrgt ( i_chip->getTrgt() );
+ FAPI_CALL_HWP( l_ret, exp_is_broadcast_capable, fapiTrgt );
+
+ #endif
- mss::states l_ret = mss::states::NO;
- FAPI_CALL_HWP( l_ret, mss::mcbist::is_broadcast_capable, fapiTrgt );
return ( mss::states::YES == l_ret );
- */
- return false;
}
//------------------------------------------------------------------------------
template<>
-uint32_t startSfRead<TYPE_MEM_PORT>( ExtensibleChip * i_memPort,
- const MemRank & i_rank )
+uint32_t startSfRead<TYPE_OCMB_CHIP>( ExtensibleChip * i_ocmb,
+ const MemRank & i_rank )
{
- #define PRDF_FUNC "[PlatServices::startSfRead<TYPE_MCA>] "
+ #define PRDF_FUNC "[PlatServices::startSfRead<TYPE_OCMB_CHIP>] "
PRDF_ASSERT( isInMdiaMode() ); // MDIA must be running.
- PRDF_ASSERT( nullptr != i_memPort );
- PRDF_ASSERT( TYPE_MEM_PORT == i_memPort->getType() );
+ PRDF_ASSERT( nullptr != i_ocmb );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_ocmb->getType() );
uint32_t o_rc = SUCCESS;
- /* TODO RTC 207273 - no HWP support yet
+ #ifdef CONFIG_AXONE
+
// Get the OCMB_CHIP fapi target
- ExtensibleChip * ocmbChip = getConnectedParent( i_memPort, TYPE_OCMB_CHIP );
- fapi2::Target<fapi2::TYPE_OCMB_CHIP> fapiTrgt ( ocmbChip->getTrgt() );
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapiTrgt ( i_ocmb->getTrgt() );
// Get the stop conditions.
- mss::mcbist::stop_conditions stopCond;
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER> stopCond;
stopCond.set_pause_on_mpe(mss::ON)
.set_pause_on_ue(mss::ON)
.set_pause_on_aue(mss::ON)
@@ -892,39 +895,39 @@ uint32_t startSfRead<TYPE_MEM_PORT>( ExtensibleChip * i_memPort,
{
// Get the first address of the given rank.
mss::mcbist::address saddr, eaddr;
- o_rc = getMemAddrRange<TYPE_MEM_PORT>( i_memPort, i_rank, saddr, eaddr,
- SLAVE_RANK );
+ o_rc = getMemAddrRange<TYPE_OCMB_CHIP>( i_ocmb, i_rank, saddr, eaddr,
+ SLAVE_RANK );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed",
- i_memPort->getHuid(), i_rank.getKey() );
+ i_ocmb->getHuid(), i_rank.getKey() );
break;
}
// Clear all of the counters and maintenance ECC attentions.
- o_rc = prepareNextCmd<TYPE_OCMB_CHIP>( ocmbChip );
+ o_rc = prepareNextCmd<TYPE_OCMB_CHIP>( i_ocmb );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed",
- ocmbChip->getHuid() );
+ i_ocmb->getHuid() );
break;
}
// Start the super fast read command.
errlHndl_t errl;
- FAPI_INVOKE_HWP( errl, mss::memdiags::sf_read, fapiTrgt, stopCond,
+ FAPI_INVOKE_HWP( errl, exp_sf_read, fapiTrgt, stopCond,
saddr );
if ( nullptr != errl )
{
- PRDF_ERR( PRDF_FUNC "mss::memdiags::sf_read(0x%08x,%d) failed",
- ocmbChip->getHuid(), i_rank.getMaster() );
+ PRDF_ERR( PRDF_FUNC "exp_sf_read(0x%08x,%d) failed",
+ i_ocmb->getHuid(), i_rank.getMaster() );
PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
o_rc = FAIL; break;
}
} while (0);
- */
+ #endif
return o_rc;
@@ -933,22 +936,154 @@ uint32_t startSfRead<TYPE_MEM_PORT>( ExtensibleChip * i_memPort,
//------------------------------------------------------------------------------
-// This specialization only exists to avoid a lot of extra code in some classes.
-// The input chip must still be an MEM_PORT chip.
template<>
-uint32_t startSfRead<TYPE_OCMB_CHIP>( ExtensibleChip * i_memPort,
- const MemRank & i_rank )
+uint32_t cleanupSfRead<TYPE_OCMB_CHIP>( ExtensibleChip * i_ocmbChip )
{
- return startSfRead<TYPE_MEM_PORT>( i_memPort, i_rank );
+ return SUCCESS; // Not needed for MCBIST commands.
}
//------------------------------------------------------------------------------
+#ifdef CONFIG_AXONE
+
template<>
-uint32_t cleanupSfRead<TYPE_OCMB_CHIP>( ExtensibleChip * i_ocmbChip )
+uint32_t startTdSteerCleanup<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank, AddrRangeType i_rangeType,
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER> i_stopCond )
{
- return SUCCESS; // Not needed for MCBIST commands.
+ #define PRDF_FUNC "[PlatServices::startTdSteerCleanup<TYPE_OCMB_CHIP>] "
+
+ PRDF_ASSERT( isInMdiaMode() ); // MDIA must be running.
+
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+
+ uint32_t o_rc = SUCCESS;
+
+ // Default speed is to run as fast as possible.
+ //mss_MaintCmd::TimeBaseSpeed cmdSpeed = mss_MaintCmd::FAST_MAX_BW_IMPACT;
+
+ // Set stop-on-AUE for all target scrubs. See explanation in startBgScrub()
+ // for the reasons why.
+ i_stopCond.set_pause_on_aue(mss::ON);
+
+ do
+ {
+ // Get the address range of the given rank.
+ mss::mcbist::address saddr, eaddr;
+ o_rc = getMemAddrRange<TYPE_OCMB_CHIP>( i_chip, i_rank, saddr, eaddr,
+ i_rangeType );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed",
+ i_chip->getHuid(), i_rank.getKey() );
+ break;
+ }
+
+ // Clear all of the counters and maintenance ECC attentions.
+ o_rc = prepareNextCmd<TYPE_OCMB_CHIP>( i_chip );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed",
+ i_chip->getHuid() );
+ break;
+ }
+
+ /* TODO RTC 199032 - sparing support
+ // Get the MBA fapi target.
+ fapi2::Target<fapi2::TARGET_TYPE_MBA> fapiTrgt ( i_chip->getTrgt() );
+
+ // Start the steer cleanup command.
+ mss_TimeBaseSteerCleanup cmd { fapiTrgt, saddr, eaddr, cmdSpeed,
+ i_stopCond, false };
+ errlHndl_t errl = nullptr;
+ FAPI_INVOKE_HWP( errl, cmd.setupAndExecuteCmd );
+ if ( nullptr != errl )
+ {
+ PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() on 0x%08x,0x%02x failed",
+ i_chip->getHuid(), i_rank.getKey() );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL; break;
+ }
+ */
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
}
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifdef CONFIG_AXONE
+
+template<>
+uint32_t startTdSfRead<TYPE_OCMB_CHIP>(ExtensibleChip * i_chip,
+ const MemRank & i_rank, AddrRangeType i_rangeType,
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER> i_stopCond)
+{
+ #define PRDF_FUNC "[PlatServices::startTdSfRead<TYPE_OCMB_CHIP>] "
+
+ PRDF_ASSERT( isInMdiaMode() ); // MDIA must be running.
+
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+
+ uint32_t o_rc = SUCCESS;
+
+ // Set stop-on-AUE for all target scrubs. See explanation in startBgScrub()
+ // for the reasons why.
+ i_stopCond.set_pause_on_aue(mss::ON);
+
+ do
+ {
+ // Get the address range of the given rank.
+ mss::mcbist::address saddr, eaddr;
+ o_rc = getMemAddrRange<TYPE_OCMB_CHIP>( i_chip, i_rank, saddr, eaddr,
+ i_rangeType );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed",
+ i_chip->getHuid(), i_rank.getKey() );
+ break;
+ }
+
+ // Clear all of the counters and maintenance ECC attentions.
+ o_rc = prepareNextCmd<TYPE_OCMB_CHIP>( i_chip );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed",
+ i_chip->getHuid() );
+ break;
+ }
+
+ // Get the OCMB fapi target.
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
+ fapiTrgt( i_chip->getTrgt() );
+
+ // Start the super fast read command.
+ errlHndl_t errl;
+ FAPI_INVOKE_HWP( errl, exp_sf_read, fapiTrgt, i_stopCond, saddr );
+ if ( nullptr != errl )
+ {
+ PRDF_ERR( PRDF_FUNC "exp_sf_read(0x%08x,%d) failed",
+ i_chip->getHuid(), i_rank.getMaster() );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL; break;
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+#endif
+
//------------------------------------------------------------------------------
} // end namespace PlatServices
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.H b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.H
index a27f1b92e..c12cf5a51 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.H
+++ b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.H
@@ -66,7 +66,7 @@ int32_t mdiaSendEventMsg( TARGETING::TargetHandle_t i_trgt,
/**
* @brief Initiates a reconfig loop due to an RCD parity error.
- * @param i_trgt An MCA or MEM_PORT target.
+ * @param i_trgt An MCA target.
* @return True if the number of allowed reconfig loops has been exceeded.
* False otherwise.
*/
@@ -113,7 +113,7 @@ bool isBroadcastModeCapable( ExtensibleChip * i_chip );
/**
* @brief Starts a super fast read command from the first address of the given
* rank to the end of memory.
- * @param i_chip MCBIST/MCA, MBA, or MEM_PORT chip.
+ * @param i_chip MCBIST/MCA, MBA, or OCMB chip.
* @param i_rank Will start the command on the first address of this slave
* rank. To ensure the command is started on a master rank boundary,
* make sure the slave rank value is 0.
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices_rt.C b/src/usr/diag/prdf/plat/prdfPlatServices_rt.C
index 25a470f8d..0fbe5b969 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices_rt.C
+++ b/src/usr/diag/prdf/plat/prdfPlatServices_rt.C
@@ -37,6 +37,8 @@
// Platform includes
#include <prdfCenMbaDataBundle.H>
+#include <prdfP9McbistDataBundle.H>
+#include <prdfOcmbDataBundle.H>
#include <prdfMemScrubUtils.H>
#include <prdfPlatServices.H>
@@ -51,6 +53,8 @@
#include <p9_stop_api.H>
#include <rt_todintf.H>
+#include <hwp_wrappers.H>
+
//------------------------------------------------------------------------------
using namespace TARGETING;
@@ -105,28 +109,6 @@ void sendPredDeallocRequest( uint64_t i_saddr, uint64_t i_eaddr )
__dyndealloc( i_saddr, i_eaddr, MEMORY_ERROR_PREDICTIVE );
}
-uint32_t nvdimmNotifyPhypProtChange( TARGETING::TargetHandle_t i_target,
- const NVDIMM::nvdimm_protection_t i_state )
-{
- #define PRDF_FUNC "[PlatServices::nvdimmNotifyPhypProtChange] "
-
- uint32_t o_rc = SUCCESS;
-
- errlHndl_t errl = NVDIMM::notifyNvdimmProtectionChange( i_target, i_state );
- if ( nullptr != errl )
- {
- PRDF_ERR( PRDF_FUNC "NVDIMM::notifyNvdimmProtectionChange(0x%08x) "
- "failed.", getHuid(i_target) );
- PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
- o_rc = FAIL;
- }
-
- return o_rc;
-
- #undef PRDF_FUNC
-
-}
-
//##############################################################################
//## Nimbus Maintenance Command wrappers
//##############################################################################
@@ -172,7 +154,8 @@ uint32_t stopBgScrub<TYPE_MCA>( ExtensibleChip * i_chip )
//------------------------------------------------------------------------------
template<>
-uint32_t resumeBgScrub<TYPE_MCBIST>( ExtensibleChip * i_chip )
+uint32_t resumeBgScrub<TYPE_MCBIST>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
{
#define PRDF_FUNC "[PlatServices::resumeBgScrub<TYPE_MCBIST>] "
@@ -195,9 +178,42 @@ uint32_t resumeBgScrub<TYPE_MCBIST>( ExtensibleChip * i_chip )
break;
}
+ // Check UE and CE stop counters to determine stop conditions
+ mss::mcbist::stop_conditions<> stopCond;
+ if ( getMcbistDataBundle(i_chip)->iv_ueStopCounter.thReached(io_sc) )
+ {
+ // If we've reached the limit of UEs we're allowed to stop on
+ // per rank, only set the stop on mpe stop condition.
+ stopCond.set_pause_on_mpe(mss::ON);
+ }
+ else if (getMcbistDataBundle(i_chip)->iv_ceStopCounter.thReached(io_sc))
+ {
+ // If we've reached the limit of CEs we're allowed to stop on
+ // per rank, set all the normal stop conditions except stop on CE
+ stopCond.set_pause_on_aue(mss::ON);
+
+ #ifdef CONFIG_HBRT_PRD
+
+ stopCond.set_pause_on_mpe(mss::ON)
+ .set_pause_on_ue(mss::ON);
+
+ // In MNFG mode, stop on RCE_ETE to get an accurate callout for IUEs
+ if ( mfgMode() ) stopCond.set_thresh_rce(1);
+
+ #endif
+ }
+ else
+ {
+ // If we haven't reached threshold on the number of UEs or CEs we
+ // have stopped on, do not change the stop conditions.
+ stopCond = mss::mcbist::stop_conditions<>(
+ mss::mcbist::stop_conditions<>::DONT_CHANGE );
+ }
+
// Resume the command on the next address.
errlHndl_t errl;
- FAPI_INVOKE_HWP( errl, mss::memdiags::continue_cmd, fapiTrgt );
+ FAPI_INVOKE_HWP( errl, mss::memdiags::continue_cmd, fapiTrgt,
+ mss::mcbist::end_boundary::DONT_CHANGE, stopCond );
if ( nullptr != errl )
{
@@ -217,12 +233,14 @@ uint32_t resumeBgScrub<TYPE_MCBIST>( ExtensibleChip * i_chip )
//------------------------------------------------------------------------------
template<>
-uint32_t resumeBgScrub<TYPE_MCA>( ExtensibleChip * i_chip )
+uint32_t resumeBgScrub<TYPE_MCA>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
{
PRDF_ASSERT( nullptr != i_chip );
PRDF_ASSERT( TYPE_MCA == i_chip->getType() );
- return resumeBgScrub<TYPE_MCBIST>(getConnectedParent(i_chip, TYPE_MCBIST));
+ return resumeBgScrub<TYPE_MCBIST>(getConnectedParent(i_chip, TYPE_MCBIST),
+ io_sc);
}
//##############################################################################
@@ -362,7 +380,8 @@ uint32_t __resumeScrub<TYPE_MBA>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
template<>
-uint32_t resumeBgScrub<TYPE_MBA>( ExtensibleChip * i_chip )
+uint32_t resumeBgScrub<TYPE_MBA>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
{
PRDF_ASSERT( nullptr != i_chip );
PRDF_ASSERT( TYPE_MBA == i_chip->getType() );
@@ -418,19 +437,21 @@ uint32_t stopBgScrub<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
uint32_t rc = SUCCESS;
- /* TODO RTC 207273 - no HWP support yet
+ #ifdef CONFIG_AXONE
+
fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapiTrgt ( i_chip->getTrgt() );
errlHndl_t errl;
- FAPI_INVOKE_HWP( errl, mss::memdiags::stop, fapiTrgt );
+ FAPI_INVOKE_HWP( errl, exp_stop, fapiTrgt );
if ( nullptr != errl )
{
- PRDF_ERR( PRDF_FUNC "mss::memdiags::stop(0x%08x) failed", i_chip->getHuid());
+ PRDF_ERR( PRDF_FUNC "exp_stop(0x%08x) failed", i_chip->getHuid());
PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
rc = FAIL;
}
- */
+
+ #endif
return rc;
@@ -440,19 +461,8 @@ uint32_t stopBgScrub<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
//------------------------------------------------------------------------------
template<>
-uint32_t stopBgScrub<TYPE_MEM_PORT>( ExtensibleChip * i_chip )
-{
- PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
-
- ExtensibleChip* ocmbChip = getConnectedParent( i_chip, TYPE_OCMB_CHIP );
- return stopBgScrub<TYPE_OCMB_CHIP>( ocmbChip );
-}
-
-//------------------------------------------------------------------------------
-
-template<>
-uint32_t resumeBgScrub<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
+uint32_t resumeBgScrub<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
{
#define PRDF_FUNC "[PlatServices::resumeBgScrub<TYPE_OCMB_CHIP>] "
@@ -461,9 +471,9 @@ uint32_t resumeBgScrub<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
uint32_t o_rc = SUCCESS;
- /* TODO RTC 207273 - no hwp support yet
+ #ifdef CONFIG_AXONE
- // Get the OCMB_CHIP fapi target
+ // Get the OCMB fapi target
fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapiTrgt ( i_chip->getTrgt() );
do
@@ -477,13 +487,45 @@ uint32_t resumeBgScrub<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
break;
}
+ // Check UE and CE stop counters to determine stop conditions
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER> stopCond;
+ if ( getOcmbDataBundle(i_chip)->iv_ueStopCounter.thReached(io_sc) )
+ {
+ // If we've reached the limit of UEs we're allowed to stop on
+ // per rank, only set the stop on mpe stop condition.
+ stopCond.set_pause_on_mpe(mss::ON);
+ }
+ else if ( getOcmbDataBundle(i_chip)->iv_ceStopCounter.thReached(io_sc) )
+ {
+ // If we've reached the limit of CEs we're allowed to stop on
+ // per rank, set all the normal stop conditions except stop on CE
+ stopCond.set_pause_on_aue(mss::ON);
+
+ #ifdef CONFIG_HBRT_PRD
+
+ stopCond.set_pause_on_mpe(mss::ON)
+ .set_pause_on_ue(mss::ON);
+
+ // In MNFG mode, stop on RCE_ETE to get an accurate callout for IUEs
+ if ( mfgMode() ) stopCond.set_thresh_rce(1);
+
+ #endif
+ }
+ else
+ {
+ // If we haven't reached threshold on the number of UEs or CEs we
+ // have stopped on, do not change the stop conditions.
+ stopCond = mss::mcbist::stop_conditions<mss::mc_type::EXPLORER>(
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER>::DONT_CHANGE );
+ }
+
// Resume the command on the next address.
errlHndl_t errl;
- FAPI_INVOKE_HWP( errl, mss::memdiags::continue_cmd, fapiTrgt );
-
+ FAPI_INVOKE_HWP( errl, exp_continue_cmd, fapiTrgt,
+ mss::mcbist::end_boundary::DONT_CHANGE, stopCond );
if ( nullptr != errl )
{
- PRDF_ERR( PRDF_FUNC "mss::memdiags::continue_cmd(0x%08x) failed",
+ PRDF_ERR( PRDF_FUNC "exp_continue_cmd(0x%08x) failed",
i_chip->getHuid() );
PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
o_rc = FAIL; break;
@@ -491,25 +533,13 @@ uint32_t resumeBgScrub<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
} while (0);
- */
+ #endif
return o_rc;
#undef PRDF_FUNC
}
-//------------------------------------------------------------------------------
-
-template<>
-uint32_t resumeBgScrub<TYPE_MEM_PORT>( ExtensibleChip * i_chip )
-{
- PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
-
- ExtensibleChip* ocmbChip = getConnectedParent( i_chip, TYPE_OCMB_CHIP );
- return resumeBgScrub<TYPE_OCMB_CHIP>( ocmbChip );
-}
-
//##############################################################################
//## Line Delete Functions
//##############################################################################
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices_rt.H b/src/usr/diag/prdf/plat/prdfPlatServices_rt.H
index 5407c94ad..49d4c0a73 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices_rt.H
+++ b/src/usr/diag/prdf/plat/prdfPlatServices_rt.H
@@ -30,7 +30,6 @@
#include <p9_l2err_extract.H>
#include <p9_pm_callout.H>
#include <prdfMemAddress.H>
-#include <isteps/nvdimm/nvdimm.H>
namespace PRDF
{
@@ -65,22 +64,13 @@ void sendDynMemDeallocRequest( uint64_t i_saddr, uint64_t i_eaddr );
*/
void sendPredDeallocRequest( uint64_t i_saddr, uint64_t i_eaddr );
-/**
- * @brief Notify PHYP of NVDIMM protection status
- *
- * @param i_target Processor with NVDIMM
- * @param i_state Protection state of NVDIMM
- */
-uint32_t nvdimmNotifyPhypProtChange( TARGETING::Target * i_target,
- const NVDIMM::nvdimm_protection_t i_state );
-
//##############################################################################
//## Nimbus/Centaur Maintenance Command wrappers
//##############################################################################
/**
* @brief Stops Background Scrubbing.
- * @param i_chip MCBIST, MCA, MBA, MEM_PORT, or OCMB chip.
+ * @param i_chip MCBIST, MCA, MBA, or OCMB chip.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
template<TARGETING::TYPE T>
@@ -99,11 +89,13 @@ uint32_t stopBgScrub( ExtensibleChip * i_chip );
* due to an error. It should not be called after executing a Targeted
* Diagnotics procedure.
*
- * @param i_chip MCBIST, MCA, MBA, MEM_PORT, or OCMB chip.
+ * @param i_chip MCBIST, MCA, MBA, or OCMB chip.
+ * @param io_sc The step code data struct.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
template<TARGETING::TYPE T>
-uint32_t resumeBgScrub( ExtensibleChip * i_chip );
+uint32_t resumeBgScrub( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc );
/**
* @brief Resumes TD scrubbing after it has paused on error.
diff --git a/src/usr/diag/prdf/prdfMain_ipl.C b/src/usr/diag/prdf/prdfMain_ipl.C
index b73356575..755206b1e 100644
--- a/src/usr/diag/prdf/prdfMain_ipl.C
+++ b/src/usr/diag/prdf/prdfMain_ipl.C
@@ -42,10 +42,10 @@
#include <prdfCenMbaDataBundle.H>
#include <prdfPlatServices.H>
#include <prdfP9McaDataBundle.H>
+#include <prdfOcmbDataBundle.H>
#include <prdfMemBgScrub.H>
// Custom compile configs
-#include <config.h>
#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS
#include <prdfFileRegisterAccess.H>
@@ -98,6 +98,11 @@ int32_t analyzeIplCEStats( TargetHandle_t i_trgt, bool &o_calloutMade )
MbaDataBundle * db = getMbaDataBundle( chip );
o_calloutMade = db->getIplCeStats()->analyzeStats();
}
+ else if ( TYPE_OCMB_CHIP == type )
+ {
+ OcmbDataBundle * db = getOcmbDataBundle( chip );
+ o_calloutMade = db->getIplCeStats()->analyzeStats();
+ }
else
{
PRDF_ERR( PRDF_FUNC "Unsupported target type %d", type );
@@ -155,6 +160,8 @@ errlHndl_t startScrub( const TargetHandle_t i_trgt )
{
case TYPE_MBA: startInitialBgScrub<TYPE_MBA>( chip); break;
case TYPE_MCBIST: startInitialBgScrub<TYPE_MCBIST>(chip); break;
+ case TYPE_OCMB_CHIP:
+ startInitialBgScrub<TYPE_OCMB_CHIP>(chip); break;
default:
PRDF_ERR( PRDF_FUNC "Unsupported maintenance target type "
"0x%02x", chip->getType() );
diff --git a/src/usr/diag/prdf/prdf_hb_only.mk b/src/usr/diag/prdf/prdf_hb_only.mk
index 72ef8880d..6217c6b40 100644
--- a/src/usr/diag/prdf/prdf_hb_only.mk
+++ b/src/usr/diag/prdf/prdf_hb_only.mk
@@ -75,10 +75,20 @@ prd_incpath += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/pm/
prd_incpath += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/lib/
prd_incpath += ${ROOTPATH}/src/import/generic/memory/lib/utils/
prd_incpath += ${ROOTPATH}/src/import/chips/p9/utils/imageProcs/
+prd_incpath += ${ROOTPATH}/src/import/chips/common/utils/
prd_incpath += ${ROOTPATH}/src/import/chips/common/utils/imageProcs/
prd_incpath += ${ROOTPATH}/src/import/hwpf/fapi2/include
prd_incpath += ${ROOTPATH}/src/import/
prd_incpath += ${ROOTPATH}/src/import/chips/centaur/procedures/hwp/io/
+prd_incpath += ${ROOTPATH}/src/usr/isteps/nvdimm
+
+# For including hwp_wrappers.H
+prd_incpath += ${ROOTPATH}/src/import/generic/memory/lib/prd/
+prd_incpath += ${ROOTPATH}/src/import/generic/memory/lib/utils/mcbist/
+prd_incpath += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/
+prd_incpath += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
+prd_incpath += ${ROOTPATH}/obj/genfiles/chips/ocmb/explorer/procedures/hwp/memory/lib/
+prd_incpath += ${ROOTPATH}/obj/genfiles/generic/memory/lib/
################################################################################
# Hostboot only object files common to both IPL and runtime
@@ -130,12 +140,6 @@ ifeq (${HOSTBOOT_RUNTIME},1)
# plat/
prd_obj += prdfPlatServices_rt.o
-# nvdimm
-prd_vpath += ${ROOTPATH}/src/usr/isteps/nvdimm/
-prd_vpath += ${ROOTPATH}/src/usr/isteps/nvdimm/runtime
-prd_obj_no_sim += nvdimm.o
-prd_obj_no_sim += nvdimm_rt.o
-
endif
################################################################################
@@ -190,6 +194,19 @@ prd_obj_no_sim += p9c_dimmBadDqBitmapFuncs.o
prd_obj_no_sim += p9c_query_channel_failure.o
prd_obj_no_sim += p9c_mss_rowRepairFuncs.o
+prd_vpath += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/
+prd_vpath += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/
+prd_vpath += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/
+prd_vpath += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils
+prd_vpath += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/memory/lib/utils/
+prd_obj_no_sim += hwp_wrappers_nim.o
+prd_obj_no_sim += hwp_wrappers_exp.o
+prd_obj_no_sim += nimbus_pos.o
+prd_obj_no_sim += explorer_pos.o
+prd_obj_no_sim += exp_mcbist.o
+prd_obj_no_sim += exp_memdiags.o
+prd_obj_no_sim += explorer_memory_size.o
+
################################################################################
# The following are hardware procedure utilities that we are pulling into the
# PRD library (only needed here for HBRT). This code is already compiled in
diff --git a/src/usr/diag/prdf/runtime/makefile b/src/usr/diag/prdf/runtime/makefile
index 8f7338756..970ce9333 100644
--- a/src/usr/diag/prdf/runtime/makefile
+++ b/src/usr/diag/prdf/runtime/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2014,2018
+# Contributors Listed Below - COPYRIGHT 2014,2019
# [+] International Business Machines Corp.
#
#
@@ -38,13 +38,16 @@ include ../prdf_hb_only.mk # Will define PRD_SRC_PATH and PRD_INC_PATH
include ../common/prdf_common_fsp_and_hb.mk
include ../common/framework/prdf_framework.mk
include ../common/plat/p9/prdf_plat_p9.mk
+include ../common/plat/axone/prdf_plat_axone.mk
include ../common/plat/cen/prdf_plat_cen.mk
include ../common/plat/mem/prdf_plat_mem.mk
include ../common/plat/centaur/prdf_plat_centaur.mk
include ../common/plat/cumulus/prdf_plat_cumulus.mk
include ../common/plat/nimbus/prdf_plat_nimbus.mk
+include ../common/plat/explorer/prdf_plat_explorer.mk
include ../plat/cen/prdf_plat_cen_hb_only.mk
include ../plat/mem/prdf_plat_mem_hb_only.mk
+include ../plat/explorer/prdf_plat_explorer_hb_only.mk
include ../plat/p9/prdf_plat_p9_hb_only.mk
VPATH += ${prd_vpath}
diff --git a/src/usr/diag/prdf/test/prdfTest_BadDqBitmap.H b/src/usr/diag/prdf/test/prdfTest_BadDqBitmap.H
new file mode 100644
index 000000000..4b4fa8fea
--- /dev/null
+++ b/src/usr/diag/prdf/test/prdfTest_BadDqBitmap.H
@@ -0,0 +1,227 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/test/prdfTest_BadDqBitmap.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __TEST_PRDFBADDQBITMAP_H
+#define __TEST_PRDFBADDQBITMAP_H
+
+/**
+ * @file prdfTest_BadDqBitmap.H
+ *
+ * @brief prdf testing reading and writing the BAD_DQ_BITMAP attribute
+ */
+
+#ifdef __HOSTBOOT_MODULE
+ #include <cxxtest/TestSuite.H>
+ #include <errl/errlentry.H>
+ #include <errl/errlmanager.H>
+#else
+ #include <cxxtest/TestSuite.h>
+ #include <fsp/FipsGlobalFixture.H>
+ #include <errlentry.H>
+#endif
+
+#include <prdfTrace.H>
+#include <prdfMain.H>
+#include "prdfsimMacros.H"
+#include <prdfMemDqBitmap.H>
+#include <prdfPlatServices.H>
+#include <prdfTargetServices.H>
+
+class WriteBadDqBitmap: public CxxTest::TestSuite
+{
+
+public:
+
+ void TestNimbusReadWriteBadDqBitmap(void)
+ {
+ using namespace PRDF;
+ using namespace TARGETING;
+ using namespace PlatServices;
+
+ TargetHandle_t masterProc = nullptr;
+ targetService().masterProcChipTargetHandle(masterProc);
+
+ // Nimbus only test
+ if ( MODEL_NIMBUS == masterProc->getAttr<ATTR_MODEL>() )
+ {
+ TS_INFO("- TestNimbusReadWriteBadDqBitmap - Start -");
+
+ uint32_t rc = SUCCESS;
+
+ // Get an MCBIST
+ TargetHandle_t mcb = getConnectedChild(masterProc, TYPE_MCBIST, 0);
+ if ( nullptr == mcb )
+ {
+ TS_FAIL( "ERROR: Failed to get MCBIST" );
+ }
+ // Get an MCA
+ TargetHandle_t mca = getConnectedChild( mcb, TYPE_MCA, 0 );
+ if ( nullptr == mca )
+ {
+ TS_FAIL( "ERROR: Failed to get MCA" );
+ }
+
+ // Make arbitrary initial data
+ MemRank rank( 0, 0 );
+ const uint8_t initialBitmap[DQ_BITMAP::BITMAP_SIZE] =
+ { 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00 };
+ BitmapData initialData;
+ memcpy( initialData[0].bitmap, initialBitmap,
+ sizeof(initialData[0].bitmap) );
+
+ // Set with the initial data
+ MemDqBitmap setBitmap( mca, rank, initialData );
+ rc = setBadDqBitmap( mca, rank, setBitmap );
+ if ( SUCCESS != rc )
+ {
+ TS_FAIL( "ERROR: setBadDqBitmap failed " );
+ }
+
+ // Read the data back
+ MemDqBitmap getBitmap;
+ rc = getBadDqBitmap( mca, rank, getBitmap );
+ if ( SUCCESS != rc )
+ {
+ TS_FAIL( "ERROR: getBadDqBitmap failed" );
+ }
+
+ BitmapData newData = getBitmap.getData();
+
+ // Compare the read data to the initial data. The last byte (byte 9)
+ // is for spares so we won't worry about comparing that.
+ for ( uint8_t n = 0; n < (DQ_BITMAP::BITMAP_SIZE-1); n++ )
+ {
+ if ( newData.at(0).bitmap[n] != initialBitmap[n] )
+ {
+ TS_FAIL( "TestNimbusReadWriteBadDqBitmap: Incorrect data "
+ "found. newData[%d]=0x%x initialBitmap[%d]=0x%x",
+ n, newData.at(0).bitmap[n], n, initialBitmap[n] );
+ }
+ }
+
+ // Clear the vpd just in case
+ rc = clearBadDqBitmap( mca, rank );
+ if ( SUCCESS != rc )
+ {
+ TS_FAIL( "ERROR: clearBadDqBitmap failed" );
+ }
+
+ TS_INFO("- TestNimbusReadWriteBadDqBitmap - End -");
+ }
+
+ }
+
+ void TestAxoneReadWriteBadDqBitmap(void)
+ {
+ using namespace PRDF;
+ using namespace TARGETING;
+ using namespace PlatServices;
+
+ TargetHandle_t masterProc = nullptr;
+ targetService().masterProcChipTargetHandle(masterProc);
+
+ // Axone only test
+ if ( MODEL_AXONE == masterProc->getAttr<ATTR_MODEL>() )
+ {
+ TS_INFO("- TestAxoneReadWriteBadDqBitmap - Start -");
+
+ uint32_t rc = SUCCESS;
+
+ // Get an OCMB
+ TargetHandle_t mc = getConnectedChild( masterProc, TYPE_MC, 0 );
+ if ( nullptr == mc )
+ {
+ TS_FAIL( "ERROR: Failed to get MC" );
+ }
+ TargetHandle_t omic = getConnectedChild( mc, TYPE_OMIC, 0 );
+ if ( nullptr == omic )
+ {
+ TS_FAIL( "ERROR: Failed to get OMIC" );
+ }
+ TargetHandle_t omi = getConnectedChild( omic, TYPE_OMI, 0 );
+ if ( nullptr == omi )
+ {
+ TS_FAIL( "ERROR: Failed to get OMI" );
+ }
+ TargetHandle_t ocmb = getConnectedChild( omi, TYPE_OCMB_CHIP, 0 );
+ if ( nullptr == ocmb )
+ {
+ TS_FAIL( "ERROR: Failed to get OCMB" );
+ }
+ // Make arbitrary initial data
+ MemRank rank( 0 );
+ const uint8_t initialBitmap[DQ_BITMAP::BITMAP_SIZE] =
+ { 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0x00 };
+ BitmapData initialData;
+ memcpy( initialData[0].bitmap, initialBitmap,
+ sizeof(initialData[0].bitmap) );
+
+ // Set with the initial data
+ MemDqBitmap setBitmap( ocmb, rank, initialData );
+ rc = setBadDqBitmap( ocmb, rank, setBitmap );
+ if ( SUCCESS != rc )
+ {
+ TS_FAIL( "ERROR: setBadDqBitmap failed " );
+ }
+
+ // Read the data back
+ MemDqBitmap getBitmap;
+ rc = getBadDqBitmap( ocmb, rank, getBitmap );
+ if ( SUCCESS != rc )
+ {
+ TS_FAIL( "ERROR: getBadDqBitmap failed" );
+ }
+
+ BitmapData newData = getBitmap.getData();
+
+ // Compare the read data to the initial data. The last byte (byte 9)
+ // is for spares so we won't worry about comparing that.
+ for ( uint8_t n = 0; n < (DQ_BITMAP::BITMAP_SIZE-1); n++ )
+ {
+ if ( newData.at(0).bitmap[n] != initialBitmap[n] )
+ {
+ TS_FAIL( "TestAxoneReadWriteBadDqBitmap: Incorrect data "
+ "found. newData[%d]=0x%x initialBitmap[%d]=0x%x",
+ n, newData.at(0).bitmap[n], n, initialBitmap[n] );
+ }
+ }
+
+ // Clear the vpd just in case
+ rc = clearBadDqBitmap( ocmb, rank );
+ if ( SUCCESS != rc )
+ {
+ TS_FAIL( "ERROR: clearBadDqBitmap failed" );
+ }
+
+ TS_INFO("- TestAxoneReadWriteBadDqBitmap - End -");
+
+ }
+
+ }
+
+//------------------------------------------------------------------------------
+
+};
+#endif
diff --git a/src/usr/diag/prdf/test/prdf_hb_common_test.mk b/src/usr/diag/prdf/test/prdf_hb_common_test.mk
index a148e0c24..5d1e7ea36 100755
--- a/src/usr/diag/prdf/test/prdf_hb_common_test.mk
+++ b/src/usr/diag/prdf/test/prdf_hb_common_test.mk
@@ -70,6 +70,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/cache/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/pm/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/lib/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/imageProcs
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs
EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include
EXTRAINCDIR += ${ROOTPATH}/src/import/
@@ -91,8 +92,9 @@ TESTS += ${PRD_USR_TEST_PATH}/prdfTest.H
TESTS += ${PRD_USR_TEST_PATH}/prdfTest_XBus.H
TESTS += ${PRD_USR_TEST_PATH}/prdfTest_ABus.H
TESTS += ${PRD_USR_TEST_PATH}/prdfTest_ProcCentFir.H
+TESTS += ${PRD_USR_TEST_PATH}/prdfTest_BadDqBitmap.H
TESTS += ${PRD_USR_TEST_PATH}/prdfTest_Ex.H
-TESTS += $(if $(CONFIG_AXONE_BRING_UP),,${PRD_USR_TEST_PATH}/prdfTest_NimbusTpLFir.H)
+TESTS += ${PRD_USR_TEST_PATH}/prdfTest_NimbusTpLFir.H
#@TODO RTC:178802
#TESTS += ${PRD_USR_TEST_PATH}/prdfTest_Mcs.H
diff --git a/src/usr/diag/prdf/test/prdfsimHomRegisterAccess.C b/src/usr/diag/prdf/test/prdfsimHomRegisterAccess.C
index 3e3079883..d6b02b5ee 100755
--- a/src/usr/diag/prdf/test/prdfsimHomRegisterAccess.C
+++ b/src/usr/diag/prdf/test/prdfsimHomRegisterAccess.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -43,7 +43,7 @@ SimScomAccessor::~SimScomAccessor()
uint32_t SimScomAccessor::Access(TARGETING::TargetHandle_t i_target,
BitString & bs,
uint64_t registerId,
- MopRegisterAccess::Operation operation) const
+ RegisterAccess::Operation operation) const
{
PRDF_DENTER("SimScomAccessor::Access()");
uint32_t rc = SUCCESS;
@@ -53,8 +53,8 @@ uint32_t SimScomAccessor::Access(TARGETING::TargetHandle_t i_target,
{
switch (operation)
{
- case MopRegisterAccess::WRITE: l_op = ScrDB::WRITE; break;
- case MopRegisterAccess::READ: l_op = ScrDB::READ; break;
+ case RegisterAccess::WRITE: l_op = ScrDB::WRITE; break;
+ case RegisterAccess::READ: l_op = ScrDB::READ; break;
default:
PRDF_ERR( "SimScomAccessor::Access() unsupported operation: 0x%X", operation );
rc = PRD_SCANCOM_FAILURE;
diff --git a/src/usr/diag/prdf/test/prdfsimHomRegisterAccess.H b/src/usr/diag/prdf/test/prdfsimHomRegisterAccess.H
index b8a610f75..f5566eb54 100755
--- a/src/usr/diag/prdf/test/prdfsimHomRegisterAccess.H
+++ b/src/usr/diag/prdf/test/prdfsimHomRegisterAccess.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -73,7 +73,7 @@ class SimScomAccessor : public ScomAccessor
virtual uint32_t Access(TARGETING::TargetHandle_t i_target,
BitString & bs,
uint64_t registerId,
- MopRegisterAccess::Operation operation) const;
+ RegisterAccess::Operation operation) const;
private:
diff --git a/src/usr/diag/prdf/test/prdfsimScrDB.C b/src/usr/diag/prdf/test/prdfsimScrDB.C
index 6308ba423..a6a67bd9c 100755
--- a/src/usr/diag/prdf/test/prdfsimScrDB.C
+++ b/src/usr/diag/prdf/test/prdfsimScrDB.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -24,7 +24,7 @@
/* IBM_PROLOG_END_TAG */
#include "prdfsimScrDB.H"
-#include <iipMopRegisterAccess.h>
+#include <prdfHomRegisterAccess.H>
#include <prdfTrace.H>
#include <prdfPlatServices.H>
#include "prdfsimServices.H"
diff --git a/src/usr/dump/dumpCollect.C b/src/usr/dump/dumpCollect.C
index 6b95a2c2d..b85bcd28b 100644
--- a/src/usr/dump/dumpCollect.C
+++ b/src/usr/dump/dumpCollect.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2019 */
+/* Contributors Listed Below - COPYRIGHT 2012,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -41,6 +41,8 @@
#include <dump/dumpif.H>
#include <util/utiltce.H>
#include <isteps/mem_utils.H>
+#include <string.h>
+#include <stdio.h>
#include <sys/msg.h> // message Q's
#include <mbox/mbox_queues.H> //
@@ -54,7 +56,163 @@ TRAC_INIT(&g_trac_dump, "DUMP", 4*KILOBYTE);
namespace DUMP
{
-
+////////////
+// Define an SPR number to name str map. Note that this inverse of how
+// the HWP uses it... so use the same mechanism/data - just inverse
+std::map<uint32_t, const char*> SPRNUM_MAP;
+typedef std::map<uint32_t, const char*>::iterator SPRNUM_MAP_IT;
+
+#define LIST_SPR_NAME_REG(_op_)\
+ _op_(XER ,1 )\
+ _op_(DSCR_RU ,3 )\
+ _op_(LR ,8 )\
+ _op_(CTR ,9 )\
+ _op_(UAMR ,13 )\
+ _op_(DSCR ,17 )\
+ _op_(DSISR ,18 )\
+ _op_(DAR ,19 )\
+ _op_(DEC ,22 )\
+ _op_(SDR1 ,25 )\
+ _op_(SRR0 ,26 )\
+ _op_(SRR1 ,27 )\
+ _op_(CFAR ,28 )\
+ _op_(AMR ,29 )\
+ _op_(PIDR ,48 )\
+ _op_(IAMR ,61 )\
+ _op_(TFHAR ,128 )\
+ _op_(TFIAR ,129 )\
+ _op_(TEXASR ,130 )\
+ _op_(TEXASRU ,131 )\
+ _op_(CTRL_RU ,136 )\
+ _op_(TIDR ,144 )\
+ _op_(CTRL ,152 )\
+ _op_(FSCR ,153 )\
+ _op_(UAMOR ,157 )\
+ _op_(GSR ,158 )\
+ _op_(PSPB ,159 )\
+ _op_(DPDES ,176 )\
+ _op_(DAWR0 ,180 )\
+ _op_(RPR ,186 )\
+ _op_(CIABR ,187 )\
+ _op_(DAWRX0 ,188 )\
+ _op_(HFSCR ,190 )\
+ _op_(VRSAVE ,256 )\
+ _op_(SPRG3_RU ,259 )\
+ _op_(TB ,268 )\
+ _op_(TBU_RU ,269 )\
+ _op_(SPRG0 ,272 )\
+ _op_(SPRG1 ,273 )\
+ _op_(SPRG2 ,274 )\
+ _op_(SPRG3 ,275 )\
+ _op_(SPRC ,276 )\
+ _op_(SPRD ,277 )\
+ _op_(CIR ,283 )\
+ _op_(TBL ,284 )\
+ _op_(TBU ,285 )\
+ _op_(TBU40 ,286 )\
+ _op_(PVR ,287 )\
+ _op_(HSPRG0 ,304 )\
+ _op_(HSPRG1 ,305 )\
+ _op_(HDSISR ,306 )\
+ _op_(HDAR ,307 )\
+ _op_(SPURR ,308 )\
+ _op_(PURR ,309 )\
+ _op_(HDEC ,310 )\
+ _op_(HRMOR ,313 )\
+ _op_(HSRR0 ,314 )\
+ _op_(HSRR1 ,315 )\
+ _op_(TFMR ,317 )\
+ _op_(LPCR ,318 )\
+ _op_(LPIDR ,319 )\
+ _op_(HMER ,336 )\
+ _op_(HMEER ,337 )\
+ _op_(PCR ,338 )\
+ _op_(HEIR ,339 )\
+ _op_(AMOR ,349 )\
+ _op_(TIR ,446 )\
+ _op_(PTCR ,464 )\
+ _op_(USPRG0 ,496 )\
+ _op_(USPRG1 ,497 )\
+ _op_(UDAR ,499 )\
+ _op_(SEIDR ,504 )\
+ _op_(URMOR ,505 )\
+ _op_(USRR0 ,506 )\
+ _op_(USRR1 ,507 )\
+ _op_(UEIR ,509 )\
+ _op_(ACMCR ,510 )\
+ _op_(SMFCTRL ,511 )\
+ _op_(SIER_RU ,768 )\
+ _op_(MMCR2_RU ,769 )\
+ _op_(MMCRA_RU ,770 )\
+ _op_(PMC1_RU ,771 )\
+ _op_(PMC2_RU ,772 )\
+ _op_(PMC3_RU ,773 )\
+ _op_(PMC4_RU ,774 )\
+ _op_(PMC5_RU ,775 )\
+ _op_(PMC6_RU ,776 )\
+ _op_(MMCR0_RU ,779 )\
+ _op_(SIAR_RU ,780 )\
+ _op_(SDAR_RU ,781 )\
+ _op_(MMCR1_RU ,782 )\
+ _op_(SIER ,784 )\
+ _op_(MMCR2 ,785 )\
+ _op_(MMCRA ,786 )\
+ _op_(PMC1 ,787 )\
+ _op_(PMC2 ,788 )\
+ _op_(PMC3 ,789 )\
+ _op_(PMC4 ,790 )\
+ _op_(PMC5 ,791 )\
+ _op_(PMC6 ,792 )\
+ _op_(MMCR0 ,795 )\
+ _op_(SIAR ,796 )\
+ _op_(SDAR ,797 )\
+ _op_(MMCR1 ,798 )\
+ _op_(IMC ,799 )\
+ _op_(BESCRS ,800 )\
+ _op_(BESCRSU ,801 )\
+ _op_(BESCRR ,802 )\
+ _op_(BESCRRU ,803 )\
+ _op_(EBBHR ,804 )\
+ _op_(EBBRR ,805 )\
+ _op_(BESCR ,806 )\
+ _op_(LMRR ,813 )\
+ _op_(LMSER ,814 )\
+ _op_(TAR ,815 )\
+ _op_(ASDR ,816 )\
+ _op_(PSSCR_SU ,823 )\
+ _op_(IC ,848 )\
+ _op_(VTB ,849 )\
+ _op_(LDBAR ,850 )\
+ _op_(MMCRC ,851 )\
+ _op_(PMSR ,853 )\
+ _op_(PMMAR ,854 )\
+ _op_(PSSCR ,855 )\
+ _op_(L2QOSR ,861 )\
+ _op_(WORC ,863 )\
+ _op_(TRIG0 ,880 )\
+ _op_(TRIG1 ,881 )\
+ _op_(TRIG2 ,882 )\
+ _op_(PMCR ,884 )\
+ _op_(RWMR ,885 )\
+ _op_(WORT ,895 )\
+ _op_(PPR ,896 )\
+ _op_(PPR32 ,898 )\
+ _op_(TSCR ,921 )\
+ _op_(TTR ,922 )\
+ _op_(TRACE ,1006)\
+ _op_(HID ,1008)\
+ _op_(PIR ,1023)\
+ _op_(NIA ,2000)\
+ _op_(MSR ,2001)\
+ _op_(CR ,2002)\
+ _op_(FPSCR ,2003)\
+ _op_(VSCR ,2004)\
+ _op_(SLBE ,2005)\
+ _op_(SLBV ,2006)
+
+
+#define DO_SPRNUM_MAP(in_name, in_number)\
+ SPRNUM_MAP[in_number] = #in_name;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@@ -107,6 +265,31 @@ errlHndl_t doDumpCollect(void)
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
+// Replace reg num with name
+void replaceRegNumWithName( hostArchRegDataEntry *hostRegData )
+{
+ char str[sizeof(reg_t)];
+
+ if(hostRegData->reg.type == DUMP_ARCH_REG_TYPE_GPR)
+ {
+ snprintf(str,sizeof(reg_t), "GPR%d\0", hostRegData->reg.num);
+ strncpy(hostRegData->reg.name, str, sizeof(reg_t));
+ }
+ else if (hostRegData->reg.type == DUMP_ARCH_REG_TYPE_SPR)
+ {
+ if(SPRNUM_MAP.find(hostRegData->reg.num) != SPRNUM_MAP.end())
+ {
+ strncpy(hostRegData->reg.name, SPRNUM_MAP[hostRegData->reg.num], sizeof(reg_t));
+ }
+ //else unknown... leave as number for debug
+ }
+ //else unknown type... leave as number for debug
+
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
// Returns the physical address corresponding to a PHYP MDST/MDRT entry
void* getPhysAddr( uint64_t i_phypAddr )
{
@@ -153,6 +336,9 @@ errlHndl_t copyArchitectedRegs(void)
// Architected Reg Dump table struct pointers
procDumpAreaEntry *procTableEntry = nullptr;
+ //Setup SPR num to string mapping
+ LIST_SPR_NAME_REG(DO_SPRNUM_MAP)
+
do
{
// Get the PROC_DUMP_AREA_TBL address from SPIRAH
@@ -196,16 +382,30 @@ errlHndl_t copyArchitectedRegs(void)
procTableEntry = reinterpret_cast<procDumpAreaEntry *>(procTableAddr);
pDstAddrBase = getPhysAddr(procTableEntry->dstArrayAddr);
vMapDstAddrBase = mm_block_map(pDstAddrBase,
- procTableEntry->dstArraySize);
+ (ALIGN_PAGE(procTableEntry->dstArraySize) + PAGESIZE));
+
+ //Need to adjust actual virtual address due to mm_block_map only
+ //mapping on page boundary to account for non page aligned addresses
+ //from PHYP/OPAL
+ uint64_t tmpAddr = reinterpret_cast<uint64_t>(vMapDstAddrBase);
+ vMapDstAddrBase = reinterpret_cast<void*>(tmpAddr +
+ (procTableEntry->dstArrayAddr & (PAGESIZE-1)));
// Map architected register reserved memory to VA addresses
- uint64_t srcAddr = ISTEP::get_top_homer_mem_addr() -
- VMM_ARCH_REG_DATA_SIZE_ALL_PROC -
- VMM_ALL_HOMER_OCC_MEMORY_SIZE;
+ TARGETING::Target * l_sys = NULL;
+ TARGETING::targetService().getTopLevelTarget( l_sys );
+ assert(l_sys != NULL);
+ auto srcAddr =
+ l_sys->getAttr<TARGETING::ATTR_SBE_ARCH_DUMP_ADDR>();
+
pSrcAddrBase = reinterpret_cast<void * const>(srcAddr);
vMapSrcAddrBase = mm_block_map(pSrcAddrBase,
VMM_ARCH_REG_DATA_SIZE_ALL_PROC);
+ TRACDCOMP(g_trac_dump, "src address [0x%X] [%p], destArrayaddr"
+ " [%X] dest[%p] [%p]", srcAddr, vMapSrcAddrBase,
+ procTableEntry->dstArrayAddr, pDstAddrBase, vMapDstAddrBase);
+
// Get list of functional processor chips, in MPIPL path we
// don't expect any deconfiguration
TARGETING::TargetHandleList procChips;
@@ -214,13 +414,13 @@ errlHndl_t copyArchitectedRegs(void)
uint64_t dstTempAddr = reinterpret_cast<uint64_t>(vMapDstAddrBase);
procTableEntry->capArraySize = 0;
- for (const auto & procChip: procChips)
+ for (uint32_t procNum = 0; procNum < procChips.size(); procNum++)
{
- uint8_t procNum = procChip->getAttr<TARGETING::ATTR_POSITION>();
// Base addresses w.r.t PROC positions. This is static here
// and used for reference below to calculate all other addresses
uint64_t procSrcAddr = (reinterpret_cast<uint64_t>(vMapSrcAddrBase)+
procNum * VMM_ARCH_REG_DATA_PER_PROC_SIZE);
+ TRACDCOMP(g_trac_dump, "SBE Proc[%d] [%p]", procNum, procSrcAddr);
sbeArchRegDumpProcHdr_t *sbeProcHdr =
reinterpret_cast<sbeArchRegDumpProcHdr_t *>(procSrcAddr);
@@ -294,7 +494,11 @@ errlHndl_t copyArchitectedRegs(void)
hostArchRegDataHdr *hostHdr =
reinterpret_cast<hostArchRegDataHdr *>(dstTempAddr);
+ TRACDCOMP(g_trac_dump, " Thread[%d] src[%p] dest[%p]",
+ idx, procSrcAddr, dstTempAddr);
+
// Fill thread header info
+ memset(hostHdr, 0x0, sizeof(hostHdr));
hostHdr->pir = sbeTdHdr->pir;
hostHdr->coreState = sbeTdHdr->coreState;
hostHdr->iv_regArrayHdr.hdatOffset =
@@ -330,10 +534,16 @@ errlHndl_t copyArchitectedRegs(void)
hostArchRegDataEntry *hostRegData =
reinterpret_cast<hostArchRegDataEntry *>(dstTempAddr);
- hostRegData->regType = sbeRegData->regType;
- hostRegData->regNum = sbeRegData->regNum;
+ hostRegData->reg.type = sbeRegData->regType;
+ hostRegData->reg.num = sbeRegData->regNum;
hostRegData->regVal = sbeRegData->regVal;
+ // If HOST type is PHYP replace register number with strings
+ if (TARGETING::is_phyp_load())
+ {
+ replaceRegNumWithName(hostRegData);
+ }
+
dstTempAddr = reinterpret_cast<uint64_t>(dstTempAddr +
sizeof(hostArchRegDataEntry));
//Update the SBE data source address to point to the
@@ -367,9 +577,6 @@ errlHndl_t copyArchitectedRegs(void)
procTableEntry->capArrayAddr = procTableEntry->dstArrayAddr;
// Update the PDA Table Entries to Attribute to be fetched in istep 21
- TARGETING::TargetService& targetService = TARGETING::targetService();
- TARGETING::Target* l_sys = NULL;
- targetService.getTopLevelTarget(l_sys);
l_sys->setAttr<TARGETING::ATTR_PDA_THREAD_REG_STATE_ENTRY_FORMAT>(
procTableEntry->threadRegVersion);
l_sys->setAttr<TARGETING::ATTR_PDA_THREAD_REG_ENTRY_SIZE>(
diff --git a/src/usr/errl/errl.mk b/src/usr/errl/errl.mk
index 8cab37324..8caf92216 100644
--- a/src/usr/errl/errl.mk
+++ b/src/usr/errl/errl.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2015,2018
+# Contributors Listed Below - COPYRIGHT 2015,2019
# [+] International Business Machines Corp.
#
#
@@ -41,3 +41,4 @@ OBJS += errludsensor.o
OBJS += errludstate.o
OBJS += errlmanager_common.o
OBJS += errli2c.o
+OBJS += errludattribute.o
diff --git a/src/usr/errl/errlentry.C b/src/usr/errl/errlentry.C
index 61eeb15f2..78e1f9bc6 100644
--- a/src/usr/errl/errlentry.C
+++ b/src/usr/errl/errlentry.C
@@ -49,7 +49,6 @@
#include <errl/errludstate.H>
#include <errl/errli2c.H>
#include <trace/interface.H>
-#include <config.h>
#include "../trace/entry.H"
#include <util/align.H>
@@ -60,7 +59,6 @@
#include <targeting/common/targetservice.H>
#include <targeting/common/utilFilter.H>
#include <targeting/common/commontargeting.H>
-#include <config.h>
#include <initservice/initserviceif.H>
#include <attributeenums.H>
#include "errlentry_consts.H"
@@ -405,18 +403,6 @@ void ErrlEntry::addPartCallout(const TARGETING::Target *i_target,
i_target, i_partType, i_priority,
i_deconfigState, i_gardErrorType);
- // Need targeting for nvdimm check
- if(Util::isTargetingLoaded() && TARGETING::targetService().isInitialized())
- {
- // Add procedure callout to replace the cable to the NVDIMM
- if( (i_target->getAttr<TARGETING::ATTR_TYPE>() == TARGETING::TYPE_DIMM)
- && ( isNVDIMM(i_target) ) )
- {
- addProcedureCallout( HWAS::EPUB_PRC_NVDIMM_ERR,
- HWAS::SRCI_PRIORITY_HIGH );
- }
- }
-
const void* pData = nullptr;
uint32_t size = 0;
TARGETING::EntityPath* ep = nullptr;
@@ -599,42 +585,7 @@ void ErrlEntry::addHwCallout(const TARGETING::Target *i_target,
i_deconfigState, i_gardErrorType);
#endif
- // Add procedure callout to replace the cable to the NVDIMM
- if( isNVDIMM(i_target) )
- {
- addProcedureCallout( HWAS::EPUB_PRC_NVDIMM_ERR,
- HWAS::SRCI_PRIORITY_HIGH );
- }
-
TARGETING::EntityPath ep;
- TARGETING::TYPE l_type = i_target->getAttr<TARGETING::ATTR_TYPE>();
-
- TARGETING::TYPE l_type_ecid = l_type;
- const TARGETING::Target* l_parentTarget = i_target;
- if((l_type_ecid != TARGETING::TYPE_MEMBUF) &&
- (l_type_ecid != TARGETING::TYPE_PROC) &&
- (l_type_ecid != TARGETING::TYPE_NODE)
- )
- {
- //since this returns NULL if the parent is not found,
- // we need a placeholder
- const TARGETING::Target* l_tempParentTarget =
- getParentChip(l_parentTarget);
- if(l_tempParentTarget != NULL)
- {
- l_parentTarget = l_tempParentTarget;
- l_type_ecid = l_parentTarget->getAttr<TARGETING::ATTR_TYPE>();
- }
- }
- //if we have found a type_membuf or type_proc, store the ecid
- //otherwise, (type_node), do nothing.
- if(l_type_ecid == TARGETING::TYPE_MEMBUF ||
- l_type_ecid == TARGETING::TYPE_PROC)
- {
- ErrlUserDetailsAttribute(l_parentTarget,
- TARGETING::ATTR_ECID).addToLog(this);
- }
-
ep = i_target->getAttr<TARGETING::ATTR_PHYS_PATH>();
// size is total EntityPath size minus unused path elements
@@ -704,99 +655,24 @@ void ErrlEntry::addVersionInfo()
if ( !INITSERVICE::spBaseServicesEnabled()
&& PNOR::isSectionAvailable(PNOR::VERSION))
{
-
-// Setting variables only used in config secureboot
-#ifdef CONFIG_SECUREBOOT
- bool l_secureSectionLoaded = false;
- errlHndl_t l_errl_loadSecureSection = nullptr;
-#endif
-
- errlHndl_t l_errl = nullptr;
-
do
{
-
-#ifdef CONFIG_SECUREBOOT
- l_errl_loadSecureSection = PNOR::loadSecureSection(PNOR::VERSION);
- if (l_errl_loadSecureSection)
- {
- TRACFCOMP( g_trac_errl,
- "addVersionInfo: Failed to load secure VERSION");
- // Since an error occurred while attempting to add version info
- // to another error log there is nothing that can be done with
- // this error since attempting to commit it will lead to an
- // infinite loop of committing the error and then recalling this
- // function. If this error occurred then the VERSION partition
- // is not added and the error log commit continues.
- delete l_errl_loadSecureSection;
- l_errl_loadSecureSection = nullptr;
- break;
- }
- else
- {
- l_secureSectionLoaded = true;
- }
-#endif
-
- // Get PNOR Version
- PNOR::SectionInfo_t l_pnorVersionInfo;
- l_errl = getSectionInfo(PNOR::VERSION, l_pnorVersionInfo);
-
- if (l_errl)
- {
- TRACFCOMP( g_trac_errl,
- "addVersionInfo: Failed to getSectionInfo");
- // Since an error occurred while attempting to add version info
- // to another error log there is nothing that can be done with
- // this error since attempting to commit it will lead to an
- // infinite loop of committing the error and then recalling this
- // function. If this error occurred then the VERSION partition
- // is not added and the error log commit continues.
- delete l_errl;
- l_errl = nullptr;
- break;
- }
-
const uint8_t* l_versionData =
- reinterpret_cast<uint8_t*>(l_pnorVersionInfo.vaddr);
-
- size_t l_numberOfBytes = 0;
+ ERRORLOG::getCachedVersionPartition();
+ size_t l_versionSize =
+ ERRORLOG::getCachedVersionPartitionSize();
- // Determine the size of the version data. The max size is the given
- // size in the SectionInfo but can be less.
- while ((static_cast<char>(l_versionData[l_numberOfBytes]) != '\0')
- && l_numberOfBytes < l_pnorVersionInfo.size)
+ if(!l_versionData || !l_versionSize)
{
- ++l_numberOfBytes;
+ break;
}
- char l_pVersionString[l_numberOfBytes + 1]={0};
+ char l_pVersionString[l_versionSize + 1]={0};
- memcpy(l_pVersionString, l_versionData, l_numberOfBytes);
+ memcpy(l_pVersionString, l_versionData, l_versionSize);
ErrlUserDetailsString(l_pVersionString).addToLog(this);
} while(0);
-
-#ifdef CONFIG_SECUREBOOT
- if (l_secureSectionLoaded)
- {
- l_errl_loadSecureSection = PNOR::unloadSecureSection(PNOR::VERSION);
- if(l_errl_loadSecureSection)
- {
- TRACFCOMP( g_trac_errl,
- "addVersionInfo: Failed to unload secure VERSION");
- // Since an error occurred while attempting to add version info
- // to another error log there is nothing that can be done with
- // this error since attempting to commit it will lead to an
- // infinite loop of committing the error and then recalling this
- // function. If this error occurred then the VERSION partition
- // is not added and the error log commit continues.
- delete l_errl_loadSecureSection;
- l_errl_loadSecureSection = nullptr;
- }
- }
-#endif
-
}
// End of IPL only block
@@ -947,75 +823,142 @@ void ErrlEntry::checkHiddenLogsEnable( )
}
///////////////////////////////////////////////////////////////////////////////
-// Called by addHwCallout to get the part and serial numbers from the current
-// target so that it can be appended to the error log
-#ifdef CONFIG_BMC_IPMI
- void ErrlEntry::addPartAndSerialNumbersToErrLog
-(const TARGETING::Target * i_target)
+// Called by addHwCallout to retrieve various pieces of card
+// and/or chip data, e.g. part number, serial number, ecid.
+void ErrlEntry::addPartIdInfoToErrLog
+ (const TARGETING::Target * i_target)
{
- TRACDCOMP(g_trac_errl, ENTER_MRK"ErrlEntry::addPartAndSerialNumbersToErrLog()");
+ TRACDCOMP(g_trac_errl, ENTER_MRK"ErrlEntry::addPartIdInfoToErrLog()");
-
- // Get the type of the target
const TARGETING::Target * l_target = i_target;
- TARGETING::TYPE l_type = l_target->getAttr<TARGETING::ATTR_TYPE>();
+ const TARGETING::Target * l_targetPrev = nullptr;
+ ErrlUserDetailsAttribute* l_attrdata = nullptr;
- do
+ //Add the part number to the error log.
+ TARGETING::TargetHandleList l_parentList;
+ TARGETING::ATTR_PART_NUMBER_type l_PN = {};
+ while( !l_target->tryGetAttr<TARGETING::ATTR_PART_NUMBER>(l_PN) )
{
- if((l_type != TARGETING::TYPE_PROC ) &&
- (l_type != TARGETING::TYPE_DIMM ) &&
- (l_type != TARGETING::TYPE_MEMBUF ))
+ // Get immediate parent
+ TARGETING::targetService().getAssociated(
+ l_parentList,
+ l_target,
+ TARGETING::TargetService::PARENT,
+ TARGETING::TargetService::IMMEDIATE);
+
+ // never found a match...
+ if (l_parentList.size() != 1)
{
- TARGETING::PredicatePostfixExpr l_procDimmMembuf;
- TARGETING::TargetHandleList l_pList;
+ l_target = nullptr;
+ break;
+ }
- TARGETING::PredicateCTM l_procs(TARGETING::CLASS_CHIP,
- TARGETING::TYPE_PROC);
+ l_target = l_parentList[0];
+ l_parentList.clear(); // clear out old entry
+ } // end while
+ if( l_target )
+ {
+ l_attrdata = new ErrlUserDetailsAttribute(l_target);
+ l_attrdata->addData(TARGETING::ATTR_PART_NUMBER);
+ l_targetPrev = l_target;
+ }
- TARGETING::PredicateCTM l_dimms(TARGETING::CLASS_CARD,
- TARGETING::TYPE_DIMM);
+ // Note - it is extremely likely that we will end up with the same
+ // target for PN and SN, but since this is error path only we're
+ // opting for thoroughness over efficiency.
- TARGETING::PredicateCTM l_membufs(TARGETING::CLASS_CHIP,
- TARGETING::TYPE_MEMBUF);
+ //Add the serial number to the error log.
+ l_target = i_target;
+ TARGETING::ATTR_SERIAL_NUMBER_type l_SN = {};
+ while( !l_target->tryGetAttr<TARGETING::ATTR_SERIAL_NUMBER>(l_SN) )
+ {
+ // Get immediate parent
+ TARGETING::targetService().getAssociated(
+ l_parentList,
+ l_target,
+ TARGETING::TargetService::PARENT,
+ TARGETING::TargetService::IMMEDIATE);
- l_procDimmMembuf.push(&l_procs).push(&l_dimms).Or()
- .push(&l_membufs).Or();
+ // never found a match...
+ if (l_parentList.size() != 1)
+ {
+ l_target = nullptr;
+ break;
+ }
- // Search for any parents with TYPE_PROC, TYPE_DIMM, or TYPE_MEMBUF
- TARGETING::targetService().getAssociated( l_pList, l_target,
- TARGETING::TargetService::PARENT,
- TARGETING::TargetService::ALL,
- &l_procDimmMembuf);
- // If no parent of desired type is present, break
- if(!l_pList.size())
- {
- TRACFCOMP(g_trac_errl, "Error! errlentry.C::addPartAndSerialNumbersToErrLog - No parent containing Serial/Part numbers found.");
- break;
- }
- else
- {
- // We have found the parent
- l_target = l_pList[0];
- }
+ l_target = l_parentList[0];
+ l_parentList.clear(); // clear out old entry
+ } // end while
+ if( l_target )
+ {
+ // not likely to happen, but just in case...
+ if( l_attrdata && (l_targetPrev != l_target) )
+ {
+ // got a new target, commit the previous data and start over
+ l_attrdata->addToLog(this);
+ delete l_attrdata;
+ l_attrdata = nullptr;
+ }
+ if( !l_attrdata )
+ {
+ l_attrdata = new ErrlUserDetailsAttribute(l_target);
+ }
+
+ l_attrdata->addData(TARGETING::ATTR_SERIAL_NUMBER);
+ l_targetPrev = l_target;
+ }
+
+ //Add the ECID to the error log.
+ l_target = i_target;
+ TARGETING::ATTR_ECID_type l_ECID = {};
+ while( !l_target->tryGetAttr<TARGETING::ATTR_ECID>(l_ECID) )
+ {
+ // Get immediate parent
+ TARGETING::targetService().getAssociated(
+ l_parentList,
+ l_target,
+ TARGETING::TargetService::PARENT,
+ TARGETING::TargetService::IMMEDIATE);
+ // never found a match...
+ if (l_parentList.size() != 1)
+ {
+ l_target = nullptr;
+ break;
}
- // We have made it here so we have found a target that contains
- // ATTR_SERIAL_NUMBER and ATTR_PART_NUMBER
- //Add the part number to the error log.
- ErrlUserDetailsAttribute( l_target,
- TARGETING::ATTR_PART_NUMBER).addToLog(this);
- //Add the serial number to the error log.
- ErrlUserDetailsAttribute( l_target,
- TARGETING::ATTR_SERIAL_NUMBER).addToLog(this);
+ l_target = l_parentList[0];
+ l_parentList.clear(); // clear out old entry
+ } // end while
+ if( l_target )
+ {
+ // not likely to happen, but just in case...
+ if( l_attrdata && (l_targetPrev != l_target) )
+ {
+ // got a new target, commit the previous data and start over
+ l_attrdata->addToLog(this);
+ delete l_attrdata;
+ l_attrdata = nullptr;
+ }
+ if( !l_attrdata )
+ {
+ l_attrdata = new ErrlUserDetailsAttribute(l_target);
+ }
+ l_attrdata->addData(TARGETING::ATTR_ECID);
+ l_targetPrev = l_target;
+ }
- }while( 0 );
+ if( l_attrdata )
+ {
+ l_attrdata->addToLog(this);
+ delete l_attrdata;
+ }
- TRACDCOMP(g_trac_errl, EXIT_MRK"ErrlEntry::addPartAndSerialNumbersToErrLog()");
+ TRACDCOMP(g_trac_errl, EXIT_MRK"ErrlEntry::addPartIdInfoToErrLog()");
}
-
+#ifdef CONFIG_BMC_IPMI
// Find the FRU ID associated with target.
// Returns first FRU ID found as it navigates the target's parent hierarchy
TARGETING::ATTR_FRU_ID_type getFRU_ID(TARGETING::Target * i_target)
@@ -1154,8 +1097,8 @@ void ErrlEntry::commit( compId_t i_committerComponent )
this);
if(!l_err)
{
+ addPartIdInfoToErrLog( l_target );
#ifdef CONFIG_BMC_IPMI
- addPartAndSerialNumbersToErrLog( l_target );
addSensorDataToErrLog( l_target, l_ud->priority);
#endif
}
diff --git a/src/usr/errl/errlentry_consts.H b/src/usr/errl/errlentry_consts.H
index e6784c217..816738010 100644
--- a/src/usr/errl/errlentry_consts.H
+++ b/src/usr/errl/errlentry_consts.H
@@ -66,7 +66,6 @@ const epubProcToSub_t PROCEDURE_TO_SUBSYS_TABLE[] =
{ EPUB_PRC_COOLING_SYSTEM_ERR , EPUB_MISC_SUBSYS },
{ EPUB_PRC_FW_VERIFICATION_ERR , EPUB_FIRMWARE_SUBSYS },
{ EPUB_PRC_GPU_ISOLATION_PROCEDURE, EPUB_CEC_HDW_SUBSYS },
- { EPUB_PRC_NVDIMM_ERR , EPUB_MEMORY_SUBSYS },
};
struct epubTargetTypeToSub_t
@@ -103,6 +102,13 @@ const epubTargetTypeToSub_t TARGET_TO_SUBSYS_TABLE[] =
{ TARGETING::TYPE_TPM , EPUB_CEC_HDW_SUBSYS },
{ TARGETING::TYPE_MC , EPUB_MEMORY_SUBSYS },
{ TARGETING::TYPE_SMPGROUP , EPUB_CEC_HDW_SUBSYS },
+ { TARGETING::TYPE_OMI , EPUB_MEMORY_SUBSYS },
+ { TARGETING::TYPE_MCC , EPUB_MEMORY_SUBSYS },
+ { TARGETING::TYPE_OMIC , EPUB_MEMORY_SUBSYS },
+ { TARGETING::TYPE_OCMB_CHIP , EPUB_MEMORY_SUBSYS },
+ { TARGETING::TYPE_MEM_PORT , EPUB_MEMORY_SUBSYS },
+ { TARGETING::TYPE_I2C_MUX , EPUB_CEC_HDW_SUBSYS },
+ { TARGETING::TYPE_PMIC , EPUB_MEMORY_SUBSYS },
};
struct epubBusTypeToSub_t
@@ -120,6 +126,7 @@ const epubBusTypeToSub_t BUS_TO_SUBSYS_TABLE[] =
{ HWAS::I2C_BUS_TYPE , EPUB_CEC_HDW_I2C_DEVS },
{ HWAS::PSI_BUS_TYPE , EPUB_CEC_HDW_SP_PHYP_INTF },
{ HWAS::O_BUS_TYPE , EPUB_PROCESSOR_BUS_CTL },
+ { HWAS::OMI_BUS_TYPE , EPUB_MEMORY_BUS },
};
struct epubClockTypeToSub_t
@@ -159,6 +166,9 @@ const epubPartTypeToSub_t PART_TO_SUBSYS_TABLE[] =
{ HWAS::PROC_REF_CLOCK , EPUB_CEC_HDW_CLK_CTL },
{ HWAS::PCI_REF_CLOCK , EPUB_CEC_HDW_CLK_CTL },
{ HWAS::SMP_CABLE , EPUB_CEC_HDW_SUBSYS },
+ { HWAS::BPM_CABLE_PART_TYPE , EPUB_MEMORY_SUBSYS },
+ { HWAS::NV_CONTROLLER_PART_TYPE , EPUB_MEMORY_SUBSYS },
+ { HWAS::BPM_PART_TYPE , EPUB_MEMORY_SUBSYS },
};
struct epubSensorTypeToSub_t
diff --git a/src/usr/errl/errli2c.C b/src/usr/errl/errli2c.C
index b3838a866..2c814ca58 100644
--- a/src/usr/errl/errli2c.C
+++ b/src/usr/errl/errli2c.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,7 +33,6 @@
#include <hwas/common/deconfigGard.H>
#include <targeting/common/targetservice.H>
#include <targeting/common/utilFilter.H>
-#include <config.h>
#include <attributeenums.H>
#include <i2c/eepromif.H>
diff --git a/src/usr/errl/errlmanager.C b/src/usr/errl/errlmanager.C
index c32c2b2b7..2e787d2e0 100644
--- a/src/usr/errl/errlmanager.C
+++ b/src/usr/errl/errlmanager.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -50,15 +50,18 @@
#include <arch/pirformat.H>
#include <errldisplay/errldisplay.H>
#include <console/consoleif.H>
-#include <config.h>
#include <functional>
#include <hwas/common/deconfigGard.H>
#include <kernel/terminate.H>
#include <debugpointers.H>
+#include <sys/sync.h>
namespace ERRORLOG
{
+// Used in VERSION partition caching
+mutex_t g_errlMutex = MUTEX_INITIALIZER;
+
extern trace_desc_t* g_trac_errl;
#ifdef STORE_ERRL_IN_L3
@@ -103,6 +106,20 @@ bool compareEidToPlid(const uint32_t i_plid,
return (i_pair.first->eid() == i_plid);
}
+const uint8_t* getCachedVersionPartition()
+{
+ return Singleton<ErrlManager>::instance().getCachedVersionPartition();
+}
+
+size_t getCachedVersionPartitionSize()
+{
+ return Singleton<ErrlManager>::instance().getCachedVersionPartitionSize();
+}
+
+errlHndl_t cacheVersionPartition()
+{
+ return Singleton<ErrlManager>::instance().cacheVersionPartition();
+}
class AtLoadFunctions
{
@@ -120,6 +137,7 @@ AtLoadFunctions atLoadFunction;
///////////////////////////////////////////////////////////////////////////////
ErrlManager::ErrlManager() :
iv_pnorReadyForErrorLogs(false),
+ iv_recvdShutdownEvent(false),
iv_hwasProcessCalloutFn(NULL),
iv_msgQ(NULL),
iv_pnorAddr(NULL),
@@ -129,7 +147,9 @@ ErrlManager::ErrlManager() :
iv_isMboxEnabled(false), // assume mbox isn't ready yet..
iv_isIpmiEnabled(false), // assume ipmi isn't ready yet..
iv_nonInfoCommitted(false),
- iv_isErrlDisplayEnabled(false)
+ iv_isErrlDisplayEnabled(false),
+ iv_versionPartitionCache(nullptr),
+ iv_versionPartitionCacheSize(0)
{
TRACFCOMP( g_trac_errl, ENTER_MRK "ErrlManager::ErrlManager constructor" );
@@ -270,6 +290,30 @@ void ErrlManager::errlogMsgHndlr ()
msg_t * theMsg = msg_wait( iv_msgQ );
TRACFCOMP( g_trac_errl, INFO_MRK"Got an error log Msg - Type: 0x%08x",
theMsg->type );
+
+ // if we've been shut down then do nothing except delete the msg or send
+ // a response depending on the message type.
+ if(iv_recvdShutdownEvent)
+ {
+ TRACFCOMP( g_trac_errl, INFO_MRK "Error log service is shutdown. "
+ "Message will be ignored.");
+ switch( theMsg->type )
+ {
+ // Shutdown and flush message types expect a response
+ case ERRLOG_SHUTDOWN_TYPE:
+ case ERRLOG_FLUSH_TYPE:
+ msg_respond ( iv_msgQ, theMsg );
+ break;
+
+ // All other messages just need to be freed
+ default:
+ msg_free(theMsg);
+ break;
+ }
+ // wait for next message
+ continue;
+ }
+
//Process message just received
switch( theMsg->type )
{
@@ -1009,6 +1053,9 @@ void ErrlManager::errlogShutdown()
// prior to the PNOR resource provider shutting down.
PNOR::flush(PNOR::HB_ERRLOGS);
+ // Remember that we have recieved the shutdown event
+ iv_recvdShutdownEvent = true;
+
return;
}
@@ -1031,4 +1078,118 @@ bool ErrlManager::_updateErrlListIter(ErrlListItr_t & io_it)
return l_removed;
}
+const uint8_t* ErrlManager::getCachedVersionPartition() const
+{
+ mutex_lock(&g_errlMutex);
+ const uint8_t* l_versionPtr = iv_versionPartitionCache;
+ mutex_unlock(&g_errlMutex);
+ return l_versionPtr;
+}
+
+size_t ErrlManager::getCachedVersionPartitionSize() const
+{
+ mutex_lock(&g_errlMutex);
+ size_t l_versionSize = iv_versionPartitionCacheSize;
+ mutex_unlock(&g_errlMutex);
+ return l_versionSize;
+}
+
+errlHndl_t ErrlManager::cacheVersionPartition()
+{
+ errlHndl_t l_errl = nullptr;
+ bool l_versionPartitionLoaded = false;
+
+ do {
+
+ if(iv_isVersionPartitionCached ||
+ !PNOR::isSectionAvailable(PNOR::VERSION))
+ {
+ // No need to try to cache more than once or if
+ // there is no VERSION partition
+ break;
+ }
+
+#ifdef CONFIG_SECUREBOOT
+ l_errl = PNOR::loadSecureSection(PNOR::VERSION);
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_errl, ERR_MRK"ErrlManager::cacheVersionPartition() - could not load VERSION partition");
+ break;
+ }
+
+ l_versionPartitionLoaded = true;
+#endif
+
+ PNOR::SectionInfo_t l_pnorVersionSectionInfo;
+ l_errl = getSectionInfo(PNOR::VERSION, l_pnorVersionSectionInfo);
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_errl, ERR_MRK"ErrlManager::cacheVersionPartition() - could not get VERSION section info");
+ break;
+ }
+
+ // Since multiple errls may be at different stages of commit at the same
+ // time, lock the mutex to prevent atomicity issues
+ mutex_lock(&g_errlMutex);
+
+ iv_versionPartitionCacheSize = 0;
+
+ const char* l_versionSectionPtr =
+ reinterpret_cast<char*>(l_pnorVersionSectionInfo.vaddr);
+
+ // The actual size of the text in the VERSION partition is likely to be less
+ // than the declared size. Calculate the actual size here.
+ while((l_versionSectionPtr[iv_versionPartitionCacheSize] != '\0') &&
+ (iv_versionPartitionCacheSize < l_pnorVersionSectionInfo.size))
+ {
+ ++iv_versionPartitionCacheSize;
+ }
+ iv_versionPartitionCache = new uint8_t[iv_versionPartitionCacheSize];
+
+ memcpy(const_cast<uint8_t*>(iv_versionPartitionCache),
+ reinterpret_cast<uint8_t*>(l_pnorVersionSectionInfo.vaddr),
+ iv_versionPartitionCacheSize);
+
+ mutex_unlock(&g_errlMutex);
+
+ } while(0);
+
+ if(l_versionPartitionLoaded)
+ {
+#ifdef CONFIG_SECUREBOOT
+ errlHndl_t l_unloadSecErr = PNOR::unloadSecureSection(PNOR::VERSION);
+ if(l_unloadSecErr)
+ {
+ TRACFCOMP(g_trac_errl, ERR_MRK"ErrlManager::cacheVersionPartition() - could not unload VERSION partition");
+ if(l_errl)
+ {
+ l_unloadSecErr->plid(l_errl->plid());
+ errlCommit(l_unloadSecErr, ERRL_COMP_ID);
+ }
+ else
+ {
+ l_errl = l_unloadSecErr;
+ l_unloadSecErr = nullptr;
+ }
+ }
+#endif
+ }
+
+ if(l_errl)
+ {
+ if(iv_versionPartitionCache)
+ {
+ delete[] iv_versionPartitionCache;
+ iv_versionPartitionCache = nullptr;
+ }
+ iv_versionPartitionCacheSize = 0;
+ }
+
+ // Set the cache attrmpted flag regardless of whether we actually
+ // were able to cache the partition
+ iv_isVersionPartitionCached = true;
+
+ return l_errl;
+}
+
} // End namespace
diff --git a/src/usr/errl/errlmanager_common.C b/src/usr/errl/errlmanager_common.C
index e1e965e5a..bd84f2828 100644
--- a/src/usr/errl/errlmanager_common.C
+++ b/src/usr/errl/errlmanager_common.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -23,7 +23,6 @@
/* */
/* IBM_PROLOG_END_TAG */
#include <errl/errlmanager.H>
-#include <config.h>
#include <hwas/common/hwasCallout.H>
#include <errl/errlreasoncodes.H>
#ifdef CONFIG_BMC_IPMI
diff --git a/src/usr/errl/errludattribute.C b/src/usr/errl/errludattribute.C
new file mode 100644
index 000000000..5d031545f
--- /dev/null
+++ b/src/usr/errl/errludattribute.C
@@ -0,0 +1,84 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/errl/errludattribute.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errl/errludattribute.H>
+#include <errl/errlreasoncodes.H>
+#include <targeting/common/targetservice.H>
+#include <targeting/common/trace.H>
+
+namespace ERRORLOG
+{
+using namespace TARGETING;
+extern TARG_TD_t g_trac_errl;
+
+
+//------------------------------------------------------------------------------
+ErrlUserDetailsAttribute::ErrlUserDetailsAttribute(
+ const Target * i_pTarget, uint32_t i_attr)
+ : iv_pTarget(i_pTarget), iv_dataSize(0)
+{
+ // Set up ErrlUserDetails instance variables
+ iv_CompId = ERRL_COMP_ID;
+ iv_Version = 1;
+ iv_SubSection = ERRL_UDT_ATTRIBUTE;
+ // override the default of false
+ iv_merge = true;
+
+ // first, write out the HUID
+ addData(ATTR_HUID);
+ if (i_attr != ATTR_HUID) {
+ addData(i_attr);
+ }
+}
+
+//------------------------------------------------------------------------------
+ErrlUserDetailsAttribute::ErrlUserDetailsAttribute(
+ const Target * i_pTarget)
+ : iv_pTarget(i_pTarget), iv_dataSize(0)
+{
+ // Set up ErrlUserDetails instance variables
+ iv_CompId = ERRL_COMP_ID;
+ iv_Version = 1;
+ iv_SubSection = ERRL_UDT_ATTRIBUTE;
+ // override the default of false
+ iv_merge = true;
+
+ // first, write out the HUID
+ addData(ATTR_HUID);
+}
+
+//------------------------------------------------------------------------------
+ErrlUserDetailsAttribute::~ErrlUserDetailsAttribute()
+{ }
+} // namespace
+
+// Pull in the auto-generated portion
+// ::addData
+// ::dumpAll
+// Generated by xmltohb.pl
+#include <errludattribute_gen.C>
+
diff --git a/src/usr/errl/errludlogregister.C b/src/usr/errl/errludlogregister.C
index 0db5aaca9..e908b0d4d 100644
--- a/src/usr/errl/errludlogregister.C
+++ b/src/usr/errl/errludlogregister.C
@@ -223,6 +223,7 @@ void ErrlUserDetailsLogRegister::copyRegisterData(
case DeviceFW::SCOM: // userif.H
case DeviceFW::FSI: // userif.H
case DeviceFW::SPD: // userif.H
+ case DeviceFW::NVDIMM: // userif.H
case DeviceFW::XSCOM: // driverif.H
case DeviceFW::FSISCOM: // driverif.H
case DeviceFW::IBSCOM: // driverif.H
diff --git a/src/usr/errl/parser/genErrlParsers.pl b/src/usr/errl/parser/genErrlParsers.pl
index 19be84266..2ae0282e5 100755
--- a/src/usr/errl/parser/genErrlParsers.pl
+++ b/src/usr/errl/parser/genErrlParsers.pl
@@ -996,9 +996,9 @@ close(SUBSYSTEM_TYPES_FILE);
# Generate a list of all possible SRCs and their descriptions
# ------------------------------------------------------------------
open(OFILE, ">", $srcFileName) or die ("Cannot open: $srcFileName: $!");
-foreach my $sub (sort keys %subsysList)
+foreach my $rcVal (sort keys %srcList)
{
- foreach my $rcVal (sort keys %srcList)
+ foreach my $sub (sort keys %subsysList)
{
my $src = "BC$sub$rcVal";
print OFILE "//////////////////////////////////////////////////////\n";
diff --git a/src/usr/errl/parser/makefile b/src/usr/errl/parser/makefile
index 905e4e6fd..8db2fc0fc 100644
--- a/src/usr/errl/parser/makefile
+++ b/src/usr/errl/parser/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2011,2016
+# Contributors Listed Below - COPYRIGHT 2011,2019
# [+] Google Inc.
# [+] International Business Machines Corp.
#
diff --git a/src/usr/errl/plugins/errludattributeP.H b/src/usr/errl/plugins/errludattributeP.H
new file mode 100644
index 000000000..d097ad9e7
--- /dev/null
+++ b/src/usr/errl/plugins/errludattributeP.H
@@ -0,0 +1,41 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/errl/plugins/errludattributeP.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef ERRL_UDATTRIBUTEP_H
+#define ERRL_UDATTRIBUTEP_H
+
+/**
+ * Defines the classes that allow you to parse attribute data
+ * that was previously saved to an error log with
+ * ERRORLOG::ErrlUserDetailsAttribute.
+ */
+
+#include "errluserdetails.H"
+
+// Pull in the auto-generated portion for the parser
+// Created by xmltohb.pl
+#include <errludattributeP_gen.H>
+
+
+#endif // ERRL_UDATTRIBUTEP_H
diff --git a/src/usr/errl/plugins/errludbacktrace.H b/src/usr/errl/plugins/errludbacktrace.H
index 898ea8faa..9ecc11511 100644
--- a/src/usr/errl/plugins/errludbacktrace.H
+++ b/src/usr/errl/plugins/errludbacktrace.H
@@ -5,7 +5,10 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
+/* [+] International Business Machines Corp. */
+/* [+] YADRO */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -113,7 +116,7 @@ public:
for( int i = 0; i < l_count; i++ )
{
// endian convert the stack address
- uint64_t l_addr = ntohll(*p64);
+ uint64_t l_addr = ntohll(UINT64_FROM_PTR(p64));
// get nearest symbol
const char * l_pSymbol = symTab.nearestSymbol( l_addr );
diff --git a/src/usr/errl/plugins/errludcallout.H b/src/usr/errl/plugins/errludcallout.H
index fc45e5590..47cbfd9fd 100644
--- a/src/usr/errl/plugins/errludcallout.H
+++ b/src/usr/errl/plugins/errludcallout.H
@@ -210,6 +210,7 @@ case HWAS::_type: i_parser.PrintString( "Bus Type", #_type); break;
case_BUS_TYPE(I2C_BUS_TYPE)
case_BUS_TYPE(PSI_BUS_TYPE)
case_BUS_TYPE(O_BUS_TYPE)
+ case_BUS_TYPE(OMI_BUS_TYPE)
default:
i_parser.PrintNumber( "Bus Type", "UNKNOWN: 0x%X",
ntohl(pData->busType) );
diff --git a/src/usr/errl/plugins/errludlogregister.H b/src/usr/errl/plugins/errludlogregister.H
index f795a9643..221458022 100644
--- a/src/usr/errl/plugins/errludlogregister.H
+++ b/src/usr/errl/plugins/errludlogregister.H
@@ -5,9 +5,10 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2014 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
+/* [+] YADRO */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -79,7 +80,7 @@ public:
{
// first is the HUID
uint32_t *pData = reinterpret_cast<uint32_t *>(pBuf);
- if (ntohl(*pData) == 0xFFFFFFFF)
+ if (ntohl(UINT32_FROM_PTR(pData)) == 0xFFFFFFFF)
{
i_parser.PrintString("LogRegister",
"Target: MASTER_PROCESSOR_CHIP_TARGET_SENTINEL");
@@ -87,7 +88,7 @@ public:
else
{
i_parser.PrintNumber( "LogRegister",
- "Target: HUID = 0x%08X", ntohl(*pData) );
+ "Target: HUID = 0x%08X", ntohl(UINT32_FROM_PTR(pData)) );
}
pData++;
pBuf += sizeof(*pData);
@@ -122,6 +123,11 @@ public:
numArgs = 1;
addrParams.push_back(" SPD keyword enumaration");
break;
+ case DeviceFW::NVDIMM: // userif.H
+ i_parser.PrintString("AccessType", "DeviceFW::NVDIMM");
+ numArgs = 1;
+ addrParams.push_back(" NVDIMM address");
+ break;
case DeviceFW::XSCOM: // driverif.H
i_parser.PrintString("AccessType", "DeviceFW::XSCOM");
numArgs = 1;
@@ -199,7 +205,7 @@ public:
for (int32_t i = 0;i < numArgs;i++)
{
std::vector<char> l_traceEntry(20);
- sprintf(&(l_traceEntry[0]),"0x%016llX", ntohll(*pData64));
+ sprintf(&(l_traceEntry[0]),"0x%016llX", ntohll(UINT64_FROM_PTR(pData64)));
i_parser.PrintString(addrParams[i], &(l_traceEntry[0]));
pData64++;
diff --git a/src/usr/errl/plugins/errludparser.H b/src/usr/errl/plugins/errludparser.H
index ddaadade7..6957d4632 100755
--- a/src/usr/errl/plugins/errludparser.H
+++ b/src/usr/errl/plugins/errludparser.H
@@ -5,8 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
+/* [+] YADRO */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -84,6 +85,7 @@ static bool myDataParse(\
{\
l_rc = true;\
l_pParser->parse(i_ver, i_parser, i_buffer, i_buflen);\
+ delete l_pParser;\
}\
return l_rc;\
}\
diff --git a/src/usr/errl/plugins/errludparserfactoryerrl.H b/src/usr/errl/plugins/errludparserfactoryerrl.H
index fbefe231f..d5999c807 100644
--- a/src/usr/errl/plugins/errludparserfactoryerrl.H
+++ b/src/usr/errl/plugins/errludparserfactoryerrl.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -34,7 +34,7 @@
#include "errludstring.H"
#include "errludtarget.H"
#include "errludbacktrace.H"
-#include "errludattribute.H"
+#include "errludattributeP.H"
#include "errludlogregister.H"
#include "errludcallout.H"
#include "errludsensor.H"
diff --git a/src/usr/errl/plugins/errludwofdata.H b/src/usr/errl/plugins/errludwofdata.H
index f792c5485..203a4a14e 100644
--- a/src/usr/errl/plugins/errludwofdata.H
+++ b/src/usr/errl/plugins/errludwofdata.H
@@ -5,8 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
+/* [+] YADRO */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -98,7 +99,7 @@ public:
// addWofCompareDataToErrl() in plat_wof_access.C
if ((NULL != i_pBuffer) && (i_buflen >= sizeof(tableEntries)))
{
- tableEntries = ntohs(*(reinterpret_cast<uint16_t*>(i_pBuffer)));
+ tableEntries = ntohs(UINT16_FROM_PTR(i_pBuffer));
}
// How many entries are really present in this buffer?
diff --git a/src/usr/errl/plugins/errluserdetails.H b/src/usr/errl/plugins/errluserdetails.H
index 917dcf266..eac453505 100755
--- a/src/usr/errl/plugins/errluserdetails.H
+++ b/src/usr/errl/plugins/errluserdetails.H
@@ -5,8 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
+/* [+] YADRO */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -39,6 +40,88 @@ namespace ERRORLOG
{
/**
+ * @struct UnalignedData
+ * @brief Structure used for safe assigment from unaligned pointer, it forces
+ * the compiler to generate extra instructions and satisfy architectural
+ * alignment requirements.
+ */
+template<typename T> struct UnalignedData {
+ T value;
+} __attribute__ ((packed));
+
+/**
+ * @brief Read integral value from unaligned pointer.
+ *
+ * @param[in] i_pUint64 - Pointer to uint64_t value
+ *
+ * @return uint64_t value from specified pointer
+ */
+inline uint64_t UINT64_FROM_PTR(const void* i_pUint64)
+{
+ return reinterpret_cast<const UnalignedData<uint64_t>*>(i_pUint64)->value;
+}
+
+/**
+ * @brief Read integral value from unaligned pointer.
+ *
+ * @param[in] i_pUint32 - Pointer to uint32_t value
+ *
+ * @return uint32_t value from specified pointer
+ */
+inline uint32_t UINT32_FROM_PTR(const void* i_pUint32)
+{
+ return reinterpret_cast<const UnalignedData<uint32_t>*>(i_pUint32)->value;
+}
+
+/**
+ * @brief Read integral value from unaligned pointer.
+ *
+ * @param[in] i_pUint16 - Pointer to uint16_t value
+ *
+ * @return uint16_t value from specified pointer
+ */
+inline uint16_t UINT16_FROM_PTR(const void* i_pUint16)
+{
+ return reinterpret_cast<const UnalignedData<uint16_t>*>(i_pUint16)->value;
+}
+
+/**
+ * @brief Read integral value from unaligned pointer.
+ *
+ * @param[in] i_pInt64 - Pointer to int64_t value
+ *
+ * @return int64_t value from specified pointer
+ */
+inline int64_t INT64_FROM_PTR(const void* i_pInt64)
+{
+ return reinterpret_cast<const UnalignedData<int64_t>*>(i_pInt64)->value;
+}
+
+/**
+ * @brief Read integral value from unaligned pointer.
+ *
+ * @param[in] i_pInt32 - Pointer to int32_t value
+ *
+ * @return int32_t value from specified pointer
+ */
+inline int32_t INT32_FROM_PTR(const void* i_pInt32)
+{
+ return reinterpret_cast<const UnalignedData<int32_t>*>(i_pInt32)->value;
+}
+
+/**
+ * @brief Read integral value from unaligned pointer.
+ *
+ * @param[in] i_pInt16 - Pointer to int16_t value
+ *
+ * @return int16_t value from specified pointer
+ */
+inline int16_t INT16_FROM_PTR(const void* i_pInt16)
+{
+ return reinterpret_cast<const UnalignedData<int16_t>*>(i_pInt16)->value;
+}
+
+/**
* @brief Returns the uint64_t at the pointed to location in host byte order
*
* @param[in] i_pUint64 Pointer to a uint64_t in network byte order
@@ -47,7 +130,7 @@ namespace ERRORLOG
*/
inline uint64_t NTH_UINT64(const void* i_pUint64)
{
- return (ntohll(*(reinterpret_cast<const uint64_t*>(i_pUint64))));
+ return (ntohll(UINT64_FROM_PTR(i_pUint64)));
}
/**
@@ -59,7 +142,7 @@ inline uint64_t NTH_UINT64(const void* i_pUint64)
*/
inline uint32_t NTH_UINT32(const void* i_pUint32)
{
- return (ntohl(*(reinterpret_cast<const uint32_t*>(i_pUint32))));
+ return (ntohl(UINT32_FROM_PTR(i_pUint32)));
}
/**
@@ -71,7 +154,7 @@ inline uint32_t NTH_UINT32(const void* i_pUint32)
*/
inline uint16_t NTH_UINT16(const void* i_pUint16)
{
- return (ntohs(*(reinterpret_cast<const uint16_t*>(i_pUint16))));
+ return (ntohs(UINT16_FROM_PTR(i_pUint16)));
}
/**
diff --git a/src/usr/errl/runtime/rt_errlmanager.C b/src/usr/errl/runtime/rt_errlmanager.C
index 9fb624608..e545641bb 100644
--- a/src/usr/errl/runtime/rt_errlmanager.C
+++ b/src/usr/errl/runtime/rt_errlmanager.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -47,6 +47,8 @@ uint8_t ErrlManager::iv_hiddenErrLogsEnable =
extern trace_desc_t* g_trac_errl;
+// Maximum size of error log that can be sent to the host
+const uint32_t MAX_FSP_ERROR_LOG_LENGTH = 4096;
//////////////////////////////////////////////////////////////////////////////
@@ -188,10 +190,14 @@ void ErrlManager::sendMboxMsg ( errlHndl_t& io_err )
if(g_hostInterfaces)
{
uint32_t l_msgSize = io_err->flattenedSize();
+ if (l_msgSize > MAX_FSP_ERROR_LOG_LENGTH)
+ {
+ l_msgSize = MAX_FSP_ERROR_LOG_LENGTH;
+ }
if (g_hostInterfaces->sendErrorLog)
{
uint8_t * temp_buff = new uint8_t [l_msgSize ];
- io_err->flatten ( temp_buff, l_msgSize );
+ io_err->flatten ( temp_buff, l_msgSize, true /* truncate */ );
size_t rc = g_hostInterfaces->sendErrorLog(io_err->plid(),
l_msgSize,
diff --git a/src/usr/errl/runtime/test/test_runtimeDeconfig.H b/src/usr/errl/runtime/test/test_runtimeDeconfig.H
index 2f5d37259..0cf1a0a52 100644
--- a/src/usr/errl/runtime/test/test_runtimeDeconfig.H
+++ b/src/usr/errl/runtime/test/test_runtimeDeconfig.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -51,8 +51,8 @@ class deconfigureTargetAtRuntimeTest : public CxxTest::TestSuite
// pass in a null target pointer
TARGETING::Target * l_target = nullptr;
- errlHndl_t l_errl =
- HWAS::theDeconfigGard().deconfigureTargetAtRuntime(
+ errlHndl_t l_errl = nullptr;
+ l_errl = HWAS::theDeconfigGard().deconfigureTargetAtRuntime(
l_target,
HWAS::DeconfigGard::FULLY_AT_RUNTIME,
l_errl);
@@ -118,8 +118,8 @@ class deconfigureTargetAtRuntimeTest : public CxxTest::TestSuite
l_target = l_cores.at(0);
- errlHndl_t l_errl =
- HWAS::theDeconfigGard().deconfigureTargetAtRuntime(
+ errlHndl_t l_errl = nullptr;
+ l_errl = HWAS::theDeconfigGard().deconfigureTargetAtRuntime(
l_target,
HWAS::DeconfigGard::SPEC_DECONFIG,
l_errl);
@@ -179,8 +179,8 @@ class deconfigureTargetAtRuntimeTest : public CxxTest::TestSuite
TARGETING::Target * l_target = l_proc.at(0);
- errlHndl_t l_errl =
- HWAS::theDeconfigGard().deconfigureTargetAtRuntime(
+ errlHndl_t l_errl = nullptr;
+ l_errl = HWAS::theDeconfigGard().deconfigureTargetAtRuntime(
l_target,
HWAS::DeconfigGard::FULLY_AT_RUNTIME,
l_errl);
diff --git a/src/usr/errl/test/errltest.H b/src/usr/errl/test/errltest.H
index ff5df6b65..32e798ac4 100644
--- a/src/usr/errl/test/errltest.H
+++ b/src/usr/errl/test/errltest.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -1214,6 +1214,57 @@ public:
l_err = NULL;
}
+ /**
+ * @brief Ensure all callouts have a SUBSYS mapping
+ *
+ */
+ void testErrl_ensureSubsystemMapping(void)
+ {
+ // dummy log to call non-static methods with
+ errlHndl_t l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ ERRORLOG::ERRL_TEST_MOD_ID,
+ ERRORLOG::ERRL_TEST_REASON_CODE,
+ 0x494E464F, //INFO
+ 0);
+
+ // Walk through every BUS_TYPE
+ for( busTypeEnum bus = (busTypeEnum)(NO_BUS_TYPE+1);
+ bus < LAST_BUS_TYPE;
+ bus = (busTypeEnum)(bus+1) )
+ {
+ if( l_err->getSubSystem(bus) == EPUB_MISC_UNKNOWN )
+ {
+ TS_FAIL( "No subsystem returned for BUS_TYPE %d", bus );
+ }
+ }
+
+ // Walk through every PART_TYPE
+ for( partTypeEnum part = (partTypeEnum)(NO_PART_TYPE+1);
+ part < LAST_PART_TYPE;
+ part = (partTypeEnum)(part+1) )
+ {
+ if( l_err->getSubSystem(part) == EPUB_MISC_UNKNOWN )
+ {
+ TS_FAIL( "No subsystem returned for PART_TYPE %d", part );
+ }
+ }
+
+ // Walk through every SENSOR_TYPE
+ for( sensorTypeEnum sensor = (sensorTypeEnum)(UNKNOWN_SENSOR+1);
+ sensor < LAST_SENSOR_TYPE;
+ sensor = (sensorTypeEnum)(sensor+1) )
+ {
+ if( l_err->getSubSystem(sensor) == EPUB_MISC_UNKNOWN )
+ {
+ TS_FAIL( "No subsystem returned for SENSOR_TYPE %d", sensor );
+ }
+ }
+
+ // Note - Can't loop over epubProcedureID because the values are
+ // sparsely populated
+
+ }
};
diff --git a/src/usr/errldisplay/errldisplay.C b/src/usr/errldisplay/errldisplay.C
index b8c26614e..3f04618cd 100644
--- a/src/usr/errldisplay/errldisplay.C
+++ b/src/usr/errldisplay/errldisplay.C
@@ -67,6 +67,7 @@
#include <targeting/common/targetservice.H>
#include <targeting/common/iterators/targetiterator.H>
#include <targeting/common/target.H>
+#include <arch/ppc.H>
#ifdef CONFIG_CONSOLE_OUTPUT_FFDCDISPLAY
//Generated hearder files for HWP parsing
@@ -325,6 +326,7 @@ case HWAS::_type: CONSOLE::displayf(NULL, " Bus Type : %s", #_t
case_BUS_TYPE(I2C_BUS_TYPE)
case_BUS_TYPE(PSI_BUS_TYPE)
case_BUS_TYPE(O_BUS_TYPE)
+ case_BUS_TYPE(OMI_BUS_TYPE)
default:
CONSOLE::displayf(NULL, " Bus Type : UNKNOWN 0x%X",
callout->busType);
@@ -338,7 +340,6 @@ case HWAS::_type: CONSOLE::displayf(NULL, " Bus Type : %s", #_t
case HWAS::HW_CALLOUT:
CONSOLE::displayf(NULL, " Callout type : Hardware Callout");
- CONSOLE::displayf(NULL, " CPU id : %d", callout->cpuid);
displayGard = true;
l_gard = callout->gardErrorType;
@@ -675,9 +676,9 @@ void ErrLogDisplay::msgDisplay (const errlHndl_t &i_err,
CONSOLE::displayf(NULL,
"================================================");
- CONSOLE::displayf(NULL, "Error reported by %s (0x%04X) PLID 0x%08X",
+ CONSOLE::displayf(NULL, "Error reported by %s (0x%04X) EID 0x%08X",
findComponentName( i_committerComp ),
- i_committerComp, i_err->plid() );
+ i_committerComp, i_err->eid() );
//PRD doesn't follow the rest of the HB conventions
// Handle them special
@@ -709,7 +710,7 @@ void ErrLogDisplay::msgDisplay (const errlHndl_t &i_err,
displayHwpf( user_data->iv_pData, user_data->iv_Size,
user_data->iv_header.iv_sst);
}
- else
+ else if(user_data->iv_header.iv_compId == ERRL_COMP_ID)
{
switch ( user_data->iv_header.iv_sst )
{
diff --git a/src/usr/errldisplay/makefile b/src/usr/errldisplay/makefile
index b094bfc63..a2fe4c9e4 100644
--- a/src/usr/errldisplay/makefile
+++ b/src/usr/errldisplay/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2017
+# Contributors Listed Below - COPYRIGHT 2013,2019
# [+] Google Inc.
# [+] International Business Machines Corp.
#
@@ -48,3 +48,4 @@ EXTRAINCDIR += ${GENDIR}/plugins/prdf/
EXTRAINCDIR += ${ROOTPATH}/src/usr/diag/prdf/plugins/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/include/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/centaur/common/include/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/
diff --git a/src/usr/expaccess/errlud_expscom.C b/src/usr/expaccess/errlud_expscom.C
new file mode 100644
index 000000000..7480b9887
--- /dev/null
+++ b/src/usr/expaccess/errlud_expscom.C
@@ -0,0 +1,216 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/expaccess/errlud_expscom.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file errlud_expscom.C
+ * @brief Utility to add Explorer logs to your hostboot error
+ */
+#include "errlud_expscom.H"
+#include "expscom_trace.H"
+#include <errl/hberrltypes.H> // pelSectionHeader_t
+#include <exp_fw_log_data.H> // explorer log gathering tools
+#include <fapi2/plat_hwp_invoker.H> // FAPI_INVOKE_HWP
+#include <expscom/expscom_reasoncodes.H> // user-detail subsections
+#include <errl/errlmanager.H> // errlCommit
+
+using namespace EXPSCOM;
+
+// Main function to add Explorer logs to a HB error log
+bool EXPSCOM::expAddLog( const exp_log_type i_type,
+ TARGETING::Target * i_ocmb,
+ errlHndl_t & io_errl )
+{
+ bool l_logsAdded = false;
+ explog_section_header_t l_header; // use 0 defaults
+
+ // Meta data included with each section
+ const uint32_t META_SECTION_SIZE = sizeof(l_header) +
+ sizeof(ERRORLOG::pelSectionHeader_t);
+
+ // @todo RTC 214628
+ // Hopefully create a way to tell how much room is left in io_errl
+ uint32_t l_bytesAvailableInLog = 4 * KILOBYTE;
+
+ if (l_bytesAvailableInLog > META_SECTION_SIZE)
+ {
+ errlHndl_t l_errl = nullptr;
+ std::vector<uint8_t>l_error_log_data; // explorer error entry data
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target(i_ocmb);
+
+ // Make HWP call to grab explorer error log data
+ if (i_type == EXPSCOM::ACTIVE_LOG)
+ {
+ TRACFCOMP( g_trac_expscom, INFO_MRK "FAPI_INVOKE_HWP exp_active_error_log");
+ FAPI_INVOKE_HWP( l_errl, exp_active_log,
+ l_fapi_ocmb_target, l_error_log_data );
+ }
+ else
+ {
+ TRACFCOMP( g_trac_expscom, INFO_MRK "FAPI_INVOKE_HWP exp_saved_error_log");
+ FAPI_INVOKE_HWP( l_errl, exp_saved_log,
+ l_fapi_ocmb_target, l_error_log_data );
+ }
+
+ if (l_errl)
+ {
+ // Unable to grab explorer error log data
+ TRACFCOMP( g_trac_expscom, ERR_MRK "Unable to grab explorer error log data");
+ l_errl->collectTrace(EXPSCOM_COMP_NAME);
+
+ // This error is not a system critical failure, should be just noted
+ l_errl->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);
+
+ // Associate this error with the original explorer failure log
+ l_errl->plid(io_errl->plid());
+ errlCommit(l_errl, EXPSCOM_COMP_ID);
+ }
+ else
+ {
+ // Cycle through data and add sections to io_errl
+ // Most recent error log entries are at the end of the data returned
+ // so need to work backwards from the end
+ l_header.error_data_size = FIRST_EXPLORER_DATA_SECTION_SIZE;
+ uint32_t l_explorer_bytes_left = l_error_log_data.size();
+ uint8_t * l_end_ptr = l_error_log_data.data() + l_explorer_bytes_left;
+
+ // while explorer data to append
+ while (l_explorer_bytes_left && l_bytesAvailableInLog)
+ {
+ // Can we add a full packet size of error data?
+ if (l_bytesAvailableInLog > (l_header.error_data_size + META_SECTION_SIZE))
+ {
+ // Check if we don't have full packet of explorer error data
+ if (l_explorer_bytes_left < l_header.error_data_size)
+ {
+ // Reduce the packet size to include the last of explorer error data
+ l_header.error_data_size = l_explorer_bytes_left;
+ }
+ }
+ else if ( l_bytesAvailableInLog > META_SECTION_SIZE ) // Any room left for another section?
+ {
+ // Is there enough explorer error data for room available?
+ if ( l_explorer_bytes_left >=
+ (l_bytesAvailableInLog - META_SECTION_SIZE) )
+ {
+ // Not enough room is available for all the remaining explorer error data
+ // Use up the rest of the space available
+ l_header.error_data_size = l_bytesAvailableInLog - META_SECTION_SIZE;
+ }
+ else
+ {
+ // Room is available but not enough explorer data for full packet size
+ // Reduce the packet size to include the last of explorer error data
+ l_header.error_data_size = l_explorer_bytes_left;
+ }
+ }
+ else
+ {
+ // No more space available in hostboot error log
+ break;
+ }
+
+ // Offset into explorer error log data returned
+ l_header.offset_exp_log = l_explorer_bytes_left -
+ l_header.error_data_size;
+
+ // Add the section entry to the HWP error log
+ if ( i_type == EXPSCOM::ACTIVE_LOG )
+ {
+ ExpscomActiveLogUD(l_header, (l_end_ptr - l_header.error_data_size)).
+ addToLog(io_errl);
+ }
+ else
+ {
+ ExpscomSavedLogUD(l_header, (l_end_ptr - l_header.error_data_size)).
+ addToLog(io_errl);
+ }
+ l_logsAdded = true;
+
+ // Update to next packet of Explorer error log data
+ l_end_ptr -= l_header.error_data_size; // update to always be the tail of data to add
+ l_header.packet_num++;
+ l_explorer_bytes_left -= l_header.error_data_size;
+ l_bytesAvailableInLog -= (META_SECTION_SIZE + l_header.error_data_size);
+ l_header.error_data_size = FOLLOWING_EXPLORER_DATA_SECTION_SIZE;
+ }
+ }
+ }
+ else
+ {
+ TRACFCOMP( g_trac_expscom, INFO_MRK
+ "expAddErrorLog: Unable to add any %d type error logs,"
+ " only have %d bytes available in log", i_type, l_bytesAvailableInLog );
+ }
+ return l_logsAdded;
+}
+
+//------------------------------------------------------------------------------
+// Expscom Active Log User Details
+//------------------------------------------------------------------------------
+ExpscomActiveLogUD::ExpscomActiveLogUD(
+ const explog_section_header_t & i_header_info,
+ const uint8_t * i_data_portion )
+{
+ // Set up Ud instance variables
+ iv_CompId = EXPSCOM_COMP_ID;
+ iv_Version = 1;
+ iv_SubSection = EXPSCOM_UDT_ACTIVE_LOG;
+
+ uint8_t * l_pBuf = reallocUsrBuf( sizeof(i_header_info) +
+ i_header_info.error_data_size );
+
+ memcpy(l_pBuf, &i_header_info, sizeof(i_header_info));
+ l_pBuf += sizeof(i_header_info);
+ memcpy(l_pBuf, i_data_portion, i_header_info.error_data_size);
+ l_pBuf += i_header_info.error_data_size;
+}
+
+ExpscomActiveLogUD::~ExpscomActiveLogUD()
+{
+}
+
+//------------------------------------------------------------------------------
+// Expscom Saved Log User Details
+//------------------------------------------------------------------------------
+ExpscomSavedLogUD::ExpscomSavedLogUD(
+ const explog_section_header_t & i_header_info,
+ const uint8_t * i_data_portion )
+{
+ // Set up Ud instance variables
+ iv_CompId = EXPSCOM_COMP_ID;
+ iv_Version = 1;
+ iv_SubSection = EXPSCOM_UDT_SAVED_LOG;
+
+ uint8_t * l_pBuf = reallocUsrBuf( sizeof(i_header_info) +
+ i_header_info.error_data_size );
+
+ memcpy(l_pBuf, &i_header_info, sizeof(i_header_info));
+ l_pBuf += sizeof(i_header_info);
+ memcpy(l_pBuf, i_data_portion, i_header_info.error_data_size);
+ l_pBuf += i_header_info.error_data_size;
+}
+
+ExpscomSavedLogUD::~ExpscomSavedLogUD()
+{
+}
diff --git a/src/usr/expaccess/errlud_expscom.H b/src/usr/expaccess/errlud_expscom.H
new file mode 100644
index 000000000..acb17bc2c
--- /dev/null
+++ b/src/usr/expaccess/errlud_expscom.H
@@ -0,0 +1,160 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/expaccess/errlud_expscom.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __ERRLUD_EXPSCOM_H
+#define __ERRLUD_EXPSCOM_H
+
+/**
+ * @file errlud_expscom.H
+ * @brief Utility functions to add Explorer logs to your hostboot error
+ */
+#include <stdint.h>
+
+#include <errl/errluserdetails.H>
+
+// targeting support
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/utilFilter.H>
+
+namespace EXPSCOM
+{
+/**
+ * @brief Enum for what kind of Explorer log
+ */
+enum exp_log_type : uint8_t
+{
+ ACTIVE_LOG = 1, // RAM error section
+ SAVED_LOG = 2 // SPI flash error section
+};
+
+/**
+ * @brief Adds Explorer log data to platform log
+ * Grabs explorer error log based on type and then breaks that data
+ * into smaller user-data sections adding them to the platform log.
+ * Note: First section will be the smallest and contain the most recent
+ * trace data. Probably contains most relevent traces, so try to make
+ * always fit in the error log.
+ * @param i_type - what kind of explorer error log to add
+ * @param i_ocmb - Explorer target
+ * @param io_errl - Platform error log to add logs into
+ * @return true if explorer error data added, else false
+ */
+bool expAddLog( const exp_log_type i_type,
+ TARGETING::Target * i_ocmb,
+ errlHndl_t & io_errl );
+
+
+
+/**
+ * @brief Header data of every explorer error log user-data section
+ */
+struct explog_section_header_t
+{
+ uint16_t packet_num; // ordering byte (0 = first packet)
+ uint32_t offset_exp_log; // offset where data portion started in full explorer log
+ uint16_t error_data_size; // size of data portion following header
+
+ explog_section_header_t()
+ : packet_num(0),
+ offset_exp_log(0),
+ error_data_size(0)
+ {}
+} __attribute__((__packed__));
+
+// Break large explorer log data into smaller error sections
+// to avoid dropping important debug data.
+// Make most important first section smaller so this won't get dropped
+const uint16_t FIRST_EXPLORER_DATA_SECTION_SIZE = 0x0100;
+const uint16_t FOLLOWING_EXPLORER_DATA_SECTION_SIZE = 0x0200;
+
+
+/**
+ * @class ExpscomActiveLogUD
+ *
+ * Adds Explorer Active log information to an error log as user detail
+ * Data is from Explorer RAM
+ *
+ */
+class ExpscomActiveLogUD : public ERRORLOG::ErrlUserDetails
+{
+ public:
+ /**
+ * @brief Constructor
+ *
+ * @param i_header_info Meta information added to beginning of section
+ * @param i_data_portion Pointer to portion of Active log data
+ *
+ */
+ ExpscomActiveLogUD( const explog_section_header_t & i_header_info,
+ const uint8_t * i_data_portion );
+
+ /**
+ * @brief Destructor
+ */
+ virtual ~ExpscomActiveLogUD();
+
+ // Disabled
+ ExpscomActiveLogUD() = delete;
+ ExpscomActiveLogUD(ExpscomActiveLogUD &) = delete;
+ ExpscomActiveLogUD & operator=(ExpscomActiveLogUD &) = delete;
+};
+
+
+
+
+/**
+ * @class ExpscomSavedLogUD
+ *
+ * Adds Explorer Saved log information to an error log as user detail
+ * Data is from Explorer SPI flash
+ *
+ */
+class ExpscomSavedLogUD : public ERRORLOG::ErrlUserDetails
+{
+ public:
+ /**
+ * @brief Constructor
+ *
+ * @param i_header_info Meta information added to beginning of section
+ * @param i_data_portion Pointer to portion of Saved error data
+ *
+ */
+ ExpscomSavedLogUD( const explog_section_header_t & i_header_info,
+ const uint8_t * i_data_portion );
+
+ /**
+ * @brief Destructor
+ */
+ virtual ~ExpscomSavedLogUD();
+
+ // Disabled
+ ExpscomSavedLogUD() = delete;
+ ExpscomSavedLogUD(ExpscomSavedLogUD &) = delete;
+ ExpscomSavedLogUD & operator=(ExpscomSavedLogUD &) = delete;
+};
+
+}
+
+#endif
diff --git a/src/usr/expaccess/expaccess.mk b/src/usr/expaccess/expaccess.mk
index 84835c522..d4431e0cd 100644
--- a/src/usr/expaccess/expaccess.mk
+++ b/src/usr/expaccess/expaccess.mk
@@ -25,14 +25,20 @@
EXTRAINCDIR += ${ROOTPATH}/src/import
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc/
EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2
-# Need to build exp_indband to use EKB's getMMIO/putMMIO/getCMD/getRSP
+VPATH += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/inband/
+
+# Need to build exp_inband to use EKB's getMMIO/putMMIO/getCMD/getRSP
OBJS += exp_inband.o
OBJS += expscom_trace.o
OBJS += expscom_utils.o
OBJS += i2cscomdd.o
-OBJS += mmioscomdd.o \ No newline at end of file
+OBJS += mmioscomdd.o
+OBJS += exp_fw_log.o
+OBJS += exp_fw_log_data.o
+OBJS += errlud_expscom.o
diff --git a/src/usr/expaccess/expscom_utils.C b/src/usr/expaccess/expscom_utils.C
index 5ea7eeeb2..c4818379c 100644
--- a/src/usr/expaccess/expscom_utils.C
+++ b/src/usr/expaccess/expscom_utils.C
@@ -55,20 +55,21 @@ errlHndl_t validateInputs(DeviceFW::OperationType i_opType,
errlHndl_t l_err = nullptr;
uint32_t l_commonPlid = 0; // If there are multiple issues found link logs with first
- TARGETING::ATTR_MODEL_type l_targetModel =
- i_target->getAttr<TARGETING::ATTR_MODEL>();
+ // Verify that the target is of type OCMB_CHIP
+ TARGETING::ATTR_TYPE_type l_targetType =
+ i_target->getAttr<TARGETING::ATTR_TYPE>();
- // Only target we can perform ocmb scoms on are explorer OCMB chip targets
- if( l_targetModel != TARGETING::MODEL_EXPLORER )
+ // Only target we can perform ocmb scoms on are OCMB chip targets
+ if( l_targetType != TARGETING::TYPE_OCMB_CHIP )
{
- TRACFCOMP( g_trac_expscom, ERR_MRK "validateInputs> Invalid target type : l_targetModel=%d", l_targetModel );
+ TRACFCOMP( g_trac_expscom, ERR_MRK "validateInputs> Invalid target type : l_targetType=0x%X", l_targetType );
/*@
* @errortype
* @moduleid EXPSCOM::MOD_OCMB_UTILS
* @reasoncode EXPSCOM::RC_INVALID_MODEL_TYPE
* @userdata1 SCOM Address
* @userdata2 Model Type
- * @devdesc validateInputs> Invalid target type (!= OCMB_CHP)
+ * @devdesc validateInputs> Invalid target type (!= OCMB_CHIP)
* @custdesc A problem occurred during the IPL of the system:
* Invalid target type for a SCOM operation.
*/
@@ -76,7 +77,7 @@ errlHndl_t validateInputs(DeviceFW::OperationType i_opType,
EXPSCOM::MOD_OCMB_UTILS,
EXPSCOM::RC_INVALID_MODEL_TYPE,
i_scomAddr,
- l_targetModel,
+ l_targetType,
ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
l_err->collectTrace(EXPSCOM_COMP_NAME);
diff --git a/src/usr/expaccess/mmioscomdd.C b/src/usr/expaccess/mmioscomdd.C
index bf4513158..00feb38d4 100644
--- a/src/usr/expaccess/mmioscomdd.C
+++ b/src/usr/expaccess/mmioscomdd.C
@@ -31,7 +31,7 @@
/*****************************************************************************/
// I n c l u d e s
/*****************************************************************************/
-#include <exp_inband.H> // mmio_get_scom
+#include <lib/inband/exp_inband.H> // mmio_get_scom
#include <lib/shared/exp_consts.H> // IBM_SCOM_INDICATOR
#include <hwpf/fapi2/include/fapi2_hwp_executor.H>// FAPI_EXEC_HWP
#include "mmioscomdd.H" //mmioScomPerformOp
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/memory_size.C b/src/usr/expaccess/plugins/EXPSCOM_COMP_ID_Parse.C
index ddcb6f94a..54bf595b6 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/memory_size.C
+++ b/src/usr/expaccess/plugins/EXPSCOM_COMP_ID_Parse.C
@@ -1,7 +1,7 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/memory_size.C $ */
+/* $Source: src/usr/expaccess/plugins/EXPSCOM_COMP_ID_Parse.C $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
@@ -22,3 +22,11 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+/**
+ * @file EXPSCOM_COMP_ID_Parse.C
+ * @brief Build the Explorer User Details parser factory
+ */
+#include "errludparser.H"
+#include "expscomUdParserFactory.H"
+
+ERRL_MAKE_UD_PARSER(EXPSCOM::UserDetailsParserFactory, hbfw::EXPSCOM_COMP_ID)
diff --git a/src/usr/expaccess/plugins/errludP_expscom.H b/src/usr/expaccess/plugins/errludP_expscom.H
new file mode 100644
index 000000000..73d449ba4
--- /dev/null
+++ b/src/usr/expaccess/plugins/errludP_expscom.H
@@ -0,0 +1,168 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/expaccess/plugins/errludP_expscom.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef ERRL_UDP_EXPSCOM_H
+#define ERRL_UDP_EXPSCOM_H
+
+/**
+ * @file errludP_expscom.H
+ * Defines the ErrlUserDetailsParser classes that parse EXPSCOM FFDC
+ */
+
+#include "errluserdetails.H"
+#include <string.h>
+
+#define TO_UINT16(ptr) (ntohs(*(reinterpret_cast<uint16_t*>(ptr))))
+#define TO_UINT32(ptr) (ntohl(*(reinterpret_cast<uint32_t*>(ptr))))
+
+namespace EXPSCOM
+{
+
+/**
+ * @brief Header data of every explorer error log section
+ */
+typedef struct __attribute__((packed))
+{
+ uint16_t packet_num; // ordering byte (0 = first packet)
+ uint32_t offset_exp_log; // offset where data portion started in full explorer log
+ uint16_t error_data_size; // size of data portion following header
+} explog_section_header_t;
+
+/**
+ * @class UdParserExpActiveErrorLog
+ *
+ * Parses user-data sections for Explorer's Active logs
+ */
+class UdParserExpActiveLog : public ERRORLOG::ErrlUserDetailsParser
+{
+public:
+ /**
+ * @brief Constructor
+ */
+ UdParserExpActiveLog() {}
+
+ /**
+ * @brief Destructor
+ */
+ virtual ~UdParserExpActiveLog() {}
+
+ /**
+ * @brief Parses string user detail data from an error log
+ *
+ * @param i_version Version of the data
+ * @param i_parse ErrlUsrParser object for outputting information
+ * @param i_pBuffer Pointer to buffer containing detail data
+ * @param i_buflen Length of the buffer
+ */
+ virtual void parse(errlver_t i_version,
+ ErrlUsrParser & i_parser,
+ void * i_pBuffer,
+ const uint32_t i_buflen) const
+ {
+ explog_section_header_t * pHeader = reinterpret_cast<explog_section_header_t *>(i_pBuffer);
+ i_parser.PrintHeading("Explorer Active (RAM) Log Data");
+ i_parser.PrintNumber("Order packet", "%d", TO_UINT16(&(pHeader->packet_num)));
+ i_parser.PrintNumber("Data starting offset", "0x%.8lX", TO_UINT32(&(pHeader->offset_exp_log)));
+ i_parser.PrintNumber("Size of data section", "0x%.4lX", TO_UINT16(&(pHeader->error_data_size)));
+ i_parser.PrintBlank();
+ uint16_t errorDataSize = TO_UINT16(&(pHeader->error_data_size));
+ if (errorDataSize <= (i_buflen - sizeof(explog_section_header_t)))
+ {
+ char * l_trace_error_data = static_cast<char*>(i_pBuffer) + sizeof(explog_section_header_t);
+ i_parser.PrintHexDump(l_trace_error_data, errorDataSize);
+ }
+ else
+ {
+ i_parser.PrintHeading("ERROR DATA MISSING -- printing entire section in hex");
+ i_parser.PrintNumber("Expected data size", "0x%.4lX", i_buflen - sizeof(explog_section_header_t));
+ i_parser.PrintHexDump(i_pBuffer, i_buflen);
+ }
+
+ }
+
+ // Disabled
+ UdParserExpActiveLog(const UdParserExpActiveLog&) = delete;
+ UdParserExpActiveLog & operator=(const UdParserExpActiveLog&) = delete;
+};
+
+/**
+ * @class UdParserExpSavedErrorLog
+ *
+ * Parses user-data sections for Explorer's Saved logs
+ */
+class UdParserExpSavedLog : public ERRORLOG::ErrlUserDetailsParser
+{
+public:
+ /**
+ * @brief Constructor
+ */
+ UdParserExpSavedLog() {}
+
+ /**
+ * @brief Destructor
+ */
+ virtual ~UdParserExpSavedLog() {}
+
+ /**
+ * @brief Parses string user detail data from an error log
+ *
+ * @param i_version Version of the data
+ * @param i_parse ErrlUsrParser object for outputting information
+ * @param i_pBuffer Pointer to buffer containing detail data
+ * @param i_buflen Length of the buffer
+ */
+ virtual void parse(errlver_t i_version,
+ ErrlUsrParser & i_parser,
+ void * i_pBuffer,
+ const uint32_t i_buflen) const
+ {
+ explog_section_header_t * pHeader = reinterpret_cast<explog_section_header_t *>(i_pBuffer);
+ i_parser.PrintHeading("Explorer Saved (SPI flash) Log Data");
+ i_parser.PrintNumber("Order packet", "%d", TO_UINT16(&(pHeader->packet_num)));
+ i_parser.PrintNumber("Data starting offset", "0x%.8lX", TO_UINT32(&(pHeader->offset_exp_log)));
+ i_parser.PrintNumber("Size of data section", "0x%.4lX", TO_UINT16(&(pHeader->error_data_size)));
+ i_parser.PrintBlank();
+ uint16_t errorDataSize = TO_UINT16(&pHeader->error_data_size);
+ if (errorDataSize <= (i_buflen - sizeof(explog_section_header_t)))
+ {
+ char * l_trace_error_data = static_cast<char*>(i_pBuffer) + sizeof(explog_section_header_t);
+ i_parser.PrintHexDump(l_trace_error_data, errorDataSize);
+ }
+ else
+ {
+ i_parser.PrintHeading("ERROR DATA MISSING -- printing entire section in hex");
+ i_parser.PrintNumber("Expected data size", "0x%.4lX", i_buflen - sizeof(explog_section_header_t));
+ i_parser.PrintHexDump(i_pBuffer, i_buflen);
+ }
+
+ }
+
+ // Disabled
+ UdParserExpSavedLog(const UdParserExpSavedLog&) = delete;
+ UdParserExpSavedLog & operator=(const UdParserExpSavedLog&) = delete;
+};
+
+} // end EXPSCOM namespace
+
+#endif
diff --git a/src/usr/expaccess/plugins/expscomUdParserFactory.H b/src/usr/expaccess/plugins/expscomUdParserFactory.H
new file mode 100644
index 000000000..6a006e308
--- /dev/null
+++ b/src/usr/expaccess/plugins/expscomUdParserFactory.H
@@ -0,0 +1,58 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/expaccess/plugins/expscomUdParserFactory.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file expscomUdParserFactory.H
+ * @brief Registers Explorer User Detail parsers
+ */
+#if !defined(_EXPSCOMUDPARSERFACTORY_H)
+#define _EXPSCOMUDPARSERFACTORY_H
+
+#include "errludparserfactory.H"
+#include "errludP_expscom.H"
+
+namespace EXPSCOM
+{
+ class UserDetailsParserFactory
+ : public ERRORLOG::ErrlUserDetailsParserFactory
+ {
+ public:
+ UserDetailsParserFactory()
+ {
+ registerParser<UdParserExpActiveLog>
+ (EXPSCOM_UDT_ACTIVE_LOG);
+
+ registerParser<UdParserExpSavedLog>
+ (EXPSCOM_UDT_SAVED_LOG);
+ }
+
+ private:
+
+ UserDetailsParserFactory(const UserDetailsParserFactory &);
+ UserDetailsParserFactory & operator=
+ (const UserDetailsParserFactory &);
+ };
+};
+
+#endif
diff --git a/src/usr/expaccess/runtime/makefile b/src/usr/expaccess/runtime/makefile
index ed744eab2..722d966e6 100644
--- a/src/usr/expaccess/runtime/makefile
+++ b/src/usr/expaccess/runtime/makefile
@@ -22,6 +22,7 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+HOSTBOOT_RUNTIME = 1
ROOTPATH = ../../../..
MODULE = expaccess_rt
@@ -30,7 +31,9 @@ SUBDIRS += test.d
include ../expaccess.mk
+EXTRAINCDIR += ../
+
VPATH += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
VPATH += ${ROOTPATH}/src/usr/expaccess/
-include ${ROOTPATH}/config.mk \ No newline at end of file
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/expaccess/runtime/test/makefile b/src/usr/expaccess/runtime/test/makefile
index 442fc0953..3359dc760 100644
--- a/src/usr/expaccess/runtime/test/makefile
+++ b/src/usr/expaccess/runtime/test/makefile
@@ -30,9 +30,6 @@ MODULE = testexpaccess_rt
include ../../test/test.mk
-#TODO RTC:196806 re-enable mmio communication tests when mmio works
TESTS = ../../test/expscomtest.H
include ${ROOTPATH}/config.mk
-
-
diff --git a/src/usr/expaccess/test/expErrlTest.C b/src/usr/expaccess/test/expErrlTest.C
new file mode 100644
index 000000000..10f3b1189
--- /dev/null
+++ b/src/usr/expaccess/test/expErrlTest.C
@@ -0,0 +1,158 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/expaccess/test/expErrlTest.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file expErrlTest.C
+ * @brief Tests the various ways to grab/add explorer error log data
+ */
+#include <rcExpLog.H> // RC error log side
+#include <fapi2.H>
+#include <fapi2/plat_hwp_invoker.H> // FAPI_INVOKE_HWP
+#include <errl/errlmanager.H>
+#include "../errlud_expscom.H" // HB error log side
+
+
+fapi2::ReturnCode get_scom(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint64_t i_address,
+ fapi2::buffer<uint64_t>& o_data)
+{
+ return fapi2::getScom(i_target,i_address,o_data);
+}
+
+uint32_t expErrorLogHb()
+{
+ uint32_t numTests = 0;
+ uint32_t numFails = 0;
+ errlHndl_t l_err = nullptr;
+
+ // Create a vector of TARGETING::Target pointers
+ TARGETING::TargetHandleList l_chipList;
+
+ // Get a list of all of the functioning ocmb chips
+ TARGETING::getAllChips(l_chipList, TARGETING::TYPE_OCMB_CHIP, true);
+
+ //Verify at least one ocmb found, some systems do not have ocmb chips
+ if(l_chipList.size() == 0 )
+ {
+ FAPI_INF("expErrorLogHb: No OCMB targets found, skipping test");
+ }
+
+ // create an error for each OCMB and grab the trace data
+ for ( auto & l_ocmb : l_chipList )
+ {
+ // Get a scom error with bad address
+ FAPI_INF("expErrorLogHb - Get a scom error with bad address for ocmb 0x%.8X",
+ TARGETING::get_huid(l_ocmb));
+ numTests++;
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapi2_ocmbTarget(l_ocmb);
+ fapi2::buffer<uint64_t> l_scom_buffer;
+ FAPI_INVOKE_HWP( l_err, get_scom, fapi2_ocmbTarget,
+ 0xFFFFFFFF, l_scom_buffer );
+ if (l_err)
+ {
+ FAPI_INF("expErrorLogHb - created error log 0x%04X, now adding explorer errors", l_err->plid());
+
+ // Add explorer error logs to this and commit
+ bool logAdded = false;
+ numTests++;
+ logAdded = EXPSCOM::expAddLog(EXPSCOM::ACTIVE_LOG, l_ocmb, l_err);
+ if (!logAdded)
+ {
+ TS_FAIL("expErrorLogHb: No ACTIVE explorer logs added to 0x%04X", l_err->plid());
+ numFails++;
+ }
+
+ numTests++;
+ logAdded = EXPSCOM::expAddLog(EXPSCOM::SAVED_LOG, l_ocmb, l_err);
+ if (!logAdded)
+ {
+ TS_FAIL("expErrorLogHb: No SAVED explorer logs added to 0x%04X", l_err->plid());
+ numFails++;
+ }
+ errlCommit(l_err, CXXTEST_COMP_ID);
+ }
+ else
+ {
+ TS_FAIL("expErrorLogHb: getScom(0xFFFFFFFF) worked on 0x%.8X",
+ TARGETING::get_huid(l_ocmb));
+ numFails++;
+ }
+ }
+
+ FAPI_INF("expErrorLogHb Test Complete. %d/%d fails", numFails, numTests);
+
+ return numFails;
+}
+
+uint32_t expErrorLogRc()
+{
+ uint32_t numTests = 0;
+ uint32_t numFails = 0;
+ errlHndl_t l_errl = nullptr;
+ FAPI_INF("expErrorLogRc() running");
+ do
+ {
+ // Create a vector of TARGETING::Target pointers
+ TARGETING::TargetHandleList l_chipList;
+
+ // Get a list of all of the functioning ocmb chips
+ TARGETING::getAllChips(l_chipList, TARGETING::TYPE_OCMB_CHIP, true);
+ TARGETING::Target * l_ocmb = nullptr;
+
+ //Take the first ocmb and use it
+ if (l_chipList.size() > 0)
+ {
+ l_ocmb = l_chipList[0];
+ }
+ else
+ {
+ FAPI_INF("expErrorLogRc: No OCMB targets found, skipping test");
+ break;
+ }
+
+ numTests++;
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapi2_ocmbTarget(l_ocmb);
+ // This procedure creates an RC error and then adds Explorer log data
+ // to that error
+ // (0x500 bytes of ACTIVE log data, 0x450 bytes of SAVED log data)
+ FAPI_INVOKE_HWP(l_errl, exp_error_rc, fapi2_ocmbTarget, 0x500, 0x450);
+ if(l_errl != nullptr)
+ {
+ // Commit this error log so it can be examined for Explorer log data
+ FAPI_INF("exp_errorFfdc_fail returned expected errl");
+ errlCommit(l_errl,CXXTEST_COMP_ID);
+ l_errl = nullptr;
+ }
+ else
+ {
+ TS_FAIL("expErrorLogRc: No error from exp_errorFfdc_fail !!");
+ numFails++;
+ }
+ } while (0);
+
+ FAPI_INF("expErrorLogRc Test Complete. %d/%d fails",
+ numFails , numTests);
+
+ return numFails;
+}
diff --git a/src/usr/expaccess/test/expErrlTest.H b/src/usr/expaccess/test/expErrlTest.H
new file mode 100644
index 000000000..77b44452d
--- /dev/null
+++ b/src/usr/expaccess/test/expErrlTest.H
@@ -0,0 +1,129 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/expaccess/test/expErrlTest.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __expErrlTest_H
+#define __expErrlTest_H
+
+/**
+ * @file ExpErrorLogTest.H
+ *
+ * @brief Test case for explorer error log grabbing/adding
+*/
+
+#include <cxxtest/TestSuite.H>
+#include <fapi2.H>
+#include "expErrlTest.C"
+#include <exptest_utils.H>
+
+using namespace fapi2;
+
+class test_expErrorLog: public CxxTest::TestSuite
+{
+public:
+
+ /**
+ * @brief Test adding Explorer error logs via RC
+ */
+ void testExpErrorLogRc(void)
+ {
+ // @todo RTC 214629 - disabled until simics implements exp_error_log
+ return;
+
+ if (!iv_serializeTestMutex)
+ {
+ TS_FAIL("iv_serializedTestMutex is not setup, unable to continue");
+ }
+ else
+ {
+ // Inband operations can't be run at the same time
+ // atomic section >>
+ mutex_lock(iv_serializeTestMutex);
+ uint32_t l_res = expErrorLogRc();
+ if (l_res != 0)
+ {
+ TS_FAIL("rcTestExpErrorLogRc. Fail l_res=%d", l_res);
+ }
+ // atomic section <<
+ mutex_unlock(iv_serializeTestMutex);
+ }
+ }
+
+ /**
+ * @brief Test hostboot side of adding Explorer error log to errl
+ */
+ void testExpErrorLogHb(void)
+ {
+ // @todo RTC 214629 - disabled until simics implements exp_error_log
+ return;
+
+ if (!iv_serializeTestMutex)
+ {
+ TS_FAIL("iv_serializedTestMutex is not setup, unable to continue");
+ }
+ else
+ {
+ // Inband operations can't be run at the same time
+ // atomic section >>
+ mutex_lock(iv_serializeTestMutex);
+ uint32_t l_res = expErrorLogHb();
+
+ if (l_res != 0)
+ {
+ TS_FAIL("testExpErrorLogHb. Fail l_res=%d", l_res);
+ }
+ // atomic section <<
+ mutex_unlock(iv_serializeTestMutex);
+ }
+ }
+
+ /**
+ * @brief Constructor
+ */
+ test_expErrorLog() : CxxTest::TestSuite()
+ {
+ // All modules are loaded by runtime,
+ // so testcase loading of modules is not required
+#ifndef __HOSTBOOT_RUNTIME
+ errlHndl_t err = nullptr;
+
+ // For testing, just load the library needed and don't bother with
+ // unloading to avoid pulling the rug from under other tests that need
+ // the loaded library
+ err = exptest::loadModule(exptest::MSS_LIBRARY_NAME);
+ if(err)
+ {
+ TS_FAIL("OCMBCommTest() - Constuctor: failed to load MSS module");
+ errlCommit( err, TARG_COMP_ID );
+ }
+#endif
+ iv_serializeTestMutex = exptest::getTestMutex();
+ };
+
+ private:
+ // This is used for tests that need to not run operations at the same time
+ TARGETING::HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR iv_serializeTestMutex;
+
+};
+
+#endif
diff --git a/src/usr/expaccess/test/expscomtest.H b/src/usr/expaccess/test/expscomtest.H
index c943ca7ba..5f5583287 100644
--- a/src/usr/expaccess/test/expscomtest.H
+++ b/src/usr/expaccess/test/expscomtest.H
@@ -41,8 +41,9 @@
#include <fapi2_hwp_executor.H>
#include <fapi2/hw_access.H>
#include <lib/shared/exp_consts.H>
+#include "exptest_utils.H"
+#include "../expscom_trace.H"
-extern trace_desc_t* g_trac_expscom;
using namespace TARGETING;
using namespace ERRORLOG;
@@ -57,10 +58,11 @@ struct testExpscomAddrData
// Test table values
const testExpscomAddrData g_expscomAddrTable[] =
{
- {0x501C, 0x00000000DEADBEEF},
- {0x209004, 0x00000000C0DEDEAD},
- {0x8010002, 0xDEADC0DEC0DEBEEF}
+ {0x501C, 0x00000000DEADBEEF}, // UART scratch register
+ {0x209004, 0x00000000C0DEDEAD}, // PVT_CTRL - TM_SCRATCH register
+ {0x8010002, 0xDEADC0DEC0DEBEEF} // PSCOM_ERROR_MASK register
};
+
const uint32_t g_expscomAddrTableSz =
sizeof(g_expscomAddrTable)/sizeof(testExpscomAddrData);
@@ -80,7 +82,7 @@ TS_FAIL(STRING , \
l_testEntry.addr, \
get_huid(TARGET)); \
l_err = fapi2::rcToErrl(l_rc); \
-errlCommit(l_err, 0x10);
+errlCommit(l_err, CXXTEST_COMP_ID);
#define FAIL_TEST_ERRL(TARGET, STRING) \
l_fails++; \
@@ -88,7 +90,7 @@ TS_FAIL(STRING , \
l_testEntry.data, \
l_testEntry.addr, \
get_huid(TARGET)); \
-errlCommit(l_err, 0x10);
+errlCommit(l_err, CXXTEST_COMP_ID);
class expscomTest: public CxxTest::TestSuite
{
@@ -107,14 +109,33 @@ private:
return fapi2::getScom(i_target,i_address,o_data);
}
+ fapi2::ReturnCode put_scom(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_address,
+ const fapi2::buffer<uint64_t> i_data)
+ {
+ return fapi2::putScom(i_target,i_address,i_data);
+ }
+
+ fapi2::ReturnCode get_scom(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_address,
+ fapi2::buffer<uint64_t>& o_data)
+ {
+ return fapi2::getScom(i_target,i_address,o_data);
+ }
+
+ // This is used for tests that need to not run operations at the same time
+ HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR iv_serializeTestMutex;
+
public:
/**
- * @brief EXPSCOM test I2C Path
+ * @brief EXPSCOM test I2C Path of FAPI HWP interfaces
* Write value and read back to verify i2c scoms to OCMBs
*/
void testExpscomI2c(void)
{
+// Only MMIO supported at runtime
+#ifndef __HOSTBOOT_RUNTIME
TRACFCOMP( g_trac_expscom, ">> Enter testExpscomI2c");
// Keep trace of pass/fails
uint32_t l_tests = 0;
@@ -125,15 +146,16 @@ public:
// will be used to hold error from fapi calls
fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
fapi2::buffer<uint64_t> l_scom_buffer;
- TargetHandleList l_explorerList;
do{
-// Causing a data storage exception in c_str...
-#ifdef CONFIG_AXONE_BRING_UP
-TRACFCOMP( g_trac_expscom,"skipping testExpscomI2c");
-break;
-#endif
+ if (!iv_serializeTestMutex)
+ {
+ TS_FAIL("iv_serializedTestMutex is not setup");
+ break;
+ }
+
// Get the system's OCMB chips, we will use these as test targets
+ TargetHandleList l_explorerList;
getAllChips( l_explorerList,
TYPE_OCMB_CHIP,
true ); // true: return functional OCMBs
@@ -144,23 +166,44 @@ break;
break;
}
+ // Get the system's MEM_PORT units, we will use these as test targets
+ TargetHandleList l_memportList;
+ getAllChiplets( l_memportList,
+ TYPE_MEM_PORT,
+ true ); // true: return functional OCMBs
+
+ if(l_explorerList.size() != l_memportList.size() )
+ {
+ TS_FAIL( "Wrong number of MEM_PORTs (%d) compared to OCMB_CHIPs (%d)", l_memportList.size(), l_explorerList.size() );
+ break;
+ }
// We will use the first and last targets for these scom tests
auto l_firstExpChip = l_explorerList.front();
auto l_lastExpChip = l_explorerList.back();
+ auto l_firstMemPort = l_memportList.front();
+ auto l_lastMemPort = l_memportList.back();
// Cast the TARGETING::Targets into fapi2::Targets
fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_firstExpChip_fapi(l_firstExpChip);
fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_lastExpChip_fapi(l_lastExpChip);
+ fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> l_firstMemPort_fapi(l_firstMemPort);
+ fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> l_lastMemPort_fapi(l_lastMemPort);
// Save away original scom switch info so we can restore it at the end of the test
- auto first_ocmb_info = l_firstExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
- auto last_ocmb_info = l_lastExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
+ auto first_ocmb_info =
+ l_firstExpChip->getAttr<ATTR_SCOM_SWITCHES>();
+ auto last_ocmb_info =
+ l_lastExpChip->getAttr<ATTR_SCOM_SWITCHES>();
- // This goal of this tests is to make sure I2C scom to OCMB is working so force
- // scom to go over I2C path for these targets
- l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom);
- l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom);
+ // Inband operations can't be run at the same time
+ // atomic section >>
+ mutex_lock(iv_serializeTestMutex);
+
+ // The goal of these tests is to make sure I2C scom to OCMB is
+ // working so force scom to go over I2C path for these targets
+ l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom);
+ l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom);
// Loop through table for first and last OCMB targets
for( uint32_t l_num=0; l_num < g_expscomAddrTableSz; l_num++)
@@ -216,7 +259,7 @@ break;
if(l_err)
{
FAIL_TEST_ERRL(l_firstExpChip,
- "testExpscomI2c>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X")
+ "testExpscomI2c>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X");
}
l_tests++;
@@ -241,7 +284,7 @@ break;
if(l_err)
{
FAIL_TEST_ERRL(l_lastExpChip,
- "testExpscomI2c>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X")
+ "testExpscomI2c>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X");
}
l_tests++;
@@ -253,20 +296,118 @@ break;
l_scom_buffer(),
get_huid(l_lastExpChip));
}
+
+ /// Repeat everything on the MEM_PORT targets
+
+ // Read the test entry info from the global table at the top of this file
+ l_testEntry = g_expscomAddrTable[l_num];
+
+ if(l_testEntry.addr & mss::exp::i2c::IBM_SCOM_INDICATOR)
+ {
+ // If this is an IBM address then we expect 64 bits of data
+ l_scom_buffer.insert<0,64,0,uint64_t>(l_testEntry.data);
+ }
+ else
+ {
+ // Otherwise we know this is a native OCMB address and it is only 32 bits
+ l_scom_buffer.insert<32,32,0,uint32_t>(l_testEntry.data);
+ }
+
+ FAPI_INVOKE_HWP(l_err, put_scom,
+ l_firstMemPort_fapi,
+ l_testEntry.addr,
+ l_scom_buffer );
+ l_tests++;
+ if(l_err)
+ {
+ FAIL_TEST_ERRL(l_firstMemPort,
+ "testExpscomI2c>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X");
+
+ }
+
+ // putScom to last MEM_PORT over i2c
+ FAPI_INVOKE_HWP(l_err, put_scom,
+ l_lastMemPort_fapi,
+ l_testEntry.addr,
+ l_scom_buffer );
+ l_tests++;
+ if(l_err)
+ {
+ FAIL_TEST_ERRL(l_lastMemPort,
+ "testExpscomI2c>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X");
+ }
+
+
+ // Flush scom buffers so it doesnt mess up next test
+ l_scom_buffer.flush<0>();
+
+ // getScom to first MEM_PORT over i2c
+ FAPI_INVOKE_HWP(l_err, get_scom,
+ l_firstMemPort_fapi,
+ l_testEntry.addr,
+ l_scom_buffer );
+ l_tests++;
+ if(l_err)
+ {
+ FAIL_TEST_ERRL(l_firstMemPort,
+ "testExpscomI2c>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X");
+ }
+
+ l_tests++;
+ if(l_scom_buffer() != l_testEntry.data)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomI2c>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_scom_buffer(),
+ get_huid(l_firstMemPort));
+ }
+
+ // Flush scom buffers so it doesnt mess up next test
+ l_scom_buffer.flush<0>();
+
+ // getScom to last MEM_PORT over i2c
+ FAPI_INVOKE_HWP(l_err, get_scom,
+ l_lastMemPort_fapi,
+ l_testEntry.addr,
+ l_scom_buffer );
+ l_tests++;
+ if(l_err)
+ {
+ FAIL_TEST_ERRL(l_lastMemPort,
+ "testExpscomI2c>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X");
+ }
+
+ l_tests++;
+ if(l_scom_buffer() != l_testEntry.data)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomI2c>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_scom_buffer(),
+ get_huid(l_lastMemPort));
+ }
}
// Set ATTR_SCOM_SWITCHES back to their original values
- l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(first_ocmb_info);
- l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(last_ocmb_info);
- }while(0);
+ l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(first_ocmb_info);
+ l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(last_ocmb_info);
+ // << atomic section
+ mutex_unlock(iv_serializeTestMutex);
+ }while(0);
TRACFCOMP( g_trac_expscom, "<< Exit testExpscomI2c");
+#endif
return;
}
+ /**
+ * @brief Test platform level interfaces over I2C
+ */
void testExpscomI2cPlatform(void)
{
-
+// Only mmio supported at runtime
+#ifndef __HOSTBOOT_RUNTIME
TRACFCOMP( g_trac_expscom, ">> Enter testExpscomI2cPlatform");
// Keep trace of pass/fails
uint32_t l_tests = 0;
@@ -283,12 +424,11 @@ break;
TargetHandleList l_explorerList;
do{
-// Causing a data storage exception in c_str...
-#ifdef CONFIG_AXONE_BRING_UP
-TRACFCOMP( g_trac_expscom,"skipping testExpscomI2cPlatformPlatform");
-break;
-#endif
-
+ if (!iv_serializeTestMutex)
+ {
+ TS_FAIL("iv_serializedTestMutex is not setup");
+ break;
+ }
getAllChips( l_explorerList,
TYPE_OCMB_CHIP,
true ); // true: return functional OCMBs
@@ -296,7 +436,7 @@ break;
if(l_explorerList.size() == 0 )
{
- TRACFCOMP( g_trac_expscom, "No OCMB targets found, skipping testExpscomI2cPlatformPlatform");
+ TRACFCOMP( g_trac_expscom, "No OCMB targets found, skipping testExpscomI2cPlatform");
break;
}
@@ -305,412 +445,517 @@ break;
auto l_lastExpChip = l_explorerList.back();
// Save away original scom switch info so we can restore it at the end of the test
- auto first_ocmb_info = l_firstExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
- auto last_ocmb_info = l_lastExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
+ auto first_ocmb_info =
+ l_firstExpChip->getAttr<ATTR_SCOM_SWITCHES>();
+ auto last_ocmb_info =
+ l_lastExpChip->getAttr<ATTR_SCOM_SWITCHES>();
+
+ // Inband operations can't be run at the same time
+ // atomic section >>
+ mutex_lock(iv_serializeTestMutex);
// This goal of this tests is to make sure I2C scom to OCMB is working so force
// scom to go over I2C path for these targets
- l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom);
- l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom);
+ l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom);
+ l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom);
// Loop through table for first and last OCMB targets
for( uint32_t l_num=0; l_num < g_expscomAddrTableSz; l_num++)
{
- // Read the test entry info from the global table at the top of this file
- testExpscomAddrData l_testEntry = g_expscomAddrTable[l_num];
-
- if(l_testEntry.addr & mss::exp::i2c::IBM_SCOM_INDICATOR)
- {
- // If this is an IBM address then we expect 64 bits of data
- l_scom_buffer.insert<0,64,0,uint64_t>(l_testEntry.data);
- }
- else
- {
- // Otherwise we know this is a native OCMB address and it is only 32 bits
- l_scom_buffer.insert<32,32,0,uint32_t>(l_testEntry.data);
- }
- l_err = deviceWrite(l_firstExpChip,
- &l_scom_buffer,
- l_scomSize,
- DEVICE_SCOM_ADDRESS( l_testEntry.addr));
- l_tests++;
- if(l_err)
- {
- FAIL_TEST_ERRL(l_firstExpChip,
+ // Read the test entry info from the global table at the top of this file
+ testExpscomAddrData l_testEntry = g_expscomAddrTable[l_num];
+
+ if(l_testEntry.addr & mss::exp::i2c::IBM_SCOM_INDICATOR)
+ {
+ // If this is an IBM address then we expect 64 bits of data
+ l_scom_buffer.insert<0,64,0,uint64_t>(l_testEntry.data);
+ }
+ else
+ {
+ // Otherwise we know this is a native OCMB address and it is only 32 bits
+ l_scom_buffer.insert<32,32,0,uint32_t>(l_testEntry.data);
+ }
+ l_err = deviceWrite(l_firstExpChip,
+ &l_scom_buffer,
+ l_scomSize,
+ DEVICE_SCOM_ADDRESS( l_testEntry.addr));
+ l_tests++;
+ if(l_err)
+ {
+ FAIL_TEST_ERRL(l_firstExpChip,
+ "testExpscomI2cPlatform>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X");
+
+ }
+
+ l_err = deviceWrite(l_lastExpChip,
+ &l_scom_buffer,
+ l_scomSize,
+ DEVICE_SCOM_ADDRESS( l_testEntry.addr));
+ l_tests++;
+ if(l_err)
+ {
+ FAIL_TEST_ERRL(l_firstExpChip,
"testExpscomI2cPlatform>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X");
- }
-
- l_err = deviceWrite(l_lastExpChip,
- &l_scom_buffer,
- l_scomSize,
- DEVICE_SCOM_ADDRESS( l_testEntry.addr));
- l_tests++;
- if(l_err)
- {
- FAIL_TEST_ERRL(l_firstExpChip,
- "testExpscomI2cPlatform>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X");
-
- }
- // Flush scom buffers so it doesnt mess up next test
- l_scom_buffer.flush<0>();
-
- // getScom to first OCMB over i2c
- l_err = deviceRead(l_firstExpChip,
- &l_scom_buffer(),
- l_scomSize,
- DEVICE_SCOM_ADDRESS( l_testEntry.addr));
- l_tests++;
- if(l_err)
- {
- FAIL_TEST_ERRL(l_firstExpChip,
- "testExpscomI2cPlatform>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X")
- }
-
- l_tests++;
- if(l_scom_buffer() != l_testEntry.data)
- {
- l_fails++;
- TS_FAIL("testExpscomI2cPlatform>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X",
- l_testEntry.data,
- l_scom_buffer(),
- get_huid(l_firstExpChip));
- }
-
-
- // Flush scom buffers so it doesnt mess up next test
- l_scom_buffer.flush<0>();
-
- // getScom to last OCMB over i2c
- l_err = deviceRead(l_lastExpChip,
- &l_scom_buffer(),
- l_scomSize,
- DEVICE_SCOM_ADDRESS( l_testEntry.addr));
- l_tests++;
- if(l_err)
- {
- FAIL_TEST_ERRL(l_firstExpChip,
- "testExpscomI2cPlatform>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X")
- }
-
- l_tests++;
- if(l_scom_buffer() != l_testEntry.data)
- {
- l_fails++;
- TS_FAIL("testExpscomI2cPlatform>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X",
- l_testEntry.data,
- l_scom_buffer(),
- get_huid(l_firstExpChip));
- }
+ }
+ // Flush scom buffers so it doesnt mess up next test
+ l_scom_buffer.flush<0>();
+
+ // getScom to first OCMB over i2c
+ l_err = deviceRead(l_firstExpChip,
+ &l_scom_buffer(),
+ l_scomSize,
+ DEVICE_SCOM_ADDRESS( l_testEntry.addr));
+ l_tests++;
+ if(l_err)
+ {
+ FAIL_TEST_ERRL(l_firstExpChip,
+ "testExpscomI2cPlatform>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X")
+ }
+
+ l_tests++;
+ if(l_scom_buffer() != l_testEntry.data)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomI2cPlatform>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_scom_buffer(),
+ get_huid(l_firstExpChip));
+ }
+
+
+ // Flush scom buffers so it doesnt mess up next test
+ l_scom_buffer.flush<0>();
+
+ // getScom to last OCMB over i2c
+ l_err = deviceRead(l_lastExpChip,
+ &l_scom_buffer(),
+ l_scomSize,
+ DEVICE_SCOM_ADDRESS( l_testEntry.addr));
+ l_tests++;
+ if(l_err)
+ {
+ FAIL_TEST_ERRL(l_firstExpChip,
+ "testExpscomI2cPlatform>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X")
+ }
+
+ l_tests++;
+ if(l_scom_buffer() != l_testEntry.data)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomI2cPlatform>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_scom_buffer(),
+ get_huid(l_firstExpChip));
+ }
}
// Set ATTR_SCOM_SWITCHES back to their original values
- l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(first_ocmb_info);
- l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(last_ocmb_info);
+ l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(first_ocmb_info);
+ l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(last_ocmb_info);
+
+ // << atomic section
+ mutex_unlock(iv_serializeTestMutex);
+
}while(0);
TRACFCOMP( g_trac_expscom, "<< Exit testExpscomI2cPlatform");
+#endif
return;
}
-// TODO RTC: 189447 Enable MMIO tests when MMIO drivers avail
- /**
+ /**
* @brief EXPSCOM test MMIO
* Write value and read back to verify MMIO scoms to OCMBs
+ * using fapi HWPs.
*/
-// void testExpscomMmio(void)
-// {
-// TargetHandleList l_explorerList;
-// uint32_t l_tests = 0;
-// uint32_t l_fails = 0;
-// errlHndl_t l_err = nullptr;
-// fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
-// fapi2::buffer<uint64_t> l_scom_buffer;
-//
-// // Get the system's procs
-// getAllChips( l_explorerList,
-// TYPE_OCMB_CHIP,
-// true ); // true: return functional OCMBs
-//
-// auto l_firstExpChip = l_explorerList.front();
-// auto l_lastExpChip = l_explorerList.back();
-//
-// fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_firstExpChip_fapi(l_firstExpChip);
-// fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_lastExpChip_fapi(l_lastExpChip);
-//
-// auto first_ocmb_info = l_firstExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
-// auto last_ocmb_info = l_lastExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
-//
-//
-// // Loop through table for first and last OCMB, perform i2c write, then
-// // mmio read, and mmio write followed by i2c read.
-// for( uint32_t l_num=0; l_num < g_expscomAddrTableSz; l_num++)
-// {
-// testExpscomAddrData l_testEntry = g_expscomAddrTable[l_num];
-// if(l_testEntry.addr & mss::exp::i2c::IBM_SCOM_INDICATOR)
-// {
-// l_scom_buffer.insert<0,64,0,uint64_t>(l_testEntry.data);
-// }
-// else
-// {
-// l_scom_buffer.insert<0,32,0,uint32_t>(l_testEntry.data);
-// }
-//
-// // putScom to first OCMB over mmio
-// l_rc = put_scom(l_firstExpChip_fapi,
-// l_testEntry.addr,
-// l_scom_buffer);
-// l_tests++;
-// if(l_rc)
-// {
-// l_fails++;
-// TS_FAIL("testExpscomMmio>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
-// l_testEntry.data,
-// l_testEntry.addr,
-// get_huid(l_firstExpChip));
-// l_err = fapi2::rcToErrl(l_rc);
-// errlCommit(l_err, 0x10);
-// }
-//
-// // putScom to last OCMB over mmio
-// l_rc = put_scom(l_lastExpChip_fapi,
-// l_testEntry.addr,
-// l_scom_buffer);
-// l_tests++;
-// if(l_rc)
-// {
-// l_fails++;
-// TS_FAIL("testExpscomMmio>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
-// l_testEntry.data,
-// l_testEntry.addr,
-// get_huid(l_lastExpChip));
-// l_err = fapi2::rcToErrl(l_rc);
-// errlCommit(l_err, 0x10);
-// }
-//
-// // Flush scom buffer so it doesnt mess up next test
-// l_scom_buffer.flush<0>();
-//
-//
-// // getScom to first OCMB over mmio
-// l_rc = get_scom(l_firstExpChip_fapi,
-// l_testEntry.addr,
-// l_scom_buffer);
-// l_tests++;
-// if(l_rc)
-// {
-// l_fails++;
-// TS_FAIL("testExpscomMmio>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
-// l_testEntry.data,
-// l_testEntry.addr,
-// get_huid(l_firstExpChip));
-// l_err = fapi2::rcToErrl(l_rc);
-// errlCommit(l_err, 0x10);
-// }
-//
-// l_tests++;
-// if(l_scom_buffer() != l_testEntry.data)
-// {
-// l_fails++;
-// TS_FAIL("testExpscomMmio>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X",
-// l_testEntry.data,
-// l_scom_buffer(),
-// get_huid(l_firstExpChip));
-// l_err = fapi2::rcToErrl(l_rc);
-// errlCommit(l_err, 0x10);
-// }
-//
-// // Flush scom buffer so it doesnt mess up next test
-// l_scom_buffer.flush<0>();
-//
-// // getScom to last OCMB over mmio
-// l_rc = get_scom(l_lastExpChip_fapi,
-// l_testEntry.addr,
-// l_scom_buffer);
-// l_tests++;
-// if(l_rc)
-// {
-// l_fails++;
-// TS_FAIL("testExpscomMmio>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
-// l_testEntry.data,
-// l_testEntry.addr,
-// get_huid(l_lastExpChip));
-// l_err = fapi2::rcToErrl(l_rc);
-// errlCommit(l_err, 0x10);
-// }
-//
-// l_tests++;
-// if(l_scom_buffer() != l_testEntry.data)
-// {
-// l_fails++;
-// TS_FAIL("testExpscomMmio>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X",
-// l_testEntry.data,
-// l_scom_buffer(),
-// get_huid(l_lastExpChip));
-// l_err = fapi2::rcToErrl(l_rc);
-// errlCommit(l_err, 0x10);
-// }
-// }
-// // Set ATTR_SCOM_SWITCHES back to their original values
-// l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(first_ocmb_info);
-// l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(last_ocmb_info);
-// return;
-// }
-
- /**
- * @brief EXPSCOM test MMIO
- * Write value and read back to verify MMIO
- */
-// void testExpscomCombined(void)
-// {
-// TargetHandleList l_explorerList;
-// uint32_t l_tests = 0;
-// uint32_t l_fails = 0;
-// fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
-// fapi2::buffer<uint64_t> l_scom_buffer;
-//
-// // Get the system's procs
-// getAllChips( l_explorerList,
-// TYPE_OCMB_CHIP,
-// true ); // true: return functional OCMBs
-//
-// auto l_firstExpChip = l_explorerList.front();
-// auto l_lastExpChip = l_explorerList.back();
-//
-// fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_firstExpChip_fapi(l_firstExpChip);
-// fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_lastExpChip_fapi(l_lastExpChip);
-//
-// auto first_ocmb_info = l_firstExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
-// auto last_ocmb_info = l_lastExpChip->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
-//
-// // Loop through table for first and last OCMB
-// for( uint32_t l_num=0; l_num < g_expscomAddrTableSz; l_num++)
-// {
-// testExpscomAddrData l_testEntry = g_expscomAddrTable[l_num];
-//
-// if(l_testEntry.addr & mss::exp::i2c::IBM_SCOM_INDICATOR)
-// {
-// l_scom_buffer.insert<0,64,0,uint64_t>(l_testEntry.data);
-// }
-// else
-// {
-// l_scom_buffer.insert<0,32,0,uint32_t>(l_testEntry.data);
-// }
-//
-// // ODD tests : first target writes MMIO, last target writes I2C
-// // EVEN tests : first target writes I2C, last target writes MMIO
-// if(l_num % 2)
-// {
-// l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceMMIOScom);
-// l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom);
-// }
-// else
-// {
-// l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom);
-// l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceMMIOScom);
-// }
-//
-// // putScom to first OCMB over mmio
-// l_rc = put_scom(l_firstExpChip_fapi,
-// l_testEntry.addr,
-// l_scom_buffer);
-// l_tests++;
-// if(l_rc)
-// {
-// l_fails++;
-// TS_FAIL("testExpscomMmio>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
-// l_testEntry.data,
-// l_testEntry.addr,
-// get_huid(l_firstExpChip));
-// }
-//
-// // putScom to last OCMB over mmio
-// l_rc = put_scom(l_lastExpChip_fapi,
-// l_testEntry.addr,
-// l_scom_buffer);
-// l_tests++;
-// if(l_rc)
-// {
-// l_fails++;
-// TS_FAIL("testExpscomMmio>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
-// l_testEntry.data,
-// l_testEntry.addr,
-// get_huid(l_lastExpChip));
-// }
-//
-// // Flush scom buffer so it doesnt mess up next test
-// l_scom_buffer.flush<0>();
-//
-// // getScom to first OCMB over mmio
-// l_rc = get_scom(l_firstExpChip_fapi,
-// l_testEntry.addr,
-// l_scom_buffer);
-// l_tests++;
-// if(l_rc)
-// {
-// l_fails++;
-// TS_FAIL("testExpscomMmio>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
-// l_testEntry.data,
-// l_testEntry.addr,
-// get_huid(l_firstExpChip));
-// }
-//
-// l_tests++;
-// if(l_scom_buffer() != l_testEntry.data)
-// {
-// l_fails++;
-// TS_FAIL("testExpscomMmio>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X",
-// l_testEntry.data,
-// l_scom_buffer(),
-// get_huid(l_firstExpChip));
-// }
-//
-// // ODD tests : first target reads I2C, last target reads MMIO
-// // EVEN tests : first target reads MMIO, last target reads I2C
-// if(l_num % 2)
-// {
-// l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom);
-// l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceMMIOScom);
-// }
-// else
-// {
-// l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceMMIOScom);
-// l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(forceI2CScom);
-// }
-//
-// // Flush scom buffer so it doesnt mess up next test
-// l_scom_buffer.flush<0>();
-//
-// // getScom to last OCMB over mmio
-// l_rc = get_scom(l_lastExpChip_fapi,
-// l_testEntry.addr,
-// l_scom_buffer);
-// l_tests++;
-// if(l_rc)
-// {
-// l_fails++;
-// TS_FAIL("testExpscomMmio>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
-// l_testEntry.data,
-// l_testEntry.addr,
-// get_huid(l_lastExpChip));
-// }
-//
-// l_tests++;
-// if(l_scom_buffer() != l_testEntry.data)
-// {
-// l_fails++;
-// TS_FAIL("testExpscomMmio>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X",
-// l_testEntry.data,
-// l_scom_buffer(),
-// get_huid(l_lastExpChip));
-// }
-// }
-// // Set ATTR_SCOM_SWITCHES back to their original values
-// l_firstExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(first_ocmb_info);
-// l_lastExpChip->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(last_ocmb_info);
-// return;
-// }
+ void testExpscomMmio(void)
+ {
+ TargetHandleList l_explorerList;
+ uint32_t l_tests = 0;
+ uint32_t l_fails = 0;
+ errlHndl_t l_err = nullptr;
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::buffer<uint64_t> l_scom_buffer;
+
+ TRACFCOMP(g_trac_expscom, ">> Enter testExpscomMmio");
+
+ do{
+ if (!iv_serializeTestMutex)
+ {
+ TS_FAIL("iv_serializedTestMutex is not setup");
+ break;
+ }
+
+ // Get the system's procs
+ getAllChips( l_explorerList,
+ TYPE_OCMB_CHIP,
+ true ); // true: return functional OCMBs
+
+ if(l_explorerList.size() == 0 )
+ {
+ TRACFCOMP(g_trac_expscom, "No OCMB targets found, skipping testExpscomMmio");
+ break;
+ }
+
+ auto l_firstExpChip = l_explorerList.front();
+ auto l_lastExpChip = l_explorerList.back();
+
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
+ l_firstExpChip_fapi(l_firstExpChip);
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
+ l_lastExpChip_fapi(l_lastExpChip);
+
+ auto first_ocmb_info =
+ l_firstExpChip->getAttr<ATTR_SCOM_SWITCHES>();
+ auto last_ocmb_info =
+ l_lastExpChip->getAttr<ATTR_SCOM_SWITCHES>();
+
+ // Inband operations can't be run at the same time
+ // atomic section >>
+ mutex_lock(iv_serializeTestMutex);
+
+ // Force use of MMIO
+ l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceMMIOScom);
+ l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceMMIOScom);
+
+ // Loop through table for first and last OCMB, perform i2c write,
+ // then read it back
+ for( uint32_t l_num=0; l_num < g_expscomAddrTableSz; l_num++)
+ {
+ testExpscomAddrData l_testEntry = g_expscomAddrTable[l_num];
+ if(l_testEntry.addr & mss::exp::i2c::IBM_SCOM_INDICATOR)
+ {
+ l_scom_buffer.insert<0,64,0,uint64_t>(l_testEntry.data);
+ }
+ else
+ {
+ l_scom_buffer.insert<32,32,0,uint32_t>(l_testEntry.data);
+ }
+
+ // putScom to first OCMB over mmio
+ l_rc = put_scom(l_firstExpChip_fapi,
+ l_testEntry.addr,
+ l_scom_buffer);
+ l_tests++;
+ if(l_rc)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomMmio>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_testEntry.addr,
+ get_huid(l_firstExpChip));
+ l_err = fapi2::rcToErrl(l_rc);
+ errlCommit(l_err, CXXTEST_COMP_ID);
+ }
+
+ // putScom to last OCMB over mmio
+ l_rc = put_scom(l_lastExpChip_fapi,
+ l_testEntry.addr,
+ l_scom_buffer);
+ l_tests++;
+ if(l_rc)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomMmio>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_testEntry.addr,
+ get_huid(l_lastExpChip));
+ l_err = fapi2::rcToErrl(l_rc);
+ errlCommit(l_err, CXXTEST_COMP_ID);
+ }
+
+ // Flush scom buffer so it doesnt mess up next test
+ l_scom_buffer.flush<0>();
+
+ // getScom to first OCMB over mmio
+ l_rc = get_scom(l_firstExpChip_fapi,
+ l_testEntry.addr,
+ l_scom_buffer);
+ l_tests++;
+ if(l_rc)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomMmio>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_testEntry.addr,
+ get_huid(l_firstExpChip));
+ l_err = fapi2::rcToErrl(l_rc);
+ errlCommit(l_err, CXXTEST_COMP_ID);
+ }
+
+ l_tests++;
+ if(l_scom_buffer() != l_testEntry.data)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomMmio>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_scom_buffer(),
+ get_huid(l_firstExpChip));
+ l_err = fapi2::rcToErrl(l_rc);
+ errlCommit(l_err, CXXTEST_COMP_ID);
+ }
+
+ // Flush scom buffer so it doesnt mess up next test
+ l_scom_buffer.flush<0>();
+
+ // getScom to last OCMB over mmio
+ l_rc = get_scom(l_lastExpChip_fapi,
+ l_testEntry.addr,
+ l_scom_buffer);
+ l_tests++;
+ if(l_rc)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomMmio>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_testEntry.addr,
+ get_huid(l_lastExpChip));
+ l_err = fapi2::rcToErrl(l_rc);
+ errlCommit(l_err, CXXTEST_COMP_ID);
+ }
+
+ l_tests++;
+ if(l_scom_buffer() != l_testEntry.data)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomMmio>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_scom_buffer(),
+ get_huid(l_lastExpChip));
+ l_err = fapi2::rcToErrl(l_rc);
+ errlCommit(l_err, CXXTEST_COMP_ID);
+ }
+ }
+ // Set ATTR_SCOM_SWITCHES back to their original values
+ l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(first_ocmb_info);
+ l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(last_ocmb_info);
+
+ // << atomic section
+ mutex_unlock(iv_serializeTestMutex);
+ }while(0);
+
+
+ TRACFCOMP(g_trac_expscom, "<< Exit testExpscomMmio");
+ return;
+ }
+
+ /**
+ * @brief EXPSCOM test MMIO
+ * Combine I2C and MMIO reads/writes to verify that we
+ * get consistent results using FAPI HWPs.
+ */
+ void testExpscomCombined(void)
+ {
+// Only MMIO scoms supported at runtime, i2c not supported
+#ifndef __HOSTBOOT_RUNTIME
+ TargetHandleList l_explorerList;
+ uint32_t l_tests = 0;
+ uint32_t l_fails = 0;
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::buffer<uint64_t> l_scom_buffer;
+
+ TRACFCOMP(g_trac_expscom, ">> Enter testExpscomCombined");
+
+ do{
+ if (!iv_serializeTestMutex)
+ {
+ TS_FAIL("iv_serializedTestMutex is not setup");
+ break;
+ }
+
+ // Get the system's procs
+ getAllChips( l_explorerList,
+ TYPE_OCMB_CHIP,
+ true ); // true: return functional OCMBs
+
+ if(l_explorerList.size() == 0 )
+ {
+ TRACFCOMP(g_trac_expscom, "No OCMB targets found, skipping testExpscomCombined");
+ break;
+ }
+
+ auto l_firstExpChip = l_explorerList.front();
+ auto l_lastExpChip = l_explorerList.back();
+
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
+ l_firstExpChip_fapi(l_firstExpChip);
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
+ l_lastExpChip_fapi(l_lastExpChip);
+
+ auto first_ocmb_info =
+ l_firstExpChip->getAttr<ATTR_SCOM_SWITCHES>();
+ auto last_ocmb_info =
+ l_lastExpChip->getAttr<ATTR_SCOM_SWITCHES>();
+ // Inband operations can't be run at the same time
+ // atomic section >>
+ mutex_lock(iv_serializeTestMutex);
+
+ // Loop through table for first and last OCMB, perform i2c write,
+ // then mmio read, and mmio write followed by i2c read.
+ for( uint32_t l_num=0; l_num < g_expscomAddrTableSz; l_num++)
+ {
+ testExpscomAddrData l_testEntry = g_expscomAddrTable[l_num];
+
+ if(l_testEntry.addr & mss::exp::i2c::IBM_SCOM_INDICATOR)
+ {
+ l_scom_buffer.insert<0,64,0,uint64_t>(l_testEntry.data);
+ }
+ else
+ {
+ l_scom_buffer.insert<32,32,0,uint32_t>(l_testEntry.data);
+ }
+
+ // ODD tests : first target writes MMIO, last target writes I2C
+ // EVEN tests : first target writes I2C, last target writes MMIO
+ if(l_num % 2)
+ {
+ l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceMMIOScom);
+ l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom);
+ }
+ else
+ {
+ l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom);
+ l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceMMIOScom);
+ }
+
+ // putScom to first OCMB
+ l_rc = put_scom(l_firstExpChip_fapi,
+ l_testEntry.addr,
+ l_scom_buffer);
+ l_tests++;
+ if(l_rc)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomCombined>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_testEntry.addr,
+ get_huid(l_firstExpChip));
+ }
+
+ // putScom to last OCMB
+ l_rc = put_scom(l_lastExpChip_fapi,
+ l_testEntry.addr,
+ l_scom_buffer);
+ l_tests++;
+ if(l_rc)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomCombined>> Failed putScom writing 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_testEntry.addr,
+ get_huid(l_lastExpChip));
+ }
+
+ // Flush scom buffer so it doesnt mess up next test
+ l_scom_buffer.flush<0>();
+
+ // getScom to first OCMB
+ l_rc = get_scom(l_firstExpChip_fapi,
+ l_testEntry.addr,
+ l_scom_buffer);
+ l_tests++;
+ if(l_rc)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomCombined>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_testEntry.addr,
+ get_huid(l_firstExpChip));
+ }
+
+ l_tests++;
+ if(l_scom_buffer() != l_testEntry.data)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomCombined>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_scom_buffer(),
+ get_huid(l_firstExpChip));
+ }
+
+ // ODD tests : first target reads I2C, last target reads MMIO
+ // EVEN tests : first target reads MMIO, last target reads I2C
+ if(l_num % 2)
+ {
+ l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom);
+ l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceMMIOScom);
+ }
+ else
+ {
+ l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceMMIOScom);
+ l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(forceI2CScom);
+ }
+
+ // Flush scom buffer so it doesnt mess up next test
+ l_scom_buffer.flush<0>();
+
+ // getScom to last OCMB
+ l_rc = get_scom(l_lastExpChip_fapi,
+ l_testEntry.addr,
+ l_scom_buffer);
+ l_tests++;
+ if(l_rc)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomCombined>> Failed getScom reading 0x%.16X to 0x%.8X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_testEntry.addr,
+ get_huid(l_lastExpChip));
+ }
+
+ l_tests++;
+ if(l_scom_buffer() != l_testEntry.data)
+ {
+ l_fails++;
+ TS_FAIL("testExpscomCombined>> Expected 0x%.16X but got 0x%.16X on target w/ huid 0x%.8X",
+ l_testEntry.data,
+ l_scom_buffer(),
+ get_huid(l_lastExpChip));
+ }
+ }
+
+ // Set ATTR_SCOM_SWITCHES back to their original values
+ l_firstExpChip->setAttr<ATTR_SCOM_SWITCHES>(first_ocmb_info);
+ l_lastExpChip->setAttr<ATTR_SCOM_SWITCHES>(last_ocmb_info);
+
+ // << atomic section
+ mutex_unlock(iv_serializeTestMutex);
+ }while(0);
+
+ TRACFCOMP(g_trac_expscom, "<< Exit testExpscomCombined");
+#endif
+ return;
+ }
+
+ /**
+ * @brief Constructor
+ */
+ expscomTest() : CxxTest::TestSuite()
+ {
+ // All modules are loaded by runtime,
+ // so testcase loading of modules is not required
+#ifndef __HOSTBOOT_RUNTIME
+ errlHndl_t err = nullptr;
+
+ err = exptest::loadModule(exptest::MSS_LIBRARY_NAME);
+ if(err)
+ {
+ TS_FAIL("expscomTest() - Constuctor: failed to load MSS module");
+ errlCommit( err, CXXTEST_COMP_ID );
+ }
+#endif
+ iv_serializeTestMutex = exptest::getTestMutex();
+ };
+
+
+ /**
+ * @brief Destructor
+ */
+ ~expscomTest()
+ {
+ };
};
diff --git a/src/usr/expaccess/test/exptest_utils.C b/src/usr/expaccess/test/exptest_utils.C
new file mode 100644
index 000000000..01096716f
--- /dev/null
+++ b/src/usr/expaccess/test/exptest_utils.C
@@ -0,0 +1,136 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/expaccess/test/exptest_utils.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <fapi2.H>
+#include <cxxtest/TestSuite.H>
+#include "exptest_utils.H"
+
+namespace exptest
+{
+ errlHndl_t loadModule(const char * i_modName)
+ {
+ errlHndl_t err = NULL;
+
+ // VFS functions only compilable in non-runtime environment
+ #ifndef __HOSTBOOT_RUNTIME
+ if(!VFS::module_is_loaded(i_modName))
+ {
+ err = VFS::module_load(i_modName);
+ if(err)
+ {
+ TS_FAIL("loadModule() - %s load failed", i_modName );
+ }
+ else
+ {
+ FAPI_INF("loadModule: %s loaded", i_modName);
+ }
+ }
+ #endif
+ return err;
+ }
+
+ TARGETING::HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR getTestMutex(void)
+ {
+ TARGETING::HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR pMutex = nullptr;
+
+ // Get a reference to the target service
+ TARGETING::TargetService& l_targetService = TARGETING::targetService();
+
+ // Get the system target containing the test mutex
+ TARGETING::Target* l_pTarget = NULL;
+ (void) l_targetService.getTopLevelTarget(l_pTarget);
+ if (l_pTarget == nullptr)
+ {
+ TS_INFO("getTestMutex: Top level target handle is NULL");
+ }
+ else
+ {
+ // use the chip-specific mutex attribute
+ pMutex = l_pTarget->getHbMutexAttr
+ <TARGETING::ATTR_HB_MUTEX_SERIALIZE_TEST_LOCK>();
+ }
+ return pMutex;
+ }
+
+ void enableInbandScomsOcmb(const TARGETING::TargetHandle_t i_ocmbTarget)
+ {
+ mutex_t* l_mutex = nullptr;
+
+ assert((i_ocmbTarget != nullptr),
+ "enableInbandScomsOcmb: target is NULL!");
+
+ // Verify that the target is of type OCMB_CHIP
+ TARGETING::ATTR_TYPE_type l_targetType =
+ i_ocmbTarget->getAttr<TARGETING::ATTR_TYPE>();
+ assert((l_targetType == TARGETING::TYPE_OCMB_CHIP),
+ "enableInbandScomsOcmb: target is not an OCMB chip!");
+
+ TS_INFO("enableInbandScomsOcmb: switching to use MMIO on OCMB 0x%08x",
+ TARGETING::get_huid(i_ocmbTarget));
+
+ //don't mess with attributes without the mutex (just to be safe)
+ l_mutex = i_ocmbTarget->getHbMutexAttr<TARGETING::ATTR_IBSCOM_MUTEX>();
+ mutex_lock(l_mutex);
+
+ TARGETING::ScomSwitches l_switches =
+ i_ocmbTarget->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
+ l_switches.useInbandScom = 1;
+ l_switches.useI2cScom = 0;
+
+ // Modify attribute
+ i_ocmbTarget->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(l_switches);
+ mutex_unlock(l_mutex);
+ };
+
+ void disableInbandScomsOcmb(const TARGETING::TargetHandle_t i_ocmbTarget)
+ {
+ mutex_t* l_mutex = nullptr;
+
+ assert((i_ocmbTarget != nullptr),
+ "disableInbandScomsOcmb: target is NULL!");
+
+ // Verify that the target is of type OCMB_CHIP
+ TARGETING::ATTR_TYPE_type l_targetType =
+ i_ocmbTarget->getAttr<TARGETING::ATTR_TYPE>();
+ assert((l_targetType == TARGETING::TYPE_OCMB_CHIP),
+ "disableInbandScomsOcmb: target is not an OCMB chip!");
+
+ TS_INFO("disableInbandScomsOcmb: switching to use i2c on OCMB 0x%08x",
+ TARGETING::get_huid(i_ocmbTarget));
+
+ //don't mess with attributes without the mutex (just to be safe)
+ l_mutex = i_ocmbTarget->getHbMutexAttr<TARGETING::ATTR_IBSCOM_MUTEX>();
+ mutex_lock(l_mutex);
+
+ TARGETING::ScomSwitches l_switches =
+ i_ocmbTarget->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
+ l_switches.useInbandScom = 0;
+ l_switches.useI2cScom = 1;
+
+ // Modify attribute
+ i_ocmbTarget->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(l_switches);
+ mutex_unlock(l_mutex);
+ };
+
+}
diff --git a/src/usr/expaccess/test/exptest_utils.H b/src/usr/expaccess/test/exptest_utils.H
new file mode 100644
index 000000000..babba0fcf
--- /dev/null
+++ b/src/usr/expaccess/test/exptest_utils.H
@@ -0,0 +1,64 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/expaccess/test/exptest_utils.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef EXPTEST_UTILS_H_
+#define EXPTEST_UTILS_H_
+
+#ifndef __HOSTBOOT_RUNTIME
+#include <vfs/vfs.H> // module_is_loaded & module_load
+#endif
+
+namespace exptest
+{
+
+// Need this module for mss::c_str call in HWP failure path traces
+const char MSS_LIBRARY_NAME[17] = "libisteps_mss.so";
+
+/**
+ * @brief Generic function to load a module
+ * @param i_modName - module name to load
+ * @return error handle if module_load call fails
+ */
+errlHndl_t loadModule(const char * i_modName);
+
+/**
+ * @brief Get the mutex pointer for syncronizing tests
+ * @return pointer to mutex, nullptr if not found
+ */
+TARGETING::HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR getTestMutex(void);
+
+/**
+ * @brief Enable inband scoms on an OCMB target
+ * @param[in] i_ocmbTarget The target OCMB chip
+ */
+void enableInbandScomsOcmb(const TARGETING::TargetHandle_t i_ocmbTarget);
+
+/**
+ * @brief Disable inband scoms on an OCMB target (use i2c instead)
+ * @param[in] i_ocmbTarget The target OCMB chip
+ */
+void disableInbandScomsOcmb(const TARGETING::TargetHandle_t i_ocmbTarget);
+}
+
+#endif
diff --git a/src/usr/expaccess/test/makefile b/src/usr/expaccess/test/makefile
index 461a908c8..0e4f0e2e5 100644
--- a/src/usr/expaccess/test/makefile
+++ b/src/usr/expaccess/test/makefile
@@ -28,7 +28,6 @@ MODULE = testexpaccess
include test.mk
-#TODO RTC:196806 re-enable mmio communication tests when mmio works
-TESTS = expscomtest.H
+TESTS = *.H
-include ${ROOTPATH}/config.mk \ No newline at end of file
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/expaccess/test/ocmbcommtest.H b/src/usr/expaccess/test/ocmbcommtest.H
index 94d298032..3c5486a1b 100644
--- a/src/usr/expaccess/test/ocmbcommtest.H
+++ b/src/usr/expaccess/test/ocmbcommtest.H
@@ -33,13 +33,13 @@
#include <errl/errlmanager.H>
#include <errl/errlentry.H>
#include <fapi2.H>
-#ifndef __HOSTBOOT_RUNTIME
-#include <vfs/vfs.H> // module_is_loaded & module_load
-#endif
+
#include <plat_hwp_invoker.H>
-#include <exp_inband.H>
+#include <lib/inband/exp_inband.H>
#include <exp_data_structs.H>
#include <generic/memory/lib/utils/endian_utils.H>
+#include "exptest_utils.H"
+
// EXP_FW_ADAPTER_PROPERTIES_GET data response format
#define FW_ADAPTER_MAX_FW_IMAGE 4
@@ -67,64 +67,6 @@ typedef struct
} FW_ADAPTER_PROPERTIES_type;
-// Need this module for mss::c_str call in HWP failure path traces
-const char MSS_LIBRARY_NAME[17] = "libisteps_mss.so";
-
-/**
- * @brief Generic function to load a module
- * @param o_module_loaded - returns true if module is loaded by this function
- * @param i_modName - module name to load
- * @return error handle if module_load call fails
- */
-errlHndl_t loadModule(bool & o_module_loaded, const char * i_modName)
-{
- errlHndl_t err = NULL;
- o_module_loaded = false;
-
-// VFS functions only compilable in non-runtime environment
-#ifndef __HOSTBOOT_RUNTIME
- if(!VFS::module_is_loaded(i_modName))
- {
- err = VFS::module_load(i_modName);
- if(err)
- {
- TS_FAIL("loadModule() - %s load failed", i_modName );
- }
- else
- {
- o_module_loaded = true;
- FAPI_INF("loadModule: %s loaded", i_modName);
- }
- }
-#endif
- return err;
-}
-
-/**
- * @brief Generic function to unload a module
- * @param i_modName - module name to load
- * @return error handle if module_unload call fails
- */
-errlHndl_t unloadModule(const char * i_modName)
-{
- errlHndl_t err = NULL;
-
-// VFS function only compilable in non-runtime environment
-#ifndef __HOSTBOOT_RUNTIME
- err = VFS::module_unload(i_modName);
- if(err)
- {
- TS_FAIL("unloadExplorerModule() - %s unload failed", i_modName );
- }
- else
- {
- FAPI_INF("unloadModule: %s unloaded", i_modName);
- }
-#endif
- return err;
-}
-
-
class OCMBCommTest: public CxxTest::TestSuite
{
public:
@@ -189,11 +131,13 @@ class OCMBCommTest: public CxxTest::TestSuite
}
/**
- * @brief Test the Explorer inband command/response path
+ * @brief Send and check get_properties Explorer inband command
+ * @return Number of failures
*/
- void testOcmbInbandCmdRsp( void )
+ int sendOcmbInbandCmdRsp(bool setScomI2c)
{
errlHndl_t l_errl = nullptr;
+ uint8_t failures = 0;
// Create a vector of TARGETING::Target pointers
TARGETING::TargetHandleList l_chipList;
@@ -210,102 +154,217 @@ class OCMBCommTest: public CxxTest::TestSuite
for (auto & l_ocmb: l_chipList)
{
- FAPI_INF("testOcmbInbandCmdRsp: testing 0x%.8X OCMB", TARGETING::get_huid(l_ocmb));
-
- fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>l_fapi2_target( l_ocmb );
+ do
+ {
+ if (setScomI2c)
+ {
+ FAPI_INF("sendOcmbInbandCmdRsp: testing 0x%.8X OCMB using I2C", TARGETING::get_huid(l_ocmb));
+ // disable inband and use i2c when possible
+ exptest::disableInbandScomsOcmb(l_ocmb);
+ }
+ else
+ {
+ FAPI_INF("sendOcmbInbandCmdRsp: testing 0x%.8X OCMB using MMIO", TARGETING::get_huid(l_ocmb));
+ // just incase some other test disabled inband scoms
+ exptest::enableInbandScomsOcmb(l_ocmb);
+ }
+
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>l_fapi2_target( l_ocmb );
+
+ TRACFBIN(g_trac_expscom, "l_cmd: ", &l_cmd, sizeof(host_fw_command_struct));
+
+ // send the command
+ FAPI_INVOKE_HWP(l_errl, mss::exp::ib::putCMD, l_fapi2_target,
+ l_cmd);
+ if (l_errl)
+ {
+ TS_FAIL("Error from putCMD for 0x%.8X target",
+ TARGETING::get_huid(l_ocmb));
+ failures++;
+ break;
+ }
+
+ FAPI_INF("sendOcmbInbandCmdRsp: reading response");
+
+ // grab the response
+ FAPI_INVOKE_HWP(l_errl, mss::exp::ib::getRSP, l_fapi2_target,
+ l_rsp, l_rsp_data);
+ if (l_errl)
+ {
+ TS_FAIL("Error from getRSP for 0x%.8X target, plid=0x%X rc=0x%X",
+ TARGETING::get_huid(l_ocmb),
+ ERRL_GETPLID_SAFE(l_errl), ERRL_GETRC_SAFE(l_errl));
+ failures++;
+ break;
+ }
+
+ TRACFBIN(g_trac_expscom, "l_rsp: ", &l_rsp, sizeof(host_fw_response_struct));
+ TRACFBIN(g_trac_expscom, "l_rsp_data: ", l_rsp_data.data(), l_rsp_data.size());
+
+ // Check for a valid data response length
+ if (l_rsp.response_length != sizeof(FW_ADAPTER_PROPERTIES_type))
+ {
+ TS_FAIL("Unexpected response length 0x%.8X (expected 0x%.8X)",
+ l_rsp.response_length, sizeof(FW_ADAPTER_PROPERTIES_type));
+ failures++;
+ break;
+ }
+
+ // Now convert the little endian response data into big endian
+ FW_ADAPTER_PROPERTIES_type l_fw_adapter_data;
+ fw_adapter_properties_struct_from_little_endian(l_fw_adapter_data,
+ l_rsp_data);
+
+ // Check for some expected response values
+ // Simics should return 0x88 as the first byte of chip_version
+ if (l_fw_adapter_data.chip_version[0] != 0x88 )
+ {
+ TS_FAIL("Expected chip_version to start with 0x88, found 0x%02X",
+ l_fw_adapter_data.chip_version[0]);
+ failures++;
+ }
+ } while (0);
- // send the command
- FAPI_INVOKE_HWP(l_errl, mss::exp::ib::putCMD, l_fapi2_target,
- l_cmd);
if (l_errl)
{
- TS_FAIL("Error from putCMD for 0x%.8X target",
- TARGETING::get_huid(l_ocmb));
- break;
+ // Commit the error as this is NOT expected and
+ // needs to be investigated
+ errlCommit( l_errl, TARG_COMP_ID );
}
- // grab the response
- FAPI_INVOKE_HWP(l_errl, mss::exp::ib::getRSP, l_fapi2_target,
- l_rsp, l_rsp_data);
- if (l_errl)
+ if (setScomI2c)
{
- TS_FAIL("Error from getRSP for 0x%.8X target",
- TARGETING::get_huid(l_ocmb));
- break;
+ // Default the ocmb back to inband communication
+ exptest::enableInbandScomsOcmb(l_ocmb);
}
+ }
+
+ FAPI_INF("sendOcmbInbandCmdRsp: exiting");
+ return failures;
+ };
+
+ /**
+ * @brief Test the Explorer inband command/response path over MMIO
+ */
+ void testOcmbInbandCmdRspOverMMIO( void )
+ {
+ if (!iv_serializeTestMutex)
+ {
+ TS_FAIL("iv_serializedTestMutex is not setup, unable to continue");
+ }
+ else
+ {
+ // Inband operations can't be run at the same time
+ // atomic section >>
+ mutex_lock(iv_serializeTestMutex);
- // Check for a valid data response length
- if (l_rsp.response_length != sizeof(FW_ADAPTER_PROPERTIES_type))
+ int failures = sendOcmbInbandCmdRsp(false);
+ if (failures)
{
- TS_FAIL("Unexpected response length 0x%.8X (expected 0x%.8X)",
- l_rsp.response_length, sizeof(FW_ADAPTER_PROPERTIES_type));
- break;
+ TS_FAIL("testOcmbInbandCmdRspOverMMIO() failed: %d", failures);
}
+ mutex_unlock(iv_serializeTestMutex);
+ }
+ }
+
+ /**
+ * @brief Test the Explorer inband command/response path over I2C
+ * using ATTR_FORCE_SRAM_MMIO_OVER_I2C
+ */
+ void testOcmbInbandCmdRspOverI2c_via_force( void )
+ {
+ FAPI_INF("testOcmbInbandCmdRspOverI2c_via_force: entering");
+ if (!iv_serializeTestMutex)
+ {
+ TS_FAIL("iv_serializedTestMutex is not setup, unable to continue");
+ }
+ else
+ {
+ // Inband operations can't be run at the same time
+ // atomic section >>
+ mutex_lock(iv_serializeTestMutex);
+
+ // Set FORCE_SRAM_MMIO_OVER_I2C to change to use I2C instead of MMIO
+ TARGETING::Target * l_sys = nullptr;
+ TARGETING::targetService().getTopLevelTarget(l_sys);
+ crit_assert(l_sys != nullptr);
- // Now convert the little endian response data into big endian
- FW_ADAPTER_PROPERTIES_type l_fw_adapter_data;
- fw_adapter_properties_struct_from_little_endian(l_fw_adapter_data,
- l_rsp_data);
+ l_sys->setAttr<TARGETING::ATTR_FORCE_SRAM_MMIO_OVER_I2C>(0x01);
- // Check for some expected response values
- // Simics should return 0x10 as the first byte of chip_version
- if (l_fw_adapter_data.chip_version[0] != 0x10 )
+ int failures = sendOcmbInbandCmdRsp(false);
+ if (failures)
{
- TS_FAIL("Expected chip_version to start with 0x10, found 0x%02X",
- l_fw_adapter_data.chip_version[0]);
+ TS_FAIL("testOcmbInbandCmdRspOverI2c_via_force() failed: %d", failures);
}
+
+ // Restore using MMIO instead of I2C
+ l_sys->setAttr<TARGETING::ATTR_FORCE_SRAM_MMIO_OVER_I2C>(0x00);
+
+ mutex_unlock(iv_serializeTestMutex);
}
+ FAPI_INF("testOcmbInbandCmdRspOverI2c_via_force: exiting");
+ }
- if (l_errl)
+ /**
+ * @brief Test the Explorer inband command/response path over I2C
+ * using scom setting to i2c
+ */
+ void testOcmbInbandCmdRspOverI2c_via_scom_switch( void )
+ {
+ FAPI_INF("testOcmbInbandCmdRspOverI2c_via_scom_switch: entering");
+ if (!iv_serializeTestMutex)
{
- errlCommit( l_errl, TARG_COMP_ID );
+ TS_FAIL("iv_serializedTestMutex is not setup, unable to continue");
}
- FAPI_INF("testOcmbInbandCmdRsp: exiting");
- };
+ else
+ {
+ // Inband operations can't be run at the same time
+ // atomic section >>
+ mutex_lock(iv_serializeTestMutex);
+
+ // Set SCOM_SWITCHES to use i2c instead of MMMIO when
+ // running the inband cmd/rsp operations
+ int failures = sendOcmbInbandCmdRsp(true);
+ if (failures)
+ {
+ TS_FAIL("testOcmbInbandCmdRspOverI2c_via_scom_switch() failed: %d", failures);
+ }
+
+ mutex_unlock(iv_serializeTestMutex);
+ }
+ FAPI_INF("testOcmbInbandCmdRspOverI2c_via_scom_switch: exiting");
+ }
/**
* @brief Constructor
*/
OCMBCommTest() : CxxTest::TestSuite()
{
- mss_module_loaded = false;
-
// All modules are loaded by runtime,
// so testcase loading of modules is not required
#ifndef __HOSTBOOT_RUNTIME
errlHndl_t err = nullptr;
- err = loadModule(mss_module_loaded, MSS_LIBRARY_NAME);
+ err = exptest::loadModule(exptest::MSS_LIBRARY_NAME);
if(err)
{
TS_FAIL("OCMBCommTest() - Constuctor: failed to load MSS module");
errlCommit( err, TARG_COMP_ID );
}
#endif
+ iv_serializeTestMutex = exptest::getTestMutex();
};
-
/**
* @brief Destructor
*/
~OCMBCommTest()
{
- errlHndl_t err = nullptr;
- if (mss_module_loaded)
- {
- err = unloadModule(MSS_LIBRARY_NAME);
- if(err)
- {
- TS_FAIL("~OCMBCommTest() - Destructor: failed to unload MSS module");
- errlCommit( err, TARG_COMP_ID );
- }
- }
};
private:
- // use this to keep track of if we need to unload any
- // modules loaded by this testcase
- bool mss_module_loaded;
+ // This is used for tests that need to not run operations at the same time
+ TARGETING::HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR iv_serializeTestMutex;
};
diff --git a/src/usr/expaccess/test/rcExpLog.C b/src/usr/expaccess/test/rcExpLog.C
new file mode 100644
index 000000000..53e61cd5d
--- /dev/null
+++ b/src/usr/expaccess/test/rcExpLog.C
@@ -0,0 +1,55 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/expaccess/test/rcExpLog.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file rcExpLog.C
+ * @brief Call fapi2::ReturnCode functions for explorer logs
+ */
+#include <cxxtest/TestSuite.H>
+#include <fapi2.H>
+#include <plat_hwp_invoker.H>
+#include <hwp_error_info.H>
+#include <hwp_ffdc_classes.H>
+
+#include <rcExpLog.H>
+
+fapi2::ReturnCode exp_error_rc(
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_target,
+ const uint32_t i_active_log_size,
+ const uint32_t i_saved_log_size)
+{
+ FAPI_INF("Enter exp_error_rc (active %d, saved %d)...",
+ i_active_log_size, i_saved_log_size);
+
+ FAPI_ASSERT(0, fapi2::COLLECT_EXPLORER_ERROR()
+ .set_OCMB_CHIP_TARGET(i_ocmb_target)
+ .set_EXP_ACTIVE_LOG_SIZE(i_active_log_size)
+ .set_EXP_SAVED_LOG_SIZE(i_saved_log_size),
+ "Testcase exp_error_rc assert");
+
+fapi_try_exit:
+
+ FAPI_INF("Exiting exp_error_rc...");
+ return fapi2::current_err;
+}
diff --git a/src/usr/expaccess/test/rcExpLog.H b/src/usr/expaccess/test/rcExpLog.H
new file mode 100644
index 000000000..c3193bef9
--- /dev/null
+++ b/src/usr/expaccess/test/rcExpLog.H
@@ -0,0 +1,49 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/expaccess/test/rcExpLog.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file rcExpLog.H
+ *
+ * @brief These procedures provide fapi2 return codes with desired data to
+ * support testing from expErrlTest
+ */
+#ifndef _RC_EXPLOG_H_
+#define _RC_EXPLOG_H_
+
+#include <fapi2.H>
+
+
+/**
+ * @brief Creates a test RC with added Explorer log trace data
+ * @param i_ocmb_target - Explorer target
+ * @param i_active_log_size - maximum size of active (RAM) data to add
+ * @param i_saved_log_size - maximum size of saved (SPI flash) data to add
+ * @return ReturnCode with added error log data
+ */
+fapi2::ReturnCode exp_error_rc(
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_target,
+ const uint32_t i_active_log_size,
+ const uint32_t i_saved_log_size );
+
+#endif
diff --git a/src/usr/expaccess/test/test.mk b/src/usr/expaccess/test/test.mk
index 059efe27d..9dd8237df 100644
--- a/src/usr/expaccess/test/test.mk
+++ b/src/usr/expaccess/test/test.mk
@@ -22,14 +22,23 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
-EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2
-EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include
-EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs
-EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc
-EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2/
+EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
-EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include
-EXTRAINCDIR += ${ROOTPATH}/src/import
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/
+EXTRAINCDIR += ${ROOTPATH}/src/import/
+EXTRAINCDIR += ${ROOTPATH}/src/usr/expaccess/
+EXTRAINCDIR += ${ROOTPATH}/src/usr/expaccess/test/
+VPATH += ${ROOTPATH}/src/usr/expaccess/test/
+VPATH += ${ROOTPATH}/src/usr/expaccess/
+VPATH += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc/
+
+OBJS += exptest_utils.o
+OBJS += exp_collect_explorer_log.o
+OBJS += rcExpLog.o
include ${ROOTPATH}/config.mk
diff --git a/src/usr/fapi2/attribute_service.C b/src/usr/fapi2/attribute_service.C
index 0c7442fd9..4b994fe65 100644
--- a/src/usr/fapi2/attribute_service.C
+++ b/src/usr/fapi2/attribute_service.C
@@ -48,12 +48,14 @@
#include <target.H>
#include <target_types.H>
#include <hwpf_fapi2_reasoncodes.H>
+#include <chipids.H>
#include <devicefw/driverif.H>
#include <plat_attr_override_sync.H>
#include <vpd/spdenums.H>
#include <p9_pm_get_poundv_bucket_attr.H>
#include <p9_pm_get_poundw_bucket_attr.H>
+#include <p9_frequency_buckets.H>
#include <errl/errlmanager.H>
#include <targeting/common/targetservice.H>
@@ -178,11 +180,11 @@ errlHndl_t getTargetingTarget(const Target<TARGET_TYPE_ALL>& i_pFapiTarget,
return l_errl;
}
-bool getTargetingAttrHelper(TARGETING::Target * l_pTargTarget,
+bool getTargetingAttrHelper(TARGETING::Target * i_pTargTarget,
const TARGETING::ATTRIBUTE_ID i_targAttrId,
const uint32_t i_attrSize, void * o_pAttr)
{
- return l_pTargTarget->_tryGetAttr(i_targAttrId, i_attrSize, o_pAttr);
+ return i_pTargTarget->_tryGetAttr(i_targAttrId, i_attrSize, o_pAttr);
}
///
@@ -365,9 +367,52 @@ ReturnCode platGetTargetName(const Target<TARGET_TYPE_ALL>& i_pFapiTarget,
{
o_name = ENUM_ATTR_NAME_AXONE;
}
- else if (l_model == TARGETING::MODEL_EXPLORER)
+ else if (l_model == TARGETING::MODEL_OCMB)
{
- o_name = ENUM_ATTR_NAME_EXPLORER;
+ // For MODEL_OCMB the ATTR_CHIP_ID determines if it is a
+ // Gemini or an Explorer chip
+ uint32_t l_chipID =
+ l_pHbTarget->getAttr<TARGETING::ATTR_CHIP_ID>();
+
+ if (l_chipID == POWER_CHIPID::EXPLORER_16)
+ {
+ o_name = ENUM_ATTR_NAME_EXPLORER;
+ }
+ else if (l_chipID == POWER_CHIPID::GEMINI_16)
+ {
+ o_name = ENUM_ATTR_NAME_GEMINI;
+ }
+ else
+ {
+ FAPI_ERR("platGetTargetName. Unknown CHIP_ID 0x%x for MODEL_OCMB 0x%x", l_chipID, l_model);
+
+ /*@
+ * @errortype
+ * @moduleid fapi2::MOD_FAPI2_GET_TARGETING_TARGET
+ * @reasoncode RC_UNKNOWN_OCMB_CHIP_TYPE
+ * @userdata1[0:31] FAPI2 Type
+ * @userdata1[32:63] HB Target HUID
+ * @userdata2[0:31] HB Type
+ * @userdata2[32:63] HB Target CHIP_ID
+ * @devdesc HB OCMB_CHIP target found with unknown
+ * model based on ATTR_CHIP_ID
+ * @custdesc Firmware Error
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_FAPI2_GET_TARGETING_TARGET,
+ RC_UNKNOWN_OCMB_CHIP_TYPE,
+ TWO_UINT32_TO_UINT64(
+ i_pFapiTarget.getType(),
+ TARGETING::get_huid(l_pHbTarget)
+ ),
+ TWO_UINT32_TO_UINT64(
+ l_pHbTarget->
+ getAttr<TARGETING::ATTR_TYPE>(),
+ l_chipID));
+
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break;
+ }
}
else
{
@@ -466,6 +511,40 @@ ReturnCode platGetTargetPos(const Target<TARGET_TYPE_ALL>& i_pFapiTarget,
}
//******************************************************************************
+// fapi::platAttrSvc::platErrorOnSet function
+//******************************************************************************
+ReturnCode platErrorOnSet( TARGETING::Target * i_pTargTarget,
+ const fapi2::AttributeId i_fapiAttrId )
+{
+ // Just create an error to return back
+ FAPI_ERR("platErrorOnSet: Set not valid for Attribute %X on Target %.8X",
+ i_fapiAttrId, TARGETING::get_huid(i_pTargTarget) );
+ /*@
+ * @errortype
+ * @moduleid fapi2::MOD_FAPI2_PLAT_ERROR_ON_SET
+ * @reasoncode fapi2::RC_SET_ATTR_NOT_VALID
+ * @userdata1 Target HUID
+ * @userdata2 FAPI Attribute Id
+ * @devdesc platErrorOnSet> Set operation not valid
+ * @custdesc Firmware error
+ */
+ errlHndl_t l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi2::MOD_FAPI2_PLAT_ERROR_ON_SET,
+ fapi2::RC_SET_ATTR_NOT_VALID,
+ TARGETING::get_huid(i_pTargTarget),
+ i_fapiAttrId,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_errl->collectTrace(FAPI_TRACE_NAME);
+ l_errl->collectTrace(FAPI_IMP_TRACE_NAME);
+
+ // attach our log to the fapi RC and return it
+ ReturnCode l_rc;
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ return l_rc;
+}
+
+//******************************************************************************
// fapi::platAttrSvc::platGetFusedCoreMode function
//******************************************************************************
ReturnCode platGetFusedCoreMode(uint8_t & o_isFused)
@@ -2001,6 +2080,7 @@ ReturnCode platGetDQAttrISDIMM(
}
else
{
+ mutex_lock(&l_C4DQmutex);
auto l_huid = TARGETING::get_huid(l_pTarget);
auto l_iterator = std::find ( l_cachedC4DQValues.begin(),
l_cachedC4DQValues.end(),
@@ -2013,14 +2093,13 @@ ReturnCode platGetDQAttrISDIMM(
l_kvPair.huid = l_huid;
rc = getDQAttrISDIMM(l_fapiTarget, l_kvPair.value);
memcpy(o_vpdIsDimmTOC4DQVal, l_kvPair.value, sizeof(ATTR_CEN_VPD_ISDIMMTOC4DQ_Type));
- mutex_lock(&l_C4DQmutex);
l_cachedC4DQValues.push_back(l_kvPair);
- mutex_unlock(&l_C4DQmutex);
}
else
{
memcpy(o_vpdIsDimmTOC4DQVal, (*l_iterator).value, sizeof(ATTR_CEN_VPD_ISDIMMTOC4DQ_Type));
}
+ mutex_unlock(&l_C4DQmutex);
}
return rc;
@@ -2052,6 +2131,7 @@ ReturnCode platGetDQSAttrISDIMM(
}
else
{
+ mutex_lock(&l_C4DQSmutex);
auto l_huid = TARGETING::get_huid(l_pTarget);
auto l_iterator = std::find ( l_cachedC4DQSValues.begin(),
l_cachedC4DQSValues.end(),
@@ -2065,14 +2145,13 @@ ReturnCode platGetDQSAttrISDIMM(
l_kvPair.huid = l_huid;
rc = getDQSAttrISDIMM(l_fapiTarget, l_kvPair.value);
memcpy(o_vpdIsDimmTOC4DQSVal, l_kvPair.value, sizeof(ATTR_CEN_VPD_ISDIMMTOC4DQS_Type));
- mutex_lock(&l_C4DQSmutex);
l_cachedC4DQSValues.push_back(l_kvPair);
- mutex_unlock(&l_C4DQSmutex);
}
else
{
memcpy(o_vpdIsDimmTOC4DQSVal, (*l_iterator).value, sizeof(ATTR_CEN_VPD_ISDIMMTOC4DQS_Type));
}
+ mutex_unlock(&l_C4DQSmutex);
}
return rc;
@@ -2652,11 +2731,12 @@ ReturnCode platGetMBvpdSlopeInterceptData(
return rc;
}
+#ifndef CONFIG_AXONE
//******************************************************************************
// fapi::platAttrSvc::platGetFreqMcaMhz function
//******************************************************************************
ReturnCode platGetFreqMcaMhz(const Target<TARGET_TYPE_ALL>& i_fapiTarget,
- uint32_t & o_val)
+ ATTR_FREQ_MCA_MHZ_Type & o_val)
{
// The POR config for Cumulus is to run the MC/DMI clocks directly
// off of the NEST PLL in 'sync' mode. To support 'sync' mode FW
@@ -2679,7 +2759,350 @@ ReturnCode platGetFreqMcaMhz(const Target<TARGET_TYPE_ALL>& i_fapiTarget,
return l_rc;
}
+#else
+
+/// @brief This function is called by the FAPI_ATTR_GET functions that lookup
+/// values in the MEM_PLL_FREQ_BUCKETS tree. The key's used to lookup values in that
+/// tree are the ATTR_FREQ_OMI_MHZ and ATTR_OMI_PLL_VCO attributes. These are on the
+/// processor target but it is expected that all of the values match.
+/// @param[out] o_omiFreq OMI Frequency of the system
+/// @param[out] o_omiVco OMI VCO of the system
+/// @return ReturnCode Zero on success, else platform specified error.
+errlHndl_t getOmiFreqAndVco(TARGETING::ATTR_FREQ_OMI_MHZ_type & o_omiFreq,
+ TARGETING::ATTR_OMI_PLL_VCO_type & o_omiVco)
+{
+ errlHndl_t l_errl = nullptr;
+
+ // Get all functional Proc targets
+ TARGETING::TargetHandleList l_procsList;
+ getAllChips(l_procsList, TARGETING::TYPE_PROC);
+ uint8_t l_firstValidProc = 0;
+ bool l_outValueSet = false;
+
+ // Until we are told we need to support individual processor frequency
+ // assert that all of the processors have the same values
+ for(uint8_t i = 0; i < l_procsList.size(); i++)
+ {
+ // Get a list of functional OCMB targets under this processor
+ TARGETING::TargetHandleList l_childOcmbList;
+ TARGETING::getChildAffinityTargets(l_childOcmbList, l_procsList[i],
+ TARGETING::CLASS_CHIP,
+ TARGETING::TYPE_OCMB_CHIP);
+ // If there are no OCMB children for this processor then ignore it;
+ if(l_childOcmbList.size() == 0)
+ {
+ continue;
+ }
+
+ // First valid processor's values will be used to compare against all other processors
+ if(!l_outValueSet)
+ {
+ o_omiFreq = l_procsList[i]->getAttr<TARGETING::ATTR_FREQ_OMI_MHZ>();
+ o_omiVco = l_procsList[i]->getAttr<TARGETING::ATTR_OMI_PLL_VCO>();
+ l_outValueSet = true;
+ l_firstValidProc = i;
+ continue;
+ }
+
+ TARGETING::ATTR_FREQ_OMI_MHZ_type l_omiFreqToCmp = l_procsList[i]->getAttr<TARGETING::ATTR_FREQ_OMI_MHZ>();
+ TARGETING::ATTR_OMI_PLL_VCO_type l_omiVcoToCmp = l_procsList[i]->getAttr<TARGETING::ATTR_OMI_PLL_VCO>();
+
+ // If this processors OMI freq is 0 then we have not determined this proc's OMI freq yet so we can ignore it.
+ // Otherwise, if we found that this processor's OMI freq / vco values do not match the first processor's values then
+ // return an error
+ if ((l_omiFreqToCmp != 0) &&
+ (l_omiFreqToCmp != o_omiFreq ||
+ l_omiVcoToCmp != o_omiVco ))
+ {
+ FAPI_ERR("platGetMcPllBucket: Detected two processors with difference OMI VCO / FREQ combinations."
+ " Proc 0x%.08X has OMI freq = %d and OMI vco = %d. "
+ " Proc 0x%.08X has OMI freq = %d and OMI vco = %d. " ,
+ get_huid(l_procsList[l_firstValidProc]), o_omiFreq, o_omiVco,
+ get_huid(l_procsList[i]), l_omiFreqToCmp, l_omiVcoToCmp );
+ /*@
+ * @errortype
+ * @moduleid fapi2::MOD_GET_OMI_FREQ_AND_VCO
+ * @reasoncode fapi2::RC_PROC_FREQ_MISMATCH
+ * @userdata1[0:31] first ATTR_FREQ_OMI_MHZ found
+ * @userdata1[32:63] first ATTR_FREQ_PLL_VCO found
+ * @userdata2[0:31] ATTR_FREQ_OMI_MHZ mismatch found
+ * @userdata2[32:63] ATTR_FREQ_PLL_VCO mismatch found
+ * @devdesc Found mismatching processor attribute settings
+ * when we expect them to all be in sync
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi2::MOD_GET_OMI_FREQ_AND_VCO,
+ fapi2::RC_NO_MATCHING_FREQ,
+ TWO_UINT32_TO_UINT64(o_omiFreq, o_omiVco),
+ TWO_UINT32_TO_UINT64(l_omiFreqToCmp, l_omiVcoToCmp),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT);
+ l_errl->collectTrace(FAPI_IMP_TRACE_NAME, 256);
+ break;
+ }
+ }
+
+ return l_errl;
+}
+
+// OMI bucket descriptor
+struct OmiFreqVcoBucketSelect_t
+{
+ uint32_t omifreq; // OMI Frequency in MHz
+ uint32_t vco; // VCO selector
+ uint8_t pll_bucket; // MCA Frequency in MHz
+};
+
+
+//******************************************************************************
+// fapi::platAttrSvc::platGetMcPllBucket function
+//******************************************************************************
+ReturnCode platGetMcPllBucket(const Target<TARGET_TYPE_ALL>& i_fapiTarget,
+ ATTR_MC_PLL_BUCKET_Type & o_val)
+{
+ fapi2::ReturnCode l_rc;
+ errlHndl_t l_errl = nullptr;
+ TARGETING::Target * l_sysTarget = nullptr;
+ TARGETING::ATTR_FREQ_OMI_MHZ_type l_omiFreq = 0;
+ TARGETING::ATTR_OMI_PLL_VCO_type l_omiVco = 0;
+ bool l_matchFound = false;
+
+ // There can be up to 2 matches for OMI frequencies. If only 1 match is found
+ // then we ignore the VCO attribute
+ std::vector<OmiFreqVcoBucketSelect_t> l_omiFreqMatches;
+
+ do{
+ // Convert to platform-style target
+ l_errl = getTargetingTarget(i_fapiTarget, l_sysTarget);
+
+ if(l_errl)
+ {
+ FAPI_ERR("platGetMcPllBucket: Error from getTargetingTarget");
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break;
+ }
+
+ // Use helper function to lookup omi frequency and omi vco for this system
+ l_errl = getOmiFreqAndVco(l_omiFreq, l_omiVco);
+
+ if(l_errl)
+ {
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break;
+ }
+
+ // Loop through the MEM_PLL frequency buckets to see if we can find a bucket that
+ // matches what we have found for omi freq and vco
+ for(uint8_t i = 0; i < MEM_PLL_FREQ_BUCKETS; i++)
+ {
+ if(OMI_PLL_FREQ_LIST[i].omifreq == l_omiFreq)
+ {
+ OmiFreqVcoBucketSelect_t l_tmpBucketSelect = {OMI_PLL_FREQ_LIST[i].omifreq, OMI_PLL_FREQ_LIST[i].vco, i};
+ l_omiFreqMatches.push_back(l_tmpBucketSelect);
+ }
+ }
+
+ if(l_omiFreqMatches.size() > 1)
+ {
+ for(uint8_t i = 0; i < l_omiFreqMatches.size(); i++)
+ {
+ if(l_omiFreqMatches[i].vco == l_omiVco)
+ {
+ FAPI_INF("Found match to be bucket %d for freq %d, vco %d",
+ l_omiFreqMatches[i].pll_bucket,
+ OMI_PLL_FREQ_LIST[i].omifreq,
+ OMI_PLL_FREQ_LIST[i].vco);
+ l_matchFound = true;
+ // Value returned in this case is the bucket number that had the matching values
+ // MC_PLL_BUCKET attribute is 1-based so increment bucket ID by 1
+ o_val = l_omiFreqMatches[i].pll_bucket + 1;
+ break;
+ }
+ }
+ }
+ else if (l_omiFreqMatches.size() == 1)
+ {
+ FAPI_INF("Single match for OMI freq %d found in OMI_PLL_FREQ_LIST, ignoring VCO attribute. PLL Bucket = %d",
+ l_omiFreq,
+ l_omiFreqMatches[0].pll_bucket);
+ l_matchFound = true;
+ // MC_PLL_BUCKET attribute is 1-based so increment bucket ID by 1
+ o_val = l_omiFreqMatches[0].pll_bucket + 1;
+ }
+
+ // If not match is found return an error
+ if(!l_matchFound)
+ {
+ FAPI_ERR("platGetMcPllBucket: Could not find matching bucket for omiFreq = %d and vco = %d",
+ l_omiFreq, l_omiVco);
+
+ /*@
+ * @errortype
+ * @moduleid fapi2::MOD_FAPI2_PLAT_GET_MC_PLL_BUCKET
+ * @reasoncode fapi2::RC_NO_MATCHING_FREQ
+ * @userdata1[0:31] ATTR_FREQ_OMI_MHZ
+ * @userdata1[32:63] ATTR_FREQ_PLL_VCO
+ * @userdata2 Target HUID
+ * @devdesc Invalid omi frequence and omi vco settings
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi2::MOD_FAPI2_PLAT_GET_MC_PLL_BUCKET,
+ fapi2::RC_NO_MATCHING_FREQ,
+ TWO_UINT32_TO_UINT64(l_omiFreq, l_omiVco),
+ TARGETING::get_huid(l_sysTarget),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT);
+ l_errl->collectTrace(FAPI_IMP_TRACE_NAME, 256);
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break;
+ }
+
+ }while(0);
+ return l_rc;
+}
+
+//******************************************************************************
+// fapi::platAttrSvc::platGetFreqMcaMhz function
+//******************************************************************************
+ReturnCode platGetFreqMcaMhz(const Target<TARGET_TYPE_ALL>& i_fapiTarget,
+ ATTR_FREQ_MCA_MHZ_Type & o_val)
+{
+ fapi2::ReturnCode l_rc;
+ errlHndl_t l_errl = nullptr;
+ TARGETING::Target * l_sysTarget = nullptr;
+ TARGETING::ATTR_FREQ_OMI_MHZ_type l_omiFreq = 0;
+ TARGETING::ATTR_OMI_PLL_VCO_type l_omiVco = 0;
+ bool l_matchFound = false;
+
+ // There can be up to 2 matches for OMI frequencies. If only 1 match is found
+ // then we ignore the VCO attribute
+ std::vector<OmiBucketDescriptor_t> l_matchingOmiBucketDescriptors;
+
+ do{
+ // Convert to platform-style target
+ l_errl = getTargetingTarget(i_fapiTarget, l_sysTarget);
+
+ if(l_errl)
+ {
+ FAPI_ERR("platGetFreqMcaMhz: Error from getTargetingTarget");
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break;
+ }
+
+ // Use helper function to lookup omi frequency and omi vco for this system
+ l_errl = getOmiFreqAndVco(l_omiFreq, l_omiVco);
+
+ if(l_errl)
+ {
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break;
+ }
+
+ // Loop through the MEM_PLL frequency buckets to see if we can find a bucket that
+ // matches what we have found for omi freq and vco
+ for(uint8_t i = 0; i < MEM_PLL_FREQ_BUCKETS; i++)
+ {
+ if(OMI_PLL_FREQ_LIST[i].omifreq == l_omiFreq)
+ {
+ l_matchingOmiBucketDescriptors.push_back(OMI_PLL_FREQ_LIST[i]);
+ }
+ }
+
+ if(l_matchingOmiBucketDescriptors.size() > 1)
+ {
+ for(uint8_t i = 0; i < l_matchingOmiBucketDescriptors.size(); i++)
+ {
+ if(l_matchingOmiBucketDescriptors[i].vco == l_omiVco)
+ {
+ FAPI_INF("found match for freq %d, vco %d. Mca freq = %d",
+ OMI_PLL_FREQ_LIST[i].omifreq, OMI_PLL_FREQ_LIST[i].vco);
+ l_matchFound = true;
+ // Value returned in this case is the bucket number that had the matching values
+ o_val = l_matchingOmiBucketDescriptors[i].mcafreq;
+ break;
+ }
+ }
+ }
+ else if (l_matchingOmiBucketDescriptors.size() == 1)
+ {
+ FAPI_INF("Single match for OMI freq %d found in OMI_PLL_FREQ_LIST, MCA freq found = %d, ignoring VCO attribute",
+ l_omiFreq,
+ l_matchingOmiBucketDescriptors[0].mcafreq);
+ l_matchFound = true;
+ o_val = l_matchingOmiBucketDescriptors[0].mcafreq;
+ }
+
+ if(!l_matchFound)
+ {
+ FAPI_ERR("platGetFreqMcaMhz: Could not find matching bucket for omiFreq = %d and vco = %d",
+ l_omiFreq, l_omiVco);
+
+ /*@
+ * @errortype
+ * @moduleid fapi2::MOD_FAPI2_PLAT_GET_FREQ_MCA_MHZ
+ * @reasoncode fapi2::RC_NO_MATCHING_FREQ
+ * @userdata1[0:31] ATTR_FREQ_OMI_MHZ
+ * @userdata1[32:63] ATTR_FREQ_PLL_VCO
+ * @userdata2 Target HUID
+ * @devdesc Invalid omi frequence and omi vco settings
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi2::MOD_FAPI2_PLAT_GET_FREQ_MCA_MHZ,
+ fapi2::RC_NO_MATCHING_FREQ,
+ TWO_UINT32_TO_UINT64(l_omiFreq, l_omiVco),
+ TARGETING::get_huid(l_sysTarget),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT);
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break;
+ }
+
+ }while(0);
+ return l_rc;
+}
+
+
+
+#endif
+
+//******************************************************************************
+// fapi::platAttrSvc::platIncrementCounter function
+//******************************************************************************
+ReturnCode platIncrementOcmbCounter(const Target<TARGET_TYPE_ALL>& i_fapiTarget,
+ uint32_t & o_val)
+{
+ fapi2::ReturnCode rc;
+ errlHndl_t l_errl = nullptr;
+
+ TARGETING::Target * l_chipTarget = nullptr;
+ static mutex_t l_counter_mutex = MUTEX_INITIALIZER;
+ l_errl = getTargetingTarget(i_fapiTarget, l_chipTarget);
+ if (l_errl)
+ {
+ FAPI_ERR("platIncrementOcmbCounter: Error from getTargetingTarget");
+ rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ }
+ else
+ {
+ mutex_lock(&l_counter_mutex);
+ o_val = l_chipTarget->getAttr<TARGETING::ATTR_OCMB_COUNTER_HB>();
+ if( o_val == 0 )
+ {
+ // seed each target with a unique number to make messages more
+ // distinct across operations
+ o_val = (l_chipTarget->getAttr<TARGETING::ATTR_HUID>()
+ && 0x0000FFFF) << 16;
+ }
+ else
+ {
+ ++o_val;
+ }
+ l_chipTarget->setAttr<TARGETING::ATTR_OCMB_COUNTER_HB>(o_val);
+ mutex_unlock(&l_counter_mutex);
+ }
+ return rc;
+}
} // End platAttrSvc namespace
} // End fapi2 namespace
diff --git a/src/usr/fapi2/dimmBadDqBitmapFuncs.C b/src/usr/fapi2/dimmBadDqBitmapFuncs.C
index 8fb4b9fe0..170c022c5 100644
--- a/src/usr/fapi2/dimmBadDqBitmapFuncs.C
+++ b/src/usr/fapi2/dimmBadDqBitmapFuncs.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,8 +38,8 @@ extern "C"
// Utility function to check parameters and get the Bad DQ bitmap
//------------------------------------------------------------------------------
fapi2::ReturnCode dimmBadDqCheckParamGetBitmap( const fapi2::Target
- <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|fapi2::TARGET_TYPE_MEM_PORT>
- & i_fapiTrgt,
+ <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|
+ fapi2::TARGET_TYPE_MEM_PORT|fapi2::TARGET_TYPE_OCMB_CHIP> & i_fapiTrgt,
const uint8_t i_port,
const uint8_t i_dimm,
const uint8_t i_rank,
@@ -115,8 +115,8 @@ fapi2::ReturnCode dimmBadDqCheckParamGetBitmap( const fapi2::Target
//------------------------------------------------------------------------------
fapi2::ReturnCode p9DimmGetBadDqBitmap( const fapi2::Target
- <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|fapi2::TARGET_TYPE_MEM_PORT>
- & i_fapiTrgt,
+ <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|
+ fapi2::TARGET_TYPE_MEM_PORT|fapi2::TARGET_TYPE_OCMB_CHIP> & i_fapiTrgt,
const uint8_t i_dimm,
const uint8_t i_rank,
uint8_t (&o_data)[mss::BAD_DQ_BYTE_COUNT],
@@ -151,8 +151,8 @@ fapi2::ReturnCode p9DimmGetBadDqBitmap( const fapi2::Target
//------------------------------------------------------------------------------
fapi2::ReturnCode p9DimmSetBadDqBitmap( const fapi2::Target
- <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|fapi2::TARGET_TYPE_MEM_PORT>
- & i_fapiTrgt,
+ <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|
+ fapi2::TARGET_TYPE_MEM_PORT|fapi2::TARGET_TYPE_OCMB_CHIP> & i_fapiTrgt,
const uint8_t i_dimm,
const uint8_t i_rank,
const uint8_t (&i_data)[mss::BAD_DQ_BYTE_COUNT],
@@ -179,17 +179,8 @@ fapi2::ReturnCode p9DimmSetBadDqBitmap( const fapi2::Target
// Add the rank bitmap to the DIMM bitmap and write the bitmap.
memcpy( l_dqBitmap[i_rank], i_data, mss::BAD_DQ_BYTE_COUNT );
- errlHndl_t l_errl = nullptr;
- TARGETING::TargetHandle_t l_trgt = nullptr;
- l_errl = fapi2::platAttrSvc::getTargetingTarget(i_fapiTrgt, l_trgt);
- if ( l_errl )
- {
- FAPI_ERR( "p9DimmSetBadDqBitmap: Error from getTargetingTarget" );
- break;
- }
-
l_rc = FAPI_ATTR_SET( fapi2::ATTR_BAD_DQ_BITMAP, l_dimmTrgt,
- l_dqBitmap );
+ l_dqBitmap );
if ( l_rc )
{
diff --git a/src/usr/fapi2/fapi2.mk b/src/usr/fapi2/fapi2.mk
index c69d77c92..713e3e80b 100755
--- a/src/usr/fapi2/fapi2.mk
+++ b/src/usr/fapi2/fapi2.mk
@@ -59,6 +59,10 @@ EXTRAINCDIR += ${HWP_PATH_2}/hwp/memory/lib/shared/
EXTRAINCDIR += ${HWP_PATH_2}/hwp/memory/lib/utils/
EXTRAINCDIR += ${HWP_PATH_2}/vpd_accessors/
EXTRAINCDIR += ${ROOTPATH}/src/usr/scom/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/include/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
include ${ROOTPATH}/src/build/mkrules/verbose.rules.mk
define __CLEAN_TARGET
@@ -128,6 +132,10 @@ FAPI2_ERROR_XML += $(wildcard \
$(ROOTPATH)/src/import/chips/ocmb/explorer/procedures/xml/error_info/*.xml)
FAPI2_ERROR_XML += $(wildcard \
$(ROOTPATH)/src/import/chips/p9a/procedures/xml/error_info/*.xml)
+FAPI2_ERROR_XML += $(wildcard \
+ $(ROOTPATH)/src/import/chips/ocmb/gemini/procedures/xml/error_info/*.xml)
+FAPI2_ERROR_XML += $(wildcard \
+ $(ROOTPATH)/src/import/chips/ocmb/common/procedures/xml/error_info/*.xml)
# Attribute XML files.
FAPI2_ATTR_XML += $(wildcard \
@@ -140,6 +148,10 @@ FAPI2_ATTR_XML += $(wildcard \
$(ROOTPATH)/src/import/generic/procedures/xml/attribute_info/*.xml)
FAPI2_ATTR_XML += $(wildcard \
$(ROOTPATH)/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/*.xml)
+FAPI2_ATTR_XML += $(wildcard \
+ $(ROOTPATH)/src/import/chips/ocmb/gemini/procedures/xml/attribute_info/*.xml)
+FAPI2_ATTR_XML += $(wildcard \
+ $(ROOTPATH)/src/import/chips/ocmb/common/procedures/xml/attribute_info/*.xml)
# Filter out Temp defaults XML file from Attribute XML files.
# NOTE: The hb_temp_defaults.xml file is not a normal attribute file with the
diff --git a/src/usr/fapi2/platCreateHwpErrParser.pl b/src/usr/fapi2/platCreateHwpErrParser.pl
index 618459e30..84fc84316 100755
--- a/src/usr/fapi2/platCreateHwpErrParser.pl
+++ b/src/usr/fapi2/platCreateHwpErrParser.pl
@@ -6,9 +6,10 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2015,2018
+# Contributors Listed Below - COPYRIGHT 2015,2019
# [+] Google Inc.
# [+] International Business Machines Corp.
+# [+] YADRO
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -78,13 +79,14 @@ print TGFILE "// This file is generated by perl script platCreateHwpErrParser.pl
print TGFILE "#ifndef HBFWPLATHWPERRPARSER_H_\n";
print TGFILE "#define HBFWPLATHWPERRPARSER_H_\n\n";
print TGFILE "#if defined(PARSER) || defined(LOGPARSER)\n\n";
+print TGFILE "#include \"errluserdetails.H\"\n\n";
print TGFILE "namespace fapi2\n";
print TGFILE "{\n\n";
print TGFILE "void hbfwParseHwpRc(ErrlUsrParser & i_parser,\n";
print TGFILE " void * i_pBuffer,\n";
print TGFILE " const uint32_t i_buflen)\n";
print TGFILE "{\n";
-print TGFILE " uint32_t l_rc = ntohl(*(static_cast<uint32_t *>(i_pBuffer)));\n";
+print TGFILE " uint32_t l_rc = ntohl(ERRORLOG::UINT32_FROM_PTR(i_pBuffer));\n";
print TGFILE " switch(l_rc)\n";
print TGFILE " {\n";
@@ -225,6 +227,7 @@ print EDISFILE "#include <p9_perv_scom_addresses.H>\n";
print EDISFILE "#include <p9_quad_scom_addresses.H>\n";
print EDISFILE "#include <p9_xbus_scom_addresses.H>\n";
print EDISFILE "#include <cen_gen_scom_addresses.H>\n";
+print EDISFILE "#include <explorer_scom_addresses.H>\n";
print EDISFILE "#include <centaur_misc_constants.H>\n";
print EDISFILE "namespace fapi2\n";
print EDISFILE "{\n\n";
@@ -243,7 +246,7 @@ print TGFILE " uint8_t * l_pBuffer = static_cast<uint8_t *>(i_pBuffer);\n";
print TGFILE " uint32_t l_buflen = i_buflen;\n\n";
print TGFILE " // The first uint32_t is the FFDC ID\n";
print TGFILE " uint32_t * l_pFfdcId = static_cast<uint32_t *>(i_pBuffer);\n";
-print TGFILE " uint32_t l_ffdcId = ntohl(*l_pFfdcId);\n";
+print TGFILE " uint32_t l_ffdcId = ntohl(ERRORLOG::UINT32_FROM_PTR(l_pFfdcId));\n";
print TGFILE " l_pBuffer += sizeof(l_ffdcId);\n";
print TGFILE " l_buflen -= sizeof(l_ffdcId);\n";
print TGFILE " switch(l_ffdcId)\n";
@@ -364,7 +367,7 @@ foreach my $argnum (1 .. $#ARGV)
print TGFILE " if (l_buflen >= POS_LEN)\n";
print TGFILE " {\n";
print TGFILE " uint32_t * l_pBufferTemp = reinterpret_cast<uint32_t *>(l_pBuffer);\n";
- print TGFILE " i_parser.PrintNumber(\"Chip Position:\",\"%X\",ntohl(*l_pBufferTemp));\n";
+ print TGFILE " i_parser.PrintNumber(\"Chip Position:\",\"%X\",ntohl(ERRORLOG::UINT32_FROM_PTR(l_pBufferTemp)));\n";
print TGFILE " l_pBufferTemp = NULL;\n";
print TGFILE " l_pBuffer+= POS_LEN;\n";
print TGFILE " l_buflen -= POS_LEN;\n";
diff --git a/src/usr/fapi2/plat_mmio_access.C b/src/usr/fapi2/plat_mmio_access.C
index 60526761b..365aa1f22 100644
--- a/src/usr/fapi2/plat_mmio_access.C
+++ b/src/usr/fapi2/plat_mmio_access.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,9 +39,272 @@
#include <hwpf_fapi2_reasoncodes.H>
#include <fapi2/plat_mmio_access.H>
-
namespace fapi2
{
+// Address bit that designates it as an Explorer MMIO address
+static const uint64_t EXPLR_IB_MMIO_OFFSET = 0x0000000100000000ull;
+
+// Valid I2C access to 256MB SRAM space, starts at offset 0x01000000
+static const uint64_t MIN_I2C_SRAM_SPACE_ADDRESS = 0x0000000001000000ull;
+static const uint64_t MAX_I2C_SRAM_SPACE_ADDRESS = 0x0000000001030000ull;
+
+// byte transaction sizes for i2c
+static const size_t I2C_TRANSACTION_SIZE = 4; // actual size sent
+static const size_t SCOM_I2C_TRANSACTION_SIZE = 8;
+
+// Convert MMIO to I2C address (need these bits set)
+static const uint64_t EXPLR_MMIO_TO_I2C_ADDRESS_MASK = 0xA0000000;
+
+
+/**
+ * @brief Explorer Inband read via i2c
+ * @param[in] i_target - OCMB target
+ * @param[in/out] io_data_read - buffer to be filled with read data
+ * @param[in/out] io_get_size - size of buffer (returns read size)
+ * @param[in] i_i2c_addr - i2c scom address
+ * @return errlHndl_t indicating success or failure
+ */
+errlHndl_t explrIbI2cRead(TARGETING::Target * i_target,
+ uint8_t * io_data_read,
+ size_t io_get_size,
+ const uint64_t i_i2c_addr)
+{
+ errlHndl_t l_err = nullptr;
+
+ if ( io_get_size % I2C_TRANSACTION_SIZE )
+ {
+ // invalid size expected (needs to be a multiple of I2C_TRANSACTION_SIZE)
+ FAPI_ERR("explrIbI2cRead: read size %d is not a multiple of %d",
+ io_get_size, I2C_TRANSACTION_SIZE);
+ /*@
+ * @errortype
+ * @moduleid fapi2::MOD_FAPI2_EXPLR_IB_I2C_READ
+ * @reasoncode fapi2::RC_INVALID_BUFFER_SIZE
+ * @userdata1[0:31] Buffer size
+ * @userdata1[32:63] Transaction size
+ * @userdata2[0:31] HUID of input target
+ * @userdata2[32:63] i2c_address
+ * @devdesc Invalid read buffer size, needs to be divisible by transaction size
+ * @custdesc Internal firmware error
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi2::MOD_FAPI2_EXPLR_IB_I2C_READ,
+ fapi2::RC_INVALID_BUFFER_SIZE,
+ TWO_UINT32_TO_UINT64(io_get_size,
+ I2C_TRANSACTION_SIZE),
+ TWO_UINT32_TO_UINT64(
+ TARGETING::get_huid(i_target),
+ i_i2c_addr),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_err->collectTrace(FAPI_TRACE_NAME);
+ io_get_size = 0; // no data being read
+ }
+ else
+ {
+ FAPI_INF("explrIbI2cRead: deviceRead() starting at i2cscom address "
+ "0x%08X for %d bytes", i_i2c_addr, io_get_size);
+
+ // keep track of total bytes read
+ size_t total_bytes_read = 0;
+
+ // Increment this address after each read transaction
+ uint64_t i2cAddr = i_i2c_addr;
+
+ // scom transaction variables
+ size_t scomTransSize = SCOM_I2C_TRANSACTION_SIZE;
+ uint8_t scomReadData[SCOM_I2C_TRANSACTION_SIZE];
+
+ // Only able to read 4 bytes at a time with i2c, so
+ // need to break into multiple i2c read transactions
+ while( total_bytes_read < io_get_size )
+ {
+ FAPI_DBG("explrIbI2cRead: deviceRead() at i2cscom address 0x%08X", i2cAddr);
+ l_err = deviceOp( DeviceFW::READ,
+ i_target,
+ scomReadData,
+ scomTransSize,
+ DEVICE_I2CSCOM_ADDRESS(i2cAddr) );
+ if (l_err)
+ {
+ FAPI_ERR("explrIbI2cRead: target 0x%08X deviceRead() at address 0x%08X failed",
+ TARGETING::get_huid(i_target), i2cAddr);
+ l_err->collectTrace(FAPI_TRACE_NAME);
+ break;
+ }
+ else
+ {
+ FAPI_DBG("explrIbI2cRead: read %02X%02X%02X%02X",
+ scomReadData[4], scomReadData[5], scomReadData[6], scomReadData[7]);
+ }
+
+ // The MMIO hardware does this byteswap for us, since we are
+ // running this over i2c we must reorder the bytes here
+ io_data_read[total_bytes_read] = scomReadData[7];
+ io_data_read[total_bytes_read+1] = scomReadData[6];
+ io_data_read[total_bytes_read+2] = scomReadData[5];
+ io_data_read[total_bytes_read+3] = scomReadData[4];
+
+ // Only able to read 4 bytes at a time
+ total_bytes_read += I2C_TRANSACTION_SIZE;
+ i2cAddr += I2C_TRANSACTION_SIZE;
+
+ // make sure this value is correct for next op
+ scomTransSize = SCOM_I2C_TRANSACTION_SIZE;
+ }
+ }
+ return l_err;
+}
+
+
+/**
+ * @brief Explorer Inband write via i2c
+ * @param[in] i_target - OCMB target
+ * @param[in] i_write_data - data to write out
+ * @param[in/out] io_write_size - how much data to write (returns how much written)
+ * @param[in] i_i2c_addr - i2c scom address
+ * @return errlHndl_t indicating success or failure
+ */
+errlHndl_t explrIbI2cWrite(TARGETING::Target * i_target,
+ const uint8_t * i_write_data,
+ size_t io_write_size,
+ const uint64_t i_i2c_addr)
+{
+ errlHndl_t l_err = nullptr;
+
+ // Verify write can be divide up evenly
+ if ( io_write_size % I2C_TRANSACTION_SIZE )
+ {
+ // invalid size expected (needs to be a multiple of I2C_TRANSACTION_SIZE)
+ FAPI_ERR("explrIbI2cWrite: write size %d is not a multiple of %d",
+ io_write_size, I2C_TRANSACTION_SIZE);
+ /*@
+ * @errortype
+ * @moduleid fapi2::MOD_FAPI2_EXPLR_IB_I2C_WRITE
+ * @reasoncode fapi2::RC_INVALID_BUFFER_SIZE
+ * @userdata1[0:31] Buffer size
+ * @userdata1[32:63] Transaction size
+ * @userdata2[0:31] HUID of input target
+ * @userdata2[32:63] i2c_address
+ * @devdesc Invalid write buffer size, needs to be divisible by transaction size
+ * @custdesc Internal firmware error
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi2::MOD_FAPI2_EXPLR_IB_I2C_READ,
+ fapi2::RC_INVALID_BUFFER_SIZE,
+ TWO_UINT32_TO_UINT64(io_write_size,
+ I2C_TRANSACTION_SIZE),
+ TWO_UINT32_TO_UINT64(
+ TARGETING::get_huid(i_target),
+ i_i2c_addr),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_err->collectTrace(FAPI_TRACE_NAME);
+ }
+ else
+ {
+ // counter for bytes written out to SRAM space
+ size_t total_bytes_written = 0;
+
+ // going to alter this address to cycle through write data
+ uint64_t i2cAddr = i_i2c_addr;
+
+ // scom transaction variables
+ size_t scomTransSize = SCOM_I2C_TRANSACTION_SIZE;
+ uint8_t scomWriteData[SCOM_I2C_TRANSACTION_SIZE];
+
+ FAPI_INF("explrIbI2cWrite: deviceWrite() starting at i2cscom address "
+ "0x%08X for %d bytes", i_i2c_addr, io_write_size);
+
+ // Only able to write 4 bytes at a time with i2c,
+ // so need to break into multiple i2c write transactions
+ while( total_bytes_written < io_write_size )
+ {
+ memset(scomWriteData, 0x00, SCOM_I2C_TRANSACTION_SIZE);
+
+ // Only last four bytes are actually written out
+ // NOTE: MMIO hardware does this byteswap for us, but since we
+ // are running this over i2c we must reorder the bytes here
+ scomWriteData[7] = i_write_data[total_bytes_written];
+ scomWriteData[6] = i_write_data[total_bytes_written+1];
+ scomWriteData[5] = i_write_data[total_bytes_written+2];
+ scomWriteData[4] = i_write_data[total_bytes_written+3];
+
+ l_err = deviceOp( DeviceFW::WRITE,
+ i_target,
+ scomWriteData,
+ scomTransSize,
+ DEVICE_I2CSCOM_ADDRESS(i2cAddr) );
+ if (l_err)
+ {
+ FAPI_ERR("explrIbI2cWrite: i2cscom write(0x%02X%02X%02X%02X) at address 0x%08X failed",
+ scomWriteData[4], scomWriteData[5], scomWriteData[6], scomWriteData[7], i2cAddr);
+ l_err->collectTrace(FAPI_TRACE_NAME);
+ break;
+ }
+ // Really only doing 4-byte transactions
+ i2cAddr += I2C_TRANSACTION_SIZE;
+ total_bytes_written += I2C_TRANSACTION_SIZE;
+
+ // Update for next scom operation
+ scomTransSize = SCOM_I2C_TRANSACTION_SIZE;
+ }
+ }
+ return l_err;
+}
+
+/**
+ * @brief Checks if all the conditions are met to allow i2c
+ * operation instead of MMIO.
+ * @param[in] i_ocmb - OCMB target
+ * @param[in] i_mmioAddress - address passed into get/putMMIO
+ * @return true if i2c should be used instead of MMIO
+ */
+bool useI2cInsteadOfMmio( const TARGETING::Target * i_ocmb,
+ const uint64_t i_mmioAddress )
+{
+ bool useI2c = false; // default to use MMIO
+
+ uint8_t attrAllowedI2c = 0;
+
+ // Check force i2c attribute first
+ TARGETING::Target* l_sys = nullptr;
+ TARGETING::targetService().getTopLevelTarget(l_sys);
+ crit_assert(l_sys != nullptr);
+ attrAllowedI2c = l_sys->getAttr<TARGETING::ATTR_FORCE_SRAM_MMIO_OVER_I2C>();
+
+ // If not forced to use i2c, then check if that is the current scom setting
+ if (!attrAllowedI2c)
+ {
+ // The SCOM_SWITCHES attribute will keep track of when it is safe
+ // to access the ocmb via inband vs when we should do accesses over
+ // i2c. Use this attribute to decide which we want to use.
+ auto ocmb_info = i_ocmb->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
+ if (!ocmb_info.useInbandScom)
+ {
+ attrAllowedI2c = 1;
+ }
+ }
+
+ // Attribute settings must allow i2c operation before checking
+ // for a valid address range
+ if (attrAllowedI2c)
+ {
+ // Verify address is within valid SRAM range
+ if ( ((i_mmioAddress & 0x0F00000000) == EXPLR_IB_MMIO_OFFSET) &&
+ ((i_mmioAddress & 0x0FFFFFFFF) >= MIN_I2C_SRAM_SPACE_ADDRESS) &&
+ ((i_mmioAddress & 0x0FFFFFFFF) <= MAX_I2C_SRAM_SPACE_ADDRESS) )
+ {
+ useI2c = true;
+ }
+ else
+ {
+ FAPI_INF("0x%08X OCMB address 0x%.8X is outside of SRAM range so using mmio",
+ TARGETING::get_huid(i_ocmb), i_mmioAddress);
+ }
+ }
+
+ return useI2c;
+}
+
//------------------------------------------------------------------------------
// HW Communication Functions to be implemented at the platform layer.
//------------------------------------------------------------------------------
@@ -83,12 +346,22 @@ ReturnCode platGetMMIO( const Target<TARGET_TYPE_ALL>& i_target,
break; //return with error
}
- // call MMIO driver
- l_err = DeviceFW::deviceRead(l_target,
- l_data_read,
- l_get_size,
- DEVICE_MMIO_ADDRESS(i_mmioAddr, i_transSize));
-
+ // Run mmio if inband i2c isn't enabled or address is outside of SRAM range
+ if ( !useI2cInsteadOfMmio(l_target, i_mmioAddr) )
+ {
+ // call MMIO driver
+ l_err = DeviceFW::deviceRead(l_target,
+ l_data_read,
+ l_get_size,
+ DEVICE_MMIO_ADDRESS(i_mmioAddr, i_transSize));
+ }
+ else
+ {
+ // Use i2c instead of MMMIO
+ // Explorer i2c addresses are actually 32-bit and need 0xA at the beginning
+ uint64_t i2cAddr = (i_mmioAddr & 0x00000000FFFFFFFF) | EXPLR_MMIO_TO_I2C_ADDRESS_MASK;
+ l_err = explrIbI2cRead(l_target, l_data_read, l_get_size, i2cAddr);
+ }
if (l_traceit)
{
// Only trace the first 8 bytes of data read
@@ -167,11 +440,22 @@ ReturnCode platPutMMIO( const Target<TARGET_TYPE_ALL>& i_target,
std::copy(i_data.begin(), i_data.end(), l_writeDataPtr);
size_t l_dataSize = i_data.size();
- // call MMIO driver
- l_err = DeviceFW::deviceWrite(l_target,
- l_writeDataPtr,
- l_dataSize,
- DEVICE_MMIO_ADDRESS(i_mmioAddr, i_transSize));
+ // Run mmio if inband i2c isn't enabled or address is outside of SRAM range
+ if ( !useI2cInsteadOfMmio(l_target, i_mmioAddr) )
+ {
+ // call MMIO driver
+ l_err = DeviceFW::deviceWrite(l_target,
+ l_writeDataPtr,
+ l_dataSize,
+ DEVICE_MMIO_ADDRESS(i_mmioAddr, i_transSize));
+ }
+ else
+ {
+ // Address is an Explorer SRAM address, so I2C will work
+ // Explorer i2c addresses are actually 32-bit and need 0xA at the beginning
+ uint64_t i2cAddr = (i_mmioAddr & 0x00000000FFFFFFFF) | EXPLR_MMIO_TO_I2C_ADDRESS_MASK;
+ l_err = explrIbI2cWrite(l_target, l_writeDataPtr, l_dataSize, i2cAddr);
+ }
if (l_traceit)
{
// trace the first 8 bytes of written data
diff --git a/src/usr/fapi2/plat_spd_access.C b/src/usr/fapi2/plat_spd_access.C
index c8466f5da..6f3107f0c 100644
--- a/src/usr/fapi2/plat_spd_access.C
+++ b/src/usr/fapi2/plat_spd_access.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -34,6 +34,8 @@
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <fapi2_spd_access.H>
+#include <vpd/spdenums.H>
+#include <hwas/common/hwasCallout.H>
namespace fapi2
{
@@ -49,14 +51,9 @@ fapi2::ReturnCode getSPD(
{
FAPI_DBG(ENTER_MRK "getSPD");
- const uint8_t MEM_DDR3 = 0xB;
- const uint8_t MEM_DDR4 = 0xC;
- const uint32_t DDR3_KEYWORD_SIZE = 256;
- const uint32_t DDR4_KEYWORD_SIZE = 512;
-
- errlHndl_t l_errl = NULL;
+ errlHndl_t l_errl = nullptr;
fapi2::ReturnCode l_rc;
- TARGETING::Target* l_pTarget = NULL;
+ TARGETING::Target* l_pTarget = nullptr;
do
{
@@ -65,49 +62,104 @@ fapi2::ReturnCode getSPD(
TARGETING::TYPE_DIMM);
if (l_errl)
{
- FAPI_ERR("getSPD: Error from getTargetingTarget");
+ FAPI_ERR("getSPD: Error from getTargetingTarget for TYPE_DIMM");
break;
}
// If the caller passed a nullptr for blob then
// return size of the SPD
- if ( o_blob == NULL )
+ if ( o_blob == nullptr )
{
- // Get the DDR device type from SPD
- uint8_t l_memType = 0x0;
- size_t l_memSize = sizeof(l_memType);
+ // Get the DRAM generation from SPD
+ uint8_t l_memGen = 0x0;
+ size_t l_memSize = sizeof(l_memGen);
l_errl = deviceRead(l_pTarget,
- (void *)&l_memType,
- l_memSize,
- DEVICE_SPD_ADDRESS(SPD::BASIC_MEMORY_TYPE));
+ static_cast<void *>(&l_memGen),
+ l_memSize,
+ DEVICE_SPD_ADDRESS(SPD::BASIC_MEMORY_TYPE));
+
+ if ( l_errl )
+ {
+ FAPI_ERR("getSPD: Error from deviceRead for BASIC_MEMORY_TYPE")
+ break;
+ }
- if ( !l_errl )
+ switch(l_memGen)
{
- if ( l_memType == MEM_DDR3 )
+ case SPD::MEM_DDR3:
+ o_size = SPD::DDR3_SPD_SIZE;
+ break;
+
+ case SPD::MEM_DDR4:
{
- o_size = DDR3_KEYWORD_SIZE;
- }
- else if ( l_memType == MEM_DDR4 )
+ uint8_t l_memModule = 0x0;
+
+ l_errl = deviceRead(l_pTarget,
+ static_cast<void *>(&l_memModule),
+ l_memSize,
+ DEVICE_SPD_ADDRESS(SPD::MODULE_TYPE));
+
+ if( l_errl )
+ {
+ FAPI_ERR("getSPD: Error on deviceRead for MODULE_TYPE");
+ break;
+ }
+
+ if( l_memModule == SPD::MEM_DDIMM )
+ {
+ // currently getSPD only supports the ENTIRE_SPD
+ // keyword. In the DDIMM case this include the EFD
+ // data so be sure to reflect that in the size we return.
+ o_size = SPD::OCMB_SPD_EFD_COMBINED_SIZE;
+ }
+ else
+ {
+ o_size = SPD::DDR4_SPD_SIZE;
+ }
+ }// case MEM_DDR4
+ break;
+
+ default:
{
- o_size = DDR4_KEYWORD_SIZE;
- }
- else
- {
- FAPI_ERR("getSPD: Invalid DIMM DDR Type");
- break;
+ FAPI_ERR("getSPD: Unsupported DIMM DDR Generation");
+
+ /*@
+ * @errortype
+ * @moduleid MOD_FAPI2_SPD_ACCESS
+ * @reasoncode RC_INVALID_SPD_DRAM_GEN
+ * @userdata1 DDR generation
+ * @userdata2 HUID of input target
+ * @devdesc Bad SPD or unsupported DIMM
+ * @custdesc Unsupported DIMM generation
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_FAPI2_SPD_ACCESS,
+ RC_INVALID_SPD_DRAM_GEN,
+ TARGETING::get_huid(l_pTarget),
+ l_memGen );
+
+ l_errl->addHwCallout( l_pTarget,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DELAYED_DECONFIG,
+ HWAS::GARD_NULL );
}
+ break;
- FAPI_DBG("getSPD: Returning the size of the SPD :%d ", o_size);
- }
- }
+ }// switch
+
+ FAPI_DBG("getSPD: Returning the size of the SPD :%d ", o_size);
+
+ }// endif
else
{
+ // Return the entire SPD blob
l_errl = deviceRead(l_pTarget,
- o_blob,
- o_size,
- DEVICE_SPD_ADDRESS(SPD::ENTIRE_SPD));
- }
+ o_blob,
+ o_size,
+ DEVICE_SPD_ADDRESS(SPD::ENTIRE_SPD));
+ }// end else
break;
@@ -118,7 +170,7 @@ fapi2::ReturnCode getSPD(
FAPI_ERR("getSPD: Error getting SPD data for HUID=0x%.8X Size %d",
TARGETING::get_huid(l_pTarget),o_size);
- l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ l_rc.setPlatDataPtr(reinterpret_cast<void *>(l_errl));
}
FAPI_DBG("getSPD: SPD data for HUID=0x%.8X Size %d Blob %d",
diff --git a/src/usr/fapi2/plat_utils.C b/src/usr/fapi2/plat_utils.C
index 01eacb645..bcea30664 100644
--- a/src/usr/fapi2/plat_utils.C
+++ b/src/usr/fapi2/plat_utils.C
@@ -48,6 +48,7 @@
#include <p9_scan_compression.H>
#include <cen_ringId.H>
#include <scom/wakeup.H>
+#include <util/misc.H>
//******************************************************************************
// Trace descriptors
@@ -941,6 +942,13 @@ void processEIBusCallouts(const ErrorInfo & i_errInfo,
{
l_busType = HWAS::DMI_BUS_TYPE;
}
+ else if ( ((l_type1 == TARGETING::TYPE_DMI) &&
+ (l_type2 == TARGETING::TYPE_MEMBUF)) ||
+ ((l_type1 == TARGETING::TYPE_MEMBUF) &&
+ (l_type2 == TARGETING::TYPE_DMI)) )
+ {
+ l_busType = HWAS::DMI_BUS_TYPE;
+ }
else if ((l_type1 == TARGETING::TYPE_ABUS) &&
(l_type2 == TARGETING::TYPE_ABUS))
{
@@ -956,6 +964,13 @@ void processEIBusCallouts(const ErrorInfo & i_errInfo,
{
l_busType = HWAS::O_BUS_TYPE;
}
+ else if ( ((l_type1 == TARGETING::TYPE_OMI) &&
+ (l_type2 == TARGETING::TYPE_OCMB_CHIP)) ||
+ ((l_type1 == TARGETING::TYPE_OCMB_CHIP) &&
+ (l_type2 == TARGETING::TYPE_OMI)) )
+ {
+ l_busType = HWAS::OMI_BUS_TYPE;
+ }
else
{
FAPI_ERR("processEIBusCallouts: Bus between target types not known (0x%08x:0x%08x)",
@@ -1468,7 +1483,12 @@ ReturnCode delay(uint64_t i_nanoSeconds,
bool i_fixed)
{
//Note: i_fixed is deliberately ignored
- nanosleep( 0, i_nanoSeconds );
+
+ // We don't need to waste time for hardware delays if we're running in Simics
+ if( !Util::isSimicsRunning() )
+ {
+ nanosleep( 0, i_nanoSeconds );
+ }
return FAPI2_RC_SUCCESS;
}
diff --git a/src/usr/fapi2/rowRepairsFuncs.C b/src/usr/fapi2/rowRepairsFuncs.C
index 6548e31ed..67796ad20 100644
--- a/src/usr/fapi2/rowRepairsFuncs.C
+++ b/src/usr/fapi2/rowRepairsFuncs.C
@@ -34,8 +34,8 @@ extern "C"
{
fapi2::ReturnCode __getDimmRepairData( const fapi2::Target
- <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|fapi2::TARGET_TYPE_MEM_PORT>
- & i_fapiTrgt,
+ <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|
+ fapi2::TARGET_TYPE_MEM_PORT|fapi2::TARGET_TYPE_OCMB_CHIP> & i_fapiTrgt,
const uint8_t i_dimm,
const uint8_t i_rank,
TARGETING::TargetHandle_t & o_dimmTrgt,
@@ -109,8 +109,8 @@ fapi2::ReturnCode __getDimmRepairData( const fapi2::Target
//------------------------------------------------------------------------------
fapi2::ReturnCode getRowRepair( const fapi2::Target
- <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|fapi2::TARGET_TYPE_MEM_PORT>
- & i_fapiTrgt,
+ <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|
+ fapi2::TARGET_TYPE_MEM_PORT|fapi2::TARGET_TYPE_OCMB_CHIP> & i_fapiTrgt,
const uint8_t i_dimm,
const uint8_t i_rank,
uint8_t (&o_data)[mss::ROW_REPAIR_BYTE_COUNT],
@@ -147,8 +147,8 @@ fapi2::ReturnCode getRowRepair( const fapi2::Target
//------------------------------------------------------------------------------
fapi2::ReturnCode setRowRepair( const fapi2::Target
- <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|fapi2::TARGET_TYPE_MEM_PORT>
- & i_fapiTrgt,
+ <fapi2::TARGET_TYPE_MCA|fapi2::TARGET_TYPE_MBA|
+ fapi2::TARGET_TYPE_MEM_PORT|fapi2::TARGET_TYPE_OCMB_CHIP> & i_fapiTrgt,
const uint8_t i_dimm,
const uint8_t i_rank,
uint8_t (&i_data)[mss::ROW_REPAIR_BYTE_COUNT],
diff --git a/src/usr/fapi2/test/fapi2DdimmGetEfdTest.C b/src/usr/fapi2/test/fapi2DdimmGetEfdTest.C
index 13f0ed87b..400ca2a59 100644
--- a/src/usr/fapi2/test/fapi2DdimmGetEfdTest.C
+++ b/src/usr/fapi2/test/fapi2DdimmGetEfdTest.C
@@ -111,7 +111,8 @@ fapi2DdimmGetEfdTest::fapi2DdimmGetEfdTest()
{
FAPI_INF(">> fapi2DdimmGetEfdTest");
- if(TARGETING::MODEL_AXONE != TARGETING::targetService().getProcessorModel())
+ iv_attrModel = TARGETING::targetService().getProcessorModel();
+ if(TARGETING::MODEL_AXONE != iv_attrModel)
{
FAPI_INF("<< fapi2DdimmGetEfdTest: This is not AXONE. "
"Skipping AXONE tests.");
diff --git a/src/usr/fapi2/test/fapi2GetChildrenTest.H b/src/usr/fapi2/test/fapi2GetChildrenTest.H
index 3971c1270..961579e1f 100644
--- a/src/usr/fapi2/test/fapi2GetChildrenTest.H
+++ b/src/usr/fapi2/test/fapi2GetChildrenTest.H
@@ -32,7 +32,6 @@
#include <functional>
#include <plat_utils.H>
#include <error_scope.H>
-#include <config.h>
namespace fapi2
{
@@ -66,7 +65,6 @@ void test_fapi2GetChildren()
uint32_t l_targetHuid = 0xFFFFFFFF;
uint32_t l_actualSize = 0;
uint32_t l_expectedSize = 0;
- errlHndl_t l_err = nullptr;
int numTests = 0;
int numFails = 0;
@@ -225,7 +223,7 @@ void test_fapi2GetChildren()
numTests++;
if(l_actualSize != l_expectedSize)
{
- TS_FAIL("test_fapi2GetChildren:: OMIs per proc mismatch");
+ TS_FAIL("test_fapi2GetChildren:: OMIs per proc mismatch. Actual size: %d, Expected size: %d", l_actualSize, l_expectedSize);
numFails++;
break;
}
@@ -611,17 +609,25 @@ void test_fapi2GetChildren()
TARGET_STATE_PRESENT).size(); } },
// CAPP pervasive has 1 CAPP child
- {PERV_CAPP_CUMULUS_CHILDREN,
+ {PERV_CAPP_AXONE_CHILDREN,
[](TARGETING::ATTR_CHIP_UNIT_type i_unit)
{ return ((i_unit == CAPP0_RANGE) || (i_unit == CAPP1_RANGE));},
[](Target<fapi2::TARGET_TYPE_PERV>& i_perv)
{ return i_perv.getChildren<fapi2::TARGET_TYPE_CAPP>(
TARGET_STATE_PRESENT).size(); } },
- // OBUS pervasive has 3 OBUS BRICK children
- {PERV_OBUS_BRICK_CHILDREN,
+ // OBUS0,3 pervasive has 2 OBUS BRICK children
+ {PERV_OBUS_BRICK03_AXONE_CHILDREN,
[](TARGETING::ATTR_CHIP_UNIT_type i_unit)
- { return ((i_unit >= OBUS_LOW) && (i_unit <= OBUS_HIGH)); },
+ { return ((i_unit == OBUS_LOW+0) || (i_unit == OBUS_LOW+3)); },
+ [](Target<fapi2::TARGET_TYPE_PERV>& i_perv)
+ { return i_perv.getChildren<fapi2::TARGET_TYPE_OBUS_BRICK>(
+ TARGET_STATE_PRESENT).size(); } },
+
+ // OBUS1,2 pervasive has 1 OBUS BRICK child
+ {PERV_OBUS_BRICK12_AXONE_CHILDREN,
+ [](TARGETING::ATTR_CHIP_UNIT_type i_unit)
+ { return ((i_unit == OBUS_LOW+1) || (i_unit == OBUS_LOW+2)); },
[](Target<fapi2::TARGET_TYPE_PERV>& i_perv)
{ return i_perv.getChildren<fapi2::TARGET_TYPE_OBUS_BRICK>(
TARGET_STATE_PRESENT).size(); } },
@@ -699,7 +705,7 @@ void test_fapi2GetChildren()
TARGET_STATE_PRESENT).size(); } },
};
- pervasiveChildTestRec* ptr;
+ pervasiveChildTestRec* ptr = nullptr;
int numPervTests = 0;
TARGETING::ATTR_MODEL_type l_model = l_proc->getAttr<TARGETING::ATTR_MODEL>();
if (l_model == TARGETING::MODEL_NIMBUS)
@@ -750,9 +756,9 @@ void test_fapi2GetChildren()
if(candidateTarget == nullptr)
{
- TS_FAIL("test_fapi2GetChildren:: candidateTarget not found");
+ TS_FAIL("test_fapi2GetChildren:: candidateTarget not found - test %d", i);
numFails++;
- break;
+ continue;
}
l_targetHuid = TARGETING::get_huid(candidateTarget);
@@ -764,9 +770,9 @@ void test_fapi2GetChildren()
if(l_actualSize != l_expectedSize)
{
- TS_FAIL("test_fapi2GetChildren:: children of pervasive mismatch");
+ TS_FAIL("test_fapi2GetChildren:: children of pervasive mismatch for %.8X (exp=%d,act=%d)",
+ l_targetHuid,l_expectedSize,l_actualSize);
numFails++;
- break;
}
}
@@ -780,31 +786,6 @@ void test_fapi2GetChildren()
}while(0);
- if(l_actualSize != l_expectedSize)
- {
- /*@
- * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid fapi2::MOD_FAPI2_PLAT_GET_CHILDREN_TEST
- * @reasoncode fapi2::RC_INVALID_CHILD_COUNT
- * @userdata1[0:31] Expected Child Count
- * @userdata1[32:63] Actual Child Count
- * @userdata2 Parent HUID
- * @devdesc Invalid amount of child cores found
- * on a proc
- */
- l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- fapi2::MOD_FAPI2_PLAT_GET_CHILDREN_TEST,
- fapi2::RC_INVALID_CHILD_COUNT,
- TWO_UINT32_TO_UINT64(
- TO_UINT32(
- l_expectedSize),
- TO_UINT32(
- l_actualSize)),
- l_targetHuid,
- true/*SW Error*/);
- errlCommit(l_err,HWPF_COMP_ID);
- TS_FAIL("test_fapi2GetChildren Fail, for HUID: %d , expected %d children , found %d ", l_targetHuid,l_expectedSize,l_actualSize );
- }
FAPI_INF("fapi2GetChildrenTest:: Test Complete. %d/%d fails", numFails , numTests);
}
@@ -818,7 +799,6 @@ void test_fapi2GetChildrenFilter()
uint32_t l_targetHuid = 0xFFFFFFFF;
uint32_t l_actualSize = 0;
uint32_t l_expectedSize = 0;
- errlHndl_t l_err = nullptr;
TARGETING::Target * l_proc = nullptr;
TARGETING::TargetHandleList l_chipList;
do
@@ -835,7 +815,7 @@ void test_fapi2GetChildrenFilter()
}
else
{
- TS_FAIL("test_fapi2GetChildren Fail: could not find any proc, skipping tests");
+ TS_FAIL("test_fapi2GetChildrenFilter Fail: could not find any proc, skipping tests");
numFails++;
break;
}
@@ -876,7 +856,7 @@ void test_fapi2GetChildrenFilter()
if(l_actualSize != l_expectedSize)
{
numFails++;
- break;
+ TS_FAIL("test_fapi2GetChildrenFilter Fail on PERV/ALL_CORES, for HUID: 0x%.8X , expected %d children , found %d ", l_targetHuid,l_expectedSize,l_actualSize );
}
// PERV - TARGET_FILTER_CORE1
@@ -890,7 +870,7 @@ void test_fapi2GetChildrenFilter()
if(l_actualSize != l_expectedSize)
{
numFails++;
- break;
+ TS_FAIL("test_fapi2GetChildrenFilter Fail on PERV/CORE1, for HUID: 0x%.8X , expected %d children , found %d ", l_targetHuid,l_expectedSize,l_actualSize );
}
if (isHwValid(l_proc, MY_MC))
@@ -906,13 +886,26 @@ void test_fapi2GetChildrenFilter()
if(l_actualSize != l_expectedSize)
{
numFails++;
- break;
+ TS_FAIL("test_fapi2GetChildrenFilter Fail on PERV/ALL_MC, for HUID: 0x%.8X , expected %d children , found %d ", l_targetHuid,l_expectedSize,l_actualSize );
}
}
// PERV - SYNC_MODE_ALL_IO_EXCEPT_NEST
- // NOTE: 2 of 4 OBUS are Cumulus only, so expect 8 instead of 10 returned
- l_expectedSize = 8;
+ l_expectedSize = 0;
+ TARGETING::ATTR_MODEL_type l_model = l_proc->getAttr<TARGETING::ATTR_MODEL>();
+ if (l_model == TARGETING::MODEL_NIMBUS)
+ {
+ // NOTE: 2 of 4 OBUS are Cumulus only, so expect 8 instead of 10 returned
+ l_expectedSize = 8;
+ }
+ else if (l_model == TARGETING::MODEL_CUMULUS)
+ {
+ l_expectedSize = 10;
+ }
+ else if (l_model == TARGETING::MODEL_AXONE)
+ {
+ l_expectedSize = 10;
+ }
l_childPERVs = fapi2_procTarget.getChildren<fapi2::TARGET_TYPE_PERV>(
TARGET_FILTER_SYNC_MODE_ALL_IO_EXCEPT_NEST,
TARGET_STATE_PRESENT);
@@ -922,37 +915,11 @@ void test_fapi2GetChildrenFilter()
if(l_actualSize != l_expectedSize)
{
numFails++;
- break;
+ TS_FAIL("test_fapi2GetChildrenFilter Fail on PERV/ALL_IO_EXCEPT_NEST, for HUID: 0x%.8X , expected %d children , found %d ", l_targetHuid,l_expectedSize,l_actualSize );
}
}while(0);
- if(l_actualSize != l_expectedSize)
- {
- /*@
- * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid fapi2::MOD_FAPI2_PLAT_GET_CHILDREN_FILTER_TEST
- * @reasoncode fapi2::RC_INVALID_CHILD_COUNT
- * @userdata1[0:31] Expected Child Count
- * @userdata1[32:63] Actual Child Count
- * @userdata2 Parent HUID
- * @devdesc Invalid amount of child cores found
- * on a proc
- */
- l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- fapi2::MOD_FAPI2_PLAT_GET_CHILDREN_FILTER_TEST,
- fapi2::RC_INVALID_CHILD_COUNT,
- TWO_UINT32_TO_UINT64(
- TO_UINT32(
- l_expectedSize),
- TO_UINT32(
- l_actualSize)),
- l_targetHuid,
- true/*SW Error*/);
- errlCommit(l_err,HWPF_COMP_ID);
- TS_FAIL("test_fapi2GetChildrenFilter Fail, for HUID: 0x%X , expected %d children , found %d ", l_targetHuid,l_expectedSize,l_actualSize );
- }
-
FAPI_INF("test_fapi2GetChildrenFilter: Test Complete. %d/%d fails", numFails , numTests);
}
@@ -966,10 +933,12 @@ void test_fapi2getChildTargetsForCDG()
int numFails = 0;
TARGETING::Target * l_proc = nullptr;
size_t l_expectedDimms = 0;
+ TARGETING::TargetHandleList l_chipList;
+// These port and socket arguments are not valid for Axone targets
+#ifndef CONFIG_AXONE
size_t l_expectedDimmsUnderPort0 = 0;
size_t l_expectedDimmsUnderPort1 = 0;
- TARGETING::TargetHandleList l_chipList;
-
+#endif
do
{
FAPI_DBG("start of test_fapi2getChildTargetsForCDG()");
@@ -992,20 +961,24 @@ void test_fapi2getChildTargetsForCDG()
if (l_proc->getAttr<TARGETING::ATTR_MODEL>() == TARGETING::MODEL_NIMBUS)
{
l_expectedDimms = 16;
+// These port and socket arguments are not valid for Axone targets
+#ifndef CONFIG_AXONE
l_expectedDimmsUnderPort0 = l_expectedDimms;
l_expectedDimmsUnderPort1 = 0;
+#endif
}
else if (l_proc->getAttr<TARGETING::ATTR_MODEL>() == TARGETING::MODEL_CUMULUS)
{
l_expectedDimms = 8;
+// These port and socket arguments are not valid for Axone targets
+#ifndef CONFIG_AXONE
l_expectedDimmsUnderPort0 = l_expectedDimms/2;
l_expectedDimmsUnderPort1 = l_expectedDimms/2;
+#endif
}
else if (l_proc->getAttr<TARGETING::ATTR_MODEL>() == TARGETING::MODEL_AXONE)
{
l_expectedDimms = 9;
- l_expectedDimmsUnderPort0 = 0xFF; //wrong
- l_expectedDimmsUnderPort1 = 0xFF; //wrong
}
else //both are nullptr
{
@@ -1035,6 +1008,9 @@ void test_fapi2getChildTargetsForCDG()
numFails++;
}
+// These port and socket arguments are not valid for Axone targets
+// so skip testing them
+#ifndef CONFIG_AXONE
// All dimms under port 0
fapi2::getChildTargetsForCDG(fapi2_procTarget,
fapi2::TARGET_TYPE_DIMM,
@@ -1047,11 +1023,9 @@ void test_fapi2getChildTargetsForCDG()
if(l_dimmList.size() != l_expectedDimmsUnderPort0)
{
-#ifndef CONFIG_AXONE_BRING_UP
TS_FAIL("test_fapi2getChildTargetsForCDG: Dimm count %d under port 0 not equal expected %d",
l_dimmList.size(),l_expectedDimmsUnderPort0);
numFails++;
-#endif
}
// All dimms under port 1
@@ -1066,11 +1040,9 @@ void test_fapi2getChildTargetsForCDG()
if(l_dimmList.size() != l_expectedDimmsUnderPort1)
{
-#ifndef CONFIG_AXONE_BRING_UP
TS_FAIL("test_fapi2getChildTargetsForCDG: Dimm count %d under port 1 not equal expected %d",
l_dimmList.size(),l_expectedDimmsUnderPort1);
numFails++;
-#endif
}
// All dimms under socket 0
@@ -1084,11 +1056,9 @@ void test_fapi2getChildTargetsForCDG()
numTests++;
if(l_dimmList.size() != l_expectedDimms)
{
-#ifndef CONFIG_AXONE_BRING_UP
- TS_FAIL("test_fapi2getChildTargetsForCDG: Dimm count %d under socket 0 not equal expected %d",
+ TS_FAIL("test_fapi2getChildTargetsForCDG: Dimm count %d under socket 0x0, all ports, not equal expected %d",
l_dimmList.size(),l_expectedDimms);
numFails++;
-#endif
}
// All dimms under socket 1
@@ -1106,6 +1076,7 @@ void test_fapi2getChildTargetsForCDG()
l_dimmList.size(),0);
numFails++;
}
+#endif
}while(0);
diff --git a/src/usr/fapi2/test/fapi2GetVpdTest.H b/src/usr/fapi2/test/fapi2GetVpdTest.H
index 8a8dc0849..8f86430a0 100644
--- a/src/usr/fapi2/test/fapi2GetVpdTest.H
+++ b/src/usr/fapi2/test/fapi2GetVpdTest.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -46,7 +46,7 @@ public:
void testGetVPD(void)
{
-#ifdef CONFIG_SECUREBOOT
+#if (defined CONFIG_SECUREBOOT && ! defined CONFIG_AXONE)
errlHndl_t pError=NULL;
do
{
@@ -71,7 +71,7 @@ void testGetVPD(void)
testGetVPD_DQ();
testGetVPD_CK();
-#ifdef CONFIG_SECUREBOOT
+#if (defined CONFIG_SECUREBOOT && ! defined CONFIG_AXONE)
pError = PNOR::unloadSecureSection(PNOR::MEMD);
if(pError)
{
diff --git a/src/usr/fapi2/test/fapi2MmioAccessTest.H b/src/usr/fapi2/test/fapi2MmioAccessTest.H
index 3ba0f31c0..fffec22e8 100644
--- a/src/usr/fapi2/test/fapi2MmioAccessTest.H
+++ b/src/usr/fapi2/test/fapi2MmioAccessTest.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,7 +38,7 @@
#include <fapi2TestUtils.H>
#include <p9_mmiotests.H>
#include <plat_hwp_invoker.H>
-#include <config.h>
+#include <test/exptest_utils.H>
using namespace fapi2;
@@ -110,10 +110,22 @@ void test_fapi2MmioInvalidSizes()
// Get a list of all of the OCMB chips
TARGETING::getAllChips(l_ocmbTargetList, TARGETING::TYPE_OCMB_CHIP, true);
+ if (!iv_serializeTestMutex)
+ {
+ TS_FAIL("test_fapi2MmioInvalidSizes(): unable to get test mutex");
+ return;
+ }
+ mutex_lock(iv_serializeTestMutex);
+
for (auto & l_ocmb: l_ocmbTargetList)
{
Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapi2_ocmbTarget( l_ocmb );
-
+ auto first_ocmb_info = l_ocmb->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
+ if (!first_ocmb_info.useInbandScom)
+ {
+ TS_FAIL("test_fapi2MmioInvalidSizes() - scom access is not using inband");
+ continue;
+ }
numTests++;
FAPI_INVOKE_HWP(l_errl, p9_mmiotest_indivisible_by_section_size, fapi2_ocmbTarget);
if(l_errl != nullptr)
@@ -126,6 +138,12 @@ void test_fapi2MmioInvalidSizes()
TS_FAIL("No error from p9_mmiotest_indivisible_by_section_size !!");
numFails++;
}
+ auto second_ocmb_info = l_ocmb->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
+ if (!second_ocmb_info.useInbandScom)
+ {
+ TS_FAIL("p9_mmiotest_indivisible_by_section_size turned off mmio operations");
+ l_ocmb->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(first_ocmb_info);
+ }
numTests++;
FAPI_INVOKE_HWP(l_errl, p9_mmiotest_invalid_section_size, fapi2_ocmbTarget);
@@ -139,7 +157,14 @@ void test_fapi2MmioInvalidSizes()
TS_FAIL("No error from p9_mmiotest_invalid_section_size !!");
numFails++;
}
+ auto third_ocmb_info = l_ocmb->getAttr<TARGETING::ATTR_SCOM_SWITCHES>();
+ if (!third_ocmb_info.useInbandScom)
+ {
+ TS_FAIL("p9_mmiotest_invalid_section_size turned off mmio operations");
+ l_ocmb->setAttr<TARGETING::ATTR_SCOM_SWITCHES>(first_ocmb_info);
+ }
}
+ mutex_unlock(iv_serializeTestMutex);
FAPI_INF("test_fapi2MmioInvalidSizes Test Complete. %d/%d fails", numFails, numTests);
}
@@ -152,7 +177,6 @@ void test_fapi2MmioAccess()
int numTests = 0;
int numFails = 0;
-#ifndef CONFIG_AXONE_BRING_UP
errlHndl_t l_errl = nullptr;
// Create a vector of TARGETING::Target pointers
@@ -161,6 +185,12 @@ void test_fapi2MmioAccess()
// Get a list of all of the OCMB chips
TARGETING::getAllChips(l_chipList, TARGETING::TYPE_OCMB_CHIP, true);
+ if (!iv_serializeTestMutex)
+ {
+ TS_FAIL("test_fapi2MmioAccess(): unable to get test mutex");
+ return;
+ }
+ mutex_lock(iv_serializeTestMutex);
for (auto & l_ocmb: l_chipList)
{
Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi2_target( l_ocmb );
@@ -213,11 +243,41 @@ void test_fapi2MmioAccess()
l_errl = nullptr;
}
}
-#endif
+ mutex_unlock(iv_serializeTestMutex);
FAPI_INF("fapi2MmioAccessTest Test Complete. %d/%d fails", numFails, numTests);
}
+/**
+ * @brief Constructor
+ */
+Fapi2MmioAccessTest() : CxxTest::TestSuite()
+{
+ // All modules are loaded by runtime,
+ // so testcase loading of modules is not required
+#ifndef __HOSTBOOT_RUNTIME
+ errlHndl_t err = nullptr;
+ err = exptest::loadModule(exptest::MSS_LIBRARY_NAME);
+ if(err)
+ {
+ TS_FAIL("Fapi2MmioAccessTest() - Constuctor: failed to load MSS module");
+ errlCommit( err, TARG_COMP_ID );
+ }
+#endif
+ iv_serializeTestMutex = exptest::getTestMutex();
+};
+
+/**
+ * @brief Deconstructor
+ */
+~Fapi2MmioAccessTest()
+{
+}
+
+
+private:
+ // This is used for tests that need to not run operations at the same time
+ TARGETING::HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR iv_serializeTestMutex;
};
diff --git a/src/usr/fapi2/test/fapi2MvpdTestCxx.H b/src/usr/fapi2/test/fapi2MvpdTestCxx.H
index 224879070..92d791908 100644
--- a/src/usr/fapi2/test/fapi2MvpdTestCxx.H
+++ b/src/usr/fapi2/test/fapi2MvpdTestCxx.H
@@ -326,7 +326,8 @@ public:
#ifdef CONFIG_EARLY_TESTCASES
// Requires some prereqs of step7
- FAPI_INF("Skipping poundv tests");
+ FAPI_INF("Skipping poundv tests due to CONFIG_EARLY_TESTCASES");
+
#else
fapi2::ReturnCode l_rc;
@@ -421,7 +422,8 @@ public:
#ifdef CONFIG_EARLY_TESTCASES
// Requires some prereqs of step7
- FAPI_INF("Skipping poundv tests");
+ FAPI_INF("Skipping poundw tests due to CONFIG_EARLY_TESTCASES");
+
#else
fapi2::ReturnCode l_rc;
diff --git a/src/usr/fapi2/test/fapi2SpdTestCxx.H b/src/usr/fapi2/test/fapi2SpdTestCxx.H
index 2ccd457dc..d033401e8 100644
--- a/src/usr/fapi2/test/fapi2SpdTestCxx.H
+++ b/src/usr/fapi2/test/fapi2SpdTestCxx.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,6 +37,7 @@
#include <errl/errlentry.H>
#include <devicefw/driverif.H>
#include <fapi2_spd_access.H>
+#include <vpd/spdenums.H>
using namespace TARGETING;
@@ -52,76 +53,127 @@ class SPDTest: public CxxTest::TestSuite
{
public:
- /**
- * @brief Test SPD get Interface DIMMs.
- */
- void testGetSPD ( void )
- {
- fapi2::ReturnCode l_rc;
- size_t l_size = 0;
- uint8_t * l_blobData = NULL;
-
- FAPI_INF( "testGetSPD - Enter" );
-
- do
- {
- TARGETING::Target * i_pTarget = NULL;
-
- // Get DIMM Targets
- TargetHandleList dimmList;
- getDIMMTargets( dimmList );
-
- // Should get atleast one
- if( ( 0 == dimmList.size() ) ||
- ( NULL == dimmList[0] ) )
- {
- FAPI_INF( "testGetSPD- No DIMMs found!");
- break;
- }
-
- // Work on the first DIMM target
- i_pTarget = dimmList[0];
-
- // convert to fapi2 target
- fapi2::Target<fapi2::TARGET_TYPE_DIMM> fapi2_Target(i_pTarget);
-
- // SPD interface call with NULL blob to get size data
- l_rc = fapi2::getSPD(fapi2_Target, NULL, l_size);
-
- // Expect to return the size or non failure
- if( !l_size || (l_rc != fapi2::FAPI2_RC_SUCCESS) )
- {
- TS_FAIL("testGetSPD: Failed getting the size of the mem buffer");
- break;
- }
-
- // allocate the blob data of mem size length to hold data
- l_blobData = reinterpret_cast<uint8_t *>(malloc(l_size));
- memset(l_blobData,0,l_size);
-
- l_rc = fapi2::getSPD(fapi2_Target,l_blobData, l_size);
- if ( l_rc != fapi2::FAPI2_RC_SUCCESS )
- {
- TS_FAIL( "testGetSPD- Failed to read data from DIMM with HUID= 0x%x",
- TARGETING::get_huid(i_pTarget));
- break;
- }
-
- FAPI_DBG("getSPD: SPD data for DIMM with HUID=0x%.8X Size %d Blob %d",
- TARGETING::get_huid(i_pTarget),
- l_size,
- l_blobData);
-
- } while(0);
-
- if( NULL != l_blobData )
- {
- free( l_blobData );
- l_blobData = NULL;
- }
-
- FAPI_INF( "testGetSPD - Exit" );
- }
+ /**
+ * @brief Test SPD get Interface DIMMs.
+ */
+ void testGetSPD ( void )
+ {
+ fapi2::ReturnCode l_rc;
+ size_t l_spdSize = 0;
+ uint8_t * l_blobData = NULL;
+
+ FAPI_INF( "testGetSPD - Enter" );
+
+ // Get DIMM Targets
+ TargetHandleList dimmList;
+ getDIMMTargets( dimmList );
+
+ // Should get atleast one
+ if( ( 0 == dimmList.size() ) ||
+ ( NULL == dimmList[0] ) )
+ {
+ TS_FAIL( "testGetSPD- No DIMMs found!");
+ }
+
+ for( auto l_tDimm : dimmList )
+ {
+
+ // convert to fapi2 target
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> l_fDimm(l_tDimm);
+
+ // SPD interface call with NULL blob to get size data
+ l_rc = fapi2::getSPD(l_fDimm, NULL, l_spdSize);
+
+ // Expect to return the size or non failure
+ if( !l_spdSize || (l_rc != fapi2::FAPI2_RC_SUCCESS) )
+ {
+ TS_FAIL("testGetSPD: Failed getting the size of the mem buffer - Dimm %.8X", TARGETING::get_huid(l_tDimm));
+ continue;
+ }
+
+ // allocate the blob data of mem size length to hold data
+ l_blobData = reinterpret_cast<uint8_t *>(malloc(l_spdSize));
+ memset(l_blobData,0,l_spdSize);
+
+ l_rc = fapi2::getSPD(l_fDimm,l_blobData, l_spdSize);
+ if ( l_rc != fapi2::FAPI2_RC_SUCCESS )
+ {
+ TS_FAIL( "testGetSPD- Failed to read data from DIMM with HUID= 0x%x",
+ TARGETING::get_huid(l_tDimm));
+ continue;
+ }
+
+ uint8_t l_memModule = 0x0;
+ size_t l_memSize = sizeof(uint8_t);
+
+ auto l_errl = deviceRead(l_tDimm,
+ (void *)&l_memModule,
+ l_memSize,
+ DEVICE_SPD_ADDRESS(SPD::MODULE_TYPE));
+
+ if ( l_errl )
+ {
+ TS_FAIL( "testGetSPD- Failed to deviceRead with HUID= 0x%x",
+ TARGETING::get_huid(l_tDimm));
+ continue;
+ }
+
+ uint8_t l_memGen = 0x0;
+ l_errl = deviceRead(l_tDimm,
+ (void *)&l_memGen,
+ l_memSize,
+ DEVICE_SPD_ADDRESS(SPD::BASIC_MEMORY_TYPE));
+
+ if ( l_errl )
+ {
+ TS_FAIL( "testGetSPD- Failed to deviceRead with HUID= 0x%x",
+ TARGETING::get_huid(l_tDimm));
+ continue;
+ }
+
+ // figure out the expected size based on the memory type
+ size_t l_compareSize = 0;
+ if( (l_memModule == SPD::MEM_DDIMM) && (l_memGen == SPD::MEM_DDR4) )
+ {
+ l_compareSize = SPD::OCMB_SPD_EFD_COMBINED_SIZE;
+ }
+ else if( (l_memModule != SPD::MEM_DDIMM) && (l_memGen == SPD::MEM_DDR4) )
+ {
+ l_compareSize = SPD::DDR4_SPD_SIZE;
+ }
+ else if( l_memGen == SPD::MEM_DDR3 )
+ {
+ l_compareSize = SPD::DDR3_SPD_SIZE;
+ }
+ else
+ {
+ TS_FAIL( "testGetSPD - Unknown memory type for %.8X : module=0x%X, gen=0x%X",
+ TARGETING::get_huid(l_tDimm), l_memModule, l_memGen );
+ continue;
+ }
+
+ if( l_compareSize != l_spdSize )
+ {
+ TS_FAIL( "testGetSPD - Wrong SPD size for %.8X : module=0x%X, gen=0x%X, exp=%d, act=%d",
+ TARGETING::get_huid(l_tDimm), l_memModule, l_memGen,
+ l_compareSize, l_spdSize);
+ continue;
+ }
+
+ FAPI_DBG("getSPD: SPD data for DIMM with HUID=0x%.8X Size %d Blob %d",
+ TARGETING::get_huid(l_tDimm),
+ l_spdSize,
+ l_blobData);
+ }
+
+ if( NULL != l_blobData )
+ {
+ free( l_blobData );
+ l_blobData = NULL;
+ }
+
+ FAPI_INF( "testGetSPD - Exit" );
+ }
};
diff --git a/src/usr/fapi2/test/fapi2Test.mk b/src/usr/fapi2/test/fapi2Test.mk
index f7dc4d002..074e4e45d 100644
--- a/src/usr/fapi2/test/fapi2Test.mk
+++ b/src/usr/fapi2/test/fapi2Test.mk
@@ -72,6 +72,8 @@ else
## All hostboot IPL time tests
TESTS += ${shell ls ${ROOTPATH}/src/usr/fapi2/test/*Test.H | \
sort | xargs}
+EXTRAINCDIR += ${ROOTPATH}/src/usr/expaccess/
+
OBJS += p9_i2ctests.o
OBJS += p9_mmiotests.o
diff --git a/src/usr/fapi2/test/fapi2TestUtils.H b/src/usr/fapi2/test/fapi2TestUtils.H
index 7b724a094..011538c63 100644
--- a/src/usr/fapi2/test/fapi2TestUtils.H
+++ b/src/usr/fapi2/test/fapi2TestUtils.H
@@ -225,7 +225,10 @@ enum PERVASIVE_CHILDREN {
PERV_OBUS_CHILDREN = 1,
PERV_CAPP_NIMBUS_CHILDREN = 1,
PERV_CAPP_CUMULUS_CHILDREN = 2,
+ PERV_CAPP_AXONE_CHILDREN = 1,
PERV_OBUS_BRICK_CHILDREN = 3,
+ PERV_OBUS_BRICK03_AXONE_CHILDREN = 2,
+ PERV_OBUS_BRICK12_AXONE_CHILDREN = 1,
PERV_MCBIST_CHILDREN = 1,
PERV_MCS_CHILDREN = 2,
PERV_MCA_CHILDREN = 4,
diff --git a/src/usr/fapi2/test/p9_mmiotests.C b/src/usr/fapi2/test/p9_mmiotests.C
index 264e88117..1214e20fb 100644
--- a/src/usr/fapi2/test/p9_mmiotests.C
+++ b/src/usr/fapi2/test/p9_mmiotests.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,6 +37,13 @@
#include <sbe/sbe_common.H>
+// Write/Read from the inband response address (shouldn't hurt anything)
+// Constants from #include <lib/inband/exp_inband.H>
+static const uint64_t EXPLR_IB_MMIO_OFFSET = 0x0000000100000000ull; // 4GB
+static const uint64_t EXPLR_IB_SRAM_BASE = 0x01000000; // MSCCRNGE 01000000 020FFFFF
+static const uint64_t EXPLR_IB_RSP_SRAM_ADDR = EXPLR_IB_SRAM_BASE | 0x03FF00;
+static const uint64_t EXPLR_IB_RSP_ADDR = EXPLR_IB_MMIO_OFFSET | EXPLR_IB_RSP_SRAM_ADDR;
+
fapi2::ReturnCode p9_mmiotest_getmmio_invalid_target(
fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
@@ -48,7 +55,7 @@ fapi2::ReturnCode p9_mmiotest_getmmio_invalid_target(
FAPI_INF("Do getMMIO on a proc target for 8 bytes");
FAPI_TRY(fapi2::getMMIO(i_target,
- 0x1000, // mmio address relative to target
+ EXPLR_IB_RSP_ADDR, // mmio address relative to target
8, // mmio transaction size
l_mmiodata));
fapi_try_exit:
@@ -75,7 +82,7 @@ fapi2::ReturnCode p9_mmiotest_putmmio_invalid_target(
FAPI_INF( "Do putMMIO on proc target" );
FAPI_TRY(fapi2::putMMIO(i_target,
- 0x1000,
+ EXPLR_IB_RSP_ADDR,
4,
l_mmiodata));
@@ -100,7 +107,7 @@ fapi2::ReturnCode p9_mmiotest_indivisible_by_section_size(
FAPI_INF("Do getMMIO on a target for 10 bytes");
FAPI_TRY(fapi2::getMMIO(i_target,
- 0x1000, // mmio address relative to target
+ EXPLR_IB_RSP_ADDR, // mmio address relative to target
8, // mmio transaction size
l_mmiodata));
fapi_try_exit:
@@ -123,7 +130,7 @@ fapi2::ReturnCode p9_mmiotest_invalid_section_size(
FAPI_INF("Do getMMIO on a target for 12 bytes");
FAPI_TRY(fapi2::getMMIO(i_target,
- 0x1000, // mmio address relative to target
+ EXPLR_IB_RSP_ADDR, // mmio address relative to target
12, // mmio transaction size
l_mmiodata));
fapi_try_exit:
@@ -149,7 +156,7 @@ fapi2::ReturnCode p9_mmiotest_getmmio_pass(
FAPI_INF("Do single-read transaction getMMIO on an OCMB target");
FAPI_TRY(fapi2::getMMIO(i_target,
- 0x1000,
+ EXPLR_IB_RSP_ADDR,
l_mmiodataSize,
l_mmiodata) );
@@ -157,7 +164,7 @@ fapi2::ReturnCode p9_mmiotest_getmmio_pass(
l_mmiodata.resize(l_mmiodataSize*2); // do a double mmio transaction
FAPI_INF("Do double-read transaction getMMIO on an OCMB target");
FAPI_TRY(fapi2::getMMIO(i_target,
- 0x1000,
+ EXPLR_IB_RSP_ADDR,
l_mmiodataSize,
l_mmiodata) );
@@ -183,7 +190,7 @@ fapi2::ReturnCode p9_mmiotest_double_read_pass(
FAPI_INF("Do first getMMIO on an ocmb target");
FAPI_TRY(fapi2::getMMIO(i_target,
- 0x1000,
+ EXPLR_IB_RSP_ADDR,
l_mmioTransactionSize,
l_1st_read) );
@@ -195,7 +202,7 @@ fapi2::ReturnCode p9_mmiotest_double_read_pass(
FAPI_INF("Do second getMMIO on an ocmb target");
FAPI_TRY(fapi2::getMMIO(i_target,
- 0x1000,
+ EXPLR_IB_RSP_ADDR,
l_mmioTransactionSize,
l_2nd_read) );
@@ -237,7 +244,7 @@ fapi2::ReturnCode p9_mmiotest_putmmio_pass(
FAPI_INF("Do putMMIO on OCMB target");
FAPI_TRY(fapi2::putMMIO(i_target,
- 0x1000,
+ EXPLR_IB_RSP_ADDR,
4,
l_mmiodata));
fapi_try_exit:
@@ -266,14 +273,14 @@ fapi2::ReturnCode p9_mmiotest_write_read_pass(
// Write out a known value (name of this test)
FAPI_INF("Calling putMMIO on the target (size: %d)", l_data_size);
- FAPI_TRY(fapi2::putMMIO(i_target, 0x1000,
+ FAPI_TRY(fapi2::putMMIO(i_target, EXPLR_IB_RSP_ADDR,
l_mmioTransactionSize, l_mmio_data));
// now read it out and verify it was written correctly
FAPI_INF("Now read the just written data");
l_read_mmio_data.resize(l_data_size);
FAPI_TRY(fapi2::getMMIO(i_target,
- 0x1000,
+ EXPLR_IB_RSP_ADDR,
l_mmioTransactionSize,
l_read_mmio_data));
diff --git a/src/usr/fapiwrap/fapiWrap.C b/src/usr/fapiwrap/fapiWrap.C
new file mode 100644
index 000000000..8950e0a92
--- /dev/null
+++ b/src/usr/fapiwrap/fapiWrap.C
@@ -0,0 +1,106 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/fapiwrap/fapiWrap.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+// Platform includes
+#include <fapiwrap/fapiWrapif.H> // interface definitions
+#include <fapi2/plat_hwp_invoker.H> // FAPI_INVOKE_HWP
+#include <trace/interface.H> // tracing includes
+#include <vpd/spdenums.H> // DDIMM_DDR4_SPD_SIZE
+#include <devicefw/driverif.H> // deviceRead
+
+// Imported Includes
+#include <exp_getidec.H> // exp_getidec
+#include <pmic_i2c_addr_get.H> // get_pmic_i2c_addr
+#include <chipids.H> // for GEMINI ID
+
+
+trace_desc_t* g_trac_fapiwrap;
+TRAC_INIT(&g_trac_fapiwrap, FAPIWRAP_COMP_NAME, 6*KILOBYTE, TRACE::BUFFER_SLOW);
+
+
+namespace FAPIWRAP
+{
+ errlHndl_t explorer_getidec( TARGETING::Target * i_ocmbChip,
+ uint16_t& o_chipId,
+ uint8_t& o_ec)
+ {
+ errlHndl_t l_errl = nullptr;
+
+ //assert type of i_ocmbChip == TARGETING::TYPE_OCMB_CHIP
+ assert(i_ocmbChip->getAttr<TARGETING::ATTR_TYPE>() == TARGETING::TYPE_OCMB_CHIP,
+ "exp_getidec_wrap: error expected type OCMB_CHIP");
+
+ fapi2::Target <fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target(i_ocmbChip);
+
+ FAPI_INVOKE_HWP(l_errl,
+ exp_getidec,
+ l_fapi_ocmb_target,
+ o_chipId,
+ o_ec);
+
+ return l_errl;
+ }
+
+ errlHndl_t get_pmic_dev_addr( TARGETING::Target * i_ocmbChip,
+ const uint8_t i_pmic_id,
+ uint8_t& o_pmic_devAddr)
+ {
+ errlHndl_t l_errl = nullptr;
+
+ do{
+
+ auto l_chipId = i_ocmbChip->getAttr< TARGETING::ATTR_CHIP_ID>();
+
+ if( l_chipId == POWER_CHIPID::GEMINI_16)
+ {
+ // If this is a Gemini OCMB then there are no PMIC targets
+ // so just set the out parm to NO_PMIC_DEV_ADDR and break
+ o_pmic_devAddr = NO_PMIC_DEV_ADDR;
+ break;
+ }
+
+ uint8_t l_spdBlob[SPD::DDIMM_DDR4_SPD_SIZE];
+ size_t l_spdSize = SPD::DDIMM_DDR4_SPD_SIZE;
+
+ l_errl = deviceRead(i_ocmbChip,
+ l_spdBlob,
+ l_spdSize,
+ DEVICE_SPD_ADDRESS(SPD::ENTIRE_SPD_WITHOUT_EFD));
+
+ if(l_errl)
+ {
+ TRACFCOMP( g_trac_fapiwrap, ERR_MRK"get_pmic_dev_addr() "
+ "Error reading SPD associated with OCMB 0x%.08X",
+ TARGETING::get_huid(i_ocmbChip));
+ break;
+ }
+
+ o_pmic_devAddr = get_pmic_i2c_addr(reinterpret_cast<char *>(l_spdBlob),
+ i_pmic_id);
+
+ }while(0);
+ return l_errl;
+ }
+} \ No newline at end of file
diff --git a/src/usr/fapiwrap/makefile b/src/usr/fapiwrap/makefile
new file mode 100644
index 000000000..1916630db
--- /dev/null
+++ b/src/usr/fapiwrap/makefile
@@ -0,0 +1,53 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/fapiwrap/makefile $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+ROOTPATH = ../../..
+MODULE = fapiwrap
+
+# Add the import path to the include path
+EXTRAINCDIR += ${ROOTPATH}/src/import
+# to get fapi2.H
+EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include/
+# to get target.H
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2/
+# to get common_ringId.H
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs/
+# to get ffdc_includes.H
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc/
+# to get chipids.H
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils
+
+# HWP include directories :
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/common/spd_access/
+
+# HWP objects
+OBJS += exp_getidec.o
+
+OBJS += fapiWrap.o
+
+# Add HWP src directories to VPATH
+VPATH += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
+
+include ${ROOTPATH}/config.mk \ No newline at end of file
diff --git a/src/usr/fsi/fsipres.C b/src/usr/fsi/fsipres.C
index 873b58af4..f0a8f7c3a 100644
--- a/src/usr/fsi/fsipres.C
+++ b/src/usr/fsi/fsipres.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -33,7 +33,6 @@
#include <errl/errlmanager.H>
#include <hwas/common/hwasCallout.H>
#include <targeting/common/predicates/predicatectm.H>
-#include <config.h>
#include <initservice/initserviceif.H>
extern trace_desc_t* g_trac_fsi;
diff --git a/src/usr/fsi/runtime/rt_fsi.C b/src/usr/fsi/runtime/rt_fsi.C
index 75103cc4b..551ef7b4e 100644
--- a/src/usr/fsi/runtime/rt_fsi.C
+++ b/src/usr/fsi/runtime/rt_fsi.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -24,7 +24,7 @@
/* IBM_PROLOG_END_TAG */
#include <stdlib.h>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <runtime/interface.h>
#include <targeting/common/targetservice.H>
diff --git a/src/usr/gpio/HBconfig b/src/usr/gpio/HBconfig
index e5f650eb9..20ed72dd0 100644
--- a/src/usr/gpio/HBconfig
+++ b/src/usr/gpio/HBconfig
@@ -1,4 +1,4 @@
config GPIODD
- default n
+ default y
help
Enable GPIO device driver support
diff --git a/src/usr/gpio/gpio_pca9551.C b/src/usr/gpio/gpio_pca9551.C
new file mode 100644
index 000000000..6edbd1a9a
--- /dev/null
+++ b/src/usr/gpio/gpio_pca9551.C
@@ -0,0 +1,343 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/gpio/gpio_pca9551.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file gpio_pca9551.C
+ *
+ * @brief Implements Interfaces Specific to the PCA9551 GPIO Devices
+ *
+ * @note Reference: https://www.nxp.com/docs/en/data-sheet/PCA9551.pdf
+ *
+ */
+
+
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <errl/errludstring.H>
+#include <targeting/common/targetservice.H>
+#include <targeting/common/commontargeting.H>
+#include <devicefw/driverif.H>
+#include "gpiodd.H"
+#include <gpio/gpioddreasoncodes.H>
+#include <gpio/gpioif.H>
+#include <config.h>
+
+extern trace_desc_t* g_trac_gpio;
+
+// Set to TRACFCOMP to enable unit trace
+#define TRACUCOMP(args...) TRACDCOMP(args)
+
+using namespace DeviceFW;
+using namespace TARGETING;
+
+namespace GPIO
+{
+
+
+void gpioPca9551SetReigsterHelper(const PCA9551_LEDS_t i_led,
+ const PCA9551_LED_Output_Settings_t i_setting,
+ uint8_t & io_led_register_data)
+{
+ uint8_t l_led = i_led;
+ uint8_t l_mask = PCA9551_LED_SETTINGS_MASK; // 2-bit mask shifted over to
+ // match i_led's value
+ uint8_t l_setting = i_setting; // will be shifted with 2-bit mask before it is applied
+
+ // Adjust values for LEDs 4 to 7 to match calculations below for LEDs 0 to 3
+ if (i_led > PCA9551_LED3)
+ {
+ l_led = l_led / PCA9551_LED_SETTINGS_DIVISOR;
+ }
+ TRACUCOMP(g_trac_gpio, "gpioPca9551SetReigsterHelper: "
+ "i_led=0x%.2X, l_led=0x%.2X, l_mask=0x%.2X, "
+ "l_setting=0x%.2X, data0=0x%.2X",
+ i_led, l_led, l_mask, l_setting,io_led_register_data);
+
+ // Move 2-bit mask and setting to cover the correct values
+ // Setting register is uint8_t broken into 4 2-bit setting sections:
+ // [LED3 Setting][LED2 Setting][LED1 Setting][LED0 Setting]
+ // --OR--
+ // [LED7 Setting][LED6 Setting][LED5 Setting][LED4 Setting]
+
+ const uint8_t match = 0x01; // shift values until l_led == match
+
+ // l_led must be >= match or following loop won't work
+ assert(l_led >= match, "gpioPca9551SetReigsterHelper: l_led %d is < match %d", l_led, match);
+
+ TRACUCOMP(g_trac_gpio,"gpioPca9551SetReigsterHelper: Pre-loop: "
+ "l_led=0x%.2X, match=0x%.2X",
+ l_led, match);
+ while ( match != l_led )
+ {
+ l_led = l_led >> PCA9551_LED_SHIFT_AMOUNT;
+ l_mask = l_mask << PCA9551_LED_SETTINGS_MASK_SHIFT_AMOUNT;
+ l_setting = l_setting << PCA9551_LED_SETTINGS_MASK_SHIFT_AMOUNT;
+ TRACUCOMP(g_trac_gpio,"gpioPca9551SetReigsterHelper: inside-loop: "
+ "l_led=0x%.2X, l_mask=0x%.2X, l_setting=0x%.2X",
+ l_led, l_mask, l_setting);
+ }
+ TRACUCOMP(g_trac_gpio, "gpioPca9551SetReigsterHelper: Post-loop: "
+ "l_mask=0x%.2X, l_setting=0x%.2X",
+ l_mask, l_setting);
+
+ // Apply Mask to Register data and then OR-in setting bits
+ io_led_register_data = (io_led_register_data & ~l_mask) | l_setting;
+ TRACUCOMP(g_trac_gpio, "gpioPca9551SetReigsterHelper: "
+ "io_led_register_data=0x%.2X",
+ io_led_register_data);
+
+ return;
+}
+
+
+errlHndl_t gpioPca9551GetLeds(TARGETING::Target * i_target,
+ uint8_t & o_led_data)
+{
+ errlHndl_t err = nullptr;
+
+ TRACUCOMP(g_trac_gpio, ENTER_MRK"gpioPca9551GetLeds: "
+ "i_target 0x%.08X",
+ get_huid(i_target));
+
+ do
+ {
+
+ // Read PCA9551 INPUT Register to get Pin (aka LED) Values
+ uint8_t data = 0;
+ size_t data_len = sizeof(data);
+ const size_t exp_data_len = data_len;
+ uint64_t device_type = PCA9551_GPIO_PHYS_PRES;
+ uint64_t register_addr = PCA9551_REGISTER_INPUT;
+
+ err = DeviceFW::deviceOp
+ ( DeviceFW::READ,
+ i_target,
+ &data,
+ data_len,
+ DEVICE_GPIO_ADDRESS(device_type, register_addr)
+ );
+ if(err)
+ {
+ TRACFCOMP(g_trac_gpio, ERR_MRK"gpioPca9551GetLeds: "
+ "Reading INPUT register failed");
+ break;
+ }
+ else
+ {
+ o_led_data = data;
+ TRACUCOMP(g_trac_gpio, INFO_MRK"gpioPca9551GetLeds: "
+ "register_addr=0x%X, o_led_data=0x%.2X",
+ register_addr, o_led_data);
+ }
+ assert(data_len==exp_data_len, "gpioPca9551GetLeds: expected %d size of data but got %d", exp_data_len, data_len);
+
+ } while (0);
+
+ if (err)
+ {
+ err->collectTrace( GPIO_COMP_NAME );
+ }
+
+ return err;
+}
+
+errlHndl_t gpioPca9551SetLed(TARGETING::Target * i_target,
+ const PCA9551_LEDS_t i_led,
+ const PCA9551_LED_Output_Settings_t i_setting,
+ uint8_t & o_led_data)
+{
+ errlHndl_t err = nullptr;
+
+ TRACUCOMP(g_trac_gpio, ENTER_MRK"gpioPca9551SetLed: "
+ "i_target 0x%.8X, i_led=0x%.2X, i_setting=0x%.2X",
+ get_huid(i_target), i_led, i_setting);
+
+ do
+ {
+ uint64_t deviceType = PCA9551_GPIO_PHYS_PRES;
+
+ // First Read Select Register - either LS0 (LEDs 0-3) or LS1 (LEDs 4-7)
+ uint64_t register_addr = PCA9551_REGISTER_LS0;
+ if (i_led > PCA9551_LED3)
+ {
+ register_addr = PCA9551_REGISTER_LS1;
+ }
+ uint8_t data = 0;
+ size_t data_len = sizeof(data);
+ const size_t exp_data_len = data_len;
+
+ err = DeviceFW::deviceOp
+ ( DeviceFW::READ,
+ i_target,
+ &data,
+ data_len,
+ DEVICE_GPIO_ADDRESS(deviceType, register_addr)
+ );
+ if(err)
+ {
+ TRACFCOMP(g_trac_gpio, ERR_MRK"gpioPca9551SetLed: "
+ "Reading LED Select register 0x%X failed",
+ register_addr);
+ break;
+ }
+ else
+ {
+ TRACUCOMP(g_trac_gpio, INFO_MRK"gpioPca9551SetLed: "
+ "LED Select register_addr=0x%X, data=0x%.2X",
+ register_addr, data);
+ }
+ assert(data_len==exp_data_len, "gpioPca9551SetLed: expected %d size of data but got %d", exp_data_len, data_len);
+
+
+ // Create Setting Register to Write Back:
+ uint8_t write_data = data;
+ gpioPca9551SetReigsterHelper(i_led, i_setting, write_data);
+
+ // Write LED Select Register
+ data = write_data;
+
+ err = DeviceFW::deviceOp
+ ( DeviceFW::WRITE,
+ i_target,
+ &data,
+ data_len,
+ DEVICE_GPIO_ADDRESS(deviceType, register_addr)
+ );
+ if(err)
+ {
+ TRACFCOMP(g_trac_gpio, ERR_MRK"gpioPca9551SetLed: "
+ "Writing LED Select register 0x%X failed",
+ register_addr);
+ break;
+ }
+ else
+ {
+ TRACUCOMP(g_trac_gpio, INFO_MRK"gpioPca9551SetLed: "
+ "Writing LED Select register_addr=0x%X, data=0x%.2X",
+ register_addr, data);
+ }
+ assert(data_len==exp_data_len, "gpioPca9551SetLed: expected %d size of data but got %d", exp_data_len, data_len);
+
+
+ // Read Back LED Select Register
+ data = 0;
+ err = DeviceFW::deviceOp
+ ( DeviceFW::READ,
+ i_target,
+ &data,
+ data_len,
+ DEVICE_GPIO_ADDRESS(deviceType, register_addr)
+ );
+ if(err)
+ {
+ TRACFCOMP(g_trac_gpio, ERR_MRK"gpioPca9551SetLed: "
+ "Reading LED Select register 0x%X failed",
+ register_addr);
+ break;
+ }
+ else
+ {
+ TRACUCOMP(g_trac_gpio, INFO_MRK"gpioPca9551SetLed: "
+ "LED Select register_addr=0x%X, data=0x%.2X",
+ register_addr, data);
+ }
+ assert(data_len==exp_data_len, "gpioPca9551SetLed: expected %d size of data but got %d", exp_data_len, data_len);
+
+ // Compare data written and data read back
+ if (data != write_data)
+ {
+ TRACFCOMP(g_trac_gpio, ERR_MRK"gpioPca9551SetLed: "
+ "Reading Back LED Select register 0x%X had unexpected data=",
+ "0x%.2X. Expected 0x%.2X",
+ register_addr, data, write_data);
+
+ /*@
+ * @errortype
+ * @reasoncode GPIO_PCA9551_DATA_MISMATCH
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid GPIO_PCA9551_SET_LED
+ * @userdata1[0:31] HUID of Master Processor Target
+ * @userdata1[32:63] Input LED to Set
+ * @userdata2[0:31] Expected Data (aka data written)
+ * @userdata2[32:63] Data Read Back
+ * @devdesc Setting of LED value did not appear to work
+ * @custdesc A problem occurred during the IPL
+ * of the system.
+ */
+ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ GPIO_PCA9551_SET_LED,
+ GPIO_PCA9551_DATA_MISMATCH,
+ TWO_UINT32_TO_UINT64(
+ get_huid(i_target),
+ i_led),
+ TWO_UINT32_TO_UINT64(
+ write_data,
+ data),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ break;
+ }
+
+ // Read PCA9551 INPUT Register to get Pin (aka LED) Values
+ data = 0;
+ data_len = sizeof(data);
+ register_addr = PCA9551_REGISTER_INPUT;
+
+ err = DeviceFW::deviceOp
+ ( DeviceFW::READ,
+ i_target,
+ &data,
+ data_len,
+ DEVICE_GPIO_ADDRESS(deviceType, register_addr)
+ );
+ if(err)
+ {
+ TRACFCOMP(g_trac_gpio, ERR_MRK"gpioPca9551SetLed: "
+ "Reading INPUT register failed");
+ break;
+ }
+ else
+ {
+ o_led_data = data;
+ TRACUCOMP(g_trac_gpio, INFO_MRK"gpioPca9551SetLed: "
+ "INPUT register_addr=0x%X, o_led_data=0x%.2X",
+ register_addr, o_led_data);
+ }
+ assert(data_len==exp_data_len, "gpioPca9551SetLed: expected %d size of data but got %d", exp_data_len, data_len);
+
+ } while (0);
+
+ if (err)
+ {
+ err->collectTrace( GPIO_COMP_NAME );
+ }
+
+ return err;
+
+}
+
+}; // end namespace GPIO
+
diff --git a/src/usr/gpio/gpiodd.C b/src/usr/gpio/gpiodd.C
index 559dab79e..50fa193c5 100644
--- a/src/usr/gpio/gpiodd.C
+++ b/src/usr/gpio/gpiodd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -34,6 +34,8 @@
#include <devicefw/driverif.H>
#include "gpiodd.H"
#include <gpio/gpioddreasoncodes.H>
+#include <gpio/gpioif.H>
+#include <config.h>
trace_desc_t * g_trac_gpio = NULL;
TRAC_INIT( & g_trac_gpio, GPIO_COMP_NAME, KILOBYTE );
@@ -57,6 +59,11 @@ DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
TARGETING::TYPE_MEMBUF,
gpioPerformOp);
+DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
+ DeviceFW::GPIO,
+ TARGETING::TYPE_PROC,
+ gpioPerformOp);
+
errlHndl_t gpioPerformOp(DeviceFW::OperationType i_opType,
TARGETING::Target * i_target,
void * io_buffer,
@@ -237,20 +244,51 @@ errlHndl_t gpioReadAttributes ( TARGETING::Target * i_target,
{
errlHndl_t err = NULL;
- TARGETING::GpioInfo gpioData;
-
bool attrReadErr = false;
+#ifndef CONFIG_FSP_BUILD
+ TARGETING::GpioInfo gpioData;
+#endif
+ TARGETING::GpioInfoPhysPres gpioDataPhysPres;
switch(io_gpioInfo.deviceType)
{
+#ifndef CONFIG_FSP_BUILD
case PCA95X_GPIO:
if( !( i_target->
tryGetAttr<TARGETING::ATTR_GPIO_INFO>( gpioData ) ) )
{
attrReadErr = true;
}
+ else
+ {
+ io_gpioInfo.i2cMasterPath = gpioData.i2cMasterPath;
+ io_gpioInfo.engine = gpioData.engine;
+ io_gpioInfo.i2cPort = gpioData.port;
+ io_gpioInfo.i2cDeviceAddr = gpioData.devAddr;
+ io_gpioInfo.i2cMuxBusSelector = gpioData.i2cMuxBusSelector;
+ io_gpioInfo.i2cMuxPath = gpioData.i2cMuxPath;
+ }
break;
+#endif
+ case PCA9551_GPIO_PHYS_PRES:
+
+ if( !( i_target->
+ tryGetAttr<TARGETING::ATTR_GPIO_INFO_PHYS_PRES>(gpioDataPhysPres)))
+ {
+ attrReadErr = true;
+ }
+ else
+ {
+ io_gpioInfo.i2cMasterPath = gpioDataPhysPres.i2cMasterPath;
+ io_gpioInfo.engine = gpioDataPhysPres.engine;
+ io_gpioInfo.i2cPort = gpioDataPhysPres.port;
+ io_gpioInfo.i2cDeviceAddr = gpioDataPhysPres.devAddr;
+ io_gpioInfo.i2cMuxBusSelector = gpioDataPhysPres.i2cMuxBusSelector;
+ io_gpioInfo.i2cMuxPath = gpioDataPhysPres.i2cMuxPath;
+ }
+ break;
+
default:
TRACFCOMP( g_trac_gpio,ERR_MRK"gpioReadAttributes() - "
@@ -309,16 +347,6 @@ errlHndl_t gpioReadAttributes ( TARGETING::Target * i_target,
err->collectTrace( GPIO_COMP_NAME );
}
- if( !err )
- {
- io_gpioInfo.i2cMasterPath = gpioData.i2cMasterPath;
- io_gpioInfo.engine = gpioData.engine;
- io_gpioInfo.i2cPort = gpioData.port;
- io_gpioInfo.i2cDeviceAddr = gpioData.devAddr;
- io_gpioInfo.i2cMuxBusSelector = gpioData.i2cMuxBusSelector;
- io_gpioInfo.i2cMuxPath = gpioData.i2cMuxPath;
- }
-
return err;
}
diff --git a/src/usr/gpio/makefile b/src/usr/gpio/makefile
index d40eaa130..fd42e2d1d 100644
--- a/src/usr/gpio/makefile
+++ b/src/usr/gpio/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2014
+# Contributors Listed Below - COPYRIGHT 2014,2019
# [+] Google Inc.
# [+] International Business Machines Corp.
#
@@ -27,6 +27,8 @@ ROOTPATH = ../../..
MODULE = gpio
OBJS += $(if $(CONFIG_GPIODD),gpiodd.o,)
+OBJS += $(if $(CONFIG_GPIODD),gpio_pca9551.o,)
+
# no way to test this at the moment TODO RTC 111415
#SUBDIRS = test.d
diff --git a/src/usr/hdat/hdatiohub.C b/src/usr/hdat/hdatiohub.C
index c2f5d7eea..c9be567ff 100644
--- a/src/usr/hdat/hdatiohub.C
+++ b/src/usr/hdat/hdatiohub.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -54,7 +54,6 @@ vpdData mvpdData[] =
{ PVPD::VINI, PVPD::B4 },
{ PVPD::VINI, PVPD::B7 },
{ PVPD::VINI, PVPD::PF },
- { PVPD::VINI, PVPD::LX },
};
const HdatKeywordInfo l_pvpdKeywords[] =
@@ -74,7 +73,18 @@ const HdatKeywordInfo l_pvpdKeywords[] =
{ PVPD::B4, "B4" },
{ PVPD::B7, "B7" },
{ PVPD::PF, "PF" },
- { PVPD::LX, "LX" },
+};
+
+vpdData pvpdDataAxone[] =
+{
+ { PVPD::OPFR, PVPD::VP },
+ { PVPD::OPFR, PVPD::VS },
+};
+
+const HdatKeywordInfo l_pvpdKeywordsAxone[] =
+{
+ { PVPD::VP, "VP" },
+ { PVPD::VS, "VS" },
};
extern trace_desc_t *g_trac_hdat;
@@ -653,13 +663,28 @@ errlHndl_t HdatIoHubFru::addDaughterCard(uint32_t i_resourceId,
// told to allow for on the constructor
if (iv_actDaughterCnt < iv_maxDaughters)
{
+ //Get the processor model
+ auto l_model = TARGETING::targetService().getProcessorModel();
+
if ( l_vpdType == FRU_BP )
{
-
- uint32_t i_num = sizeof(mvpdData)/sizeof(mvpdData[0]);
- l_vpdObj = new HdatVpd(l_errlHndl, i_resourceId,i_target,
- HDAT_KID_STRUCT_NAME,i_index,BP,
- mvpdData,i_num,l_pvpdKeywords);
+ //@TODO:RTC 213229(Remove HDAT hack or Axone)
+ //Check whether the code can be more fault tolerant by avoiding
+ //model check
+ if(l_model == TARGETING::MODEL_NIMBUS)
+ {
+ uint32_t i_num = sizeof(mvpdData)/sizeof(mvpdData[0]);
+ l_vpdObj = new HdatVpd(l_errlHndl, i_resourceId,i_target,
+ HDAT_KID_STRUCT_NAME,i_index,BP,
+ mvpdData,i_num,l_pvpdKeywords);
+ }
+ else if(l_model == TARGETING::MODEL_AXONE)
+ {
+ uint32_t i_num = sizeof(pvpdDataAxone)/sizeof(pvpdDataAxone[0]);
+ l_vpdObj = new HdatVpd(l_errlHndl, i_resourceId,i_target,
+ HDAT_KID_STRUCT_NAME,i_index,BP,
+ pvpdDataAxone,i_num,l_pvpdKeywordsAxone);
+ }
}
//@TODO: RTC 148660 pci slots and cards
@@ -900,6 +925,10 @@ errlHndl_t hdatLoadIoData(const hdatMsAddr_t &i_msAddr,
{
l_hub->hdatModuleId = HDAT_MODULE_TYPE_ID_NIMBUS_LAGRANGE;
}
+ else if(l_model == TARGETING::MODEL_AXONE)
+ {
+ l_hub->hdatModuleId = HDAT_MODULE_TYPE_ID_AXONE_HOPPER;
+ }
else if(l_model == TARGETING::MODEL_CUMULUS)
{
l_hub->hdatModuleId = HDAT_MODULE_TYPE_ID_CUMULUS_DUOMO;
diff --git a/src/usr/hdat/hdatiohub.H b/src/usr/hdat/hdatiohub.H
index 14c3a8524..9823c9146 100755
--- a/src/usr/hdat/hdatiohub.H
+++ b/src/usr/hdat/hdatiohub.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -273,6 +273,7 @@ enum hdatHubStatus
//@TODO:RTC 166789: Need to access the module type from HB targeting model
#define HDAT_MODULE_TYPE_ID_NIMBUS_LAGRANGE 0x0022
#define HDAT_MODULE_TYPE_ID_CUMULUS_DUOMO 0x0030
+#define HDAT_MODULE_TYPE_ID_AXONE_HOPPER 0x0040
diff --git a/src/usr/hdat/hdatiplparms.C b/src/usr/hdat/hdatiplparms.C
index a22dfbbe2..c0b24e49d 100755
--- a/src/usr/hdat/hdatiplparms.C
+++ b/src/usr/hdat/hdatiplparms.C
@@ -564,10 +564,7 @@ static void hdatGetFeatureFlagInfo(
l_ddLevel = l_pvr.getDDLevel();
// Default to Nimbus DD2.3
- uint8_t l_ddLvlIdx = 2;
- l_featFlagArr = hdatIplpFeatureFlagSettingsArray[l_riskLvl][l_ddLvlIdx];
- l_featFlagArrSize =
- sizeof(hdatIplpFeatureFlagSettingsArray[l_riskLvl][l_ddLvlIdx]);
+ uint8_t l_ddLvlIdx = HDAT_NIMBUS_DD_23_IDX;
// Set the value based on DD level and risk level
if (l_pvr.chipType == PVR_t::NIMBUS_CHIP)
@@ -586,12 +583,17 @@ static void hdatGetFeatureFlagInfo(
{
l_ddLvlIdx = HDAT_NIMBUS_DD_23_IDX;
}
-
- l_featFlagArr = hdatIplpFeatureFlagSettingsArray[l_riskLvl][l_ddLvlIdx];
- l_featFlagArrSize =
- sizeof(hdatIplpFeatureFlagSettingsArray[l_riskLvl][l_ddLvlIdx]);
}
-
+ else if (l_pvr.chipFamily == PVR_t::P9_AXONE)
+ {
+ // Axone follows the Nimbus DD2.3 settings
+ l_ddLvlIdx = HDAT_NIMBUS_DD_23_IDX;
+ }
+
+ l_featFlagArr = hdatIplpFeatureFlagSettingsArray[l_riskLvl][l_ddLvlIdx];
+ l_featFlagArrSize =
+ sizeof(hdatIplpFeatureFlagSettingsArray[l_riskLvl][l_ddLvlIdx]);
+
HDAT_DBG("Feature flag array size:0x%x, Model:0x%x, DD Level:0x%x "
"Risk Level:0x%x", l_featFlagArrSize, l_pvr.chipType,
l_ddLevel, l_riskLvl);
@@ -705,8 +707,16 @@ void HdatIplParms::hdatGetSystemParamters()
HDAT_ERR(" Error in getting attribute PAYLOAD_IN_MIRROR_MEM");
}
- this->iv_hdatIPLParams->iv_sysParms.hdatSystemAttributes |=
- l_pSysTarget->getAttr<ATTR_RISK_LEVEL>() ? HDAT_RISK_LEVEL_ELEVATED : 0 ;
+ // Check both compat and native mode for relevant risk levels
+ ATTR_RISK_LEVEL_type l_risk = l_pSysTarget->getAttr<ATTR_RISK_LEVEL>();
+ if( !((l_risk == UTIL::P9N22_P9C12_RUGBY_FAVOR_SECURITY)
+ || (l_risk == UTIL::P9N23_P9C13_NATIVE_SMF_RUGBY_FAVOR_SECURITY)) )
+ {
+ // running in a mode that doesn't favor security, set elevated risk
+ this->iv_hdatIPLParams->iv_sysParms.hdatSystemAttributes |=
+ HDAT_RISK_LEVEL_ELEVATED;
+ }
+
this->iv_hdatIPLParams->iv_sysParms.hdatSystemAttributes |=
l_pSysTarget->getAttr<ATTR_IS_MPIPL_SUPPORTED>() ? HDAT_MPIPL_SUPPORTED : 0 ;
diff --git a/src/usr/hdat/hdatiplparms.H b/src/usr/hdat/hdatiplparms.H
index 86eb4ad5f..7e7380e93 100755
--- a/src/usr/hdat/hdatiplparms.H
+++ b/src/usr/hdat/hdatiplparms.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -593,7 +593,7 @@ const hdatIplpFeatureFlagSetting_t hdatIplpFeatureFlagSettingsArray[NUM_RISK_LEV
#define HDAT_SMM_ENABLED 0x40000000
#define HDAT_CRYPTO_DISABLED_BIT 0x20000000
#define HDAT_RISK_LEVEL_ELEVATED 0x10000000
-#define HDAT_MPIPL_SUPPORTED 0x08000000
+#define HDAT_MPIPL_SUPPORTED 0x04000000
#define HDAT_ECO_ENABLED 0x80000000
#define HDAT_ECO_CAPABLE 0x40000000
diff --git a/src/usr/hdat/hdatmsarea.C b/src/usr/hdat/hdatmsarea.C
index 78c3633e8..336428644 100755
--- a/src/usr/hdat/hdatmsarea.C
+++ b/src/usr/hdat/hdatmsarea.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -309,7 +309,8 @@ errlHndl_t HdatMsArea::addAddrRange(hdatMsAddr_t &i_start,
bool i_rangeIsMirrorable,
uint8_t i_mirroringAlgorithm,
hdatMsAddr_t &i_startMirrAddr,
- uint32_t i_memcntlrId)
+ uint32_t i_memcntlrId,
+ bool i_hdatSmf)
{
HDAT_ENTER();
errlHndl_t l_errlHndl = NULL;
@@ -324,9 +325,10 @@ errlHndl_t HdatMsArea::addAddrRange(hdatMsAddr_t &i_start,
l_addr->hdatMsAreaStrAddr = i_start;
l_addr->hdatMsAreaEndAddr = i_end;
l_addr->hatMsAreaProcChipId = i_procChipId;
- l_addr->hdatSMMAttributes.hdatRangeIsMirrorable =
- i_rangeIsMirrorable ? 1 : 0;
+ l_addr->hdatSMMAttributes.hdatRangeIsMirrorable =
+ i_rangeIsMirrorable ? 1 : 0;
l_addr->hdatSMMAttributes.hdatMirroringAlgorithm = i_mirroringAlgorithm;
+ l_addr->hdatSMMAttributes.hdatIsSMFmemory = i_hdatSmf;
l_addr->hdatStartMirrAddr = i_startMirrAddr;
l_addr->hdatMsAreaMemCntId = i_memcntlrId;
iv_addrRngArrayHdr.hdatArrayCnt++;
@@ -343,7 +345,7 @@ errlHndl_t HdatMsArea::addAddrRange(hdatMsAddr_t &i_start,
* @userdata2 maximum number of array entries
* @userdata3 ID number of mainstore area
* @userdata4 none
- * @devdesc Failed trying to add another entry to a mainstore area
+ * @devdesc Failed trying to add another entry to a mainstore area
* address range array
*/
hdatBldErrLog(l_errlHndl,
diff --git a/src/usr/hdat/hdatmsarea.H b/src/usr/hdat/hdatmsarea.H
index f39ad3737..83236d134 100755
--- a/src/usr/hdat/hdatmsarea.H
+++ b/src/usr/hdat/hdatmsarea.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -51,7 +51,7 @@ namespace HDAT
/* Constants */
/*----------------------------------------------------------------------------*/
-const uint16_t HDAT_MS_AREA_VERSION = 0x30;
+const uint16_t HDAT_MS_AREA_VERSION = 0x50;
const char HDAT_MSAREA_STRUCT_NAME[] = "MSAREA";
/** @brief Since the size of each MS Area must the same as all others, the
@@ -119,10 +119,11 @@ struct hdatMsAreaSize_t
*/
struct hdatSMMAttributes_t
{
- uint8_t hdatRangeIsMirrorable; // 0x0000 Memory range is mirrorable
- uint8_t hdatMirroringAlgorithm; // 0x0001 Hardware mirroring algorithm to
+ uint8_t hdatRangeIsMirrorable; // 0x0000 Memory range is mirrorable
+ uint8_t hdatMirroringAlgorithm; // 0x0001 Hardware mirroring algorithm to
// use
- uint16_t hdatReserved; // 0x0002
+ uint8_t hdatIsSMFmemory; // 0x0002 SMF memory region
+ uint8_t hdatReserved; // 0x0003
} __attribute__ ((packed));
@@ -418,6 +419,7 @@ public:
* @param[in] i_startMirrAddr - Specifies the starting mirrorable
* address for range
* @param[in] i_memcntlrId - Memory Controller ID
+ * @param[in] i_hdatSmf - Whether the range is in SMF memory
*
* @return A null error log handle if successful, else the return code pointed
* to by o_errlHndl contains one of:
@@ -427,10 +429,11 @@ public:
errlHndl_t addAddrRange(hdatMsAddr_t &i_start,
hdatMsAddr_t &i_end,
uint32_t i_procChipId,
- bool i_rangeIsMirrorable,
- uint8_t i_mirroringAlgorithm,
- hdatMsAddr_t &i_startMirrAddr,
- uint32_t i_memcntlrId);
+ bool i_rangeIsMirrorable,
+ uint8_t i_mirroringAlgorithm,
+ hdatMsAddr_t &i_startMirrAddr,
+ uint32_t i_memcntlrId,
+ bool i_hdatSmf);
/**
diff --git a/src/usr/hdat/hdatmsvpd.C b/src/usr/hdat/hdatmsvpd.C
index e5593db3d..5b67903f7 100755
--- a/src/usr/hdat/hdatmsvpd.C
+++ b/src/usr/hdat/hdatmsvpd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -609,7 +609,8 @@ errlHndl_t HdatMsVpd::addMsAreaAddr(uint16_t i_msAreaId,
bool i_rangeIsMirrorable,
uint8_t i_mirroringAlgorithm,
uint64_t i_startMirrAddr,
- uint32_t i_hdatMemCntrlID)
+ uint32_t i_hdatMemCntrlID,
+ bool i_hdatSmf)
{
errlHndl_t l_errlHndl = NULL;
HdatMsArea *l_obj;
@@ -620,8 +621,14 @@ errlHndl_t HdatMsVpd::addMsAreaAddr(uint16_t i_msAreaId,
if (i_msAreaId < iv_actMsAreaCnt)
{
l_obj = HDAT_MS_AREA(i_msAreaId);
- l_errlHndl = l_obj->addAddrRange(i_start, i_end, i_procChipId,
- i_rangeIsMirrorable, i_mirroringAlgorithm, l_startMirrAddr, i_hdatMemCntrlID);
+ l_errlHndl = l_obj->addAddrRange(i_start,
+ i_end,
+ i_procChipId,
+ i_rangeIsMirrorable,
+ i_mirroringAlgorithm,
+ l_startMirrAddr,
+ i_hdatMemCntrlID,
+ i_hdatSmf);
}
else
{
@@ -926,6 +933,8 @@ void HdatMsVpd::prt()
iv_mover.hdatMoverAddr.lo);
HDAT_INF(" hdatBSRAddr = 0X %08X %08X ", iv_mover.hdatBSRAddr.hi,
iv_mover.hdatBSRAddr.lo);
+ HDAT_INF(" hdatXSCOMAddr = 0X %08X %08X", iv_mover.hdatXSCOMAddr.hi,
+ iv_mover.hdatXSCOMAddr.lo);
HDAT_INF(" **hdatMsVpdImtAddrRange_t**");
hdatPrintHdrs(NULL, NULL, &iv_IMTaddrRngArrayHdr, NULL);
@@ -1013,8 +1022,13 @@ errlHndl_t HdatMsVpd::hdatLoadMsData(uint32_t &o_size, uint32_t &o_count)
l_addr_range.lo = 0x0;
l_end = l_addr_range;
+ //Get the processor model
+ auto l_model = TARGETING::targetService().getProcessorModel();
+
uint32_t l_sizeConfigured = 0;
- uint64_t l_maxMsAddr = hdatGetMaxMemConfiguredAddress();
+
+ uint64_t l_maxMsAddr =
+ hdatGetMaxMemConfiguredAddress(l_model);
hdatMsAddr_t l_tmpMaxMsAddr;
l_tmpMaxMsAddr.hi = (l_maxMsAddr & 0xFFFFFFFF00000000ull) >> 32;
@@ -1037,10 +1051,19 @@ errlHndl_t HdatMsVpd::hdatLoadMsData(uint32_t &o_size, uint32_t &o_count)
TARGETING::ATTR_MAX_MCS_PER_SYSTEM_type l_maxMsAreas =
l_pSysTarget->getAttr<TARGETING::ATTR_MAX_MCS_PER_SYSTEM>();
+ if (l_model == TARGETING::MODEL_NIMBUS)
+ {
+ l_maxMsAreas *= 2;
+ }
+ else
+ {
+ l_maxMsAreas = HDAT_MAX_MSAREA_AXONE;
+ }
+
// Initialize the MS vpd class
// TODO : RTC Story 166994 to set the maximum number of Ms Area entries
// from new attribute
- hdatInit(l_tmpMaxMsAddr,l_tmpMaxMsAddr,l_sizeConfigured,l_maxMsAreas*2,
+ hdatInit(l_tmpMaxMsAddr,l_tmpMaxMsAddr,l_sizeConfigured,l_maxMsAreas,
l_mostSigAffinityDomain_x,l_ueCount,l_mirroringBaseAddress_x);
TARGETING::ATTR_XSCOM_BASE_ADDRESS_type l_xscomAddr =
@@ -1056,7 +1079,9 @@ errlHndl_t HdatMsVpd::hdatLoadMsData(uint32_t &o_size, uint32_t &o_count)
setXSCOM(l_hdatXscomAddr);
}
+ // This contains the MS Area Index
uint32_t l_index = 0;
+
//for each proc/ memory controller in the system
TARGETING::PredicateCTM l_procPred(TARGETING::CLASS_CHIP,
TARGETING::TYPE_PROC);
@@ -1076,77 +1101,12 @@ errlHndl_t HdatMsVpd::hdatLoadMsData(uint32_t &o_size, uint32_t &o_count)
for(;l_procs;++l_procs)
{
+ bool l_smfAdded = false;
+
TARGETING::Target *l_pProcTarget = *(l_procs);
TARGETING::ATTR_ORDINAL_ID_type l_procChipId
= l_pProcTarget->getAttr<TARGETING::ATTR_ORDINAL_ID>();
-
- //For each MCA
- TARGETING::PredicateCTM l_allMca(TARGETING::CLASS_UNIT,
- TARGETING::TYPE_MCA);
- TARGETING::PredicateHwas l_funcMca;
- l_funcMca.functional(true);
- TARGETING::PredicatePostfixExpr l_allFuncMca;
- l_allFuncMca.push(&l_allMca).push(&l_funcMca).And();
-
- TARGETING::TargetHandleList l_mcaList;
-
- TARGETING::targetService().
- getAssociated(l_mcaList, l_pProcTarget,
- TARGETING::TargetService::CHILD,
- TARGETING::TargetService::ALL, &l_allFuncMca);
-
- TARGETING::ATTR_PROC_MEM_BASES_type l_procMemBases = {0};
- assert(l_pProcTarget->
- tryGetAttr<TARGETING::ATTR_PROC_MEM_BASES>(l_procMemBases));
-
- //Sharing count for each group
- TARGETING::ATTR_MSS_MEM_MC_IN_GROUP_type l_mcaSharingCount = {0};
-
- //Group ID for each group, group id will be assigned only
- //if the group is shared
- TARGETING::ATTR_MSS_MEM_MC_IN_GROUP_type l_mcsSharingGrpIds = {0};
-
- //Size configured under each group
- TARGETING::ATTR_PROC_MEM_SIZES_type l_procMemSizesBytes = {0};
-
- assert(l_pProcTarget->tryGetAttr<TARGETING::ATTR_PROC_MEM_SIZES>
- (l_procMemSizesBytes));
-
-
-
- for(uint32_t l_mcaIdx = 0; l_mcaIdx<l_mcaList.size();
- ++l_mcaIdx)
- {
- uint32_t l_mcaInGrp = 0;
- TARGETING::Target *l_pMcaTarget =
- l_mcaList[l_mcaIdx];
- if(!hdatFindGroupForMc(l_pProcTarget,
- l_pMcaTarget,
- l_mcaInGrp))
- {
- //Skip this MCA is not in any group
- continue;
- }
-
- //Increment sharing count if mem configured under group.
- if(l_procMemSizesBytes[l_mcaInGrp] > 0)
- {
- l_mcaSharingCount[l_mcaInGrp]++;
-
- //Assign sharing group id only if shared
- //And only when first instance of sharing is found
- if(l_mcaSharingCount[l_mcaInGrp] ==
- HDAT_MIN_NUM_FOR_SHARING)
- {
- l_mcsSharingGrpIds[l_mcaInGrp] =
- l_nxtSharingGroupId;
- l_nxtSharingGroupId++;
- }
- }
- }
-
-
// TODO : RTC Story 159682
// Further CHTM support needs to be added which contains the trace
// array for 24 cores
@@ -1154,14 +1114,14 @@ errlHndl_t HdatMsVpd::hdatLoadMsData(uint32_t &o_size, uint32_t &o_count)
hdatMsAddr_t l_hdatNhtmEndAddr;
TARGETING::ATTR_PROC_NHTM_BAR_BASE_ADDR_type l_nhtmStartAddr =
- l_pProcTarget->getAttr<TARGETING::ATTR_PROC_NHTM_BAR_BASE_ADDR>();
+ l_pProcTarget->getAttr<TARGETING::ATTR_PROC_NHTM_BAR_BASE_ADDR>();
TARGETING::ATTR_PROC_NHTM_BAR_SIZE_type l_nhtmSize =
l_pProcTarget->getAttr<TARGETING::ATTR_PROC_NHTM_BAR_SIZE>();
if( 0 != l_nhtmSize )
{
l_hdatNhtmStartAddr.hi =
- (l_nhtmStartAddr & 0xFFFFFFFF00000000ull) >> 32;
+ (l_nhtmStartAddr & 0xFFFFFFFF00000000ull) >> 32;
l_hdatNhtmStartAddr.lo =
l_nhtmStartAddr & 0x00000000FFFFFFFFull;
l_hdatNhtmStartAddr.hi |= HDAT_REAL_ADDRESS_MASK;
@@ -1185,433 +1145,1236 @@ errlHndl_t HdatMsVpd::hdatLoadMsData(uint32_t &o_size, uint32_t &o_count)
l_nhtmSize);
}
+ TARGETING::ATTR_PROC_MEM_BASES_type l_procMemBases = {0};
+ assert(l_pProcTarget->
+ tryGetAttr<TARGETING::ATTR_PROC_MEM_BASES>(l_procMemBases));
+
+ TARGETING::ATTR_PROC_MIRROR_BASES_type l_MirrorAddr = {0};
+ assert(l_pProcTarget->tryGetAttr<
+ TARGETING::ATTR_PROC_MIRROR_BASES>(l_MirrorAddr));
+
+ TARGETING::ATTR_PROC_MIRROR_SIZES_type l_MirrorSize = {0};
+ assert(l_pProcTarget->tryGetAttr<
+ TARGETING::ATTR_PROC_MIRROR_SIZES>(l_MirrorSize));
- TARGETING::PredicateCTM l_mcbistPredicate(TARGETING::CLASS_UNIT,
+ TARGETING::ATTR_PAYLOAD_IN_MIRROR_MEM_type l_payLoadMirrorMem =
+ l_pSysTarget->getAttr<TARGETING::ATTR_PAYLOAD_IN_MIRROR_MEM>();
+
+ if(l_model == TARGETING::MODEL_NIMBUS)
+ {
+ //Sharing count for each group
+ TARGETING::ATTR_MSS_MEM_MC_IN_GROUP_type l_mcaSharingCount
+ = {0};
+
+ //Group ID for each group, group id will be assigned only
+ //if the group is shared
+ TARGETING::ATTR_MSS_MEM_MC_IN_GROUP_type l_mcsSharingGrpIds
+ = {0};
+
+ //Size configured under each group
+ TARGETING::ATTR_PROC_MEM_SIZES_type l_procMemSizesBytes = {0};
+
+ assert(l_pProcTarget->tryGetAttr<TARGETING::ATTR_PROC_MEM_SIZES>
+ (l_procMemSizesBytes));
+
+ //For each MCA
+ TARGETING::PredicateCTM l_allMca(TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MCA);
+ TARGETING::PredicateHwas l_funcMca;
+ l_funcMca.functional(true);
+ TARGETING::PredicatePostfixExpr l_allFuncMca;
+ l_allFuncMca.push(&l_allMca).push(&l_funcMca).And();
+
+ TARGETING::TargetHandleList l_mcaList;
+
+ TARGETING::targetService().
+ getAssociated(l_mcaList, l_pProcTarget,
+ TARGETING::TargetService::CHILD,
+ TARGETING::TargetService::ALL, &l_allFuncMca);
+
+ for(uint32_t l_mcaIdx = 0; l_mcaIdx<l_mcaList.size();
+ ++l_mcaIdx)
+ {
+ uint32_t l_mcaInGrp = 0;
+ TARGETING::Target *l_pMcaTarget =
+ l_mcaList[l_mcaIdx];
+ if(!hdatFindGroupForMc(l_pProcTarget,
+ l_pMcaTarget,
+ l_mcaInGrp))
+ {
+ //Skip this MCA is not in any group
+ continue;
+ }
+
+ //Increment sharing count if mem configured under group.
+ if(l_procMemSizesBytes[l_mcaInGrp] > 0)
+ {
+ l_mcaSharingCount[l_mcaInGrp]++;
+
+ //Assign sharing group id only if shared
+ //And only when first instance of sharing is found
+ if(l_mcaSharingCount[l_mcaInGrp] ==
+ HDAT_MIN_NUM_FOR_SHARING)
+ {
+ l_mcsSharingGrpIds[l_mcaInGrp] =
+ l_nxtSharingGroupId;
+ l_nxtSharingGroupId++;
+ }
+ }
+ }
+
+ TARGETING::PredicateCTM l_mcbistPredicate(TARGETING::CLASS_UNIT,
TARGETING::TYPE_MCBIST);
- TARGETING::PredicatePostfixExpr l_presentMcbist;
+ TARGETING::PredicatePostfixExpr l_presentMcbist;
l_presentMcbist.push(&l_mcbistPredicate).
push(&l_predHwasFunc).And();
- TARGETING::TargetHandleList l_mcbistList;
+ TARGETING::TargetHandleList l_mcbistList;
- // Find Associated MCBIST list
- TARGETING::targetService().getAssociated(l_mcbistList,
+ // Find Associated MCBIST list
+ TARGETING::targetService().getAssociated(l_mcbistList,
l_pProcTarget,
TARGETING::TargetService::CHILD_BY_AFFINITY,
TARGETING::TargetService::ALL,
&l_presentMcbist);
- //scan all mcbist in this proc
- for(uint32_t l_mcbistIdx =0;
- l_mcbistIdx < l_mcbistList.size();
- ++l_mcbistIdx)
- {
- TARGETING::Target *l_pMcbistTarget = l_mcbistList[l_mcbistIdx];
-
- TARGETING::PredicateCTM l_mcsPredicate(TARGETING::CLASS_UNIT,
- TARGETING::TYPE_MCS);
+ //scan all mcbist in this proc
+ for(uint32_t l_mcbistIdx =0;
+ l_mcbistIdx < l_mcbistList.size();
+ ++l_mcbistIdx)
+ {
+ TARGETING::Target *l_pMcbistTarget =
+ l_mcbistList[l_mcbistIdx];
+
+ TARGETING::PredicateCTM l_mcsPredicate(
+ TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MCS);
- TARGETING::PredicatePostfixExpr l_funcMcs;
+ TARGETING::PredicatePostfixExpr l_funcMcs;
l_funcMcs.push(&l_mcsPredicate).push(&l_predHwasFunc).And();
- TARGETING::TargetHandleList l_mcsList;
+ TARGETING::TargetHandleList l_mcsList;
- // Find Associated memory controllers
- TARGETING::targetService().getAssociated(l_mcsList,
+ // Find Associated memory controllers
+ TARGETING::targetService().getAssociated(l_mcsList,
l_pMcbistTarget,
TARGETING::TargetService::CHILD,
TARGETING::TargetService::ALL,
&l_funcMcs);
- uint32_t l_memBusFreq = getMemBusFreq(l_pMcbistTarget);
+ uint32_t l_memBusFreq = getMemBusFreq(l_pMcbistTarget);
- //scan all mcs in this proc to get sharing counit
- for(uint32_t l_mcsIdx = 0;l_mcsIdx<l_mcsList.size(); ++l_mcsIdx)
- {
- TARGETING::Target *l_pMcsTarget = l_mcsList[l_mcsIdx];
+ //scan all mcs in this proc to get sharing counit
+ for(uint32_t l_mcsIdx = 0;l_mcsIdx<l_mcsList.size();
+ ++l_mcsIdx)
+ {
+ TARGETING::Target *l_pMcsTarget = l_mcsList[l_mcsIdx];
- //for each MCA connected to this this MCS
- TARGETING::PredicateCTM l_mcaPredicate(
- TARGETING::CLASS_UNIT, TARGETING::TYPE_MCA);
+ //for each MCA connected to this this MCS
+ TARGETING::PredicateCTM l_mcaPredicate(
+ TARGETING::CLASS_UNIT, TARGETING::TYPE_MCA);
- TARGETING::PredicateHwas l_predMca;
- l_predMca.present(true);
- TARGETING::PredicatePostfixExpr l_presentMca;
- l_presentMca.push(&l_mcaPredicate).push(&l_predMca).And();
- TARGETING::TargetHandleList l_mcaList;
+ TARGETING::PredicateHwas l_predMca;
+ l_predMca.present(true);
+ TARGETING::PredicatePostfixExpr l_presentMca;
+ l_presentMca.push(&l_mcaPredicate).
+ push(&l_predMca).And();
+ TARGETING::TargetHandleList l_mcaList;
- // Get associated MCAs
- TARGETING::targetService().
- getAssociated(l_mcaList, l_pMcsTarget,
- TARGETING::TargetService::CHILD_BY_AFFINITY,
- TARGETING::TargetService::ALL, &l_presentMca);
+ // Get associated MCAs
+ TARGETING::targetService().
+ getAssociated(l_mcaList, l_pMcsTarget,
+ TARGETING::TargetService::CHILD_BY_AFFINITY,
+ TARGETING::TargetService::ALL, &l_presentMca);
- for(uint32_t l_mcaIdx = 0; l_mcaIdx<l_mcaList.size();
- ++l_mcaIdx)
- {
- TARGETING::Target *l_pMcaTarget =
- l_mcaList[l_mcaIdx];
+ for(uint32_t l_mcaIdx = 0; l_mcaIdx<l_mcaList.size();
+ ++l_mcaIdx)
+ {
+ TARGETING::Target *l_pMcaTarget =
+ l_mcaList[l_mcaIdx];
- //Group which this MCA is belonging
- uint32_t l_mcaInGrp = 0;
+ //Group which this MCA is belonging
+ uint32_t l_mcaInGrp = 0;
- if(!hdatFindGroupForMc(l_pProcTarget,
- l_pMcaTarget,
- l_mcaInGrp))
- {
- HDAT_INF("No group found for MCA");
- //Skip this MCS is not under any group
- continue;
- }
- uint32_t l_mcaFruId = 0;
- hdatMemParentType l_parentType= HDAT_MEM_PARENT_CEC_FRU;
-
- std::list<hdatRamArea> l_areas;
- l_areas.clear();
- uint32_t l_areaSizeInMB = 0;
- bool l_areaFunctional = false;
- uint32_t l_numDimms =0;
-
- l_err = hdatScanDimms(l_pMcaTarget,
- l_pMcsTarget,
- l_mcaFruId,
- l_areas,
- l_areaSizeInMB,
- l_numDimms,
- l_areaFunctional,
- l_parentType);
-
- if(NULL != l_err)
- {
- HDAT_ERR("Error in calling Scan Dimms");
- break;
- }
+ if(!hdatFindGroupForMc(l_pProcTarget,
+ l_pMcaTarget,
+ l_mcaInGrp))
+ {
+ HDAT_INF("No group found for MCA");
+ //Skip this MCS is not under any group
+ continue;
+ }
+ uint32_t l_mcaFruId = 0;
+ hdatMemParentType l_parentType =
+ HDAT_MEM_PARENT_CEC_FRU;
+
+ std::list<hdatRamArea> l_areas;
+ l_areas.clear();
+ uint32_t l_areaSizeInMB = 0;
+ bool l_areaFunctional = false;
+ uint32_t l_numDimms =0;
+
+ l_err = hdatScanDimms(l_pMcaTarget,
+ l_pMcsTarget,
+ l_mcaFruId,
+ l_areas,
+ l_areaSizeInMB,
+ l_numDimms,
+ l_areaFunctional,
+ l_parentType);
+
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in calling Scan Dimms");
+ break;
+ }
- HDAT_INF("l_areaSizeInMB:0x%.8X l_numDimms:0x%.8X "
- "l_areas.size():0x%.8X", l_areaSizeInMB, l_numDimms,
- l_areas.size());
+ HDAT_INF("l_areaSizeInMB:0x%.8X l_numDimms:0x%.8X "
+ "l_areas.size():0x%.8X", l_areaSizeInMB,
+ l_numDimms, l_areas.size());
- //Skip if no memory configured under this MCS
- if(l_areaSizeInMB == 0)
- {
- continue;
- }
+ //Skip if no memory configured under this MCS
+ if(l_areaSizeInMB == 0)
+ {
+ continue;
+ }
- uint32_t l_maxMemBlocks = 0;
- l_err =
+ uint32_t l_maxMemBlocks = 0;
+ l_err =
hdatGetMaxMemoryBlocks(l_pMcsTarget,l_maxMemBlocks);
- if(NULL != l_err)
- {
- HDAT_ERR("Error error in get max blocks");
- break;
- }
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error error in get max blocks");
+ break;
+ }
- TARGETING::ATTR_SLCA_RID_type l_procRid =
+ TARGETING::ATTR_SLCA_RID_type l_procRid =
l_pProcTarget->getAttr<TARGETING::ATTR_SLCA_RID>();
- TARGETING::ATTR_SLCA_INDEX_type l_procSlcaIndex =
- l_pProcTarget->getAttr<TARGETING::ATTR_SLCA_INDEX>();
-
+ TARGETING::ATTR_SLCA_INDEX_type l_procSlcaIndex =
+ l_pProcTarget->getAttr
+ <TARGETING::ATTR_SLCA_INDEX>();
- l_err = addMsAreaFru(l_procRid,
- l_procSlcaIndex,
- l_pProcTarget,
- l_index,
- l_numDimms,
- MAX_CHIP_EC_CNT_PER_MSAREA,
- l_maxMemBlocks);
+ l_err = addMsAreaFru(l_procRid,
+ l_procSlcaIndex,
+ l_pProcTarget,
+ l_index,
+ l_numDimms,
+ MAX_CHIP_EC_CNT_PER_MSAREA,
+ l_maxMemBlocks);
- if(NULL != l_err)
- {
- HDAT_ERR("Error adding MSArea %d"
- "Number of Dimms: %d Max Blocks: %d",
- l_index,
- l_numDimms,l_maxMemBlocks);
- break;
- }
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error adding MSArea %d"
+ "Number of Dimms: %d Max Blocks: %d",
+ l_index,
+ l_numDimms,l_maxMemBlocks);
+ break;
+ }
- uint32_t l_memStatus = 0;
- //If group is shared with more than one area
- if(l_mcaSharingCount[l_mcaInGrp] >=
- HDAT_MIN_NUM_FOR_SHARING)
- {
- l_memStatus = HDAT_MEM_SHARED;
- setMsAreaInterleavedId(l_index,
- l_mcsSharingGrpIds[l_mcaInGrp]);
- }
+ uint32_t l_memStatus = 0;
+ //If group is shared with more than one area
+ if(l_mcaSharingCount[l_mcaInGrp] >=
+ HDAT_MIN_NUM_FOR_SHARING)
+ {
+ l_memStatus = HDAT_MEM_SHARED;
+ setMsAreaInterleavedId(l_index,
+ l_mcsSharingGrpIds[l_mcaInGrp]);
+ }
- setMsAreaType(l_index,l_parentType);
- setMsAreaSize(l_index,l_areaSizeInMB);
+ setMsAreaType(l_index,l_parentType);
+ setMsAreaSize(l_index,l_areaSizeInMB);
- iv_maxSize.hdatTotSize += l_areaSizeInMB;
+ iv_maxSize.hdatTotSize += l_areaSizeInMB;
- l_memStatus |= l_areaFunctional ?
- (HDAT_MEM_INSTALLED | HDAT_MEM_FUNCTIONAL) :
- HDAT_MEM_INSTALLED;
+ l_memStatus |= l_areaFunctional ?
+ (HDAT_MEM_INSTALLED | HDAT_MEM_FUNCTIONAL) :
+ HDAT_MEM_INSTALLED;
- setMsAreaStat(l_index, l_memStatus);
+ setMsAreaStat(l_index, l_memStatus);
- //Add MCS ec level
- uint32_t l_mcsEcLevel = 0;
- uint32_t l_mcsChipId = 0;
- l_err = hdatGetIdEc(l_pMcsTarget,
- l_mcsEcLevel,
- l_mcsChipId);
- if(NULL != l_err)
- {
- HDAT_ERR("Error in getting MCS ID "
+ //Add MCS ec level
+ uint32_t l_mcsEcLevel = 0;
+ uint32_t l_mcsChipId = 0;
+ l_err = hdatGetIdEc(l_pMcsTarget,
+ l_mcsEcLevel,
+ l_mcsChipId);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in getting MCS ID "
"and EC HUID:[0x%08X]",
l_pMcsTarget->getAttr<TARGETING::ATTR_HUID>());
- break;
- }
+ break;
+ }
- l_err = addEcEntry(l_index,
- l_mcsChipId,
- l_mcsEcLevel);
- if(NULL != l_err)
- {
- HDAT_ERR("Error in adding"
+ l_err = addEcEntry(l_index,
+ l_mcsChipId,
+ l_mcsEcLevel);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in adding"
" ID[0x%08X] and EC[0x%08X] to ms area"
" HUID:[0x%08X]",l_mcsChipId,
l_mcsEcLevel,
l_pMcsTarget->getAttr<TARGETING::ATTR_HUID>());
- break;
- }
+ break;
+ }
- // Need to get i2c Master data correctly
- std::vector<hdatI2cData_t> l_i2cDevEntries;
+ // Need to get i2c Master data correctly
+ std::vector<hdatI2cData_t> l_i2cDevEntries;
- TARGETING::PredicateCTM l_membufPredicate(
- TARGETING::CLASS_CHIP, TARGETING::TYPE_MEMBUF);
+ TARGETING::PredicateCTM l_membufPredicate(
+ TARGETING::CLASS_CHIP, TARGETING::TYPE_MEMBUF);
- TARGETING::PredicatePostfixExpr l_presentMemBuf;
- l_presentMemBuf.push(&l_membufPredicate).
+ TARGETING::PredicatePostfixExpr l_presentMemBuf;
+ l_presentMemBuf.push(&l_membufPredicate).
push(&l_predHwasPresent).And();
- TARGETING::TargetHandleList l_membufList;
+ TARGETING::TargetHandleList l_membufList;
- // Find Associated membuf
- TARGETING::targetService().getAssociated(l_membufList,
- l_pMcsTarget,
- TARGETING::TargetService::CHILD_BY_AFFINITY,
- TARGETING::TargetService::ALL,
- &l_presentMemBuf);
- //Skip is there is no Membuf attached to this MCS
- if(l_membufList.size() > 0)
- {
- TARGETING::Target *l_pMembufTarget =
- l_membufList[0];
- if (l_pMembufTarget != NULL)
+ // Find Associated membuf
+ TARGETING::targetService().getAssociated(
+ l_membufList,
+ l_pMcsTarget,
+ TARGETING::TargetService::CHILD_BY_AFFINITY,
+ TARGETING::TargetService::ALL,
+ &l_presentMemBuf);
+ //Skip is there is no Membuf attached to this MCS
+ if(l_membufList.size() > 0)
{
- hdatGetI2cDeviceInfo(l_pMembufTarget,
- l_i2cDevEntries);
+ TARGETING::Target *l_pMembufTarget =
+ l_membufList[0];
+ if (l_pMembufTarget != NULL)
+ {
+ hdatGetI2cDeviceInfo(l_pMembufTarget,
+ l_model,
+ l_i2cDevEntries);
+ }
}
- }
- setMsaI2cInfo(l_index, l_i2cDevEntries);
+ setMsaI2cInfo(l_index, l_i2cDevEntries);
- std::list<hdatRamArea>::iterator l_area =
- l_areas.begin();
+ std::list<hdatRamArea>::iterator l_area =
+ l_areas.begin();
- for (uint32_t l_ramId = 0;
- l_area != l_areas.end();
- ++l_ramId, ++l_area)
- {
- uint32_t l_status = (l_area)->ivFunctional ?
+ for (uint32_t l_ramId = 0;
+ l_area != l_areas.end();
+ ++l_ramId, ++l_area)
+ {
+ uint32_t l_status = (l_area)->ivFunctional ?
(HDAT_RAM_INSTALLED | HDAT_RAM_FUNCTIONAL)
: HDAT_RAM_INSTALLED;
- TARGETING::Target *l_pDimmTarget =
- TARGETING::Target::getTargetFromHuid(l_area->ivHuid);
-
- TARGETING::ATTR_SLCA_RID_type l_dimmRid =
- l_pDimmTarget->getAttr<TARGETING::ATTR_SLCA_RID>();
-
- TARGETING::ATTR_SLCA_INDEX_type l_dimmSlcaIndex =
- l_pDimmTarget->getAttr<TARGETING::ATTR_SLCA_INDEX>();
-
- uint32_t l_dimmId =
- 1 << (31 - (l_pDimmTarget->getAttr<TARGETING::ATTR_FAPI_POS>() % MAX_DIMMS_PER_MCBIST));
- l_err = addRamFru(l_index,
- l_pDimmTarget,
- l_dimmRid,
- l_dimmSlcaIndex,
- l_ramId,
- l_status,
- (l_area)->ivSize,
- l_dimmId,
- l_memBusFreq);
-
- if (l_err) // Failed to add ram fru information
- {
- HDAT_ERR("Error in adding RAM FRU"
- "Index:%d Rid:[0x%08X] status:[0x%08X]"
- "Size:[0x%08X] RamID:[0x%08X]",
- l_index,(l_area)->ivHuid,
- l_status,(l_area)->ivSize,l_ramId);
- ERRORLOG::errlCommit(l_err,HDAT_COMP_ID);
-
- delete l_err;
- l_err = NULL;
- continue;
- }
- }//end of RAM list
+ TARGETING::Target *l_pDimmTarget =
+ TARGETING::Target::getTargetFromHuid(
+ l_area->ivHuid);
+
+ TARGETING::ATTR_SLCA_RID_type l_dimmRid =
+ l_pDimmTarget->getAttr
+ <TARGETING::ATTR_SLCA_RID>();
+
+ TARGETING::ATTR_SLCA_INDEX_type l_dimmSlcaIndex=
+ l_pDimmTarget->getAttr
+ <TARGETING::ATTR_SLCA_INDEX>();
+
+ uint32_t l_dimmId =
+ 1 << (31 - (l_pDimmTarget->getAttr
+ <TARGETING::ATTR_FAPI_POS>() %
+ MAX_DIMMS_PER_MCBIST));
+ l_err = addRamFru(l_index,
+ l_pDimmTarget,
+ l_dimmRid,
+ l_dimmSlcaIndex,
+ l_ramId,
+ l_status,
+ (l_area)->ivSize,
+ l_dimmId,
+ l_memBusFreq);
+
+ if (l_err) // Failed to add ram fru information
+ {
+ HDAT_ERR("Error in adding RAM FRU"
+ "Index:%d Rid:[0x%08X] status:[0x%08X]"
+ "Size:[0x%08X] RamID:[0x%08X]",
+ l_index,(l_area)->ivHuid,
+ l_status,(l_area)->ivSize,l_ramId);
+ ERRORLOG::errlCommit(l_err,HDAT_COMP_ID);
+
+ delete l_err;
+ l_err = NULL;
+ continue;
+ }
+ }//end of RAM list
- l_addr_range.hi = (l_procMemBases[l_mcaInGrp] &
+ l_addr_range.hi = (l_procMemBases[l_mcaInGrp] &
0xFFFFFFFF00000000ull) >> 32;
- l_addr_range.lo = l_procMemBases[l_mcaInGrp] &
+ l_addr_range.lo = l_procMemBases[l_mcaInGrp] &
0x00000000FFFFFFFFull;
- l_end = l_addr_range;
+ l_end = l_addr_range;
- //Update the range
- l_end.hi += (l_procMemSizesBytes[l_mcaInGrp] &
+ //Update the range
+ l_end.hi += (l_procMemSizesBytes[l_mcaInGrp] &
0xFFFFFFFF00000000ull) >> 32;
- l_end.lo += l_procMemSizesBytes[l_mcaInGrp] &
+ l_end.lo += l_procMemSizesBytes[l_mcaInGrp] &
0x00000000FFFFFFFFull;
- HDAT_INF("MCS:0x%08X l_addr_range:0x%08X 0x%08X"
- " l_end:0x%08X 0x%08X",
- l_pMcsTarget->getAttr<TARGETING::ATTR_HUID>(),
- l_addr_range.hi, l_addr_range.lo,
- l_end.hi,l_end.lo);
-
- uint64_t l_hdatMirrorAddr_x = 0x0ull;
- uint64_t l_hdatMirrorAddr = 0x0ull;
- uint32_t l_hdatMemcntrlID = 0x0 ;
- uint8_t l_hdatMirrorAlogrithm = 0xFF;
- bool l_rangeIsMirrorable = false;
-
- TARGETING::ATTR_PROC_MIRROR_BASES_type
- l_MirrorAddr = {0};
- assert(l_pProcTarget->tryGetAttr<
- TARGETING::ATTR_PROC_MIRROR_BASES>(l_MirrorAddr));
-
- TARGETING::ATTR_PROC_MIRROR_SIZES_type
- l_MirrorSize = {0};
- assert(l_pProcTarget->tryGetAttr<
- TARGETING::ATTR_PROC_MIRROR_SIZES>(l_MirrorSize));
-
- uint64_t l_startAddr =
+ HDAT_INF("MCS:0x%08X l_addr_range:0x%08X 0x%08X"
+ " l_end:0x%08X 0x%08X",
+ l_pMcsTarget->getAttr<TARGETING::ATTR_HUID>(),
+ l_addr_range.hi, l_addr_range.lo,
+ l_end.hi,l_end.lo);
+
+ uint64_t l_hdatMirrorAddr_x = 0x0ull;
+ uint64_t l_hdatMirrorAddr = 0x0ull;
+ uint32_t l_hdatMemcntrlID = 0x0 ;
+ uint8_t l_hdatMirrorAlogrithm = 0xFF;
+ bool l_rangeIsMirrorable = false;
+
+ //Calculate the mirror address and related data
+ uint64_t l_startAddr =
(((uint64_t)(l_addr_range.hi) << 32 )
| (uint64_t)(l_addr_range.lo));
- l_hdatMirrorAddr_x =
- (l_startAddr / 2) + l_mirrorBaseAddress_x;
-
- TARGETING::ATTR_PAYLOAD_IN_MIRROR_MEM_type
- l_payLoadMirrorMem =
- l_pSysTarget->getAttr<
- TARGETING::ATTR_PAYLOAD_IN_MIRROR_MEM>();
+ l_hdatMirrorAddr_x =
+ (l_startAddr / 2) + l_mirrorBaseAddress_x;
- HDAT_INF(
- "Start add : 0x%016llX MirrorBase : 0x%016llX"
- " MirrorAddr : 0x%016llX PayLoadMirrorMem : 0x%X",
- l_startAddr, l_mirrorBaseAddress_x,
- l_hdatMirrorAddr_x, l_payLoadMirrorMem);
+ HDAT_INF(
+ "Start add : 0x%016llX MirrorBase : 0x%016llX"
+ " MirrorAddr : 0x%016llX PayLoadMirrorMem : 0x%X",
+ l_startAddr, l_mirrorBaseAddress_x,
+ l_hdatMirrorAddr_x, l_payLoadMirrorMem);
- if ( 0 != l_payLoadMirrorMem )
- {
- for ( int idx=0 ; idx <
- (int)(sizeof(TARGETING::ATTR_PROC_MIRROR_SIZES_type)
- / sizeof(uint64_t)) ; idx++ )
+ if ( 0 != l_payLoadMirrorMem )
{
- HDAT_INF("Mirror size : 0x%016llX"
- " MirrorAddr[idx] : 0x%016llX"
- " hdatMirrorAddr_x : 0x%016llX",
- l_MirrorSize[idx], l_MirrorAddr[idx],
- l_hdatMirrorAddr_x);
+ for ( int idx=0 ; idx <
+ (int)
+ (sizeof(TARGETING::ATTR_PROC_MIRROR_SIZES_type)
+ / sizeof(uint64_t)) ; idx++ )
+ {
+ HDAT_INF("Mirror size : 0x%016llX"
+ " MirrorAddr : 0x%016llX"
+ " hdatMirrorAddr_x : 0x%016llX",
+ l_MirrorSize[idx], l_MirrorAddr[idx],
+ l_hdatMirrorAddr_x);
- if( (0 != l_MirrorSize[idx]) &&
+ if( (0 != l_MirrorSize[idx]) &&
(l_MirrorAddr[idx] == l_hdatMirrorAddr_x) )
- {
- l_rangeIsMirrorable = true;
- l_hdatMirrorAddr = l_MirrorAddr[idx]
+ {
+ l_rangeIsMirrorable = true;
+ l_hdatMirrorAddr = l_MirrorAddr[idx]
| HDAT_REAL_ADDRESS_MASK64;
- break;
+ break;
+ }
}
}
- }
- if(l_pProcTarget->getAttr<TARGETING::ATTR_MODEL>() == TARGETING::MODEL_NIMBUS)
- {
+
// Set the memory controller ID
- l_hdatMemcntrlID |= 1 << (31 - l_pMcbistTarget->getAttr<TARGETING::ATTR_CHIP_UNIT>());
- l_hdatMemcntrlID |= 1 << (31 - (l_pMcsTarget->getAttr<TARGETING::ATTR_CHIP_UNIT>() + 4));
- l_hdatMemcntrlID |= 1 << (31 - (l_pMcaTarget->getAttr<TARGETING::ATTR_CHIP_UNIT>() + 8));
- }
- else if(l_pProcTarget->getAttr<TARGETING::ATTR_MODEL>() == TARGETING::MODEL_CUMULUS)
- {
- //TODO : MEmory controller ID for cumulus need to be defined.
- HDAT_INF("Memory controller ID : 0 since this is Cumulus proc");
- }
- l_err = addMsAreaAddr(l_index,
- l_addr_range,
- l_end,
- l_procChipId,
- l_rangeIsMirrorable,
- l_hdatMirrorAlogrithm,
- l_hdatMirrorAddr,
- l_hdatMemcntrlID);
- if(NULL != l_err)
+ l_hdatMemcntrlID |=
+ 1 << (31 - l_pMcbistTarget->getAttr
+ <TARGETING::ATTR_CHIP_UNIT>());
+ l_hdatMemcntrlID |=
+ 1 << (31 - (l_pMcsTarget->getAttr
+ <TARGETING::ATTR_CHIP_UNIT>() + 4));
+ l_hdatMemcntrlID |=
+ 1 << (31 - (l_pMcaTarget->getAttr
+ <TARGETING::ATTR_CHIP_UNIT>() + 8));
+
+ l_err = addMsAreaAddr(l_index,
+ l_addr_range,
+ l_end,
+ l_procChipId,
+ l_rangeIsMirrorable,
+ l_hdatMirrorAlogrithm,
+ l_hdatMirrorAddr,
+ l_hdatMemcntrlID);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in adding addMsAreaAddr"
+ " to ms area index[%d]",
+ l_index);
+ break;
+ }
+
+ // TODO : RTC Story 159682
+ // Further CHTM support needs to be added which
+ // contains the trace array for 24 cores
+ // Reinitializing the NHTM size
+
+ // Don't re-init NHTM size -- only one HTM region
+ // per proc
+ uint64_t l_end_hi = l_end.hi;
+ uint64_t l_end_lo = l_end.lo;
+ uint64_t l_end_addr =
+ ((l_end_hi << 32 ) | l_end_lo);
+
+
+ uint64_t l_addr_range_hi = l_addr_range.hi;
+ uint64_t l_addr_range_lo = l_addr_range.lo;
+ uint64_t l_start_addr =
+ ((l_addr_range_hi << 32 )| l_addr_range_lo);
+
+ uint64_t l_size_bytes = ((uint64_t)l_areaSizeInMB) *
+ l_mcaSharingCount[l_mcaInGrp] * 1024 * 1024;
+
+ if((0 != l_nhtmSize) &&
+ (l_size_bytes != (l_end_addr - l_start_addr)))
+ {
+ HDAT_INF("NHTM Bar size = 0x%016llX "
+ " MS area size = 0x%016llX"
+ " l_end_addr = 0x%016llX"
+ " l_start_addr = 0x%016llX",
+ l_nhtmSize,l_size_bytes, l_end_addr,
+ l_start_addr);
+
+ l_addr_range.lo = l_hdatNhtmStartAddr.lo;
+ l_addr_range.hi = l_hdatNhtmStartAddr.hi;
+
+ l_end.lo = l_hdatNhtmEndAddr.lo;
+ l_end.hi = l_hdatNhtmEndAddr.hi;
+
+ l_err = addMsAreaAddr(l_index,
+ l_addr_range,
+ l_end,
+ l_procChipId,
+ false, 0, 0);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in adding "
+ " addMsAreaAddr to ms area index[%d]",
+ l_index);
+ break;
+ }
+ l_nhtmSize=0; //only add 1 entry
+ }
+ l_addr_range = l_end;
+
+ auto l_smfStartAddr = l_pProcTarget->
+ getAttr<TARGETING::ATTR_PROC_SMF_BAR_BASE_ADDR>();
+ auto l_smfSize = l_pProcTarget->
+ getAttr<TARGETING::ATTR_PROC_SMF_BAR_SIZE>();
+
+ if(l_smfSize && !l_smfAdded)
+ {
+ hdatMsAddr_t l_hdatSmfStartAddr{};
+ hdatMsAddr_t l_hdatSmfEndAddr{};
+ l_hdatSmfStartAddr.hi =
+ (l_smfStartAddr & 0xFFFFFFFF00000000ull) >> 32;
+ l_hdatSmfStartAddr.lo =
+ l_smfStartAddr & 0x00000000FFFFFFFFull;
+ l_hdatSmfStartAddr.hi |= HDAT_REAL_ADDRESS_MASK;
+
+ l_hdatSmfEndAddr.hi =
+ ((l_smfStartAddr + l_smfSize) &
+ 0xFFFFFFFF00000000ull) >>32;
+ l_hdatSmfEndAddr.lo =
+ (l_smfStartAddr + l_smfSize) &
+ 0x00000000FFFFFFFFull;
+ l_hdatSmfEndAddr.hi |= HDAT_REAL_ADDRESS_MASK;
+
+ l_err = addMsAreaAddr(l_index,
+ l_hdatSmfStartAddr,
+ l_hdatSmfEndAddr,
+ l_procChipId,
+ false, //rangeIsMirrorable
+ 0, // i_mirroringAlgorithm
+ 0, // i_startMirrAddr
+ l_hdatMemcntrlID,
+ true); // i_hdatsmf
+ l_smfAdded = true;
+ }
+
+ if(l_err)
+ {
+ HDAT_ERR("Could not add SMF memory range to "
+ "HDAT at index[%d]", l_index);
+ break;
+ }
+ else
+ {
+ HDAT_INF("Added SMF memory range to HDAT at "
+ "index[%d]; start addr: 0x%08x; end addr: 0x%08x"
+ "; size: 0x%08x",
+ l_smfStartAddr,
+ l_smfStartAddr + l_smfSize,
+ l_smfSize);
+ }
+
+ l_index++;
+ } //end of mca list
+ if(l_err)
{
- HDAT_ERR("Error in adding addMsAreaAddr"
- " to ms area index[%d]",
- l_index);
break;
}
+ } //end of MCS list
+ if(l_err)
+ {
+ break;
+ }
+ } //end of MCBIST list
+ }
+ else //if model is Axone
+ {
+ //Sharing count for each group
+ TARGETING::ATTR_MSS_MEM_MC_IN_GROUP_type l_mccSharingCount
+ = {0};
+
+ //Size configured under each group
+ TARGETING::ATTR_PROC_MEM_SIZES_type l_procMemSizesBytes = {0};
+
+ assert(l_pProcTarget->tryGetAttr<TARGETING::ATTR_PROC_MEM_SIZES>
+ (l_procMemSizesBytes));
+
+ //For each MCC
+ TARGETING::PredicateCTM l_allMcc(TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MCC);
+ TARGETING::PredicateHwas l_funcMcc;
+ l_funcMcc.functional(true);
+ TARGETING::PredicatePostfixExpr l_allFuncMcc;
+ l_allFuncMcc.push(&l_allMcc).push(&l_funcMcc).And();
+
+ TARGETING::TargetHandleList l_mccList;
+
+ TARGETING::targetService().
+ getAssociated(l_mccList, l_pProcTarget,
+ TARGETING::TargetService::CHILD,
+ TARGETING::TargetService::ALL, &l_allFuncMcc);
+
+ for(uint32_t l_mccIdx = 0; l_mccIdx<l_mccList.size();
+ ++l_mccIdx)
+ {
+ uint32_t l_mccInGrp = 0;
+
+ TARGETING::Target *l_pMccTarget =
+ l_mccList[l_mccIdx];
+ if(!hdatFindGroupForMcc(l_pProcTarget,
+ l_pMccTarget,
+ l_mccInGrp))
+ {
+ //Skip this MCC is not in any group
+ continue;
+ }
+
+ //Increment sharing count if mem configured under group.
+ if(l_procMemSizesBytes[l_mccInGrp] > 0)
+ {
+ l_mccSharingCount[l_mccInGrp]++;
+ }
+ }
+
+ TARGETING::PredicateCTM l_mcPredicate(TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MC);
+
+ TARGETING::PredicatePostfixExpr l_presentMc;
+ l_presentMc.push(&l_mcPredicate).
+ push(&l_predHwasFunc).And();
+
+ TARGETING::TargetHandleList l_mcList;
+
+ // Find Associated MC list
+ TARGETING::targetService().getAssociated(l_mcList,
+ l_pProcTarget,
+ TARGETING::TargetService::CHILD_BY_AFFINITY,
+ TARGETING::TargetService::ALL,
+ &l_presentMc);
- // TODO : RTC Story 159682
- // Further CHTM support needs to be added which contains
- // the trace array for 24 cores
- // Reinitializing the NHTM size
+ //scan all mc in this proc
+ for(uint32_t l_mcIdx =0;
+ l_mcIdx < l_mcList.size();
+ ++l_mcIdx)
+ {
+ TARGETING::Target *l_pMcTarget = l_mcList[l_mcIdx];
- //Don't re-init NHTM size -- only one HTM region per proc
- uint64_t l_end_hi = l_end.hi;
- uint64_t l_end_lo = l_end.lo;
- uint64_t l_end_addr = ((l_end_hi << 32 ) | l_end_lo);
+ TARGETING::PredicateCTM l_miPredicate(
+ TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MI);
+ TARGETING::PredicatePostfixExpr l_funcMi;
+ l_funcMi.push(&l_miPredicate).push(&l_predHwasFunc).And();
- uint64_t l_addr_range_hi = l_addr_range.hi;
- uint64_t l_addr_range_lo = l_addr_range.lo;
- uint64_t l_start_addr =((l_addr_range_hi << 32 )| l_addr_range_lo);
+ TARGETING::TargetHandleList l_miList;
- uint64_t l_size_bytes = ((uint64_t)l_areaSizeInMB) * l_mcaSharingCount[l_mcaInGrp] * 1024 * 1024;
+ // Find Associated mi list
+ TARGETING::targetService().getAssociated(l_miList,
+ l_pMcTarget,
+ TARGETING::TargetService::CHILD,
+ TARGETING::TargetService::ALL,
+ &l_funcMi);
- if((0 != l_nhtmSize) &&
- (l_size_bytes != (l_end_addr - l_start_addr)))
+ //for each MI connected to this this MC
+ for(uint32_t l_miIdx = 0;l_miIdx<l_miList.size();
+ ++l_miIdx)
+ {
+ TARGETING::Target *l_pMiTarget = l_miList[l_miIdx];
+
+ //for each MCC connected to this this MI
+ TARGETING::PredicateCTM l_mccPredicate(
+ TARGETING::CLASS_UNIT, TARGETING::TYPE_MCC);
+
+ TARGETING::PredicateHwas l_predMcc;
+ l_predMcc.present(true);
+ TARGETING::PredicatePostfixExpr l_presentMcc;
+ l_presentMcc.push(&l_mccPredicate).
+ push(&l_predMcc).And();
+ TARGETING::TargetHandleList l_mccList;
+
+ // Get associated MCCs
+ TARGETING::targetService().
+ getAssociated(l_mccList, l_pMiTarget,
+ TARGETING::TargetService::CHILD_BY_AFFINITY,
+ TARGETING::TargetService::ALL, &l_presentMcc);
+
+ for(uint32_t l_mccIdx = 0; l_mccIdx<l_mccList.size();
+ ++l_mccIdx)
{
- HDAT_INF("NHTM Bar size = 0x%016llX "
- " MS area size = 0x%016llX"
- " l_end_addr = 0x%016llX"
- " l_start_addr = 0x%016llX",
- l_nhtmSize,l_size_bytes, l_end_addr,
- l_start_addr);
+ TARGETING::Target *l_pMccTarget =
+ l_mccList[l_mccIdx];
- l_addr_range.lo = l_hdatNhtmStartAddr.lo;
- l_addr_range.hi = l_hdatNhtmStartAddr.hi;
+ //Group which this MCC is belonging
+ uint32_t l_mccInGrp = 0;
- l_end.lo = l_hdatNhtmEndAddr.lo;
- l_end.hi = l_hdatNhtmEndAddr.hi;
+ if(!hdatFindGroupForMcc(l_pProcTarget,
+ l_pMccTarget,
+ l_mccInGrp))
+ {
+ HDAT_INF("No group found for MCC");
+ //Skip this MCC as it is not under any group
+ continue;
+ }
- l_err = addMsAreaAddr(l_index,
- l_addr_range,
- l_end,
- l_procChipId,
- false, 0, 0);
- if(NULL != l_err)
+ //for each OMI connected to this this MCC
+ TARGETING::PredicateCTM l_omiPredicate(
+ TARGETING::CLASS_UNIT, TARGETING::TYPE_OMI);
+
+ TARGETING::PredicateHwas l_predOmi;
+ l_predOmi.present(true);
+ TARGETING::PredicatePostfixExpr l_presentOmi;
+ l_presentOmi.push(&l_omiPredicate).
+ push(&l_predOmi).And();
+ TARGETING::TargetHandleList l_omiList;
+
+ // Get associated OMIs
+ TARGETING::targetService().
+ getAssociated(l_omiList, l_pMccTarget,
+ TARGETING::TargetService::CHILD_BY_AFFINITY,
+ TARGETING::TargetService::ALL, &l_presentOmi);
+
+ for(uint32_t l_omiIdx = 0;
+ l_omiIdx<l_omiList.size();
+ ++l_omiIdx)
+ {
+ TARGETING::Target *l_pOmiTarget =
+ l_omiList[l_omiIdx];
+
+ //for each OCMB CHIP connected to this this OMI
+ TARGETING::PredicateCTM l_ocmbPredicate(
+ TARGETING::CLASS_CHIP,
+ TARGETING::TYPE_OCMB_CHIP);
+
+ TARGETING::PredicateHwas l_predOcmb;
+ l_predOcmb.present(true);
+ TARGETING::PredicatePostfixExpr l_presentOcmb;
+ l_presentOcmb.push(&l_ocmbPredicate).
+ push(&l_predOcmb).And();
+ TARGETING::TargetHandleList l_ocmbList;
+
+ // Get associated OCMB CHIP's
+ TARGETING::targetService().
+ getAssociated(l_ocmbList, l_pOmiTarget,
+ TARGETING::TargetService::CHILD_BY_AFFINITY,
+ TARGETING::TargetService::ALL, &l_presentOcmb);
+
+ for(uint32_t l_ocmbIdx = 0;
+ l_ocmbIdx<l_ocmbList.size();
+ ++l_ocmbIdx)
+ {
+ TARGETING::Target *l_pOcmbTarget =
+ l_ocmbList[l_ocmbIdx];
+
+ // Swift uses a DDIMM. It is a single FRU
+ // that includes 1 OCMB chip and some dram
+ hdatMemParentType l_parentType =
+ HDAT_MEM_PARENT_RISER;
+
+ std::list<hdatRamArea> l_areas;
+ l_areas.clear();
+ uint32_t l_areaSizeInMB = 0;
+ bool l_areaFunctional = false;
+ uint32_t l_numDimms =0;
+
+ l_err = hdatScanDimmsAxone(l_pOcmbTarget,
+ l_areas,
+ l_areaSizeInMB,
+ l_numDimms,
+ l_areaFunctional,
+ l_parentType);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in calling Scan Dimms");
+ break;
+ }
+
+ HDAT_INF("l_areaSizeInMB:0x%.8X "
+ "l_numDimms:0x%.8X "
+ "l_areas.size():0x%.8X", l_areaSizeInMB,
+ l_numDimms, l_areas.size());
+
+ // Skip if no memory configured under
+ // OCMB_CHIP
+ if(l_areaSizeInMB == 0)
+ {
+ continue;
+ }
+
+ uint32_t l_maxMemBlocks = 0;
+ l_err = hdatGetMaxMemoryBlocks
+ (l_pOcmbTarget,l_maxMemBlocks);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error to get max blocks");
+ break;
+ }
+
+ TARGETING::ATTR_SLCA_RID_type l_procRid =
+ l_pProcTarget->getAttr
+ <TARGETING::ATTR_SLCA_RID>();
+
+ TARGETING::ATTR_SLCA_INDEX_type
+ l_procSlcaIndex = l_pProcTarget->getAttr
+ <TARGETING::ATTR_SLCA_INDEX>();
+
+ l_err = addMsAreaFru(l_procRid,
+ l_procSlcaIndex,
+ l_pProcTarget,
+ l_index,
+ l_numDimms,
+ MAX_CHIP_EC_CNT_PER_MSAREA,
+ l_maxMemBlocks);
+
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error adding MSArea %d"
+ "Number of Dimms: %d "
+ "Max Blocks: %d",
+ l_index,
+ l_numDimms,l_maxMemBlocks);
+ break;
+ }
+
+ uint32_t l_memStatus = 0;
+
+ //If group is shared with more than one area
+ if(l_mccSharingCount[l_mccInGrp] >=
+ HDAT_MIN_NUM_FOR_SHARING)
+ {
+ l_memStatus = HDAT_MEM_SHARED;
+ setMsAreaInterleavedId(l_index,
+ l_mccInGrp);
+ }
+ //The memory channel is defined as a single
+ // MCC, and all of the memory on that
+ // channel is part of a single address
+ // space. That means that both OCMBs on
+ // the same MCC share an address space.
+ // While this isn't the same mechanism as
+ // true interleaving, it looks the same to
+ // the code consuming HDAT, so we need to
+ // set the sharing flags appropriately.
+ else if( l_omiList.size() > 1 )
+ {
+ l_memStatus = HDAT_MEM_SHARED;
+ setMsAreaInterleavedId(l_index,
+ l_mccInGrp);
+ }
+
+ setMsAreaType(l_index,l_parentType);
+ setMsAreaSize(l_index,l_areaSizeInMB);
+
+ iv_maxSize.hdatTotSize += l_areaSizeInMB;
+
+ l_memStatus |= l_areaFunctional ?
+ (HDAT_MEM_INSTALLED |
+ HDAT_MEM_FUNCTIONAL) :
+ HDAT_MEM_INSTALLED;
+
+ setMsAreaStat(l_index, l_memStatus);
+
+ //Add OMI ec level
+ uint32_t l_omiEcLevel = 0;
+ uint32_t l_omiChipId = 0;
+ l_err = hdatGetIdEc(l_pOmiTarget,
+ l_omiEcLevel,
+ l_omiChipId);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in getting OMI ID "
+ "and EC HUID:[0x%08X]",
+ l_pOmiTarget->getAttr
+ <TARGETING::ATTR_HUID>());
+ break;
+ }
+
+ l_err = addEcEntry(l_index,
+ l_omiChipId,
+ l_omiEcLevel);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in adding"
+ " ID[0x%08X] and "
+ "EC[0x%08X] to ms area"
+ " HUID:[0x%08X]",l_omiChipId,
+ l_omiEcLevel,
+ l_pOmiTarget->getAttr
+ <TARGETING::ATTR_HUID>());
+ break;
+ }
+
+ // Get the i2c Master data
+ std::vector<hdatI2cData_t> l_i2cDevEntries;
+
+ if (l_pOcmbTarget != NULL)
+ {
+ hdatGetI2cDeviceInfo(l_pOcmbTarget,
+ l_model,
+ l_i2cDevEntries);
+ }
+
+ setMsaI2cInfo(l_index, l_i2cDevEntries);
+
+ //for each mem-port connected to this this
+ //ocmb_chip
+ TARGETING::PredicateCTM l_allMemPort(
+ TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MEM_PORT);
+ TARGETING::PredicateHwas l_funcMemPort;
+ l_funcMemPort.functional(true);
+ TARGETING::PredicatePostfixExpr
+ l_allFuncMemPort;
+ l_allFuncMemPort.push(&l_allMemPort).
+ push(&l_funcMemPort).And();
+
+ TARGETING::TargetHandleList l_memPortList;
+
+ TARGETING::targetService().
+ getAssociated(l_memPortList,
+ l_pOcmbTarget,
+ TARGETING::TargetService::CHILD,
+ TARGETING::TargetService::ALL,
+ &l_allFuncMemPort);
+
+ TARGETING::Target *l_pmemPortTarget;
+
+ l_pmemPortTarget = l_memPortList[0];
+
+ uint32_t l_memBusFreq = 0;
+ l_memBusFreq =
+ getMemBusFreqAxone(l_pmemPortTarget);
+
+ std::list<hdatRamArea>::iterator l_area =
+ l_areas.begin();
+
+ for (uint32_t l_ramId = 0;
+ l_area != l_areas.end();
+ ++l_ramId, ++l_area)
+ {
+ uint32_t l_status =
+ (l_area)->ivFunctional ?
+ (HDAT_RAM_INSTALLED |
+ HDAT_RAM_FUNCTIONAL)
+ : HDAT_RAM_INSTALLED;
+
+ TARGETING::Target *l_pDimmTarget =
+ TARGETING::Target::getTargetFromHuid(
+ l_area->ivHuid);
+
+ TARGETING::ATTR_SLCA_RID_type l_dimmRid
+ = 0;
+ TARGETING::ATTR_SLCA_INDEX_type
+ l_dimmSlcaIndex = 0;
+ l_dimmRid
+ = l_pDimmTarget->getAttr
+ <TARGETING::ATTR_SLCA_RID>();
+
+ l_dimmSlcaIndex =
+ l_pDimmTarget->getAttr
+ <TARGETING::ATTR_SLCA_INDEX>();
+
+ uint32_t l_dimmId = 0;
+ l_dimmId |=
+ 1 << (31 - l_pOmiTarget->getAttr
+ <TARGETING::ATTR_CHIP_UNIT>());
+ l_dimmId |=
+ 1 << (31 - (l_pmemPortTarget->getAttr
+ <TARGETING::ATTR_CHIP_UNIT>()+16));
+ l_dimmId |=
+ 1 << (31 - (l_pDimmTarget->getAttr
+ <TARGETING::ATTR_REL_POS>()+20));
+
+ l_err = addRamFru(l_index,
+ l_pDimmTarget,
+ l_dimmRid,
+ l_dimmSlcaIndex,
+ l_ramId,
+ l_status,
+ (l_area)->ivSize,
+ l_dimmId,
+ l_memBusFreq);
+
+ if (l_err) // Failed to add ram fru
+ {
+ HDAT_ERR("Error in adding RAM FRU"
+ "Index:%d Rid:[0x%08X] "
+ "status:[0x%08X]"
+ "Size:[0x%08X] RamID:[0x%08X]",
+ l_index,(l_area)->ivHuid,
+ l_status,(l_area)->ivSize,
+ l_ramId);
+ ERRORLOG::errlCommit(l_err,
+ HDAT_COMP_ID);
+
+ delete l_err;
+ l_err = NULL;
+ continue;
+ }
+ }//end of RAM list
+
+ l_addr_range.hi =
+ (l_procMemBases[l_mccInGrp] &
+ 0xFFFFFFFF00000000ull) >> 32;
+ l_addr_range.lo =
+ l_procMemBases[l_mccInGrp] &
+ 0x00000000FFFFFFFFull;
+
+ l_end = l_addr_range;
+
+ //Update the range
+ l_end.hi +=
+ (l_procMemSizesBytes[l_mccInGrp] &
+ 0xFFFFFFFF00000000ull) >> 32;
+ l_end.lo +=
+ l_procMemSizesBytes[l_mccInGrp] &
+ 0x00000000FFFFFFFFull;
+
+ HDAT_INF("MI:0x%08X l_addr_range:0x%08X "
+ "0x%08X"
+ " l_end:0x%08X 0x%08X",
+ l_pMiTarget->getAttr
+ <TARGETING::ATTR_HUID>(),
+ l_addr_range.hi, l_addr_range.lo,
+ l_end.hi,l_end.lo);
+
+ uint64_t l_hdatMirrorAddr_x = 0x0ull;
+ uint64_t l_hdatMirrorAddr = 0x0ull;
+ uint32_t l_hdatMemcntrlID = 0x0 ;
+ uint8_t l_hdatMirrorAlogrithm = 0xFF;
+ bool l_rangeIsMirrorable = false;
+
+ //Calculate the mirror address and
+ //related data
+ uint64_t l_startAddr =
+ (((uint64_t)(l_addr_range.hi) << 32 )
+ | (uint64_t)(l_addr_range.lo));
+ l_hdatMirrorAddr_x = (l_startAddr / 2) +
+ l_mirrorBaseAddress_x;
+
+ HDAT_INF("Start add : 0x%016llX "
+ "MirrorBase : 0x%016llX"
+ " MirrorAddr : 0x%016llX"
+ " PayLoadMirrorMem : 0x%X",
+ l_startAddr, l_mirrorBaseAddress_x,
+ l_hdatMirrorAddr_x, l_payLoadMirrorMem);
+
+ if ( 0 != l_payLoadMirrorMem )
+ {
+ for ( int idx=0 ; idx <
+ (int)(sizeof
+ (TARGETING::ATTR_PROC_MIRROR_SIZES_type)
+ / sizeof(uint64_t)) ; idx++ )
+ {
+ HDAT_INF("Mirror size : 0x%016llX"
+ " MirrorAddr : 0x%016llX"
+ " hdatMirrorAddr_x : 0x%016llX",
+ l_MirrorSize[idx],
+ l_MirrorAddr[idx],
+ l_hdatMirrorAddr_x);
+
+ if( (0 != l_MirrorSize[idx]) &&
+ (l_MirrorAddr[idx] ==
+ l_hdatMirrorAddr_x) )
+ {
+ l_rangeIsMirrorable = true;
+ l_hdatMirrorAddr =
+ l_MirrorAddr[idx] |
+ HDAT_REAL_ADDRESS_MASK64;
+ break;
+ }
+ }
+ }
+
+ // Set the memory controller ID
+ l_hdatMemcntrlID |=
+ 1 << (31 - l_pMcTarget->getAttr
+ <TARGETING::ATTR_CHIP_UNIT>());
+ l_hdatMemcntrlID |=
+ 1 << (31 - (l_pMiTarget->getAttr
+ <TARGETING::ATTR_CHIP_UNIT>() + 4));
+ l_hdatMemcntrlID |=
+ 1 << (31 - (l_pMccTarget->getAttr
+ <TARGETING::ATTR_CHIP_UNIT>() + 8));
+ l_hdatMemcntrlID |=
+ 1 << (31 - (l_pOmiTarget->getAttr
+ <TARGETING::ATTR_CHIP_UNIT>() + 16));
+
+ l_err = addMsAreaAddr(l_index,
+ l_addr_range,
+ l_end,
+ l_procChipId,
+ l_rangeIsMirrorable,
+ l_hdatMirrorAlogrithm,
+ l_hdatMirrorAddr,
+ l_hdatMemcntrlID);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in adding addMsAreaAddr"
+ " to ms area index[%d]",
+ l_index);
+ break;
+ }
+
+ // TODO : RTC Story 159682
+ // Further CHTM support needs to be added
+ // which contains the trace array for
+ // 24 cores
+ // Reinitializing the NHTM size
+
+ // Don't re-init NHTM size -- only one HTM
+ // region per proc
+ uint64_t l_end_hi = l_end.hi;
+ uint64_t l_end_lo = l_end.lo;
+ uint64_t l_end_addr =
+ ((l_end_hi << 32 ) | l_end_lo);
+
+
+ uint64_t l_addr_range_hi = l_addr_range.hi;
+ uint64_t l_addr_range_lo = l_addr_range.lo;
+ uint64_t l_start_addr =
+ ((l_addr_range_hi << 32 )| l_addr_range_lo);
+
+ uint64_t l_size_bytes =
+ ((uint64_t)l_areaSizeInMB) *
+ l_mccSharingCount[l_mccInGrp] * 1024 * 1024;
+
+ if((0 != l_nhtmSize) &&
+ (l_size_bytes !=
+ (l_end_addr - l_start_addr)))
+ {
+ HDAT_INF("NHTM Bar size = 0x%016llX "
+ " MS area size = 0x%016llX"
+ " l_end_addr = 0x%016llX"
+ " l_start_addr = 0x%016llX",
+ l_nhtmSize,l_size_bytes,
+ l_end_addr,
+ l_start_addr);
+
+ l_addr_range.lo =
+ l_hdatNhtmStartAddr.lo;
+ l_addr_range.hi =
+ l_hdatNhtmStartAddr.hi;
+
+ l_end.lo = l_hdatNhtmEndAddr.lo;
+ l_end.hi = l_hdatNhtmEndAddr.hi;
+
+ l_err = addMsAreaAddr(l_index,
+ l_addr_range,
+ l_end,
+ l_procChipId,
+ false, 0, 0);
+ if(NULL != l_err)
+ {
+ HDAT_ERR("Error in adding "
+ " addMsAreaAddr to ms area "
+ "index[%d]",
+ l_index);
+ break;
+ }
+ l_nhtmSize=0; //only add 1 entry
+ }
+ l_addr_range = l_end;
+
+ // Add SMF memory addr range
+ auto l_smfStartAddr = l_pProcTarget->
+ getAttr<TARGETING::ATTR_PROC_SMF_BAR_BASE_ADDR>();
+ auto l_smfSize = l_pProcTarget->
+ getAttr<TARGETING::ATTR_PROC_SMF_BAR_SIZE>();
+
+ if(l_smfSize && !l_smfAdded)
+ {
+ hdatMsAddr_t l_hdatSmfStartAddr{};
+ hdatMsAddr_t l_hdatSmfEndAddr{};
+ l_hdatSmfStartAddr.hi =
+ (l_smfStartAddr & 0xFFFFFFFF00000000ull) >> 32;
+ l_hdatSmfStartAddr.lo =
+ l_smfStartAddr & 0x00000000FFFFFFFFull;
+ l_hdatSmfStartAddr.hi |= HDAT_REAL_ADDRESS_MASK;
+
+ l_hdatSmfEndAddr.hi =
+ ((l_smfStartAddr + l_smfSize) &
+ 0xFFFFFFFF00000000ull) >>32;
+ l_hdatSmfEndAddr.lo =
+ (l_smfStartAddr + l_smfSize) &
+ 0x00000000FFFFFFFFull;
+ l_hdatSmfEndAddr.hi |= HDAT_REAL_ADDRESS_MASK;
+
+ l_err = addMsAreaAddr(l_index,
+ l_hdatSmfStartAddr,
+ l_hdatSmfEndAddr,
+ l_procChipId,
+ false, //rangeIsMirrorable
+ 0, // i_mirroringAlgorithm
+ 0, // i_startMirrAddr
+ l_hdatMemcntrlID,
+ true); // i_hdatsmf
+ l_smfAdded = true;
+ }
+
+ if(l_err)
+ {
+ HDAT_ERR("Could not add SMF memory range to "
+ "HDAT at index[%d]", l_index);
+ break;
+ }
+ else
+ {
+ HDAT_INF("Added SMF memory range to HDAT at "
+ "index[%d]; start addr: 0x%08x; end addr: 0x%08x"
+ "; size: 0x%08x",
+ l_smfStartAddr,
+ l_smfStartAddr + l_smfSize,
+ l_smfSize);
+ }
+ l_index++;
+ } // end of OCMB_CHIP list
+ if(l_err)
+ {
+ break;
+ }
+ } //end of OMI list
+ if(l_err)
{
- HDAT_ERR("Error in adding "
- " addMsAreaAddr to ms area index[%d]",
- l_index);
break;
}
- l_nhtmSize=0; //only add 1 entry
+ } //end of MCC list
+ if(l_err)
+ {
+ break;
}
- l_addr_range = l_end;
- l_index++;
- } //end of mca list
- } //end of MCS list
- } //end of MCBIST list
+ } //end of MI list
+ if(l_err)
+ {
+ break;
+ }
+ } //end of MC list
+ }
if(l_err)
{
// Error message recorded above
@@ -1823,7 +2586,8 @@ void HdatMsVpd::commit(void * i_addr,
/*******************************************************************************
* hdatGetMaxMemConfiguredAddress
*******************************************************************************/
-uint64_t HdatMsVpd::hdatGetMaxMemConfiguredAddress()
+uint64_t HdatMsVpd::hdatGetMaxMemConfiguredAddress(
+ TARGETING::ATTR_MODEL_type i_model)
{
//For each processor in the system
TARGETING::PredicateCTM l_procChipPred(TARGETING::CLASS_CHIP,
@@ -1856,49 +2620,101 @@ uint64_t HdatMsVpd::hdatGetMaxMemConfiguredAddress()
assert(l_pProcTarget->
tryGetAttr<TARGETING::ATTR_PROC_MEM_BASES>(l_procMemBases));
+ if (i_model == TARGETING::MODEL_NIMBUS)
+ {
+ //For each MCA
+ TARGETING::PredicateCTM l_allMca(TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MCA);
+ TARGETING::PredicateHwas l_funcMca;
+ l_funcMca.functional(true);
+ TARGETING::PredicatePostfixExpr l_allFuncMca;
+ l_allFuncMca.push(&l_allMca).push(&l_funcMca).And();
- //For each MCA
- TARGETING::PredicateCTM l_allMca(TARGETING::CLASS_UNIT,
- TARGETING::TYPE_MCA);
- TARGETING::PredicateHwas l_funcMca;
- l_funcMca.functional(true);
- TARGETING::PredicatePostfixExpr l_allFuncMca;
- l_allFuncMca.push(&l_allMca).push(&l_funcMca).And();
-
- TARGETING::TargetHandleList l_mcaList;
+ TARGETING::TargetHandleList l_mcaList;
- TARGETING::targetService().
+ TARGETING::targetService().
getAssociated(l_mcaList, l_pProcTarget,
TARGETING::TargetService::CHILD,
TARGETING::TargetService::ALL, &l_allFuncMca);
- for(uint32_t i=0; i < l_mcaList.size(); i++)
- {
+ for(uint32_t i=0; i < l_mcaList.size(); i++)
+ {
- TARGETING::Target *l_pMcaTarget = l_mcaList[i];
+ TARGETING::Target *l_pMcaTarget = l_mcaList[i];
- uint32_t l_mcaInGroup = 0;
- if(!hdatFindGroupForMc(l_pProcTarget,
- l_pMcaTarget,
- l_mcaInGroup))
- {
- HDAT_INF("Input target is not in group,"
- " MCA HUID:[0x%08X]",
- l_pMcaTarget->getAttr<TARGETING::ATTR_HUID>());
- //Skip this MC not part of any group
- continue;
+ uint32_t l_mcaInGroup = 0;
+ if(!hdatFindGroupForMc(l_pProcTarget,
+ l_pMcaTarget,
+ l_mcaInGroup))
+ {
+ HDAT_INF("Input target is not in group,"
+ " MCA HUID:[0x%08X]",
+ l_pMcaTarget->getAttr<TARGETING::ATTR_HUID>());
+ //Skip this MC not part of any group
+ continue;
+ }
+
+ if(!l_processedAnyGroup ||
+ (l_procMemBases[l_mcaInGroup] > l_maxBase))
+ {
+ l_maxBase = l_procMemBases[l_mcaInGroup];
+ l_processedAnyGroup = true;
+ l_maxMsAddress =
+ l_maxBase + l_procMemSizesBytes[l_mcaInGroup];
+ HDAT_INF("Max MS Addr l_maxMsAddress: = 0x%016llX,"
+ "l_maxBase= 0x%016llX,"
+ "l_procMemSizesBytes[l_mcaInGroup]= 0x%016llX",
+ l_maxMsAddress, l_maxBase,
+ l_procMemSizesBytes[l_mcaInGroup]);
+ }
}
+ }
+ else
+ {
+ //For each MCC
+ TARGETING::PredicateCTM l_allMcc(TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MCC);
+ TARGETING::PredicateHwas l_funcMcc;
+ l_funcMcc.functional(true);
+ TARGETING::PredicatePostfixExpr l_allFuncMcc;
+ l_allFuncMcc.push(&l_allMcc).push(&l_funcMcc).And();
- if(!l_processedAnyGroup ||
- (l_procMemBases[l_mcaInGroup] > l_maxBase))
+ TARGETING::TargetHandleList l_mccList;
+
+ TARGETING::targetService().
+ getAssociated(l_mccList, l_pProcTarget,
+ TARGETING::TargetService::CHILD,
+ TARGETING::TargetService::ALL, &l_allFuncMcc);
+
+ for(uint32_t i=0; i < l_mccList.size(); i++)
{
- l_maxBase = l_procMemBases[l_mcaInGroup];
- l_processedAnyGroup = true;
- l_maxMsAddress = l_maxBase + l_procMemSizesBytes[l_mcaInGroup];
- HDAT_INF("Max MS Addr l_maxMsAddress: = 0x%016llX,"
- "l_maxBase= 0x%016llX,"
- "l_procMemSizesBytes[l_mcaInGroup]= 0x%016llX",
- l_maxMsAddress, l_maxBase, l_procMemSizesBytes[l_mcaInGroup]);
+ TARGETING::Target *l_pMccTarget = l_mccList[i];
+
+ uint32_t l_mccInGroup = 0;
+ if(!hdatFindGroupForMcc(l_pProcTarget,
+ l_pMccTarget,
+ l_mccInGroup))
+ {
+ HDAT_INF("Input target is not in group,"
+ " MCC HUID:[0x%08X]",
+ l_pMccTarget->getAttr<TARGETING::ATTR_HUID>());
+ //Skip this MCC as its not part of any group
+ continue;
+ }
+
+ if(!l_processedAnyGroup ||
+ (l_procMemBases[l_mccInGroup] > l_maxBase))
+ {
+ l_maxBase = l_procMemBases[l_mccInGroup];
+ l_processedAnyGroup = true;
+ l_maxMsAddress =
+ l_maxBase + l_procMemSizesBytes[l_mccInGroup];
+ HDAT_INF("Max MS Addr l_maxMsAddress: = 0x%016llX,"
+ "l_maxBase= 0x%016llX,"
+ "l_procMemSizesBytes[l_omiInGroup]= 0x%016llX",
+ l_maxMsAddress, l_maxBase,
+ l_procMemSizesBytes[l_mccInGroup]);
+ }
}
}
@@ -2004,6 +2820,56 @@ bool HdatMsVpd::hdatFindGroupForMc(const TARGETING::Target *i_pProcTarget,
return l_foundGroup;
}
+
+//******************************************************************************
+//* hdatFindGroupForMcc
+//******************************************************************************
+bool HdatMsVpd::hdatFindGroupForMcc(const TARGETING::Target *i_pProcTarget,
+ const TARGETING::Target *i_pMccTarget,
+ uint32_t& o_groupOfMcc)
+{
+ bool l_foundGroup = false;
+ TARGETING::ATTR_MSS_MEM_MC_IN_GROUP_type l_mccGroups = {0};
+ assert(i_pProcTarget != NULL || i_pMccTarget != NULL);
+
+ assert(!(i_pProcTarget->getAttr<TARGETING::ATTR_TYPE>()
+ != TARGETING::TYPE_PROC)||
+ !(i_pProcTarget->getAttr<TARGETING::ATTR_CLASS>()
+ != TARGETING::CLASS_CHIP));
+
+ assert(i_pProcTarget->
+ tryGetAttr<TARGETING::ATTR_MSS_MEM_MC_IN_GROUP>(l_mccGroups));
+
+ assert(!(i_pMccTarget->getAttr<TARGETING::ATTR_TYPE>()
+ != TARGETING::TYPE_MCC)||
+ !(i_pMccTarget->getAttr<TARGETING::ATTR_CLASS>()
+ != TARGETING::CLASS_UNIT));
+ TARGETING::ATTR_CHIP_UNIT_type l_chipUnit =
+ i_pMccTarget->getAttr<TARGETING::ATTR_CHIP_UNIT>();
+ uint32_t l_sizeOfArray = sizeof(l_mccGroups)/sizeof(l_mccGroups[0]);
+
+ assert(!(sizeof( l_mccGroups[0] ) != sizeof(uint8_t)));
+
+ assert(!( l_chipUnit >= ( sizeof( l_mccGroups[0] ) * HDAT_BITS_PER_BYTE )));
+
+ const uint8_t MC_IN_GROUP_MCC_0 = 0x80;
+ for(uint32_t l_idx =0; l_idx < l_sizeOfArray;++l_idx)
+ {
+ //Attribute ATTR_MSS_MEM_MC_IN_GROUP is an array of bitmask
+ //bit 0 of bitmask corresponds to mcc 0, bit 7 to mcc 7
+ if((l_mccGroups[l_idx] & (MC_IN_GROUP_MCC_0 >> l_chipUnit)) ==
+ (MC_IN_GROUP_MCC_0 >> l_chipUnit))
+ {
+ HDAT_INF("hdatFindGroupForMcc::: Found group : %d",l_idx);
+ o_groupOfMcc = l_idx;
+ l_foundGroup = true;
+ break;
+ }
+ }
+
+ return l_foundGroup;
+}
+
/*******************************************************************************
* hdatScanDimms
*******************************************************************************/
@@ -2148,6 +3014,145 @@ errlHndl_t HdatMsVpd::hdatScanDimms(const TARGETING::Target *i_pTarget,
while(0);
return l_err;
}
+
+/*******************************************************************************
+* hdatScanDimmsAxone
+*******************************************************************************/
+errlHndl_t HdatMsVpd::hdatScanDimmsAxone(const TARGETING::Target *i_pOcmbTarget,
+ std::list<hdatRamArea>& o_areas,
+ uint32_t& o_areaSize,
+ uint32_t& o_dimmNum,
+ bool& o_areaFunctional,
+ hdatMemParentType& o_parentType)
+{
+ errlHndl_t l_err = NULL;
+
+ do
+ {
+ if(i_pOcmbTarget->getAttr<TARGETING::ATTR_TYPE>() !=
+ TARGETING::TYPE_OCMB_CHIP)
+ {
+ HDAT_ERR("Input Target is type not OCMB_CHIP");
+ break;
+ }
+
+ //for each mem-port connected to this this ocmb_chip
+ TARGETING::PredicateCTM l_allMemPort(TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MEM_PORT);
+ TARGETING::PredicateHwas l_funcMemPort;
+ l_funcMemPort.functional(true);
+ TARGETING::PredicatePostfixExpr l_allFuncMemPort;
+ l_allFuncMemPort.push(&l_allMemPort).push(&l_funcMemPort).And();
+
+ TARGETING::TargetHandleList l_memPortList;
+
+ TARGETING::targetService().
+ getAssociated(l_memPortList, i_pOcmbTarget,
+ TARGETING::TargetService::CHILD,
+ TARGETING::TargetService::ALL, &l_allFuncMemPort);
+
+ for(uint32_t i=0; i < l_memPortList.size(); i++)
+ {
+ TARGETING::Target *l_pmemPortTarget = l_memPortList[i];
+
+ TARGETING::ATTR_MEM_EFF_DIMM_SIZE_type l_dimSizes = {0};
+ //Get configured memory size
+ if(!l_pmemPortTarget->
+ tryGetAttr<TARGETING::ATTR_MEM_EFF_DIMM_SIZE>(l_dimSizes))
+ {
+ HDAT_ERR("DIMM size should be available with MEM_PORT");
+ }
+
+ //for each DIMM connected to this this MCA
+ TARGETING::PredicateCTM l_dimmPredicate(TARGETING::
+ CLASS_LOGICAL_CARD,
+ TARGETING::TYPE_DIMM);
+ TARGETING::PredicateHwas l_predDimm;
+ l_predDimm.present(true);
+ TARGETING::PredicatePostfixExpr l_presentDimm;
+ l_presentDimm.push(&l_dimmPredicate).push(&l_predDimm).And();
+
+ TARGETING::TargetHandleList l_dimmList;
+
+ // Get associated dimms
+ TARGETING::targetService().
+ getAssociated(l_dimmList, l_pmemPortTarget,
+ TARGETING::TargetService::CHILD_BY_AFFINITY,
+ TARGETING::TargetService::ALL, &l_presentDimm);
+
+ for(uint32_t j=0; j < l_dimmList.size(); ++j)
+ {
+ //fetch each dimm
+ TARGETING::Target *l_pDimmTarget = l_dimmList[j];
+
+ uint32_t l_dimmfru = 0;
+ l_dimmfru = l_pDimmTarget->getAttr<TARGETING::ATTR_FRU_ID>();
+
+ TARGETING::ATTR_MEM_PORT_type l_dimmMemPort = 0;
+
+ if(!l_pDimmTarget->
+ tryGetAttr<TARGETING::ATTR_MEM_PORT>(l_dimmMemPort))
+ {
+ HDAT_ERR("DIMM size should be available with MEM_PORT");
+ }
+
+ //Convert GB to MB
+ uint32_t l_dimmSizeInMB = l_dimSizes[l_dimmMemPort] *
+ HDAT_MB_PER_GB;
+ uint32_t l_huid = TARGETING::get_huid(l_pDimmTarget);
+
+ bool foundArea = false;
+ for (std::list<hdatRamArea>::iterator l_area = o_areas.begin();
+ l_area != o_areas.end();
+ ++l_area)
+ {
+ //we do not need to compare each dimm fru id with mca fru id
+ //to create ram area, by the below logic
+ //dimms with same fruid will fall into same ram area
+ //even if they have fru id same with mca
+ if (l_area->ivfruId == l_dimmfru)//this means soldered dimms
+ {
+ foundArea = true;
+ l_area->ivFunctional = (l_area)->ivFunctional ||
+ isFunctional(l_pDimmTarget);
+ (l_area)->ivFunctional = true;
+ (l_area)->ivSize += l_dimmSizeInMB;
+ break;
+ }
+ }
+
+ //Search in the list of RAM Areas if not
+ //present create a new ram area
+ if (!foundArea)
+ {
+ o_dimmNum++;
+ o_areas.push_back(hdatRamArea(l_huid,
+ isFunctional(l_pDimmTarget),
+ l_dimmSizeInMB,l_dimmfru));
+ }
+ o_areaSize += l_dimmSizeInMB;
+ o_areaFunctional = o_areaFunctional ||
+ isFunctional(l_pDimmTarget);
+ } //end of dimm list
+
+ o_parentType = HDAT_MEM_PARENT_CEC_FRU;
+
+ if(l_err != NULL)
+ {
+ //break if error
+ break;
+ }
+ } // end of mem_port list
+ if(l_err != NULL)
+ {
+ //break if error
+ break;
+ }
+ }
+ while(0);
+ return l_err;
+}
+
/*******************************************************************************
* hdatGetMaxMemoryBlocks
*******************************************************************************/
diff --git a/src/usr/hdat/hdatmsvpd.H b/src/usr/hdat/hdatmsvpd.H
index 0778e3e9a..93955ba39 100755
--- a/src/usr/hdat/hdatmsvpd.H
+++ b/src/usr/hdat/hdatmsvpd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -63,6 +63,10 @@ const uint32_t HDAT_START_INSTANCE = 0;
const uint32_t HDAT_RHB_MAX_RANGE_ENTRIES = 20;
const uint32_t MAX_DIMMS_PER_MCBIST = 8;
+//@TODO:RTC 213230(HDAT Axone additional support)
+//Need to revisit the number if needed
+const uint32_t HDAT_MAX_MSAREA_AXONE = 32;
+
/** @brief Structure version number
*/
const uint16_t HDAT_MS_VPD_VERSION = 0x24;
@@ -632,6 +636,7 @@ class HdatMsVpd : public HdatHdif
* @param[in] i_startMirrAddr - Specifies the starting mirrorable
* address for range
* @param[in] i_hdatMemCntlID - Memory Controller ID
+ * @param[in] i_hdatSmf - Whether the range is in SMF memory
*
* @return A null error log handle if successful, else the return code
* pointed to by errlHndl_t contains one of:
@@ -645,7 +650,8 @@ class HdatMsVpd : public HdatHdif
bool i_rangeIsMirrorable = false,
uint8_t i_mirroringAlgorithm = 0,
uint64_t i_startMirrAddr = 0,
- uint32_t i_hdatMemCntlID = 0);
+ uint32_t i_hdatMemCntlID = 0,
+ bool i_hdatSmf = false);
/**
@@ -809,10 +815,12 @@ class HdatMsVpd : public HdatHdif
/**
* @brief Gets maximum configured memory address
*
+ * @param[in] i_model Target model
*
* @return value of ms address
*/
- uint64_t hdatGetMaxMemConfiguredAddress();
+ uint64_t hdatGetMaxMemConfiguredAddress(
+ TARGETING::ATTR_MODEL_type i_model);
/**
* @brief Fetches the group of MC
@@ -828,6 +836,19 @@ class HdatMsVpd : public HdatHdif
uint32_t& o_groupOfMc);
/**
+ * @brief Fetches the group of MCC
+ *
+ * @param[in] i_pTarget Proc target
+ * @param[in] i_pMccTarget MCC target
+ * @param[out] o_groupOfMcc MCC group value
+ *
+ * @return Success or failure
+ */
+ bool hdatFindGroupForMcc(const TARGETING::Target *i_pProcTarget,
+ const TARGETING::Target *i_pMccTarget,
+ uint32_t& o_groupOfMcc);
+
+ /**
* @brief Get the DIMMS list present on the system
*
* @param[in] i_pTarget Mca target
@@ -854,6 +875,28 @@ class HdatMsVpd : public HdatHdif
hdatMemParentType& i_parentType);
/**
+ * @brief Get the DIMMS list present on the axone system
+ *
+ * @param[in] i_pTarget OCMB Chip target
+ * @param[out] o_areas list of ram area structure based on the DIMM
+ * present.
+ * @param[out] o_areaSize - Total DIMM size
+ * @param[out] o_dimmNum - Total DIMM number
+ * @param[out] o_areaFunctional - DIMM functional status
+ * @param[out] o_parentType - memory parent type based on whether
+ * the dimms are pluggable or soldered
+ *
+ * @return A null error log handle if successful, else the return the
+ * error handle
+ */
+ errlHndl_t hdatScanDimmsAxone(const TARGETING::Target *i_pOcmbTarget,
+ std::list<hdatRamArea>& o_areas,
+ uint32_t& o_areaSize,
+ uint32_t& o_dimmNum,
+ bool& o_areaFunctional,
+ hdatMemParentType& i_parentType);
+
+ /**
* @brief Get max memory blocks connected to membuf
*
* @param[in] i_pTarget Mcs target
diff --git a/src/usr/hdat/hdatpcrd.C b/src/usr/hdat/hdatpcrd.C
index b052afb5d..c813b010f 100644
--- a/src/usr/hdat/hdatpcrd.C
+++ b/src/usr/hdat/hdatpcrd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -446,8 +446,10 @@ errlHndl_t HdatPcrd::hdatLoadPcrd(uint32_t &o_size, uint32_t &o_count)
// Need to get i2c Master data correctly
std::vector<hdatI2cData_t> l_i2cDevEntries;
+ TARGETING::ATTR_MODEL_type l_model = TARGETING::MODEL_NIMBUS;
+ l_model = l_pProcTarget->getAttr<TARGETING::ATTR_MODEL>();
- hdatGetI2cDeviceInfo(l_pProcTarget, l_i2cDevEntries);
+ hdatGetI2cDeviceInfo(l_pProcTarget, l_model, l_i2cDevEntries);
l_pcrdHI2cTotalSize = sizeof(*l_hostI2cFullPcrdHdrPtr) +
(sizeof(hdatI2cData_t) * l_i2cDevEntries.size());
diff --git a/src/usr/hdat/hdatutil.C b/src/usr/hdat/hdatutil.C
index d0b3edca1..83deff106 100644
--- a/src/usr/hdat/hdatutil.C
+++ b/src/usr/hdat/hdatutil.C
@@ -772,7 +772,10 @@ errlHndl_t hdatGetPvpdFullRecord(TARGETING::Target * i_target,
theRecord,0,0,0,
ERRORLOG::ERRL_SEV_INFORMATIONAL,
HDAT_VERSION1,
- true);
+ false);
+ //@TODO:RTC 213229(Remove HDAT hack or Axone)
+ //There are known differences where not all records will be
+ //present. So changing now from true to false.
continue;
}
@@ -1738,6 +1741,7 @@ bool byNodeProcAffinity(
*
* @param[in] i_pTarget
* The i2c master target handle, or nullptr for all i2c masters
+ * @param[in] i_model Target model
* @param[out] o_i2cDevEntries
* The host i2c dev entries
*
@@ -1746,6 +1750,7 @@ bool byNodeProcAffinity(
*******************************************************************************/
void hdatGetI2cDeviceInfo(
TARGETING::Target* i_pTarget,
+ TARGETING::ATTR_MODEL_type i_model,
std::vector<hdatI2cData_t>& o_i2cDevEntries)
{
HDAT_ENTER();
@@ -1825,11 +1830,13 @@ void hdatGetI2cDeviceInfo(
"detected");
++linkId.instance;
- if( (i_pTarget == nullptr)
- || (i_pTarget == i2cDevice.masterChip))
+ if( (i_pTarget == nullptr) ||
+ (i_pTarget == i2cDevice.masterChip)
+ )
{
o_i2cDevEntries.push_back(l_hostI2cObj);
}
+
}
}
@@ -2144,60 +2151,77 @@ errlHndl_t hdatUpdateSMPLinkInfoData(hdatHDIFDataArray_t * i_SMPInfoFullPcrdHdrP
uint32_t getMemBusFreq(const TARGETING::Target* i_pTarget)
{
-
HDAT_ENTER();
- TARGETING::ATTR_MSS_FREQ_type l_MemBusFreqInMHz = 0;
+ TARGETING::ATTR_MSS_FREQ_type l_MemBusFreqInMHz = 0;
TARGETING::ATTR_CLASS_type l_class = GETCLASS(i_pTarget);
TARGETING::ATTR_TYPE_type l_type = GETTYPE(i_pTarget);
- if((l_class == TARGETING::CLASS_CHIP) && (l_type == TARGETING::TYPE_PROC))
+ if((l_class == TARGETING::CLASS_CHIP) &&
+ (l_type == TARGETING::TYPE_PROC))
{
TARGETING::PredicateCTM l_mcbistPredicate(TARGETING::CLASS_UNIT,
TARGETING::TYPE_MCBIST);
TARGETING::PredicateHwas l_predHwasFunc;
TARGETING::PredicatePostfixExpr l_presentMcbist;
l_presentMcbist.push(&l_mcbistPredicate).
- push(&l_predHwasFunc).And();
+ push(&l_predHwasFunc).And();
TARGETING::TargetHandleList l_mcbistList;
// Find Associated MCBIST list
TARGETING::targetService().getAssociated(l_mcbistList,
- i_pTarget,
- TARGETING::TargetService::CHILD_BY_AFFINITY,
- TARGETING::TargetService::ALL,
- &l_presentMcbist);
+ i_pTarget,
+ TARGETING::TargetService::CHILD_BY_AFFINITY,
+ TARGETING::TargetService::ALL,
+ &l_presentMcbist);
if(l_mcbistList.size() == 0)
{
HDAT_ERR("Didn't find any mcbist for a proc with huid [0x%08X]",
- i_pTarget->getAttr<TARGETING::ATTR_HUID>());
+ i_pTarget->getAttr<TARGETING::ATTR_HUID>());
}
else
{
TARGETING::Target *l_pMcbistTarget = l_mcbistList[0];
if( l_pMcbistTarget->tryGetAttr<TARGETING::ATTR_MSS_FREQ>
- (l_MemBusFreqInMHz) == false )
+ (l_MemBusFreqInMHz) == false )
{
- HDAT_ERR(" MSS_FREQ not present for MCBIST with huid [0x%08X]",
- l_pMcbistTarget->getAttr<TARGETING::ATTR_HUID>());
+ HDAT_ERR("MSS_FREQ not present for MCBIST with "
+ "huid [0x%08X]",
+ l_pMcbistTarget->getAttr<TARGETING::ATTR_HUID>());
}
}
- }
- else if((l_class == TARGETING::CLASS_UNIT) && (l_type == TARGETING::TYPE_MCBIST))
+ }
+ else if((l_class == TARGETING::CLASS_UNIT) &&
+ (l_type == TARGETING::TYPE_MCBIST))
{
- if(i_pTarget->tryGetAttr<TARGETING::ATTR_MSS_FREQ>
- (l_MemBusFreqInMHz) == false )
- {
- HDAT_ERR(" MSS_FREQ not present for MCBIST with huid [0x%08X]",
- i_pTarget->getAttr<TARGETING::ATTR_HUID>());
- }
+ if(i_pTarget->tryGetAttr<TARGETING::ATTR_MSS_FREQ>
+ (l_MemBusFreqInMHz) == false )
+ {
+ HDAT_ERR(" MSS_FREQ not present for MCBIST with huid [0x%08X]",
+ i_pTarget->getAttr<TARGETING::ATTR_HUID>());
+ }
}
else
{
- HDAT_ERR(" Input target with HUID [0x%08X] is not of proc/mcbist target type",
- i_pTarget->getAttr<TARGETING::ATTR_HUID>());
+ HDAT_ERR(" Input target with HUID [0x%08X] is not of "
+ "proc/mcbist target type",
+ i_pTarget->getAttr<TARGETING::ATTR_HUID>());
+ }
+ HDAT_EXIT();
+ return l_MemBusFreqInMHz;
+}
+
+uint32_t getMemBusFreqAxone(const TARGETING::Target* i_pTarget)
+{
+ HDAT_ENTER();
+ TARGETING::ATTR_MEM_EFF_FREQ_type l_MemBusFreqInMHz = {0};
+ if( i_pTarget->tryGetAttr<TARGETING::ATTR_MEM_EFF_FREQ>
+ (l_MemBusFreqInMHz) == false )
+ {
+ HDAT_ERR("MSS_EFF_FREQ not present for MEM PORT with "
+ "huid [0x%08X]",
+ i_pTarget->getAttr<TARGETING::ATTR_HUID>());
}
-
HDAT_EXIT();
return l_MemBusFreqInMHz;
}
diff --git a/src/usr/hdat/hdatutil.H b/src/usr/hdat/hdatutil.H
index 893852482..942549467 100755
--- a/src/usr/hdat/hdatutil.H
+++ b/src/usr/hdat/hdatutil.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -572,6 +572,7 @@ errlHndl_t hdatGetFullEepromVpd ( TARGETING::Target * i_target,
*
* @param[in] i_pTarget
* The i2c master target handle
+ * @param[in] i_model Target model
* @param[out] o_i2cDevEntries
* The host i2c dev entries
*
@@ -579,6 +580,7 @@ errlHndl_t hdatGetFullEepromVpd ( TARGETING::Target * i_target,
*
*******************************************************************************/
void hdatGetI2cDeviceInfo(TARGETING::Target* i_pTarget,
+ TARGETING::ATTR_MODEL_type i_model,
std::vector<hdatI2cData_t>&o_i2cDevEntries);
/*******************************************************************************
@@ -620,6 +622,13 @@ errlHndl_t hdatUpdateSMPLinkInfoData(hdatHDIFDataArray_t * i_SMPInfoFullPcrdHdrP
* @return Memory bus frequency. upon any error conditions it returns 0.
*******************************************************************************/
uint32_t getMemBusFreq(const TARGETING::Target* i_pTarget);
+
+/******************************************************************************
+ * @brief get Memory bus frequency of given target.
+ * @param[in] i_pTarget : input target handle
+ * @return Memory bus frequency. upon any error conditions it returns 0.
+*******************************************************************************/
+uint32_t getMemBusFreqAxone(const TARGETING::Target* i_pTarget);
};// end namespace
#endif // HDATUTILITY_H
diff --git a/src/usr/hdat/hdatvpd.C b/src/usr/hdat/hdatvpd.C
index a07996921..9c72c020c 100755
--- a/src/usr/hdat/hdatvpd.C
+++ b/src/usr/hdat/hdatvpd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -58,6 +58,13 @@ extern trace_desc_t * g_hdatTraceDesc;
/*----------------------------------------------------------------------------*/
const uint16_t HDAT_VPD_VERSION = 0x0020;
+const uint8_t LX_RECORD_TEMPLATE[] =
+{0x84, 0x1C, 0x00, 0x52, 0x54, 0x04, 0x4C, 0x58,
+ 0x52, 0x30, 0x56, 0x5A, 0x02, 0x30, 0x31, 0x4C,
+ 0x58, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x50, 0x46, 0x02, 0x00, 0x00, 0x78};
+const uint16_t LX_RECORD_SIZE = 32;
+const uint16_t LX_KEYWORD_OFFSET= 18;
/** @brief See the prologue in hdatvpd.H
*/
@@ -118,6 +125,19 @@ iv_kwdSize(0), iv_kwd(NULL)
HDAT_DBG("hdatGetAsciiKwd returned kwd size =%d",iv_kwdSize);
+ char *o_fmtKwd;
+ uint32_t o_fmtkwdSize;
+ o_errlHndl = hdatformatAsciiKwd(i_fetchVpd, i_num, theSize, iv_kwd,
+ iv_kwdSize, o_fmtKwd, o_fmtkwdSize, i_pvpdKeywords);
+ if( o_fmtKwd != NULL )
+ {
+ delete[] iv_kwd;
+ iv_kwd = new char [o_fmtkwdSize];
+ memcpy(iv_kwd,o_fmtKwd,o_fmtkwdSize);
+ iv_kwdSize = o_fmtkwdSize;
+ delete[] o_fmtKwd;
+ }
+
if(strcmp(i_eyeCatcher,"IO KID")==0)
{
using namespace TARGETING;
@@ -130,30 +150,23 @@ iv_kwdSize(0), iv_kwd(NULL)
//fetching lx data
uint64_t l_LXvalue = l_sysTarget->getAttr<ATTR_ASCII_VPD_LX_KEYWORD>();
- char *temp_kwd = new char [iv_kwdSize];
- uint32_t temp_kwdSize = iv_kwdSize;
- memcpy(temp_kwd, iv_kwd,iv_kwdSize);
- delete[] iv_kwd;
- iv_kwdSize +=sizeof(uint64_t);
- iv_kwd = new char [iv_kwdSize];
- memcpy(iv_kwd,temp_kwd,temp_kwdSize);
- memcpy((void *)(iv_kwd+temp_kwdSize),&l_LXvalue,sizeof(uint64_t));
- theSize[i_num-1] = sizeof(uint64_t);
- delete[] temp_kwd;
- }
- char *o_fmtKwd;
- uint32_t o_fmtkwdSize;
- o_errlHndl = hdatformatAsciiKwd(i_fetchVpd, i_num, theSize, iv_kwd,
- iv_kwdSize, o_fmtKwd, o_fmtkwdSize, i_pvpdKeywords);
- if( o_fmtKwd != NULL )
- {
+ char *temp_lx = new char[LX_RECORD_SIZE];
+ memcpy(temp_lx, LX_RECORD_TEMPLATE, LX_RECORD_SIZE);
+ memcpy((void*)(temp_lx + LX_KEYWORD_OFFSET), &l_LXvalue, sizeof(uint64_t));
+
+ //append LXR0 record to VINI record
+ size_t combined_size = iv_kwdSize + LX_RECORD_SIZE;
+ char * temp_buf = new char[combined_size];
+ memcpy(temp_buf,iv_kwd,iv_kwdSize);
+ memcpy((void *)(temp_buf+iv_kwdSize),temp_lx, LX_RECORD_SIZE);
+
+ delete[] temp_lx;
delete[] iv_kwd;
- iv_kwd = new char [o_fmtkwdSize];
- memcpy(iv_kwd,o_fmtKwd,o_fmtkwdSize);
- iv_kwdSize = o_fmtkwdSize;
- delete[] o_fmtKwd;
+ iv_kwd = temp_buf;
+ iv_kwdSize = combined_size;
}
+
if (NULL == o_errlHndl)
{
iv_fru.hdatSlcaIdx = l_slcaIdx;
@@ -194,7 +207,10 @@ iv_kwdSize(0), iv_kwd(NULL)
TARGETING::TargetHandleList l_targList;
PredicateCTM predNode(TARGETING::CLASS_ENC, TARGETING::TYPE_NODE);
PredicateHwas predFunctional;
- predFunctional.functional(true);
+ //@TODO:RTC 213229(Remove HDAT hack or Axone)
+ //crashes below at l_target because the node got deconfigured
+ //changed from functional to present
+ predFunctional.present(true);
PredicatePostfixExpr nodeCheckExpr;
nodeCheckExpr.push(&predNode).push(&predFunctional).And();
@@ -238,16 +254,20 @@ iv_kwdSize(0), iv_kwd(NULL)
//fetching lx data
uint64_t l_LXvalue = l_sysTarget->getAttr<ATTR_ASCII_VPD_LX_KEYWORD>();
- char *temp_kwd = new char [iv_kwdSize];
- uint32_t temp_kwdSize = iv_kwdSize;
- memcpy(temp_kwd, iv_kwd,iv_kwdSize);
+ char *temp_lx = new char[LX_RECORD_SIZE];
+ memcpy(temp_lx, LX_RECORD_TEMPLATE, LX_RECORD_SIZE);
+ memcpy((void*)(temp_lx + LX_KEYWORD_OFFSET), &l_LXvalue, sizeof(uint64_t));
+
+ //append LXR0 record to VINI record
+ size_t combined_size = iv_kwdSize + LX_RECORD_SIZE;
+ char * temp_buf = new char[combined_size];
+ memcpy(temp_buf,iv_kwd,iv_kwdSize);
+ memcpy((void *)(temp_buf+iv_kwdSize),temp_lx, LX_RECORD_SIZE);
+
+ delete[] temp_lx;
delete[] iv_kwd;
- iv_kwdSize +=sizeof(uint64_t);
- iv_kwd = new char [iv_kwdSize];
- memcpy(iv_kwd,temp_kwd,temp_kwdSize);
- memcpy((void *)(iv_kwd+temp_kwdSize),&l_LXvalue,sizeof(uint64_t));
- theSize[i_num-1] = sizeof(uint64_t);
- delete[] temp_kwd;
+ iv_kwd = temp_buf;
+ iv_kwdSize = combined_size;
}
if (NULL == o_errlHndl)
{
diff --git a/src/usr/htmgt/htmgt.C b/src/usr/htmgt/htmgt.C
index f83cf65a8..db34411d5 100644
--- a/src/usr/htmgt/htmgt.C
+++ b/src/usr/htmgt/htmgt.C
@@ -31,7 +31,6 @@
#include "htmgt_memthrottles.H"
#include "htmgt_poll.H"
#include <devicefw/userif.H>
-#include <config.h>
#include <console/consoleif.H>
// Targeting support
diff --git a/src/usr/htmgt/htmgt_occ.H b/src/usr/htmgt/htmgt_occ.H
index e53d78fe6..21079c2ad 100644
--- a/src/usr/htmgt/htmgt_occ.H
+++ b/src/usr/htmgt/htmgt_occ.H
@@ -99,6 +99,16 @@ namespace HTMGT
} __attribute__ ((__packed__));
typedef struct occErrlCallout occErrlCallout_t;
+ // PGPE Callout Structure
+ struct pgpeErrlCallout
+ {
+ uint64_t calloutValue;
+ uint8_t type;
+ uint8_t priority;
+ uint8_t reserved[6];
+ } __attribute__ ((__packed__));
+ typedef struct pgpeErrlCallout pgpeErrlCallout_t;
+
/**
* @class Occ
@@ -382,6 +392,21 @@ namespace HTMGT
/**
+ * @brief Add specified PGEP callout to the error log
+ *
+ * @param[in,out] io_errlHndl elog to add callout
+ * @param[in] i_priority priority for callout
+ * @param[in] i_callout callout from PGPE
+ * @param[in,out] io_numCallouts number of callouts in elog,
+ * incremented if new callout added
+ * */
+ bool elogAddPgpeCallout(errlHndl_t & io_errlHndl,
+ HWAS::callOutPriority & i_priority,
+ const pgpeErrlCallout_t i_callout,
+ uint8_t & io_callout_num);
+
+
+ /**
* @brief Update the GPU presence sensors in the system
*/
void updateGpuPresence();
diff --git a/src/usr/htmgt/occError.C b/src/usr/htmgt/occError.C
index 492d047ce..690a86c54 100644
--- a/src/usr/htmgt/occError.C
+++ b/src/usr/htmgt/occError.C
@@ -128,11 +128,23 @@ namespace HTMGT
const occErrlEntry_t * l_occElog =
reinterpret_cast<occErrlEntry_t*> (l_buffer.pointer());
- TMGT_BIN("OCC ELOG", l_occElog, 256);
+ TMGT_BIN("OCC ELOG", l_occElog, 320);
- // Get user details section
+ unsigned int l_elog_header_len = OCC_ELOG_HEADER_LENGTH;
+ unsigned int l_max_callout = l_occElog->occ_data.maxCallouts;
+ unsigned int l_callout_size = sizeof(occErrlCallout_t);
+ if (i_source != OCC_ERRSRC_405)
+ {
+ // PGPE logs require different memory alignment/structures
+ l_elog_header_len = PGPE_ELOG_HEADER_LENGTH;
+ l_max_callout = l_occElog->pgpe_data.maxCallouts;
+ l_callout_size = sizeof(pgpeErrlCallout_t);
+ }
+
+ // Get user details section (after callouts)
const occErrlUsrDtls_t *l_usrDtls_ptr = (occErrlUsrDtls_t *)
- ((uint8_t*)l_occElog + sizeof(occErrlEntry_t));
+ ( (uint8_t*)l_occElog +
+ l_elog_header_len + (l_max_callout * l_callout_size) );
const uint32_t l_occSrc = l_comp_id | l_occElog->reasonCode;
ERRORLOG::errlSeverity_t severity =
@@ -166,6 +178,16 @@ namespace HTMGT
severity,
l_call_home_event);
+ uint16_t l_extendedRC = l_usrDtls_ptr->modId << 16;
+ if (i_source == OCC_ERRSRC_405)
+ {
+ l_extendedRC |= l_occElog->occ_data.extendedRC;
+ }
+ else
+ {
+ l_extendedRC |= l_occElog->pgpe_data.extendedRC;
+ }
+
// Create OCC error log
// NOTE: word 4 (used by extended reason code) to save off OCC
// sub component value which is needed to correctly parse
@@ -178,8 +200,7 @@ namespace HTMGT
l_usrDtls_ptr->userData1,
l_usrDtls_ptr->userData2,
l_usrDtls_ptr->userData3,
- (l_usrDtls_ptr->modId << 16 ) |
- l_occElog->extendedRC, // extended reason code
+ l_extendedRC,
severity);
if (l_call_home_event)
@@ -190,26 +211,36 @@ namespace HTMGT
}
// Add callout information
- const uint8_t l_max_callouts = l_occElog->maxCallouts;
bool l_bad_fru_data = false;
uint8_t numCallouts = 0;
uint8_t calloutIndex = 0;
- while (calloutIndex < l_max_callouts)
+ while (calloutIndex < l_max_callout)
{
- const occErrlCallout_t callout =
- l_occElog->callout[calloutIndex];
- if (callout.type != 0)
+ const occErrlCallout_t *callout = (occErrlCallout_t*)
+ ( (uint8_t*)l_occElog + l_elog_header_len +
+ (calloutIndex*l_callout_size) );
+ if (callout->type != 0)
{
HWAS::callOutPriority priority;
bool l_success = true;
- l_success = elogXlateSrciPriority(callout.priority,
+ l_success = elogXlateSrciPriority(callout->priority,
priority);
if (l_success == true)
{
- l_success = elogAddCallout(l_errlHndl,
- priority,
- callout,
- numCallouts);
+ if (i_source == OCC_ERRSRC_405)
+ {
+ l_success = elogAddCallout(l_errlHndl,
+ priority,
+ *callout,
+ numCallouts);
+ }
+ else
+ {
+ l_success = elogAddPgpeCallout(l_errlHndl,
+ priority,
+ *((pgpeErrlCallout_t*)callout),
+ numCallouts);
+ }
if (l_success == false)
{
l_bad_fru_data = true;
@@ -220,24 +251,26 @@ namespace HTMGT
l_bad_fru_data = true;
TMGT_ERR("occProcessElog: Priority translate"
" failure (priority = 0x%02X)",
- callout.priority);
+ callout->priority);
}
}
else
{ // make sure all the remaining callout data are zeros,
// otherwise mark bad fru data
- const occErrlCallout_t zeros = { 0 };
- while (calloutIndex < l_max_callouts)
+ uint8_t *l_ptr = (uint8_t*)callout;
+ unsigned int l_len =
+ (l_max_callout-calloutIndex) * l_callout_size;
+ while (l_len != 0)
{
- if (memcmp(&l_occElog->callout[calloutIndex],
- &zeros, sizeof(occErrlCallout_t)))
+ if (*l_ptr != 0x00)
{
TMGT_ERR("occProcessElog: The remaining"
" callout data should be all zeros");
l_bad_fru_data = true;
break;
}
- ++calloutIndex;
+ l_len--;
+ l_ptr++;
}
break;
}
@@ -248,8 +281,10 @@ namespace HTMGT
errlHndl_t err2 = nullptr;
if (l_bad_fru_data == true)
{
- TMGT_BIN("Callout Data", &l_occElog->callout[0],
- sizeof(occErrlCallout)*ERRL_MAX_CALLOUTS);
+ const uint8_t *callout_ptr = (uint8_t*)l_occElog
+ + l_elog_header_len;
+ TMGT_BIN("Callout Data", callout_ptr,
+ l_callout_size * ERRL_MAX_CALLOUTS);
/*@
* @errortype
* @refcode LIC_REFCODE
@@ -516,6 +551,65 @@ namespace HTMGT
} // end Occ::elogAddCallout()
+ // Add callout to specified elog
+ bool Occ::elogAddPgpeCallout(errlHndl_t & io_errlHndl,
+ HWAS::callOutPriority & i_priority,
+ const pgpeErrlCallout_t i_callout,
+ uint8_t & io_callout_num)
+ {
+ bool l_success = true;
+
+ TMGT_INF("elogAddPgpeCallout: Add callout type:0x%02X, value:0x%016llX,"
+ " priority:0x%02X",
+ i_callout.type,i_callout.calloutValue, i_priority);
+
+ if (i_callout.type == OCC_CALLOUT_TYPE_COMPONENT_ID)
+ {
+ tmgtCompxlateType l_compDataType;
+ uint32_t l_compData = 0;
+ const uint8_t l_compId = (i_callout.calloutValue & 0xFF);
+
+ if (elogGetTranslationData(l_compId, l_compDataType, l_compData))
+ {
+ switch(l_compDataType)
+ {
+ case TMGT_COMP_DATA_SYMBOLIC_FRU:
+ TMGT_INF("elogAddPgpeCallout: symbolic callout: 0x%08X",
+ l_compData);
+ break;
+ case TMGT_COMP_DATA_PROCEDURE:
+ io_errlHndl->addProcedureCallout(
+ (HWAS::epubProcedureID)l_compData,
+ i_priority);
+ io_callout_num++;
+ break;
+ case TMGT_COMP_DATA_END_OF_TABLE:
+ break;
+ default:
+ TMGT_ERR("elogAddPgpeCallout: Invalid component id"
+ " 0x%02X", l_compId);
+ l_success = false;
+ }
+ }
+ else
+ {
+ TMGT_ERR("elogAddPgpeCallout: Component id translate failure"
+ " (id=0x%02X)", l_compId);
+ l_success = false;
+ }
+ }
+ else
+ {
+ TMGT_ERR("elogAddPgpeCallout: Invalid callout type (type=%d)",
+ i_callout.type);
+ l_success = false;
+ }
+
+ return l_success;;
+
+ } // end Occ::elogAddPgpeCallout()
+
+
void Occ::elogProcessActions(const uint8_t i_actions,
const uint32_t i_src,
uint32_t i_data,
diff --git a/src/usr/htmgt/occError.H b/src/usr/htmgt/occError.H
index ac98bf8bb..216c4b946 100644
--- a/src/usr/htmgt/occError.H
+++ b/src/usr/htmgt/occError.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -130,6 +130,8 @@ namespace HTMGT
#define ERRL_MAX_CALLOUTS 6
// OCC Error Log Structure
+ const unsigned int OCC_ELOG_HEADER_LENGTH = 12;
+ const unsigned int PGPE_ELOG_HEADER_LENGTH = 16;
struct occErrlEntry
{
// Log CheckSum
@@ -144,14 +146,30 @@ namespace HTMGT
uint8_t severity;
// Actions to process the errors
uint8_t actions;
- // Reserved
- uint16_t reserved;
- // Extended Reason Code
- uint16_t extendedRC;
- // Log Callout Number
- uint8_t maxCallouts;
- // Callouts
- occErrlCallout callout[ERRL_MAX_CALLOUTS];
+
+ union // PGPE has different alignment requirements, so structure differs
+ {
+ struct {
+ // Max Elog Size
+ uint16_t maxSize;
+ // Extended Reason Code
+ uint16_t extendedRC;
+ // Log Callout Number
+ uint8_t maxCallouts;
+ } occ_data __attribute__((packed));
+ struct {
+ // Log Callout Number
+ uint8_t maxCallouts;
+ // Extended Reason Code
+ uint16_t extendedRC;
+ // Max Elog Size
+ uint16_t maxSize;
+ // Reserved
+ uint16_t reserved[2];
+ } pgpe_data __attribute__ ((__packed__));
+ };
+
+ // Callouts start
} __attribute__ ((__packed__));
typedef struct occErrlEntry occErrlEntry_t;
@@ -192,10 +210,13 @@ namespace HTMGT
const tmgtCompXlate_t tmgt_compXlateTable[TMGT_MAX_COMP_IDS] =
{
- { 0x01, TMGT_COMP_DATA_PROCEDURE, HWAS::EPUB_PRC_HB_CODE}, // FW
- { 0x04, TMGT_COMP_DATA_SYMBOLIC_FRU, OVERTMP}, // over temperature
- { 0x05, TMGT_COMP_DATA_SYMBOLIC_FRU, TPMD_OV}, // oversub throttling
- { 0xFF, TMGT_COMP_DATA_END_OF_TABLE, 0}, // none
+ { OCC_COMPONENT_ID_FIRMWARE,
+ TMGT_COMP_DATA_PROCEDURE,HWAS::EPUB_PRC_HB_CODE},
+ { OCC_COMPONENT_ID_OVER_TEMPERATURE, TMGT_COMP_DATA_SYMBOLIC_FRU,
+ OVERTMP},
+ { OCC_COMPONENT_ID_OVERSUBSCRIPTION, TMGT_COMP_DATA_SYMBOLIC_FRU,
+ TPMD_OV},
+ { OCC_COMPONENT_ID_NONE, TMGT_COMP_DATA_END_OF_TABLE, 0} // END
};
diff --git a/src/usr/htmgt/runtime/rt_occ.C b/src/usr/htmgt/runtime/rt_occ.C
index 652e767ed..d25d12f96 100644
--- a/src/usr/htmgt/runtime/rt_occ.C
+++ b/src/usr/htmgt/runtime/rt_occ.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,7 +27,7 @@
#include <htmgt/htmgt.H>
#include "../htmgt_utility.H"
#include <targeting/common/commontargeting.H>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
using namespace TARGETING;
diff --git a/src/usr/hwas/common/deconfigGard.C b/src/usr/hwas/common/deconfigGard.C
index 727611eed..89df5b160 100644
--- a/src/usr/hwas/common/deconfigGard.C
+++ b/src/usr/hwas/common/deconfigGard.C
@@ -42,7 +42,6 @@
#include <targeting/common/targetservice.H>
#ifdef __HOSTBOOT_MODULE
-#include <config.h>
#include <errl/errlmanager.H>
#if (!defined(CONFIG_CONSOLE_OUTPUT_TRACE) && defined(CONFIG_CONSOLE))
#include <console/consoleif.H>
@@ -174,6 +173,17 @@ errlHndl_t DeconfigGard::applyGardRecord(Target *i_pTarget,
// all ok - do the work
HWAS_MUTEX_LOCK(iv_mutex);
+#if (!defined(CONFIG_CONSOLE_OUTPUT_TRACE) && defined(CONFIG_CONSOLE))
+ const char* l_tmpstring =
+ i_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>().toString();
+ CONSOLE::displayf("HWAS", "Applying GARD record for HUID=0x%08X (%s) due to 0x%.8X",
+ get_huid(i_pTarget),
+ l_tmpstring,
+ l_errlogEid);
+ free((void*)(l_tmpstring));
+ l_tmpstring = nullptr;
+#endif
+
// Deconfigure the Target
// don't need to check ATTR_DECONFIG_GARDABLE -- if we get
// here, it's because of a gard record on this target
@@ -643,9 +653,13 @@ errlHndl_t DeconfigGard::deconfigureTargetsFromGardRecordsForIpl(
}
#if (!defined(CONFIG_CONSOLE_OUTPUT_TRACE) && defined(CONFIG_CONSOLE))
+ const char* l_tmpstring =
+ l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>().toString();
CONSOLE::displayf("HWAS", "Deconfig HUID 0x%08X, %s",
get_huid(l_pTarget),
- l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>().toString());
+ l_tmpstring);
+ free((void*)(l_tmpstring));
+ l_tmpstring = nullptr;
#endif
} // for
@@ -912,9 +926,13 @@ errlHndl_t DeconfigGard::deconfigureTargetsFromGardRecordsForIpl(
}
#if (!defined(CONFIG_CONSOLE_OUTPUT_TRACE) && defined(CONFIG_CONSOLE))
+ const char* l_tmpstring =
+ l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>().toString();
CONSOLE::displayf("HWAS", "Deconfig HUID 0x%08X, %s",
get_huid(l_pTarget),
- l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>().toString());
+ l_tmpstring);
+ free((void*)(l_tmpstring));
+ l_tmpstring = nullptr;
#endif
l_specDeconfigVector.erase(l_specDeconfigVector.begin());
diff --git a/src/usr/hwas/common/hwas.C b/src/usr/hwas/common/hwas.C
index 45a88cf85..94d947dad 100644
--- a/src/usr/hwas/common/hwas.C
+++ b/src/usr/hwas/common/hwas.C
@@ -41,7 +41,6 @@
#include <stdio.h> // sprintf
#ifdef __HOSTBOOT_MODULE
-#include <config.h>
#include <initservice/initserviceif.H>
#endif
@@ -569,6 +568,59 @@ errlHndl_t discoverMuxTargetsAndEnable(const Target &i_sysTarget)
return l_err;
}
+/**
+ * @brief Do presence detect on only PMIC targets and enable HWAS state
+ *
+ * @param[in] i_sysTarget the top level target (CLASS_SYS)
+ * @return errlHndl_t return nullptr if no error,
+ * else return a handle to an error entry
+ *
+ */
+errlHndl_t discoverPmicTargetsAndEnable(const Target &i_sysTarget)
+{
+ HWAS_INF(ENTER_MRK"discoverPmicTargetsAndEnable");
+
+ errlHndl_t l_err{nullptr};
+
+ do
+ {
+ // Only get PMIC targets
+ const PredicateCTM l_pmicPred(CLASS_ASIC, TYPE_PMIC);
+ TARGETING::PredicatePostfixExpr l_asicPredExpr;
+ l_asicPredExpr.push(&l_pmicPred);
+ TargetHandleList l_pPmicCheckPres;
+ targetService().getAssociated( l_pPmicCheckPres, (&i_sysTarget),
+ TargetService::CHILD, TargetService::ALL, &l_asicPredExpr);
+
+ // Do the presence detect on only PMIC targets
+ // NOTE: this function will remove any non-functional targets
+ // from pPmicCheckPres
+ l_err = platPresenceDetect(l_pPmicCheckPres);
+
+ // If an issue with platPresenceDetect, then exit, returning
+ // error back to caller
+ if (nullptr != l_err)
+ {
+ break;
+ }
+
+ // Enable the HWAS State for the PMICs
+ const bool l_present(true);
+ const bool l_functional(true);
+ const uint32_t l_errlEid(0);
+ for (TargetHandle_t pTarget : l_pPmicCheckPres)
+ {
+ // set HWAS state to show PMIC is present and functional
+ enableHwasState(pTarget, l_present, l_functional, l_errlEid);
+ }
+ } while (0);
+
+ HWAS_INF(EXIT_MRK"discoverPmicTargetsAndEnable exit with %s",
+ (nullptr == l_err ? "no error" : "error"));
+
+ return l_err;
+}
+
errlHndl_t discoverTargets()
{
HWAS_DBG("discoverTargets entry");
@@ -643,11 +695,13 @@ errlHndl_t discoverTargets()
PredicateCTM predPmic(CLASS_ASIC, TYPE_PMIC);
// We can ignore chips of TYPE_I2C_MUX because they
// were already detected above in discoverMuxTargetsAndEnable
+ // Also we can ignore chips of type PMIC because they will be processed
+ // below.
PredicateCTM predMux(CLASS_CHIP, TYPE_I2C_MUX);
PredicatePostfixExpr checkExpr;
checkExpr.push(&predChip).push(&predDimm).Or().push(&predEnc).Or().
- push(&predMcs).Or().push(&predPmic).Or().
- push(&predMux).Not().And();
+ push(&predMcs).Or().push(&predMux).Not().And().
+ push(&predPmic).Not().And();
TargetHandleList pCheckPres;
targetService().getAssociated( pCheckPres, pSys,
@@ -728,19 +782,22 @@ errlHndl_t discoverTargets()
MOD_DISCOVER_TARGETS,
RC_PARTIAL_GOOD_INFORMATION);
- if( (pTarget->getAttr<ATTR_CLASS>() == CLASS_CHIP) &&
- (l_targetType != TYPE_TPM) &&
- (l_targetType != TYPE_SP) &&
- (l_targetType != TYPE_BMC) &&
- (l_targetType != TYPE_I2C_MUX))
+ if( (pTarget->getAttr<ATTR_CLASS>() == CLASS_CHIP)
+ && (l_targetType != TYPE_TPM)
+ && (l_targetType != TYPE_SP)
+ && (l_targetType != TYPE_BMC)
+ && (l_targetType != TYPE_I2C_MUX))
{
// read Chip ID/EC data from these physical chips
errl = platReadIDEC(pTarget);
if (errl)
- { // read of ID/EC failed even tho we THOUGHT we were present.
- HWAS_INF("pTarget %.8X - read IDEC failed (eid 0x%X) - bad",
- errl->eid(), pTarget->getAttr<ATTR_HUID>());
+ {
+ // read of ID/EC failed even tho we THOUGHT we were present.
+ HWAS_INF("pTarget 0x%.8X - read IDEC failed "
+ "(eid 0x%X) - bad",
+ get_huid(pTarget), errl->eid());
+
// chip NOT present and NOT functional, so that FSP doesn't
// include this for HB to process
chipPresent = false;
@@ -758,8 +815,9 @@ errlHndl_t discoverTargets()
if (errl)
{ // read of PG failed even tho we were present..
- HWAS_INF("pTarget %.8X - read PG failed (eid 0x%X)- bad",
- errl->eid(), pTarget->getAttr<ATTR_HUID>());
+ HWAS_INF("pTarget 0x%.8X - read PG failed "
+ "(eid 0x%X) - bad",
+ get_huid(pTarget), errl->eid());
chipFunctional = false;
errlEid = errl->eid();
@@ -861,6 +919,16 @@ errlHndl_t discoverTargets()
} // for pTarget_it
+ // After processing all other targets look at the pmics,
+ // we must wait because we need the SPD cached from the OCMBs
+ // which occurs when OCMBs go through presence detection above
+ errl = discoverPmicTargetsAndEnable(*pSys);
+
+ if (errl != NULL)
+ {
+ break; // break out of the do/while so that we can return
+ }
+
// Check for non-present Procs and if found, trigger
// DeconfigGard::_invokeDeconfigureAssocProc() to run by setting
// setXAOBusEndpointDeconfigured to true
@@ -966,6 +1034,13 @@ bool isChipFunctional(const TARGETING::TargetHandle_t &i_target,
uint16_t l_xbus = (l_model == MODEL_NIMBUS) ?
VPD_CP00_PG_XBUS_GOOD_NIMBUS : VPD_CP00_PG_XBUS_GOOD_CUMULUS;
+ uint16_t l_perv = (l_model == MODEL_AXONE) ?
+ VPD_CP00_PG_PERVASIVE_GOOD_AXONE : VPD_CP00_PG_PERVASIVE_GOOD;
+
+ uint16_t l_n2 = (l_model == MODEL_AXONE) ?
+ VPD_CP00_PG_N2_GOOD_AXONE : VPD_CP00_PG_N2_GOOD;
+
+
// Check all bits in FSI entry
if (i_pgData[VPD_CP00_PG_FSI_INDEX] !=
VPD_CP00_PG_FSI_GOOD)
@@ -981,14 +1056,14 @@ bool isChipFunctional(const TARGETING::TargetHandle_t &i_target,
else
// Check all bits in PRV entry
if (i_pgData[VPD_CP00_PG_PERVASIVE_INDEX] !=
- VPD_CP00_PG_PERVASIVE_GOOD)
+ l_perv)
{
HWAS_INF("pTarget %.8X - Pervasive pgData[%d]: "
"actual 0x%04X, expected 0x%04X - bad",
i_target->getAttr<ATTR_HUID>(),
VPD_CP00_PG_PERVASIVE_INDEX,
i_pgData[VPD_CP00_PG_PERVASIVE_INDEX],
- VPD_CP00_PG_PERVASIVE_GOOD);
+ l_perv);
l_chipFunctional = false;
}
else
@@ -1018,14 +1093,14 @@ bool isChipFunctional(const TARGETING::TargetHandle_t &i_target,
}
else
// Check all bits in N2 entry
- if (i_pgData[VPD_CP00_PG_N2_INDEX] != VPD_CP00_PG_N2_GOOD)
+ if (i_pgData[VPD_CP00_PG_N2_INDEX] != l_n2)
{
HWAS_INF("pTarget %.8X - N2 pgData[%d]: "
"actual 0x%04X, expected 0x%04X - bad",
i_target->getAttr<ATTR_HUID>(),
VPD_CP00_PG_N2_INDEX,
i_pgData[VPD_CP00_PG_N2_INDEX],
- VPD_CP00_PG_N2_GOOD);
+ l_n2);
l_chipFunctional = false;
}
else
@@ -3839,7 +3914,7 @@ errlHndl_t updateProcCompatibilityRiskLevel()
"force compatibility of invalid MRW risk level %d",
l_risk);
- /*
+ /*@
* @errortype
* @severity ERRL_SEV_UNRECOVERABLE
* @moduleid MOD_UPDATE_PROC_COMPAT_RISK_LEVEL
@@ -3906,7 +3981,7 @@ errlHndl_t updateProcCompatibilityRiskLevel()
"force native compatibility of mixed processor levels",
" (0x%02X and 0x%02X)", l_firstEc, l_lastEc );
- /*
+ /*@
* @errortype
* @severity ERRL_SEV_UNRECOVERABLE
* @moduleid MOD_UPDATE_PROC_COMPAT_RISK_LEVEL
@@ -3977,7 +4052,7 @@ errlHndl_t updateProcCompatibilityRiskLevel()
"force native compatibility of DD2.3 for risk level %d",
l_risk);
- /*
+ /*@
* @errortype
* @severity ERRL_SEV_UNRECOVERABLE
* @moduleid MOD_UPDATE_PROC_COMPAT_RISK_LEVEL
@@ -4064,6 +4139,33 @@ errlHndl_t updateProcCompatibilityRiskLevel()
return l_err;
}
+/**
+ * @brief Normalize the RISK_LEVEL for Axone to use the upper range
+ */
+void normalizeRiskLevelForAxone( void )
+{
+ // Axone follows Nimbus DD2.3 settings except it can use
+ // the low or high numbers. Let's normalize it to the
+ // high range to make things less confusing.
+ Target* pSys;
+ targetService().getTopLevelTarget(pSys);
+ auto l_risk = pSys->getAttr<TARGETING::ATTR_RISK_LEVEL>();
+ if( TARGETING::UTIL::P9A_RUGBY_FAVOR_SECURITY_LOWER == l_risk )
+ {
+ l_risk = TARGETING::UTIL::P9A_RUGBY_FAVOR_SECURITY;
+ }
+ else if( TARGETING::UTIL::P9A_RUGBY_FAVOR_PERFORMANCE_LOWER == l_risk )
+ {
+ l_risk = TARGETING::UTIL::P9A_RUGBY_FAVOR_PERFORMANCE;
+ }
+ else
+ {
+ // Nothing to change, just leave
+ return;
+ }
+ pSys->setAttr<TARGETING::ATTR_RISK_LEVEL>(l_risk);
+}
+
errlHndl_t validateProcessorEcLevels()
{
HWAS_INF("validateProcessorEcLevels entry");
@@ -4109,6 +4211,12 @@ errlHndl_t validateProcessorEcLevels()
break;
}
}
+ else if(TARGETING::MODEL_AXONE == l_model)
+ {
+ // Axone follows Nimbus DD2.3 settings except it can use
+ // the low or high numbers, going to force one way.
+ normalizeRiskLevelForAxone();
+ }
//Loop through all functional procs and create error logs
//for any processors whose EC does not match the master
diff --git a/src/usr/hwas/common/pgLogic.C b/src/usr/hwas/common/pgLogic.C
index 2cc30944f..cd0aa9b19 100644
--- a/src/usr/hwas/common/pgLogic.C
+++ b/src/usr/hwas/common/pgLogic.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -31,6 +31,7 @@
#include <hwas/common/hwasError.H>
using namespace HWAS::COMMON;
+using namespace HWAS; //needed for trace macros
namespace PARTIAL_GOOD
{
@@ -134,6 +135,7 @@ namespace PARTIAL_GOOD
// MC
// PG/AG Masks
const uint16_t MC_R1_AG_MASK = 0xE0FD;
+ const uint16_t MC_R1_AG_MASK_AXONE = 0xE03D;
const uint16_t MC_R2_PG_MASK = 0x0040;
const uint16_t MC_R3_PG_MASK = 0x0020;
@@ -257,6 +259,9 @@ namespace PARTIAL_GOOD
if (rulesIterator == pgRules_map.end())
{
+ HWAS_ERR( "No rules found for type %d",
+ i_target->getAttr<TARGETING::ATTR_TYPE>() );
+
// Target is missing from the table. This is an error, so break
// out of this section of code and return the appropriate error
// below.
@@ -344,6 +349,12 @@ namespace PARTIAL_GOOD
// the following error if applicable.
if ((l_errl == nullptr) && (o_targetPgLogic.size() == 0))
{
+ HWAS_ERR( "No rule found for Target %.8X of type %d",
+ get_huid(i_target),
+ i_target->getAttr<TARGETING::ATTR_TYPE>() );
+ uint64_t userdata1 = static_cast<uint64_t>(i_target->getAttr<TARGETING::ATTR_TYPE>());
+ userdata1 <<= 32;
+ userdata1 |= static_cast<uint64_t>(get_huid(i_target));
/*@
* @errortype
* @severity ERRL_SEV_UNRECOVERABLE
@@ -358,15 +369,16 @@ namespace PARTIAL_GOOD
*
* @custdesc A problem occured during IPL of the system:
* Internal Firmware Error
- * @userdata1 target type attribute
- * @userdata2 HUID of the target
+ * @userdata1[00:31] target type attribute
+ * @userdata1[32:63] HUID of the target
+ * @userdata2 Number of rules for this target type
*/
l_errl = hwasError(
ERRL_SEV_UNRECOVERABLE,
HWAS::MOD_FIND_RULES_FOR_TARGET,
HWAS::RC_NO_PG_LOGIC,
- i_target->getAttr<TARGETING::ATTR_TYPE>(),
- get_huid(i_target));
+ userdata1,
+ pgRules_map.size());
}
return l_errl;
@@ -481,8 +493,7 @@ namespace PARTIAL_GOOD
!= TARGETING::OPTICS_CONFIG_MODE_SMP)
&& ((i_pgData[N3_PG_INDEX] & NPU_R1_PG_MASK) != ALL_OFF_AG_MASK))
{
- TRACFCOMP(HWAS::g_trac_imp_hwas,
- "pDesc 0x%.8X - OBUS_BRICK pgData[%d]: "
+ HWAS_INF( "pDesc 0x%.8X - OBUS_BRICK pgData[%d]: "
"actual 0x%04X, expected 0x%04X - bad",
i_desc->getAttr<TARGETING::ATTR_HUID>(),
N3_PG_INDEX,
diff --git a/src/usr/hwas/hwasPlat.C b/src/usr/hwas/hwasPlat.C
index bea5b4d8f..1cea60415 100644
--- a/src/usr/hwas/hwasPlat.C
+++ b/src/usr/hwas/hwasPlat.C
@@ -43,13 +43,16 @@
#include <sys/misc.h>
#include <pnor/pnorif.H>
+#include <fapiwrap/fapiWrapif.H>
#include <hwas/common/hwas_reasoncodes.H>
#include <targeting/common/utilFilter.H>
#include <fsi/fsiif.H>
-#include <config.h>
#include <targeting/common/targetservice.H>
#include <chipids.H>
+#include <vpd/spdenums.H>
+
+#include <map>
#ifdef CONFIG_SUPPORT_EEPROM_CACHING
#include <i2c/eepromif.H>
@@ -85,13 +88,19 @@ errlHndl_t platReadIDEC(const TargetHandle_t &i_target)
// Call over to the target-specific layer since every chip can have
// unique registers
size_t sz = 0;
- errlHndl_t l_errl =
- DeviceFW::deviceWrite(i_target,
- nullptr,
- sz,
- DEVICE_IDEC_ADDRESS());
+ errlHndl_t errl = nullptr;
- return l_errl;
+ // Pass a 1 as va_arg to signal phase 1 of ocmbIDEC to execute.
+ // Other IDEC functions will ignore this argument.
+ const uint64_t Phase1 = 1;
+ errl = DeviceFW::deviceWrite(i_target,
+ nullptr,
+ sz,
+ DEVICE_IDEC_ADDRESS(),
+ Phase1);
+
+
+ return errl;
}
/**
@@ -234,6 +243,70 @@ DEVICE_REGISTER_ROUTE(DeviceFW::WRITE,
TARGETING::TYPE_MEMBUF,
cfamIDEC);
+/**
+ * @brief During early IPL the OCMB isn't able to be read from so this function,
+ * executed during discover targets, will read from the SPD and set the
+ * CHIP_ID, EC, and HDAT_EC attributes with what is found there.
+ *
+ * @param[in] i_target Presence detect target
+ *
+ * @return errlHndl_t An error log if reading from the SPD failed.
+ * Otherwise, other errors are predictive and
+ * committed. So nullptr will be returned in those
+ * cases and on success.
+ */
+errlHndl_t ocmbIdecPhase1(const TARGETING::TargetHandle_t& i_target);
+
+/**
+ * @brief Once the OCMB is able to be read from the second phase will execute
+ * and cross-check the data given from the SPD is consistent with what
+ * was read from the chip itself. If the data is not consistent then the
+ * CHIP_ID, EC, and HDAT_EC attributes will be updated with what was
+ * found from the OCMB read since that data would be correct.
+ *
+ * @param[in] i_target Presence detect target
+ *
+ * @return errlHndl_t An error log if reading from the OCMB ID/EC
+ * register failed. Otherwise, other errors are
+ * predictive and committed. So nullptr will be
+ * returned in those cases and on success.
+ */
+errlHndl_t ocmbIdecPhase2(const TARGETING::TargetHandle_t& i_target);
+
+/**
+ * @brief Read the chipid and EC/DD-level for OCMB chips and set the attributes.
+ * In this function there are two phases that are executed at different
+ * times during IPL. The OCMB is held in reset and unable to be read from
+ * during early IPL. So the first phase, executed during discover
+ * targets, will read from the SPD and set the attributes with what is
+ * found there. Once the OCMB is able to be read from the second phase
+ * will execute and cross-check the data given from the SPD is consistent
+ * with what was read from the chip itself. If the data is not consistent
+ * then the attributes will be updated with what was found from the OCMB
+ * read since that data would be correct.
+ *
+ * @param[in] i_opType Operation type, see DeviceFW::OperationType
+ * in driverif.H
+ *
+ * @param[in] i_target Presence detect target
+ *
+ * @param[in/out] io_buffer Unused by this function
+ *
+ * @param[in/out] io_buflen Unused by this function
+ *
+ * @param[in] i_accessType DeviceFW::AccessType enum (userif.H)
+ *
+ * @param[in] i_args This is an argument list for DD framework.
+ * In this function, there is one argument to
+ * signal which phase to execute.
+ *
+ * @return errlHndl_t If there is an issue while reading from the SPD
+ * or the OCMB chip, or an unexpected memory
+ * interface type then this function will return an
+ * error. Otherwise, all other errors are
+ * predictive and committed. So nullptr will be
+ * returned in that case or on success.
+ */
errlHndl_t ocmbIDEC(DeviceFW::OperationType i_opType,
TARGETING::Target* i_target,
void* io_buffer,
@@ -241,16 +314,456 @@ errlHndl_t ocmbIDEC(DeviceFW::OperationType i_opType,
int64_t i_accessType,
va_list i_args)
{
- // for now just hardcode the answer to something explicitly invalid
- uint8_t l_ec = INVALID__ATTR_EC;
- i_target->setAttr<TARGETING::ATTR_EC>(l_ec);
- i_target->setAttr<TARGETING::ATTR_HDAT_EC>(l_ec);
+ errlHndl_t error = nullptr;
+
+ // Determine which phase of this function to run.
+ uint64_t phase = va_arg(i_args, uint64_t);
+
+ // Execute the correct phase based on the va_arg given.
+ if (phase == 1)
+ {
+ error = ocmbIdecPhase1(i_target);
+ }
+ else
+ {
+ error = ocmbIdecPhase2(i_target);
+ }
+
+
+ return error;
+}
+
+/**
+ * @brief This is a small helper function that the ocmb IDEC functions use to
+ * add all the proper callouts and commit errorlogs.
+ *
+ * @param[in] i_target Presence detect target
+ *
+ * @param[in] io_error The error log to be committed
+ *
+ */
+void ocmbErrlCommit(const TARGETING::TargetHandle_t& i_target,
+ errlHndl_t& io_error)
+{
+ io_error->addHwCallout(i_target,
+ SRCI_PRIORITY_HIGH,
+ NO_DECONFIG,
+ GARD_NULL);
+
+ io_error->addPartCallout(i_target,
+ VPD_PART_TYPE,
+ SRCI_PRIORITY_MED,
+ NO_DECONFIG,
+ GARD_NULL);
+
+ io_error->addProcedureCallout(EPUB_PRC_HB_CODE,
+ SRCI_PRIORITY_LOW);
- // we can assume this is an Explorer chip though
- uint32_t l_id = POWER_CHIPID::EXPLORER_16;
- i_target->setAttr<TARGETING::ATTR_CHIP_ID>(l_id);
+ ERRORLOG::errlCommit(io_error, HWAS_COMP_ID);
+
+}
+
+/**
+ * @brief This helper function will lookup the chip id and ec levels of
+ * a given OCMB based on what is found in a provided SPD buffer.
+ * The target is passed along for trace information.
+ *
+ * @param[in] i_target OCMB target we are looking up IDEC for
+ *
+ * @param[in] i_spdBuffer Buffer of at least SPD::OCMB_SPD_EFD_COMBINED_SIZE
+ * bytes of the given OCMB's SPD
+ *
+ * @param[out] o_chipId Chip Id associated with the given OCMB
+ * (see src/import/chips/common/utils/chipids.H)
+ *
+ * @param[out] o_ec EC level associated with the given OCMB
+ *
+ * @return nullptr if success, error log otherwise
+ *
+ */
+errlHndl_t getOcmbIdecFromSpd(const TARGETING::TargetHandle_t& i_target,
+ uint8_t * i_spdBuffer,
+ uint16_t& o_chipId,
+ uint8_t& o_ec)
+{
+ errlHndl_t l_errl = nullptr;
+ // These bytes are used for FFDC and verification purposes.
+ const size_t SPD_REVISION_OFFSET = 1;
+ const size_t DRAM_INTERFACE_TYPE_OFFSET = 2;
+ const size_t MEMORY_MODULE_INTERFACE_TYPE_OFFSET = 3;
+
+ // This is the value that signifies the SPD we read is for a DDIMM.
+ const uint8_t DDIMM_MEMORY_INTERFACE_TYPE = 0x0A;
+
+ const uint8_t l_spdModuleRevision =
+ *(i_spdBuffer + SPD_REVISION_OFFSET);
+
+ const uint8_t l_spdDRAMInterfaceType =
+ *(i_spdBuffer + DRAM_INTERFACE_TYPE_OFFSET);
+
+ const uint8_t l_spdMemoryInterfaceType =
+ *(i_spdBuffer + MEMORY_MODULE_INTERFACE_TYPE_OFFSET);
+
+ // Byte 1 SPD Module Revision
+ // Byte 2 DRAM Interface Type Presented or Emulated
+ // Byte 3 Memory Module Interface Type
+ const uint32_t SPD_FFDC_BYTES = TWO_UINT16_TO_UINT32(
+ TWO_UINT8_TO_UINT16(l_spdModuleRevision, l_spdDRAMInterfaceType),
+ TWO_UINT8_TO_UINT16(l_spdMemoryInterfaceType, 0));
+
+ do{
+
+ // Since the byte offsets used to get the IDEC info out of the SPD are
+ // specific to the DDIMM interface type we must first verify that we
+ // read from an SPD of that type.
+ if (DDIMM_MEMORY_INTERFACE_TYPE != l_spdMemoryInterfaceType)
+ {
+ HWAS_ERR("getOcmbIdecFromSpd> memory module interface type "
+ "didn't match the expected type. "
+ "Expected 0x%.2X, Actual 0x%.2X",
+ DDIMM_MEMORY_INTERFACE_TYPE,
+ l_spdMemoryInterfaceType);
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_OCMB_IDEC
+ * @reasoncode RC_OCMB_INTERFACE_TYPE_MISMATCH
+ * @userdata1[0:7] SPD Module Revision
+ * @userdata1[8:15] DRAM Interface Type Presented or Emulated
+ * @userdata1[16:23] Memory Module Interface Type
+ * @userdata1[24:31] Unused
+ * @userdata1[32:63] Expected memory interface type
+ * @userdata2 HUID of OCMB target
+ * @devdesc The memory interface type read from the SPD did
+ * not match the DDIMM value. Setting the
+ * appropriate IDEC values for this target cannot
+ * continue.
+ * @custdesc Invalid or unsupported memory card installed.
+ */
+ l_errl = hwasError(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_OCMB_IDEC,
+ RC_OCMB_INTERFACE_TYPE_MISMATCH,
+ TWO_UINT32_TO_UINT64(SPD_FFDC_BYTES,
+ DDIMM_MEMORY_INTERFACE_TYPE),
+ TARGETING::get_huid(i_target));
+
+ l_errl->addProcedureCallout(EPUB_PRC_HB_CODE,
+ SRCI_PRIORITY_LOW);
+
+ l_errl->addHwCallout(i_target,
+ SRCI_PRIORITY_HIGH,
+ NO_DECONFIG,
+ GARD_NULL);
+
+
+ break;
+ }
+
+ // SPD IDEC info is in the following three bytes
+ const size_t SPD_ID_LEAST_SIGNIFICANT_BYTE_OFFSET = 198;
+ const size_t SPD_ID_MOST_SIGNIFICANT_BYTE_OFFSET = 199;
+ const size_t DMB_REV_OFFSET = 200;
+
+ // Get the ID from the SPD and verify that it matches what we read from
+ // the IDEC register.
+ uint16_t l_spdId = TWO_UINT8_TO_UINT16(
+ *(i_spdBuffer + SPD_ID_LEAST_SIGNIFICANT_BYTE_OFFSET),
+ *(i_spdBuffer + SPD_ID_MOST_SIGNIFICANT_BYTE_OFFSET));
+
+ // Bytes 200 of the SPD contains the DMB Revision, this is essentially the
+ // OCMB manufacture's version of the chip. The manufacture can define any
+ // format for this field and we must add special logic to convert the
+ // manufacture's DMB_REV to the EC level IBM is familiar with.
+ uint8_t l_spdDmbRev = *(i_spdBuffer + DMB_REV_OFFSET);
+
+ HWAS_INF("getOcmbIdecFromSpd> OCMB 0x%.8x l_spdId = 0x%.4X l_spdDmbRev = 0x%.2x",
+ TARGETING::get_huid(i_target), l_spdId, l_spdDmbRev);
+
+ if (DDIMM_DMB_ID::EXPLORER == l_spdId)
+ {
+ o_chipId = POWER_CHIPID::EXPLORER_16;
+ // Must convert Explorer's versioning into IBM-style EC levels.
+ // Explorer vendor has stated versioning will start at 0xA0 and increment
+ // 1st nibble for major revisions and 2nd nibble by 1 for minor revisions
+ // Examples :
+ // Version 0xA0 = EC 0x10
+ // Version 0xA1 = EC 0x11
+ // Version 0xB2 = EC 0x22
+
+ // Resulting formula from pattern in examples above is as follows:
+ o_ec = (l_spdDmbRev - 0x90);
+ }
+ else if (DDIMM_DMB_ID::GEMINI == l_spdId)
+ {
+ o_chipId = POWER_CHIPID::GEMINI_16;
+
+ HWAS_ASSERT(l_spdDmbRev == 0x0,
+ "Invalid Gemini DMB Revision Number, expected to find 0x0 at byte 200 in Gemini SPD");
+
+ // 0x10 is the only valid EC level for Gemini cards. If we find 0x0 @ byte 200 in
+ // the Gemini SPD then we will return 0x10 as the EC level
+ o_ec = 0x10;
+ }
+ else
+ {
+ HWAS_ERR("getOcmbIdecFromSpd> Unknown OCMB chip type discovered in SPD "
+ "ID=0x%.4X OCMB HUID 0x%.8x",
+ l_spdId,
+ TARGETING::get_huid(i_target));
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_OCMB_IDEC
+ * @reasoncode RC_OCMB_UNKNOWN_CHIP_TYPE
+ * @userdata1[0:7] SPD Module Revision
+ * @userdata1[8:15] DRAM Interface Type Presented or Emulated
+ * @userdata1[16:23] Memory Module Interface Type
+ * @userdata1[24:31] Unused
+ * @userdata1[32:63] SPD Chip Id
+ * @userdata2 HUID of OCMB target
+ * @devdesc The ID read from the SPD didn't match any known
+ * OCMB chip types.
+ * @custdesc Unsupported memory installed.
+ */
+ l_errl = hwasError(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ MOD_OCMB_IDEC_PHASE_1,
+ RC_OCMB_UNKNOWN_CHIP_TYPE,
+ TWO_UINT32_TO_UINT64(SPD_FFDC_BYTES, l_spdId),
+ TARGETING::get_huid(i_target));
+
+ break;
+ }
+
+ }while(0);
+
+ return l_errl;
+
+}
+
+
+errlHndl_t ocmbIdecPhase1(const TARGETING::TargetHandle_t& i_target)
+{
+ errlHndl_t l_errl = nullptr;
+
+ // Allocate buffer to hold SPD and init to 0
+ size_t l_spdBufferSize = SPD::DDIMM_DDR4_SPD_SIZE;
+ uint8_t* l_spdBuffer = new uint8_t[l_spdBufferSize];
+ memset(l_spdBuffer, 0, l_spdBufferSize);
+ uint16_t l_chipId = 0;
+ uint8_t l_chipEc = 0;
+
+ do {
+
+ // Read the SPD off the ocmb but skip reading the EFD to save time.
+ l_errl = deviceRead(i_target,
+ l_spdBuffer,
+ l_spdBufferSize,
+ DEVICE_SPD_ADDRESS(SPD::ENTIRE_SPD_WITHOUT_EFD));
+
+ // If unable to retrieve the SPD buffer then can't
+ // extract the IDEC data, so return error.
+ if (l_errl != nullptr)
+ {
+ HWAS_ERR("ocmbIdecPhase1> Error while trying to read "
+ "ENTIRE SPD from 0x%.08X ",
+ TARGETING::get_huid(i_target));
+ break;
+ }
+
+ // Make sure we got back the size we were expecting.
+ assert(l_spdBufferSize == SPD::DDIMM_DDR4_SPD_SIZE,
+ "ocmbIdecPhase1> OCMB SPD read size %d "
+ "doesn't match the expected size %d",
+ l_spdBufferSize,
+ SPD::DDIMM_DDR4_SPD_SIZE);
+
+ l_errl = getOcmbIdecFromSpd(i_target,
+ l_spdBuffer,
+ l_chipId,
+ l_chipEc);
+
+ // If we were unable to read the IDEC information from the SPD
+ // then break out early and do not set the associated attributes
+ if (l_errl != nullptr)
+ {
+ HWAS_ERR("ocmbIdecPhase1> Error while trying to parse "
+ "chip id and ec values from SPD read from OCMB 0x%.08X ",
+ TARGETING::get_huid(i_target));
+ break;
+ }
+
+ HWAS_INF("ocmbIdecPhase1> Read Chip ID = 0x%x Chip EC = 0x%x from target 0x%.08X",
+ l_chipId, l_chipEc, TARGETING::get_huid(i_target) );
+
+ // set the explorer chip EC attributes.
+ i_target->setAttr<TARGETING::ATTR_EC>(l_chipEc);
+ i_target->setAttr<TARGETING::ATTR_HDAT_EC>(l_chipEc);
+
+ // set the explorer chip id attribute.
+ i_target->setAttr<TARGETING::ATTR_CHIP_ID>(l_chipId);
+
+ } while(0);
+
+ delete[] l_spdBuffer;
+ return l_errl;
+
+}
+
+errlHndl_t ocmbIdecPhase2(const TARGETING::TargetHandle_t& i_target)
+{
+ const uint32_t GEM_IDEC_SCOM_REGISTER = 0x0801240e;
+ const TARGETING::ATTR_CHIP_ID_type l_chipIdFromSpd =
+ i_target->getAttr<TARGETING::ATTR_CHIP_ID>();
+
+ errlHndl_t l_errl = nullptr;
+ uint64_t l_idec = 0;
+ size_t l_op_size = sizeof(l_idec);
+ uint8_t l_ec = 0;
+ uint16_t l_id = 0;
+
+ do {
+
+ if(l_chipIdFromSpd == POWER_CHIPID::EXPLORER_16)
+ {
+ // Call platform independent lookup for Explorer OCMBs
+ l_errl = FAPIWRAP::explorer_getidec(i_target, l_id, l_ec);
+
+ if (l_errl != nullptr)
+ {
+ HWAS_ERR("ocmbIdecPhase2> explorer OCMB 0x%.8X - failed to read ID/EC",
+ TARGETING::get_huid(i_target));
+
+ break;
+ }
+ }
+ else
+ {
+ // read the register containing IDEC info on Gemini OCMBs
+ l_errl = DeviceFW::deviceRead(i_target,
+ &l_idec,
+ l_op_size,
+ DEVICE_SCOM_ADDRESS(GEM_IDEC_SCOM_REGISTER));
+
+ if (l_errl != nullptr)
+ {
+ HWAS_ERR("ocmbIdecPhase2> gemini OCMB 0x%.8X - failed to read ID/EC",
+ TARGETING::get_huid(i_target));
+
+ break;
+ }
+
+ // Need to convert Gemini's IDEC register from MmL000CC
+ // to cfam standard format MLmCC000
+ uint32_t l_major = 0xF0000000 & static_cast<uint32_t>(l_idec);
+ uint32_t l_minor = 0x0F000000 & static_cast<uint32_t>(l_idec);
+ uint32_t l_location = 0x00F00000 & static_cast<uint32_t>(l_idec);
+ l_idec = (l_major | (l_location << 4) | (l_minor >> 4)
+ | ((l_idec & 0x000000FF) << 12));
+ // Parse out the information we need
+ l_ec = POWER_CHIPID::extract_ddlevel(l_idec);
+ l_id = POWER_CHIPID::extract_chipid16(l_idec);
+ }
+
+ HWAS_INF("ocmbIdecPhase2> OCMB 0x%.8X - read ID/EC successful. "
+ "ID = 0x%.4X, EC = 0x%.2X, Full IDEC 0x%x",
+ TARGETING::get_huid(i_target),
+ l_id,
+ l_ec,
+ l_idec);
+
+ if (l_id != l_chipIdFromSpd)
+ {
+ HWAS_ERR("ocmbIdecPhase2> OCMB Chip Id and associated SPD Chip Id "
+ "don't match: OCMB ID=0x%.4X; SPD ID=0x%.4X;",
+ l_id,
+ l_chipIdFromSpd);
+
+ HWAS_ERR("ocmbIdecPhase2> Previous CHIP_ID 0x%.4X was set based on values from "
+ "SPD read will now be overwritten with values from OCMB IDEC register "
+ "ID=0x%.4X",
+ l_chipIdFromSpd,
+ l_id);
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_OCMB_IDEC
+ * @reasoncode RC_OCMB_CHIP_ID_MISMATCH
+ * @userdata1[00:31] OCMB IDEC Register ID
+ * @userdata1[32:63] IDEC ID found in OCMB's SPD
+ * @userdata2[32:63] HUID of OCMB target
+ * @devdesc The IDEC info read from the OCMB and SPD
+ * did not match the expected values.
+ * @custdesc Firmware Error
+ */
+ l_errl = hwasError(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ MOD_OCMB_IDEC,
+ RC_OCMB_CHIP_ID_MISMATCH,
+ TWO_UINT32_TO_UINT64(l_id, l_chipIdFromSpd),
+ TARGETING::get_huid(i_target));
+
+ // Add callouts and commit
+ ocmbErrlCommit(i_target, l_errl);
+
+ // Since there was an error then the ID values don't agree between
+ // the OCMB read and the SPD read. Since the OCMB has the correct
+ // answer, set the attributes to the values read from that instead
+ // of the SPD.
+ i_target->setAttr<TARGETING::ATTR_CHIP_ID>(l_id);
+ }
+
+ const uint8_t l_ecFromSpd = i_target->getAttr<TARGETING::ATTR_EC>();
+
+ if (l_ec != l_ecFromSpd)
+ {
+ HWAS_ERR("ocmbIdecPhase2> OCMB Revision and associated SPD "
+ "Revision don't match: OCMB EC=0x%.2X; "
+ "SPD EC=0x%.2X; ",
+ l_ec, l_ecFromSpd);
+
+ HWAS_ERR("ocmbIdecPhase2> Previous EC and HDAT_EC attributes 0x%.2X,"
+ " which were set with values found in SPD will be overwritten"
+ " with value from OCMB IDEC register ID=0x%.2X",
+ l_ecFromSpd,
+ l_ec);
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_OCMB_IDEC
+ * @reasoncode RC_OCMB_SPD_REVISION_MISMATCH
+ * @userdata1[00:31] OCMB IDEC register EC
+ * @userdata1[32:63] EC found in OCMB's SPD
+ * @userdata2[00:31] OCMB Chip ID Attribute
+ * @userdata2[32:63] HUID of OCMB target
+ * @devdesc The EC (Revision) info read from the OCMB and
+ * SPD did not match the expected values.
+ * @custdesc Firmware Error
+ */
+ l_errl = hwasError(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ MOD_OCMB_IDEC,
+ RC_OCMB_SPD_REVISION_MISMATCH,
+ TWO_UINT32_TO_UINT64(l_ec, l_ecFromSpd),
+ TWO_UINT32_TO_UINT64(
+ i_target->getAttr<TARGETING::ATTR_CHIP_ID>(),
+ TARGETING::get_huid(i_target)));
+
+ // Add callouts and commit
+ ocmbErrlCommit(i_target, l_errl);
+
+ // Since there was an error then the EC values don't agree between
+ // the OCMB read and the SPD read. Since the OCMB has the correct
+ // answer, set the attributes to the values read from that instead
+ // of the SPD.
+ i_target->setAttr<TARGETING::ATTR_EC>(l_ec);
+ i_target->setAttr<TARGETING::ATTR_HDAT_EC>(l_ec);
+ }
+
+ } while(0);
+
+ return l_errl;
- return nullptr;
}
// Register the presence detect function with the device framework
@@ -628,7 +1141,10 @@ errlHndl_t platPresenceDetect(TargetHandleList &io_targets)
DEVICE_CACHE_EEPROM_ADDRESS(present, EEPROM::VPD_PRIMARY));
errl = deviceRead(pTarget, &present, presentSize,
DEVICE_CACHE_EEPROM_ADDRESS(present, EEPROM::VPD_PRIMARY));
- errlCommit(errl, HWAS_COMP_ID);
+ if( errl )
+ {
+ errlCommit(errl, HWAS_COMP_ID);
+ }
// errl is now null, move on to next target
}
#endif
diff --git a/src/usr/hwas/hwasPlatDeconfigGard.C b/src/usr/hwas/hwasPlatDeconfigGard.C
index 0bdbb4c24..3f5a461eb 100644
--- a/src/usr/hwas/hwasPlatDeconfigGard.C
+++ b/src/usr/hwas/hwasPlatDeconfigGard.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -41,7 +41,6 @@
#include <vpd/mvpdenums.H>
#include <stdio.h>
#include <sys/mm.h>
-#include <config.h>
#include <initservice/istepdispatcherif.H>
#include <initservice/initserviceif.H>
diff --git a/src/usr/hwas/test/hwas1test.H b/src/usr/hwas/test/hwas1test.H
index 6784d4408..306fea006 100644
--- a/src/usr/hwas/test/hwas1test.H
+++ b/src/usr/hwas/test/hwas1test.H
@@ -48,8 +48,74 @@
#include <targeting/common/commontargeting.H>
#include <targeting/common/utilFilter.H>
+const uint16_t pgDataAllGoodAxone[HWAS::VPD_CP00_PG_DATA_ENTRIES] =
+ {(uint16_t)HWAS::VPD_CP00_PG_FSI_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_PERVASIVE_GOOD_AXONE,
+ (uint16_t)HWAS::VPD_CP00_PG_N0_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_N1_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_N2_GOOD_AXONE,
+ (uint16_t)HWAS::VPD_CP00_PG_N3_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_XBUS_GOOD_CUMULUS,
+ (uint16_t)HWAS::VPD_CP00_PG_MCxx_GOOD_AXONE,
+ (uint16_t)HWAS::VPD_CP00_PG_MCxx_GOOD_AXONE,
+ (uint16_t)HWAS::VPD_CP00_PG_OBUS_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_OBUS_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_OBUS_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_OBUS_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_PCIx_GOOD[0],
+ (uint16_t)HWAS::VPD_CP00_PG_PCIx_GOOD[1],
+ (uint16_t)HWAS::VPD_CP00_PG_PCIx_GOOD[2],
+ (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD};
+
// Buffer with all good data (CUMULUS chip)
-const uint16_t pgDataAllGood[HWAS::VPD_CP00_PG_DATA_ENTRIES] =
+const uint16_t pgDataAllGoodCumulus[HWAS::VPD_CP00_PG_DATA_ENTRIES] =
{(uint16_t)HWAS::VPD_CP00_PG_FSI_GOOD,
(uint16_t)HWAS::VPD_CP00_PG_PERVASIVE_GOOD,
(uint16_t)HWAS::VPD_CP00_PG_N0_GOOD,
@@ -371,9 +437,20 @@ public:
? (uint16_t)VPD_CP00_PG_RESERVED_GOOD
: (uint16_t)VPD_CP00_PG_OBUS_GOOD;
uint16_t pgData[VPD_CP00_PG_DATA_ENTRIES];
- memcpy(pgData,
- pgDataAllGood,
- VPD_CP00_PG_DATA_LENGTH);
+
+ if(MODEL_AXONE == l_model)
+ {
+ memcpy(pgData,
+ pgDataAllGoodAxone,
+ VPD_CP00_PG_DATA_LENGTH);
+ }
+ else
+ {
+ memcpy(pgData,
+ pgDataAllGoodCumulus,
+ VPD_CP00_PG_DATA_LENGTH);
+ }
+
pgData[VPD_CP00_PG_XBUS_INDEX] = l_xbus;
pgData[VPD_CP00_PG_OB0_INDEX + 1] = l_obus12;
pgData[VPD_CP00_PG_OB0_INDEX + 2] = l_obus12;
@@ -460,9 +537,18 @@ public:
l_mask);
}
- // Restore the "all good" data
- pgData[VPD_CP00_PG_PERVASIVE_INDEX] =
- (uint16_t)VPD_CP00_PG_PERVASIVE_GOOD;
+ if(MODEL_AXONE == l_model)
+ {
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_PERVASIVE_INDEX] =
+ (uint16_t)VPD_CP00_PG_PERVASIVE_GOOD_AXONE;
+ }
+ else
+ {
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_PERVASIVE_INDEX] =
+ (uint16_t)VPD_CP00_PG_PERVASIVE_GOOD;
+ }
}
TS_INFO( "testHWASisChipFunctional: N0 is not functional");
@@ -562,6 +648,19 @@ public:
// Restore the "all good" data
pgData[VPD_CP00_PG_N2_INDEX] =
(uint16_t)VPD_CP00_PG_N2_GOOD;
+
+ if(MODEL_AXONE == l_model)
+ {
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_N2_INDEX] =
+ (uint16_t)VPD_CP00_PG_N2_GOOD_AXONE;
+ }
+ else
+ {
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_N2_INDEX] =
+ (uint16_t)VPD_CP00_PG_N2_GOOD;
+ }
}
TS_INFO( "testHWASisChipFunctional: N3 is not functional");
@@ -686,9 +785,20 @@ public:
? (uint16_t)VPD_CP00_PG_RESERVED_GOOD
: (uint16_t)VPD_CP00_PG_OBUS_GOOD;
uint16_t pgData[VPD_CP00_PG_DATA_ENTRIES];
- memcpy(pgData,
- pgDataAllGood,
- VPD_CP00_PG_DATA_LENGTH);
+
+ if(MODEL_AXONE == l_model)
+ {
+ memcpy(pgData,
+ pgDataAllGoodAxone,
+ VPD_CP00_PG_DATA_LENGTH);
+ }
+ else
+ {
+ memcpy(pgData,
+ pgDataAllGoodCumulus,
+ VPD_CP00_PG_DATA_LENGTH);
+ }
+
pgData[VPD_CP00_PG_XBUS_INDEX] = l_xbus;
pgData[VPD_CP00_PG_OB0_INDEX + 1] = l_obus12;
pgData[VPD_CP00_PG_OB0_INDEX + 2] = l_obus12;
@@ -1107,9 +1217,19 @@ public:
pDesc->getAttr<ATTR_HUID>());
}
- // Restore the "all good" data
- pgData[l_indexMC] = VPD_CP00_PG_MCxx_GOOD;
+ if(MODEL_AXONE == l_model)
+ {
+ // Restore the "all good" data
+ pgData[l_indexMC] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE;
+ }
+ else
+ {
+ // Restore the "all good" data
+ pgData[l_indexMC] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ }
}
break;
@@ -1208,8 +1328,18 @@ public:
pDesc->getAttr<ATTR_HUID>());
}
- // Restore the "all good" data
- pgData[l_indexMC] = VPD_CP00_PG_MCxx_GOOD;
+ if(MODEL_AXONE == l_model)
+ {
+ // Restore the "all good" data
+ pgData[l_indexMC] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE;
+ }
+ else
+ {
+ // Restore the "all good" data
+ pgData[l_indexMC] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ }
}
break;
@@ -1307,8 +1437,18 @@ public:
pDesc->getAttr<ATTR_HUID>());
}
- // Restore the "all good" data
- pgData[l_indexMC] = VPD_CP00_PG_MCxx_GOOD;
+ if(MODEL_AXONE == l_model)
+ {
+ // Restore the "all good" data
+ pgData[l_indexMC] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE;
+ }
+ else
+ {
+ // Restore the "all good" data
+ pgData[l_indexMC] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ }
}
break;
@@ -1406,8 +1546,18 @@ public:
pDesc->getAttr<ATTR_HUID>());
}
- // Restore the "all good" data
- pgData[l_indexMC] = VPD_CP00_PG_MCxx_GOOD;
+ if(MODEL_AXONE == l_model)
+ {
+ // Restore the "all good" data
+ pgData[l_indexMC] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE;
+ }
+ else
+ {
+ // Restore the "all good" data
+ pgData[l_indexMC] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ }
}
break;
@@ -1506,8 +1656,18 @@ public:
pDesc->getAttr<ATTR_HUID>());
}
- // Restore the "all good" data
- pgData[l_indexMC] = VPD_CP00_PG_MCxx_GOOD;
+ if(MODEL_AXONE == l_model)
+ {
+ // Restore the "all good" data
+ pgData[l_indexMC] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE;
+ }
+ else
+ {
+ // Restore the "all good" data
+ pgData[l_indexMC] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ }
}
break;
@@ -1871,9 +2031,18 @@ public:
pDesc->getAttr<ATTR_HUID>());
}
- // Restore the "all good" data
- pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]] =
- (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ if(MODEL_AXONE == l_model)
+ {
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE;
+ }
+ else
+ {
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ }
}
@@ -1987,9 +2156,18 @@ public:
pDesc->getAttr<ATTR_HUID>());
}
- // Restore the "all good" data
- pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit]] =
- (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ if(MODEL_AXONE == l_model)
+ {
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit]] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE;
+ }
+ else
+ {
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit]] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ }
}
// TEST WITH BAD MAGIC PORT (MCA0 or MCA4)
@@ -2038,8 +2216,18 @@ public:
pDesc->getAttr<ATTR_HUID>());
}
- pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit / 2]] =
- (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ if(MODEL_AXONE == l_model)
+ {
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit / 2]] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE;
+ }
+ else
+ {
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit / 2]] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ }
// Try bad MCA Port setting for MCA2/3 & MCA6/7
if ( VPD_CP00_PG_MCxx_IOMyy[l_chipUnit / 2] !=
@@ -2147,14 +2335,26 @@ public:
}
// Restore the "all good" data
- pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]] =
- (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ if(MODEL_AXONE == l_model)
+ {
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE;
+ }
+ else
+ {
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ }
+
}
break;
case TYPE_OBUS_BRICK:
{
+#ifndef CONFIG_AXONE //@todo-RTC:208518 - Add Axone OBUS_BRICK rules
//Two cases here:
//OBUS==SMP --> Target should be present regardless
// of PG
@@ -2186,7 +2386,7 @@ public:
TS_FAIL("testHWAS"
"checkPartialGoodForDescendants> "
"functional = 0x%x, should be true "
- "because"
+ "because "
"OBUS_BRICK is SMP: PG = 0x%04x. "
"pDesc HUID 0x%.8x",
checkPartialGoodForDescendants(
@@ -2211,7 +2411,7 @@ public:
TS_FAIL("testHWAS"
"checkPartialGoodForDescendants> "
"functional = 0x%x, should be "
- "false because"
+ "false because "
"OBUS_BRICK is NVLINK: PG = "
"0x%04x. "
"pDesc HUID 0x%.8x",
@@ -2227,10 +2427,12 @@ public:
pgData[VPD_CP00_PG_N3_INDEX] =
(uint16_t)VPD_CP00_PG_N3_GOOD;
+#endif
break;
}
case TYPE_NPU:
+#ifndef CONFIG_AXONE //@todo-RTC:208518 - Add Axone NPU rules
TS_INFO( "testHWAScheckPartialGoodForDescendants: "
"NPU is not functional");
pgData[VPD_CP00_PG_N3_INDEX] |=
@@ -2250,6 +2452,7 @@ public:
pgData[VPD_CP00_PG_N3_INDEX] =
(uint16_t)VPD_CP00_PG_N3_GOOD;
+#endif
break;
case TYPE_PERV:
diff --git a/src/usr/hwas/test/hwasGardTest.H b/src/usr/hwas/test/hwasGardTest.H
index 01c8d1735..1edc8a445 100644
--- a/src/usr/hwas/test/hwasGardTest.H
+++ b/src/usr/hwas/test/hwasGardTest.H
@@ -51,7 +51,7 @@
#define DISABLE_EX_UNIT_TESTS 1
//$$#define DISABLE_UNIT_TESTS 0
-#define DISABLE_OMI_UNIT_TESTS 0
+#define DISABLE_OMI_UNIT_TESTS 1
#if DISABLE_OMI_UNIT_TESTS
#define ENABLE_OMI_UNIT_TEST_1 0
diff --git a/src/usr/hwplibs/nest/nestmemutils.mk b/src/usr/hwplibs/nest/nestmemutils.mk
index 26b6a406c..9962f3b0e 100644
--- a/src/usr/hwplibs/nest/nestmemutils.mk
+++ b/src/usr/hwplibs/nest/nestmemutils.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2017,2018
+# Contributors Listed Below - COPYRIGHT 2017,2019
# [+] International Business Machines Corp.
#
#
@@ -26,15 +26,26 @@
ROOTPATH=../../../..
+P9_PROCEDURE_PATH = ${ROOTPATH}/src/import/chips/p9/procedures/
HWP_NEST_MEM_UTILS_PATH := ${ROOTPATH}/src/import/chips/p9/procedures/hwp/nest/
+EXP_COMMON_PATH = ${ROOTPATH}/src/import/chips/ocmb/explorer/common
+AXONE_PROCEDURE_PATH = ${ROOTPATH}/src/import/chips/p9a/procedures
EXTRAINCDIR += ${HWP_NEST_MEM_UTILS_PATH}
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2/
EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs
+EXTRAINCDIR += ${EXP_COMMON_PATH}/include/
+EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/
+EXTRAINCDIR += ${ROOTPATH}/src/import/
+EXTRAINCDIR += ${AXONE_PROCEDURE_PATH}/hwp/memory/
+EXTRAINCDIR += ${P9_PROCEDURE_PATH}/hwp/memory
VPATH += ${HWP_NEST_MEM_UTILS_PATH}
include ${ROOTPATH}/procedure.rules.mk
include ${HWP_NEST_MEM_UTILS_PATH}/p9_putmemproc.mk
+OBJS += $(if $(CONFIG_AXONE),p9a_throttle_sync.o,p9_throttle_sync.o)
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/i2c/eepromCache.C b/src/usr/i2c/eepromCache.C
index ef906302c..bbdddf334 100644
--- a/src/usr/i2c/eepromCache.C
+++ b/src/usr/i2c/eepromCache.C
@@ -30,17 +30,18 @@
#include <devicefw/driverif.H>
#include <errl/errlmanager.H>
#include <fsi/fsiif.H>
+#include <hwas/hwasPlat.H>
#include "i2c.H"
#include "eepromCache.H"
#include <i2c/i2cif.H>
-#include <i2c/eepromif.H>
+
#include <i2c/eepromddreasoncodes.H>
#include <initservice/initserviceif.H>
#include <initservice/initsvcreasoncodes.H>
#include <pnor/pnorif.H>
#include <vpd/vpd_if.H>
+
#include <errl/errludtarget.H>
-#include <config.h>
#ifdef CONFIG_CONSOLE
#include <console/consoleif.H>
#endif
@@ -53,6 +54,10 @@ extern trace_desc_t* g_trac_eeprom;
namespace EEPROM
{
+// Any time we access either any of the global variables defined below we want
+// to wrap the call in this mutex to avoid multi-threading issues
+mutex_t g_eecacheMutex = MUTEX_INITIALIZER;
+
// Global variable that will keep track of the virtual address which
// points to the start of the EECACHE section, and the size of this section.
// It is handy to keep these around so we do not need to look them up in the
@@ -63,166 +68,10 @@ uint64_t g_eecachePnorSize = 0;
// Global map which is used as a way to quickly look up the virtual address
// of a given eeprom's cached data in EECACHE section
// Key = eepromRecordHeader with unique info filled out
-// Value = virtual address pointing to the cached eeprom data in pnor
-std::map<eepromRecordHeader, uint64_t> g_cachedEeproms;
-
-// Any time we access either any of the global variables defined above we want
-// to wrap the call in this mutex to avoid multi-threading issues
-mutex_t g_eecacheMutex = MUTEX_INITIALIZER;
-
-uint64_t lookupEepromAddr(const eepromRecordHeader& i_eepromRecordHeader)
-{
- uint64_t l_vaddr = 0;
- std::map<eepromRecordHeader, uint64_t>::iterator l_it;
-
- // Wrap lookup in mutex because reads are not thread safe
- mutex_lock(&g_eecacheMutex);
- l_it = g_cachedEeproms.find(i_eepromRecordHeader);
- mutex_unlock(&g_eecacheMutex);
-
- if(l_it != g_cachedEeproms.end())
- {
- l_vaddr = l_it->second;
- }
-
- if(l_vaddr == 0)
- {
- TRACSSCOMP( g_trac_eeprom, "lookupEepromAddr() failed to find I2CM Huid: 0x%.08X, Port: 0x%.02X, Engine: 0x%.02X, Dev Addr: 0x%.02X, Mux Select: 0x%.02X, Size: 0x%.08X in g_cachedEeproms",
- i_eepromRecordHeader.completeRecord.i2c_master_huid,
- i_eepromRecordHeader.completeRecord.port,
- i_eepromRecordHeader.completeRecord.engine,
- i_eepromRecordHeader.completeRecord.devAddr,
- i_eepromRecordHeader.completeRecord.mux_select,
- i_eepromRecordHeader.completeRecord.cache_copy_size);
- }
- return l_vaddr;
-}
-
-errlHndl_t buildEepromRecordHeader(TARGETING::Target * i_target,
- eeprom_addr_t & io_eepromInfo,
- eepromRecordHeader & o_eepromRecordHeader)
-{
-
- TARGETING::Target * l_muxTarget = nullptr;
- TARGETING::Target * l_i2cMasterTarget = nullptr;
- TARGETING::TargetService& l_targetService = TARGETING::targetService();
- errlHndl_t l_errl = nullptr;
-
- do{
-
- l_errl = eepromReadAttributes(i_target, io_eepromInfo);
- if(l_errl)
- {
- TRACFCOMP( g_trac_eeprom,
- "buildEepromRecordHeader() error occured reading eeprom attributes for eepromType %d, target 0x%.08X, returning!!",
- io_eepromInfo.eepromRole,
- TARGETING::get_huid(i_target));
- l_errl->collectTrace(EEPROM_COMP_NAME);
- break;
- }
-
- // Grab the I2C mux target so we can read the HUID, if the target is NULL we will not be able
- // to lookup attribute to uniquely ID this eeprom so we will not cache it
- l_muxTarget = l_targetService.toTarget( io_eepromInfo.i2cMuxPath);
- if(l_muxTarget == nullptr)
- {
- TRACFCOMP( g_trac_eeprom,
- "buildEepromRecordHeader() Mux target associated with target 0x%.08X resolved to a nullptr , check attribute for eepromType %d. Skipping Cache",
- TARGETING::get_huid(i_target),
- io_eepromInfo.eepromRole);
- /*@
- * @errortype
- * @moduleid EEPROM_CACHE_EEPROM
- * @reasoncode EEPROM_I2C_MUX_PATH_ERROR
- * @userdata1 HUID of target we want to cache
- * @userdata2 Type of EEPROM we are caching
- * @devdesc buildEepromRecordHeader invalid mux target
- */
- l_errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- EEPROM_CACHE_EEPROM,
- EEPROM_I2C_MUX_PATH_ERROR,
- TARGETING::get_huid(i_target),
- io_eepromInfo.eepromRole,
- ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
- l_errl->collectTrace(EEPROM_COMP_NAME);
- break;
- }
-
- // Grab the I2C master target so we can read the HUID, if the target is NULL we will not be able
- // to lookup attribute to uniquely ID this eeprom so we will not cache it
- l_i2cMasterTarget = l_targetService.toTarget( io_eepromInfo.i2cMasterPath );
- if(l_i2cMasterTarget == nullptr)
- {
- TRACFCOMP( g_trac_eeprom,
- "buildEepromRecordHeader() I2C Master target associated with target 0x%.08X resolved to a nullptr , check attribute for eepromType %d. Skipping Cache ",
- TARGETING::get_huid(i_target),
- io_eepromInfo.eepromRole);
- /*@
- * @errortype
- * @moduleid EEPROM_CACHE_EEPROM
- * @reasoncode EEPROM_I2C_MASTER_PATH_ERROR
- * @userdata1 HUID of target we want to cache
- * @userdata2 Type of EEPROM we are caching
- * @devdesc buildEepromRecordHeader invalid master target
- */
- l_errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- EEPROM_CACHE_EEPROM,
- EEPROM_I2C_MASTER_PATH_ERROR,
- TARGETING::get_huid(i_target),
- io_eepromInfo.eepromRole,
- ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
- l_errl->collectTrace(EEPROM_COMP_NAME);
- break;
- }
-
- // This is what we will compare w/ when we are going through the existing
- // caches in the eeprom to see if we have already cached something
- // Or if no matches are found we will copy this into the header
- o_eepromRecordHeader.completeRecord.i2c_master_huid = l_i2cMasterTarget->getAttr<TARGETING::ATTR_HUID>();
- o_eepromRecordHeader.completeRecord.port = static_cast<uint8_t>(io_eepromInfo.port);
- o_eepromRecordHeader.completeRecord.engine = static_cast<uint8_t>(io_eepromInfo.engine);
- o_eepromRecordHeader.completeRecord.devAddr = static_cast<uint8_t>(io_eepromInfo.devAddr);
- o_eepromRecordHeader.completeRecord.mux_select = static_cast<uint8_t>(io_eepromInfo.i2cMuxBusSelector);
- o_eepromRecordHeader.completeRecord.cache_copy_size = static_cast<uint32_t>(io_eepromInfo.devSize_KB);
-
- // Do not set valid bit nor internal offset here as we do not have
- // enough information availible to determine
-
- }while(0);
-
- return l_errl;
-}
-
-// Do NOT allow adding/removing eeproms to cache during RT
-#ifndef __HOSTBOOT_RUNTIME
-
-bool addEepromToCachedList(const eepromRecordHeader & i_eepromRecordHeader)
-{
- bool l_matchFound = true;
- std::map<eepromRecordHeader, uint64_t>::iterator it;
-
- // Map accesses are not thread safe, make sure this is always wrapped in mutex
- mutex_lock(&g_eecacheMutex);
-
- if(g_cachedEeproms.find(i_eepromRecordHeader) == g_cachedEeproms.end())
- {
- g_cachedEeproms[i_eepromRecordHeader] = g_eecachePnorVaddr + i_eepromRecordHeader.completeRecord.internal_offset;
- TRACSSCOMP( g_trac_eeprom, "addEepromToCachedList() Adding I2CM Huid: 0x%.08X, Port: 0x%.02X, Engine: 0x%.02X, Dev Addr: 0x%.02X, Mux Select: 0x%.02X, Size: 0x%.08X to g_cachedEeproms",
- i_eepromRecordHeader.completeRecord.i2c_master_huid,
- i_eepromRecordHeader.completeRecord.port,
- i_eepromRecordHeader.completeRecord.engine,
- i_eepromRecordHeader.completeRecord.devAddr,
- i_eepromRecordHeader.completeRecord.mux_select,
- i_eepromRecordHeader.completeRecord.cache_copy_size);
- l_matchFound = false;
- }
-
- mutex_unlock(&g_eecacheMutex);
-
- return l_matchFound;
-}
+// Value = A struct of 2 uint64_t virtual addresses ,one points to header address
+// and other points to the location of the cache, and a byte indicating
+// if this eeprom's hardware has changed this IPL
+std::map<eepromRecordHeader, EeepromEntryMetaData_t> g_cachedEeproms;
/**
* @brief Lookup I2C information for given eeprom, check if eeprom exists in cache.
@@ -252,13 +101,19 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target,
bool l_updateHeader = true;
bool l_updateContents = true;
+ // Initially assume this is a new eeprom cache entry
+ bool l_newEntryDetected = true;
+
do{
// eepromReadAttributes keys off the eepromRole value
// to determine what attribute to lookup to get eeprom info
l_eepromInfo.eepromRole = i_eepromType;
// if the target is present, then this record is valid
- l_eepromRecordHeader.completeRecord.cached_copy_valid = i_present;
+ if(i_present)
+ {
+ l_eepromRecordHeader.completeRecord.cached_copy_valid = 1;
+ }
// buildEepromRecordHeader will call eepromReadAttributes to fill in l_eepromInfo
// with info looked up in attributes and also fill in l_eepromRecordHeader
@@ -271,7 +126,7 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target,
if(l_errl)
{
// buildEepromRecordHeader should have traced any relavent information if
- // is was needed, just break out and pass the error along
+ // it was needed, just break out and pass the error along
break;
}
@@ -310,7 +165,7 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target,
// if nothing has been cached before then version should
// be set to be the latest version of the struct available
l_eecacheSectionHeaderPtr->version = EECACHE_VERSION_LATEST;
- TRACFCOMP( g_trac_eeprom,
+ TRACDCOMP( g_trac_eeprom,
"cacheEeprom() Found Empty Cache, set version of cache structure to be 0x%.02x",
EECACHE_VERSION_1);
}
@@ -322,7 +177,7 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target,
// This means the start of first eeprom's cached data will be immediately
// following the end of the EECACHE header.
l_eecacheSectionHeaderPtr->end_of_cache = sizeof(eecacheSectionHeader);
- TRACFCOMP( g_trac_eeprom,
+ TRACDCOMP( g_trac_eeprom,
"cacheEeprom() Found Empty Cache, set end of cache to be 0x%.04x (End of ToC)",
sizeof(eecacheSectionHeader));
}
@@ -356,6 +211,9 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target,
// to be the current "end of cache" offset in the toc.
l_eepromRecordHeader.completeRecord.internal_offset = l_eecacheSectionHeaderPtr->end_of_cache;
l_eecacheSectionHeaderPtr->end_of_cache += l_eepromLen;
+
+ // Set cached_copy_valid to 0 until the cache contents actually gets loaded
+ l_recordHeaderToUpdate->completeRecord.cached_copy_valid = 0;
l_updateContents = i_present;
break;
}
@@ -366,6 +224,9 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target,
if( memcmp(l_recordHeaderToUpdate, &l_eepromRecordHeader, NUM_BYTE_UNIQUE_ID ) == 0 )
{
l_recordHeaderToUpdateIndex = i;
+ // We have matched with existing eeprom in the PNOR's EECACHE
+ // section. So we know this is not a new entry.
+ l_newEntryDetected = false;
if( l_recordHeaderToUpdate->completeRecord.cache_copy_size != l_eepromRecordHeader.completeRecord.cache_copy_size)
{
@@ -410,81 +271,192 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target,
#ifdef CONFIG_CONSOLE
CONSOLE::displayf(EEPROM_COMP_NAME,
- "New EEPROM size detected for an existing part, clearing EEPROM cache and performing reconfig loop");
+ "New EEPROM size detected for an existing part,"
+ "clearing EEPROM cache and performing reconfig loop");
#endif
INITSERVICE::doShutdown(INITSERVICE::SHUTDOWN_DO_RECONFIG_LOOP);
}
- //
- // At this point we have found a match in the PNOR but we need
- // to decide what all needs an update
- //
-
- // Stash the internal_offset of the section we found in so we can add
- // this record to g_cachedEeproms for later use
+ // Stash the internal_offset of the section we found in so we
+ // can add this record to g_cachedEeproms for later use
l_eepromRecordHeader.completeRecord.internal_offset =
- l_recordHeaderToUpdate->completeRecord.internal_offset;
+ l_recordHeaderToUpdate->completeRecord.internal_offset;
+ TRACSSCOMP(g_trac_eeprom,
+ "cacheEeprom() already found copy for eeprom role %d "
+ "for target w/ HUID 0x.%08X in EECACHE table of contents",
+ i_eepromType , TARGETING::get_huid(i_target));
+ break;
+ }
+ }
- if(l_recordHeaderToUpdate->completeRecord.cached_copy_valid)
- {
- // If the existing eeprom record is valid, then only update the
- // contents if the SN/PN for current HW do not match the eeprom
- // record. (target must be present to cache)
+ // pass the record we have been building up (l_eepromRecordHeader)
+ // and the virtual address of this eeprom's record entry in the
+ // EECACHE table of contents as a uint64.
+ if(!addEepromToCachedList(l_eepromRecordHeader,
+ reinterpret_cast<uint64_t>(l_recordHeaderToUpdate)))
+ {
+ TRACSSCOMP( g_trac_eeprom,
+ "cacheEeprom() Eeprom w/ Role %d, HUID 0x.%08X added to the global map of cached eeproms",
+ i_eepromType , TARGETING::get_huid(i_target));
+ }
+ else
+ {
+ // If this target's eeprom has already been cached in PNOR and our global map
+ // indicates the cache entry was updated this boot, then we must also
+ // mark this target associated with the cached eeprom as changed for hwas
+ if( hasEeepromChanged( l_eepromRecordHeader ) )
+ {
+ HWAS::markTargetChanged(i_target);
+ }
+ TRACSSCOMP( g_trac_eeprom,
+ "cacheEeprom() Eeprom w/ Role %d, HUID 0x.%08X already in global map of cached eeproms",
+ i_eepromType , TARGETING::get_huid(i_target));
- // TODO RTC:203788 add lookup for PN and SN matches
- //if( !i_present || PNandSNMatch )
- {
- l_updateContents = false;
- }
+ // Cache entry has already been updated via another target, just break out
+ break;
+ }
- // If target is present there is nothing in the
- // header to update
- if( i_present )
- {
- l_updateHeader = false;
- }
+ // Only check if the cache is in sync with HARDWARE if there is an
+ // existing EECACHE section. Otherwise, the code after this logic will
+ // take care of adding a new eeprom cache section for the target.
+ if (l_recordHeaderToUpdate->completeRecord.cached_copy_valid)
+ {
+ // At this point we have found a match in the PNOR but we need
+ // to decide what all needs an update.
+
+ // Create namespace alias for targeting to reduce number of
+ // new lines required to be within line character limit.
+ namespace T = TARGETING;
+
+ // If the existing eeprom record is valid, then only update
+ // the contents if the SN/PN for current HW do not match the
+ // eeprom record. (target must be present to cache)
+ T::EEPROM_CONTENT_TYPE l_eepromContentType =
+ T::EEPROM_CONTENT_TYPE_RAW;
+
+ if (i_eepromType == EEPROM::VPD_PRIMARY)
+ {
+ auto l_eepromVpd =
+ i_target->getAttr<T::ATTR_EEPROM_VPD_PRIMARY_INFO>();
+
+ l_eepromContentType =
+ static_cast<T::EEPROM_CONTENT_TYPE>(
+ l_eepromVpd.eepromContentType);
+ }
+ else
+ {
+ auto l_eepromVpd =
+ i_target->getAttr<T::ATTR_EEPROM_VPD_BACKUP_INFO>();
+
+ l_eepromContentType =
+ static_cast<T::EEPROM_CONTENT_TYPE>(
+ l_eepromVpd.eepromContentType);
+ }
+
+
+ bool l_isInSync = false;
+
+ if (i_present)
+ {
+ l_errl = VPD::ensureEepromCacheIsInSync(i_target,
+ l_eepromContentType,
+ l_isInSync);
+
+ if (l_errl != nullptr)
+ {
+ break;
}
- else if(!i_present)
+
+ if(l_isInSync)
{
- // If the target is not present, then do not update contents or header
l_updateContents = false;
- l_updateHeader = false;
}
- TRACSSCOMP( g_trac_eeprom, "cacheEeprom() already found copy for eeprom role %d for target w/ HUID 0x.%08X",
- i_eepromType , TARGETING::get_huid(i_target));
- break;
}
- }
+ else
+ {
+ // Clear out the contents of the cache for this eeprom if we have detected that it
+ // was once valid, indicating it was present at one time, and is now showing
+ // up as not present. We want to clear the contents of cache so we can achieve
+ // the replug behavior where a tester can remove the part, boot, then plug in the
+ // same part and boot again fresh.
+ void * l_internalSectionAddr =
+ reinterpret_cast<uint8_t *>(l_eecacheSectionHeaderPtr) +
+ l_eepromRecordHeader.completeRecord.internal_offset;
+
+ memset( l_internalSectionAddr, 0xFF ,
+ (l_recordHeaderToUpdate->completeRecord.cache_copy_size * KILOBYTE));
+
+ l_updateContents = false;
+
+ setIsValidCacheEntry(l_eepromRecordHeader, false);
+
+ TRACFCOMP( g_trac_eeprom, "Detected Master 0x%.08X"
+ " Engine 0x%.02X Port 0x%.02X"
+ " MuxSelect 0x%.02X DevAddr 0x%.02X"
+ " no longer present, clearing cache and marking cache as invalid",
+ l_recordHeaderToUpdate->completeRecord.i2c_master_huid,
+ l_recordHeaderToUpdate->completeRecord.engine,
+ l_recordHeaderToUpdate->completeRecord.port,
+ l_recordHeaderToUpdate->completeRecord.mux_select,
+ l_recordHeaderToUpdate->completeRecord.devAddr);
+
+ setEeepromChanged(l_eepromRecordHeader);
+ // We have cleared the cache entry, this indicates we have found a part has been removed.
+ // Mark that the target is changed in hwas.
+ HWAS::markTargetChanged(i_target);
+ }
- if(!addEepromToCachedList(l_eepromRecordHeader))
+ // If target is present there is nothing in the
+ // header to update
+ if( i_present )
+ {
+ l_updateHeader = false;
+ }
+ }
+ else if(!i_present)
{
- TRACSSCOMP( g_trac_eeprom, "cacheEeprom() Eeprom w/ Role %d, HUID 0x.%08X added to cached list",
- i_eepromType , TARGETING::get_huid(i_target));
+ // If the target is not present, then do not update contents
+ l_updateContents = false;
+ // Only update header if this is a new entry
+ l_updateHeader = l_newEntryDetected;
}
- else
+ // The check below makes sure that is isnt a new entry
+ // If there is a matching header entry in PNOR marked 'invalid'
+ // but we now see the target as present, this indicates a replacement
+ // part has been added where a part was removed
+ else if(!l_newEntryDetected)
{
- TRACSSCOMP( g_trac_eeprom, "cacheEeprom() Eeprom w/ Role %d, HUID 0x.%08X already in cached list",
- i_eepromType , TARGETING::get_huid(i_target));
+ TRACFCOMP(g_trac_eeprom, "cacheEeprom() Detected replacement of a part"
+ " Master 0x%.08X Engine 0x%.02X"
+ " Port 0x%.02X MuxSelect 0x%.02X DevAddr 0x%.02X"
+ " that was previously removed, we will update the cache with new part's eeproms contents",
+ l_recordHeaderToUpdate->completeRecord.i2c_master_huid,
+ l_recordHeaderToUpdate->completeRecord.engine,
+ l_recordHeaderToUpdate->completeRecord.port,
+ l_recordHeaderToUpdate->completeRecord.mux_select,
+ l_recordHeaderToUpdate->completeRecord.devAddr);
}
-
// Above we have determined whether the contents of the eeprom at
// hand need to have their contents updated. Only do the following
// steps that update the eeprom's cached data if we were told to do so.
- if(l_updateContents )
+ if( l_updateContents )
{
assert(l_recordHeaderToUpdateIndex != INVALID_EEPROM_INDEX,
"More than MAX_EEPROMS_VERSION_1 in system XML");
+ TRACFCOMP( g_trac_eeprom, "cacheEeprom() updating cache entry");
+
void * l_tmpBuffer;
l_tmpBuffer = malloc(l_eepromLen);
void * l_internalSectionAddr =
- reinterpret_cast<uint8_t *>(l_eecacheSectionHeaderPtr) + l_eepromRecordHeader.completeRecord.internal_offset;
+ reinterpret_cast<uint8_t *>(l_eecacheSectionHeaderPtr) +
+ l_eepromRecordHeader.completeRecord.internal_offset;
TRACSSCOMP( g_trac_eeprom, "cacheEeprom() passing the following into deviceOp eeprom address : huid 0x%.08X length 0x%.08X vaddr %p" ,
get_huid(i_target), l_eepromLen, l_internalSectionAddr);
@@ -543,6 +515,18 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target,
break;
}
+ // Set mark_target_changed and cached_copy_valid and update set updateHeader
+ // Since we have copied stuff in the cache is valid, and been updated.
+ // Even if this is a replacement ( cached_copy_valid was already 1) we
+ // must set mark_target_changed so just always update the header
+ setEeepromChanged(l_eepromRecordHeader);
+ // We will update header in PNOR below so no need to call
+ // setIsValidCacheEntry right here
+ l_eepromRecordHeader.completeRecord.cached_copy_valid = 1;
+ l_updateHeader = true;
+ // We have updated the cache entry, this indicates we have found a "new" part.
+ // Mark that the target is changed in hwas.
+ HWAS::markTargetChanged(i_target);
}
// Above we have determined whether the header entry for the eeprom at
@@ -550,6 +534,7 @@ errlHndl_t cacheEeprom(TARGETING::Target* i_target,
// the eeprom's header entry if we were told to do so.
if(l_updateHeader)
{
+ TRACFCOMP( g_trac_eeprom, "cacheEeprom() updating header entry");
TRACDBIN( g_trac_eeprom, "cacheEeprom: l_eecacheSectionHeaderPtr currently ",
l_eecacheSectionHeaderPtr,
sizeof(eecacheSectionHeader));
@@ -658,175 +643,318 @@ DEVICE_REGISTER_ROUTE( DeviceFW::READ,
TARGETING::TYPE_DIMM,
genericI2CEepromCache );
-#endif
+DEVICE_REGISTER_ROUTE( DeviceFW::READ,
+ DeviceFW::EEPROM_CACHE,
+ TARGETING::TYPE_NODE,
+ genericI2CEepromCache );
-errlHndl_t eepromPerformOpCache(DeviceFW::OperationType i_opType,
- TARGETING::Target * i_target,
- void * io_buffer,
- size_t& io_buflen,
- eeprom_addr_t &i_eepromInfo)
+errlHndl_t setIsValidCacheEntry(const TARGETING::Target * i_target,
+ const EEPROM_ROLE &i_eepromRole,
+ bool i_isValid)
{
errlHndl_t l_errl = nullptr;
eepromRecordHeader l_eepromRecordHeader;
+ eeprom_addr_t l_eepromInfo;
do{
- TRACSSCOMP( g_trac_eeprom, ENTER_MRK"eepromPerformOpCache() "
- "Target HUID 0x%.08X Enter", TARGETING::get_huid(i_target));
+ TRACDCOMP( g_trac_eeprom, ENTER_MRK"setIsValidCacheEntry() "
+ "Target HUID 0x%.08X Eeprom Role = %d Enter",
+ TARGETING::get_huid(i_target), l_eepromInfo.eepromRole);
- l_errl = buildEepromRecordHeader(i_target, i_eepromInfo, l_eepromRecordHeader);
+ l_eepromInfo.eepromRole = i_eepromRole;
+ l_errl = buildEepromRecordHeader(const_cast<TARGETING::Target *>(i_target), l_eepromInfo, l_eepromRecordHeader);
if(l_errl)
{
- // buildEepromRecordHeader should have traced any relavent information if
- // it was needed, just break out and pass the error along
break;
}
- uint64_t l_eepromCacheVaddr = lookupEepromAddr(l_eepromRecordHeader);
+ l_errl = setIsValidCacheEntry(l_eepromRecordHeader, i_isValid);
- // Ensure that a copy of the eeprom exists in our map of cached eeproms
- if(l_eepromCacheVaddr)
- {
- // First check if io_buffer is a nullptr, if so then assume user is
- // requesting size back in io_bufferlen
- if(io_buffer == nullptr)
- {
- io_buflen = l_eepromRecordHeader.completeRecord.cache_copy_size * KILOBYTE;
- TRACSSCOMP( g_trac_eeprom, "eepromPerformOpCache() "
- "io_buffer == nullptr , returning io_buflen as 0x%lx",
- io_buflen);
- break;
- }
+ }while(0);
- TRACSSCOMP( g_trac_eeprom, "eepromPerformOpCache() "
- "Performing %s on target 0x%.08X offset 0x%lx length 0x%x vaddr 0x%lx",
- (i_opType == DeviceFW::READ) ? "READ" : "WRITE",
- TARGETING::get_huid(i_target),
- i_eepromInfo.offset, io_buflen, l_eepromCacheVaddr);
+ return l_errl;
+}
- // Make sure that offset + buflen are less than the total size of the eeprom
- if(i_eepromInfo.offset + io_buflen > (l_eepromRecordHeader.completeRecord.cache_copy_size * KILOBYTE))
- {
- TRACFCOMP(g_trac_eeprom,
- ERR_MRK"eepromPerformOpCache: i_eepromInfo.offset + i_offset is greater than size of eeprom (0x%x KB)",
- l_eepromRecordHeader.completeRecord.cache_copy_size);
- /*@
- * @errortype
- * @moduleid EEPROM_CACHE_PERFORM_OP
- * @reasoncode EEPROM_OVERFLOW_ERROR
- * @userdata1 Length of Operation
- * @userdata2 Offset we are attempting to read/write
- * @custdesc Soft error in Firmware
- * @devdesc cacheEeprom invalid op type
- */
- l_errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- EEPROM_CACHE_PERFORM_OP,
- EEPROM_OVERFLOW_ERROR,
- TO_UINT64(io_buflen),
- TO_UINT64(i_eepromInfo.offset),
- ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
- ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
- l_errl->collectTrace( EEPROM_COMP_NAME );
+errlHndl_t setIsValidCacheEntry(const eepromRecordHeader& i_eepromRecordHeader, bool i_isValid)
+{
+ errlHndl_t l_errl = nullptr;
+ eepromRecordHeader * l_eepromRecordHeaderToUpdate;
+ std::map<eepromRecordHeader, EeepromEntryMetaData_t>::iterator l_headerMapIterator;
- break;
- }
+ do{
- if(i_opType == DeviceFW::READ)
- {
- memcpy(io_buffer, reinterpret_cast<void *>(l_eepromCacheVaddr + i_eepromInfo.offset), io_buflen);
- }
- else if(i_opType == DeviceFW::WRITE)
- {
- memcpy(reinterpret_cast<void *>(l_eepromCacheVaddr + i_eepromInfo.offset), io_buffer, io_buflen);
+ TRACDCOMP( g_trac_eeprom, ENTER_MRK"setIsValidCacheEntry() ");
- #ifndef __HOSTBOOT_RUNTIME
- // Perform flush to ensure pnor is updated
- int rc = mm_remove_pages( FLUSH,
- reinterpret_cast<void *>(l_eepromCacheVaddr + i_eepromInfo.offset),
- io_buflen );
- if( rc )
- {
- TRACFCOMP(g_trac_eeprom,ERR_MRK"eepromPerformOpCache: Error from mm_remove_pages trying for flush contents write to pnor! rc=%d",rc);
- /*@
- * @errortype
- * @moduleid EEPROM_CACHE_PERFORM_OP
- * @reasoncode EEPROM_FAILED_TO_FLUSH_CONTENTS
- * @userdata1 Requested Address
- * @userdata2 rc from mm_remove_pages
- * @devdesc cacheEeprom mm_remove_pages FLUSH failed
- */
- l_errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- EEPROM_CACHE_PERFORM_OP,
- EEPROM_FAILED_TO_FLUSH_CONTENTS,
- (l_eepromCacheVaddr + i_eepromInfo.offset),
- TO_UINT64(rc),
- ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
- l_errl->collectTrace( EEPROM_COMP_NAME );
- }
- #endif //__HOSTBOOT_RUNTIME
- }
- else
- {
- TRACFCOMP(g_trac_eeprom,ERR_MRK"eepromPerformOpCache: Invalid OP_TYPE passed to function, i_opType=%d", i_opType);
- /*@
- * @errortype
- * @moduleid EEPROM_CACHE_PERFORM_OP
- * @reasoncode EEPROM_INVALID_OPERATION
- * @userdata1[0:31] Op Type that was invalid
- * @userdata1[32:63] Eeprom Role
- * @userdata2 Offset we are attempting to perfrom op on
- * @custdesc Soft error in Firmware
- * @devdesc cacheEeprom invalid op type
- */
- l_errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- EEPROM_CACHE_PERFORM_OP,
- EEPROM_INVALID_OPERATION,
- TWO_UINT32_TO_UINT64(i_opType,
- i_eepromInfo.eepromRole),
- TO_UINT64(i_eepromInfo.offset),
- ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
- ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
- l_errl->collectTrace( EEPROM_COMP_NAME );
- }
+ // Find the address of the header entry in the table of contents of the EECACHE pnor section
+ l_eepromRecordHeaderToUpdate =
+ reinterpret_cast<eepromRecordHeader *>(lookupEepromHeaderAddr(i_eepromRecordHeader));
+
+ if(l_eepromRecordHeaderToUpdate == 0)
+ {
+ TRACFCOMP(g_trac_eeprom,
+ ERR_MRK"setIsValidCacheEntry: Attempting to invalidate cache for an "
+ "eeprom but we could not find in global eecache map");
+ /*@
+ * @errortype
+ * @moduleid EEPROM_INVALIDATE_CACHE
+ * @reasoncode EEPROM_CACHE_NOT_FOUND_IN_MAP
+ * @userdata1[0:7] i2c_master_huid
+ * @userdata1[8:9] port on i2c master eeprom slave is on
+ * @userdata1[10:11] engine on i2c master eeprom slave is on
+ * @userdata1[12:13] devAddr of eeprom slave
+ * @userdata1[14:15] muxSelect of eeprom slave (0xFF is not valid)
+ * @userdata2[0:7] size of eeprom
+ * @devdesc invalidateCache failed to find cache in map
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_INVALIDATE_CACHE,
+ EEPROM_CACHE_NOT_FOUND_IN_MAP,
+ TWO_UINT32_TO_UINT64(
+ i_eepromRecordHeader.completeRecord.i2c_master_huid,
+ TWO_UINT16_TO_UINT32(
+ TWO_UINT8_TO_UINT16(
+ i_eepromRecordHeader.completeRecord.port,
+ i_eepromRecordHeader.completeRecord.engine),
+ TWO_UINT8_TO_UINT16(
+ i_eepromRecordHeader.completeRecord.devAddr,
+ i_eepromRecordHeader.completeRecord.mux_select))),
+ i_eepromRecordHeader.completeRecord.cache_copy_size,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
}
- else
+
+ // Ensure that information at the address we just looked up matches the record we built up
+ if( memcmp(&l_eepromRecordHeaderToUpdate->uniqueRecord.uniqueID,
+ &i_eepromRecordHeader.uniqueRecord.uniqueID,
+ NUM_BYTE_UNIQUE_ID ) != 0 )
+ {
+ TRACFCOMP(g_trac_eeprom,ERR_MRK"setIsValidCacheEntry: Attempting to invalidate cache for an"
+ "eeprom but we could not find the entry in table of contents of EECACHE section of pnor");
+ /*@
+ * @errortype
+ * @moduleid EEPROM_INVALIDATE_CACHE
+ * @reasoncode EEPROM_CACHE_NOT_FOUND_IN_PNOR
+ * @userdata1[0:7] i2c_master_huid
+ * @userdata1[8:9] port on i2c master eeprom slave is on
+ * @userdata1[10:11] engine on i2c master eeprom slave is on
+ * @userdata1[12:13] devAddr of eeprom slave
+ * @userdata1[14:15] muxSelect of eeprom slave (0xFF is not valid)
+ * @userdata2[0:7] size of eeprom
+ * @devdesc invalidateCache failed to find cache in pnor
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_INVALIDATE_CACHE,
+ EEPROM_CACHE_NOT_FOUND_IN_PNOR,
+ TWO_UINT32_TO_UINT64(
+ i_eepromRecordHeader.completeRecord.i2c_master_huid,
+ TWO_UINT16_TO_UINT32(
+ TWO_UINT8_TO_UINT16(
+ i_eepromRecordHeader.completeRecord.port,
+ i_eepromRecordHeader.completeRecord.engine),
+ TWO_UINT8_TO_UINT16(
+ i_eepromRecordHeader.completeRecord.devAddr,
+ i_eepromRecordHeader.completeRecord.mux_select))),
+ i_eepromRecordHeader.completeRecord.cache_copy_size,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ // Update the header so that it state the entry is invalid
+ l_eepromRecordHeaderToUpdate->completeRecord.cached_copy_valid = i_isValid;
+
+ // Flush the page to make sure it gets to the PNOR
+ int rc = mm_remove_pages( FLUSH,
+ l_eepromRecordHeaderToUpdate,
+ sizeof(eepromRecordHeader) );
+ if( rc )
{
- TRACFCOMP( g_trac_eeprom,"eepromPerformOpCache: Failed to find entry in cache for 0x%.08X, %s failed",
- TARGETING::get_huid(i_target),
- (i_opType == DeviceFW::READ) ? "READ" : "WRITE");
+ TRACFCOMP(g_trac_eeprom,
+ ERR_MRK"setIsValidCacheEntry: Error from mm_remove_pages trying for flush header write to pnor, rc=%d",rc);
/*@
* @errortype
- * @moduleid EEPROM_CACHE_PERFORM_OP
- * @reasoncode EEPROM_NOT_IN_CACHE
- * @userdata1[0:31] Op Type
- * @userdata1[32:63] Eeprom Role
- * @userdata2 Offset we are attempting to read/write
- * @custdesc Soft error in Firmware
- * @devdesc Tried to lookup eeprom not in cache
+ * @moduleid EEPROM_INVALIDATE_CACHE
+ * @reasoncode EEPROM_FAILED_TO_FLUSH_HEADER
+ * @userdata1 Requested Address
+ * @userdata2 rc from mm_remove_pages
+ * @devdesc invalidateCache mm_remove_pages FLUSH failed
*/
l_errl = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- EEPROM_CACHE_PERFORM_OP,
- EEPROM_NOT_IN_CACHE,
- TWO_UINT32_TO_UINT64(i_opType,
- i_eepromInfo.eepromRole),
- TO_UINT64(i_eepromInfo.offset),
+ EEPROM_INVALIDATE_CACHE,
+ EEPROM_FAILED_TO_FLUSH_HEADER,
+ (uint64_t)l_eepromRecordHeaderToUpdate,
+ TO_UINT64(rc),
ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
- ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
- l_errl->collectTrace( EEPROM_COMP_NAME );
+ break;
}
- TRACSSCOMP( g_trac_eeprom, EXIT_MRK"eepromPerformOpCache() "
- "Target HUID 0x%.08X Exit", TARGETING::get_huid(i_target));
-
}while(0);
return l_errl;
}
+bool addEepromToCachedList(const eepromRecordHeader & i_eepromRecordHeader,
+ const uint64_t i_recordHeaderVaddr)
+{
+ bool l_matchFound = true;
+
+ // Map accesses are not thread safe, make sure this is always wrapped in mutex
+ mutex_lock(&g_eecacheMutex);
+
+ if(g_cachedEeproms.find(i_eepromRecordHeader) == g_cachedEeproms.end())
+ {
+ g_cachedEeproms[i_eepromRecordHeader].cache_entry_address =
+ g_eecachePnorVaddr + i_eepromRecordHeader.completeRecord.internal_offset;
+
+ g_cachedEeproms[i_eepromRecordHeader].header_entry_address =
+ i_recordHeaderVaddr;
+
+ TRACSSCOMP( g_trac_eeprom,
+ "addEepromToCachedList() Adding I2CM Huid: 0x%.08X, Port: 0x%.02X,"
+ " Engine: 0x%.02X, Dev Addr: 0x%.02X, Mux Select: 0x%.02X,"
+ " Size: 0x%.08X to g_cachedEeproms",
+ i_eepromRecordHeader.completeRecord.i2c_master_huid,
+ i_eepromRecordHeader.completeRecord.port,
+ i_eepromRecordHeader.completeRecord.engine,
+ i_eepromRecordHeader.completeRecord.devAddr,
+ i_eepromRecordHeader.completeRecord.mux_select,
+ i_eepromRecordHeader.completeRecord.cache_copy_size);
+
+ l_matchFound = false;
+ }
+
+ mutex_unlock(&g_eecacheMutex);
+
+ return l_matchFound;
+}
+
+void printTableOfContents(void)
+{
+ eecacheSectionHeader * l_eecacheSectionHeaderPtr =
+ reinterpret_cast<eecacheSectionHeader*>(g_eecachePnorVaddr);
+
+ TRACFCOMP( g_trac_eeprom,
+ "printTableOfContents(): Version = 0x%.02X"
+ " End of Cache = 0x.08X",
+ l_eecacheSectionHeaderPtr->version,
+ l_eecacheSectionHeaderPtr->end_of_cache);
+
+ for(uint8_t i = 0; i < MAX_EEPROMS_VERSION_1; i++)
+ {
+ eepromRecordHeader l_currentRecordHeader =
+ l_eecacheSectionHeaderPtr->recordHeaders[i];
+
+ if( l_currentRecordHeader.completeRecord.internal_offset !=
+ UNSET_INTERNAL_OFFSET_VALUE)
+ {
+ TRACFCOMP( g_trac_eeprom,
+ "printTableOfContents(): I2CM Huid: 0x%.08X, Port: 0x%.02X,"
+ " Engine: 0x%.02X, Dev Addr: 0x%.02X,"
+ " Mux Select: 0x%.02X, Size: 0x%.08X",
+ l_currentRecordHeader.completeRecord.i2c_master_huid,
+ l_currentRecordHeader.completeRecord.port,
+ l_currentRecordHeader.completeRecord.engine,
+ l_currentRecordHeader.completeRecord.devAddr,
+ l_currentRecordHeader.completeRecord.mux_select,
+ l_currentRecordHeader.completeRecord.cache_copy_size);
+
+ TRACFCOMP( g_trac_eeprom,
+ " "
+ "Internal Offset: 0x%.08X, Cache Valid: 0x%.02X",
+ l_currentRecordHeader.completeRecord.internal_offset,
+ l_currentRecordHeader.completeRecord.cached_copy_valid);
+ }
+ }
+
}
+
+bool hasEeepromChanged(const eepromRecordHeader & i_eepromRecordHeader)
+{
+ bool l_eepromHasChanged = false;
+
+ // Map accesses are not thread safe, make sure this is always wrapped in mutex
+ mutex_lock(&g_eecacheMutex);
+
+ if(g_cachedEeproms.find(i_eepromRecordHeader) != g_cachedEeproms.end())
+ {
+ l_eepromHasChanged = g_cachedEeproms[i_eepromRecordHeader].mark_target_changed;
+ }
+
+ mutex_unlock(&g_eecacheMutex);
+
+ return l_eepromHasChanged;
+}
+
+void setEeepromChanged(const eepromRecordHeader & i_eepromRecordHeader)
+{
+
+ // Map accesses are not thread safe, make sure this is always wrapped in mutex
+ mutex_lock(&g_eecacheMutex);
+
+ if(g_cachedEeproms.find(i_eepromRecordHeader) != g_cachedEeproms.end())
+ {
+ g_cachedEeproms[i_eepromRecordHeader].mark_target_changed = true;
+ }
+
+ mutex_unlock(&g_eecacheMutex);
+
+}
+
+uint64_t lookupEepromCacheAddr(const eepromRecordHeader& i_eepromRecordHeader)
+{
+ uint64_t l_vaddr = 0;
+ std::map<eepromRecordHeader, EeepromEntryMetaData_t>::iterator l_it;
+
+ // Wrap lookup in mutex because reads are not thread safe
+ mutex_lock(&g_eecacheMutex);
+ l_it = g_cachedEeproms.find(i_eepromRecordHeader);
+
+ if(l_it != g_cachedEeproms.end())
+ {
+ l_vaddr = l_it->second.cache_entry_address;
+ }
+
+ mutex_unlock(&g_eecacheMutex);
+
+ return l_vaddr;
+}
+
+uint64_t lookupEepromHeaderAddr(const eepromRecordHeader& i_eepromRecordHeader)
+{
+ uint64_t l_vaddr = 0;
+ std::map<eepromRecordHeader, EeepromEntryMetaData_t>::iterator l_it;
+
+ // Wrap lookup in mutex because reads are not thread safe
+ mutex_lock(&g_eecacheMutex);
+ l_it = g_cachedEeproms.find(i_eepromRecordHeader);
+
+ if(l_it != g_cachedEeproms.end())
+ {
+ l_vaddr = l_it->second.header_entry_address;
+ }
+ mutex_unlock(&g_eecacheMutex);
+
+ if(l_vaddr == 0)
+ {
+ TRACFCOMP( g_trac_eeprom,
+ "lookupEepromHeaderAddr() failed to find"
+ " I2CM Huid: 0x%.08X, Port: 0x%.02X,"
+ " Engine: 0x%.02X, Dev Addr: 0x%.02X,"
+ " Mux Select: 0x%.02X, Size: 0x%.08X"
+ "in g_cachedEeproms",
+ i_eepromRecordHeader.completeRecord.i2c_master_huid,
+ i_eepromRecordHeader.completeRecord.port,
+ i_eepromRecordHeader.completeRecord.engine,
+ i_eepromRecordHeader.completeRecord.devAddr,
+ i_eepromRecordHeader.completeRecord.mux_select,
+ i_eepromRecordHeader.completeRecord.cache_copy_size);
+ }
+ return l_vaddr;
+}
+
+} \ No newline at end of file
diff --git a/src/usr/i2c/eepromCache.H b/src/usr/i2c/eepromCache.H
index 5cad475ba..253367b07 100644
--- a/src/usr/i2c/eepromCache.H
+++ b/src/usr/i2c/eepromCache.H
@@ -97,10 +97,44 @@ errlHndl_t buildEepromRecordHeader(TARGETING::Target * i_target,
eeprom_addr_t & io_eepromInfo,
eepromRecordHeader & o_eepromRecordHeader);
+
+#ifndef __HOSTBOOT_RUNTIME
+
+/**
+*
+* @brief Check if entry already exists in g_cachedEeproms, if a match is
+* found then return true. If there is no match, add it to the list
+* and return false;
+*
+* @param[in] i_eepromRecordHeader Header for record we want to add to map
+*
+* @param[in] i_recordHeaderVaddr Virtual address to PNOR copy of header information
+*
+* @return TRUE if entry is already in map FALSE if this is a new entry
+*
+*/
+bool addEepromToCachedList(const eepromRecordHeader & i_eepromRecordHeader,
+ const uint64_t i_recordHeaderVaddr);
+
+/**
+*
+* @brief Perform a lookup on the global map g_cachedEeproms to get a
+* virtual address for a given EEPROM entry in the EECACHE table of contents
+*
+* @param[in] i_eepromRecordHeader
+*
+* @pre It is expected that i_eepromRecordHeader has valid information for
+* the uniqueID (i2cm_huid, port, engine, devAddr, mux_select)
+*
+* @return uint64_t virtual address pointing to the cached eeprom data in pnor
+*
+*/
+uint64_t lookupEepromHeaderAddr(const eepromRecordHeader& i_eepromRecordHeader);
+
/**
*
* @brief Perform a lookup on the global map g_cachedEeproms to get a
-* virtual address for a given EEPROM
+* virtual address for a given EEPROM cache entry
*
* @param[in] i_eepromRecordHeader
*
@@ -110,8 +144,127 @@ errlHndl_t buildEepromRecordHeader(TARGETING::Target * i_target,
* @return uint64_t virtual address pointing to the cached eeprom data in pnor
*
*/
-uint64_t lookupEepromAddr(const eepromRecordHeader & i_eepromRecordHeader);
+uint64_t lookupEepromCacheAddr(const eepromRecordHeader& i_eepromRecordHeader);
+
+/**
+*
+* @brief Print the info found in the Table of Contents of the EECACHE
+* section of pnor to trace buffer
+*
+* @return void
+*
+*/
+void printTableOfContents(void);
+
+
+/**
+*
+* @brief Update the record entry in the Table of Contents of the EECACHE
+* section of pnor to either mark the contents of the cache to be
+* valid or invalid
+*
+* @param[in] i_target Target associated with EEPROM
+*
+* @param[in] i_eepromRole Role of EEPROM associated with target (VPD_PRIMARY etc)
+*
+* @param[in] i_isValid Mark eeprom cache valid or invalid ?
+*
+* @return errlHndl_t - nullptr if successful, otherwise a pointer to the
+* error log.
+*
+*/
+errlHndl_t setIsValidCacheEntry(const TARGETING::Target * i_target,
+ const EEPROM_ROLE &i_eepromRole,
+ bool i_isValid);
+
+/**
+*
+* @brief Update the record entry in the Table of Contents of the EECACHE
+* section of pnor to either mark the contents of the cache to be
+* valid or invalid
+*
+* @param[in] i_eepromRecordHeader eepromRecord oject already filled in (including eepromRole)
+*
+* @param[in] i_isValid Mark eeprom cache valid or invalid ?
+*
+* @return errlHndl_t - nullptr if successful, otherwise a pointer to the
+* error log.
+*
+*/
+errlHndl_t setIsValidCacheEntry(const eepromRecordHeader& i_eepromRecordHeader, bool i_isValid);
+
+/**
+*
+* @brief Lookup a given i_eepromRecordHeader in the global map of eeprom
+* caches and check if the eeprom has changed this IPL or not
+*
+* @param[in] i_eepromRecordHeader we want to look up
+*
+* @return bool Return TRUE if eeprom is found in map AND mark_target_changed
+ was set to true for the eeprom entry. Return FALSE otherwise.
+*
+*/
+bool hasEeepromChanged(const eepromRecordHeader & i_eepromRecordHeader);
+
+/**
+*
+* @brief Lookup a given i_eepromRecordHeader in the global map of eeprom
+* caches and mark that it has changed this IPL
+*
+* @param[in] i_eepromRecordHeader we want to mark as changed
+*
+* @return void
+*/
+void setEeepromChanged(const eepromRecordHeader & i_eepromRecordHeader);
+#else
+/**
+*
+* @brief Check if entry already exists in g_cachedEeproms, if a match is
+* found then return true. If there is no match, add it to the list
+* and return false;
+*
+* @param[in] i_eepromRecordHeader Header for record we want to add to map
+*
+* @param[in] i_recordHeaderVaddr Virtual address to PNOR copy of header information
+*
+* @param[in] i_instance Node ID that this eeprom is on
+*
+* @return TRUE if entry is already in map FALSE if this is a new entry
+*
+*/
+bool addEepromToCachedList(const eepromRecordHeader & i_eepromRecordHeader,
+ const uint64_t i_recordHeaderVaddr,
+ const uint8_t i_instance);
+
+/**
+*
+* @brief Perform a lookup on the global map g_cachedEeproms to get a
+* virtual address for a given EEPROM cache entry
+*
+* @param[in] i_eepromRecordHeader Header for record we want to add to lookup address for
+*
+* @param[in] i_isntance Node ID that this eeprom is on
+*
+* @pre It is expected that i_eepromRecordHeader has valid information for
+* the uniqueID (i2cm_huid, port, engine, devAddr, mux_select)
+*
+* @return uint64_t virtual address pointing to the cached eeprom data in pnor
+*
+*/
+uint64_t lookupEepromCacheAddr(const eepromRecordHeader& i_eepromRecordHeader,
+ const uint8_t i_instance);
+
+/**
+*
+* @brief Walk through g_cachedEeproms map and print information about
+* the cached eeproms found
+*
+* @return void
+*
+*/
+void printCurrentCachedEepromMap(void);
+#endif // __HOSTBOOT_RUNTIME
}
#endif \ No newline at end of file
diff --git a/src/usr/i2c/eepromCache_common.C b/src/usr/i2c/eepromCache_common.C
new file mode 100644
index 000000000..72c982056
--- /dev/null
+++ b/src/usr/i2c/eepromCache_common.C
@@ -0,0 +1,325 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/i2c/eepromCache_common.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include "eepromCache.H"
+#include <errl/errlmanager.H>
+#include <i2c/eepromif.H>
+#include <i2c/eepromddreasoncodes.H>
+#include <errl/errludtarget.H>
+
+#ifdef __HOSTBOOT_RUNTIME
+#include <targeting/attrrp.H>
+#else
+#include <sys/mm.h>
+#endif
+
+extern trace_desc_t* g_trac_eeprom;
+
+//#define TRACSSCOMP(args...) TRACFCOMP(args)
+#define TRACSSCOMP(args...)
+
+namespace EEPROM
+{
+
+errlHndl_t buildEepromRecordHeader(TARGETING::Target * i_target,
+ eeprom_addr_t & io_eepromInfo,
+ eepromRecordHeader & o_eepromRecordHeader)
+{
+
+ TARGETING::Target * l_muxTarget = nullptr;
+ TARGETING::Target * l_i2cMasterTarget = nullptr;
+ TARGETING::TargetService& l_targetService = TARGETING::targetService();
+ errlHndl_t l_errl = nullptr;
+
+ do{
+
+ l_errl = eepromReadAttributes(i_target, io_eepromInfo);
+ if(l_errl)
+ {
+ TRACFCOMP( g_trac_eeprom,
+ "buildEepromRecordHeader() error occurred reading eeprom attributes for eepromType %d, target 0x%.08X, returning!!",
+ io_eepromInfo.eepromRole,
+ TARGETING::get_huid(i_target));
+ l_errl->collectTrace(EEPROM_COMP_NAME);
+ break;
+ }
+
+ // Grab the I2C mux target so we can read the HUID, if the target is NULL we will not be able
+ // to lookup attribute to uniquely ID this eeprom so we will not cache it
+ l_muxTarget = l_targetService.toTarget( io_eepromInfo.i2cMuxPath);
+ if(l_muxTarget == nullptr)
+ {
+ TRACFCOMP( g_trac_eeprom,
+ "buildEepromRecordHeader() Mux target associated with target 0x%.08X resolved to a nullptr , check attribute for eepromType %d. Skipping Cache",
+ TARGETING::get_huid(i_target),
+ io_eepromInfo.eepromRole);
+ /*@
+ * @errortype
+ * @moduleid EEPROM_CACHE_EEPROM
+ * @reasoncode EEPROM_I2C_MUX_PATH_ERROR
+ * @userdata1 HUID of target we want to cache
+ * @userdata2 Type of EEPROM we are caching
+ * @devdesc buildEepromRecordHeader invalid mux target
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_CACHE_EEPROM,
+ EEPROM_I2C_MUX_PATH_ERROR,
+ TARGETING::get_huid(i_target),
+ io_eepromInfo.eepromRole,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_errl->collectTrace(EEPROM_COMP_NAME);
+ break;
+ }
+
+ // Grab the I2C master target so we can read the HUID, if the target is NULL we will not be able
+ // to lookup attribute to uniquely ID this eeprom so we will not cache it
+ l_i2cMasterTarget = l_targetService.toTarget( io_eepromInfo.i2cMasterPath );
+ if(l_i2cMasterTarget == nullptr)
+ {
+ TRACFCOMP( g_trac_eeprom,
+ "buildEepromRecordHeader() I2C Master target associated with target 0x%.08X resolved to a nullptr , check attribute for eepromType %d. Skipping Cache ",
+ TARGETING::get_huid(i_target),
+ io_eepromInfo.eepromRole);
+ /*@
+ * @errortype
+ * @moduleid EEPROM_CACHE_EEPROM
+ * @reasoncode EEPROM_I2C_MASTER_PATH_ERROR
+ * @userdata1 HUID of target we want to cache
+ * @userdata2 Type of EEPROM we are caching
+ * @devdesc buildEepromRecordHeader invalid master target
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_CACHE_EEPROM,
+ EEPROM_I2C_MASTER_PATH_ERROR,
+ TARGETING::get_huid(i_target),
+ io_eepromInfo.eepromRole,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_errl->collectTrace(EEPROM_COMP_NAME);
+ break;
+ }
+
+ // This is what we will compare w/ when we are going through the existing
+ // caches in the eeprom to see if we have already cached something
+ // Or if no matches are found we will copy this into the header
+ o_eepromRecordHeader.completeRecord.i2c_master_huid = l_i2cMasterTarget->getAttr<TARGETING::ATTR_HUID>();
+ o_eepromRecordHeader.completeRecord.port = static_cast<uint8_t>(io_eepromInfo.port);
+ o_eepromRecordHeader.completeRecord.engine = static_cast<uint8_t>(io_eepromInfo.engine);
+ o_eepromRecordHeader.completeRecord.devAddr = static_cast<uint8_t>(io_eepromInfo.devAddr);
+ o_eepromRecordHeader.completeRecord.mux_select = static_cast<uint8_t>(io_eepromInfo.i2cMuxBusSelector);
+ o_eepromRecordHeader.completeRecord.cache_copy_size = static_cast<uint32_t>(io_eepromInfo.devSize_KB);
+
+ // Do not set valid bit nor internal offset here as we do not have
+ // enough information availible to determine
+
+ }while(0);
+
+ return l_errl;
+}
+
+errlHndl_t eepromPerformOpCache(DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t& io_buflen,
+ eeprom_addr_t &i_eepromInfo)
+{
+ errlHndl_t l_errl = nullptr;
+ eepromRecordHeader l_eepromRecordHeader;
+
+ do{
+
+ TRACSSCOMP( g_trac_eeprom, ENTER_MRK"eepromPerformOpCache() "
+ "Target HUID 0x%.08X Enter", TARGETING::get_huid(i_target));
+
+ l_errl = buildEepromRecordHeader(i_target,
+ i_eepromInfo,
+ l_eepromRecordHeader);
+
+ if(l_errl)
+ {
+ // buildEepromRecordHeader should have traced any relavent information if
+ // it was needed, just break out and pass the error along
+ break;
+ }
+
+#ifndef __HOSTBOOT_RUNTIME
+ uint64_t l_eepromCacheVaddr = lookupEepromCacheAddr(l_eepromRecordHeader);
+#else
+ uint8_t l_instance = TARGETING::AttrRP::getNodeId(i_target);
+ uint64_t l_eepromCacheVaddr = lookupEepromCacheAddr(l_eepromRecordHeader, l_instance);
+#endif
+
+ // Ensure that a copy of the eeprom exists in our map of cached eeproms
+ if(l_eepromCacheVaddr)
+ {
+ // First check if io_buffer is a nullptr, if so then assume user is
+ // requesting size back in io_bufferlen
+ if(io_buffer == nullptr)
+ {
+ io_buflen = l_eepromRecordHeader.completeRecord.cache_copy_size * KILOBYTE;
+ TRACSSCOMP( g_trac_eeprom, "eepromPerformOpCache() "
+ "io_buffer == nullptr , returning io_buflen as 0x%lx",
+ io_buflen);
+ break;
+ }
+
+ TRACSSCOMP( g_trac_eeprom, "eepromPerformOpCache() "
+ "Performing %s on target 0x%.08X offset 0x%lx length 0x%x vaddr 0x%lx",
+ (i_opType == DeviceFW::READ) ? "READ" : "WRITE",
+ TARGETING::get_huid(i_target),
+ i_eepromInfo.offset, io_buflen, l_eepromCacheVaddr);
+
+ // Make sure that offset + buflen are less than the total size of the eeprom
+ if(i_eepromInfo.offset + io_buflen >
+ (l_eepromRecordHeader.completeRecord.cache_copy_size * KILOBYTE))
+ {
+ TRACFCOMP(g_trac_eeprom,
+ ERR_MRK"eepromPerformOpCache: i_eepromInfo.offset + i_offset is greater than size of eeprom (0x%x KB)",
+ l_eepromRecordHeader.completeRecord.cache_copy_size);
+ /*@
+ * @errortype
+ * @moduleid EEPROM_CACHE_PERFORM_OP
+ * @reasoncode EEPROM_OVERFLOW_ERROR
+ * @userdata1 Length of Operation
+ * @userdata2 Offset we are attempting to read/write
+ * @custdesc Soft error in Firmware
+ * @devdesc cacheEeprom invalid op type
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_CACHE_PERFORM_OP,
+ EEPROM_OVERFLOW_ERROR,
+ TO_UINT64(io_buflen),
+ TO_UINT64(i_eepromInfo.offset),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
+ l_errl->collectTrace( EEPROM_COMP_NAME );
+
+ break;
+ }
+
+ if(i_opType == DeviceFW::READ)
+ {
+ memcpy(io_buffer,
+ reinterpret_cast<void *>(l_eepromCacheVaddr + i_eepromInfo.offset),
+ io_buflen);
+ }
+ else if(i_opType == DeviceFW::WRITE)
+ {
+ memcpy(reinterpret_cast<void *>(l_eepromCacheVaddr + i_eepromInfo.offset),
+ io_buffer,
+ io_buflen);
+
+#ifndef __HOSTBOOT_RUNTIME
+ // Perform flush to ensure pnor is updated
+ int rc = mm_remove_pages( FLUSH,
+ reinterpret_cast<void *>(l_eepromCacheVaddr + i_eepromInfo.offset),
+ io_buflen );
+ if( rc )
+ {
+ TRACFCOMP(g_trac_eeprom,
+ ERR_MRK"eepromPerformOpCache: Error from mm_remove_pages trying for flush contents write to pnor! rc=%d",
+ rc);
+ /*@
+ * @errortype
+ * @moduleid EEPROM_CACHE_PERFORM_OP
+ * @reasoncode EEPROM_FAILED_TO_FLUSH_CONTENTS
+ * @userdata1 Requested Address
+ * @userdata2 rc from mm_remove_pages
+ * @devdesc cacheEeprom mm_remove_pages FLUSH failed
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_CACHE_PERFORM_OP,
+ EEPROM_FAILED_TO_FLUSH_CONTENTS,
+ (l_eepromCacheVaddr + i_eepromInfo.offset),
+ TO_UINT64(rc),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_errl->collectTrace( EEPROM_COMP_NAME );
+ }
+#endif
+ }
+ else
+ {
+ TRACFCOMP(g_trac_eeprom,
+ ERR_MRK"eepromPerformOpCache: Invalid OP_TYPE passed to function, i_opType=%d",
+ i_opType);
+ /*@
+ * @errortype
+ * @moduleid EEPROM_CACHE_PERFORM_OP
+ * @reasoncode EEPROM_INVALID_OPERATION
+ * @userdata1[0:31] Op Type that was invalid
+ * @userdata1[32:63] Eeprom Role
+ * @userdata2 Offset we are attempting to perfrom op on
+ * @custdesc Soft error in Firmware
+ * @devdesc cacheEeprom invalid op type
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_CACHE_PERFORM_OP,
+ EEPROM_INVALID_OPERATION,
+ TWO_UINT32_TO_UINT64(i_opType,
+ i_eepromInfo.eepromRole),
+ TO_UINT64(i_eepromInfo.offset),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
+ l_errl->collectTrace( EEPROM_COMP_NAME );
+ }
+ }
+ else
+ {
+ TRACFCOMP( g_trac_eeprom,"eepromPerformOpCache: Failed to find entry in cache for 0x%.08X, %s failed",
+ TARGETING::get_huid(i_target),
+ (i_opType == DeviceFW::READ) ? "READ" : "WRITE");
+ /*@
+ * @errortype
+ * @moduleid EEPROM_CACHE_PERFORM_OP
+ * @reasoncode EEPROM_NOT_IN_CACHE
+ * @userdata1[0:31] Op Type
+ * @userdata1[32:63] Eeprom Role
+ * @userdata2 Offset we are attempting to read/write
+ * @custdesc Soft error in Firmware
+ * @devdesc Tried to lookup eeprom not in cache
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_CACHE_PERFORM_OP,
+ EEPROM_NOT_IN_CACHE,
+ TWO_UINT32_TO_UINT64(i_opType,
+ i_eepromInfo.eepromRole),
+ TO_UINT64(i_eepromInfo.offset),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errl);
+ l_errl->collectTrace( EEPROM_COMP_NAME );
+ }
+
+ TRACSSCOMP( g_trac_eeprom, EXIT_MRK"eepromPerformOpCache() "
+ "Target HUID 0x%.08X Exit", TARGETING::get_huid(i_target));
+
+ }while(0);
+
+ return l_errl;
+}
+} \ No newline at end of file
diff --git a/src/usr/i2c/eeprom_utils.C b/src/usr/i2c/eeprom_utils.C
index 806a0cf31..8333ebf49 100644
--- a/src/usr/i2c/eeprom_utils.C
+++ b/src/usr/i2c/eeprom_utils.C
@@ -87,6 +87,18 @@ bool eepromPresence ( TARGETING::Target * i_target )
break;
}
+ // If the target has dynamic device address attribute, then use that instead of the
+ // read-only address found in ATTR_EEPROM_XX_INFO attrs. We use the dynamic address
+ // attribute because ATTR_EEPROM_XX_INFO attrs are not writable and its difficult
+ // to override complex attributes.
+ if(i_target->tryGetAttr<TARGETING::ATTR_DYNAMIC_I2C_DEVICE_ADDRESS>(i2cInfo.devAddr))
+ {
+ TRACDCOMP(g_trac_eeprom,
+ "Using DYNAMIC_I2C_DEVICE_ADDRESS %.2x for HUID %.8x",
+ i2cInfo.devAddr,
+ TARGETING::get_huid(i_target));
+ }
+
//Check for the target at the I2C level
l_present = I2C::i2cPresence(i2cMasterTarget,
i2cInfo.port,
@@ -373,7 +385,7 @@ errlHndl_t eepromReadAttributes ( TARGETING::Target * i_target,
// Printing mux info separately, if combined, nothing is displayed
char* l_muxPath = o_i2cInfo.i2cMuxPath.toString();
- TRACFCOMP(g_trac_eeprom, "eepromReadAttributes(): "
+ TRACUCOMP(g_trac_eeprom, "eepromReadAttributes(): "
"muxSelector=0x%X, muxPath=%s",
o_i2cInfo.i2cMuxBusSelector,
l_muxPath);
diff --git a/src/usr/i2c/eepromdd.C b/src/usr/i2c/eepromdd.C
index 74b6d3692..2243e9b38 100755
--- a/src/usr/i2c/eepromdd.C
+++ b/src/usr/i2c/eepromdd.C
@@ -41,6 +41,11 @@
// va_list
#include "eepromCache.H"
#include "eepromdd_hardware.H"
+#include <i2c/eepromddreasoncodes.H>
+#ifdef __HOSTBOOT_RUNTIME
+// Need to be able to convert HB target id's to runtime target ids
+#include <targeting/attrrp.H>
+#endif
extern trace_desc_t* g_trac_eeprom;
@@ -87,19 +92,59 @@ errlHndl_t resolveSource(TARGETING::Target * i_target,
err = buildEepromRecordHeader(i_target,
io_i2cInfo,
l_eepromRecordHeader);
+#ifndef __HOSTBOOT_RUNTIME
// if lookupEepromAddr returns non-zero address
// then we know it exists in cache somewhere
- if(lookupEepromAddr(l_eepromRecordHeader))
+ if(lookupEepromCacheAddr(l_eepromRecordHeader))
{
- TRACFCOMP(g_trac_eeprom,"Eeprom found in cache, looking at eecache");
+ TRACDCOMP(g_trac_eeprom,"Eeprom found in cache, looking at eecache");
o_source = EEPROM::CACHE;
}
else
{
- TRACFCOMP(g_trac_eeprom,"Eeprom not found in cache, looking at hardware");
+ TRACDCOMP(g_trac_eeprom,"Eeprom not found in cache, looking at hardware");
o_source = EEPROM::HARDWARE;
}
-
+#else
+ uint8_t l_instance = TARGETING::AttrRP::getNodeId(i_target);
+ // if lookupEepromAddr returns non-zero address
+ // then we know it exists in cache somewhere
+ if(lookupEepromCacheAddr(l_eepromRecordHeader, l_instance))
+ {
+ TRACDCOMP(g_trac_eeprom,"Eeprom found in cache, looking at eecache");
+ o_source = EEPROM::CACHE;
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @moduleid EEPROM_RESOLVE_SOURCE
+ * @reasoncode EEPROM_CACHE_NOT_FOUND_IN_MAP
+ * @userdata1[0:7] i2c_master_huid
+ * @userdata1[8:9] port on i2c master eeprom slave is on
+ * @userdata1[10:11] engine on i2c master eeprom slave is on
+ * @userdata1[12:13] devAddr of eeprom slave
+ * @userdata1[14:15] muxSelect of eeprom slave (0xFF is not valid)
+ * @userdata2[0:7] size of eeprom
+ * @devdesc resolveSource failed to find cache in map during runtime
+ */
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM_RESOLVE_SOURCE,
+ EEPROM_CACHE_NOT_FOUND_IN_MAP,
+ TWO_UINT32_TO_UINT64(
+ l_eepromRecordHeader.completeRecord.i2c_master_huid,
+ TWO_UINT16_TO_UINT32(
+ TWO_UINT8_TO_UINT16(
+ l_eepromRecordHeader.completeRecord.port,
+ l_eepromRecordHeader.completeRecord.engine),
+ TWO_UINT8_TO_UINT16(
+ l_eepromRecordHeader.completeRecord.devAddr,
+ l_eepromRecordHeader.completeRecord.mux_select))),
+ l_eepromRecordHeader.completeRecord.cache_copy_size,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ }
+#endif
return err;
}
@@ -178,29 +223,35 @@ errlHndl_t eepromPerformOp( DeviceFW::OperationType i_opType,
if(l_source == EEPROM::CACHE )
{
// Read the copy of the EEPROM data we have cached in PNOR
- err = eepromPerformOpCache(i_opType, i_target, io_buffer, io_buflen, i2cInfo);
+ err = eepromPerformOpCache(i_opType, i_target,
+ io_buffer, io_buflen, i2cInfo);
if(err)
{
break;
}
-
- // If the operation is a write we also need to "write through" to HW after
- // we write cache
+ // TODO RTC:212469 Complete Work needed for Axone i2c runtime support
+ #ifndef __HOSTBOOT_RUNTIME
if(i_opType == DeviceFW::WRITE)
{
- err = eepromPerformOpHW(i_opType, i_target, io_buffer, io_buflen, i2cInfo);
+ // If the operation is a write we also need to
+ // "write through" to HW after we write cache
+ err = eepromPerformOpHW(i_opType, i_target,
+ io_buffer, io_buflen, i2cInfo);
}
+ #endif
}
else if(l_source == EEPROM::HARDWARE)
{
// Read from the actual physical EEPROM device
- err = eepromPerformOpHW(i_opType, i_target, io_buffer, io_buflen, i2cInfo);
+ err = eepromPerformOpHW(i_opType, i_target, io_buffer,
+ io_buflen, i2cInfo);
}
#else
// Read from the actual physical EEPROM device
- err = eepromPerformOpHW(i_opType, i_target, io_buffer, io_buflen, i2cInfo);
+ err = eepromPerformOpHW(i_opType, i_target, io_buffer,
+ io_buflen, i2cInfo);
#endif // CONFIG_SUPPORT_EEPROM_CACHING
diff --git a/src/usr/i2c/eepromdd_hardware.C b/src/usr/i2c/eepromdd_hardware.C
index 351ca549a..b48c3889e 100644
--- a/src/usr/i2c/eepromdd_hardware.C
+++ b/src/usr/i2c/eepromdd_hardware.C
@@ -109,7 +109,7 @@ errlHndl_t eepromPerformOpHW(DeviceFW::OperationType i_opType,
( io_i2cInfo.devSize_KB * KILOBYTE ) )
{
TRACFCOMP( g_trac_eeprom,
- ERR_MRK"eepromPerformOp(): Device Overflow! "
+ ERR_MRK"eepromPerformOpHW(): Device Overflow! "
"C-e/p/dA=%d-%d/%d/0x%X, offset=0x%X, len=0x%X "
"devSizeKB=0x%X", io_i2cInfo.eepromRole, io_i2cInfo.engine,
io_i2cInfo.port, io_i2cInfo.devAddr, io_i2cInfo.offset,
@@ -155,19 +155,19 @@ errlHndl_t eepromPerformOpHW(DeviceFW::OperationType i_opType,
l_currentOpLen = l_snglChipSize - io_i2cInfo.offset;
}
- TRACFCOMP( g_trac_eeprom,
- "eepromPerformOp(): i_opType=%d "
+ TRACDCOMP( g_trac_eeprom,
+ "eepromPerformOpHW(): i_opType=%d "
"C-e/p/dA=%d-%d/%d/0x%X, offset=0x%X, len=0x%X, ",
i_opType, io_i2cInfo.eepromRole, io_i2cInfo.engine,
- io_i2cInfo.port, io_i2cInfo.devAddr, io_i2cInfo.offset, io_buflen)
+ io_i2cInfo.port, io_i2cInfo.devAddr, io_i2cInfo.offset, io_buflen);
- TRACFCOMP (g_trac_eeprom,
- "eepromPerformOp(): snglChipKB=0x%X, chipCount=0x%X, devSizeKB=0x%X",
+ TRACDCOMP (g_trac_eeprom,
+ "eepromPerformOpHW(): snglChipKB=0x%X, chipCount=0x%X, devSizeKB=0x%X",
l_snglChipSize, io_i2cInfo.chipCount, io_i2cInfo.devSize_KB);
// Printing mux info separately, if combined, nothing is displayed
char* l_muxPath = io_i2cInfo.i2cMuxPath.toString();
- TRACFCOMP(g_trac_eeprom, "eepromPerformOp(): "
+ TRACDCOMP(g_trac_eeprom, "eepromPerformOpHW(): "
"muxSelector=0x%X, muxPath=%s",
io_i2cInfo.i2cMuxBusSelector,
l_muxPath);
@@ -207,7 +207,7 @@ errlHndl_t eepromPerformOpHW(DeviceFW::OperationType i_opType,
else
{
TRACFCOMP( g_trac_eeprom,
- ERR_MRK"eepromPerformOp(): "
+ ERR_MRK"eepromPerformOpHW(): "
"Invalid EEPROM Operation!");
/*@
diff --git a/src/usr/i2c/fapi_i2c_dd.C b/src/usr/i2c/fapi_i2c_dd.C
index bf1771865..35a838998 100644
--- a/src/usr/i2c/fapi_i2c_dd.C
+++ b/src/usr/i2c/fapi_i2c_dd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -41,6 +41,8 @@
#include <devicefw/driverif.H>
#include <i2c/i2creasoncodes.H>
#include "fapi_i2c_dd.H"
+#include <time.h>
+#include <stdio.h>
extern trace_desc_t* g_trac_i2c;
@@ -69,6 +71,11 @@ DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
TARGETING::TYPE_OCMB_CHIP,
fapiI2cPerformOp );
+DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
+ DeviceFW::FAPI_I2C,
+ TARGETING::TYPE_PMIC,
+ fapiI2cPerformOp );
+
errlHndl_t fapiI2cPerformOp(DeviceFW::OperationType i_opType,
TARGETING::Target * i_target,
void * io_buffer,
@@ -78,6 +85,7 @@ errlHndl_t fapiI2cPerformOp(DeviceFW::OperationType i_opType,
{
errlHndl_t l_err = nullptr;
errlHndl_t l_err_retryable = nullptr;
+ bool l_non_retryable_err_hit = false;
const uint8_t FAPI_I2C_MAX_RETRIES = 2;
TARGETING::ATTR_FAPI_I2C_CONTROL_INFO_type l_i2cInfo;
@@ -89,6 +97,10 @@ errlHndl_t fapiI2cPerformOp(DeviceFW::OperationType i_opType,
l_cfgData = va_arg( i_args, uint8_t* );
}
+ timespec_t l_startTime;
+ timespec_t l_endTime;
+ clock_gettime(CLOCK_MONOTONIC, &l_startTime);
+
TRACUCOMP(g_trac_i2c, ENTER_MRK"fapiI2cPerformOp(): "
"%s operation on target %.8X",
(i_opType==DeviceFW::READ)?"READ":"WRITE",
@@ -103,6 +115,18 @@ errlHndl_t fapiI2cPerformOp(DeviceFW::OperationType i_opType,
break;
}
+ // If the target has dynamic device address attribute, then use that instead of the
+ // read-only address found in ATTR_FAPI_I2C_CONTROL_INFO. We use the dynamic address
+ // attribute because ATTR_FAPI_I2C_CONTROL_INFO is not writable and its difficult
+ // to override complex attributes.
+ if(i_target->tryGetAttr<TARGETING::ATTR_DYNAMIC_I2C_DEVICE_ADDRESS>(l_i2cInfo.devAddr))
+ {
+ TRACDCOMP(g_trac_i2c,
+ "Using DYNAMIC_I2C_DEVICE_ADDRESS %.2x for HUID %.8x",
+ l_i2cInfo.devAddr,
+ TARGETING::get_huid(i_target));
+ }
+
// grab target pointer to master
TARGETING::TargetService& ts = TARGETING::targetService();
TARGETING::Target * i2cm = ts.toTarget(l_i2cInfo.i2cMasterPath);
@@ -136,8 +160,6 @@ errlHndl_t fapiI2cPerformOp(DeviceFW::OperationType i_opType,
TARGETING::get_huid(i_target),
0,
true /*Add HB SW Callout*/ );
-
- l_err->collectTrace( I2C_COMP_NAME );
break;
}
@@ -164,8 +186,6 @@ errlHndl_t fapiI2cPerformOp(DeviceFW::OperationType i_opType,
i_opType,
TARGETING::get_huid(i_target),
true /*Add HB SW Callout*/ );
-
- l_err->collectTrace( I2C_COMP_NAME );
break;
}
@@ -204,8 +224,7 @@ errlHndl_t fapiI2cPerformOp(DeviceFW::OperationType i_opType,
"Error: rc=0x%X, tgt=0x%X, No Retry (retry=%d)",
l_err->reasonCode(),
TARGETING::get_huid(i_target), retry);
- l_err->collectTrace(I2C_COMP_NAME);
-
+ l_non_retryable_err_hit = true;
// break from retry loop
break;
}
@@ -267,35 +286,54 @@ errlHndl_t fapiI2cPerformOp(DeviceFW::OperationType i_opType,
} // end of retryable error loop
+ clock_gettime(CLOCK_MONOTONIC, &l_endTime);
+ char l_time_str[128];
+ snprintf(l_time_str, sizeof(l_time_str),
+ "Start Time: %lu sec %lu ns End Time: %lu sec %lu ns",
+ l_startTime.tv_sec, l_startTime.tv_nsec,
+ l_endTime.tv_sec, l_endTime.tv_nsec);
+
// Handle saved retryable error, if any
if (l_err_retryable)
{
- if (l_err)
+ // This is the case where we had 1 or more retryable errors and
+ // eventually hit a non retryable error.
+ if (l_err && l_non_retryable_err_hit)
{
// commit original retryable error with new err PLID
l_err_retryable->plid(l_err->plid());
TRACFCOMP(g_trac_i2c, "fapiI2cPerformOp(): Committing saved "
"retryable error eid=0x%X with plid of returned err 0x%X",
l_err_retryable->eid(), l_err_retryable->plid());
-
+ ERRORLOG::ErrlUserDetailsString(l_time_str)
+ .addToLog(l_err_retryable);
ERRORLOG::ErrlUserDetailsTarget(i_target)
.addToLog(l_err_retryable);
l_err_retryable->collectTrace(I2C_COMP_NAME);
+ l_err_retryable->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);
errlCommit(l_err_retryable, I2C_COMP_ID);
}
else
{
- // Since we eventually succeeded,
- // delete original retryable error
- TRACUCOMP(g_trac_i2c, "fapiI2cPerformOp(): Op successful, "
- "deleting saved retryable err eid=0x%X, plid=0x%X",
+ // In this case we have either hit the max retryable errors and
+ // failed, or hit one or more retryable errors and eventually
+ // passed. Either way we do not need this l_err_retryable anymore.
+ TRACUCOMP(g_trac_i2c, "fapiI2cPerformOp(): Op successful, or we hit max Retries and"
+ " the caller is polling on this i2c op. Deleting saved retryable err eid=0x%X,"
+ " plid=0x%X.",
l_err_retryable->eid(), l_err_retryable->plid());
-
delete l_err_retryable;
l_err_retryable = nullptr;
}
}
+ if(l_err)
+ {
+ ERRORLOG::ErrlUserDetailsString(l_time_str)
+ .addToLog(l_err);
+ l_err->collectTrace(I2C_COMP_NAME);
+ }
+
} while (0);
return l_err;
@@ -376,10 +414,10 @@ errlHndl_t i2cWrite( TARGETING::Target * i_target,
i_buffer,
io_buffer_size,
DEVICE_I2C_ADDRESS(i_i2cInfo->port,
- i_i2cInfo->engine,
- i_i2cInfo->devAddr,
- i_i2cInfo->i2cMuxBusSelector,
- &(i_i2cInfo->i2cMuxPath) ) );
+ i_i2cInfo->engine,
+ i_i2cInfo->devAddr,
+ i_i2cInfo->i2cMuxBusSelector,
+ &(i_i2cInfo->i2cMuxPath) ) );
if( l_err )
{
diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C
index 63b579202..2439f1eff 100755
--- a/src/usr/i2c/i2c.C
+++ b/src/usr/i2c/i2c.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2019 */
+/* Contributors Listed Below - COPYRIGHT 2011,2020 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -94,6 +94,7 @@ TRAC_INIT( & g_trac_i2cr, "I2CR", KILOBYTE );
#define MAX_NACK_RETRIES 3
#define PAGE_OPERATION 0xffffffff // Special value use to determine type of op
#define P9_ENGINE_SCOM_OFFSET 0x1000
+constexpr uint64_t FSI_BUS_SPEED_MHZ = 133; //FSI runs at 133MHz
// Derived from ATTR_I2C_BUS_SPEED_ARRAY[engine][port] attribute
const TARGETING::ATTR_I2C_BUS_SPEED_ARRAY_type g_var = {{NULL}};
@@ -447,14 +448,16 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
// Else this is not a page operation, call the normal common function
else
{
- if( (subop==DeviceFW::I2C_SMBUS_BLOCK)
- || (subop==DeviceFW::I2C_SMBUS_BYTE)
- || (subop==DeviceFW::I2C_SMBUS_WORD))
+ if( (subop == DeviceFW::I2C_SMBUS_BLOCK)
+ || (subop == DeviceFW::I2C_SMBUS_BYTE)
+ || (subop == DeviceFW::I2C_SMBUS_WORD)
+ || (subop == DeviceFW::I2C_SMBUS_WORD_NO_PEC)
+ || (subop == DeviceFW::I2C_SMBUS_BLOCK_NO_BYTE_COUNT) )
{
args.smbus.commandCode =
static_cast<decltype(args.smbus.commandCode)>(
va_arg(i_args,uint64_t));
- args.smbus.usePec = true; // All implementations use PEC
+ args.smbus.usePec = true; // Most implementations use PEC
args.i2cMuxBusSelector = va_arg(i_args,uint64_t);
args.i2cMuxPath = reinterpret_cast<const TARGETING::EntityPath*>(
va_arg(i_args, uint64_t));
@@ -477,11 +480,23 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
if ( args.offset_length != 0 )
{
args.offset_buffer = temp;
-
}
}
- args.subop=subop;
+ if (subop == DeviceFW::I2C_SMBUS_WORD_NO_PEC)
+ {
+ args.smbus.usePec = false;
+ args.subop = DeviceFW::I2C_SMBUS_WORD;
+ }
+ else if (subop == DeviceFW::I2C_SMBUS_BLOCK_NO_BYTE_COUNT)
+ {
+ args.smbus.usePec = false;
+ args.subop=subop;
+ }
+ else
+ {
+ args.subop=subop;
+ }
err = i2cCommonOp( i_opType,
i_target,
@@ -1284,11 +1299,22 @@ errlHndl_t i2cAccessMux( TARGETING::Target* i_masterTarget,
if (! (l_i2cMuxTarget->tryGetAttr<TARGETING::ATTR_FAPI_I2C_CONTROL_INFO>(l_muxData)) )
{
TRACFCOMP(g_trac_i2c,
- "i2cAccessMux(): get attributes failed");
+ "i2cAccessMux(): getting ATTR_FAPI_I2C_CONTROL_INFO failed");
break;
}
- uint8_t l_muxSelector = i_i2cMuxBusSelector;
+ TARGETING::ATTR_MODEL_type l_muxModel;
+ if (! (l_i2cMuxTarget->tryGetAttr<TARGETING::ATTR_MODEL>(l_muxModel)) )
+ {
+ TRACFCOMP(g_trac_i2c,
+ "i2cAccessMux(): getting ATTR_MODEL failed");
+ break;
+ }
+
+ assert(l_muxModel == TARGETING::MODEL_PCA9847, "Invalid model of mux detected");
+ const uint8_t PCA9847_ENABLE_BIT = 8;
+
+ uint8_t l_muxSelector = i_i2cMuxBusSelector | PCA9847_ENABLE_BIT;
uint8_t *l_ptrMuxSelector = &l_muxSelector;
size_t l_muxSelectorSize = sizeof(l_muxSelector);
@@ -1430,7 +1456,8 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType,
/*******************************************************/
/* Perform the I2C Operation */
/*******************************************************/
-
+ TRACUCOMP( g_trac_i2c, INFO_MRK "i2cCommonOp() -- opType: %d, subOp: %d",
+ static_cast<uint64_t>(i_opType), i_args.subop);
/***********************************************/
/* I2C SMBUS Send Byte */
/***********************************************/
@@ -1598,14 +1625,16 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType,
/***********************************************/
/* I2C SMBUS Block Write */
/***********************************************/
- else if( (i_opType == DeviceFW::WRITE )
- && (i_args.subop == DeviceFW::I2C_SMBUS_BLOCK))
+ else if( (i_opType == DeviceFW::WRITE ) &&
+ ((i_args.subop == DeviceFW::I2C_SMBUS_BLOCK) ||
+ (i_args.subop == DeviceFW::I2C_SMBUS_BLOCK_NO_BYTE_COUNT)) )
{
TRACUCOMP(g_trac_i2c, INFO_MRK
- "I2C SMBUS Block Write: Command code = 0x%02X, "
- "Use PEC = %d. io_buflen = %lu",
- i_args.smbus.commandCode,
- i_args.smbus.usePec, io_buflen);
+ "I2C SMBUS Block Write: Command code = 0x%02X, SubCmd = 0x%02X "
+ "Use PEC = %d. io_buflen = %lu, io_buffer byte0: 0x%02X",
+ i_args.smbus.commandCode, i_args.subop,
+ i_args.smbus.usePec, io_buflen,
+ *reinterpret_cast<uint8_t*>(io_buffer));
// If requested length is for < 1 byte or > 255 bytes for a block
// write transaction, throw an error.
@@ -1649,12 +1678,29 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType,
io_buflen,
io_buffer,
i_args.smbus.usePec);
+ void * writeStart = &blockWrite.commandCode;
+
+ // byteCount might be altered into commandCode, so store its value
+ size_t dataByteCount = blockWrite.byteCount;
+ if (i_args.subop == DeviceFW::I2C_SMBUS_BLOCK_NO_BYTE_COUNT)
+ {
+ // Moving commandCode down a byte so it is followed
+ // immediately by dataBytes[] instead of byteCount
+ // (this removes byteCount from the block write)
+ writeStart = &blockWrite.byteCount;
+ blockWrite.byteCount = blockWrite.commandCode;
+ blockWrite.messageSize -= sizeof(blockWrite.commandCode);
+ TRACUCOMP(g_trac_i2c, INFO_MRK
+ "I2C SMBUS Block Write no-byte-count: removing byteCount,"
+ " msgSize = %d", blockWrite.messageSize);
+ }
+
do {
size_t writeSize = blockWrite.messageSize;
const auto writeSizeExp = writeSize;
err = i2cWrite(i_target,
- &blockWrite.commandCode,
+ writeStart,
writeSize,
i_args);
if(err)
@@ -1666,7 +1712,8 @@ errlHndl_t i2cCommonOp( DeviceFW::OperationType i_opType,
"Write size mismatch; expected %d but got %d",
writeSizeExp,writeSize);
- io_buflen = blockWrite.byteCount;
+
+ io_buflen = dataByteCount;
} while(0);
@@ -4308,13 +4355,23 @@ errlHndl_t i2cSetBusVariables ( TARGETING::Target * i_target,
if ( io_args.switches.useFsiI2C == 1 )
{
- // @todo RTC 117560 - verify correct frequency
- local_bus_MHZ = g_I2C_NEST_FREQ_MHZ;
+ // For FSI I2C we should use the FSI clock
+ local_bus_MHZ = FSI_BUS_SPEED_MHZ;
}
else
{
- // For Host I2C use Nest Frequency
- local_bus_MHZ = g_I2C_NEST_FREQ_MHZ;
+ // For Host I2C use Nest Frequency as base
+
+ // PIB_CLK = NEST_FREQ / 4
+ uint64_t pib_clk = g_I2C_NEST_FREQ_MHZ / 4;
+
+#ifdef CONFIG_AXONE
+ // Axone has a by-2 internal divider
+ local_bus_MHZ = pib_clk / 2;
+#else
+ // Nimbus/Cumulus have a by-4 internal divider
+ local_bus_MHZ = pib_clk / 4;
+#endif
}
io_args.bit_rate_divisor = i2cGetBitRateDivisor(io_args.bus_speed,
@@ -5148,8 +5205,13 @@ void getMasterInfo( const TARGETING::Target* i_chip,
info.engine = engine;
info.freq = i2cGetNestFreq()*FREQ_CONVERSION::HZ_PER_MHZ;
// PIB_CLK = NEST_FREQ /4
- // Local Bus = PIB_CLK / 4
+#ifdef CONFIG_AXONE
+ // Local Bus = PIB_CLK / 2 [Axone]
+ info.freq = info.freq/8; //convert nest to local bus
+#else
+ // Local Bus = PIB_CLK / 4 [Nimbus/Cumulus]
info.freq = info.freq/16; //convert nest to local bus
+#endif
TRACFCOMP(g_trac_i2c,"getMasterInfo(%.8X): pushing back engine=%d, scomAddr=0x%X",TARGETING::get_huid(i_chip), engine, info.scomAddr);
@@ -5447,6 +5509,7 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster,
// Lookup i2c info for the TPM
l_err = TPMDD::tpmReadAttributes(pTpm,
tpmInfo, locality);
+
if( NULL != l_err )
{
// Unable to get info, so we skip
@@ -5474,11 +5537,34 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster,
l_currentDI.slavePort = 0xFF;
l_currentDI.busFreqKhz = (tpmInfo.busFreq)
/ FREQ_CONVERSION::HZ_PER_KHZ;
- l_currentDI.deviceType =
- TARGETING::HDAT_I2C_DEVICE_TYPE_NUVOTON_TPM;
l_currentDI.devicePurpose =
TARGETING::HDAT_I2C_DEVICE_PURPOSE_TPM;
- strcpy(l_currentDI.deviceLabel,"?nuvoton,npct601,tpm,host");
+
+ // Read TPM Model attribute to determine some values
+ if (tpmInfo.model == TPMDD::TPM_MODEL_65x)
+ {
+ strcpy(l_currentDI.deviceLabel,"?nuvoton,npct601,tpm,host");
+ l_currentDI.deviceType =
+ TARGETING::HDAT_I2C_DEVICE_TYPE_NUVOTON_TPM;
+ }
+ else if (tpmInfo.model == TPMDD::TPM_MODEL_75x)
+ {
+ strcpy(l_currentDI.deviceLabel,"?tcg,tpm_i2c_ptp,tpm,host");
+ l_currentDI.deviceType =
+ TARGETING::HDAT_I2C_DEVICE_TYPE_TCG_I2C_TPM;
+ }
+ else
+ {
+ // Should never get here as tpmReadAttributes will fail if
+ // unknown TPM Model, but just in case do this:
+ strcpy(l_currentDI.deviceLabel,
+ "?unknwon,unknown,tpm,host");
+ }
+
+ TRACUCOMP(g_trac_i2c,"TPM 0x%X is Model %d using label %s",
+ TARGETING::get_huid(pTpm),
+ tpmInfo.model,
+ l_currentDI.deviceLabel);
o_deviceInfo.push_back(l_currentDI);
} //end of tpm iter
diff --git a/src/usr/i2c/i2c.H b/src/usr/i2c/i2c.H
index eca944479..6f230ac58 100755
--- a/src/usr/i2c/i2c.H
+++ b/src/usr/i2c/i2c.H
@@ -112,10 +112,10 @@ static uint64_t g_I2C_NEST_FREQ_MHZ = i2cGetNestFreq();
ALWAYS_INLINE inline uint16_t i2cGetBitRateDivisor(uint64_t i_bus_speed_khz,
uint64_t i_local_bus_MHZ)
{
- // BRD = ( ( ( LocalBus_MHZ / 16 ) / i_bus_speed_khz ) - 1 ) / 4
+ // BRD = ( ( LocalBus_MHZ) / i_bus_speed_khz ) - 1 ) / 4
// Use tmp variable to convert everything to KHZ safely
- uint64_t tmp = ( i_local_bus_MHZ / 16 ) * 1000;
+ uint64_t tmp = i_local_bus_MHZ * 1000;
return ( ( ( tmp / i_bus_speed_khz ) - 1 ) / 4 );
}
diff --git a/src/usr/i2c/i2c.mk b/src/usr/i2c/i2c.mk
index 6d4ef8935..0300d2c46 100644
--- a/src/usr/i2c/i2c.mk
+++ b/src/usr/i2c/i2c.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2015
+# Contributors Listed Below - COPYRIGHT 2015,2019
# [+] International Business Machines Corp.
#
#
@@ -27,4 +27,4 @@ OBJS += eepromdd.o
OBJS += eepromdd_hardware.o
OBJS += eeprom_utils.o
OBJS += errlud_i2c.o
-OBJS += $(if $(CONFIG_SUPPORT_EEPROM_CACHING),eepromCache.o)
+OBJS += $(if $(CONFIG_SUPPORT_EEPROM_CACHING),eepromCache_common.o)
diff --git a/src/usr/i2c/i2cTargetPres.C b/src/usr/i2c/i2cTargetPres.C
index c3809f099..c7c9421a3 100644
--- a/src/usr/i2c/i2cTargetPres.C
+++ b/src/usr/i2c/i2cTargetPres.C
@@ -32,7 +32,7 @@
#include <initservice/initserviceif.H>
#include <errl/errlmanager.H>
#include "i2c_common.H"
-
+#include <fapiwrap/fapiWrapif.H>
extern trace_desc_t* g_trac_i2c;
@@ -182,6 +182,18 @@ errlHndl_t genericI2CTargetPresenceDetect(TARGETING::Target* i_target,
//* If we make it through all of the checks then we have verified master is present *
//***********************************************************************************
+ // If the target has dynamic device address attribute, then use that instead of the
+ // read-only address found in ATTR_FAPI_I2C_CONTROL_INFO. We use the dynamic address
+ // attribute because ATTR_FAPI_I2C_CONTROL_INFO is not writable and its difficult
+ // to override complex attributes.
+ if(i_target->tryGetAttr<TARGETING::ATTR_DYNAMIC_I2C_DEVICE_ADDRESS>(l_i2cInfo.devAddr))
+ {
+ TRACDCOMP(g_trac_i2c,
+ "Using DYNAMIC_I2C_DEVICE_ADDRESS %.2x for HUID %.8x",
+ l_i2cInfo.devAddr,
+ TARGETING::get_huid(i_target));
+ }
+
//Check for the target at the I2C level
l_target_present = I2C::i2cPresence(l_i2cMasterTarget,
l_i2cInfo.port,
@@ -223,10 +235,6 @@ errlHndl_t ocmbI2CPresencePerformOp(DeviceFW::OperationType i_opType,
{
errlHndl_t l_invalidateErrl = nullptr;
- // @TODO RTC 208696: Gemini vs Explorer Presence Detection via SPD
- // This function will be updated to differentiate between Explorer and
- // Gemini OCMB chips. For now, presense of an OCMB chip is inferred by
- // the presense of the eeprom.
bool l_ocmbPresent = EEPROM::eepromPresence(i_target);
memcpy(io_buffer, &l_ocmbPresent, sizeof(l_ocmbPresent));
@@ -236,10 +244,97 @@ errlHndl_t ocmbI2CPresencePerformOp(DeviceFW::OperationType i_opType,
}
/**
- * @brief Performs a presence detect operation on a Target that has the
+ * @brief Performs a presence detect operation on a PMIC Target
+ *
+ * @param[in] i_opType Operation type, see DeviceFW::OperationType
+ * in driverif.H
+ * @param[in] i_target Presence detect target
+ * @param[in/out] io_buffer Read: Pointer to output data storage
+ * Write: Pointer to input data storage
+ * @param[in/out] io_buflen Input: size of io_buffer (in bytes, always 1)
+ * Output: Success = 1, Failure = 0
+ * @param[in] i_accessType DeviceFW::AccessType enum (userif.H)
+ * @param[in] i_args This is an argument list for DD framework.
+ * In this function, there are no arguments.
+ * @return errlHndl_t
+ */
+errlHndl_t pmicI2CPresencePerformOp(DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ va_list i_args)
+{
+
+ errlHndl_t l_errl = nullptr;
+ bool l_pmicPresent = 0;
+ uint8_t l_devAddr;
+ TARGETING::Target* l_parentOcmb = TARGETING::getImmediateParentByAffinity(i_target);
+ auto l_parentHwasState = l_parentOcmb->getAttr<TARGETING::ATTR_HWAS_STATE>();
+
+ do{
+
+ if(! l_parentHwasState.present)
+ {
+ // If the parent chip is not present, then neither is the pmic
+ // so just break out and return not present
+ break;
+ }
+
+ TARGETING::ATTR_REL_POS_type l_relPos = i_target->getAttr<TARGETING::ATTR_REL_POS>();
+
+ // PMICs will have a different device address depending on the vendor.
+ // Prior to doing present detection on a pmic we must first query the
+ // device address from the parent OCMB's SPD
+ l_errl = FAPIWRAP::get_pmic_dev_addr(l_parentOcmb,
+ l_relPos,
+ l_devAddr);
+ if (l_errl)
+ {
+ TRACFCOMP( g_trac_i2c, ERR_MRK"pmicI2CPresencePerformOp() "
+ "Error attempting to read pmic device address on OCMB 0x%.08X",
+ TARGETING::get_huid(l_parentOcmb));
+ break;
+ }
+
+ assert(l_devAddr != 0,
+ "Found devAddr for PMIC 0x%.08x to be 0, this cannot be. Check SPD and REL_POS on target",
+ TARGETING::get_huid(i_target));
+
+ if(l_devAddr == FAPIWRAP::NO_PMIC_DEV_ADDR)
+ {
+ // There is no pmic device address for this rel position on this ocmb so
+ // break and return not present.
+ break;
+ }
+
+ i_target->setAttr<TARGETING::ATTR_DYNAMIC_I2C_DEVICE_ADDRESS>(l_devAddr);
+
+ l_errl = genericI2CTargetPresenceDetect(i_target,
+ io_buflen,
+ l_pmicPresent);
+
+ if (l_errl)
+ {
+ TRACFCOMP( g_trac_i2c, ERR_MRK"pmicI2CPresencePerformOp() "
+ "Error detecting target 0x%.08X, io_buffer will not be set",
+ TARGETING::get_huid(i_target));
+ break;
+ }
+
+ // Copy variable describing if target is present or not to i/o buffer param
+ memcpy(io_buffer, &l_pmicPresent, sizeof(l_pmicPresent));
+ io_buflen = sizeof(l_pmicPresent);
+
+ }while(0);
+
+ return l_errl;
+}
+
+/**
+ * @brief Performs a presence detect operation on a Mux Target that has the
* ATTR_FAPI_I2C_CONTROL_INFO and can be detected via that device
*
- * Currently used to detect I2C_MUTEX targets
*
* @param[in] i_opType Operation type, see DeviceFW::OperationType
* in driverif.H
@@ -253,7 +348,7 @@ errlHndl_t ocmbI2CPresencePerformOp(DeviceFW::OperationType i_opType,
* In this function, there are no arguments.
* @return errlHndl_t
*/
-errlHndl_t basicI2CPresencePerformOp(DeviceFW::OperationType i_opType,
+errlHndl_t muxI2CPresencePerformOp(DeviceFW::OperationType i_opType,
TARGETING::Target* i_target,
void* io_buffer,
size_t& io_buflen,
@@ -261,13 +356,13 @@ errlHndl_t basicI2CPresencePerformOp(DeviceFW::OperationType i_opType,
va_list i_args)
{
bool l_muxPresent = 0;
- errlHndl_t l_returnedError = nullptr;
+ errlHndl_t l_errl = nullptr;
- l_returnedError = genericI2CTargetPresenceDetect(i_target,
- io_buflen,
- l_muxPresent);
+ l_errl = genericI2CTargetPresenceDetect(i_target,
+ io_buflen,
+ l_muxPresent);
- if (l_returnedError)
+ if (l_errl)
{
TRACFCOMP( g_trac_i2c, ERR_MRK"basicI2CTargetPresenceDetect() "
"Error detecting target 0x%.08X, io_buffer will not be set",
@@ -280,7 +375,7 @@ errlHndl_t basicI2CPresencePerformOp(DeviceFW::OperationType i_opType,
io_buflen = sizeof(l_muxPresent);
}
- return l_returnedError;
+ return l_errl;
}
// Register the ocmb presence detect function with the device framework
@@ -293,12 +388,12 @@ DEVICE_REGISTER_ROUTE(DeviceFW::READ,
DEVICE_REGISTER_ROUTE( DeviceFW::READ,
DeviceFW::PRESENT,
TARGETING::TYPE_I2C_MUX,
- basicI2CPresencePerformOp );
+ muxI2CPresencePerformOp );
// Register the pmic vrm presence detect function with the device framework
DEVICE_REGISTER_ROUTE( DeviceFW::READ,
DeviceFW::PRESENT,
TARGETING::TYPE_PMIC,
- basicI2CPresencePerformOp );
+ pmicI2CPresencePerformOp );
}
diff --git a/src/usr/i2c/makefile b/src/usr/i2c/makefile
index 535484752..10e55c9de 100644
--- a/src/usr/i2c/makefile
+++ b/src/usr/i2c/makefile
@@ -33,6 +33,7 @@ OBJS += i2c.o
OBJS += $(if $(CONFIG_TPMDD),tpmdd.o,)
OBJS += fapi_i2c_dd.o
OBJS += i2cTargetPres.o
+OBJS += $(if $(CONFIG_SUPPORT_EEPROM_CACHING),eepromCache.o)
SUBDIRS += test.d
SUBDIRS += runtime.d
diff --git a/src/usr/i2c/runtime/makefile b/src/usr/i2c/runtime/makefile
index e6bf9330b..73d3d464b 100644
--- a/src/usr/i2c/runtime/makefile
+++ b/src/usr/i2c/runtime/makefile
@@ -1,11 +1,11 @@
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
-# $Source: src/usr/vpd/runtime/makefile $
+# $Source: src/usr/i2c/runtime/makefile $
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2015
+# Contributors Listed Below - COPYRIGHT 2013,2019
# [+] International Business Machines Corp.
#
#
@@ -32,7 +32,7 @@ include ../i2c.mk
#add unique object modules
OBJS += rt_i2c.o
-
+OBJS += $(if $(CONFIG_SUPPORT_EEPROM_CACHING),rt_eepromCache.o)
VPATH += ..
include $(ROOTPATH)/config.mk
diff --git a/src/usr/i2c/runtime/rt_eepromCache.C b/src/usr/i2c/runtime/rt_eepromCache.C
new file mode 100644
index 000000000..2b775ddb5
--- /dev/null
+++ b/src/usr/i2c/runtime/rt_eepromCache.C
@@ -0,0 +1,285 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/i2c/runtime/rt_eepromCache.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file rt_eepromCache.C
+ *
+ * @brief Runtime functionality of the eeprom cache driver
+ *
+ */
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+
+#include <errl/errlentry.H>
+#include <devicefw/driverif.H>
+#include <i2c/eepromddreasoncodes.H>
+#include <runtime/interface.h>
+#include <targeting/runtime/rt_targeting.H>
+#include <targeting/common/utilFilter.H>
+#include <targeting/attrrp.H>
+#include <trace/interface.H>
+#include <util/runtime/util_rt.H>
+#include <sys/internode.h>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+
+#include "../eepromCache.H"
+
+// ----------------------------------------------
+// Trace definitions
+// ----------------------------------------------
+extern trace_desc_t* g_trac_eeprom;
+
+//#define TRACSSCOMP(args...) TRACFCOMP(args)
+#define TRACSSCOMP(args...)
+
+namespace EEPROM
+{
+
+// Any time we access either any of the global variables defined above we want
+// to wrap the call in this mutex to avoid multi-threading issues
+mutex_t g_eecacheMutex = MUTEX_INITIALIZER;
+
+uint64_t g_eecachePnorVaddr[MAX_NODES_PER_SYS] = {0,0,0,0,0,0,0,0};
+std::map<eepromRecordHeader, EeepromEntryMetaData_t> g_cachedEeproms[MAX_NODES_PER_SYS];
+
+// ------------------------------------------------------------------
+// rtEecacheInit
+// ------------------------------------------------------------------
+struct rtEecacheInit
+{
+ rtEecacheInit()
+ {
+ errlHndl_t l_errl = nullptr;
+
+ // Add cache status for the node
+ TARGETING::TargetHandleList l_nodeList;
+ getEncResources(l_nodeList,
+ TARGETING::TYPE_NODE,
+ TARGETING::UTIL_FILTER_ALL);
+ // Find all the targets with VPD switches
+ for (auto & l_node : l_nodeList)
+ {
+ uint8_t l_instance = TARGETING::AttrRP::getNodeId(l_node);
+ uint64_t vpd_size = 0;
+ eecacheSectionHeader* l_sectionHeader =
+ reinterpret_cast<eecacheSectionHeader*>(
+ hb_get_rt_rsvd_mem(Util::HBRT_MEM_LABEL_VPD,
+ l_instance, vpd_size));
+
+ g_eecachePnorVaddr[l_instance] = reinterpret_cast<uint64_t>(l_sectionHeader);
+
+ // Check if reserved memory does not exist for this instance
+ if ((NULL == l_sectionHeader) || (0 == vpd_size))
+ {
+ TRACFCOMP(g_trac_eeprom,
+ "rtEecacheInit(): ERROR Could not find VPD section of reserved memory for Node %d, ",
+ l_instance);
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid EEPROM_CACHE_INIT_RT
+ * @reasoncode EEPROM_CACHE_NO_VPD_IN_RSV_MEM
+ * @userdata1 Node Id
+ * @userdata2 Unused
+ *
+ * @devdesc Attempted to lookup VPD in reserved memory
+ * and failed
+ * @custdesc A problem occurred during the IPL of the
+ * system.
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM::EEPROM_CACHE_INIT_RT,
+ EEPROM::EEPROM_CACHE_NO_VPD_IN_RSV_MEM,
+ l_instance,
+ 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ errlCommit (l_errl, EEPROM_COMP_ID);
+ break;
+
+ }
+
+ eepromRecordHeader * l_recordHeaderToCopy = nullptr;
+ uint8_t l_eepromCount = 0;
+ for(int8_t i = 0; i < MAX_EEPROMS_VERSION_1; i++)
+ {
+ // Keep track of current record so we can use outside for loop
+ l_recordHeaderToCopy = &l_sectionHeader->recordHeaders[i];
+
+ // If internal_offset is UNSET_INTERNAL_OFFSET_VALUE then we will assume this address not been filled
+ if(l_recordHeaderToCopy->completeRecord.internal_offset != UNSET_INTERNAL_OFFSET_VALUE)
+ {
+ l_eepromCount++;
+ // Will return true if already found an entry in the list
+ if(addEepromToCachedList(*l_recordHeaderToCopy,
+ reinterpret_cast<uint64_t>(l_recordHeaderToCopy),
+ l_instance))
+ {
+
+ TRACFCOMP(g_trac_eeprom,
+ "rtEecacheInit(): ERROR Duplicate cache entries found in VPD reserved memory section");
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid EEPROM_CACHE_INIT_RT
+ * @reasoncode EEPROM_DUPLICATE_CACHE_ENTRY
+ * @userdata1[0:31] i2c_master_huid
+ * @userdata1[32:39] port on i2c master eeprom slave is on
+ * @userdata1[40:47] engine on i2c master eeprom slave is on
+ * @userdata1[48:55] devAddr of eeprom slave
+ * @userdata1[56:63] muxSelect of eeprom slave (0xFF is not valid)
+ * @userdata2[0:31] size of eeprom
+ * @userdata2[32:63] Node Id
+ * @devdesc Attempted to lookup VPD in reserved memory
+ * and failed
+ * @custdesc A problem occurred during the IPL of the
+ * system.
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ EEPROM::EEPROM_CACHE_INIT_RT,
+ EEPROM::EEPROM_DUPLICATE_CACHE_ENTRY,
+ TWO_UINT32_TO_UINT64(
+ l_recordHeaderToCopy->completeRecord.i2c_master_huid,
+ TWO_UINT16_TO_UINT32(
+ TWO_UINT8_TO_UINT16(
+ l_recordHeaderToCopy->completeRecord.port,
+ l_recordHeaderToCopy->completeRecord.engine),
+ TWO_UINT8_TO_UINT16(
+ l_recordHeaderToCopy->completeRecord.devAddr,
+ l_recordHeaderToCopy->completeRecord.mux_select))),
+ TWO_UINT32_TO_UINT64(l_recordHeaderToCopy->completeRecord.cache_copy_size,
+ TO_UINT32(l_instance)),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ errlCommit (l_errl, EEPROM_COMP_ID);
+ // Something is wrong so we have committed the unrecoverable
+ // but keep processing the eeproms because we want a full picture
+ // of what we understand the eeprom cache contents to be
+ continue;
+ }
+ }
+ }
+
+ TRACFCOMP(g_trac_eeprom, "Found %d cached eeproms in reserved memory for node %d",
+ l_eepromCount, l_instance);
+
+ printCurrentCachedEepromMap();
+
+ }
+ }
+
+};
+rtEecacheInit g_rtEecacheInit;
+
+void printCurrentCachedEepromMap(void)
+{
+ TRACFCOMP( g_trac_eeprom,
+ "printCurrentCachedEepromMap():");
+
+ mutex_lock(&g_eecacheMutex);
+ for(int8_t i = 0; i < MAX_NODES_PER_SYS; i++)
+ {
+ for(std::map<eepromRecordHeader, EeepromEntryMetaData_t>::iterator iter = g_cachedEeproms[i].begin();
+ iter != g_cachedEeproms[i].end();
+ ++iter)
+ {
+ TRACSSCOMP( g_trac_eeprom,
+ "printTableOfContents(): I2CM Huid: 0x%.08X, Port: 0x%.02X,"
+ " Engine: 0x%.02X, Dev Addr: 0x%.02X,"
+ " Mux Select: 0x%.02X, Size: 0x%.08X",
+ iter->first.completeRecord.i2c_master_huid,
+ iter->first.completeRecord.port,
+ iter->first.completeRecord.engine,
+ iter->first.completeRecord.devAddr,
+ iter->first.completeRecord.mux_select,
+ iter->first.completeRecord.cache_copy_size);
+
+ TRACSSCOMP( g_trac_eeprom,
+ " "
+ "Internal Offset: 0x%.08X, Cache Valid: 0x%.02X",
+ iter->first.completeRecord.internal_offset,
+ iter->first.completeRecord.cached_copy_valid);
+ }
+ }
+ mutex_unlock(&g_eecacheMutex);
+
+}
+
+uint64_t lookupEepromCacheAddr(const eepromRecordHeader& i_eepromRecordHeader,
+ const uint8_t i_instance)
+{
+ uint64_t l_vaddr = 0;
+ std::map<eepromRecordHeader, EeepromEntryMetaData_t>::iterator l_it;
+
+ // Wrap lookup in mutex because reads are not thread safe
+ mutex_lock(&g_eecacheMutex);
+ l_it = g_cachedEeproms[i_instance].find(i_eepromRecordHeader);
+
+ if(l_it != g_cachedEeproms[i_instance].end())
+ {
+ l_vaddr = l_it->second.cache_entry_address;
+ }
+ mutex_unlock(&g_eecacheMutex);
+ return l_vaddr;
+}
+
+bool addEepromToCachedList(const eepromRecordHeader & i_eepromRecordHeader,
+ const uint64_t i_recordHeaderVaddr,
+ const uint8_t i_instance)
+{
+ bool l_matchFound = true;
+
+ // Map accesses are not thread safe, make sure this is always wrapped in mutex
+ mutex_lock(&g_eecacheMutex);
+
+ if(g_cachedEeproms[i_instance].find(i_eepromRecordHeader) ==
+ g_cachedEeproms[i_instance].end())
+ {
+ g_cachedEeproms[i_instance][i_eepromRecordHeader].cache_entry_address =
+ g_eecachePnorVaddr[i_instance] + i_eepromRecordHeader.completeRecord.internal_offset;
+
+ g_cachedEeproms[i_instance][i_eepromRecordHeader].header_entry_address =
+ i_recordHeaderVaddr;
+
+ TRACSSCOMP( g_trac_eeprom,
+ "addEepromToCachedList() Adding I2CM Huid: 0x%.08X, Port: 0x%.02X,"
+ " Engine: 0x%.02X, Dev Addr: 0x%.02X, Mux Select: 0x%.02X,"
+ " Size: 0x%.08X to g_cachedEeproms",
+ i_eepromRecordHeader.completeRecord.i2c_master_huid,
+ i_eepromRecordHeader.completeRecord.port,
+ i_eepromRecordHeader.completeRecord.engine,
+ i_eepromRecordHeader.completeRecord.devAddr,
+ i_eepromRecordHeader.completeRecord.mux_select,
+ i_eepromRecordHeader.completeRecord.cache_copy_size);
+
+ l_matchFound = false;
+ }
+
+ mutex_unlock(&g_eecacheMutex);
+
+ return l_matchFound;
+}
+
+} // end namespace EEPROM
diff --git a/src/usr/i2c/runtime/rt_i2c.C b/src/usr/i2c/runtime/rt_i2c.C
index 16f62c76e..d3f5537c6 100755
--- a/src/usr/i2c/runtime/rt_i2c.C
+++ b/src/usr/i2c/runtime/rt_i2c.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -41,7 +41,7 @@
#include <devicefw/driverif.H>
#include <i2c/i2creasoncodes.H>
#include <runtime/interface.h>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include "../errlud_i2c.H"
// ----------------------------------------------
@@ -146,10 +146,10 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
int rc = 0;
bool l_host_if_enabled = true;
- RT_TARG::rtChipId_t proc_id = 0;
+ TARGETING::rtChipId_t proc_id = 0;
// Convert target to proc id
- err = RT_TARG::getRtTarget( i_target,
+ err = TARGETING::getRtTarget( i_target,
proc_id);
if(err)
{
diff --git a/src/usr/i2c/test/eecachetest.H b/src/usr/i2c/test/eecachetest.H
new file mode 100644
index 000000000..cc5233bf6
--- /dev/null
+++ b/src/usr/i2c/test/eecachetest.H
@@ -0,0 +1,121 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/i2c/test/eecachetest.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __EECACHETEST_H
+#define __EECACHETEST_H
+
+/**
+ * @file eepromtest.H
+ *
+ * @brief Test cases for the eeprom cache code
+ */
+
+#include <cxxtest/TestSuite.H>
+#include "../eepromCache.H"
+
+extern trace_desc_t* g_trac_eeprom;
+
+using namespace TARGETING;
+using namespace EEPROM;
+
+class EECACHETest: public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief Verify we can mark a cache as invalid then mark it valid again
+ */
+ void test_invalidateCache( void )
+ {
+ uint8_t l_numTests = 0;
+ uint8_t l_numFails = 0;
+
+ TRACFCOMP( g_trac_eeprom, ENTER_MRK"test_invalidateCache" );
+
+ do{
+ // Uncomment to verify manually
+ //printTableOfContents();
+
+ // Get a processor Target
+ TARGETING::TargetService& tS = TARGETING::targetService();
+ TARGETING::Target* testTarget = NULL;
+ tS.masterProcChipTargetHandle( testTarget );
+ assert(testTarget != NULL);
+
+ // Create dummy eeprom info w/ VPD_PRIMARY set
+ const EEPROM_ROLE l_eepromRole = EEPROM::VPD_PRIMARY;
+
+ eeprom_addr_t l_primaryVpdEeprom;
+ l_primaryVpdEeprom.eepromRole = l_eepromRole;
+
+ eepromRecordHeader l_eepromRecordHeader_forLookup;
+ eepromRecordHeader * l_eepromRecordHeader_realPnor;
+
+ buildEepromRecordHeader( testTarget,
+ l_primaryVpdEeprom,
+ l_eepromRecordHeader_forLookup);
+
+ l_eepromRecordHeader_realPnor = reinterpret_cast<eepromRecordHeader *>(lookupEepromHeaderAddr(l_eepromRecordHeader_forLookup));
+
+ l_numTests++;
+ if(l_eepromRecordHeader_realPnor->completeRecord.cached_copy_valid != 1)
+ {
+ TS_FAIL("test_invalidateCache Master Proc VPD EECACHE is expected to be valid at start of test!");
+ l_numFails++;
+ break;
+ }
+
+ // Invalidate the cache entry
+ setIsValidCacheEntry(testTarget, l_eepromRole, 0);
+
+ l_numTests++;
+ if(l_eepromRecordHeader_realPnor->completeRecord.cached_copy_valid != 0)
+ {
+ TS_FAIL("test_invalidateCache Master Proc VPD EECACHE is expected to be invalid after setIsValidCacheEntry(invalid) is called!");
+ l_numFails++;
+ break;
+ }
+
+ // Re-validate the cache entry
+ setIsValidCacheEntry(testTarget, l_eepromRole, 1);
+
+ l_numTests++;
+ if(l_eepromRecordHeader_realPnor->completeRecord.cached_copy_valid != 1)
+ {
+ TS_FAIL("test_invalidateCache Master Proc VPD EECACHE is expected to be invalid after setIsValidCacheEntry(valid) is called!");
+ l_numFails++;
+ break;
+ }
+
+ // Uncomment to verify manually
+ // printTableOfContents();
+
+ }while(0);
+
+ TRACFCOMP( g_trac_eeprom, EXIT_MRK"test_getEEPROMs numTests = %d / num fails = %d", l_numTests, l_numFails );
+ }
+
+};
+
+#endif \ No newline at end of file
diff --git a/src/usr/i2c/test/makefile b/src/usr/i2c/test/makefile
index ef774e6e0..fa9cf31c0 100644
--- a/src/usr/i2c/test/makefile
+++ b/src/usr/i2c/test/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2011,2015
+# Contributors Listed Below - COPYRIGHT 2011,2019
# [+] International Business Machines Corp.
#
#
@@ -26,6 +26,7 @@ ROOTPATH = ../../../..
MODULE = testi2c
TESTS = eepromddtest.H
+TESTS += $(if $(CONFIG_SUPPORT_EEPROM_CACHING), eecachetest.H, )
TESTS += i2ctest.H
TESTS += $(if $(CONFIG_TPMDD),tpmddtest.H,)
diff --git a/src/usr/i2c/test/tpmddtest.H b/src/usr/i2c/test/tpmddtest.H
index 8cd1fbc2c..0ea987949 100755
--- a/src/usr/i2c/test/tpmddtest.H
+++ b/src/usr/i2c/test/tpmddtest.H
@@ -111,21 +111,33 @@ class TPMDDTest: public CxxTest::TestSuite
uint32_t data = 0x0;
size_t dataSize = sizeof(data);
+ // default to most common ID
+ uint32_t expected_vendorID = TPMDD::TPM_VENDORID_65x;
+ uint8_t tpmModel = TPM_MODEL_UNDETERMINED;
+
TRACFCOMP( g_trac_tpmdd,
"testTPMReadVendorID - Start" );
do
{
-#ifdef CONFIG_AXONE_BRING_UP
- TRACFCOMP( g_trac_tpmdd,"Skipping test on Axone" );
- break;
-#endif
-
// Get a TPM Target
TARGETING::Target* testTarget = getTestTarget();
if (NULL == testTarget)
{
- continue;
+ break;
+ }
+
+ if ( !(testTarget->tryGetAttr<ATTR_TPM_MODEL>(tpmModel)) )
+ {
+ TS_FAIL("Unable to read ATTR_TPM_MODEL for %.8X target",
+ get_huid(testTarget));
+ break;
+ }
+
+ // This should match Axone and later systems
+ if (TPM_MODEL_75x == tpmModel)
+ {
+ expected_vendorID = TPMDD::TPM_VENDORID_75x;
}
num_ops++;
@@ -144,16 +156,16 @@ class TPMDDTest: public CxxTest::TestSuite
TPMDD_COMP_ID );
delete err;
err = NULL;
- continue;
+ break;
}
else if ((data & TPMDD::TPM_VENDORID_MASK)
- // Only 65x supported in simics for now:
- != TPMDD::TPM_VENDORID_65x)
+ != expected_vendorID)
{
fails++;
TS_FAIL( "testTPMReadVendorID - Failed to read "
- "correct vendor id ID=0x%X", data);
- continue;
+ "correct vendor id ID=0x%X, expected 0x%X", data,
+ expected_vendorID);
+ break;
}
else
@@ -161,7 +173,7 @@ class TPMDDTest: public CxxTest::TestSuite
TRACUCOMP(g_trac_tpmdd, "testTPMReadVendorID - "
"VendorID returned as expected. ID=0x%X",
data);
- continue;
+ break;
}
} while( 0 );
TRACFCOMP( g_trac_tpmdd,
diff --git a/src/usr/i2c/tpmdd.C b/src/usr/i2c/tpmdd.C
index a6f96514b..93aac12b9 100755
--- a/src/usr/i2c/tpmdd.C
+++ b/src/usr/i2c/tpmdd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2019 */
+/* Contributors Listed Below - COPYRIGHT 2011,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -51,7 +51,6 @@
#include <i2c/i2cif.H>
#include <secureboot/service.H>
#include <secureboot/trustedbootif.H>
-#include <scom/centaurScomCache.H> // for TRACE_ERR_FMT, TRACE_ERR_ARGS
#include "tpmdd.H"
#include "errlud_i2c.H"
diff --git a/src/usr/initservice/baseinitsvc/initservice.C b/src/usr/initservice/baseinitsvc/initservice.C
index d06b36f6a..acd70bb42 100644
--- a/src/usr/initservice/baseinitsvc/initservice.C
+++ b/src/usr/initservice/baseinitsvc/initservice.C
@@ -1060,8 +1060,7 @@ bool InitService::unregisterShutdownEvent(msg_q_t i_msgQ)
{
for(EventRegistry_t::iterator r = iv_regMsgQ.begin();
- r != iv_regMsgQ.end();
- ++r)
+ r != iv_regMsgQ.end();)
{
// erase all instances
if(r->msgQ == i_msgQ)
@@ -1072,7 +1071,11 @@ bool InitService::unregisterShutdownEvent(msg_q_t i_msgQ)
r->compID, r->msgQ, r->msgType, r->msgPriority);
result = true;
- iv_regMsgQ.erase(r);
+ r = iv_regMsgQ.erase(r);
+ }
+ else
+ {
+ ++r;
}
}
}
diff --git a/src/usr/initservice/bootconfig/bootconfig.C b/src/usr/initservice/bootconfig/bootconfig.C
index 8e2bf266b..f4839eee7 100644
--- a/src/usr/initservice/bootconfig/bootconfig.C
+++ b/src/usr/initservice/bootconfig/bootconfig.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,7 +27,6 @@
/******************************************************************************/
#include <lpc/lpcif.H>
#include <devicefw/userif.H>
-#include <config.h>
#include <errl/errlentry.H>
#include "bootconfig.H"
diff --git a/src/usr/initservice/bootconfig/bootconfig_ast2400.C b/src/usr/initservice/bootconfig/bootconfig_ast2400.C
index 87caa32a5..cd4916203 100644
--- a/src/usr/initservice/bootconfig/bootconfig_ast2400.C
+++ b/src/usr/initservice/bootconfig/bootconfig_ast2400.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,7 +33,6 @@
#include <trace/interface.H>
#include <hwas/common/deconfigGard.H>
#include <console/consoleif.H>
-#include <config.h>
#include <sio/sio.H>
#include <devicefw/driverif.H>
diff --git a/src/usr/initservice/bootconfig/bootconfigif.C b/src/usr/initservice/bootconfig/bootconfigif.C
index 488a8f537..1d931d705 100644
--- a/src/usr/initservice/bootconfig/bootconfigif.C
+++ b/src/usr/initservice/bootconfig/bootconfigif.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,12 +27,10 @@
/******************************************************************************/
#include <lpc/lpcif.H>
#include <devicefw/userif.H>
-#include <config.h>
#include <errl/errlentry.H>
#include <initservice/bootconfigif.H>
#include "bootconfig.H"
#include "bootconfig_ast2400.H"
-#include <config.h>
namespace INITSERVICE
{
diff --git a/src/usr/initservice/extinitsvc/extinitsvctasks.H b/src/usr/initservice/extinitsvc/extinitsvctasks.H
index ef8fb76f0..70b88a0d4 100644
--- a/src/usr/initservice/extinitsvc/extinitsvctasks.H
+++ b/src/usr/initservice/extinitsvc/extinitsvctasks.H
@@ -276,7 +276,17 @@ const TaskInfo g_exttaskinfolist[] = {
EXT_IMAGE, // Extended Module
}
},
-
+ /**
+ * @brief fapiwrap task, handles fapi wrapper for platform libraries
+ */
+ {
+ "libfapiwrap.so" , // taskname
+ NULL, // no pointer to fn
+ {
+ INIT_TASK, // task type
+ EXT_IMAGE, // Extended Module
+ }
+ },
// @todo RTC:145354 Restore testprdf and testattn in p9 branch
/**
@@ -430,6 +440,18 @@ const TaskInfo g_exttaskinfolist[] = {
},
#endif
+ /**
+ * @brief SMF module
+ */
+ {
+ "libsmf.so", // taskname
+ NULL, // no pointer to fn
+ {
+ INIT_TASK, // task type
+ EXT_IMAGE, // Extended Module
+ }
+ },
+
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// NOTE: libistepdisp.so needs to always be last in this list!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C
index 8f2d57298..4680bb82c 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.C
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C
@@ -78,7 +78,6 @@
#include <ipmi/ipmiif.H>
#endif
-#include <config.h>
#include <initservice/bootconfigif.H>
#include <trace/trace.H>
#include <util/utilmbox_scratch.H>
@@ -94,6 +93,7 @@
#include <p9_perv_scom_addresses.H>
// ---------------------------
#include <initservice/extinitserviceif.H>
+#include <kernel/terminate.H>
namespace ISTEPS_TRACE
@@ -2508,6 +2508,9 @@ errlHndl_t IStepDispatcher::sendProgressCode(bool i_needsLock)
Util::writeScratchReg( SPLESS::MBOX_SCRATCH_REG5,
l_scratch5.data32 );
+ //--- Push the scratch reg into kernel to be added into TI area
+ termSetIstep(l_scratch5.data32);
+
#ifdef CONFIG_ISTEP_LPC_PORT80_DEBUG
// Starting port 80h value for hostboot isteps. Each step started will
// increase the value by one.
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.H b/src/usr/initservice/istepdispatcher/istepdispatcher.H
index 558fc95d1..ea383c4c9 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.H
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -44,7 +44,6 @@
#include <initservice/taskargs.H>
#include <initservice/initsvcreasoncodes.H>
#include <initservice/initsvcstructs.H>
-#include <config.h>
#include "../baseinitsvc/initservice.H"
#include "splesscommon.H"
#include "istep_mbox_msgs.H"
diff --git a/src/usr/intr/intrrp.C b/src/usr/intr/intrrp.C
index d198610af..37b40ca97 100644
--- a/src/usr/intr/intrrp.C
+++ b/src/usr/intr/intrrp.C
@@ -53,7 +53,6 @@
#include <arch/ppc.H>
#include <arch/pirformat.H>
#include <arch/pvrformat.H>
-#include <config.h>
#include <p9_misc_scom_addresses.H>
#include <p9n2_misc_scom_addresses_fld.H>
#include <util/utilmbox_scratch.H>
@@ -547,13 +546,6 @@ errlHndl_t IntrRp::_init()
break;
}
- //Route LSI interrupt events over PSIHB instead of local wire
- // This is a HW Bug Workaround for slaves using the PSIHB and
- // the master using the local wire
- routeLSIInterrupts(l_procIntrHdlr);
-
- enableLsiInterrupts();
-
TRACFCOMP(g_trac_intr, "IntrRp::_init() Enabling PSIHB Interrupts");
//Enable PSIHB Interrupts
l_err = enableInterrupts(l_procIntrHdlr);
@@ -562,6 +554,13 @@ errlHndl_t IntrRp::_init()
TRACFCOMP(g_trac_intr, "IntrRp::_init() Error enabling Interrupts");
break;
}
+
+ //Route LSI interrupt events over PSIHB instead of local wire
+ // This is a HW Bug Workaround for slaves using the PSIHB and
+ // the master using the local wire
+ routeLSIInterrupts(l_procIntrHdlr);
+
+ enableLsiInterrupts();
}
// Build up list of unregistered LSI sources, at this point no sourced
diff --git a/src/usr/ipmibase/ipmibt.C b/src/usr/ipmibase/ipmibt.C
index 1f99a3384..8e4a3b38f 100644
--- a/src/usr/ipmibase/ipmibt.C
+++ b/src/usr/ipmibase/ipmibt.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,7 +38,6 @@
#include "ipmirp.H"
#include <ipmi/ipmiif.H>
#include <errno.h>
-#include <config.h>
// Defined in ipmidd.C
extern trace_desc_t * g_trac_ipmi;
diff --git a/src/usr/ipmibase/ipmiconfig.C b/src/usr/ipmibase/ipmiconfig.C
index 269ae00b2..278f21028 100644
--- a/src/usr/ipmibase/ipmiconfig.C
+++ b/src/usr/ipmibase/ipmiconfig.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -30,7 +30,7 @@
// Information contained in the Get Interface Capabilities command
//
// Request to response time default, in seconds
-const uint8_t IPMI::g_bmc_timeout = 5;
+const uint8_t IPMI::g_bmc_timeout = 30;
// Number of allowed outstanding requests default
const uint8_t IPMI::g_outstanding_req = 0x01;
diff --git a/src/usr/ipmibase/ipmidd.C b/src/usr/ipmibase/ipmidd.C
index 647930442..16582af68 100644
--- a/src/usr/ipmibase/ipmidd.C
+++ b/src/usr/ipmibase/ipmidd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,7 +42,6 @@
#include <initservice/initserviceif.H>
#include <util/align.H>
#include <lpc/lpcif.H>
-#include <config.h>
#include <sys/msg.h>
#include <errno.h>
diff --git a/src/usr/ipmibase/ipmimsg.C b/src/usr/ipmibase/ipmimsg.C
index d86b68229..f4d1705bd 100644
--- a/src/usr/ipmibase/ipmimsg.C
+++ b/src/usr/ipmibase/ipmimsg.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -32,7 +32,6 @@
#include "ipmimsg.H"
#include <kernel/console.H>
-#include <config.h>
// Defined in ipmidd.C
extern trace_desc_t * g_trac_ipmi;
diff --git a/src/usr/ipmibase/ipmirp.C b/src/usr/ipmibase/ipmirp.C
index fb502ee98..152521cc0 100644
--- a/src/usr/ipmibase/ipmirp.C
+++ b/src/usr/ipmibase/ipmirp.C
@@ -36,7 +36,6 @@
#include <devicefw/driverif.H>
#include <devicefw/userif.H>
-#include <config.h>
#include <sys/task.h>
#include <initservice/taskargs.H>
#include <initservice/initserviceif.H>
diff --git a/src/usr/ipmiext/ipmidcmi.C b/src/usr/ipmiext/ipmidcmi.C
index 24f192d29..b3f9d1e22 100644
--- a/src/usr/ipmiext/ipmidcmi.C
+++ b/src/usr/ipmiext/ipmidcmi.C
@@ -5,8 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
+/* [+] Maxim Polyakov */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -34,6 +35,8 @@
#include <ipmi/ipmi_reasoncodes.H>
extern trace_desc_t * g_trac_ipmi;
+#define DCMI_CAP_RESPONSE_DATA_LENGTH 7
+
namespace SENSOR
{
enum dcmi_cc
@@ -42,6 +45,107 @@ namespace SENSOR
POWER_LIMIT_NOT_ACTIVE = 0x80,
};
+ static errlHndl_t getPowerManagementSupportStatus(bool &support)
+ {
+ errlHndl_t err = NULL;
+ IPMI::completion_code cc = IPMI::CC_UNKBAD;
+
+ support = false;
+
+ size_t len = 2;
+ uint8_t* data = new uint8_t[len];
+ data[0] = 0xDC; // Group Extension Identification
+ data[1] = 0x01; // Selector - Supported DCMI Capabilities
+
+ err = IPMI::sendrecv(IPMI::get_dcmi_capability_info(), cc, len, data);
+ do
+ {
+ if (err)
+ {
+ TRACFCOMP(g_trac_ipmi,
+ "Failed to send DCMI Capabilities Command to BMC");
+ break;
+ }
+
+ if (cc != IPMI::CC_OK)
+ {
+ TRACFCOMP(g_trac_ipmi,
+ "Get DCMI Capabilities Command: "
+ "bad completion code from BMC=0x%x",
+ cc);
+
+ /*@
+ * @errortype ERRL_SEV_INFORMATIONAL
+ * @moduleid IPMI::MOD_IPMIDCMI
+ * @reasoncode IPMI::RC_GET_DCMI_CAP_CMD_FAILED
+ * @userdata1 BMC IPMI Completion code.
+ * @devdesc Request to get DCMI Capabilities information
+ * failed
+ * @custdesc The DCMI Capabilities Info Command retrieve
+ * data from the BMC has failed.
+ *
+ */
+
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ IPMI::MOD_IPMIDCMI,
+ IPMI::RC_GET_DCMI_CAP_CMD_FAILED,
+ static_cast<uint64_t>(cc),
+ 0,
+ true);
+ break;
+ }
+
+ if (len != DCMI_CAP_RESPONSE_DATA_LENGTH)
+ {
+ TRACFCOMP(g_trac_ipmi,
+ "Get DCMI Capabilities Command: "
+ "invalid data length=%d",
+ len);
+
+ /*@
+ * @errortype ERRL_SEV_INFORMATIONAL
+ * @moduleid IPMI::MOD_IPMIDCMI
+ * @reasoncode IPMI::RC_INVALID_QRESPONSE
+ * @userdata1 Response data length.
+ * @devdesc Request to get DCMI Capabilities information
+ * failed
+ * @custdesc The DCMI Capabilities Info Command retrieve
+ * data with invalid length.
+ *
+ */
+
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ IPMI::MOD_IPMIDCMI,
+ IPMI::RC_INVALID_QRESPONSE,
+ static_cast<uint64_t>(len),
+ 0,
+ true);
+ break;
+ }
+
+ // from the DCMI spec v1.5, Revision 1.0, August 23, 2011
+ // DCMI Capabilities Response Command Format:
+ // cc: byte 1 completion code
+ // data:
+ // data[0]: byte 1 0xDC
+ // data[1]: byte 2 Major Version (01h)
+ // data[2]: byte 3 Minor Version (05h)
+ // data[3]: byte 4 Parameter Revision (02h)
+ // data[4]: byte 5 Reserved
+ // data[5]: byte 6 Platform capabilities
+ // [7:1] Reserved
+ // [0] Power management
+ // data[6]: byte 7 Manageability Access Capabilities
+ support = !!(data[5] & 0x1);
+
+ } while(false);
+
+ delete[] data;
+ return err;
+ }
+
// fetch the user defined power limit stored on the BMC
// using the DCMI Get Power Limit command
errlHndl_t getUserPowerLimit( uint16_t &o_powerLimit, bool &o_limitActive )
@@ -53,6 +157,31 @@ namespace SENSOR
errlHndl_t l_err = NULL;
+ // Power Management support check
+ bool support;
+ l_err = getPowerManagementSupportStatus(support);
+ if (l_err != NULL)
+ {
+ // Since the Power Management support information isn`t received,
+ // commit this error and still try to read the power limit. If the
+ // Power Management is really unsupported, the DCMI Get Power Limit
+ // command will return error code in l_cc
+ l_err->collectTrace(IPMI_COMP_NAME);
+ errlCommit(l_err, IPMI_COMP_ID);
+
+ TRACFCOMP(g_trac_ipmi,
+ "Failed to determine if the BMC supports Power Management");
+
+ support = true;
+ }
+
+ if (!support)
+ {
+ TRACFCOMP(g_trac_ipmi,
+ "Power Management is not supported by BMC");
+ return NULL;
+ }
+
// per DCMI spec data size is 3 bytes
size_t len = 3;
diff --git a/src/usr/ipmiext/ipmifruinv.C b/src/usr/ipmiext/ipmifruinv.C
index e70d5afa0..14ad957d1 100644
--- a/src/usr/ipmiext/ipmifruinv.C
+++ b/src/usr/ipmiext/ipmifruinv.C
@@ -7,8 +7,9 @@
/* */
/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
-/* [+] Jim Yuan */
-/* [+] Maxim Polyakov */
+/* [+] Super Micro Computer, Inc. */
+/* [+] YADRO */
+/* [+] lixg */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -546,42 +547,43 @@ errlHndl_t IpmiFruInv::formatMfgData(std::vector<uint8_t> i_mfgDateData,
{
errlHndl_t l_errl = NULL;
- // MB keyword size is 8 hex bytes, throw an error if it is smaller so we
- // don't do an invalid access.
- if (i_mfgDateData.size() != 8)
+ do
{
- /*@
- * @errortype
- * @moduleid IPMI::MOD_IPMIFRU_INV
- * @reasoncode IPMI::RC_INVALID_VPD_DATA
- * @userdata1 Size of vpd data
- *
- * @devdesc VPD data is invalid size
- */
- l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
- IPMI::MOD_IPMIFRU_INV,
- IPMI::RC_INVALID_VPD_DATA,
- i_mfgDateData.size());
-
- TARGETING::Target* nodeTarget = NULL;
- TARGETING::PredicateCTM nodeFilter(TARGETING::CLASS_ENC,
- TARGETING::TYPE_NODE);
- TARGETING::TargetRangeFilter nodeItr(
- TARGETING::targetService().begin(),
- TARGETING::targetService().end(),
- &nodeFilter);
-
- nodeTarget = *nodeItr;
-
- // Callout out node since that is where the VPD lives
- l_errl->addHwCallout(nodeTarget,
- HWAS::SRCI_PRIORITY_HIGH,
- HWAS::NO_DECONFIG,
- HWAS::GARD_NULL );
+ // MB keyword size is 8 hex bytes, throw an error if it is smaller so we
+ // don't do an invalid access.
+ if (i_mfgDateData.size() != 8)
+ {
+ /*@
+ * @errortype
+ * @moduleid IPMI::MOD_IPMIFRU_INV
+ * @reasoncode IPMI::RC_INVALID_VPD_DATA
+ * @userdata1 Size of vpd data
+ *
+ * @devdesc VPD data is invalid size
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ IPMI::MOD_IPMIFRU_INV,
+ IPMI::RC_INVALID_VPD_DATA,
+ i_mfgDateData.size());
+
+ TARGETING::Target* nodeTarget = NULL;
+ TARGETING::PredicateCTM nodeFilter(TARGETING::CLASS_ENC,
+ TARGETING::TYPE_NODE);
+ TARGETING::TargetRangeFilter nodeItr(
+ TARGETING::targetService().begin(),
+ TARGETING::targetService().end(),
+ &nodeFilter);
+
+ nodeTarget = *nodeItr;
+
+ // Callout out node since that is where the VPD lives
+ l_errl->addHwCallout(nodeTarget,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL );
+ break;
+ }
- }
- else
- {
// Convert Centuries / Years / months / day / hour / minute / second
// into a uint64 representing number of minute since 1/1/96
@@ -594,6 +596,25 @@ errlHndl_t IpmiFruInv::formatMfgData(std::vector<uint8_t> i_mfgDateData,
uint8_t hour = bcd2_to_int(i_mfgDateData.at(5));
uint8_t minute = bcd2_to_int(i_mfgDateData.at(6));
+ // Do some sanity checking on the data so the math below doesn't
+ // go crazy and cause a crash
+ if ( (century < 20)
+ || (month < 1) || (month > 12)
+ || (day < 1) || (day > 31)
+ || (hour > 23) || (minute > 59) )
+ {
+ o_mfgDate = 0xFFFFFFFF;
+ TRACFCOMP(g_trac_ipmi,"MfgDate error: %02X %02X %02X %02X %02X %02X %02X ",
+ i_mfgDateData.at(0),
+ i_mfgDateData.at(1),
+ i_mfgDateData.at(2),
+ i_mfgDateData.at(3),
+ i_mfgDateData.at(4),
+ i_mfgDateData.at(5),
+ i_mfgDateData.at(6));
+ break;
+ }
+
// Subtract year
uint8_t numOfYears = (century*100 + year) - 1996;
// Subtract month
@@ -612,6 +633,7 @@ errlHndl_t IpmiFruInv::formatMfgData(std::vector<uint8_t> i_mfgDateData,
// Add a day for every leap year
// Check if we need to consider the current year
+ // Year is related to century, anybody familiar with this may fix it
if (month <= 2)
{
// We don't need to consider this year for a leap year, as it
@@ -638,7 +660,7 @@ errlHndl_t IpmiFruInv::formatMfgData(std::vector<uint8_t> i_mfgDateData,
// Convert into minutes
o_mfgDate = (((numOfDays*24)*60) + (hour*60) + minute);
- }
+ } while(0);
return l_errl;
}
@@ -2406,6 +2428,8 @@ void IPMIFRUINV::gatherSetData(const TARGETING::Target* i_pSys,
TARGETING::PredicateCTM predChip(TARGETING::CLASS_CHIP);
TARGETING::PredicateCTM predDimm(TARGETING::CLASS_LOGICAL_CARD,
TARGETING::TYPE_DIMM);
+ TARGETING::PredicateCTM predOcmb(TARGETING::CLASS_CHIP,
+ TARGETING::TYPE_OCMB_CHIP);
TARGETING::PredicatePostfixExpr checkExpr;
TARGETING::PredicateHwas l_present;
// @todo-RTC:124553 - Additional logic for deconfigured Frus
@@ -2427,6 +2451,9 @@ void IPMIFRUINV::gatherSetData(const TARGETING::Target* i_pSys,
checkExpr.push(&predDimm).Or().push(&l_present).And();
}
+ // We do NOT want to process fruInv for OCMB_CHIP targets
+ checkExpr.push(&predOcmb).Not().And();
+
TARGETING::TargetHandleList pCheckPres;
TARGETING::targetService().getAssociated( pCheckPres, i_pSys,
TARGETING::TargetService::CHILD, TARGETING::TargetService::ALL,
diff --git a/src/usr/ipmiext/ipmisensor.C b/src/usr/ipmiext/ipmisensor.C
index 5dd428d06..ae6032353 100644
--- a/src/usr/ipmiext/ipmisensor.C
+++ b/src/usr/ipmiext/ipmisensor.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -1363,7 +1363,7 @@ namespace SENSOR
TARGETING::targetService().getTopLevelTarget(sys);
assert(sys != NULL);
getChildAffinityTargets(nodes, sys, TARGETING::CLASS_ENC,
- TARGETING::TYPE_NODE);
+ TARGETING::TYPE_NODE, false);
assert(!nodes.empty());
//Backplane sensor ID
@@ -1390,8 +1390,13 @@ namespace SENSOR
static uint16_t L_NV_bits = 0;
errlHndl_t l_err = nullptr;
- if (L_NV_bits == 0)
- {
+ do {
+ // only do the lookup once
+ if (L_NV_bits != 0)
+ {
+ break;
+ }
+
// grab system enclosure node
TARGETING::TargetHandle_t l_sys = NULL;
TARGETING::TargetHandleList l_nodeTargets;
@@ -1399,61 +1404,63 @@ namespace SENSOR
assert(l_sys != NULL);
getChildAffinityTargets(l_nodeTargets, l_sys, TARGETING::CLASS_ENC,
TARGETING::TYPE_NODE);
- assert(!l_nodeTargets.empty());
+ if(l_nodeTargets.empty())
+ {
+ TRACFCOMP(g_trac_ipmi,"getNVCfgIDBit(): No functional nodes - forcing invalid config");
+ break;
+ }
// get keyword size first
PVPD::pvpdRecord l_Record = PVPD::VNDR;
PVPD::pvpdKeyword l_KeyWord = PVPD::NV;
size_t l_nvKwdSize = 0;
l_err = deviceRead(l_nodeTargets[0],NULL,l_nvKwdSize,
- DEVICE_PVPD_ADDRESS(l_Record,l_KeyWord));
- if (!l_err)
+ DEVICE_PVPD_ADDRESS(l_Record,l_KeyWord));
+ if (l_err)
{
- if (l_nvKwdSize == sizeof(HDAT::hdatNVKwdStruct_t))
+ TRACFCOMP(g_trac_ipmi,"getNVCfgIDBit(): Error getting VNDR:NV size");
+ break;
+ }
+
+ if (l_nvKwdSize != sizeof(HDAT::hdatNVKwdStruct_t))
+ {
+ TRACFCOMP(g_trac_ipmi,"Invalid NV keyword size: %d, expected %d",l_nvKwdSize,sizeof(HDAT::hdatNVKwdStruct_t));
+ break;
+ }
+
+ uint8_t l_kwd[l_nvKwdSize] = {0};
+ // now read the keyword
+ l_err = deviceRead(l_nodeTargets[0],l_kwd,l_nvKwdSize,
+ DEVICE_PVPD_ADDRESS(l_Record,l_KeyWord));
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_ipmi,"getNVCfgIDBit(): Error reading VNDR:NV");
+ break;
+ }
+
+ HDAT::hdatNVKwdStruct_t * NVptr =
+ reinterpret_cast<HDAT::hdatNVKwdStruct_t*>(l_kwd);
+
+ // Valid NV keyword config has NV00 as magic header
+ if ( !memcmp((char*)&(NVptr->magic),"NV00", 4) )
+ {
+ uint8_t cfgID = NVptr->config;
+ if (cfgID < 16) // maximum setting (bits 0-15)
{
- uint8_t l_kwd[l_nvKwdSize] = {0};
- // now read the keyword
- l_err = deviceRead(l_nodeTargets[0],l_kwd,l_nvKwdSize,
- DEVICE_PVPD_ADDRESS(l_Record,l_KeyWord));
- if (!l_err)
- {
- HDAT::hdatNVKwdStruct_t * NVptr =
- reinterpret_cast<HDAT::hdatNVKwdStruct_t*>(l_kwd);
-
- // Valid NV keyword config has NV00 as magic header
- if ( !memcmp((char*)&(NVptr->magic),"NV00", 4) )
- {
- uint8_t cfgID = NVptr->config;
- if (cfgID < 16) // maximum setting (bits 0-15)
- {
- L_NV_bits = 0x0001 << cfgID;
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,"getNVCfgIDBit(): Invalid NV config 0x%02X", cfgID);
- }
- }
- else
- {
- TRACFCOMP(g_trac_ipmi, "Invalid NV magic header: 0x%.8X", NVptr->magic);
- TRACFBIN(g_trac_ipmi, "NV KEYWORD", l_kwd, l_nvKwdSize);
- }
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,ERR_MRK"%.8X Error getting VNDR record data",l_err->eid());
- }
+ L_NV_bits = 0x0001 << cfgID;
}
else
{
- TRACFCOMP(g_trac_ipmi,"Invalid NV keyword size: %d, expected %d",l_nvKwdSize,sizeof(HDAT::hdatNVKwdStruct_t));
+ TRACFCOMP(g_trac_ipmi,"getNVCfgIDBit(): Invalid NV config 0x%02X", cfgID);
+ break;
}
}
else
{
- TRACFCOMP(g_trac_ipmi,ERR_MRK"%.8X Error getting VNDR record size",l_err->eid());
+ TRACFCOMP(g_trac_ipmi, "Invalid NV magic header: 0x%.8X", NVptr->magic);
+ TRACFBIN(g_trac_ipmi, "NV KEYWORD", l_kwd, l_nvKwdSize);
}
- }
+ } while(0);
o_cfgID_bitwise = L_NV_bits;
diff --git a/src/usr/ipmiext/runtime/rt_ipmirp.C b/src/usr/ipmiext/runtime/rt_ipmirp.C
index 496b3f782..83b4d9b10 100644
--- a/src/usr/ipmiext/runtime/rt_ipmirp.C
+++ b/src/usr/ipmiext/runtime/rt_ipmirp.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -30,7 +30,6 @@
#include <ipmi/ipmi_reasoncodes.H>
#include <ipmi/ipmiif.H>
-#include <config.h>
#include <sys/task.h>
#include <initservice/taskargs.H>
#include <initservice/initserviceif.H>
diff --git a/src/usr/isteps/expupd/expupd.C b/src/usr/isteps/expupd/expupd.C
new file mode 100644
index 000000000..3f63ac191
--- /dev/null
+++ b/src/usr/isteps/expupd/expupd.C
@@ -0,0 +1,393 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/isteps/expupd/expupd.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include <expupd/expupd_reasoncodes.H>
+#include <pnor/pnorif.H>
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/utilFilter.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <isteps/hwpisteperror.H>
+#include <isteps/hwpistepud.H>
+#include <fapi2.H>
+#include <fapi2/plat_hwp_invoker.H>
+#include <fapi2/hw_access.H>
+#include <chipids.H>
+#include <trace/interface.H>
+#include <hbotcompid.H>
+#include "ocmbFwImage.H"
+#include <exp_fw_update.H>
+#include <initservice/istepdispatcherif.H>
+
+using namespace ISTEP_ERROR;
+using namespace ERRORLOG;
+using namespace TARGETING;
+
+namespace expupd
+{
+
+// Initialize the trace buffer for this component
+trace_desc_t* g_trac_expupd = nullptr;
+TRAC_INIT(&g_trac_expupd, EXPUPD_COMP_NAME, 2*KILOBYTE);
+
+/**
+ * @brief Structure for retrieving the explorer SHA512 hash value
+ *
+ */
+typedef union sha512regs
+{
+ struct
+ {
+ uint32_t imageId;
+ uint8_t sha512Hash[HEADER_SHA512_SIZE];
+ };
+ uint8_t unformatted[sizeof(uint32_t) + HEADER_SHA512_SIZE];
+}sha512regs_t;
+
+/**
+ * @brief Retrieve the SHA512 hash for the currently flashed explorer
+ * firmware image.
+ *
+ * @param[in] i_target Target of the OCMB chip to retrieve the SHA512 hash
+ * @param[out] o_regs Structure for storing the retrieved SHA512 hash
+ *
+ * @return NULL on success. Non-null on failure.
+ */
+errlHndl_t getFlashedHash(TargetHandle_t i_target, sha512regs_t& o_regs)
+{
+ fapi2::buffer<uint64_t> l_scomBuffer;
+ uint8_t* l_scomPtr = reinterpret_cast<uint8_t*>(l_scomBuffer.pointer());
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>l_fapi2Target(i_target);
+ errlHndl_t l_err = nullptr;
+
+ //Start addres of hash register (a.k.a. RAM1 register)
+ const uint32_t HASH_REG_ADDR = 0x00002200;
+
+ // loop until we've filled the sha512regs_t struct
+ for(uint32_t l_bytesCopied = 0; l_bytesCopied < sizeof(sha512regs_t);
+ l_bytesCopied += sizeof(uint32_t))
+ {
+ // Use getScom, this knows internally whether to use i2c or inband
+ FAPI_INVOKE_HWP(l_err, getScom,
+ l_fapi2Target,
+ HASH_REG_ADDR + l_bytesCopied,
+ l_scomBuffer);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "getFlashedHash: Failed reading SHA512 hash from"
+ " ocmb[0x%08x]. bytesCopied[%u]",
+ TARGETING::get_huid(i_target), l_bytesCopied);
+
+ break;
+ }
+
+ // copy scom buffer into the unformatted uint8_t array.
+ // Even though the scom buffer is 8 bytes, only 4 bytes are read and
+ // copied into the least significant 4 bytes.
+ memcpy(&o_regs.unformatted[l_bytesCopied], l_scomPtr + sizeof(uint32_t),
+ sizeof(uint32_t));
+ }
+
+ return l_err;
+}
+
+/**
+ * @brief Check flash image SHA512 hash value of each explorer chip
+ * and update the flash if it does not match the SHA512 hash
+ * of the image in PNOR.
+ *
+ * @param[out] o_stepError Error handle for logging istep failures
+ *
+ */
+void updateAll(IStepError& o_stepError)
+{
+ bool l_imageLoaded = false;
+ errlHndl_t l_err = nullptr;
+ bool l_rebootRequired = false;
+
+ // Get a list of OCMB chips
+ TARGETING::TargetHandleList l_ocmbTargetList;
+ getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
+
+ Target* l_pTopLevel = nullptr;
+ targetService().getTopLevelTarget( l_pTopLevel );
+ assert(l_pTopLevel, "expupd::updateAll: no TopLevelTarget");
+
+ TRACFCOMP(g_trac_expupd, ENTER_MRK
+ "updateAll: %d ocmb chips found",
+ l_ocmbTargetList.size());
+
+ do
+ {
+ // If no OCMB chips exist, we're done.
+ if(l_ocmbTargetList.size() == 0)
+ {
+ break;
+ }
+
+ // Check if we have any overrides to force our behavior
+ auto l_forced_behavior =
+ l_pTopLevel->getAttr<TARGETING::ATTR_OCMB_FW_UPDATE_OVERRIDE>();
+
+ // Exit now if told to
+ if( TARGETING::OCMB_FW_UPDATE_BEHAVIOR_PREVENT_UPDATE
+ == l_forced_behavior )
+ {
+ TRACFCOMP(g_trac_expupd, INFO_MRK "Skipping update due to override (PREVENT_UPDATE)");
+ break;
+ }
+
+ // Read explorer fw image from pnor
+ PNOR::SectionInfo_t l_pnorSectionInfo;
+ rawImageInfo_t l_imageInfo;
+
+#ifdef CONFIG_SECUREBOOT
+ l_err = PNOR::loadSecureSection(PNOR::OCMBFW);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "updateAll: Failed to load OCMBFW section"
+ " from PNOR!");
+
+ l_err->collectTrace(EXPUPD_COMP_NAME);
+
+ // Create IStep error log and cross reference to error that occurred
+ o_stepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, EXPUPD_COMP_ID );
+
+ break;
+ }
+#endif //CONFIG_SECUREBOOT
+
+ l_imageLoaded = true;
+
+ // get address and size of packaged image
+ l_err = PNOR::getSectionInfo(PNOR::OCMBFW, l_pnorSectionInfo);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "updateAll: Failure in getSectionInfo()");
+
+ l_err->collectTrace(EXPUPD_COMP_NAME);
+
+ // Create IStep error log and cross reference to error that occurred
+ o_stepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, EXPUPD_COMP_ID );
+ break;
+ }
+
+ // Verify the header and retrieve address, size and
+ // SHA512 hash of unpackaged image
+ l_err = ocmbFwValidateImage(
+ l_pnorSectionInfo.vaddr,
+ l_pnorSectionInfo.secureProtectedPayloadSize,
+ l_imageInfo);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "updateAll: Failure in expupdValidateImage");
+
+ l_err->collectTrace(EXPUPD_COMP_NAME);
+
+ // Create IStep error log and cross reference to error that occurred
+ o_stepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, EXPUPD_COMP_ID );
+ break;
+ }
+
+ // For each explorer chip, compare flash hash with PNOR hash and
+ // create a list of explorer chips with differing hash values.
+ TARGETING::TargetHandleList l_flashUpdateList;
+ for(const auto & l_ocmbTarget : l_ocmbTargetList)
+ {
+ sha512regs_t l_regs;
+
+ //skip all gemini ocmb chips (not updateable)
+ if(l_ocmbTarget->getAttr<TARGETING::ATTR_CHIP_ID>() ==
+ POWER_CHIPID::GEMINI_16)
+ {
+ TRACFCOMP(g_trac_expupd,
+ "updateAll: skipping update of gemini OCMB 0x%08x",
+ TARGETING::get_huid(l_ocmbTarget));
+ continue;
+ }
+
+ //retrieve the SHA512 hash for the currently flashed image.
+ l_err = getFlashedHash(l_ocmbTarget, l_regs);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "updateAll: Failure in getFlashedHash(huid = 0x%08x)",
+ TARGETING::get_huid(l_ocmbTarget));
+
+ l_err->collectTrace(EXPUPD_COMP_NAME);
+
+ // Create IStep error log and cross reference to error
+ // that occurred
+ o_stepError.addErrorDetails(l_err);
+
+ errlCommit(l_err, EXPUPD_COMP_ID);
+
+ //Don't stop on error, go to next target.
+ continue;
+ }
+
+ // Trace the hash and image ID values
+ TRACFCOMP(g_trac_expupd,
+ "updateAll: OCMB 0x%08x image ID=0x%08x",
+ TARGETING::get_huid(l_ocmbTarget), l_regs.imageId);
+ TRACFBIN(g_trac_expupd, "SHA512 HASH FROM EXPLORER",
+ l_regs.sha512Hash, HEADER_SHA512_SIZE);
+
+ //Compare hashes. If different, add to list for update.
+ if(memcmp(l_regs.sha512Hash, l_imageInfo.imageSHA512HashPtr,
+ HEADER_SHA512_SIZE))
+ {
+ TRACFCOMP(g_trac_expupd,
+ "updateAll: SHA512 hash mismatch on ocmb[0x%08x]",
+ TARGETING::get_huid(l_ocmbTarget));
+
+ //add target to our list of targets needing an update
+ l_flashUpdateList.push_back(l_ocmbTarget);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_expupd,
+ "updateAll: SHA512 hash for ocmb[0x%08x]"
+ " matches SHA512 hash of PNOR image.",
+ TARGETING::get_huid(l_ocmbTarget));
+
+ // Add every OCMB to the update list if told to
+ if( TARGETING::OCMB_FW_UPDATE_BEHAVIOR_FORCE_UPDATE
+ == l_forced_behavior )
+ {
+ TRACFCOMP(g_trac_expupd, INFO_MRK "Forcing update due to override (FORCE_UPDATE)");
+ l_flashUpdateList.push_back(l_ocmbTarget);
+ }
+ }
+ }
+
+ TRACFCOMP(g_trac_expupd,
+ "updateAll: updating flash for %d OCMB chips",
+ l_flashUpdateList.size());
+
+ // Exit now if we were asked to only do the check portion
+ if( TARGETING::OCMB_FW_UPDATE_BEHAVIOR_CHECK_BUT_NO_UPDATE
+ == l_forced_behavior )
+ {
+ TRACFCOMP(g_trac_expupd, INFO_MRK "Skipping update due to override (CHECK_BUT_NO_UPDATE)");
+ break;
+ }
+
+ // update each explorer in the list of chips needing updates
+ for(const auto & l_ocmb : l_flashUpdateList)
+ {
+ TRACFCOMP(g_trac_expupd, "updateAll: updating OCMB 0x%08x",
+ TARGETING::get_huid(l_ocmb));
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>l_fapi2Target(l_ocmb);
+
+ // reset watchdog for each ocmb as this function can be very slow
+ INITSERVICE::sendProgressCode();
+
+ // Invoke procedure
+ FAPI_INVOKE_HWP(l_err, exp_fw_update, l_fapi2Target,
+ l_imageInfo.imagePtr, l_imageInfo.imageSize);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_expupd,
+ "Error from exp_fw_update for OCMB 0x%08x",
+ TARGETING::get_huid(l_ocmb));
+
+ l_err->collectTrace(EXPUPD_COMP_NAME);
+
+ // Create IStep error log and cross reference to error
+ // that occurred
+ o_stepError.addErrorDetails( l_err );
+
+ errlCommit(l_err, EXPUPD_COMP_ID);
+
+ // Don't stop on error, go to next target.
+ continue;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_expupd,
+ "updateAll: successfully updated OCMB 0x%08x",
+ TARGETING::get_huid(l_ocmb));
+
+ // Request reboot for new firmware to be used
+ l_rebootRequired = true;
+ }
+ }
+ }while(0);
+
+ // unload explorer fw image
+ if(l_imageLoaded)
+ {
+#ifdef CONFIG_SECUREBOOT
+ l_err = PNOR::unloadSecureSection(PNOR::OCMBFW);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "updateAll: Failed to unload OCMBFW");
+
+ l_err->collectTrace(EXPUPD_COMP_NAME);
+
+ // Create IStep error log and cross reference to error that occurred
+ o_stepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, EXPUPD_COMP_ID );
+ }
+#endif //CONFIG_SECUREBOOT
+ }
+
+ // force reboot if any updates were successful
+ if(l_rebootRequired)
+ {
+ TRACFCOMP(g_trac_expupd,
+ "updateAll: OCMB chip(s) was updated. Requesting reboot...");
+ auto l_reconfigAttr =
+ l_pTopLevel->getAttr<TARGETING::ATTR_RECONFIGURE_LOOP>();
+ l_reconfigAttr |= RECONFIGURE_LOOP_OCMB_FW_UPDATE;
+ l_pTopLevel->setAttr<TARGETING::ATTR_RECONFIGURE_LOOP>(l_reconfigAttr);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_expupd, "updateAll: No OCMB chips were updated");
+ }
+
+
+ TRACFCOMP(g_trac_expupd, EXIT_MRK"updateAll()");
+}
+
+}//namespace expupd
diff --git a/src/usr/isteps/expupd/expupd.mk b/src/usr/isteps/expupd/expupd.mk
new file mode 100644
index 000000000..b7b769e7a
--- /dev/null
+++ b/src/usr/isteps/expupd/expupd.mk
@@ -0,0 +1,38 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/isteps/expupd/expupd.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+EXTRAINCDIR += ${ROOTPATH}/src/import
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc/
+EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils
+
+OBJS += expupd.o
+OBJS += ocmbFwImage.o
+
+# Need to build exp_fw_update procedure
+OBJS += exp_fw_update.o
diff --git a/src/usr/isteps/expupd/expupd_trace.H b/src/usr/isteps/expupd/expupd_trace.H
new file mode 100644
index 000000000..a2da13a8f
--- /dev/null
+++ b/src/usr/isteps/expupd/expupd_trace.H
@@ -0,0 +1,40 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/isteps/expupd/expupd_trace.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __EXPUPD_TRACE_H
+#define __EXPUPD_TRACE_H
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <trace/interface.H>
+
+namespace expupd
+{
+
+extern trace_desc_t *g_trac_expupd;
+
+} // end namespace
+
+#endif
diff --git a/src/usr/isteps/expupd/makefile b/src/usr/isteps/expupd/makefile
new file mode 100644
index 000000000..2ee89f6e4
--- /dev/null
+++ b/src/usr/isteps/expupd/makefile
@@ -0,0 +1,35 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/isteps/expupd/makefile $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+ROOTPATH = ../../../..
+MODULE = expupd
+
+SUBDIRS += test.d
+
+include expupd.mk
+
+include ${ROOTPATH}/config.mk
+
+VPATH += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
diff --git a/src/usr/isteps/expupd/ocmbFwImage.C b/src/usr/isteps/expupd/ocmbFwImage.C
new file mode 100644
index 000000000..dee2affdd
--- /dev/null
+++ b/src/usr/isteps/expupd/ocmbFwImage.C
@@ -0,0 +1,391 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/isteps/expupd/ocmbFwImage.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include "ocmbFwImage.H"
+#include <expupd/ocmbFwImage_const.H>
+#include <expupd/expupd_reasoncodes.H>
+#include "expupd_trace.H"
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <hbotcompid.H>
+#include <algorithm>
+
+#define EXPUPD_8BYTE_ALIGNED(_SIZE) (!(_SIZE & 0x7))
+
+namespace expupd
+{
+
+/**
+ * @brief Validates a tagged data triplet
+ * @param[in] i_tripletPtr starting address of a tagged data triplet
+ * @param[in] i_endDataPtr ending address of the OCMB firmware header
+ * @param[out] o_imageInfo Structure will hold pointer to SHA512 hash (if found)
+ * @param[out] o_numBytes total number of bytes used by this tagged data triplet
+ * @return errlHndl_t indicating success or failure
+ *
+ */
+errlHndl_t parseTaggedDataTriplet(const uint8_t* i_tripletPtr,
+ const uint8_t* i_endDataPtr,
+ rawImageInfo_t& o_imageInfo,
+ uint32_t& o_numBytes)
+{
+ errlHndl_t l_err = nullptr;
+
+ // Determine start of the data for the tagged data triplet
+ const uint8_t* l_dataStartPtr = i_tripletPtr + sizeof(taggedTriplet_t);
+ const taggedTriplet_t* l_ttPtr =
+ reinterpret_cast<const taggedTriplet_t*>(i_tripletPtr);
+
+ // Assume failure and set number of bytes consumed to 0
+ o_numBytes = 0;
+
+ do
+ {
+ // Check that we have enough room for the triplet
+ if((l_dataStartPtr > i_endDataPtr) ||
+ ((l_dataStartPtr + l_ttPtr->dataSize) > i_endDataPtr) ||
+ !EXPUPD_8BYTE_ALIGNED(l_ttPtr->dataSize))
+ {
+ int64_t l_reqdSize = sizeof(taggedTriplet_t);
+ l_reqdSize += (l_dataStartPtr > i_endDataPtr)? 0: l_ttPtr->dataSize;
+
+ int64_t l_allocSize =
+ reinterpret_cast<int64_t>(i_endDataPtr - i_tripletPtr);
+
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "parseTaggedDataTriplet: Triplet does not fit or is"
+ " misaligned. bytesReqd[%d] bytesAllocated[%d]",
+ l_reqdSize,
+ l_allocSize);
+
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_PARSE_TAGGED_DATA_TRIPLET
+ * @reasoncode EXPUPD::INVALID_DATA_TRIPLET_SIZE
+ * @userdata1 allocated size
+ * @userdata2 required size
+ * @devdesc Tagged data triplet size is too big or misaligned
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_PARSE_TAGGED_DATA_TRIPLET,
+ EXPUPD::INVALID_DATA_TRIPLET_SIZE,
+ l_allocSize,
+ l_reqdSize,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ // Check for the SHA512 tag
+ if(l_ttPtr->tagId == TAG_SHA512)
+ {
+ // Check that hash data is complete
+ if(l_ttPtr->dataSize != HEADER_SHA512_SIZE)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "parseTaggedDataTriplet: Invalid hash triplet size."
+ " expected[%u] actual[%u]",
+ HEADER_SHA512_SIZE,
+ l_ttPtr->dataSize);
+
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_PARSE_TAGGED_DATA_TRIPLET
+ * @reasoncode EXPUPD::INVALID_HASH_TRIPLET_SIZE
+ * @userdata1 Expected Size
+ * @userdata2 Actual Size
+ * @devdesc Incorrect hash size in OCMB image header
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_PARSE_TAGGED_DATA_TRIPLET,
+ EXPUPD::INVALID_HASH_TRIPLET_SIZE,
+ HEADER_SHA512_SIZE,
+ l_ttPtr->dataSize,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ // Save off pointer to hash for later.
+ o_imageInfo.imageSHA512HashPtr = l_dataStartPtr;
+ }
+ else if(l_ttPtr->tagId == TAG_KEY_VALUE_PAIRS)
+ {
+ //trace up to MAX_BIN_TRACE bytes of the data in case it is useful
+ TRACFBIN(g_trac_expupd, "OCMB FW IMAGE KEY/VALUE DATA",
+ l_dataStartPtr,
+ std::min(l_ttPtr->dataSize, MAX_BIN_TRACE));
+ }
+ else
+ {
+ //unsupported tag id.
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "parseTaggedDataTriplet: Invalid tag id[%u].",
+ l_ttPtr->tagId);
+
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_PARSE_TAGGED_DATA_TRIPLET
+ * @reasoncode EXPUPD::INVALID_TAG_ID
+ * @userdata1 tag id
+ * @userdata2 <unused>
+ * @devdesc Invalid tag id found in OCMB image header
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_PARSE_TAGGED_DATA_TRIPLET,
+ EXPUPD::INVALID_TAG_ID,
+ l_ttPtr->tagId,
+ 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ //Parsing was successful. Set bytes consumed.
+ o_numBytes = sizeof(taggedTriplet_t) + l_ttPtr->dataSize;
+ }while(0);
+
+ return l_err;
+}
+
+/**
+ * @brief Validates OCMB firmware header of packaged image
+ *
+ * @param[in] i_imageStart Start address of packaged image
+ * @param[in] i_imageSize Size of packaged image
+ * @param[out] o_imageInfo Information pertaining to image after
+ * being stripped of OCMB firmware header
+ * @return errlHndl_t indicating success or failure
+ *
+ */
+errlHndl_t ocmbFwValidateImage(const uint64_t i_imageStart,
+ const uint64_t i_imageSize,
+ rawImageInfo_t& o_imageInfo)
+{
+ const uint8_t* l_imageStartPtr =
+ reinterpret_cast<const uint8_t*>(i_imageStart);
+ errlHndl_t l_err = nullptr;
+
+ TRACFCOMP(g_trac_expupd,
+ ENTER_MRK "ocmbFwValidateImage(): startAddr[0x%016x] size[%u]",
+ i_imageStart, i_imageSize);
+
+ //clear out o_imageInfo
+ memset(&o_imageInfo, 0, sizeof(o_imageInfo));
+
+ do
+ {
+ const uint64_t l_minHeaderSize =
+ sizeof(ocmbFwHeader_t) +
+ sizeof(taggedTriplet_t) + HEADER_SHA512_SIZE;
+
+ const uint64_t l_maxHeaderSize =
+ std::min(static_cast<const uint64_t>(HEADER_MAX_SIZE),
+ i_imageSize);
+
+ // Check input parameters
+ if((!l_imageStartPtr) || (i_imageSize < l_minHeaderSize))
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "ocmbFwValidateImage: Invalid image address[%p] or"
+ " size[%u]",
+ l_imageStartPtr, i_imageSize);
+
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE
+ * @reasoncode EXPUPD::INVALID_PARMS
+ * @userdata1 i_imageStart
+ * @userdata2 i_imageSize
+ * @devdesc Invalid size or address for OCMB Flash Image
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE,
+ EXPUPD::INVALID_PARMS,
+ i_imageStart,
+ i_imageSize,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ const ocmbFwHeader_t* l_header =
+ reinterpret_cast<const ocmbFwHeader_t*>(l_imageStartPtr);
+
+ // Check eye catcher value
+ if(l_header->eyeCatcher != EYE_CATCHER_VALUE)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "ocmbFwValidateImage: Invalid eye catcher value: "
+ "expected[0x%016llx] actual[0x%016llx]",
+ EYE_CATCHER_VALUE, l_header->eyeCatcher);
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE
+ * @reasoncode EXPUPD::INVALID_EYE_CATCHER
+ * @userdata1 Expected Value
+ * @userdata2 Actual Value
+ * @devdesc Invalid eye catcher value for OCMB Flash Image
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE,
+ EXPUPD::INVALID_EYE_CATCHER,
+ EYE_CATCHER_VALUE,
+ l_header->eyeCatcher,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ // Check header version
+ if((l_header->majorVersion != HEADER_VERSION_MAJOR) ||
+ (l_header->minorVersion != HEADER_VERSION_MINOR))
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "ocmbFwValidateImage: Unsupported header version: %u.%u",
+ l_header->majorVersion, l_header->minorVersion);
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE
+ * @reasoncode EXPUPD::INVALID_HEADER_VERSION
+ * @userdata1 majorVersion
+ * @userdata2 minorVersion
+ * @devdesc Invalid header version for OCMB Flash Image
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE,
+ EXPUPD::INVALID_HEADER_VERSION,
+ l_header->majorVersion,
+ l_header->minorVersion,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ //Check that header size is within min/max range and 8byte aligned
+ if((l_header->headerSize < l_minHeaderSize) ||
+ (l_header->headerSize > l_maxHeaderSize) ||
+ !EXPUPD_8BYTE_ALIGNED(l_header->headerSize))
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "ocmbFwValidateImage: Unsupported header size: %u bytes",
+ l_header->headerSize);
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE
+ * @reasoncode EXPUPD::INVALID_HEADER_SIZE
+ * @userdata1 header size
+ * @userdata2 maximum allowed size
+ * @devdesc Invalid header size for OCMB Flash Image
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE,
+ EXPUPD::INVALID_HEADER_SIZE,
+ l_header->headerSize,
+ l_maxHeaderSize,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ // Trace header information.
+ TRACFCOMP(g_trac_expupd, "OCMB HEADER: Version[%u.%u] size[%u]"
+ " triplets[%u]",
+ l_header->majorVersion,
+ l_header->minorVersion,
+ l_header->headerSize,
+ l_header->numTriplets);
+
+ // Parse all tagged triplet data
+ const uint8_t* l_curTripletPtr = l_imageStartPtr + sizeof(*l_header);
+ const uint8_t* l_endDataPtr = l_imageStartPtr + l_header->headerSize;
+ for(uint32_t l_curTriplet = 0;
+ l_curTriplet < l_header->numTriplets;
+ l_curTriplet++)
+ {
+ uint32_t l_numBytes = 0;
+
+ // This will set o_imageInfo.imageSHA512Ptr if
+ // SHA512 hash is found
+ l_err = parseTaggedDataTriplet(l_curTripletPtr,
+ l_endDataPtr,
+ o_imageInfo,
+ l_numBytes);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "ocmbFwValidateImage: Failed parsing tagged data"
+ " triplet %u of %u",
+ l_curTriplet + 1, l_header->numTriplets);
+ break;
+ }
+
+ // Advance to next triplet
+ l_curTripletPtr += l_numBytes;
+ }
+ if(l_err)
+ {
+ break;
+ }
+
+ // Check if we found a SHA512 hash in the header
+ if(!o_imageInfo.imageSHA512HashPtr)
+ {
+ TRACFCOMP(g_trac_expupd, ERR_MRK
+ "ocmbFwValidateImage: No SHA512 Hash found in header!");
+ /* @errorlog
+ * @errortype ERRL_SEV_PREDICTIVE
+ * @moduleid EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE
+ * @reasoncode EXPUPD::MISSING_SHA512_HASH
+ * @userdata1 <unused>
+ * @userdata2 <unused>
+ * @devdesc Missing SHA512 hash in OCMB Flash Image
+ * @custdesc Error occurred during system boot.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ EXPUPD::MOD_OCMB_FW_VALIDATE_IMAGE,
+ EXPUPD::MISSING_SHA512_HASH,
+ 0, 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+ //** Header is valid if we made it this far **
+
+ // Trace the SHA512 hash
+ TRACFBIN(g_trac_expupd, "OCMB FW IMAGE SHA512 HASH",
+ o_imageInfo.imageSHA512HashPtr, HEADER_SHA512_SIZE);
+
+ // Set the image start address and size and we are done here.
+ o_imageInfo.imagePtr = l_imageStartPtr + l_header->headerSize;
+ o_imageInfo.imageSize = i_imageSize - l_header->headerSize;
+
+ }while(0);
+
+ TRACFCOMP(g_trac_expupd, EXIT_MRK "ocmbFwValidateImage()");
+ return l_err;
+}
+
+} //namespace expupd
+
diff --git a/src/usr/isteps/expupd/ocmbFwImage.H b/src/usr/isteps/expupd/ocmbFwImage.H
new file mode 100644
index 000000000..5e5de2e64
--- /dev/null
+++ b/src/usr/isteps/expupd/ocmbFwImage.H
@@ -0,0 +1,68 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/isteps/expupd/ocmbFwImage.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __OCMBFWIMAGE_H
+#define __OCMBFWIMAGE_H
+
+/**
+ * @file ocmbFwImage.H
+ *
+ * Interface for validating the OCMB firmware image from PNOR
+ *
+ */
+
+#include <errl/errlentry.H>
+
+namespace expupd
+{
+
+constexpr uint32_t HEADER_SHA512_SIZE = 64;
+
+/**
+ * @brief Parameters pertaining to an unpackaged (raw) OCMB firmware image
+ */
+typedef struct rawImageInfo
+{
+ const uint8_t* imagePtr;
+ size_t imageSize;
+ const uint8_t* imageSHA512HashPtr;
+}rawImageInfo_t;
+
+/**
+ * @brief Validates OCMB firmware header of packaged image
+ *
+ * @param[in] i_imageStart Start address of packaged image
+ * @param[in] i_imageSize Size of packaged image
+ * @param[out] o_imageInfo Information pertaining to image after
+ * being stripped of OCMB firmware header
+ * @return errlHndl_t indicating success or failure
+ *
+ */
+errlHndl_t ocmbFwValidateImage(const uint64_t i_imageStart,
+ const uint64_t i_imageSize,
+ rawImageInfo_t& o_imageInfo);
+
+}//namespace expupd
+
+#endif
diff --git a/src/usr/isteps/expupd/test/expupdatetest.H b/src/usr/isteps/expupd/test/expupdatetest.H
new file mode 100644
index 000000000..1fed4813e
--- /dev/null
+++ b/src/usr/isteps/expupd/test/expupdatetest.H
@@ -0,0 +1,175 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/isteps/expupd/test/expupdatetest.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __EXPUPDATETEST_H
+#define __EXPUPDATETEST_H
+
+/**
+ * @file expupdatetest.H
+ *
+ * @brief Test cases for explorer chip firmware update
+ */
+
+#include <cxxtest/TestSuite.H>
+#include <errl/errlmanager.H>
+#include <errl/errlentry.H>
+#include <fapi2.H>
+#include <plat_hwp_invoker.H>
+#include <lib/inband/exp_inband.H>
+#include <exp_data_structs.H>
+#include <exp_fw_update.H>
+#include <generic/memory/lib/utils/endian_utils.H>
+#ifndef __HOSTBOOT_RUNTIME
+#include <vfs/vfs.H> // module_is_loaded & module_load
+#endif
+#include <test/exptest_utils.H>
+
+const char MSS_LIBRARY_NAME[] = "libisteps_mss.so";
+const char EXPUPD_LIBRARY_NAME[] = "libexpupd.so";
+
+/**
+ * @brief Generic function to load a module
+ * @param i_modName - module name to load
+ * @return error handle if module_load call fails
+ */
+errlHndl_t loadModule(const char * i_modName)
+{
+ errlHndl_t err = nullptr;
+
+// VFS functions only compilable in non-runtime environment
+#ifndef __HOSTBOOT_RUNTIME
+ if(!VFS::module_is_loaded(i_modName))
+ {
+ err = VFS::module_load(i_modName);
+ if(err)
+ {
+ TS_FAIL("loadModule() - %s load failed", i_modName );
+ }
+ else
+ {
+ TS_TRACE("loadModule: %s loaded", i_modName);
+ }
+ }
+#endif
+ return err;
+}
+
+
+class ExpUpdateTest: public CxxTest::TestSuite
+{
+ public:
+
+ /**
+ * @brief Test the explorer firmware update procedure
+ */
+ void testExpFwUpdate( void )
+ {
+ errlHndl_t l_errl = nullptr;
+
+ uint8_t l_dataBuffer[4096] = {0};
+
+ // Create a vector of TARGETING::Target pointers
+ TARGETING::TargetHandleList l_chipList;
+
+ // Get a list of all of the functioning ocmb chips
+ TARGETING::getAllChips(l_chipList, TARGETING::TYPE_OCMB_CHIP, true);
+
+ TARGETING::HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR l_mutex = exptest::getTestMutex();
+ if (l_mutex == nullptr)
+ {
+ TS_FAIL("testExpFwUpdate: unable to get test mutex");
+ }
+ else
+ {
+ for (const auto & l_ocmb: l_chipList)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>l_fapi2_target(l_ocmb);
+
+ // Inband operations can't be run at the same time
+ // atomic section >>
+ mutex_lock(l_mutex);
+
+ // Invoke procedure
+ FAPI_INVOKE_HWP(l_errl, exp_fw_update, l_fapi2_target,
+ l_dataBuffer, sizeof(l_dataBuffer));
+
+ // << atomic section
+ mutex_unlock(l_mutex);
+ if (l_errl)
+ {
+#if 0 // skipping exp_fw_update error until simics is changed - @fixme:RTC-209865
+ TS_FAIL("Error from exp_fw_update for 0x%.8X target",
+ TARGETING::get_huid(l_ocmb));
+#endif
+ break;
+ }
+ }
+
+ if (l_errl)
+ {
+ errlCommit(l_errl, CXXTEST_COMP_ID);
+ }
+ }
+
+ TS_INFO("testExpFwUpdate: exiting");
+ };
+
+ /**
+ * @brief Constructor
+ */
+ ExpUpdateTest() : CxxTest::TestSuite()
+ {
+ // All modules are loaded by runtime,
+ // so testcase loading of modules is not required
+#ifndef __HOSTBOOT_RUNTIME
+ errlHndl_t err = nullptr;
+
+ err = loadModule(MSS_LIBRARY_NAME);
+ if(err)
+ {
+ TS_FAIL("ExpUpdateTest() - Constuctor: failed to load MSS module");
+ errlCommit( err, CXXTEST_COMP_ID );
+ }
+ err = loadModule(EXPUPD_LIBRARY_NAME);
+ if(err)
+ {
+ TS_FAIL("ExpUpdateTest() - Constuctor: failed to load EXPUPD module");
+ errlCommit( err, CXXTEST_COMP_ID );
+ }
+#endif
+ };
+
+
+ /**
+ * @brief Destructor
+ */
+ ~ExpUpdateTest()
+ {
+ };
+
+ private:
+};
+
+#endif
diff --git a/src/import/chips/ocmb/gemini/procedures/hwp/memory/lib/mss_gemini.mk b/src/usr/isteps/expupd/test/makefile
index acafbc603..d028105f9 100644
--- a/src/import/chips/ocmb/gemini/procedures/hwp/memory/lib/mss_gemini.mk
+++ b/src/usr/isteps/expupd/test/makefile
@@ -1,7 +1,7 @@
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
-# $Source: src/import/chips/ocmb/gemini/procedures/hwp/memory/lib/mss_gemini.mk $
+# $Source: src/usr/isteps/expupd/test/makefile $
#
# OpenPOWER HostBoot Project
#
@@ -22,3 +22,12 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+
+ROOTPATH = ../../../../..
+MODULE = testexpupd
+
+include test.mk
+
+TESTS = expupdatetest.H
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/isteps/expupd/test/test.mk b/src/usr/isteps/expupd/test/test.mk
new file mode 100644
index 000000000..aca30b7f4
--- /dev/null
+++ b/src/usr/isteps/expupd/test/test.mk
@@ -0,0 +1,35 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/isteps/expupd/test/test.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2
+EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include
+EXTRAINCDIR += ${ROOTPATH}/src/import
+EXTRAINCDIR += ${ROOTPATH}/src/usr/expaccess
+
diff --git a/src/usr/isteps/istep06/call_host_update_master_tpm.C b/src/usr/isteps/istep06/call_host_update_master_tpm.C
index 284d43450..fa374f279 100644
--- a/src/usr/isteps/istep06/call_host_update_master_tpm.C
+++ b/src/usr/isteps/istep06/call_host_update_master_tpm.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -31,6 +31,8 @@
#include <trustedbootif.H>
#include <initservice/isteps_trace.H>
#include <secureboot/service.H>
+#include <secureboot/phys_presence_if.H>
+#include <config.h>
namespace ISTEP_06
{
@@ -39,7 +41,7 @@ void* call_host_update_master_tpm( void *io_pArgs )
{
ISTEP_ERROR::IStepError l_stepError;
- TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call_host_update_master_tpm entry" );
errlHndl_t l_err = nullptr;
@@ -67,10 +69,28 @@ void* call_host_update_master_tpm( void *io_pArgs )
ERRORLOG::errlCommit( l_err, SECURE_COMP_ID );
}
- TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "call_host_update_master_tpm exit" );
+ // Check for Physical Presence
+#ifdef CONFIG_PHYS_PRES_PWR_BUTTON
+ l_err = SECUREBOOT::detectPhysPresence();
+ if (l_err)
+ {
+ // @TODO RTC 210301 - Handle Error Log Correctly, but for now
+ // just delete it
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "call_host_update_master_tpm: Error back from "
+ "SECUREBOOT::detectPhysPresence: rc=0x%X, plid=0x%X. "
+ "Deleting error for now",
+ ERRL_GETRC_SAFE(l_err), ERRL_GETPLID_SAFE(l_err));
+ delete l_err;
+ l_err = nullptr;
+ }
+#endif
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "call_host_update_master_tpm exit" );
return l_stepError.getErrorHandle();
+
+
}
};
diff --git a/src/usr/isteps/istep06/call_host_voltage_config.C b/src/usr/isteps/istep06/call_host_voltage_config.C
index 6cb647e9b..5e7b0eb94 100644
--- a/src/usr/isteps/istep06/call_host_voltage_config.C
+++ b/src/usr/isteps/istep06/call_host_voltage_config.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -489,7 +489,7 @@ void* call_host_voltage_config( void *io_pArgs )
l_err->addHwCallout(l_proc,
HWAS::SRCI_PRIORITY_HIGH,
- HWAS::DECONFIG,
+ HWAS::DELAYED_DECONFIG,
HWAS::GARD_NULL );
// Create IStep error log and
@@ -538,7 +538,7 @@ void* call_host_voltage_config( void *io_pArgs )
l_err->addHwCallout(l_proc,
HWAS::SRCI_PRIORITY_HIGH,
- HWAS::DECONFIG,
+ HWAS::DELAYED_DECONFIG,
HWAS::GARD_NULL );
// Create IStep error log and
diff --git a/src/usr/isteps/istep06/host_discover_targets.C b/src/usr/isteps/istep06/host_discover_targets.C
index 89e0dd8dd..7884056c1 100644
--- a/src/usr/isteps/istep06/host_discover_targets.C
+++ b/src/usr/isteps/istep06/host_discover_targets.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -59,6 +59,7 @@
//SBE interfacing
#include <sbeio/sbeioif.H>
#include <sys/misc.h>
+#include <sbe/sbeif.H>
#include <p9_query_core_access_state.H>
#include <p9_setup_sbe_config.H>
@@ -618,13 +619,71 @@ void* host_discover_targets( void *io_pArgs )
errlCommit (l_err, ISTEP_COMP_ID);
}
} // end if (l_pMasterProcChip)
- TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "host_discover_targets exit" );
#ifdef CONFIG_PRINT_SYSTEM_INFO
print_system_info();
#endif
+ // Handle the case where we don't have a valid memory map swap victim due
+ // to a module swap - See TARGETING::adjustMemoryMap()
+ if( l_pTopLevel->getAttr<TARGETING::ATTR_FORCE_SBE_UPDATE>()
+ == TARGETING::FORCE_SBE_UPDATE_BAR_MISMATCH )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "Forcing SBE update to handle swapped memory map" );
+ l_err = SBE::updateProcessorSbeSeeproms();
+ if(l_err)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "host_discover_targets: Error calling updateProcessorSbeSeeproms");
+ l_stepError.addErrorDetails( l_err );
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+
+ // We should never get here, if we do that means the SBE update didn't
+ // actually happen. That is a problem since we're currently running
+ // with mismatched BAR data
+ TARGETING::ATTR_XSCOM_BASE_ADDRESS_type l_xscom =
+ l_pMasterProcChip->getAttr<TARGETING::ATTR_XSCOM_BASE_ADDRESS>();
+ TARGETING::ATTR_PROC_EFF_FABRIC_GROUP_ID_type l_group =
+ l_pMasterProcChip->getAttr<TARGETING::ATTR_PROC_EFF_FABRIC_GROUP_ID>();
+ TARGETING::ATTR_PROC_EFF_FABRIC_CHIP_ID_type l_chip =
+ l_pMasterProcChip->getAttr<TARGETING::ATTR_PROC_EFF_FABRIC_CHIP_ID>();
+ /*@
+ * @errortype
+ * @moduleid ISTEP::MOD_DISCOVER_TARGETS
+ * @reasoncode ISTEP::RC_CANNOT_BOOT_WITH_MISMATCHED_BARS
+ * @userdata1 Current XSCOM BAR
+ * @userdata2[0-31] Desired ATTR_PROC_EFF_FABRIC_GROUP_ID
+ * @userdata2[32:63] Desired ATTR_PROC_EFF_FABRIC_GROUP_ID
+ * @devdesc Not able to update the SBE to correct the BAR mismatch
+ * @custdesc Required module update failed
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ ISTEP::MOD_DISCOVER_TARGETS,
+ ISTEP::RC_CANNOT_BOOT_WITH_MISMATCHED_BARS,
+ l_xscom,
+ TWO_UINT32_TO_UINT64(
+ l_group,
+ l_chip));
+
+ l_err->addHwCallout( l_pMasterProcChip,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL );
+
+ l_err->collectTrace(TARG_COMP_NAME);
+ l_err->collectTrace(SBE_COMP_NAME);
+ l_err->collectTrace("ISTEPS_TRACE",256);
+
+ // Create IStep error log and cross ref error that occurred
+ l_stepError.addErrorDetails( l_err );
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "host_discover_targets exit" );
+
return l_stepError.getErrorHandle();
}
diff --git a/src/usr/isteps/istep06/host_gard.C b/src/usr/isteps/istep06/host_gard.C
index 4a9852e17..1f16c866c 100644
--- a/src/usr/isteps/istep06/host_gard.C
+++ b/src/usr/isteps/istep06/host_gard.C
@@ -51,7 +51,6 @@
#include <console/consoleif.H>
// Custom compile configs
-#include <config.h>
#ifdef CONFIG_DRTM
#include <secureboot/drtm.H>
diff --git a/src/usr/isteps/istep06/host_init_fsi.C b/src/usr/isteps/istep06/host_init_fsi.C
index 2e294893e..455068633 100644
--- a/src/usr/isteps/istep06/host_init_fsi.C
+++ b/src/usr/isteps/istep06/host_init_fsi.C
@@ -37,7 +37,6 @@
#include <isteps/hwpisteperror.H>
#include <attributeenums.H>
#include <secureboot/trustedbootif.H>
-#include <config.h>
//Targeting
#include <targeting/common/commontargeting.H>
diff --git a/src/usr/isteps/istep07/call_mss_attr_update.C b/src/usr/isteps/istep07/call_mss_attr_update.C
index 4e015d7b8..a9e10d040 100644
--- a/src/usr/isteps/istep07/call_mss_attr_update.C
+++ b/src/usr/isteps/istep07/call_mss_attr_update.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -62,7 +62,6 @@
#include <fapi2/target.H>
#include <fapi2/plat_hwp_invoker.H>
-#include <config.h>
// HWP
#include <p9_mss_attr_update.H>
@@ -72,6 +71,9 @@
#include <isteps/mem_utils.H>
+#include <secureboot/smf_utils.H>
+#include <initservice/mboxRegs.H>
+
namespace ISTEP_07
{
@@ -307,6 +309,33 @@ errlHndl_t check_proc0_memory_config(IStepError & io_istepErr)
(l_procIds[i].proc)->getAttr<ATTR_FABRIC_CHIP_ID>());
}
+ TARGETING::Target* l_sys = nullptr;
+ TARGETING::targetService().getTopLevelTarget(l_sys);
+ assert(l_sys != nullptr, "Top level target is nullptr!");
+
+ TARGETING::ATTR_MASTER_MBOX_SCRATCH_type l_scratchRegs;
+ assert(
+ l_sys->tryGetAttr<TARGETING::ATTR_MASTER_MBOX_SCRATCH>(l_scratchRegs),
+ "failed to get MASTER_MBOX_SCRATCH");
+ INITSERVICE::SPLESS::MboxScratch6_t l_scratch6 {
+ l_scratchRegs[INITSERVICE::SPLESS::SCRATCH_6]};
+
+ // If the smfConfig bit in scratch reg6 does not match the SMF_ENABLED
+ // setting on the system, then the SBE is in disagreement with the system on
+ // whether SMF mode should be enabled. We need to force SBE update here so
+ // that the XSCOM BAR on the slave proc is set correctly before
+ // we try to perform XSCOM operations in istep10.
+ if(l_scratch6.smfConfig != SECUREBOOT::SMF::isSmfEnabled())
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "SBE and SYS disagree on the SMF setting; SBE thinks it "
+ "should be %s, but it should actually be %s;"
+ "requesting SBE update.",
+ l_scratch6.smfConfig ? "enabled" : "disabled",
+ SECUREBOOT::SMF::isSmfEnabled() ? "enabled" : "disabled");
+ l_updateNeeded = true;
+ }
+
if(l_updateNeeded)
{
do
diff --git a/src/usr/isteps/istep07/call_mss_eff_config.C b/src/usr/isteps/istep07/call_mss_eff_config.C
index 3f9b52371..e5ac21875 100644
--- a/src/usr/isteps/istep07/call_mss_eff_config.C
+++ b/src/usr/isteps/istep07/call_mss_eff_config.C
@@ -30,46 +30,59 @@
/******************************************************************************/
// Includes
/******************************************************************************/
+
+// STD
#include <stdint.h>
+#include <stdlib.h>
#include <map>
+// Generated
+#include <attributeenums.H>
+#include <config.h>
+
+// Errors and Tracing Support
#include <trace/interface.H>
#include <initservice/taskargs.H>
+#include <initservice/isteps_trace.H>
#include <errl/errlentry.H>
-
-#include <isteps/hwpisteperror.H>
#include <errl/errludtarget.H>
+#include <isteps/hwpisteperror.H>
+#include <hbotcompid.H>
-#include <initservice/isteps_trace.H>
-
+// Pnor Support
#include <pnor/pnorif.H>
-// targeting support
+// Targeting Support
#include <targeting/common/commontargeting.H>
#include <targeting/common/utilFilter.H>
-#include <config.h>
+// Fapi Support
#include <fapi2.H>
#include <fapi2/plat_hwp_invoker.H>
-// HWP
+// Nimbus Specific HWPs
#include <p9_mss_eff_config.H>
#include <p9_mss_eff_config_thermal.H>
#include <p9_mss_eff_grouping.H>
+
+// Cumulus Specific HWPs
#include <p9c_mss_eff_config.H>
#include <p9c_mss_eff_mb_interleave.H>
#include <p9c_mss_eff_config_thermal.H>
+// Axone Specific HWPs
#ifdef CONFIG_AXONE
#include <p9a_mss_eff_config.H>
-#include <p9a_mss_eff_config_thermal.H>
+#include <exp_mss_eff_config_thermal.H>
#endif
-#include <hbotcompid.H>
+// SMF Support
+#include <secureboot/smf.H>
+// NVDIMM Support
#include <nvram/nvram_interface.H>
-#include <secureboot/smf.H>
-#include <stdlib.h>
+
+
namespace ISTEP_07
{
@@ -167,13 +180,13 @@ void* call_mss_eff_config( void *io_pArgs )
{
IStepError l_StepError;
errlHndl_t l_err = nullptr;
-#ifdef CONFIG_SECUREBOOT
+#if (defined CONFIG_SECUREBOOT && ! defined CONFIG_AXONE)
auto memdLoaded = false;
#endif
do {
- #ifdef CONFIG_SECUREBOOT
+ #if (defined CONFIG_SECUREBOOT && ! defined CONFIG_AXONE)
// MEMD used by p9_mss_eff_config HWP
l_err = loadSecureSection(PNOR::MEMD);
if (l_err)
@@ -194,14 +207,11 @@ void* call_mss_eff_config( void *io_pArgs )
TARGETING::ATTR_MODEL_type l_procModel = TARGETING::targetService().getProcessorModel();
- TARGETING::Target* l_sys = nullptr;
- targetService().getTopLevelTarget(l_sys);
- assert( l_sys != nullptr );
-
TARGETING::TargetHandleList l_membufTargetList;
TARGETING::TargetHandleList l_mcsTargetList;
TARGETING::TargetHandleList l_memportTargetList;
- std::vector<fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>> l_fapi_memport_targets;
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>> l_fapi_ocmb_targets;
+
if(l_procModel == TARGETING::MODEL_CUMULUS)
{
@@ -310,11 +320,10 @@ void* call_mss_eff_config( void *io_pArgs )
const fapi2::Target <fapi2::TARGET_TYPE_MEM_PORT> l_fapi_memport_target
(l_memport_target);
- // TODO RTC: 207850 Remove workaround setting EFF_DIMM_SIZE when MSS has code that sets this
- uint32_t l_defaultMemSize[] = {0x8, 0x0};
- FAPI_ATTR_SET(fapi2::ATTR_MEM_EFF_DIMM_SIZE, l_fapi_memport_target, l_defaultMemSize);
+ const auto l_fapi2_ocmb_target =
+ l_fapi_memport_target.getParent<fapi2::TARGET_TYPE_OCMB_CHIP>();
- l_fapi_memport_targets.push_back(l_fapi_memport_target);
+ l_fapi_ocmb_targets.push_back(l_fapi2_ocmb_target);
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call p9a_mss_eff_config HWP on MEM_PORT HUID %.8X",
@@ -475,18 +484,18 @@ void* call_mss_eff_config( void *io_pArgs )
#ifdef CONFIG_AXONE
else if(l_procModel == TARGETING::MODEL_AXONE)
{
- if(l_fapi_memport_targets.size() > 0)
+ if(l_fapi_ocmb_targets.size() > 0)
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "call p9a_mss_eff_config_thermal HWP on %d MEM_PORT targets",
- l_fapi_memport_targets.size());
+ "call exp_mss_eff_config_thermal HWP on %d OCMB_CHIP targets",
+ l_fapi_ocmb_targets.size());
- FAPI_INVOKE_HWP(l_err, p9a_mss_eff_config_thermal, l_fapi_memport_targets);
+ FAPI_INVOKE_HWP(l_err, exp_mss_eff_config_thermal, l_fapi_ocmb_targets);
if (l_err)
{
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: p9a_mss_eff_config_thermal HWP",
+ "ERROR 0x%.8X: exp_mss_eff_config_thermal HWP",
l_err->reasonCode());
// Ensure istep error created and has same plid as this error
@@ -498,13 +507,13 @@ void* call_mss_eff_config( void *io_pArgs )
else
{
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : p9a_mss_eff_config_thermal HWP");
+ "SUCCESS : exp_mss_eff_config_thermal HWP");
}
}
else
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "No MEM_PORT targets found, skipping p9a_mss_eff_config_thermal HWP");
+ "No OCMB_CHIP targets found, skipping exp_mss_eff_config_thermal HWP");
}
}
#endif
@@ -564,7 +573,7 @@ void* call_mss_eff_config( void *io_pArgs )
} while (0);
- #ifdef CONFIG_SECUREBOOT
+ #if (defined CONFIG_SECUREBOOT && ! defined CONFIG_AXONE)
if(memdLoaded)
{
l_err = unloadSecureSection(PNOR::MEMD);
diff --git a/src/usr/isteps/istep07/call_mss_freq.C b/src/usr/isteps/istep07/call_mss_freq.C
index c6e6ac038..5495526ee 100644
--- a/src/usr/isteps/istep07/call_mss_freq.C
+++ b/src/usr/isteps/istep07/call_mss_freq.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -78,9 +78,9 @@ using namespace TARGETING;
void* call_mss_freq( void *io_pArgs )
{
IStepError l_StepError;
- errlHndl_t l_err = NULL;
+ errlHndl_t l_err = nullptr;
- #ifdef CONFIG_SECUREBOOT
+ #if (defined CONFIG_SECUREBOOT && ! defined CONFIG_AXONE)
bool l_isMemdLoaded = false;
#endif
@@ -88,7 +88,7 @@ void* call_mss_freq( void *io_pArgs )
do
{
- #ifdef CONFIG_SECUREBOOT
+ #if (defined CONFIG_SECUREBOOT && ! defined CONFIG_AXONE)
// Load MEMD so that vpd_supported_freqs can use it.
l_err = loadSecureSection(PNOR::MEMD);
if (l_err)
@@ -197,30 +197,30 @@ void* call_mss_freq( void *io_pArgs )
#ifdef CONFIG_AXONE
else if(l_procModel == TARGETING::MODEL_AXONE)
{
- TARGETING::TargetHandleList l_memportTargetList;
- getAllChiplets(l_memportTargetList, TYPE_MEM_PORT);
+ TARGETING::TargetHandleList l_procTargList;
+ getAllChips(l_procTargList, TYPE_PROC);
- for (const auto & l_memport_target : l_memportTargetList)
+ for (const auto & l_proc_target : l_procTargList)
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"p9a_mss_freq HWP target HUID %.8x",
- TARGETING::get_huid(l_memport_target));
+ TARGETING::get_huid(l_proc_target));
// call the HWP with each target ( if parallel, spin off a task )
- fapi2::Target <fapi2::TARGET_TYPE_MEM_PORT> l_fapi_memport_target
- (l_memport_target);
+ fapi2::Target <fapi2::TARGET_TYPE_PROC_CHIP> l_fapi_proc_target
+ (l_proc_target);
- FAPI_INVOKE_HWP(l_err, p9a_mss_freq, l_fapi_memport_target);
+ FAPI_INVOKE_HWP(l_err, p9a_mss_freq, l_fapi_proc_target);
// process return code.
if ( l_err )
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"ERROR 0x%.8X: p9a_mss_freq HWP on target HUID %.8x",
- l_err->reasonCode(), TARGETING::get_huid(l_memport_target) );
+ l_err->reasonCode(), TARGETING::get_huid(l_proc_target) );
// capture the target data in the elog
- ErrlUserDetailsTarget(l_memport_target).addToLog( l_err );
+ ErrlUserDetailsTarget(l_proc_target).addToLog( l_err );
// Create IStep error log and cross reference to error that occurred
l_StepError.addErrorDetails( l_err );
@@ -248,13 +248,25 @@ void* call_mss_freq( void *io_pArgs )
// allow it to change here
TARGETING::Target * l_sys = nullptr;
TARGETING::targetService().getTopLevelTarget( l_sys );
- // TODO RTC: 207596 Get nest boot freq for OMIs
- #ifndef CONFIG_AXONE_BRING_UP
- uint32_t l_originalNest = Util::getBootNestFreq();
- #endif
+
+ TARGETING::ATTR_FREQ_PB_MHZ_type l_originalNestFreq = Util::getBootNestFreq();
+
+ // Omi Freq is only used in P9a and beyond, to limit #ifdef
+ // craziness below just leave it at 0 so it never changes
+ TARGETING::ATTR_FREQ_OMI_MHZ_type l_originalOmiFreq = 0;
+#ifdef CONFIG_AXONE
+ TARGETING::ATTR_OMI_PLL_VCO_type l_originalOmiVco = 0; // unused but needed for func call
+ l_err = fapi2::platAttrSvc::getOmiFreqAndVco(l_originalOmiFreq, l_originalOmiVco);
+ if(l_err)
+ {
+ l_StepError.addErrorDetails( l_err );
+ errlCommit( l_err, ISTEP_COMP_ID );
+ break;
+ }
+#endif
// Read MC_SYNC_MODE from SBE itself and set the attribute
- uint8_t l_bootSyncMode = 0;
+ TARGETING::ATTR_MC_SYNC_MODE_type l_bootSyncMode = 0;
l_err = SBE::getBootMcSyncMode( l_bootSyncMode );
if( l_err )
{
@@ -318,23 +330,23 @@ void* call_mss_freq( void *io_pArgs )
#ifdef CONFIG_AXONE
else if(l_procModel == TARGETING::MODEL_AXONE)
{
- TARGETING::TargetHandleList l_mcTargetList;
- getAllChiplets(l_mcTargetList, TYPE_MC);
- for (const auto & l_mc_target : l_mcTargetList)
+ TARGETING::TargetHandleList l_procTargetList;
+ getAllChips(l_procTargetList, TYPE_PROC);
+ for (const auto & l_proc_target : l_procTargetList)
{
// call the HWP with each target ( if parallel, spin off a task )
- fapi2::Target <fapi2::TARGET_TYPE_MC> l_fapi_mc_target(l_mc_target);
+ fapi2::Target <fapi2::TARGET_TYPE_PROC_CHIP> l_fapi_proc_target(l_proc_target);
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "START : running p9a_mss_freq_system HWP on target 0x%.08X", TARGETING::get_huid(l_mc_target));;
+ "START : running p9a_mss_freq_system HWP on target 0x%.08X", TARGETING::get_huid(l_proc_target));;
- FAPI_INVOKE_HWP(l_err, p9a_mss_freq_system, l_fapi_mc_target);
+ FAPI_INVOKE_HWP(l_err, p9a_mss_freq_system, l_proc_target);
// process return code.
if ( l_err )
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR: p9a_mss_freq_system HWP while running on mc target 0x%.08X", TARGETING::get_huid(l_mc_target));;
+ "ERROR: p9a_mss_freq_system HWP while running on mc target 0x%.08X", TARGETING::get_huid(l_proc_target));;
- ERRORLOG::ErrlUserDetailsTarget(l_mc_target).addToLog(l_err);
+ ERRORLOG::ErrlUserDetailsTarget(l_proc_target).addToLog(l_err);
// Create IStep error log and cross reference to error that occurred
l_StepError.addErrorDetails( l_err );
@@ -345,7 +357,7 @@ void* call_mss_freq( void *io_pArgs )
else
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : p9a_mss_freq_system HWP on target 0x%.08X", TARGETING::get_huid(l_mc_target));;
+ "SUCCESS : p9a_mss_freq_system HWP on target 0x%.08X", TARGETING::get_huid(l_proc_target));;
}
}
}
@@ -357,34 +369,55 @@ void* call_mss_freq( void *io_pArgs )
break;
}
- // TODO RTC: 207596 Get nest boot freq for OMIs
- #ifndef CONFIG_AXONE_BRING_UP
// Get latest MC_SYNC_MODE and FREQ_PB_MHZ
- uint8_t l_mcSyncMode = l_masterProc->getAttr<TARGETING::ATTR_MC_SYNC_MODE>();
- uint32_t l_newNest = l_sys->getAttr<TARGETING::ATTR_FREQ_PB_MHZ>();
+ TARGETING::ATTR_MC_SYNC_MODE_type l_mcSyncMode = l_masterProc->getAttr<TARGETING::ATTR_MC_SYNC_MODE>();
+ TARGETING::ATTR_FREQ_OMI_MHZ_type l_newOmiFreq = 0;
+ TARGETING::ATTR_FREQ_PB_MHZ_type l_newNestFreq = l_sys->getAttr<TARGETING::ATTR_FREQ_PB_MHZ>();
+#ifdef CONFIG_AXONE
+ TARGETING::ATTR_OMI_PLL_VCO_type l_newOmiVco = 0; // unused but needed for func call
+ l_err = fapi2::platAttrSvc::getOmiFreqAndVco(l_newOmiFreq, l_newOmiVco);
+ if(l_err)
+ {
+ l_StepError.addErrorDetails( l_err );
+ errlCommit( l_err, ISTEP_COMP_ID );
+ break;
+ }
+#endif
//Trigger sbe update if the nest frequency changed.
- if( (l_newNest != l_originalNest) || (l_mcSyncMode != l_bootSyncMode) )
+ if( (l_newNestFreq != l_originalNestFreq)
+ || (l_mcSyncMode != l_bootSyncMode)
+ || (l_newOmiFreq != l_originalOmiFreq)
+ )
{
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
"The nest frequency or sync mode changed!"
" Original Nest: %d New Nest: %d"
- " Original syncMode: %d New syncMode: %d",
- l_originalNest, l_newNest, l_bootSyncMode, l_mcSyncMode );
+ " Original syncMode: %d New syncMode: %d"
+ " Original Omi : %d New Omi : %d"
+ , l_originalNestFreq, l_newNestFreq, l_bootSyncMode, l_mcSyncMode
+ , l_originalOmiFreq, l_newOmiFreq
+ );
if(l_sys->getAttr<TARGETING::ATTR_IS_MPIPL_HB>() == true)
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"Error: SBE update detected in MPIPL");
+ // It is highly unlikely nest frequency will change
+ // in Axone systems but OMI freq might. Its is impossible
+ // for OMI freq to change in Nimbus/Cumulus systems. So
+ // we will display Nest freq in error for Nimbus/Cumulus and
+ // display OMI freq for Axone.
+
/*@
* @errortype
* @moduleid MOD_SBE_PERFORM_UPDATE_CHECK
* @reasoncode RC_SBE_UPDATE_IN_MPIPL
* @userdata1[0:31] original mc sync mode
* @userdata1[32:63] new mc sync mode
- * @userdata2[0:31] original nest frequency
- * @userdata2[32:63] new nest frequency
+ * @userdata2[0:31] original (nest p9 | omi p9a+) frequency
+ * @userdata2[32:63] new (nest p9 | omi p9a+) frequency
* @devdesc SBE cannot be reset during MPIPL
* @custdesc Illegal action during boot
*/
@@ -394,8 +427,16 @@ void* call_mss_freq( void *io_pArgs )
TWO_UINT32_TO_UINT64(
TO_UINT32(l_bootSyncMode),
TO_UINT32(l_mcSyncMode)),
+#ifndef CONFIG_AXONE
+ TWO_UINT32_TO_UINT64(
+ l_originalNestFreq,
+ l_newNestFreq));
+#else
TWO_UINT32_TO_UINT64(
- l_originalNest, l_newNest));
+ l_originalOmiFreq,
+ l_newOmiFreq));
+#endif
+ l_err->collectTrace("ISTEPS_TRACE");
l_StepError.addErrorDetails( l_err );
errlCommit( l_err, ISTEP_COMP_ID );
@@ -403,8 +444,9 @@ void* call_mss_freq( void *io_pArgs )
else
{
TARGETING::setFrequencyAttributes(l_sys,
- l_newNest);
+ l_newNestFreq);
l_err = SBE::updateProcessorSbeSeeproms();
+
if( l_err )
{
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
@@ -419,11 +461,10 @@ void* call_mss_freq( void *io_pArgs )
}
}
}
- #endif
} while(0);
- #ifdef CONFIG_SECUREBOOT
+ #if (defined CONFIG_SECUREBOOT && ! defined CONFIG_AXONE)
if(l_isMemdLoaded)
{
// Should not have any uncommitted errors at this point.
diff --git a/src/usr/isteps/istep07/host_mss_attr_cleanup.C b/src/usr/isteps/istep07/host_mss_attr_cleanup.C
index ed1cbc25a..4456018ae 100644
--- a/src/usr/isteps/istep07/host_mss_attr_cleanup.C
+++ b/src/usr/isteps/istep07/host_mss_attr_cleanup.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -56,7 +56,6 @@
#include <fapi2/target.H>
#include <fapi2/plat_hwp_invoker.H>
-#include <config.h>
// HWP
#include <p9c_mss_attr_cleanup.H>
@@ -75,7 +74,6 @@ using namespace TARGETING;
void* host_mss_attr_cleanup( void *io_pArgs )
{
IStepError l_StepError;
- errlHndl_t l_err = NULL;
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_mss_attr_cleanup entry");
// errlHndl_t l_err = NULL;
@@ -98,7 +96,9 @@ void* host_mss_attr_cleanup( void *io_pArgs )
l_pTopLevel->setAttr<TARGETING::ATTR_MRW_HW_MIRRORING_ENABLE>
(fapi2::ENUM_ATTR_MRW_HW_MIRRORING_ENABLE_FALSE);
}
-
+ // TODO RTC 198112 Memory Reconfig Loop for Axone
+ #ifndef CONFIG_AXONE
+ errlHndl_t l_err = nullptr;
TargetHandleList l_funcDimmList;
// Get all the functional Dimms
TARGETING::getAllLogicalCards(l_funcDimmList, TYPE_DIMM, true);
@@ -123,6 +123,7 @@ void* host_mss_attr_cleanup( void *io_pArgs )
}
}
+ #endif
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_mss_attr_cleanup exit" );
diff --git a/src/usr/isteps/istep07/makefile b/src/usr/isteps/istep07/makefile
index c9dfba28a..3befa6684 100644
--- a/src/usr/isteps/istep07/makefile
+++ b/src/usr/isteps/istep07/makefile
@@ -31,6 +31,7 @@ HWP_PATH_P9 += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/memory
HWP_PATH_CEN += ${ROOTPATH}/src/import/chips/centaur/procedures/hwp/memory
# Axone
HWP_PATH_P9A += ${ROOTPATH}/src/import/chips/p9a/procedures/hwp/memory
+HWP_PATH_P9A += ${ROOTPATH}/src/import/chips/ocmb/common/procedures/hwp/pmic
# Explorer
HWP_PATH_EXP += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory
@@ -71,14 +72,19 @@ EXTRAINCDIR += ${HWP_PATH_CEN}/lib/
EXTRAINCDIR += ${HWP_PATH_CEN}/lib/shared/
EXTRAINCDIR += ${HWP_PATH_CEN}/lib/utils/
EXTRAINCDIR += ${HWP_PATH_EXP}/lib/eff_config/
-EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/chips/ocmb/explorer/procedures/hwp/memory/
+EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/chips/ocmb/explorer/procedures/hwp/memory/lib/
EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/generic/memory/lib/
EXTRAINCDIR += ${EXP_COMMON_PATH}/include/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/common/procedures/hwp/pmic/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/common/include
+EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/chips/ocmb/common/procedures/hwp/pmic/
+EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/chips/ocmb/common/procedures/hwp/pmic/lib
VPATH += ${HWP_PATH} ${HWP_PATH_P9}/lib/spd
VPATH += $(PROCEDURES_PATH)/hwp/nest ${ROOTPATH}/src/usr/fapi2
VPATH += ${PROCEDURES_PATH}/hwp/perv
VPATH += ${HWP_PATH_P9}/lib ${HWP_PATH_P9}/lib/utils ${HWP_PATH_P9}/lib/eff_config
+VPATH += ${HWP_PATH_P9A}/lib/eff_config
VPATH += ${HWP_PATH_P9}/lib/freq ${HWP_PATH_P9}/lib/dimm
VPATH += ${ROOTPATH}/src/usr/sbe
@@ -108,12 +114,13 @@ include $(HWP_PATH_CEN)/p9c_mss_bulk_pwr_throttles.mk
include $(HWP_PATH_CEN)/p9c_mss_eff_mb_interleave.mk
-# Axone only objects
+# Axone only objects
OBJS += $(if $(CONFIG_AXONE),p9a_mss_volt.o,)
OBJS += $(if $(CONFIG_AXONE),p9a_mss_freq.o,)
OBJS += $(if $(CONFIG_AXONE),p9a_mss_freq_system.o,)
OBJS += $(if $(CONFIG_AXONE),p9a_mss_eff_config.o,)
-OBJS += $(if $(CONFIG_AXONE),p9a_mss_eff_config_thermal.o,)
+OBJS += $(if $(CONFIG_AXONE),exp_mss_eff_config_thermal.o,)
+OBJS += $(if $(CONFIG_AXONE),pmic_efd_processing.o,)
#host_mss_attr_cleanup : MSS ATTR Cleanup
include $(HWP_PATH_CEN)/p9c_mss_attr_cleanup.mk
diff --git a/src/usr/isteps/istep08/call_host_set_voltages.C b/src/usr/isteps/istep08/call_host_set_voltages.C
index 11c37a50d..fe37ef21b 100644
--- a/src/usr/isteps/istep08/call_host_set_voltages.C
+++ b/src/usr/isteps/istep08/call_host_set_voltages.C
@@ -46,7 +46,10 @@
#include <p9_setup_evid.H>
#include <nest/nestHwpHelperFuncs.H> // fapiHWPCallWrapperForChip
#include <hbToHwsvVoltageMsg.H> // platform_set_nest_voltages
-
+#ifdef CONFIG_AXONE
+#include <chipids.H> // for EXPLORER ID
+#include <pmic_enable.H>
+#endif
// Init Service support
#include <initservice/initserviceif.H> // INITSERVICE::spBaseServicesEnabled
@@ -69,9 +72,6 @@ void* call_host_set_voltages(void *io_pArgs)
do
{
- // Skip p9_setup_evid on Axone, no targets exist
- #ifndef CONFIG_AXONE_BRING_UP
-
TargetHandleList l_procList;
// Get the system's procs
getAllChips( l_procList,
@@ -115,7 +115,6 @@ void* call_host_set_voltages(void *io_pArgs)
{
break;
}
- #endif
// If no error occurred and FSP is present,
// send voltage information to HWSV
@@ -156,8 +155,43 @@ void* call_host_set_voltages(void *io_pArgs)
fapiHWPCallWrapperHandler(P9_IO_XBUS_IMAGE_BUILD, l_stepError,
HWPF_COMP_ID, TYPE_PROC);
}
- }while( 0 );
+#ifdef CONFIG_AXONE
+ // Create a vector of TARGETING::Target pointers
+ TargetHandleList l_chipList;
+
+ // Get a list of all of the functioning ocmb chips
+ TARGETING::getAllChips(l_chipList, TARGETING::TYPE_OCMB_CHIP, true);
+
+ for (const auto & l_ocmb: l_chipList)
+ {
+ // PMICs are not present on Gemini, so skip this enable call
+ // check EXPLORER first as this is most likely the configuration
+ uint32_t chipId = l_ocmb->getAttr< TARGETING::ATTR_CHIP_ID>();
+ if (chipId == POWER_CHIPID::EXPLORER_16)
+ {
+ TRACFCOMP( g_trac_isteps_trace, "call_host_set_voltages: "
+ "calling pmic_enable on OCMB 0x%.8X", get_huid(l_ocmb) );
+
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>l_fapi2_target(l_ocmb);
+
+ // Invoke procedure
+ FAPI_INVOKE_HWP(l_err, pmic_enable, l_fapi2_target);
+ }
+
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_isteps_trace,
+ "Error from pmic_enable for 0x%.8X target",
+ TARGETING::get_huid(l_ocmb));
+
+ // Capture error and continue to next OCMB
+ captureError(l_err, l_stepError, HWPF_COMP_ID, l_ocmb);
+ }
+ }
+#endif
+
+ }while( 0 );
TRACFCOMP(g_trac_isteps_trace, EXIT_MRK"call_host_set_voltages exit");
diff --git a/src/usr/isteps/istep08/call_proc_attr_update.C b/src/usr/isteps/istep08/call_proc_attr_update.C
index 0b73652b5..d287c09ef 100644
--- a/src/usr/isteps/istep08/call_proc_attr_update.C
+++ b/src/usr/isteps/istep08/call_proc_attr_update.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -57,7 +57,6 @@
#include <devicefw/userif.H>
#include <vpd/mvpdenums.H>
-#include <config.h>
#include <p9_attr_update.H>
diff --git a/src/usr/isteps/istep08/call_proc_xbus_scominit.C b/src/usr/isteps/istep08/call_proc_xbus_scominit.C
index b446f7b06..970f1b608 100644
--- a/src/usr/isteps/istep08/call_proc_xbus_scominit.C
+++ b/src/usr/isteps/istep08/call_proc_xbus_scominit.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -59,7 +59,6 @@
#include <devicefw/userif.H>
#include <vpd/mvpdenums.H>
-#include <config.h>
#include <p9_io_xbus_scominit.H>
namespace ISTEP_08
diff --git a/src/usr/isteps/istep08/makefile b/src/usr/isteps/istep08/makefile
index 225e07735..5b1da4f21 100644
--- a/src/usr/isteps/istep08/makefile
+++ b/src/usr/isteps/istep08/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2015,2018
+# Contributors Listed Below - COPYRIGHT 2015,2019
# [+] International Business Machines Corp.
#
#
@@ -24,6 +24,10 @@
# IBM_PROLOG_END_TAG
ROOTPATH = ../../../..
PROCEDURES_PATH = ${ROOTPATH}/src/import/chips/p9/procedures
+
+# OCMB path
+COMMON_PATH_OCMB += ${ROOTPATH}/src/import/chips/ocmb/common
+
MODULE = istep08
EXTRAINCDIR += ${PROCEDURES_PATH}/hwp/pm/
@@ -38,10 +42,18 @@ EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/include/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/imageProcs/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs/
EXTRAINCDIR += ${ROOTPATH}/src/usr/isteps/
EXTRAINCDIR += ${ROOTPATH}/src/usr/sbeio/
EXTRAINCDIR += ${PROCEDURES_PATH}/hwp/pm/include/registers
+EXTRAINCDIR += ${COMMON_PATH_OCMB}/procedures/hwp/pmic/
+EXTRAINCDIR += ${COMMON_PATH_OCMB}/procedures/hwp/pmic/lib/utils/
+EXTRAINCDIR += ${COMMON_PATH_OCMB}/include/
+EXTRAINCDIR += ${ROOTPATH}/src/import/
+EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/chips/ocmb/common/procedures/hwp/pmic/lib/
+EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/generic/memory/lib/
+
OBJS += call_host_slave_sbe_config.o
OBJS += call_host_setup_sbe.o
@@ -61,6 +73,10 @@ VPATH += ${PROCEDURES_PATH}/hwp/io/ ${PROCEDURES_PATH}/hwp/initfiles/
VPATH += ${PROCEDURES_PATH}/hwp/sbe/
VPATH += ${PROCEDURES_PATH}/hwp/pm/
VPATH += ${PROCEDURES_PATH}/hwp/lib
+VPATH += ${COMMON_PATH_OCMB}/pmic/
+VPATH += ${COMMON_PATH_OCMB}/procedures/hwp/pmic/
+VPATH += ${COMMON_PATH_OCMB}/procedures/hwp/pmic/lib/utils/
+VPATH += ${COMMON_PATH_OCMB}/include/
include ${ROOTPATH}/procedure.rules.mk
@@ -110,4 +126,9 @@ MODULE = istep08
# Take another look at PM lib
include $(PROCEDURES_PATH)/hwp/pm/p9_pm_utils.mk
+# Axone only objects
+OBJS += $(if $(CONFIG_AXONE),pmic_common_utils.o,)
+OBJS += $(if $(CONFIG_AXONE),pmic_enable_utils.o,)
+OBJS += $(if $(CONFIG_AXONE),pmic_enable.o,)
+
include ${ROOTPATH}/config.mk
diff --git a/src/usr/isteps/istep10/call_host_rng_bist.C b/src/usr/isteps/istep10/call_host_rng_bist.C
index 68d243547..70b82a274 100644
--- a/src/usr/isteps/istep10/call_host_rng_bist.C
+++ b/src/usr/isteps/istep10/call_host_rng_bist.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -55,7 +55,6 @@
#include <devicefw/userif.H>
#include <vpd/mvpdenums.H>
-#include <config.h>
#include <fapi2/plat_hwp_invoker.H>
#include <p9_rng_init_phase1.H>
@@ -121,7 +120,7 @@ void* call_host_rng_bist( void *io_pArgs )
{
l_err->addHwCallout( l_nxTarget,
HWAS::SRCI_PRIORITY_HIGH,
- HWAS::DECONFIG,
+ HWAS::DELAYED_DECONFIG,
HWAS::GARD_NULL );
}
}
diff --git a/src/usr/isteps/istep10/call_host_slave_sbe_update.C b/src/usr/isteps/istep10/call_host_slave_sbe_update.C
index 6e230fc38..d008e8cbd 100644
--- a/src/usr/isteps/istep10/call_host_slave_sbe_update.C
+++ b/src/usr/isteps/istep10/call_host_slave_sbe_update.C
@@ -249,6 +249,7 @@ void* call_host_slave_sbe_update (void *io_pArgs)
{
errlHndl_t l_errl = NULL;
IStepError l_StepError;
+ bool l_testAltMaster = true;
TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call_host_slave_sbe_update entry" );
@@ -275,7 +276,6 @@ void* call_host_slave_sbe_update (void *io_pArgs)
errlCommit( l_errl, HWPF_COMP_ID );
}
- #ifndef CONFIG_AXONE_BRING_UP
// Call to check state of Processor SBE SEEPROMs and
// make any necessary updates
l_errl = SBE::updateProcessorSbeSeeproms(
@@ -290,8 +290,6 @@ void* call_host_slave_sbe_update (void *io_pArgs)
break;
}
- #endif
-
// Run LPC Init on Alt Master Procs
// Get list of all processors
TARGETING::TargetHandleList l_procList;
@@ -325,6 +323,7 @@ void* call_host_slave_sbe_update (void *io_pArgs)
l_errl->removeDeconfigure();
// Commit error
errlCommit( l_errl, HWPF_COMP_ID );
+ l_testAltMaster = false;
}
else
{
@@ -337,14 +336,17 @@ void* call_host_slave_sbe_update (void *io_pArgs)
// Call to Validate any Alternative Master's connection to PNOR
// Any error returned should not fail istep
- l_errl = PNOR::validateAltMaster();
- if (l_errl)
+ if (l_testAltMaster == true)
{
- //Remove any deconfigure information, we only need the PNOR Part callout and do not want
- // to deconfigure the entire proc because of a PNOR part problem
- l_errl->removeDeconfigure();
- // Commit error
- errlCommit( l_errl, HWPF_COMP_ID );
+ l_errl = PNOR::validateAltMaster();
+ if (l_errl)
+ {
+ //Remove any deconfigure information, we only need the PNOR Part callout and do not want
+ // to deconfigure the entire proc because of a PNOR part problem
+ l_errl->removeDeconfigure();
+ // Commit error
+ errlCommit( l_errl, HWPF_COMP_ID );
+ }
}
// Set SEEPROM_VERSIONS_MATCH attributes for each processor
diff --git a/src/usr/isteps/istep10/call_host_update_redundant_tpm.C b/src/usr/isteps/istep10/call_host_update_redundant_tpm.C
index 878b1b1e3..4f872f995 100644
--- a/src/usr/isteps/istep10/call_host_update_redundant_tpm.C
+++ b/src/usr/isteps/istep10/call_host_update_redundant_tpm.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -35,11 +35,11 @@
#include <errl/errludtarget.H>
#include <attributetraits.H>
-#include <config.h>
#include <util/align.H>
#include <util/algorithm.H>
#include <istepHelperFuncs.H>
#include <secureboot/trustedbootif.H>
+#include <secureboot/phys_presence_if.H>
namespace ISTEP_10
{
@@ -50,6 +50,7 @@ void* call_host_update_redundant_tpm (void *io_pArgs)
ENTER_MRK"call_host_update_redundant_tpm");
ISTEP_ERROR::IStepError l_istepError;
+
#ifdef CONFIG_TPMDD
TARGETING::Target* l_backupTpm = nullptr;
@@ -67,6 +68,26 @@ void* call_host_update_redundant_tpm (void *io_pArgs)
} while(0);
#endif
+#ifdef CONFIG_PHYS_PRES_PWR_BUTTON
+ // Check to see if a Physical Presence Window should be opened,
+ // and if so, open it. This could result in the system being shutdown
+ // to allow the system administrator to assert physical presence
+ errlHndl_t l_err = nullptr;
+ l_err = SECUREBOOT::handlePhysPresenceWindow();
+ if (l_err)
+ {
+ // @TODO RTC 210301 - Handle Error Log Correctly, but for now
+ // just delete it
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "call_host_update_redundant_tpm: Error back from "
+ "SECUREBOOT::handlePhysPresence: rc=0x%X, plid=0x%X. "
+ "Deleting error for now",
+ ERRL_GETRC_SAFE(l_err), ERRL_GETPLID_SAFE(l_err));
+ delete l_err;
+ l_err = nullptr;
+ }
+#endif
+
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
EXIT_MRK"call_host_update_redundant_tpm");
diff --git a/src/usr/isteps/istep10/call_proc_abus_scominit.C b/src/usr/isteps/istep10/call_proc_abus_scominit.C
index 745fabae3..cefb9f6d0 100644
--- a/src/usr/isteps/istep10/call_proc_abus_scominit.C
+++ b/src/usr/isteps/istep10/call_proc_abus_scominit.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -58,7 +58,6 @@
#include <devicefw/userif.H>
#include <vpd/mvpdenums.H>
-#include <config.h>
namespace ISTEP_10
diff --git a/src/usr/isteps/istep10/call_proc_build_smp.C b/src/usr/isteps/istep10/call_proc_build_smp.C
index b3ce48516..599e6f98e 100644
--- a/src/usr/isteps/istep10/call_proc_build_smp.C
+++ b/src/usr/isteps/istep10/call_proc_build_smp.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
diff --git a/src/usr/isteps/istep10/call_proc_cen_ref_clk_enable.C b/src/usr/isteps/istep10/call_proc_cen_ref_clk_enable.C
index 67a11b775..81478303a 100644
--- a/src/usr/isteps/istep10/call_proc_cen_ref_clk_enable.C
+++ b/src/usr/isteps/istep10/call_proc_cen_ref_clk_enable.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -80,7 +80,6 @@
#include <errl/errludtarget.H>
#include <attributetraits.H>
-#include <config.h>
#include <util/align.H>
#include <util/algorithm.H>
@@ -1064,9 +1063,25 @@ void* call_proc_cen_ref_clk_enable(void *io_pArgs )
"for 0x%.08X", TARGETING::get_huid(l_ocmb));
fapi2::Target <fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target(l_ocmb);
- FAPI_INVOKE_HWP(l_errl,
- exp_check_for_ready,
- l_fapi_ocmb_target);
+
+ // TODO CQ:SW482291 Remove this retry workaround when ocmb check_for_ready timeout issue is resolved
+ for(uint8_t i = 0; i < 10; i++)
+ {
+ FAPI_INVOKE_HWP(l_errl,
+ exp_check_for_ready,
+ l_fapi_ocmb_target);
+
+ // Preserve the error log if this is the last loop.
+ if(l_errl == NULL || i == 9)
+ {
+ break;
+ }
+ else
+ {
+ delete l_errl;
+ l_errl = NULL;
+ }
+ }
if (l_errl)
{
@@ -1086,8 +1101,41 @@ void* call_proc_cen_ref_clk_enable(void *io_pArgs )
else
{
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : exp_check_for_ready"
+ "SUCCESS : exp_check_for_ready "
"completed ok");
+
+ size_t size = 0;
+
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "Read IDEC from OCMB 0x%.8X",
+ TARGETING::get_huid(l_ocmb));
+
+ // This write gets translated into a read of the explorer chip
+ // in the device driver. First, a read of the chip's IDEC
+ // register occurs then ATTR_EC, ATTR_HDAT_EC, and ATTR_CHIP_ID
+ // are set with the values found in that register. So, this
+ // deviceWrite functions more as a setter for an OCMB target's
+ // attributes.
+ // Pass 2 as a va_arg to signal the ocmbIDEC function to execute
+ // phase 2 of it's read process.
+ const uint64_t Phase2 = 2;
+ l_errl = DeviceFW::deviceWrite(l_ocmb,
+ nullptr,
+ size,
+ DEVICE_IDEC_ADDRESS(),
+ Phase2);
+ if (l_errl)
+ {
+ // read of ID/EC failed even though we THOUGHT we were
+ // present.
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "OCMB 0x%.8X - read IDEC failed (eid 0x%X) - bad",
+ TARGETING::get_huid(l_ocmb), l_errl->eid());
+
+ // commit the error but keep going
+ errlCommit(l_errl, HWAS_COMP_ID);
+ // l_errl is now nullptr
+ }
}
}
#endif
diff --git a/src/usr/isteps/istep10/call_proc_chiplet_scominit.C b/src/usr/isteps/istep10/call_proc_chiplet_scominit.C
index 8e2950163..c0b9f2619 100644
--- a/src/usr/isteps/istep10/call_proc_chiplet_scominit.C
+++ b/src/usr/isteps/istep10/call_proc_chiplet_scominit.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -74,6 +74,8 @@ void* call_proc_chiplet_scominit( void *io_pArgs )
TRACFCOMP(g_trac_isteps_trace, ENTER_MRK"call_proc_chiplet_scominit entry" );
+ do{
+
if (!INITSERVICE::isSMPWrapConfig())
{
// Make the FAPI call to p9_chiplet_scominit
@@ -108,6 +110,8 @@ void* call_proc_chiplet_scominit( void *io_pArgs )
}
}
+ }while(0);
+
TRACFCOMP(g_trac_isteps_trace, EXIT_MRK"call_proc_chiplet_scominit exit" );
return l_stepError.getErrorHandle();
diff --git a/src/usr/isteps/istep10/call_proc_enable_osclite.C b/src/usr/isteps/istep10/call_proc_enable_osclite.C
index dd3c6147e..ccfa653b6 100644
--- a/src/usr/isteps/istep10/call_proc_enable_osclite.C
+++ b/src/usr/isteps/istep10/call_proc_enable_osclite.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -55,7 +55,6 @@
#include <devicefw/userif.H>
#include <vpd/mvpdenums.H>
-#include <config.h>
// -- prototype includes --
// Add any customized routines that you don't want overwritten into
diff --git a/src/usr/isteps/istep10/call_proc_npu_scominit.C b/src/usr/isteps/istep10/call_proc_npu_scominit.C
index c29be9535..7fd76d010 100644
--- a/src/usr/isteps/istep10/call_proc_npu_scominit.C
+++ b/src/usr/isteps/istep10/call_proc_npu_scominit.C
@@ -67,7 +67,6 @@ void* call_proc_npu_scominit( void *io_pArgs )
{
IStepError l_stepError;
- #ifndef CONFIG_AXONE_BRING_UP
TRACFCOMP(g_trac_isteps_trace, ENTER_MRK"call_proc_npu_scominit entry");
if (!INITSERVICE::isSMPWrapConfig())
{
@@ -76,9 +75,6 @@ void* call_proc_npu_scominit( void *io_pArgs )
HWPF_COMP_ID, TYPE_PROC);
}
TRACFCOMP(g_trac_isteps_trace, EXIT_MRK"call_proc_npu_scominit exit");
- #else
- TRACFCOMP(g_trac_isteps_trace, "Skipping call_proc_npu_scominit in Axone during bringup");
- #endif
return l_stepError.getErrorHandle();
}
diff --git a/src/usr/isteps/istep10/call_proc_pcie_scominit.C b/src/usr/isteps/istep10/call_proc_pcie_scominit.C
index 664a966e9..82bd05f55 100644
--- a/src/usr/isteps/istep10/call_proc_pcie_scominit.C
+++ b/src/usr/isteps/istep10/call_proc_pcie_scominit.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -58,7 +58,6 @@
#include <devicefw/userif.H>
#include <vpd/mvpdenums.H>
-#include <config.h>
#include "host_proc_pcie_scominit.H"
#include <p9_pcie_scominit.H>
diff --git a/src/usr/isteps/istep10/call_proc_scomoverride_chiplets.C b/src/usr/isteps/istep10/call_proc_scomoverride_chiplets.C
index 0d4c6d58f..9476672e8 100644
--- a/src/usr/isteps/istep10/call_proc_scomoverride_chiplets.C
+++ b/src/usr/isteps/istep10/call_proc_scomoverride_chiplets.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -58,7 +58,6 @@
#include <devicefw/userif.H>
#include <vpd/mvpdenums.H>
-#include <config.h>
#include <p9_scomoverride_chiplets.H>
diff --git a/src/usr/isteps/istep10/host_proc_pcie_scominit.C b/src/usr/isteps/istep10/host_proc_pcie_scominit.C
index 8895ed405..69a41ab36 100644
--- a/src/usr/isteps/istep10/host_proc_pcie_scominit.C
+++ b/src/usr/isteps/istep10/host_proc_pcie_scominit.C
@@ -44,7 +44,6 @@
#include <fapi2/target.H>
#include <fapi2/plat_hwp_invoker.H>
#include <devicefw/userif.H>
-#include <config.h>
#include "host_proc_pcie_scominit.H"
#include <hwas/common/hwas.H>
#include <hwas/common/deconfigGard.H>
diff --git a/src/usr/isteps/istep10/makefile b/src/usr/isteps/istep10/makefile
index ac6233867..2590c4f63 100644
--- a/src/usr/isteps/istep10/makefile
+++ b/src/usr/isteps/istep10/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2015,2019
+# Contributors Listed Below - COPYRIGHT 2015,2020
# [+] International Business Machines Corp.
#
#
@@ -51,6 +51,7 @@ EXTRAINCDIR += ${INITFILES_HWP_PATH}
EXTRAINCDIR += ${PERV_HWP_PATH}
EXTRAINCDIR += ${OCMB_HWP_PATH}
EXTRAINCDIR += ${ROOTPATH}/src/import/
+EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/chips/ocmb/explorer/procedures/hwp/memory/lib/
OBJS += call_proc_build_smp.o
diff --git a/src/usr/isteps/istep11/call_host_prd_hwreconfig.C b/src/usr/isteps/istep11/call_host_prd_hwreconfig.C
index e3a0a434a..2b32b625e 100644
--- a/src/usr/isteps/istep11/call_host_prd_hwreconfig.C
+++ b/src/usr/isteps/istep11/call_host_prd_hwreconfig.C
@@ -26,7 +26,6 @@
#include <errl/errlmanager.H>
#include <isteps/hwpisteperror.H>
#include <pnor/pnorif.H>
-#include <config.h>
#include <initservice/isteps_trace.H>
using namespace ERRORLOG;
@@ -40,7 +39,7 @@ void* call_host_prd_hwreconfig (void *io_pArgs)
ISTEP_ERROR::IStepError l_StepError;
//@TODO-RTC:158411 call p9_enable_reconfig.C
-#ifdef CONFIG_SECUREBOOT
+#if (defined CONFIG_SECUREBOOT && ! defined CONFIG_AXONE)
errlHndl_t l_err = NULL;
// Load the MEMD section here as the first part of step11, it
// will stay loaded until the end of step14
diff --git a/src/usr/isteps/istep12/call_cen_dmi_scominit.C b/src/usr/isteps/istep12/call_cen_dmi_scominit.C
index 8e7a9feef..868f1da2a 100644
--- a/src/usr/isteps/istep12/call_cen_dmi_scominit.C
+++ b/src/usr/isteps/istep12/call_cen_dmi_scominit.C
@@ -46,10 +46,6 @@
// HWP
#include <p9_io_cen_scominit.H>
-#ifdef CONFIG_AXONE
-#include <p9a_omi_setup_bars.H>
-#endif
-
using namespace ISTEP;
using namespace ISTEP_ERROR;
using namespace ERRORLOG;
@@ -107,50 +103,6 @@ void* call_cen_dmi_scominit (void *io_pArgs)
}
- #ifdef CONFIG_AXONE
- TARGETING::TargetHandleList l_procTargetList;
- getAllChips(l_procTargetList, TYPE_PROC);
-
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_dmi_scominit: %d procs found",
- l_procTargetList.size());
-
- for (const auto & l_proc_target : l_procTargetList)
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "p9a_omi_setup_bars HWP target HUID %.8x",
- TARGETING::get_huid(l_proc_target));
-
- // call the HWP with each target
- fapi2::Target <fapi2::TARGET_TYPE_PROC_CHIP> l_fapi_proc_target
- (l_proc_target);
-
- FAPI_INVOKE_HWP(l_err, p9a_omi_setup_bars, l_fapi_proc_target);
-
- // process return code.
- if ( l_err )
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: p9a_omi_setup_bars HWP on target HUID %.8x",
- l_err->reasonCode(), TARGETING::get_huid(l_proc_target) );
-
- // capture the target data in the elog
- ErrlUserDetailsTarget(l_proc_target).addToLog( l_err );
-
- // Create IStep error log and cross reference to error that occurred
- l_StepError.addErrorDetails( l_err );
-
- // Commit Error
- errlCommit( l_err, ISTEP_COMP_ID );
- }
- else
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : p9a_omi_setup_bars HWP");
- }
-
- }
- #endif // CONFIG_AXONE
-
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_dmi_scominit exit" );
// end task, returning any errorlogs to IStepDisp
diff --git a/src/usr/isteps/istep12/call_cen_set_inband_addr.C b/src/usr/isteps/istep12/call_cen_set_inband_addr.C
index 196f7bed7..1b1161298 100644
--- a/src/usr/isteps/istep12/call_cen_set_inband_addr.C
+++ b/src/usr/isteps/istep12/call_cen_set_inband_addr.C
@@ -44,12 +44,15 @@
#include <util/utilmbox_scratch.H>
#include <util/misc.H>
-//HWP
-#include <p9c_set_inband_addr.H>
-
#ifdef CONFIG_AXONE
+// Axone HWPs
#include <exp_omi_init.H>
#include <p9a_omi_init.H>
+#include <p9a_disable_ocmb_i2c.H>
+#include <expupd/expupd.H>
+#else
+// Cumulus HWP
+#include <p9c_set_inband_addr.H>
#endif
//Inband SCOM
@@ -60,169 +63,313 @@ using namespace ISTEP_ERROR;
using namespace ERRORLOG;
using namespace TARGETING;
-
namespace ISTEP_12
{
+void cumulus_call_cen_set_inband_addr(IStepError & io_istepError);
+void axone_call_cen_set_inband_addr(IStepError & io_istepError);
+void enableInbandScomsOCMB( TARGETING::TargetHandleList i_ocmbTargetList );
+void disableI2cAccessToOcmbs(IStepError & io_istepError);
+
void* call_cen_set_inband_addr (void *io_pArgs)
{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_set_inband_addr entry" );
IStepError l_StepError;
- errlHndl_t l_err = NULL;
auto l_procModel = TARGETING::targetService().getProcessorModel();
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_set_inband_addr entry" );
+ switch (l_procModel)
+ {
+ case TARGETING::MODEL_CUMULUS:
+ cumulus_call_cen_set_inband_addr(l_StepError);
+ // @todo RTC 187913 inband centaur scom in P9
+ // Re-enable when support available in simics
+ if ( Util::isSimicsRunning() == false )
+ {
+ //Now enable Inband SCOM for all memory mapped chips.
+ IBSCOM::enableInbandScoms();
+ }
+ break;
+ case TARGETING::MODEL_AXONE:
+ axone_call_cen_set_inband_addr(l_StepError);
+
+ // No need to disable i2c access if and error was encountered setting up the inband addr
+ if(l_StepError.isNull())
+ {
+ disableI2cAccessToOcmbs(l_StepError);
+ }
+ break;
+ case TARGETING::MODEL_NIMBUS:
+ break; // do nothing step
+ default:
+ assert(0, "call_cen_set_inband_addr: Unsupported model type 0x%04X",
+ l_procModel);
+ break;
+ }
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_set_inband_addr exit" );
+
+ // end task, returning any errorlogs to IStepDisp
+ return l_StepError.getErrorHandle();
+}
+
+#ifndef CONFIG_AXONE
+void cumulus_call_cen_set_inband_addr(IStepError & io_istepError)
+{
+ errlHndl_t l_err = nullptr;
+ TARGETING::TargetHandleList l_procTargetList;
+ getAllChips(l_procTargetList, TYPE_PROC);
+
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_set_inband_addr: %d proc chips found",
+ l_procTargetList.size());
- if(l_procModel == TARGETING::MODEL_CUMULUS)
+ for (const auto & l_proc_target : l_procTargetList)
{
- TARGETING::TargetHandleList l_procTargetList;
- getAllChips(l_procTargetList, TYPE_PROC);
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "p9c_set_inband_addr HWP target HUID %.8x",
+ TARGETING::get_huid(l_proc_target));
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_set_inband_addr: %d proc chips found",
- l_procTargetList.size());
+ // call the HWP with each target
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_fapi_proc_target
+ (l_proc_target);
- for (const auto & l_proc_target : l_procTargetList)
- {
+ FAPI_INVOKE_HWP(l_err, p9c_set_inband_addr, l_fapi_proc_target);
+ // process return code.
+ if ( l_err )
+ {
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "p9c_set_inband_addr HWP target HUID %.8x",
- TARGETING::get_huid(l_proc_target));
+ "ERROR 0x%.8X: p9c_set_inband_addr HWP on target HUID %.8x",
+ l_err->reasonCode(), TARGETING::get_huid(l_proc_target) );
- // call the HWP with each target
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_fapi_proc_target
- (l_proc_target);
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_proc_target).addToLog( l_err );
- FAPI_INVOKE_HWP(l_err, p9c_set_inband_addr, l_fapi_proc_target);
+ // Create IStep error log and cross reference to error that occurred
+ io_istepError.addErrorDetails( l_err );
- // process return code.
- if ( l_err )
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: p9c_set_inband_addr HWP on target HUID %.8x",
- l_err->reasonCode(), TARGETING::get_huid(l_proc_target) );
+ // Commit Error
+ errlCommit( l_err, ISTEP_COMP_ID );
- // capture the target data in the elog
- ErrlUserDetailsTarget(l_proc_target).addToLog( l_err );
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : p9c_set_inband_addr HWP");
+ }
+ } // proc target loop
+}
- // Create IStep error log and cross reference to error that occurred
- l_StepError.addErrorDetails( l_err );
+void axone_call_cen_set_inband_addr(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'exp_omi_init/p9a_omi_init' but Axone code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
- // Commit Error
- errlCommit( l_err, ISTEP_COMP_ID );
+void enableInbandScomsOCMB( TARGETING::TargetHandleList l_ocmbTargetList )
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'enableInbandScomsOCMB' but Axone code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
+
+void disableI2cAccessToOcmbs(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'disableI2cAccessToOcmbs' but Axone code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
- }
- else
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : p9c_set_inband_addr HWP");
- }
- }
- }
+#else
- // @todo RTC 187913 inband centaur scom in P9
- // Re-enable when support available in simics
- if ( Util::isSimicsRunning() == false )
- {
- //Now enable Inband SCOM for all membuf chips.
- IBSCOM::enableInbandScoms();
- }
+void cumulus_call_cen_set_inband_addr(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'p9c_set_inband_addr' but Cumulus code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
-#ifdef CONFIG_AXONE
- if(l_procModel == TARGETING::MODEL_AXONE)
+void axone_call_cen_set_inband_addr(IStepError & io_istepError)
+{
+ errlHndl_t l_err = nullptr;
+ TARGETING::TargetHandleList l_ocmbTargetList;
+ getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "axone_call_cen_set_inband_addr: %d ocmb chips found",
+ l_ocmbTargetList.size());
+
+ for (const auto & l_ocmb_target : l_ocmbTargetList)
{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "exp_omi_init HWP target HUID %.8x",
+ TARGETING::get_huid(l_ocmb_target) );
- TARGETING::TargetHandleList l_ocmbTargetList;
- getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
+ // call the HWP with each target
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target
+ (l_ocmb_target);
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_set_inband_addr: %d ocmb chips found",
- l_ocmbTargetList.size());
+ FAPI_INVOKE_HWP(l_err, exp_omi_init , l_fapi_ocmb_target);
- for (const auto & l_ocmb_target : l_ocmbTargetList)
+ // process return code.
+ if ( l_err )
{
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "exp_omi_init HWP target HUID %.8x",
- TARGETING::get_huid(l_ocmb_target));
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, ERR_MRK
+ "ERROR 0x%.8X: exp_omi_init HWP on target HUID 0x%.8x",
+ l_err->reasonCode(), TARGETING::get_huid(l_ocmb_target) );
- // call the HWP with each target
- fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target
- (l_ocmb_target);
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_ocmb_target).addToLog( l_err );
- FAPI_INVOKE_HWP(l_err, exp_omi_init , l_fapi_ocmb_target);
+ // Create IStep error log and cross reference to error that occurred
+ io_istepError.addErrorDetails( l_err );
- // process return code.
- if ( l_err )
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: exp_omi_init HWP on target HUID 0x%.8x",
- l_err->reasonCode(), TARGETING::get_huid(l_ocmb_target) );
+ // Commit Error
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : exp_omi_init HWP on target HUID 0x%.8x",
+ TARGETING::get_huid(l_ocmb_target) );
+ }
+ } // ocmb loop
- // capture the target data in the elog
- ErrlUserDetailsTarget(l_ocmb_target).addToLog( l_err );
+ TargetHandleList l_mccTargetList;
+ getAllChiplets(l_mccTargetList, TYPE_MCC);
- // Create IStep error log and cross reference to error that occurred
- l_StepError.addErrorDetails( l_err );
+ for (const auto & l_mcc_target : l_mccTargetList)
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "p9a_omi_init HWP target HUID %.8x",
+ TARGETING::get_huid(l_mcc_target) );
- // Commit Error
- errlCommit( l_err, ISTEP_COMP_ID );
+ // call the HWP with each target
+ fapi2::Target<fapi2::TARGET_TYPE_MCC> l_fapi_mcc_target
+ (l_mcc_target);
- }
- else
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : exp_omi_init HWP on target HUID 0x%.8x",
- TARGETING::get_huid(l_ocmb_target));
- }
+ FAPI_INVOKE_HWP(l_err, p9a_omi_init, l_fapi_mcc_target);
- }
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, ERR_MRK
+ "ERROR 0x%.8X: p9a_omi_init HWP on target HUID %.8x",
+ l_err->reasonCode(), TARGETING::get_huid(l_mcc_target) );
- TARGETING::TargetHandleList l_mccTargetList;
- getAllChiplets(l_mccTargetList, TYPE_MCC);
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_mcc_target).addToLog( l_err );
- for (const auto & l_mcc_target : l_mccTargetList)
+ // Create IStep error log and cross reference to error that occurred
+ io_istepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+ else
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "p9a_omi_init HWP target HUID %.8x",
+ "SUCCESS : p9a_omi_init HWP on target HUID 0x%.8x ,"
+ "setting scom settings to use inband for all ocmb children",
TARGETING::get_huid(l_mcc_target));
- // call the HWP with each target
- fapi2::Target<fapi2::TARGET_TYPE_MCC> l_fapi_mcc_target
- (l_mcc_target);
+ TargetHandleList l_ocmbTargetList;
+ getChildAffinityTargets(l_ocmbTargetList , l_mcc_target,
+ CLASS_CHIP, TARGETING::TYPE_OCMB_CHIP);
+ enableInbandScomsOCMB(l_ocmbTargetList);
+ }
+ } // MCC loop
+
+ // Check if any explorer chips require a firmware update and update them
+ // (skipped on MPIPL)
+ // We should be checking for updates and perform the updates even if OMI
+ // initialization failed. It's possible that the OMI failure was due to
+ // the OCMB having an old image. The update code will automatically
+ // switch to using i2c if OMI is not enabled.
+ Target* l_pTopLevel = nullptr;
+ targetService().getTopLevelTarget( l_pTopLevel );
+ assert(l_pTopLevel, "axone_call_cen_set_inband_addr: no TopLevelTarget");
+ if (l_pTopLevel->getAttr<TARGETING::ATTR_IS_MPIPL_HB>())
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "skipping expupdUpdateAll due to MPIPL");
+ }
+ else
+ {
+ expupd::updateAll(io_istepError);
+ }
+}
- FAPI_INVOKE_HWP(l_err, p9a_omi_init, l_fapi_mcc_target);
+/**
+ * @brief Loop over all processors and disable i2c path to ocmb
+ * After this point no i2c commands will be possible until we
+ * power the chip off and on.
+ * @param io_istepError - Istep error that tracks error logs for this step
+ */
+void disableI2cAccessToOcmbs(IStepError & io_istepError)
+{
+ errlHndl_t l_err = nullptr;
+ TARGETING::TargetHandleList l_procTargetList;
+ getAllChips(l_procTargetList, TARGETING::TYPE_PROC);
+ // We only want to disable i2c if we are in secure mode
+ const bool FORCE_DISABLE = false;
- // process return code.
- if ( l_err )
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: p9a_omi_init HWP on target HUID %.8x",
- l_err->reasonCode(), TARGETING::get_huid(l_mcc_target) );
+ for ( const auto & l_proc : l_procTargetList )
+ {
+ // call the HWP with each proc
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_fapi_proc_target
+ (l_proc);
- // capture the target data in the elog
- ErrlUserDetailsTarget(l_mcc_target).addToLog( l_err );
+ FAPI_INVOKE_HWP(l_err, p9a_disable_ocmb_i2c, l_fapi_proc_target, FORCE_DISABLE);
- // Create IStep error log and cross reference to error that occurred
- l_StepError.addErrorDetails( l_err );
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, ERR_MRK
+ "ERROR 0x%.8X: p9a_disable_ocmb_i2c HWP on target HUID %.8x",
+ l_err->reasonCode(), TARGETING::get_huid(l_proc) );
- // Commit Error
- errlCommit( l_err, ISTEP_COMP_ID );
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_proc).addToLog( l_err );
- }
- else
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : p9a_omi_init HWP on target HUID 0x%.8x",
- TARGETING::get_huid(l_mcc_target));
- }
+ // Create IStep error log and cross reference to error that occurred
+ io_istepError.addErrorDetails( l_err );
+ // Commit Error
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : p9a_disable_ocmb_i2c HWP on target HUID 0x%.8x",
+ TARGETING::get_huid(l_proc));
}
}
-#endif // CONFIG_AXONE
+}
+/**
+ * @brief Enable Inband Scom for the OCMB targets
+ * @param i_ocmbTargetList - OCMB targets
+ */
+void enableInbandScomsOCMB( TARGETING::TargetHandleList i_ocmbTargetList )
+{
+ mutex_t* l_mutex = NULL;
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_set_inband_addr exit" );
+ for ( const auto & l_ocmb : i_ocmbTargetList )
+ {
+ //don't mess with attributes without the mutex (just to be safe)
+ l_mutex = l_ocmb->getHbMutexAttr<TARGETING::ATTR_IBSCOM_MUTEX>();
+ mutex_lock(l_mutex);
- // end task, returning any errorlogs to IStepDisp
- return l_StepError.getErrorHandle();
+ ScomSwitches l_switches = l_ocmb->getAttr<ATTR_SCOM_SWITCHES>();
+ l_switches.useI2cScom = 0;
+ l_switches.useInbandScom = 1;
+ // Modify attribute
+ l_ocmb->setAttr<ATTR_SCOM_SWITCHES>(l_switches);
+ mutex_unlock(l_mutex);
+ }
}
+#endif // CONFIG_AXONE
+
};
diff --git a/src/usr/isteps/istep12/call_dmi_io_dccal.C b/src/usr/isteps/istep12/call_dmi_io_dccal.C
index ca2d11aef..339c8be9c 100644
--- a/src/usr/isteps/istep12/call_dmi_io_dccal.C
+++ b/src/usr/isteps/istep12/call_dmi_io_dccal.C
@@ -43,113 +43,257 @@
#include <fapi2/plat_hwp_invoker.H>
#include <util/utilmbox_scratch.H>
-// HWP
+// HWP (only bring in model-specific HWP headers to save space)
+#ifdef CONFIG_AXONE
+#include <p9a_io_omi_dccal.H>
+#include <p9a_io_omi_scominit.H>
+#else
#include <p9_io_dmi_dccal.H>
#include <p9_io_cen_dccal.H>
+#endif
using namespace ISTEP;
using namespace ISTEP_ERROR;
using namespace ERRORLOG;
using namespace TARGETING;
+#define POS_0_VECTOR 0x000000FF
+#define BITS_PER_BYTE 8
namespace ISTEP_12
{
+
+// Declare local functions
+void cumulus_dccal_setup(IStepError & io_istepError);
+void axone_dccal_setup(IStepError & io_istepError);
+
void* call_dmi_io_dccal (void *io_pArgs)
{
IStepError l_StepError;
- errlHndl_t l_err = NULL;
TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_dmi_io_dccal entry" );
do
{
+ auto l_procModel = TARGETING::targetService().getProcessorModel();
- TARGETING::TargetHandleList l_procTargetList;
- getAllChips(l_procTargetList, TYPE_PROC);
+ switch (l_procModel)
+ {
+ case TARGETING::MODEL_CUMULUS:
+ cumulus_dccal_setup(l_StepError);
+ break;
+ case TARGETING::MODEL_AXONE:
+ axone_dccal_setup(l_StepError);
+ break;
+ case TARGETING::MODEL_NIMBUS:
+ default:
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "skipping p9_io_dmi_dccal because not required for current processor model 0x%x", l_procModel);
+ break;
+ }
- if(l_procTargetList[0]->getAttr<TARGETING::ATTR_MODEL>() != TARGETING::MODEL_CUMULUS)
+ }while(0);
+
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_dmi_io_dccal exit" );
+
+ // end task, returning any errorlogs to IStepDisp
+ return l_StepError.getErrorHandle();
+}
+
+#ifndef CONFIG_AXONE
+void cumulus_dccal_setup(IStepError & io_istepError)
+{
+ errlHndl_t l_err = nullptr;
+ TARGETING::TargetHandleList l_procTargetList;
+ getAllChips(l_procTargetList, TYPE_PROC);
+
+ for (const auto & l_proc_target : l_procTargetList)
+ {
+ // a. p9_io_dmi_dccal.C (DMI target)
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "p9_io_dmi_dccal HWP target HUID %.8x",
+ TARGETING::get_huid(l_proc_target));
+
+ // call the HWP with each target
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_fapi_proc_target
+ (l_proc_target);
+
+ FAPI_INVOKE_HWP(l_err, p9_io_dmi_dccal, l_fapi_proc_target);
+
+ // process return code.
+ if ( l_err )
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "p9_io_dmi_dccal Proccessor model is not CUMULUS , skipping this step");
- break;
- }
+ "ERROR 0x%.8X: p9_io_dmi_dccal HWP on target HUID %.8x",
+ l_err->reasonCode(), TARGETING::get_huid(l_proc_target) );
+
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_proc_target).addToLog( l_err );
- for (const auto & l_proc_target : l_procTargetList)
+ // Create IStep error log and cross reference to error that occurred
+ io_istepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+ else
{
- // a. p9_io_dmi_dccal.C (DMI target)
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : p9_io_dmi_dccal HWP on target HUID %.8x",
+ TARGETING::get_huid(l_proc_target) );
+ }
+
+ // b. p9_io_cen_dccal.C (Centaur target)
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "p9_io_cen_dccal HWP target HUID %.8x",
+ TARGETING::get_huid(l_proc_target));
+ FAPI_INVOKE_HWP(l_err, p9_io_cen_dccal, l_fapi_proc_target);
+
+ // process return code.
+ if ( l_err )
+ {
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "p9_io_dmi_dccal HWP target HUID %.8x",
- TARGETING::get_huid(l_proc_target));
+ "ERROR 0x%.8X: p9_io_cen_dccal HWP on target HUID %.8x",
+ l_err->reasonCode(), TARGETING::get_huid(l_proc_target) );
- // call the HWP with each target
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_fapi_proc_target
- (l_proc_target);
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_proc_target).addToLog( l_err );
- FAPI_INVOKE_HWP(l_err, p9_io_dmi_dccal, l_fapi_proc_target);
+ // Create IStep error log and cross reference to error that occurred
+ io_istepError.addErrorDetails( l_err );
- // process return code.
- if ( l_err )
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: p9_io_dmi_dccal HWP on target HUID %.8x",
- l_err->reasonCode(), TARGETING::get_huid(l_proc_target) );
+ // Commit Error
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : p9_io_cen_dccal HWP on target HUID %.8x",
+ TARGETING::get_huid(l_proc_target) );
+ }
- // capture the target data in the elog
- ErrlUserDetailsTarget(l_proc_target).addToLog( l_err );
+ }
+}
+#else
+void cumulus_dccal_setup(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'p9_io_dmi_dccal' and 'p9_io_cen_dccal' but Cumulus code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
+#endif
- // Create IStep error log and cross reference to error that occurred
- l_StepError.addErrorDetails( l_err );
+#ifdef CONFIG_AXONE
+void axone_dccal_setup(IStepError & io_istepError)
+{
+ errlHndl_t l_err = nullptr;
+ TargetHandleList l_omic_target_list;
+ getAllChiplets(l_omic_target_list, TYPE_OMIC);
- // Commit Error
- errlCommit( l_err, ISTEP_COMP_ID );
- }
- else
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : p9_io_dmi_dccal HWP");
- }
+ for (const auto & l_omic_target : l_omic_target_list)
+ {
+ // call the HWP with each target
+ fapi2::Target<fapi2::TARGET_TYPE_OMIC> l_fapi_omic_target
+ (l_omic_target);
- // b. p9_io_cen_dccal.C (Centaur target)
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "p9a_io_omi_scominit HWP target HUID %.8x",
+ get_huid(l_omic_target));
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "p9_io_cen_dccal HWP target HUID %.8x",
- TARGETING::get_huid(l_proc_target));
+ FAPI_INVOKE_HWP(l_err, p9a_io_omi_scominit, l_fapi_omic_target);
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: p9a_io_omi_scominit HWP on target HUID %.8x",
+ l_err->reasonCode(), TARGETING::get_huid(l_omic_target) );
- FAPI_INVOKE_HWP(l_err, p9_io_cen_dccal, l_fapi_proc_target);
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_omic_target).addToLog( l_err );
- // process return code.
- if ( l_err )
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: p9_io_cen_dccal HWP on target HUID %.8x",
- l_err->reasonCode(), TARGETING::get_huid(l_proc_target) );
+ // Create IStep error log and cross reference to error that occurred
+ io_istepError.addErrorDetails( l_err );
- // capture the target data in the elog
- ErrlUserDetailsTarget(l_proc_target).addToLog( l_err );
+ // Commit Error
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+ else
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : p9a_io_omi_scominit HWP on target HUID %.8x",
+ TARGETING::get_huid(l_omic_target) );
+ }
- // Create IStep error log and cross reference to error that occurred
- l_StepError.addErrorDetails( l_err );
+ TargetHandleList l_omi_target_list;
- // Commit Error
- errlCommit( l_err, ISTEP_COMP_ID );
- }
- else
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : p9_io_cen_dccal HWP");
- }
+ getChildOmiTargetsByState(l_omi_target_list,
+ l_omic_target,
+ CLASS_UNIT,
+ TYPE_OMI,
+ UTIL_FILTER_FUNCTIONAL);
+
+ uint32_t l_laneVector = 0x00000000;
+
+ for(const auto & l_omi_target : l_omi_target_list)
+ {
+ // The OMI dc calibration HWP requires us to pass in the OMIC target
+ // and then a bit mask representing which positon of OMI we are calibrating.
+ // To get the position of the OMI relative to its parent OMIC, look up
+ // ATTR_OMI_DL_GROUP_POS then shift the POS_0_VECTOR = 0x000000FF by 1 byte to the left
+ // for every position away from 0 OMI_DL_GROUP_POS is.
+ // Therefore
+ // POS_0_VECTOR = 0x000000FF
+ // POS_1_VECTOR = 0x0000FF00
+ // POS_2_VECTOR = 0x00FF0000
+
+ l_laneVector |=
+ POS_0_VECTOR << (l_omi_target->getAttr<ATTR_OMI_DL_GROUP_POS>() * BITS_PER_BYTE);
}
- }while(0);
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "p9a_io_omi_dccal HWP target HUID %.8x with lane vector 0x%x",
+ TARGETING::get_huid(l_omic_target), l_laneVector);
+ FAPI_INVOKE_HWP(l_err, p9a_io_omi_dccal, l_fapi_omic_target, l_laneVector);
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_dmi_io_dccal exit" );
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: p9a_io_omi_dccal HWP on target HUID %.8x with lane vector 0x%x",
+ l_err->reasonCode(), TARGETING::get_huid(l_omic_target), l_laneVector);
- // end task, returning any errorlogs to IStepDisp
- return l_StepError.getErrorHandle();
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_omic_target).addToLog( l_err );
+ l_err->collectTrace("ISTEPS_TRACE", 256);
+
+ // Create IStep error log and cross reference to error that occurred
+ io_istepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+ else
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : p9a_io_omi_dccal HWP on target HUID %.8x with lane vector 0x%x",
+ TARGETING::get_huid(l_omic_target), l_laneVector );
+ }
+
+ }
+}
+#else
+void axone_dccal_setup(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'p9a_io_omi_scominit' but Axone code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
}
+#endif
};
diff --git a/src/usr/isteps/istep12/call_dmi_io_run_training.C b/src/usr/isteps/istep12/call_dmi_io_run_training.C
index 064a63a94..17bef45da 100644
--- a/src/usr/isteps/istep12/call_dmi_io_run_training.C
+++ b/src/usr/isteps/istep12/call_dmi_io_run_training.C
@@ -26,12 +26,12 @@
#include <trace/interface.H>
#include <initservice/taskargs.H>
+#include <initservice/isteps_trace.H>
#include <errl/errlentry.H>
-
-#include <isteps/hwpisteperror.H>
#include <errl/errludtarget.H>
-
-#include <initservice/isteps_trace.H>
+#include <util/utilmbox_scratch.H>
+#include <util/misc.H>
+#include <isteps/hwpisteperror.H>
// targeting support.
#include <targeting/common/commontargeting.H>
@@ -41,14 +41,15 @@
#include <config.h>
#include <fapi2.H>
#include <fapi2/plat_hwp_invoker.H>
-#include <util/utilmbox_scratch.H>
//HWP
#include <p9_io_dmi_linktrain.H>
#ifdef CONFIG_AXONE
#include <exp_omi_setup.H>
+#include <p9a_omi_train.H>
#include <exp_omi_train.H>
+#include <chipids.H> // for EXPLORER ID
#endif
using namespace ISTEP;
@@ -109,69 +110,91 @@ void* call_dmi_io_run_training (void *io_pArgs)
}
#ifdef CONFIG_AXONE
- TARGETING::TargetHandleList l_ocmbTargetList;
- getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
- for (const auto & l_ocmb_target : l_ocmbTargetList)
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "exp_omi_setup HWP target HUID 0x%.08x",
- TARGETING::get_huid(l_ocmb_target));
-
- // call the HWP with each target
- fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target
- (l_ocmb_target);
-
- FAPI_INVOKE_HWP(l_err, exp_omi_setup, l_fapi_ocmb_target);
+ TARGETING::TargetHandleList l_ocmbTargetList;
+ getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
- // process return code.
- if ( l_err )
+ for (const auto & l_ocmb_target : l_ocmbTargetList)
{
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: exp_omi_setup HWP on target HUID 0x%.08x",
- l_err->reasonCode(), TARGETING::get_huid(l_ocmb_target) );
-
- // capture the target data in the elog
- ErrlUserDetailsTarget(l_ocmb_target).addToLog( l_err );
+ // Only run exp_omi_train on EXPLORER OCMB targets. This step
+ // cannot run on GEMINI targets.
+ uint32_t chipId = l_ocmb_target->getAttr< TARGETING::ATTR_CHIP_ID>();
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target( l_ocmb_target );
+ if (chipId == POWER_CHIPID::EXPLORER_16)
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Start omi training on target HUID 0x%.8X",
+ TARGETING::get_huid(l_ocmb_target) );
+ FAPI_INVOKE_HWP(l_err, exp_omi_train, l_fapi_ocmb_target);
+
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: exp_omi_train HWP on target HUID 0x%.08x",
+ l_err->reasonCode(), TARGETING::get_huid(l_ocmb_target) );
+
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_ocmb_target).addToLog( l_err );
+
+ // Create IStep error log and cross reference to error that occurred
+ l_StepError.addErrorDetails( l_err );
+
+ // Commit Error , continue on to next OCMB
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : exp_omi_train HWP on target 0x%.08X", TARGETING::get_huid(l_ocmb_target));
+ }
+ }
+ else
+ {
+ // Gemini, just skip exp_omi_train call
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Skipping exp_omi_train HWP on because target HUID 0x%.8X, chipId 0x%.4X is a Gemini OCMB",
+ TARGETING::get_huid(l_ocmb_target), chipId );
+ }
+ }
- // Create IStep error log and cross reference to error that occurred
- l_StepError.addErrorDetails( l_err );
+ TARGETING::TargetHandleList l_omiTargetList;
+ getAllChiplets(l_omiTargetList, TYPE_OMI);
- // Commit Error , continue on to next OCMB
- errlCommit( l_err, ISTEP_COMP_ID );
- }
- else
+ for (const auto & l_omi_target : l_omiTargetList)
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : exp_omi_setup HWP on target 0x%.08X, starting training", TARGETING::get_huid(l_ocmb_target));
+ "p9a_omi_train HWP target HUID %.8x",
+ TARGETING::get_huid(l_omi_target));
+
+ // call the HWP with each OMI target
+ fapi2::Target<fapi2::TARGET_TYPE_OMI> l_fapi_omi_target(l_omi_target);
- FAPI_INVOKE_HWP(l_err, exp_omi_train, l_fapi_ocmb_target);
+ FAPI_INVOKE_HWP(l_err, p9a_omi_train , l_fapi_omi_target );
// process return code.
if ( l_err )
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: exp_omi_train HWP on target HUID 0x%.08x",
- l_err->reasonCode(), TARGETING::get_huid(l_ocmb_target) );
+ "ERROR 0x%.8X: p9a_omi_train HWP on target HUID %.8x",
+ l_err->reasonCode(), TARGETING::get_huid(l_omi_target) );
// capture the target data in the elog
- ErrlUserDetailsTarget(l_ocmb_target).addToLog( l_err );
+ ErrlUserDetailsTarget(l_omi_target).addToLog( l_err );
// Create IStep error log and cross reference to error that occurred
l_StepError.addErrorDetails( l_err );
- // Commit Error , continue on to next OCMB
+ // Commit Error
errlCommit( l_err, ISTEP_COMP_ID );
}
else
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : exp_omi_train HWP on target 0x%.08X", TARGETING::get_huid(l_ocmb_target));
+ "SUCCESS : p9a_omi_train HWP on 0x%.08X", TARGETING::get_huid(l_omi_target));
}
}
- }
-
#endif
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_dmi_io_run_training exit" );
diff --git a/src/usr/isteps/istep12/call_dmi_post_trainadv.C b/src/usr/isteps/istep12/call_dmi_post_trainadv.C
index 8f5e34106..af8ca6d0f 100644
--- a/src/usr/isteps/istep12/call_dmi_post_trainadv.C
+++ b/src/usr/isteps/istep12/call_dmi_post_trainadv.C
@@ -26,12 +26,13 @@
#include <trace/interface.H>
#include <initservice/taskargs.H>
+#include <initservice/isteps_trace.H>
#include <errl/errlentry.H>
-
-#include <isteps/hwpisteperror.H>
#include <errl/errludtarget.H>
+#include <isteps/hwpisteperror.H>
+#include <util/utilmbox_scratch.H>
+#include <util/misc.H>
-#include <initservice/isteps_trace.H>
// targeting support.
#include <targeting/common/commontargeting.H>
@@ -41,13 +42,14 @@
#include <config.h>
#include <fapi2.H>
#include <fapi2/plat_hwp_invoker.H>
-#include <util/utilmbox_scratch.H>
//HWP
#include <p9_io_dmi_post_trainadv.H>
#ifdef CONFIG_AXONE
#include <p9a_omi_train_check.H>
+#include <exp_omi_train_check.H>
+#include <chipids.H> // for EXPLORER ID
#endif
using namespace ISTEP;
@@ -129,41 +131,87 @@ void* call_dmi_post_trainadv (void *io_pArgs)
}
#ifdef CONFIG_AXONE
- // Find omi targets
- TARGETING::TargetHandleList l_omiTargetList;
- getAllChiplets(l_omiTargetList, TYPE_OMI);
-
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_dmi_post_trainadv: %d OMIs found",
- l_omiTargetList.size());
-
- for (const auto & l_omi_target : l_omiTargetList)
+ if( ! Util::isSimicsRunning() )
{
- // call the HWP with each OMI target
- fapi2::Target<fapi2::TARGET_TYPE_OMI> l_fapi_omi_target(l_omi_target);
+ // Find ocmb targets
+ TARGETING::TargetHandleList l_chipList;
+ TARGETING::getAllChips(l_chipList, TARGETING::TYPE_OCMB_CHIP, true);
- FAPI_INVOKE_HWP(l_err, p9a_omi_train_check, l_fapi_omi_target );
+ for (auto & l_ocmb: l_chipList)
+ {
+ // Only run exp_omi_train on EXPLORER OCMB targets. This step
+ // cannot run on GEMINI targets.
+ uint32_t chipId = l_ocmb->getAttr< TARGETING::ATTR_CHIP_ID>();
+ if (chipId == POWER_CHIPID::EXPLORER_16)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_ocmb_target( l_ocmb );
+ FAPI_INVOKE_HWP(l_err, exp_omi_train_check, l_ocmb_target );
+
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: exp_omi_train_check HWP on target HUID %.8x",
+ l_err->reasonCode(), TARGETING::get_huid(l_ocmb) );
+
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_ocmb).addToLog( l_err );
+
+ // Create IStep error log and cross reference to error that occurred
+ l_StepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : exp_omi_train_check HWP on target HUID %.08x",
+ TARGETING::get_huid(l_ocmb));
+ }
+ }
+ else
+ {
+ // Gemini, just skip exp_omi_train_check call
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Skipping exp_omi_train_check HWP on because target HUID 0x%.8X, chipId 0x%.4X is a Gemini OCMB",
+ TARGETING::get_huid(l_ocmb), chipId );
+ }
+ }
- // process return code.
- if ( l_err )
+ // Find omi targets
+ TARGETING::TargetHandleList l_omiTargetList;
+ getAllChiplets(l_omiTargetList, TYPE_OMI);
+
+ for (const auto & l_omi_target : l_omiTargetList)
{
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: p9a_omi_train_check HWP on target HUID %.8x",
- l_err->reasonCode(), TARGETING::get_huid(l_omi_target) );
+ // call the HWP with each OMI target
+ fapi2::Target<fapi2::TARGET_TYPE_OMI> l_fapi_omi_target(l_omi_target);
- // capture the target data in the elog
- ErrlUserDetailsTarget(l_omi_target).addToLog( l_err );
+ FAPI_INVOKE_HWP(l_err, p9a_omi_train_check, l_fapi_omi_target );
- // Create IStep error log and cross reference to error that occurred
- l_StepError.addErrorDetails( l_err );
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: p9a_omi_train_check HWP on target HUID %.8x",
+ l_err->reasonCode(), TARGETING::get_huid(l_omi_target) );
- // Commit Error
- errlCommit( l_err, ISTEP_COMP_ID );
- }
- else
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : p9a_omi_train_check HWP on target HUID %.08x",
- TARGETING::get_huid(l_omi_target));
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_omi_target).addToLog( l_err );
+
+ // Create IStep error log and cross reference to error that occurred
+ l_StepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : p9a_omi_train_check HWP on target HUID %.08x",
+ TARGETING::get_huid(l_omi_target));
+ }
}
}
#endif
diff --git a/src/usr/isteps/istep12/call_dmi_pre_trainadv.C b/src/usr/isteps/istep12/call_dmi_pre_trainadv.C
index da8a9bb96..09aa8a81f 100644
--- a/src/usr/isteps/istep12/call_dmi_pre_trainadv.C
+++ b/src/usr/isteps/istep12/call_dmi_pre_trainadv.C
@@ -26,12 +26,12 @@
#include <trace/interface.H>
#include <initservice/taskargs.H>
+#include <initservice/isteps_trace.H>
#include <errl/errlentry.H>
-
-#include <isteps/hwpisteperror.H>
#include <errl/errludtarget.H>
-
-#include <initservice/isteps_trace.H>
+#include <isteps/hwpisteperror.H>
+#include <util/misc.H>
+#include <util/utilmbox_scratch.H>
// targeting support.
#include <targeting/common/commontargeting.H>
@@ -41,11 +41,13 @@
#include <config.h>
#include <fapi2.H>
#include <fapi2/plat_hwp_invoker.H>
-#include <util/utilmbox_scratch.H>
+
//HWP
#include <p9_io_dmi_pre_trainadv.H>
#ifdef CONFIG_AXONE
+#include <exp_omi_setup.H>
+#include <p9a_omi_setup.H>
#include <p9a_omi_train.H>
#endif
@@ -128,45 +130,81 @@ void* call_dmi_pre_trainadv (void *io_pArgs)
}
#ifdef CONFIG_AXONE
- TARGETING::TargetHandleList l_omiTargetList;
- getAllChiplets(l_omiTargetList, TYPE_OMI);
-
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_dmi_pre_trainadv: %d OMIs found",
- l_omiTargetList.size());
- for (const auto & l_omi_target : l_omiTargetList)
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "p9a_omi_train HWP target HUID %.8x",
- TARGETING::get_huid(l_omi_target));
+ TARGETING::TargetHandleList l_ocmbTargetList;
+ getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
- // call the HWP with each OMI target
- fapi2::Target<fapi2::TARGET_TYPE_OMI> l_fapi_omi_target(l_omi_target);
+ for (const auto & l_ocmb_target : l_ocmbTargetList)
+ {
+ // call the HWP with each target
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target
+ (l_ocmb_target);
- FAPI_INVOKE_HWP(l_err, p9a_omi_train , l_fapi_omi_target );
- // process return code.
- if ( l_err )
- {
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: p9a_omi_train HWP on target HUID %.8x",
- l_err->reasonCode(), TARGETING::get_huid(l_omi_target) );
+ "exp_omi_setup HWP target HUID 0x%.08x",
+ TARGETING::get_huid(l_ocmb_target));
+
+ FAPI_INVOKE_HWP(l_err, exp_omi_setup, l_fapi_ocmb_target);
+
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: exp_omi_setup HWP on target HUID 0x%.08x",
+ l_err->reasonCode(), TARGETING::get_huid(l_ocmb_target) );
- // capture the target data in the elog
- ErrlUserDetailsTarget(l_omi_target).addToLog( l_err );
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_ocmb_target).addToLog( l_err );
- // Create IStep error log and cross reference to error that occurred
- l_StepError.addErrorDetails( l_err );
+ // Create IStep error log and cross reference to error that occurred
+ l_StepError.addErrorDetails( l_err );
- // Commit Error
- errlCommit( l_err, ISTEP_COMP_ID );
+ // Commit Error , continue on to next OCMB
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
}
- else
+
+ TARGETING::TargetHandleList l_omiTargetList;
+ getAllChiplets(l_omiTargetList, TYPE_OMI);
+
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_dmi_pre_trainadv: %d OMIs found",
+ l_omiTargetList.size());
+
+ for (const auto & l_omi_target : l_omiTargetList)
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : p9a_omi_train HWP on 0x%.08X", TARGETING::get_huid(l_omi_target));
+ "p9a_omi_setup HWP target HUID %.8x",
+ TARGETING::get_huid(l_omi_target));
+
+ // call the HWP with each OMI target
+ fapi2::Target<fapi2::TARGET_TYPE_OMI> l_fapi_omi_target(l_omi_target);
+
+ FAPI_INVOKE_HWP(l_err, p9a_omi_setup , l_fapi_omi_target );
+
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: p9a_omi_setup HWP on target HUID %.8x",
+ l_err->reasonCode(), TARGETING::get_huid(l_omi_target) );
+
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_omi_target).addToLog( l_err );
+
+ // Create IStep error log and cross reference to error that occurred
+ l_StepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : p9a_omi_setup HWP on 0x%.08X", TARGETING::get_huid(l_omi_target));
+ }
}
- }
+
#endif
diff --git a/src/usr/isteps/istep12/call_mss_getecid.C b/src/usr/isteps/istep12/call_mss_getecid.C
index 644661946..732862d32 100644
--- a/src/usr/isteps/istep12/call_mss_getecid.C
+++ b/src/usr/isteps/istep12/call_mss_getecid.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -46,7 +46,14 @@
#include <util/utilmbox_scratch.H>
//HWP
-#include <p9c_mss_get_cen_ecid.H>
+#ifndef CONFIG_AXONE
+ #include <p9c_mss_get_cen_ecid.H>
+#else
+ #include <chipids.H>
+ #include <exp_getecid.H>
+ #include <gem_getecid.H>
+#endif
+
using namespace ISTEP;
using namespace ISTEP_ERROR;
@@ -56,10 +63,39 @@ using namespace TARGETING;
namespace ISTEP_12
{
+void cumulus_mss_getecid(IStepError & io_istepError);
+void axone_mss_getecid(IStepError & io_istepError);
+
void* call_mss_getecid (void *io_pArgs)
{
IStepError l_StepError;
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_getecid entry" );
+ auto l_procModel = TARGETING::targetService().getProcessorModel();
+
+ switch (l_procModel)
+ {
+ case TARGETING::MODEL_CUMULUS:
+ cumulus_mss_getecid(l_StepError);
+ break;
+ case TARGETING::MODEL_AXONE:
+ axone_mss_getecid(l_StepError);
+ break;
+ case TARGETING::MODEL_NIMBUS:
+ default:
+ break;
+ }
+
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_getecid exit" );
+
+ // end task, returning any errorlogs to IStepDisp
+ return l_StepError.getErrorHandle();
+}
+
+#ifndef CONFIG_AXONE
+void cumulus_mss_getecid(IStepError & io_istepError)
+{
errlHndl_t l_err = NULL;
uint8_t l_ddr_port_status = 0;
uint8_t l_cache_enable = 0;
@@ -71,28 +107,20 @@ void* call_mss_getecid (void *io_pArgs)
{ MSS_GET_CEN_ECID_DDR_STATUS_MBA0_BAD,
MSS_GET_CEN_ECID_DDR_STATUS_MBA1_BAD };
- TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_getecid entry" );
-
// Get all Centaur targets
TARGETING::TargetHandleList l_membufTargetList;
getAllChips(l_membufTargetList, TYPE_MEMBUF);
- for (TargetHandleList::const_iterator
- l_membuf_iter = l_membufTargetList.begin();
- l_membuf_iter != l_membufTargetList.end();
- ++l_membuf_iter)
+ for ( const auto & l_membuf_target : l_membufTargetList )
{
- // make a local copy of the target for ease of use
- TARGETING::Target* l_pCentaur = *l_membuf_iter;
-
// Dump current run on target
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
"Running p9c_mss_get_cen_ecid HWP on "
- "target HUID %.8X", TARGETING::get_huid(l_pCentaur));
+ "target HUID %.8X", TARGETING::get_huid(l_membuf_target));
// call the HWP with each target
fapi2::Target <fapi2::TARGET_TYPE_MEMBUF_CHIP> l_fapi_centaur
- (l_pCentaur);
+ (l_membuf_target);
// call the HWP with each fapi2::Target
// Note: This HWP does not actually return the entire ECID data. It
@@ -108,10 +136,10 @@ void* call_mss_getecid (void *io_pArgs)
l_err->reasonCode());
// capture the target data in the elog
- ErrlUserDetailsTarget(l_pCentaur).addToLog( l_err );
+ ErrlUserDetailsTarget(l_membuf_target).addToLog( l_err );
// Create IStep error log and cross reference error that occurred
- l_StepError.addErrorDetails( l_err );
+ io_istepError.addErrorDetails( l_err );
// Commit Error
errlCommit( l_err, HWPF_COMP_ID );
@@ -131,22 +159,14 @@ void* call_mss_getecid (void *io_pArgs)
PredicateCTM l_mba_pred(CLASS_UNIT,TYPE_MBA);
TARGETING::TargetHandleList l_mbaTargetList;
getChildChiplets(l_mbaTargetList,
- l_pCentaur,
+ l_membuf_target,
TYPE_MBA);
- uint8_t l_num_func_mbas = l_mbaTargetList.size();
-
- for (TargetHandleList::const_iterator
- l_mba_iter = l_mbaTargetList.begin();
- l_mba_iter != l_mbaTargetList.end();
- ++l_mba_iter)
+ for ( const auto & l_mba_target : l_mbaTargetList )
{
- // Make a local copy of the target for ease of use
- TARGETING::Target* l_pMBA = *l_mba_iter;
-
// Get the MBA chip unit position
ATTR_CHIP_UNIT_type l_pos =
- l_pMBA->getAttr<ATTR_CHIP_UNIT>();
+ l_mba_target->getAttr<ATTR_CHIP_UNIT>();
// Check the DDR port status to see if this MBA should be
// set to nonfunctional.
@@ -154,10 +174,9 @@ void* call_mss_getecid (void *io_pArgs)
{
// call HWAS to deconfigure this target
l_err = HWAS::theDeconfigGard().deconfigureTarget(
- *l_pMBA, HWAS::DeconfigGard::
- DECONFIGURED_BY_MEMORY_CONFIG);
- l_num_func_mbas--;
-
+ *l_mba_target,
+ HWAS::DeconfigGard::
+ DECONFIGURED_BY_MEMORY_CONFIG);
if (l_err)
{
// shouldn't happen, but if it does, stop trying to
@@ -173,7 +192,7 @@ void* call_mss_getecid (void *io_pArgs)
"ERROR: error deconfiguring MBA or Centaur");
// Create IStep error log and cross ref error that occurred
- l_StepError.addErrorDetails( l_err );
+ io_istepError.addErrorDetails( l_err );
// Commit Error
errlCommit( l_err, HWPF_COMP_ID );
@@ -212,12 +231,12 @@ void* call_mss_getecid (void *io_pArgs)
// ATTR_CEN_MSS_CACHE_ENABLE is not set as writeable in src/import/chips/centaur/procedures/xml/attribute_info/memory_attributes.xml
// Should we remove below code?
// Set the ATTR_CEN_MSS_CACHE_ENABLE attribute
- //l_pCentaur->setAttr<TARGETING::ATTR_CEN_MSS_CACHE_ENABLE>(
+ //l_membuf_target->setAttr<TARGETING::ATTR_CEN_MSS_CACHE_ENABLE>(
// l_cache_enable);
// Read the ATTR_CEN_MSS_CACHE_ENABLE back to pick up any override
uint8_t l_cache_enable_attr =
- l_pCentaur->getAttr<TARGETING::ATTR_CEN_MSS_CACHE_ENABLE>();
+ l_membuf_target->getAttr<TARGETING::ATTR_CEN_MSS_CACHE_ENABLE>();
if (l_cache_enable != l_cache_enable_attr)
{
@@ -237,25 +256,21 @@ void* call_mss_getecid (void *io_pArgs)
{
// Deconfigure the L4 Cache Targets (there should be 1)
TargetHandleList l_list;
- getChildChiplets(l_list, l_pCentaur, TYPE_L4, false);
+ getChildChiplets(l_list, l_membuf_target, TYPE_L4, false);
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
"call_mss_getecid: deconfiguring %d L4s (Centaur huid: 0x%.8X)",
- l_list.size(), get_huid(l_pCentaur));
+ l_list.size(), get_huid(l_membuf_target));
- for (TargetHandleList::const_iterator
- l_l4_iter = l_list.begin();
- l_l4_iter != l_list.end();
- ++l_l4_iter)
+ for ( const auto & l_l4_target : l_list )
{
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
"call_mss_getecid: deconfiguring L4 (huid: 0x%.8X)",
- get_huid( *l_l4_iter));
+ get_huid(l_l4_target));
l_err = HWAS::theDeconfigGard().
- deconfigureTarget(**l_l4_iter ,
- HWAS::DeconfigGard::
- DECONFIGURED_BY_MEMORY_CONFIG);
+ deconfigureTarget( *l_l4_target,
+ HWAS::DeconfigGard::DECONFIGURED_BY_MEMORY_CONFIG);
if (l_err)
{
@@ -264,7 +279,7 @@ void* call_mss_getecid (void *io_pArgs)
// Create IStep error log
// and cross reference error that occurred
- l_StepError.addErrorDetails( l_err);
+ io_istepError.addErrorDetails( l_err);
// Commit Error
errlCommit(l_err, HWPF_COMP_ID);
@@ -281,11 +296,82 @@ void* call_mss_getecid (void *io_pArgs)
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"SUCCESS : mss_get_cen_ecid HWP( )" );
}
+}
+#else
+void cumulus_mss_getecid(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'p9c_mss_get_cen_ecid' but Cumulus code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
+#endif
- TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_getecid exit" );
+#ifdef CONFIG_AXONE
+void axone_mss_getecid(IStepError & io_istepError)
+{
+ errlHndl_t l_err = NULL;
- // end task, returning any errorlogs to IStepDisp
- return l_StepError.getErrorHandle();
-}
+ // Get all OCMB targets
+ TARGETING::TargetHandleList l_ocmbTargetList;
+ getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
+
+ bool isGeminiChip = false;
+ for (const auto & l_ocmb_target : l_ocmbTargetList)
+ {
+ fapi2::Target <fapi2::TARGET_TYPE_OCMB_CHIP>
+ l_fapi_ocmb_target(l_ocmb_target);
+
+ // check EXPLORER first as this is most likely the configuration
+ uint32_t chipId = l_ocmb_target->getAttr< TARGETING::ATTR_CHIP_ID>();
+ if (chipId == POWER_CHIPID::EXPLORER_16)
+ {
+ isGeminiChip = false;
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Running exp_getecid HWP on target HUID 0x%.8X",
+ TARGETING::get_huid(l_ocmb_target) );
+ FAPI_INVOKE_HWP(l_err, exp_getecid, l_fapi_ocmb_target);
+ }
+ else
+ {
+ isGeminiChip = true;
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Running gem_getecid HWP on target HUID 0x%.8X, chipId 0x%.4X",
+ TARGETING::get_huid(l_ocmb_target), chipId );
+ FAPI_INVOKE_HWP(l_err, gem_getecid, l_fapi_ocmb_target);
+ }
+
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X : %s_getecid HWP returned error",
+ l_err->reasonCode(), isGeminiChip?"gem":"exp");
+
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_ocmb_target).addToLog(l_err);
+
+ // Create IStep error log and cross reference to error that occurred
+ io_istepError.addErrorDetails( l_err );
+ // Commit Error
+ errlCommit( l_err, HWPF_COMP_ID );
+
+ break;
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS running %s_getecid HWP on target HUID 0x%.8X",
+ isGeminiChip?"gem":"exp", TARGETING::get_huid(l_ocmb_target) );
+ }
+ }
+}
+#else
+void axone_mss_getecid(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'gem_getecid' or 'exp_getecid' but Axone code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
+#endif
};
diff --git a/src/usr/isteps/istep12/call_proc_dmi_scominit.C b/src/usr/isteps/istep12/call_proc_dmi_scominit.C
index b875322b4..e0c452206 100644
--- a/src/usr/isteps/istep12/call_proc_dmi_scominit.C
+++ b/src/usr/isteps/istep12/call_proc_dmi_scominit.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -46,6 +46,11 @@
// HWP
#include <p9_io_dmi_scominit.H>
+#ifdef CONFIG_AXONE
+#include <p9a_omi_setup_bars.H>
+#endif
+
+
#include <mmio/mmio.H>
using namespace ISTEP;
@@ -63,6 +68,7 @@ void* call_proc_dmi_scominit (void *io_pArgs)
TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_proc_dmi_scominit entry" );
+#ifndef CONFIG_AXONE
TARGETING::TargetHandleList l_dmiTargetList;
getAllChiplets(l_dmiTargetList, TYPE_DMI);
@@ -105,6 +111,51 @@ void* call_proc_dmi_scominit (void *io_pArgs)
}
+#else // CONFIG_AXONE
+
+ TARGETING::TargetHandleList l_procTargetList;
+ getAllChips(l_procTargetList, TYPE_PROC);
+
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_proc_dmi_scominit: %d procs found",
+ l_procTargetList.size());
+
+ for (const auto & l_proc_target : l_procTargetList)
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "p9a_omi_setup_bars HWP target HUID %.8x",
+ TARGETING::get_huid(l_proc_target));
+
+ // call the HWP with each target
+ fapi2::Target <fapi2::TARGET_TYPE_PROC_CHIP> l_fapi_proc_target
+ (l_proc_target);
+
+ FAPI_INVOKE_HWP(l_err, p9a_omi_setup_bars, l_fapi_proc_target);
+
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: p9a_omi_setup_bars HWP on target HUID %.8x",
+ l_err->reasonCode(), TARGETING::get_huid(l_proc_target) );
+
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_proc_target).addToLog( l_err );
+
+ // Create IStep error log and cross reference to error that occurred
+ l_StepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, ISTEP_COMP_ID );
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : p9a_omi_setup_bars HWP");
+ }
+
+ }
+#endif // CONFIG_AXONE
+
// map OCMBs into Hostboot memory
l_err = MMIO::mmioSetup();
if ( l_err )
diff --git a/src/usr/isteps/istep12/makefile b/src/usr/isteps/istep12/makefile
index 6e565529d..62f6d5727 100644
--- a/src/usr/isteps/istep12/makefile
+++ b/src/usr/isteps/istep12/makefile
@@ -44,6 +44,9 @@ CENT_IO_HWP_PATH = $(CENT_PROC_PATH)/hwp/io
CENT_MEM_HWP_PATH = $(CENT_PROC_PATH)/hwp/memory
CENT_INITFILE_PATH = $(CENT_PROC_PATH)/hwp/initfiles
+GEM_PROCEDURES_PATH = ${ROOTPATH}/src/import/chips/ocmb/gemini/procedures
+
+
#Add all the extra include paths
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2/
EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include/
@@ -68,6 +71,10 @@ EXTRAINCDIR += ${P9A_MSS_HWP_PATH}
EXTRAINCDIR += ${EXPLORER_HWP_PATH}
EXTRAINCDIR += ${EXPLORER_INC_PATH}
EXTRAINCDIR += ${P9A_MSS_ACCESSOR_PATH}
+EXTRAINCDIR += ${GEM_PROCEDURES_PATH}/hwp/memory
+EXTRAINCDIR += ${GEM_PROCEDURES_PATH}/hwp/memory/lib/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils
+EXTRAINCDIR += ${EXPLORER_HWP_PATH}/lib
VPATH += $(P9_NEST_HWP_PATH)
VPATH += $(P9_PERV_HWP_PATH)
@@ -121,21 +128,30 @@ include $(P9_IO_HWP_PATH)/p9_io_dmi_clear_firs.mk
include $(CENT_INITFILE_PATH)/centaur_dmi_scom.mk
include $(P9_IO_HWP_PATH)/p9_io_erepairAccessorHwpFuncs.mk
-
VPATH += $(if $(CONFIG_AXONE),${P9A_MSS_HWP_PATH},)
VPATH += $(if $(CONFIG_AXONE),${EXPLORER_HWP_PATH},)
VPATH += $(if $(CONFIG_AXONE),${EXPLORER_OMI_HWP_PATH},)
VPATH += $(if $(CONFIG_AXONE),${P9_MEMORY_HWP_PATH},)
+VPATH += $(if $(CONFIG_AXONE),${GEM_PROCEDURES_PATH}/hwp/memory,)
+
OBJS += $(if $(CONFIG_AXONE),exp_omi_utils.o,)
OBJS += $(if $(CONFIG_AXONE),exp_omi_setup.o,)
OBJS += $(if $(CONFIG_AXONE),exp_omi_train.o,)
+OBJS += $(if $(CONFIG_AXONE),p9a_omi_setup.o,)
OBJS += $(if $(CONFIG_AXONE),p9a_omi_train.o,)
OBJS += $(if $(CONFIG_AXONE),p9a_omi_train_check.o,)
+OBJS += $(if $(CONFIG_AXONE),exp_omi_train_check.o,)
OBJS += $(if $(CONFIG_AXONE),p9a_omi_setup_bars.o,)
OBJS += $(if $(CONFIG_AXONE),p9a_addr_ext.o,)
OBJS += $(if $(CONFIG_AXONE),exp_omi_init.o,)
OBJS += $(if $(CONFIG_AXONE),p9a_omi_init.o,)
OBJS += $(if $(CONFIG_AXONE),p9a_omi_init_scom.o,)
-
+OBJS += $(if $(CONFIG_AXONE),p9a_omi_io_scom.o,)
+OBJS += $(if $(CONFIG_AXONE),p9a_omic_io_scom.o,)
+OBJS += $(if $(CONFIG_AXONE),p9a_io_omi_scominit.o,)
+OBJS += $(if $(CONFIG_AXONE),p9a_io_omi_dccal.o,)
+OBJS += $(if $(CONFIG_AXONE),gem_getecid.o,)
+OBJS += $(if $(CONFIG_AXONE),exp_getecid.o,)
+OBJS += $(if $(CONFIG_AXONE),p9a_disable_ocmb_i2c.o,)
include ${ROOTPATH}/config.mk
diff --git a/src/usr/isteps/istep13/call_mss_ddr_phy_reset.C b/src/usr/isteps/istep13/call_mss_ddr_phy_reset.C
index 00ffaf2fb..4f28f980b 100644
--- a/src/usr/isteps/istep13/call_mss_ddr_phy_reset.C
+++ b/src/usr/isteps/istep13/call_mss_ddr_phy_reset.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -41,7 +41,9 @@
#include <fapi2.H>
#include <fapi2/plat_hwp_invoker.H>
#include <p9_mss_ddr_phy_reset.H>
+#ifndef CONFIG_AXONE
#include <p9c_mss_ddr_phy_reset.H>
+#endif
using namespace ERRORLOG;
using namespace ISTEP;
@@ -103,6 +105,7 @@ void* call_mss_ddr_phy_reset (void *io_pArgs)
} // end l_mcbist loop
+#ifndef CONFIG_AXONE
if(l_stepError.getErrorHandle() == NULL)
{
// Get all Centaur targets
@@ -169,6 +172,7 @@ void* call_mss_ddr_phy_reset (void *io_pArgs)
}
}
+#endif
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call_mss_ddr_phy_reset exit" );
diff --git a/src/usr/isteps/istep13/call_mss_draminit.C b/src/usr/isteps/istep13/call_mss_draminit.C
index 915bc992b..012d3111a 100644
--- a/src/usr/isteps/istep13/call_mss_draminit.C
+++ b/src/usr/isteps/istep13/call_mss_draminit.C
@@ -23,7 +23,7 @@
/* */
/* IBM_PROLOG_END_TAG */
-//Error handling and tracing
+// Error Handling and Tracing Support
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <errl/errludtarget.H>
@@ -32,12 +32,15 @@
#include <initservice/initserviceif.H>
#include <plat_trace.H>
-//Istep 13 framework
+// Generated files
+#include <config.h>
+
+// Istep 13 framework
#include <istepHelperFuncs.H>
#include "istep13consts.H"
#include "platform_vddr.H"
-// targeting support
+// Targeting support
#include <targeting/common/commontargeting.H>
#include <targeting/common/util.H>
#include <targeting/common/utilFilter.H>
@@ -47,14 +50,21 @@
//From Import Directory (EKB Repository)
#include <fapi2.H>
-#include <p9_mss_draminit.H>
-#include <p9c_mss_draminit.H>
+#ifndef CONFIG_AXONE
+ #include <p9_mss_draminit.H>
+ #include <p9c_mss_draminit.H>
+#else
+#include <chipids.H>
+ #include <exp_draminit.H>
+ #include <gem_draminit.H>
+#endif
-#ifdef CONFIG_NVDIMM
// NVDIMM support
+#ifdef CONFIG_NVDIMM
#include <isteps/nvdimm/nvdimm.H>
#endif
+
using namespace ERRORLOG;
using namespace ISTEP;
using namespace ISTEP_ERROR;
@@ -62,8 +72,49 @@ using namespace TARGETING;
namespace ISTEP_13
{
+// Declare local functions
+void nimbus_mss_draminit(IStepError & io_istepError);
+void cumulus_mss_draminit(IStepError & io_istepError);
+void axone_mss_draminit(IStepError & io_istepError);
+void mss_post_draminit( IStepError & io_stepError );
-void mss_post_draminit( IStepError & io_stepError )
+void* call_mss_draminit (void *io_pArgs)
+{
+ IStepError l_stepError;
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_draminit entry" );
+ auto l_procModel = TARGETING::targetService().getProcessorModel();
+
+ switch (l_procModel)
+ {
+ case TARGETING::MODEL_CUMULUS:
+ cumulus_mss_draminit(l_stepError);
+ break;
+ case TARGETING::MODEL_AXONE:
+ axone_mss_draminit(l_stepError);
+ break;
+ case TARGETING::MODEL_NIMBUS:
+ nimbus_mss_draminit(l_stepError);
+ break;
+ default:
+ assert(0, "call_mss_draminit: Unsupported model type 0x%04X",
+ l_procModel);
+ break;
+ }
+
+ // call POST_DRAM_INIT function, if nothing failed above
+ if( INITSERVICE::spBaseServicesEnabled() &&
+ (l_stepError.getErrorHandle() == nullptr) )
+ {
+ mss_post_draminit(l_stepError);
+ }
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_draminit exit" );
+
+ return l_stepError.getErrorHandle();
+}
+
+void mss_post_draminit( IStepError & io_stepError )
{
errlHndl_t l_err = NULL;
bool rerun_vddr = false;
@@ -144,14 +195,11 @@ void mss_post_draminit( IStepError & io_stepError )
return;
}
-void* call_mss_draminit (void *io_pArgs)
+#ifndef CONFIG_AXONE
+void nimbus_mss_draminit(IStepError & io_istepError)
{
errlHndl_t l_err = NULL;
- IStepError l_stepError;
-
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_draminit entry" );
-
// Get all MCBIST targets
TARGETING::TargetHandleList l_mcbistTargetList;
getAllChiplets(l_mcbistTargetList, TYPE_MCBIST);
@@ -171,6 +219,10 @@ void* call_mss_draminit (void *io_pArgs)
TARGETING::TargetHandleList l_dimmTargetList;
getChildAffinityTargets(l_dimmTargetList, l_mcbist_target, CLASS_NA, TYPE_DIMM);
+ // Generate valid encryption keys
+ NVDIMM::nvdimm_gen_keys();
+
+ // Walk the dimm list and init nvdimms
for (const auto & l_dimm : l_dimmTargetList)
{
if (isNVDIMM(l_dimm))
@@ -178,7 +230,12 @@ void* call_mss_draminit (void *io_pArgs)
NVDIMM::nvdimm_init(l_dimm);
}
}
+ // After nvdimm init
+ // - nvdimm controller initialized
+ // - nvdimm encryption unlocked
+ // - nvdimms disarmed
#endif
+
FAPI_INVOKE_HWP(l_err, p9_mss_draminit, l_fapi_mcbist_target);
if (l_err)
@@ -191,12 +248,12 @@ void* call_mss_draminit (void *io_pArgs)
ErrlUserDetailsTarget(l_mcbist_target).addToLog(l_err);
// Create IStep error log and cross reference to error that occurred
- l_stepError.addErrorDetails( l_err );
-
- break;
+ io_istepError.addErrorDetails( l_err );
// Commit Error
errlCommit( l_err, HWPF_COMP_ID );
+
+ break;
}
else
{
@@ -206,85 +263,145 @@ void* call_mss_draminit (void *io_pArgs)
}
} // endfor mcbist's
+}
+void cumulus_mss_draminit(IStepError & io_istepError)
+{
+ errlHndl_t l_err = NULL;
+ // Get all Centaur targets
+ TARGETING::TargetHandleList l_membufTargetList;
+ getAllChips(l_membufTargetList, TYPE_MEMBUF);
- if(l_stepError.getErrorHandle() == NULL)
+ for (const auto & l_membufTarget : l_membufTargetList )
{
- // Get all Centaur targets
- TARGETING::TargetHandleList l_membufTargetList;
- getAllChips(l_membufTargetList, TYPE_MEMBUF);
-
- for (TargetHandleList::const_iterator
- l_membuf_iter = l_membufTargetList.begin();
- l_membuf_iter != l_membufTargetList.end();
- ++l_membuf_iter)
+ TARGETING::TargetHandleList l_mbaTargetList;
+ getChildChiplets(l_mbaTargetList, l_membufTarget, TYPE_MBA);
+
+ for (const auto & l_mbaTarget : l_mbaTargetList )
{
- // make a local copy of the target for ease of use
- TARGETING::Target* l_pCentaur = *l_membuf_iter;
-
- TARGETING::TargetHandleList l_mbaTargetList;
- getChildChiplets(l_mbaTargetList,
- l_pCentaur,
- TYPE_MBA);
-
- for (TargetHandleList::const_iterator
- l_mba_iter = l_mbaTargetList.begin();
- l_mba_iter != l_mbaTargetList.end();
- ++l_mba_iter)
- {
- // Make a local copy of the target for ease of use
- TARGETING::Target* l_mbaTarget = *l_mba_iter;
-
- // Dump current run on target
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "Running p9c_mss_draminit HWP on "
- "target HUID %.8X", TARGETING::get_huid(l_mbaTarget));
-
- // call the HWP with each target
- fapi2::Target <fapi2::TARGET_TYPE_MBA_CHIPLET> l_fapi_mba_target(l_mbaTarget);
-
- FAPI_INVOKE_HWP(l_err, p9c_mss_draminit, l_fapi_mba_target);
-
- // process return code.
- if ( l_err )
- {
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X : p9c_mss_draminit HWP returns error",
- l_err->reasonCode());
-
- // capture the target data in the elog
- ErrlUserDetailsTarget(l_mbaTarget).addToLog(l_err);
-
- // Create IStep error log and cross reference to error that occurred
- l_stepError.addErrorDetails( l_err );
-
- // Commit Error
- errlCommit( l_err, HWPF_COMP_ID );
-
- break;
- }
- else
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS running p9c_mss_draminit HWP on "
- "target HUID %.8X", TARGETING::get_huid(l_mbaTarget));
- }
-
- }
- }
+ // Dump current run on target
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Running p9c_mss_draminit HWP on "
+ "target HUID %.8X", TARGETING::get_huid(l_mbaTarget));
- }
+ // call the HWP with each target
+ fapi2::Target <fapi2::TARGET_TYPE_MBA_CHIPLET> l_fapi_mba_target(l_mbaTarget);
+
+ FAPI_INVOKE_HWP(l_err, p9c_mss_draminit, l_fapi_mba_target);
+
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X : p9c_mss_draminit HWP returns error",
+ l_err->reasonCode());
+
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_mbaTarget).addToLog(l_err);
+
+ // Create IStep error log and cross reference to error that occurred
+ io_istepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, HWPF_COMP_ID );
- // call POST_DRAM_INIT function
- if(INITSERVICE::spBaseServicesEnabled())
+ break;
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS running p9c_mss_draminit HWP on "
+ "target HUID %.8X", TARGETING::get_huid(l_mbaTarget));
+ }
+ } // end MBA loop
+ } // end MEMBUF loop
+}
+
+#else
+void nimbus_mss_draminit(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'p9_mss_draminit' but Nimbus code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
+
+void cumulus_mss_draminit(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'p9c_mss_draminit' but Cumulus code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
+#endif
+
+#ifdef CONFIG_AXONE
+void axone_mss_draminit(IStepError & io_istepError)
+{
+ errlHndl_t l_err = NULL;
+
+ // Get all OCMB targets
+ TARGETING::TargetHandleList l_ocmbTargetList;
+ getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
+
+ bool isGeminiChip = false;
+ for ( const auto & l_ocmb : l_ocmbTargetList )
{
- mss_post_draminit(l_stepError);
- }
+ fapi2::Target <fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target(l_ocmb);
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_draminit exit" );
+ // check EXPLORER first as this is most likely the configuration
+ uint32_t chipId = l_ocmb->getAttr< TARGETING::ATTR_CHIP_ID>();
+ if (chipId == POWER_CHIPID::EXPLORER_16)
+ {
+ isGeminiChip = false;
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Running exp_draminit HWP on target HUID 0x%.8X",
+ TARGETING::get_huid(l_ocmb) );
+ FAPI_INVOKE_HWP(l_err, exp_draminit, l_fapi_ocmb_target);
+ }
+ else
+ {
+ isGeminiChip = true;
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Running gem_draminit HWP on target HUID 0x%.8X, chipId 0x%.4X",
+ TARGETING::get_huid(l_ocmb), chipId );
+ FAPI_INVOKE_HWP(l_err, gem_draminit, l_fapi_ocmb_target);
+ }
- return l_stepError.getErrorHandle();
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X : %s_draminit HWP returned error",
+ l_err->reasonCode(), isGeminiChip?"gem":"exp");
+
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_ocmb).addToLog(l_err);
+
+ // Create IStep error log and cross reference to error that occurred
+ io_istepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, HWPF_COMP_ID );
+
+ break;
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS running %s_draminit HWP on target HUID 0x%.8X",
+ isGeminiChip?"gem":"exp", TARGETING::get_huid(l_ocmb) );
+ }
+ } // end of OCMB loop
+}
+
+#else
+
+void axone_mss_draminit(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'exp_draminit' or 'gem_draminit' but Axone code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
}
+#endif
};
diff --git a/src/usr/isteps/istep13/call_mss_draminit_mc.C b/src/usr/isteps/istep13/call_mss_draminit_mc.C
index cee7771bf..54b790de2 100644
--- a/src/usr/isteps/istep13/call_mss_draminit_mc.C
+++ b/src/usr/isteps/istep13/call_mss_draminit_mc.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -44,8 +44,14 @@
//From Import Directory (EKB Repository)
#include <config.h>
#include <fapi2.H>
+#ifdef CONFIG_AXONE
+#include <exp_draminit_mc.H>
+#include <chipids.H> // for EXPLORER ID
+#else
#include <p9_mss_draminit_mc.H>
#include <p9c_mss_draminit_mc.H>
+#endif
+
using namespace ERRORLOG;
@@ -66,6 +72,8 @@ void* call_mss_draminit_mc (void *io_pArgs)
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,"call_mss_draminit_mc entry" );
+#ifndef CONFIG_AXONE
+
// Get all MCBIST
TARGETING::TargetHandleList l_mcbistTargetList;
getAllChiplets(l_mcbistTargetList, TYPE_MCBIST);
@@ -117,8 +125,8 @@ void* call_mss_draminit_mc (void *io_pArgs)
{
// Dump current run on target
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "Running p9_mss_draminit_mc HWP on "
- "target HUID %.8X", TARGETING::get_huid(l_membuf_target));
+ "Running p9_mss_draminit_mc HWP on target HUID %.8X",
+ TARGETING::get_huid(l_membuf_target) );
fapi2::Target <fapi2::TARGET_TYPE_MEMBUF_CHIP> l_fapi_membuf_target
(l_membuf_target);
@@ -133,26 +141,84 @@ void* call_mss_draminit_mc (void *io_pArgs)
l_err->reasonCode());
// capture the target data in the elog
- ErrlUserDetailsTarget(l_fapi_membuf_target).addToLog( l_err );
+ ErrlUserDetailsTarget(l_membuf_target).addToLog( l_err );
- // Create IStep error log and cross reference to error that occurred
+ // Create IStep error log and cross reference to error
+ // that occurred
l_stepError.addErrorDetails( l_err );
// Commit Error
errlCommit( l_err, HWPF_COMP_ID );
-
+
break;
}
else
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"SUCCESS running p9c_mss_draminit_mc HWP on "
- "target HUID %.8X", TARGETING::get_huid(l_fapi_membuf_target));
+ "target HUID %.8X",
+ TARGETING::get_huid(l_membuf_target));
}
-
}
}
+#else
+
+ // Get all OCMB targets
+ TARGETING::TargetHandleList l_ocmbTargetList;
+ getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
+
+ for (const auto & l_ocmb_target : l_ocmbTargetList)
+ {
+ // check EXPLORER first as this is most likely the configuration
+ uint32_t chipId = l_ocmb_target->getAttr< TARGETING::ATTR_CHIP_ID>();
+ if (chipId == POWER_CHIPID::EXPLORER_16)
+ {
+ fapi2::Target <fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target
+ (l_ocmb_target);
+
+ // Dump current run on target
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Running exp_draminit_mc HWP on "
+ "target HUID %.8X", TARGETING::get_huid(l_ocmb_target));
+
+ // call the HWP with each fapi2::Target
+ FAPI_INVOKE_HWP(l_err, exp_draminit_mc, l_fapi_ocmb_target);
+ }
+ else
+ {
+ // Gemini, NOOP
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Skipping draminit_mc HWP on target HUID 0x%.8X, chipId 0x%.4X",
+ TARGETING::get_huid(l_ocmb_target), chipId );
+ }
+ if (l_err)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X : exp_draminit_mc HWP returns error",
+ l_err->reasonCode());
+
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_ocmb_target).addToLog( l_err );
+
+ // Create IStep error log and cross reference to error that occurred
+ l_stepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, HWPF_COMP_ID );
+
+ break;
+ }
+ else if (chipId == POWER_CHIPID::EXPLORER_16)
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS running exp_draminit_mc HWP on target HUID %.8X",
+ TARGETING::get_huid(l_ocmb_target));
+ }
+ }
+
+#endif
+
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_draminit_mc exit" );
return l_stepError.getErrorHandle();
diff --git a/src/usr/isteps/istep13/call_mss_draminit_trainadv.C b/src/usr/isteps/istep13/call_mss_draminit_trainadv.C
index fc42f7264..31e0a50d3 100644
--- a/src/usr/isteps/istep13/call_mss_draminit_trainadv.C
+++ b/src/usr/isteps/istep13/call_mss_draminit_trainadv.C
@@ -110,6 +110,7 @@ class MembufWorkItem: public IStepWorkItem
//******************************************************************************
void MembufWorkItem::operator()()
{
+#ifndef CONFIG_AXONE
errlHndl_t l_err = nullptr;
// reset watchdog for each memb as this function can be very slow
@@ -154,7 +155,7 @@ void MembufWorkItem::operator()()
mutex_unlock(&g_stepErrorMutex);
// Commit Error
- errlCommit( l_err, HWPF_COMP_ID );
+ errlCommit( l_err, ISTEP_COMP_ID );
break;
}
@@ -165,6 +166,8 @@ void MembufWorkItem::operator()()
TARGETING::get_huid(l_mbaTarget));
}
}
+#endif
+
}
@@ -210,7 +213,7 @@ void* call_mss_draminit_trainadv (void *io_pArgs)
l_stepError.addErrorDetails( l_err );
// Commit Error
- errlCommit( l_err, HWPF_COMP_ID );
+ errlCommit( l_err, ISTEP_COMP_ID );
}
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
@@ -252,7 +255,14 @@ void* call_mss_draminit_trainadv (void *io_pArgs)
tp.start();
//wait for all workitems to complete, then clean up all threads.
- tp.shutdown();
+ l_err = tp.shutdown();
+ if(l_err)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ ERR_MRK"call_mss_draminit_trainadv: thread pool returned an error");
+ l_stepError.addErrorDetails(l_err);
+ errlCommit(l_err, ISTEP_COMP_ID);
+ }
}
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
diff --git a/src/usr/isteps/istep13/call_mss_draminit_training.C b/src/usr/isteps/istep13/call_mss_draminit_training.C
index a167457e9..d790e3483 100644
--- a/src/usr/isteps/istep13/call_mss_draminit_training.C
+++ b/src/usr/isteps/istep13/call_mss_draminit_training.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -102,6 +102,7 @@ void* call_mss_draminit_training (void *io_pArgs)
}
}
+#ifndef CONFIG_AXONE
if(l_stepError.getErrorHandle() == NULL)
{
// Get all Centaur targets
@@ -169,6 +170,7 @@ void* call_mss_draminit_training (void *io_pArgs)
}
}
+#endif
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call_mss_draminit_training exit" );
diff --git a/src/usr/isteps/istep13/call_mss_scominit.C b/src/usr/isteps/istep13/call_mss_scominit.C
index 69e05c7ee..6c623f1d2 100644
--- a/src/usr/isteps/istep13/call_mss_scominit.C
+++ b/src/usr/isteps/istep13/call_mss_scominit.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,10 +42,13 @@
#include <config.h>
#include <fapi2.H>
#include <p9_mss_scominit.H>
-#include <p9_throttle_sync.H>
-#include <p9c_mss_scominit.H>
#ifdef CONFIG_AXONE
-#include <exp_scominit.H>
+ #include <exp_scominit.H>
+ #include <chipids.H> // for EXPLORER ID
+ #include <p9a_throttle_sync.H>
+#else
+ #include <p9c_mss_scominit.H>
+ #include <p9_throttle_sync.H>
#endif
using namespace ERRORLOG;
@@ -55,163 +58,290 @@ using namespace TARGETING;
namespace ISTEP_13
{
+void nimbus_call_mss_scominit(IStepError & io_istepError);
+void cumulus_call_mss_scominit(IStepError & io_istepError);
+void axone_call_mss_scominit(IStepError & io_istepError);
+void run_proc_throttle_sync(IStepError & io_istepError);
+
void* call_mss_scominit (void *io_pArgs)
{
- errlHndl_t l_err = NULL;
-
- IStepError l_stepError;
+ IStepError l_StepError;
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_scominit entry" );
+ auto l_procModel = TARGETING::targetService().getProcessorModel();
- do
+ switch (l_procModel)
{
- // Get all MCBIST targets
- TARGETING::TargetHandleList l_mcbistTargetList;
- getAllChiplets(l_mcbistTargetList, TYPE_MCBIST);
+ case TARGETING::MODEL_CUMULUS:
+ cumulus_call_mss_scominit(l_StepError);
+ break;
+ case TARGETING::MODEL_AXONE:
+ axone_call_mss_scominit(l_StepError);
+ break;
+ case TARGETING::MODEL_NIMBUS:
+ nimbus_call_mss_scominit(l_StepError);
+ break;
+ default:
+ assert(0, "call_mss_scominit: Unsupported model type 0x%04X",
+ l_procModel);
+ break;
+ }
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_scominit exit" );
+
+ // end task, returning any errorlogs to IStepDisp
+ return l_StepError.getErrorHandle();
+}
+
+#ifndef CONFIG_AXONE
+
+void nimbus_call_mss_scominit(IStepError & io_istepError)
+{
+ errlHndl_t l_err = nullptr;
- for (const auto & l_target : l_mcbistTargetList)
+ // Get all MCBIST targets
+ TARGETING::TargetHandleList l_mcbistTargetList;
+ getAllChiplets(l_mcbistTargetList, TYPE_MCBIST);
+
+ for (const auto & l_target : l_mcbistTargetList)
+ {
+ // Dump current run on target
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Running p9_mss_scominit HWP on target HUID %.8X",
+ TARGETING::get_huid(l_target));
+
+ fapi2::Target <fapi2::TARGET_TYPE_MCBIST> l_fapi_target
+ (l_target);
+
+ // call the HWP with each fapi2::Target
+ FAPI_INVOKE_HWP(l_err, p9_mss_scominit, l_fapi_target);
+
+ if (l_err)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: p9_mss_scominit HWP returns error",
+ l_err->reasonCode());
+
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_target).addToLog(l_err);
+
+ // Create IStep error log and cross reference to error that
+ // occurred
+ io_istepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, HWPF_COMP_ID );
+
+ break;
+ }
+ else
{
- // Dump current run on target
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "Running p9_mss_scominit HWP on "
- "target HUID %.8X",
+ "SUCCESS running p9_mss_scominit HWP on target HUID %.8X",
TARGETING::get_huid(l_target));
+ }
+ }
+}
- fapi2::Target <fapi2::TARGET_TYPE_MCBIST> l_fapi_target
- (l_target);
+void cumulus_call_mss_scominit(IStepError & io_istepError)
+{
- // call the HWP with each fapi2::Target
- FAPI_INVOKE_HWP(l_err, p9_mss_scominit, l_fapi_target);
-
- if (l_err)
- {
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: p9_mss_scominit HWP returns error",
- l_err->reasonCode());
-
- // capture the target data in the elog
- ErrlUserDetailsTarget(l_target).addToLog(l_err);
-
- // Create IStep error log and cross reference to error that
- // occurred
- l_stepError.addErrorDetails( l_err );
-
- // Commit Error
- errlCommit( l_err, HWPF_COMP_ID );
-
- break;
- }
- else
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS running p9_mss_scominit HWP on "
- "target HUID %.8X", TARGETING::get_huid(l_target));
- }
- }
+ errlHndl_t l_err = nullptr;
- if (!l_stepError.isNull())
+ // Get all MBA targets
+ TARGETING::TargetHandleList l_membufTargetList;
+ getAllChips(l_membufTargetList, TYPE_MEMBUF);
+
+ for (const auto & l_membuf_target : l_membufTargetList)
+ {
+ // Dump current run on target
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Running p9c_mss_scominit HWP on target HUID %.8X",
+ TARGETING::get_huid(l_membuf_target));
+
+ fapi2::Target <fapi2::TARGET_TYPE_MEMBUF_CHIP> l_fapi_membuf_target
+ (l_membuf_target);
+
+ // call the HWP with each fapi2::Target
+ FAPI_INVOKE_HWP(l_err, p9c_mss_scominit, l_fapi_membuf_target);
+
+ if (l_err)
{
- break;
- }
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: p9c_mss_scominit HWP returns error",
+ l_err->reasonCode());
+
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_membuf_target).addToLog(l_err);
+
+ // Create IStep error log and cross reference to error that
+ // occurred
+ io_istepError.addErrorDetails( l_err );
- // Get all MBA targets
- TARGETING::TargetHandleList l_membufTargetList;
- getAllChips(l_membufTargetList, TYPE_MEMBUF);
+ // Commit Error
+ errlCommit( l_err, HWPF_COMP_ID );
- for (const auto & l_membuf_target : l_membufTargetList)
+ break;
+ }
+ else
{
- // Dump current run on target
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "Running p9c_mss_scominit HWP on "
- "target HUID %.8X",
- TARGETING::get_huid(l_membuf_target));
+ "SUCCESS running p9c_mss_scominit HWP on target HUID %.8X",
+ TARGETING::get_huid(l_membuf_target));
+ }
+ }
- fapi2::Target <fapi2::TARGET_TYPE_MEMBUF_CHIP> l_fapi_membuf_target
- (l_membuf_target);
+ // Setup the memory throttles for worstcase mode
+ run_proc_throttle_sync(io_istepError);
+
+}
+#else
+void nimbus_call_mss_scominit(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'p9_mss_scominit' but Nimbus code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
+
+void cumulus_call_mss_scominit(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'p9c_mss_scominit' but Cumulus code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
+
+#endif
- // call the HWP with each fapi2::Target
- FAPI_INVOKE_HWP(l_err, p9c_mss_scominit, l_fapi_membuf_target);
-
- if (l_err)
- {
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: p9c_mss_scominit HWP returns error",
- l_err->reasonCode());
-
- // capture the target data in the elog
- ErrlUserDetailsTarget(l_membuf_target).addToLog(l_err);
-
- // Create IStep error log and cross reference to error that
- // occurred
- l_stepError.addErrorDetails( l_err );
-
- // Commit Error
- errlCommit( l_err, HWPF_COMP_ID );
-
- break;
- }
- else
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS running p9c_mss_scominit HWP on "
- "target HUID %.8X", TARGETING::get_huid(l_membuf_target));
- }
- }
#ifdef CONFIG_AXONE
- // Get all OCMB targets
- TARGETING::TargetHandleList l_ocmbTargetList;
- getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
+void axone_call_mss_scominit(IStepError & io_istepError)
+{
- for (const auto & l_ocmb_target : l_ocmbTargetList)
- {
- // Dump current run on target
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "Running exp_scominit HWP on "
- "target HUID %.8X",
- TARGETING::get_huid(l_ocmb_target));
+ errlHndl_t l_err = nullptr;
+
+ // Get all OCMB targets
+ TARGETING::TargetHandleList l_ocmbTargetList;
+ getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
+ for (const auto & l_ocmb_target : l_ocmbTargetList)
+ {
+ // check EXPLORER first as this is most likely the configuration
+ uint32_t chipId = l_ocmb_target->getAttr< TARGETING::ATTR_CHIP_ID>();
+ if (chipId == POWER_CHIPID::EXPLORER_16)
+ {
fapi2::Target <fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target
(l_ocmb_target);
+ // Dump current run on target
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Running exp_scominit HWP on target HUID %.8X",
+ TARGETING::get_huid(l_ocmb_target));
+
// call the HWP with each fapi2::Target
FAPI_INVOKE_HWP(l_err, exp_scominit, l_fapi_ocmb_target);
-
- if (l_err)
- {
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: exp_scominit HWP returns error",
- l_err->reasonCode());
-
- // capture the target data in the elog
- ErrlUserDetailsTarget(l_fapi_ocmb_target).addToLog(l_err);
-
- // Create IStep error log and cross reference to error that
- // occurred
- l_stepError.addErrorDetails( l_err );
-
- // Commit Error
- errlCommit( l_err, HWPF_COMP_ID );
-
- break;
- }
- else
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS running exp_scominit HWP on "
- "target HUID %.8X", TARGETING::get_huid(l_ocmb_target));
- }
+ }
+ else
+ {
+ // Gemini, NOOP
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Skipping scominit HWP on target HUID 0x%.8X, chipId 0x%.4X",
+ TARGETING::get_huid(l_ocmb_target), chipId );
}
- if (!l_stepError.isNull())
+ if (l_err)
{
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: exp_scominit HWP returns error",
+ l_err->reasonCode());
+
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_ocmb_target).addToLog(l_err);
+
+ // Create IStep error log and cross reference to error that
+ // occurred
+ io_istepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, HWPF_COMP_ID );
+
break;
}
+ else if (chipId == POWER_CHIPID::EXPLORER_16)
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS running exp_scominit HWP on "
+ "target HUID %.8X", TARGETING::get_huid(l_ocmb_target));
+ }
+ }
+
+ // Need to setup the memory throttles for worstcase mode until
+ // we get the thermals really setup later
+ run_proc_throttle_sync(io_istepError);
+
+}
+#else
+void axone_call_mss_scominit(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'exp_scominit' but Axone code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
#endif
- } while (0);
+void run_proc_throttle_sync(IStepError & io_istepError)
+{
+ errlHndl_t l_errl = nullptr;
+
+ // Run proc throttle sync
+ // Get all functional proc chip targets
+ // Use targeting code to get a list of all processors
+ TARGETING::TargetHandleList l_procChips;
+ getAllChips( l_procChips, TARGETING::TYPE_PROC );
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_scominit exit" );
- return l_stepError.getErrorHandle();
+ for (const auto & l_procChip: l_procChips)
+ {
+ //Convert the TARGETING::Target into a fapi2::Target by passing
+ //l_procChip into the fapi2::Target constructor
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
+ l_fapi2CpuTarget((l_procChip));
+
+ // Call p9_throttle_sync
+#ifndef CONFIG_AXONE
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Running p9_throttle_sync HWP on target HUID %.8X",
+ TARGETING::get_huid(l_procChip) );
+ FAPI_INVOKE_HWP( l_errl, p9_throttle_sync, l_fapi2CpuTarget );
+#else
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Running p9a_throttle_sync HWP on target HUID %.8X",
+ TARGETING::get_huid(l_procChip) );
+ FAPI_INVOKE_HWP( l_errl, p9a_throttle_sync, l_fapi2CpuTarget );
+#endif
+
+ if (l_errl)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: p9_throttle_sync HWP returns error",
+ l_errl->reasonCode());
+
+ // Capture the target data in the elog
+ ErrlUserDetailsTarget(l_procChip).addToLog(l_errl);
+
+ // Create IStep error log and cross reference
+ // to error that occurred
+ io_istepError.addErrorDetails( l_errl );
+
+ // Commit Error
+ errlCommit( l_errl, HWPF_COMP_ID );
+
+ break;
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : p9_throttle_sync HWP on 0x%.8X processor",
+ TARGETING::get_huid(l_procChip) );
+ }
+ }
}
};
diff --git a/src/usr/isteps/istep13/istep13consts.H b/src/usr/isteps/istep13/istep13consts.H
index cf459f82e..218c89283 100644
--- a/src/usr/isteps/istep13/istep13consts.H
+++ b/src/usr/isteps/istep13/istep13consts.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -29,5 +29,5 @@
const uint8_t UNLIMITED_RUN = 0xFF;
const uint8_t VPO_NUM_OF_MBAS_TO_RUN = UNLIMITED_RUN;
const uint8_t VPO_NUM_OF_MEMBUF_TO_RUN = UNLIMITED_RUN;
-const uint8_t ISTEP13_MAX_THREADS = 1;
+const uint8_t ISTEP13_MAX_THREADS = 4;
#endif
diff --git a/src/usr/isteps/istep13/makefile b/src/usr/isteps/istep13/makefile
index bd38d4f71..d85873963 100644
--- a/src/usr/isteps/istep13/makefile
+++ b/src/usr/isteps/istep13/makefile
@@ -25,11 +25,12 @@
ROOTPATH = ../../../..
MODULE = istep13
-PROCEDURES_PATH = ${ROOTPATH}/src/import/chips/p9/procedures
-CEN_PROCEDURES_PATH = ${ROOTPATH}/src/import/chips/centaur/procedures
+P9_PROCEDURES_PATH = ${ROOTPATH}/src/import/chips/p9/procedures
+CEN_PROCEDURES_PATH = ${ROOTPATH}/src/import/chips/centaur/procedures
OCMB_PROCEDURES_PATH = ${ROOTPATH}/src/import/chips/ocmb/procedures
-EXP_PROCEDURES_PATH = ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures
-
+EXP_PROCEDURES_PATH = ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures
+EXP_INCLUDE_PATH = ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/
+GEM_PROCEDURES_PATH = ${ROOTPATH}/src/import/chips/ocmb/gemini/procedures
#Add all the extra include paths
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2
@@ -42,14 +43,14 @@ EXTRAINCDIR += ${ROOTPATH}/src/import/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/imageProcs/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/include
-EXTRAINCDIR += ${PROCEDURES_PATH}/hwp/memory
-EXTRAINCDIR += ${PROCEDURES_PATH}/hwp/memory/lib
-EXTRAINCDIR += ${PROCEDURES_PATH}/hwp/memory/lib/utils
-EXTRAINCDIR += ${PROCEDURES_PATH}/hwp/memory/lib/mc/
-EXTRAINCDIR += ${PROCEDURES_PATH}/hwp/memory/lib/fir/
-EXTRAINCDIR += ${PROCEDURES_PATH}/hwp/perv
-EXTRAINCDIR += ${PROCEDURES_PATH}/hwp/nest
-EXTRAINCDIR += ${PROCEDURES_PATH}/hwp/initfiles
+EXTRAINCDIR += ${P9_PROCEDURES_PATH}/hwp/memory
+EXTRAINCDIR += ${P9_PROCEDURES_PATH}/hwp/memory/lib
+EXTRAINCDIR += ${P9_PROCEDURES_PATH}/hwp/memory/lib/utils
+EXTRAINCDIR += ${P9_PROCEDURES_PATH}/hwp/memory/lib/mc/
+EXTRAINCDIR += ${P9_PROCEDURES_PATH}/hwp/memory/lib/fir/
+EXTRAINCDIR += ${P9_PROCEDURES_PATH}/hwp/perv
+EXTRAINCDIR += ${P9_PROCEDURES_PATH}/hwp/nest
+EXTRAINCDIR += ${P9_PROCEDURES_PATH}/hwp/initfiles
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/centaur/common/include/
EXTRAINCDIR += ${ROOTPATH}/src/import/
EXTRAINCDIR += ${ROOTPATH}/
@@ -60,7 +61,13 @@ EXTRAINCDIR += ${CEN_PROCEDURES_PATH}/hwp/memory/lib/utils/
EXTRAINCDIR += ${CEN_PROCEDURES_PATH}/hwp/initfiles
EXTRAINCDIR += ${EXP_PROCEDURES_PATH}/hwp/memory/
EXTRAINCDIR += ${OCMB_PROCEDURES_PATH}/hwp/initfiles/
-
+EXTRAINCDIR += ${EXP_INCLUDE_PATH}/
+EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/
+EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/chips/ocmb/explorer/procedures/hwp/memory/lib/
+EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/generic/memory/lib/
+EXTRAINCDIR += ${GEM_PROCEDURES_PATH}/hwp/memory
+EXTRAINCDIR += ${GEM_PROCEDURES_PATH}/hwp/memory/lib/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils
# from src/usr/isteps/istep13
OBJS += call_host_disable_memvolt.o
@@ -81,61 +88,63 @@ OBJS += call_mss_draminit_mc.o
include ${ROOTPATH}/procedure.rules.mk
# PLL HWPs
-include ${PROCEDURES_PATH}/hwp/perv/p9_mem_pll_initf.mk
-include ${PROCEDURES_PATH}/hwp/perv/p9_mem_pll_setup.mk
-include ${PROCEDURES_PATH}/hwp/perv/p9_mem_pll_reset.mk
+include ${P9_PROCEDURES_PATH}/hwp/perv/p9_mem_pll_initf.mk
+include ${P9_PROCEDURES_PATH}/hwp/perv/p9_mem_pll_setup.mk
+include ${P9_PROCEDURES_PATH}/hwp/perv/p9_mem_pll_reset.mk
#Start Memclocks
-include ${PROCEDURES_PATH}/hwp/perv/p9_mem_startclocks.mk
+include ${P9_PROCEDURES_PATH}/hwp/perv/p9_mem_startclocks.mk
#Scom init
-include ${PROCEDURES_PATH}/hwp/memory/p9_mss_scominit.mk
-include ${PROCEDURES_PATH}/hwp/nest/p9_throttle_sync.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_scominit.mk
+include ${P9_PROCEDURES_PATH}/hwp/memory/p9_mss_scominit.mk
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_scominit.o)
-include ${PROCEDURES_PATH}/hwp/initfiles/p9n_ddrphy_scom.mk
-include ${PROCEDURES_PATH}/hwp/initfiles/p9n_mca_scom.mk
-include ${PROCEDURES_PATH}/hwp/initfiles/p9n_mcbist_scom.mk
+include ${P9_PROCEDURES_PATH}/hwp/initfiles/p9n_ddrphy_scom.mk
+include ${P9_PROCEDURES_PATH}/hwp/initfiles/p9n_mca_scom.mk
+include ${P9_PROCEDURES_PATH}/hwp/initfiles/p9n_mcbist_scom.mk
#Dram init
-include ${PROCEDURES_PATH}/hwp/memory/p9_mss_draminit.mk
-include ${PROCEDURES_PATH}/hwp/memory/p9_mss_draminit_training.mk
-include ${PROCEDURES_PATH}/hwp/memory/p9_mss_draminit_mc.mk
-include ${PROCEDURES_PATH}/hwp/memory/p9_mss_ddr_phy_reset.mk
-include ${PROCEDURES_PATH}/hwp/memory/p9_mss_draminit_training_adv.mk
-
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_mcbist.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_mcbist_common.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_mcbist_address.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_generic_shmoo.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_draminit.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_draminit_mc.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_draminit_training.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_ddr_phy_reset.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_draminit_training_advanced.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_mrs6_DDR4.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_ddr4_pda.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_ddr4_funcs.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_termination_control.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_access_delay_reg.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_unmask_errors.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_dimmBadDqBitmapFuncs.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_funcs.mk
-include ${CEN_PROCEDURES_PATH}/hwp/initfiles/centaur_mbs_scom.mk
-include ${CEN_PROCEDURES_PATH}/hwp/initfiles/centaur_mba_scom.mk
-include ${CEN_PROCEDURES_PATH}/hwp/initfiles/centaur_ddrphy_scom.mk
-include ${CEN_PROCEDURES_PATH}/hwp/memory/p9c_mss_row_repair.mk
+include ${P9_PROCEDURES_PATH}/hwp/memory/p9_mss_draminit.mk
+include ${P9_PROCEDURES_PATH}/hwp/memory/p9_mss_draminit_training.mk
+include ${P9_PROCEDURES_PATH}/hwp/memory/p9_mss_draminit_mc.mk
+include ${P9_PROCEDURES_PATH}/hwp/memory/p9_mss_ddr_phy_reset.mk
+include ${P9_PROCEDURES_PATH}/hwp/memory/p9_mss_draminit_training_adv.mk
+
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_mcbist.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_mcbist_common.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_mcbist_address.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_generic_shmoo.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_draminit.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_draminit_mc.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_draminit_training.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_ddr_phy_reset.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_draminit_training_advanced.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_mrs6_DDR4.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_ddr4_pda.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_ddr4_funcs.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_termination_control.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_access_delay_reg.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_unmask_errors.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_dimmBadDqBitmapFuncs.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_funcs.o)
+OBJS += $(if $(CONFIG_AXONE),,centaur_mbs_scom.o)
+OBJS += $(if $(CONFIG_AXONE),,centaur_mba_scom.o)
+OBJS += $(if $(CONFIG_AXONE),,centaur_ddrphy_scom.o)
+OBJS += $(if $(CONFIG_AXONE),,p9c_mss_row_repair.o)
OBJS += $(if $(CONFIG_AXONE),exp_scominit.o,)
OBJS += $(if $(CONFIG_AXONE),explorer_scom.o,)
+OBJS += $(if $(CONFIG_AXONE),exp_draminit_mc.o,)
+OBJS += $(if $(CONFIG_AXONE),exp_draminit.o,)
+OBJS += $(if $(CONFIG_AXONE),gem_draminit.o,)
include ${ROOTPATH}/config.mk
-VPATH += ${PROCEDURES_PATH}/hwp/memory ${PROCEDURES_PATH}/hwp/nest ${PROCEDURES_PATH}/hwp/perv ${PROCEDURES_PATH}/hwp/initfiles/
-VPATH += ${PROCEDURES_PATH}/hwp/memory/lib/ccs/ ${PROCEDURES_PATH}/hwp/memory/lib/dimm/ ${PROCEDURES_PATH}/hwp/memory/lib/utils/ ${PROCEDURES_PATH}/hwp/memory/lib/phy/
-VPATH += ${PROCEDURES_PATH}/hwp/memory/lib/mc/
-VPATH += ${PROCEDURES_PATH}/hwp/memory/lib/fir/
-VPATH += ${PROCEDURES_PATH}/hwp/memory/lib/dimm/ddr4/
+VPATH += ${P9_PROCEDURES_PATH}/hwp/memory ${P9_PROCEDURES_PATH}/hwp/nest ${P9_PROCEDURES_PATH}/hwp/perv ${P9_PROCEDURES_PATH}/hwp/initfiles/
+VPATH += ${P9_PROCEDURES_PATH}/hwp/memory/lib/ccs/ ${P9_PROCEDURES_PATH}/hwp/memory/lib/dimm/ ${P9_PROCEDURES_PATH}/hwp/memory/lib/utils/ ${P9_PROCEDURES_PATH}/hwp/memory/lib/phy/
+VPATH += ${P9_PROCEDURES_PATH}/hwp/memory/lib/mc/
+VPATH += ${P9_PROCEDURES_PATH}/hwp/memory/lib/fir/
+VPATH += ${P9_PROCEDURES_PATH}/hwp/memory/lib/dimm/ddr4/
VPATH += ${CEN_PROCEDURES_PATH}
VPATH += ${CEN_PROCEDURES_PATH}/hwp/memory/
VPATH += ${CEN_PROCEDURES_PATH}/hwp/memory/lib/
@@ -144,4 +153,5 @@ VPATH += ${CEN_PROCEDURES_PATH}/hwp/memory/lib/utils/
VPATH += ${CEN_PROCEDURES_PATH}/hwp/initfiles
VPATH += $(if $(CONFIG_AXONE),${EXP_PROCEDURES_PATH}/hwp/memory,)
+VPATH += $(if $(CONFIG_AXONE),${GEM_PROCEDURES_PATH}/hwp/memory,)
VPATH += $(if $(CONFIG_AXONE),${OCMB_PROCEDURES_PATH}/hwp/initfiles/,)
diff --git a/src/usr/isteps/istep14/call_host_mpipl_service.C b/src/usr/isteps/istep14/call_host_mpipl_service.C
index d8bdaa5af..bab3ace62 100644
--- a/src/usr/isteps/istep14/call_host_mpipl_service.C
+++ b/src/usr/isteps/istep14/call_host_mpipl_service.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -44,7 +44,6 @@
#include <vfs/vfs.H>
#include <dump/dumpif.H>
-#include <config.h>
#ifdef CONFIG_DRTM
#include <secureboot/drtm.H>
@@ -158,10 +157,10 @@ void* call_host_mpipl_service (void *io_pArgs)
do
{
- // In non-FSP based system SBE collects architected register
+ // In OPAL based system SBE collects architected register
// data. Copy architected register data from Reserved Memory
// to hypervisor memory.
- if ( !INITSERVICE::spBaseServicesEnabled() )
+ if( TARGETING::is_sapphire_load() )
{
l_err = DUMP::copyArchitectedRegs();
if (l_err)
diff --git a/src/usr/isteps/istep14/call_mss_memdiag.C b/src/usr/isteps/istep14/call_mss_memdiag.C
index 38736d2c7..4c4c6b5b2 100644
--- a/src/usr/isteps/istep14/call_mss_memdiag.C
+++ b/src/usr/isteps/istep14/call_mss_memdiag.C
@@ -33,14 +33,21 @@
#include <util/misc.H>
#include <plat_hwp_invoker.H> // for FAPI_INVOKE_HWP
-#include <lib/shared/nimbus_defaults.H> // Needed before memdiags_fir.H
-#include <lib/fir/memdiags_fir.H> // for mss::unmask::after_memdiags
+#include <lib/shared/nimbus_defaults.H> // Needed before unmask.H
+#include <lib/fir/unmask.H> // for mss::unmask::after_memdiags
#include <lib/mc/port.H> // for mss::reset_reorder_queue_settings
#if defined(CONFIG_IPLTIME_CHECKSTOP_ANALYSIS) && !defined(__HOSTBOOT_RUNTIME)
#include <isteps/pm/occCheckstop.H>
#endif
+// TODO RTC:245219
+// use PRD's version of memdiags instead of this cronus verison once its working
+#ifdef CONFIG_AXONE
+#include <exp_mss_memdiag.H>
+#include <chipids.H> // for EXPLORER ID
+#endif
+
using namespace ISTEP;
using namespace ISTEP_ERROR;
using namespace ERRORLOG;
@@ -161,6 +168,37 @@ void* call_mss_memdiag (void* io_pArgs)
// No need to unmask or turn off FIFO. That is already contained
// within the other Centaur HWPs.
}
+#ifdef CONFIG_AXONE
+ else if (MODEL_AXONE == procType )
+ {
+ // no need to run in simics
+ if ( Util::isSimicsRunning() == false )
+ {
+ // TODO RTC:245219
+ // use PRD's version of memdiags instead of this cronus verison once its working
+ TargetHandleList trgtList; getAllChips( trgtList, TYPE_OCMB_CHIP );
+ for (const auto & l_ocmb_target : trgtList)
+ {
+ uint32_t chipId = l_ocmb_target->getAttr< TARGETING::ATTR_CHIP_ID>();
+ // Only call memdiags on Explorer cards, it breaks when you run on Gemini
+ if (chipId == POWER_CHIPID::EXPLORER_16)
+ {
+ fapi2::Target <fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target(l_ocmb_target);
+ // Start Memory Diagnostics.
+ FAPI_INVOKE_HWP( errl, exp_mss_memdiag, l_fapi_ocmb_target );
+ if ( nullptr != errl )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "exp_mss_memdiag (0x%08x) "
+ "failed", get_huid(l_ocmb_target) );
+ break;
+ }
+ }
+ }
+ }
+
+ }
+#endif
} while (0);
diff --git a/src/usr/isteps/istep14/call_mss_power_cleanup.C b/src/usr/isteps/istep14/call_mss_power_cleanup.C
index 3ca963678..524d2a536 100644
--- a/src/usr/isteps/istep14/call_mss_power_cleanup.C
+++ b/src/usr/isteps/istep14/call_mss_power_cleanup.C
@@ -129,9 +129,10 @@ void* call_mss_power_cleanup (void *io_pArgs)
}
}
- // Run the nvdimm management function if the list is not empty
+ // Run the nvdimm management functions if the list is not empty
if (!l_nvdimmTargetList.empty()){
NVDIMM::nvdimm_restore(l_nvdimmTargetList);
+ NVDIMM::nvdimm_encrypt_enable(l_nvdimmTargetList);
}
}
#endif
diff --git a/src/usr/isteps/istep14/call_mss_thermal_init.C b/src/usr/isteps/istep14/call_mss_thermal_init.C
index 8e00df762..c11731e1d 100644
--- a/src/usr/isteps/istep14/call_mss_thermal_init.C
+++ b/src/usr/isteps/istep14/call_mss_thermal_init.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,10 +37,16 @@
#include <config.h>
#include <fapi2.H>
#include <fapi2/plat_hwp_invoker.H>
-#include <p9c_mss_thermal_init.H>
-#include <p9_mss_thermal_init.H>
-#include <p9_throttle_sync.H>
+#ifdef CONFIG_AXONE
+ #include <exp_mss_thermal_init.H>
+ #include <chipids.H> // for EXPLORER ID
+ #include <p9a_throttle_sync.H>
+#else
+ #include <p9c_mss_thermal_init.H>
+ #include <p9_mss_thermal_init.H>
+ #include <p9_throttle_sync.H>
+#endif
using namespace ISTEP;
using namespace ISTEP_ERROR;
@@ -49,43 +55,79 @@ using namespace TARGETING;
namespace ISTEP_14
{
+void nimbus_call_mss_thermal_init(IStepError & io_istepError);
+void cumulus_call_mss_thermal_init(IStepError & io_istepError);
+void axone_call_mss_thermal_init(IStepError & io_istepError);
+void run_proc_throttle_sync(IStepError & io_istepError);
+
void* call_mss_thermal_init (void *io_pArgs)
{
IStepError l_StepError;
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_thermal_init entry");
+
+ auto l_procModel = TARGETING::targetService().getProcessorModel();
+ switch (l_procModel)
+ {
+ case TARGETING::MODEL_CUMULUS:
+ cumulus_call_mss_thermal_init(l_StepError);
+ break;
+ case TARGETING::MODEL_AXONE:
+ axone_call_mss_thermal_init(l_StepError);
+ break;
+ case TARGETING::MODEL_NIMBUS:
+ nimbus_call_mss_thermal_init(l_StepError);
+ break;
+ default:
+ assert(0, "call_mss_thermal_init: Unsupported model type 0x%04X",
+ l_procModel);
+ break;
+ }
+
+ // This should run whether or not mss_thermal_init worked
+ run_proc_throttle_sync(l_StepError);
+
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_thermal_init exit");
+
+ // end task, returning any errorlogs to IStepDisp
+ return l_StepError.getErrorHandle();
+}
+
+#ifndef CONFIG_AXONE
+void nimbus_call_mss_thermal_init(IStepError & io_istepError)
+{
errlHndl_t l_errl = nullptr;
- // -- Cumulus only ---
- // Get all Centaur targets
- TARGETING::TargetHandleList l_memBufTargetList;
- getAllChips(l_memBufTargetList, TYPE_MEMBUF);
+ // -- Nimbus only ---
+ // Get all MCS targets
+ TARGETING::TargetHandleList l_mcsTargetList;
+ getAllChiplets(l_mcsTargetList, TYPE_MCS);
// --------------------------------------------------------------------
- // run mss_thermal_init on all functional Centaur chips
+ // run mss_thermal_init on all functional MCS chiplets
// --------------------------------------------------------------------
- for (auto l_pCentaur : l_memBufTargetList)
+ for (const auto & l_pMcs : l_mcsTargetList)
{
- fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP> l_fapi_pCentaur
- (l_pCentaur);
+ fapi2::Target<fapi2::TARGET_TYPE_MCS> l_fapi_pMcs(l_pMcs);
// Current run on target
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "Running call_mss_thermal_init HWP on "
- "target HUID %.8X", TARGETING::get_huid(l_pCentaur));
+ "Running p9_mss_thermal_init HWP on target HUID %.8X",
+ TARGETING::get_huid(l_pMcs) );
- FAPI_INVOKE_HWP( l_errl, p9c_mss_thermal_init, l_fapi_pCentaur );
+ FAPI_INVOKE_HWP( l_errl, p9_mss_thermal_init, l_fapi_pMcs );
if ( l_errl )
{
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: p9c_mss_thermal_init HWP returns error",
+ "ERROR 0x%.8X: p9_mss_thermal_init HWP returns error",
l_errl->reasonCode());
// capture the target data in the elog
- ErrlUserDetailsTarget(l_pCentaur).addToLog( l_errl );
+ ErrlUserDetailsTarget(l_pMcs).addToLog( l_errl );
// Create IStep error log and cross reference
// to error that occurred
- l_StepError.addErrorDetails( l_errl );
+ io_istepError.addErrorDetails( l_errl );
// Commit Error
errlCommit( l_errl, HWPF_COMP_ID );
@@ -94,43 +136,50 @@ void* call_mss_thermal_init (void *io_pArgs)
}
else
{
- TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : p9c_mss_thermal_init HWP( )" );
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : p9_mss_thermal_init HWP() on 0x%.8X MCS",
+ TARGETING::get_huid(l_pMcs) );
}
- }
+ } // end MCS loop
- // -- Nimbus only ---
- // Get all MCS targets
- TARGETING::TargetHandleList l_mcsTargetList;
- getAllChiplets(l_mcsTargetList, TYPE_MCS);
+}
+
+void cumulus_call_mss_thermal_init(IStepError & io_istepError)
+{
+ errlHndl_t l_errl = nullptr;
+
+ // -- Cumulus only ---
+ // Get all Centaur targets
+ TARGETING::TargetHandleList l_memBufTargetList;
+ getAllChips(l_memBufTargetList, TYPE_MEMBUF);
// --------------------------------------------------------------------
- // run mss_thermal_init on all functional MCS chiplets
+ // run mss_thermal_init on all functional Centaur chips
// --------------------------------------------------------------------
- for (auto l_pMcs : l_mcsTargetList)
+ for (const auto & l_pCentaur : l_memBufTargetList)
{
- fapi2::Target<fapi2::TARGET_TYPE_MCS> l_fapi_pMcs
- (l_pMcs);
+ fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP> l_fapi_pCentaur
+ (l_pCentaur);
// Current run on target
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "Running call_mss_thermal_init HWP on "
- "target HUID %.8X", TARGETING::get_huid(l_pMcs));
+ "Running p9c_mss_thermal_init HWP on target HUID %.8X",
+ TARGETING::get_huid(l_pCentaur) );
- FAPI_INVOKE_HWP( l_errl, p9_mss_thermal_init, l_fapi_pMcs );
+ FAPI_INVOKE_HWP( l_errl, p9c_mss_thermal_init, l_fapi_pCentaur );
if ( l_errl )
{
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: p9_mss_thermal_init HWP returns error",
+ "ERROR 0x%.8X: p9c_mss_thermal_init HWP returns error",
l_errl->reasonCode());
// capture the target data in the elog
- ErrlUserDetailsTarget(l_pMcs).addToLog( l_errl );
+ ErrlUserDetailsTarget(l_pCentaur).addToLog( l_errl );
// Create IStep error log and cross reference
// to error that occurred
- l_StepError.addErrorDetails( l_errl );
+ io_istepError.addErrorDetails( l_errl );
// Commit Error
errlCommit( l_errl, HWPF_COMP_ID );
@@ -139,70 +188,153 @@ void* call_mss_thermal_init (void *io_pArgs)
}
else
{
- TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : p9_mss_thermal_init HWP( )" );
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : p9c_mss_thermal_init HWP( ) on 0x%.8X target",
+ TARGETING::get_huid(l_pCentaur) );
}
- }
+ } // end MEMBUF loop
+}
+#else
+void nimbus_call_mss_thermal_init(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'p9_mss_thermal_init' but Nimbus code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
- do
+void cumulus_call_mss_thermal_init(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'p9c_mss_thermal_init' but Cumulus code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
+#endif
+
+#ifdef CONFIG_AXONE
+void axone_call_mss_thermal_init(IStepError & io_istepError)
+{
+ errlHndl_t l_err = nullptr;
+
+ // Get all OCMB targets
+ TARGETING::TargetHandleList l_ocmbTargetList;
+ getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP);
+
+ for (const auto & l_ocmb_target : l_ocmbTargetList)
{
- // Run proc throttle sync
- // Get all functional proc chip targets
- //Use targeting code to get a list of all processors
- TARGETING::TargetHandleList l_procChips;
- getAllChips( l_procChips, TARGETING::TYPE_PROC );
+ // check EXPLORER first as this is most likely the configuration
+ uint32_t chipId = l_ocmb_target->getAttr< TARGETING::ATTR_CHIP_ID>();
+ if (chipId == POWER_CHIPID::EXPLORER_16)
+ {
+ fapi2::Target <fapi2::TARGET_TYPE_OCMB_CHIP> l_fapi_ocmb_target
+ (l_ocmb_target);
+
+ // Dump current run on target
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Running exp_mss_thermal_init HWP on target HUID %.8X",
+ TARGETING::get_huid(l_ocmb_target));
- for (const auto & l_procChip: l_procChips)
+ // call the HWP with each fapi2::Target
+ FAPI_INVOKE_HWP(l_err, exp_mss_thermal_init, l_fapi_ocmb_target);
+ }
+ else
{
- //Convert the TARGETING::Target into a fapi2::Target by passing
- //l_procChip into the fapi2::Target constructor
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
- l_fapi2CpuTarget((l_procChip));
+ // Gemini, NOOP
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Skipping thermal_init HWP on axone target HUID 0x%.8X, chipId 0x%.4X",
+ TARGETING::get_huid(l_ocmb_target), chipId );
+ }
+
+ if (l_err)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: exp_mss_thermal_init HWP returns error",
+ l_err->reasonCode());
+ // capture the target data in the elog
+ ErrlUserDetailsTarget(l_ocmb_target).addToLog(l_err);
+
+ // Create IStep error log and cross reference to error that
+ // occurred
+ io_istepError.addErrorDetails( l_err );
+
+ // Commit Error
+ errlCommit( l_err, HWPF_COMP_ID );
+
+ break;
+ }
+ else if (chipId == POWER_CHIPID::EXPLORER_16)
+ {
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "Running p9_throttle_sync HWP on "
- "target HUID %.8X", TARGETING::get_huid(l_procChip));
-
- // Call p9_throttle_sync
- FAPI_INVOKE_HWP( l_errl, p9_throttle_sync, l_fapi2CpuTarget );
-
- if (l_errl)
- {
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: p9_throttle_sync HWP returns error",
- l_errl->reasonCode());
-
- // Capture the target data in the elog
- ErrlUserDetailsTarget(l_procChip).addToLog(l_errl);
-
- // Create IStep error log and cross reference
- // to error that occurred
- l_StepError.addErrorDetails( l_errl );
-
- // Commit Error
- errlCommit( l_errl, HWPF_COMP_ID );
-
- break;
- }
- else
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : p9_throttle_sync HWP( )" );
- }
+ "SUCCESS running exp_mss_thermal_init HWP on target HUID %.8X",
+ TARGETING::get_huid(l_ocmb_target));
}
+ } // end OCMB loop
+}
+#else
+void axone_call_mss_thermal_init(IStepError & io_istepError)
+{
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error: Trying to call 'exp_mss_thermal_init' but Axone code is not compiled in");
+ assert(0, "Calling wrong Model's HWPs");
+}
+#endif
- } while (0);
+void run_proc_throttle_sync(IStepError & io_istepError)
+{
+ errlHndl_t l_errl = nullptr;
+
+ // Run proc throttle sync
+ // Get all functional proc chip targets
+ // Use targeting code to get a list of all processors
+ TARGETING::TargetHandleList l_procChips;
+ getAllChips( l_procChips, TARGETING::TYPE_PROC );
- if(l_StepError.isNull())
+ for (const auto & l_procChip: l_procChips)
{
+ //Convert the TARGETING::Target into a fapi2::Target by passing
+ //l_procChip into the fapi2::Target constructor
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
+ l_fapi2CpuTarget((l_procChip));
+
+ // Call p9_throttle_sync
+#ifndef CONFIG_AXONE
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : call_mss_thermal_init" );
- }
+ "Running p9_throttle_sync HWP on target HUID %.8X",
+ TARGETING::get_huid(l_procChip) );
+ FAPI_INVOKE_HWP( l_errl, p9_throttle_sync, l_fapi2CpuTarget );
+#else
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Running p9a_throttle_sync HWP on target HUID %.8X",
+ TARGETING::get_huid(l_procChip) );
+ FAPI_INVOKE_HWP( l_errl, p9a_throttle_sync, l_fapi2CpuTarget );
+#endif
+ if (l_errl)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: p9_throttle_sync HWP returns error",
+ l_errl->reasonCode());
- // end task, returning any errorlogs to IStepDisp
- return l_StepError.getErrorHandle();
+ // Capture the target data in the elog
+ ErrlUserDetailsTarget(l_procChip).addToLog(l_errl);
+
+ // Create IStep error log and cross reference
+ // to error that occurred
+ io_istepError.addErrorDetails( l_errl );
+
+ // Commit Error
+ errlCommit( l_errl, HWPF_COMP_ID );
+
+ break;
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : p9_throttle_sync HWP on 0x%.8X processor",
+ TARGETING::get_huid(l_procChip) );
+ }
+ }
}
};
diff --git a/src/usr/isteps/istep14/call_proc_exit_cache_contained.C b/src/usr/isteps/istep14/call_proc_exit_cache_contained.C
index 897bb58ac..b118401f6 100644
--- a/src/usr/isteps/istep14/call_proc_exit_cache_contained.C
+++ b/src/usr/isteps/istep14/call_proc_exit_cache_contained.C
@@ -47,7 +47,6 @@
#include <arch/pirformat.H>
#include <isteps/hwpf_reasoncodes.H>
#include <devicefw/userif.H>
-#include <config.h>
#include <util/misc.H>
#include <hwas/common/hwas.H>
#include <sys/misc.h>
@@ -81,7 +80,7 @@ void* call_proc_exit_cache_contained (void *io_pArgs)
"call_proc_exit_cache_contained entry" );
errlHndl_t l_errl = nullptr;
-#ifdef CONFIG_SECUREBOOT
+#if (defined CONFIG_SECUREBOOT && ! defined CONFIG_AXONE)
if(SECUREBOOT::enabled())
{
SECUREBOOT::CENTAUR_SECURITY::ScomCache& centaurCache =
@@ -537,7 +536,7 @@ void* call_proc_exit_cache_contained (void *io_pArgs)
errlCommit( l_errl, HWPF_COMP_ID );
}
-#ifdef CONFIG_SECUREBOOT
+#if (defined CONFIG_SECUREBOOT && ! defined CONFIG_AXONE)
// Unload the MEMD section that was loaded at the beginning of step11
l_errl = unloadSecureSection(PNOR::MEMD);
if (l_errl)
diff --git a/src/usr/isteps/istep14/call_proc_setup_bars.C b/src/usr/isteps/istep14/call_proc_setup_bars.C
index 25ed067d2..9cb0f402a 100644
--- a/src/usr/isteps/istep14/call_proc_setup_bars.C
+++ b/src/usr/isteps/istep14/call_proc_setup_bars.C
@@ -22,7 +22,6 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-#include <config.h>
#include <errl/errlentry.H>
#include <isteps/hwpisteperror.H>
#include <initservice/isteps_trace.H>
diff --git a/src/usr/isteps/istep14/makefile b/src/usr/isteps/istep14/makefile
index 47c6c15e6..9aaa19c97 100644
--- a/src/usr/isteps/istep14/makefile
+++ b/src/usr/isteps/istep14/makefile
@@ -26,18 +26,22 @@ ROOTPATH = ../../../..
MODULE = istep14
PROCEDURE_PATH = ${ROOTPATH}/src/import/chips/p9/procedures
+AXONE_PROCEDURE_PATH = ${ROOTPATH}/src/import/chips/p9a/procedures
CEN_PROC_PATH = ${ROOTPATH}/src/import/chips/centaur/procedures
EXP_COMMON_PATH = ${ROOTPATH}/src/import/chips/ocmb/explorer/common
+EXPLORER_HWP_PATH = ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
#Add all the extra include paths
EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/
+EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/generic/memory/lib
+EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/chips/ocmb/explorer/procedures/hwp/memory/lib/
+EXTRAINCDIR += ${ROOTPATH}/src/import/
EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/imageProcs
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs
EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/nest
-EXTRAINCDIR += ${ROOTPATH}/src/import/
EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/include/
EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory/lib/eff_config/
@@ -50,6 +54,9 @@ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/centaur/common/include/
EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory/lib/dimm/ddr4/
EXTRAINCDIR += ${EXP_COMMON_PATH}/include/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils
+EXTRAINCDIR += ${AXONE_PROCEDURE_PATH}/hwp/memory/
+EXTRAINCDIR += ${EXPLORER_HWP_PATH}
OBJS += call_mss_memdiag.o
OBJS += call_mss_thermal_init.o
@@ -92,14 +99,24 @@ OBJS += p9_revert_sbe_mcs_setup.o
# include ${PROCEDURE_PATH}/hwp/memory/p9_mss_thermal_init.mk
# include ${CEN_PROC_PATH}/hwp/memory/p9c_mss_thermal_init.mk
# include ${CEN_PROC_PATH}/hwp/memory/p9c_mss_unmask_errors.mk
-include ${PROCEDURE_PATH}/hwp/nest/p9_throttle_sync.mk
+
include ${PROCEDURE_PATH}/hwp/memory/p9_mss_power_cleanup.mk
-include ${ROOTPATH}/config.mk
-VPATH += ${PROCEDURE_PATH}/hwp/nest/ ${PROCEDURE_PATH}/hwp/memory/
+VPATH += ${PROCEDURE_PATH}/hwp/nest/
+VPATH += ${PROCEDURE_PATH}/hwp/memory/
VPATH += ${PROCEDURE_PATH}/hwp/memory/lib/eff_config/
VPATH += ${PROCEDURE_PATH}/hwp/memory/lib/utils/
VPATH += ${PROCEDURE_PATH}/hwp/memory/lib/mcbist/
VPATH += ${PROCEDURE_PATH}/hwp/memory/lib/dimm/
VPATH += ${CEN_PROC_PATH}/hwp/memory/
VPATH += ${PROCEDURE_PATH}/hwp/memory/lib/dimm/ddr4/
+
+# Axone vs non-Axone specific HWP
+VPATH += $(if $(CONFIG_AXONE),${EXPLORER_HWP_PATH},)
+OBJS += $(if $(CONFIG_AXONE),exp_mss_thermal_init.o,)
+# TODO RTC:245219
+# use PRD's version of memdiags instead of this cronus verison once its working
+OBJS += $(if $(CONFIG_AXONE),exp_mss_memdiag.o,)
+
+include ${ROOTPATH}/config.mk
+
diff --git a/src/usr/isteps/istep15/host_build_stop_image.C b/src/usr/isteps/istep15/host_build_stop_image.C
index 26e3677f4..6bc755314 100644
--- a/src/usr/isteps/istep15/host_build_stop_image.C
+++ b/src/usr/isteps/istep15/host_build_stop_image.C
@@ -445,7 +445,17 @@ void* host_build_stop_image (void *io_pArgs)
//If running Sapphire need to place this at the top of memory instead
if(is_sapphire_load())
{
- l_memBase = get_top_homer_mem_addr();
+ //Because the way P9N/P9C are init'ed for backwards HB / SBE
+ //compatibility (SMF never enabled -- thus unsecure homer to
+ //secure homer sc2 (system call to Ultravisor) doesn't work) during
+ //istep 15 need to "trick" hostboot into placing HOMER into normal
+ //memory @HRMOR (instead of secure SMF memory). When HB goes
+ //through istep 16 it will enter UV mode if SMF is enabled, and then
+ //when PM complex is restarted in istep 21, HOMER is moved to right
+ //spot. No movement of HOME oocurs in non-SMF mode; HOMER lands in
+ //non-secure memory.
+
+ l_memBase = get_top_mem_addr();
assert (l_memBase != 0,
"host_build_stop_image: Top of memory was 0!");
@@ -502,9 +512,6 @@ void* host_build_stop_image (void *io_pArgs)
"Found %d functional procs in system",
l_procChips.size() );
- auto l_unsecureHomerSize =
- l_sys->getAttr<TARGETING::ATTR_UNSECURE_HOMER_SIZE>();
-
for (const auto & l_procChip: l_procChips)
{
do {
@@ -563,22 +570,12 @@ void* host_build_stop_image (void *io_pArgs)
break;
}
- if(SECUREBOOT::SMF::isSmfEnabled())
- {
- // In SMF mode, unsecure HOMER goes to the top of unsecure
- // memory (2MB aligned); we need to subtract the size of the
- // unsecure HOMER and align the resulting address to arrive
- // at the correct location.
- uint64_t l_unsecureHomerAddr = ALIGN_DOWN_X(
- ISTEP::get_top_mem_addr()
- - MAX_UNSECURE_HOMER_SIZE,
- 2 * MEGABYTE);
- l_procChip->setAttr<TARGETING::ATTR_UNSECURE_HOMER_ADDRESS>
- (l_unsecureHomerAddr);
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "host_build_stop_image: unsecure HOMER addr = 0x%.16llX",
- l_unsecureHomerAddr);
- }
+ //Set unsecure HOMER address to real HOMER, as this
+ //will allow SMF inits to become active (results in
+ //URMOR == HRMOR in non SMF memory). The processor self-restore
+ //code is 2MB into HOMER, so point the unsecure HOMER there.
+ l_procChip->setAttr<TARGETING::ATTR_UNSECURE_HOMER_ADDRESS>
+ (l_procRealMemAddr + (2 * MEGABYTE));
//Call p9_hcode_image_build.C HWP
FAPI_INVOKE_HWP( l_errl,
@@ -608,58 +605,6 @@ void* host_build_stop_image (void *io_pArgs)
break;
}
- // We now need to copy the data that was put in l_temp_buffer2
- // by the p9_hcode_image_build procedure into the unsecure
- // HOMER memory
- if(SECUREBOOT::SMF::isSmfEnabled())
- {
- auto l_unsecureHomerAddr = l_procChip->
- getAttr<TARGETING::ATTR_UNSECURE_HOMER_ADDRESS>();
-
-
- assert(l_unsecureHomerSize <= MAX_RING_BUF_SIZE,
- "host_build_stop_image: unsecure HOMER is bigger than the output buffer");
- assert(l_unsecureHomerSize <= MAX_UNSECURE_HOMER_SIZE,
- "host_build_stop_image: the size of unsecure HOMER is more than 0x%x", MAX_UNSECURE_HOMER_SIZE);
- assert(l_unsecureHomerAddr,
- "host_build_stop_image: the unsecure HOMER addr is 0");
-
- void* l_unsecureHomerVAddr = mm_block_map(
- reinterpret_cast<void*>(l_unsecureHomerAddr),
- l_unsecureHomerSize);
- assert(l_unsecureHomerVAddr,
- "host_build_stop_image: could not map unsecure HOMER phys addr");
- memcpy(l_unsecureHomerVAddr,
- l_temp_buffer2,
- l_unsecureHomerSize);
- int l_rc = mm_block_unmap(l_unsecureHomerVAddr);
- if(l_rc)
- {
- /*@
- * @errortype
- * @reasoncode ISTEP::RC_MM_UNMAP_FAILED
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid ISTEP::MOD_BUILD_HCODE_IMAGES
- * @userdata1 Unsecure HOMER addr
- * @userdata2 RC from mm_block_unmap
- * @devdesc Could not unmap unsecure HOMER's virtual
- * address
- * @custdesc A problem occurred during the IPL of the
- * system
- */
- l_errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- ISTEP::MOD_BUILD_HCODE_IMAGES,
- ISTEP::RC_MM_UNMAP_FAILED,
- reinterpret_cast<uint64_t>(
- l_unsecureHomerVAddr),
- l_rc,
- ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
- l_errl->collectTrace(ISTEP_COMP_NAME);
- break;
- }
- }
-
l_errl = applyHcodeGenCpuRegs( l_procChip,
l_pImageOut,
l_sizeImageOut );
diff --git a/src/usr/isteps/istep15/host_establish_ex_chiplet.C b/src/usr/isteps/istep15/host_establish_ex_chiplet.C
index be5640167..1d89bfa80 100644
--- a/src/usr/isteps/istep15/host_establish_ex_chiplet.C
+++ b/src/usr/isteps/istep15/host_establish_ex_chiplet.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -53,7 +53,6 @@ void* host_establish_ex_chiplet (void *io_pArgs)
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_establish_ex_chiplet entry" );
ISTEP_ERROR::IStepError l_StepError;
- #ifndef CONFIG_AXONE_BRING_UP
errlHndl_t l_errl = NULL;
do {
//Use targeting code to get a list of all processors
@@ -64,6 +63,7 @@ void* host_establish_ex_chiplet (void *io_pArgs)
{
const fapi2::Target<TARGET_TYPE_PROC_CHIP>
l_fapi_cpu_target(l_procChip);
+
// call p9_update_ec_eq_state.C HWP
FAPI_INVOKE_HWP( l_errl,
p9_update_ec_eq_state,
@@ -78,7 +78,6 @@ void* host_establish_ex_chiplet (void *io_pArgs)
}
}
}while(0);
- #endif
// end task, returning any errorlogs to IStepDisp
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_establish_ex_chiplet exit" );
diff --git a/src/usr/isteps/istep15/host_start_stop_engine.C b/src/usr/isteps/istep15/host_start_stop_engine.C
index 27580947d..b89804fe3 100644
--- a/src/usr/isteps/istep15/host_start_stop_engine.C
+++ b/src/usr/isteps/istep15/host_start_stop_engine.C
@@ -55,7 +55,7 @@ void* host_start_stop_engine (void *io_pArgs)
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_start_stop_engine entry" );
ISTEP_ERROR::IStepError l_StepError;
- errlHndl_t l_errl = NULL;
+ errlHndl_t l_errl __attribute__((unused)) = NULL;
// Cast to void just to get around unused var warning if #ifdef's dont work
// out to actually use the l_errl variable
@@ -79,11 +79,9 @@ void* host_start_stop_engine (void *io_pArgs)
}
#endif
-// Skip initializing the PM complex in axone simics for now
-#ifndef CONFIG_AXONE_BRING_UP
//Use targeting code to get a list of all processors
TARGETING::TargetHandleList l_procChips;
- getAllChips( l_procChips, TARGETING::TYPE_PROC );
+ getAllChips( l_procChips, TARGETING::TYPE_PROC );
for (const auto & l_procChip: l_procChips)
{
@@ -92,6 +90,10 @@ void* host_start_stop_engine (void *io_pArgs)
fapi2::Target<TARGET_TYPE_PROC_CHIP>l_fapi2CpuTarget(
(l_procChip));
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Calling p9_pm_stop_gpe_init for 0x%.8X target",
+ TARGETING::get_huid(l_procChip) );
+
//call p9_pm_stop_gpe_init.C HWP
FAPI_INVOKE_HWP(l_errl,
p9_pm_stop_gpe_init,
@@ -105,7 +107,6 @@ void* host_start_stop_engine (void *io_pArgs)
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_start_stop_engine:: failed on proc with HUID : %d",TARGETING::get_huid(l_procChip) );
}
}
-#endif
#ifdef CONFIG_IPLTIME_CHECKSTOP_ANALYSIS
// Starting SGPE in istep15.4 causes OIMR0 register to be improperly
diff --git a/src/usr/isteps/istep15/proc_set_pba_homer_bar.C b/src/usr/isteps/istep15/proc_set_pba_homer_bar.C
index 0173b1a15..5c02af9df 100644
--- a/src/usr/isteps/istep15/proc_set_pba_homer_bar.C
+++ b/src/usr/isteps/istep15/proc_set_pba_homer_bar.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -46,10 +46,17 @@
#include <return_code.H>
#include <p9_pm_set_homer_bar.H>
+#include <secureboot/smf_utils.H>
+#include <secureboot/smf.H>
+#include <isteps/mem_utils.H>
+#include <util/align.H>
+
+
//Namespaces
using namespace ERRORLOG;
using namespace TARGETING;
using namespace fapi2;
+using namespace ISTEP;
namespace ISTEP_15
{
@@ -62,12 +69,56 @@ void* proc_set_pba_homer_bar (void *io_pArgs)
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_proc_set_pba_homer_bar entry" );
ISTEP_ERROR::IStepError l_StepError;
- errlHndl_t l_errl = NULL;
+ errlHndl_t l_errl = nullptr;
TARGETING::TargetHandleList l_procChips;
+ uint64_t l_smfBase = 0x0;
+ uint64_t l_unsecureHomerAddr = get_top_mem_addr();
+
+
+ //Determine top-level system target
+ TARGETING::Target* l_sys = nullptr;
+ TARGETING::targetService().getTopLevelTarget(l_sys);
+ assert(l_sys != nullptr, "Top level target was nullptr!");
+
+ //Because the way P9N/P9C are init'ed for backwards HB / SBE
+ //compatibility (SMF never enabled -- thus unsecure homer to
+ //secure homer sc2 (system call to Ultravisor) doesn't work) during istep 15
+ //need to "trick" hostboot into placing HOMER into normal memory @
+ //HRMOR. When HB goes through istep 16 it will enter UV
+ //mode if SMF is enabled, and then when PM complex is restarted
+ //in istep 21, HOMER is moved to right spot
+ if(SECUREBOOT::SMF::isSmfEnabled())
+ {
+ l_smfBase = get_top_homer_mem_addr();
+ assert(l_smfBase != 0,
+ "proc_set_pba_homer_bar: Top of SMF memory was 0!");
+ if(is_sapphire_load())
+ {
+ l_smfBase -= VMM_ALL_HOMER_OCC_MEMORY_SIZE;
+ // Unsecure HOMER address is used in istep21 to place the
+ // unsecure part of the HOMER image outside of SMF memory.
+ // Unsecure HOMER goes to the top of unsecure
+ // memory (2MB aligned); we need to subtract the size of the
+ // unsecure HOMER and align the resulting address to arrive
+ // at the correct location.
+ l_unsecureHomerAddr = ALIGN_DOWN_X(l_unsecureHomerAddr -
+ MAX_UNSECURE_HOMER_SIZE,
+ 2 * MEGABYTE);
+ }
+ assert(l_unsecureHomerAddr != 0,
+ "proc_set_pba_homer_bar: Unsecure HOMER addr was 0!");
+
+ //Since we have the HOMER location defined, set the
+ // OCC common attribute to be used later by pm code
+ l_sys->setAttr<TARGETING::ATTR_OCC_COMMON_AREA_PHYS_ADDR>
+ (l_smfBase + VMM_HOMER_REGION_SIZE);
+ }
//Use targeting code to get a list of all processors
getAllChips( l_procChips, TARGETING::TYPE_PROC );
+
+
//Loop through all of the procs and call the HWP on each one
for (const auto & l_procChip: l_procChips)
{
@@ -92,6 +143,29 @@ void* proc_set_pba_homer_bar (void *io_pArgs)
l_StepError.addErrorDetails( l_errl );
errlCommit( l_errl, HWPF_COMP_ID );
}
+
+ if(SECUREBOOT::SMF::isSmfEnabled())
+ {
+ //Set correct SMF value used later in istep 21
+ // calculate size and location of the HCODE output buffer
+ uint32_t l_procNum =
+ l_procChip->getAttr<TARGETING::ATTR_POSITION>();
+ uint64_t l_procOffsetAddr = l_procNum * VMM_HOMER_INSTANCE_SIZE;
+
+ l_procChip->setAttr<TARGETING::ATTR_HOMER_PHYS_ADDR>
+ (l_smfBase + l_procOffsetAddr);
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "Update %.8X HOMER from 0x%.16llX to 0x%.16llX for SMF",
+ TARGETING::get_huid(l_procChip), homerAddr,
+ (l_smfBase + l_procOffsetAddr));
+
+ l_procChip->setAttr<TARGETING::ATTR_UNSECURE_HOMER_ADDRESS>
+ (l_unsecureHomerAddr);
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "proc_set_pba_homer_bar: unsecure HOMER addr = 0x%.16llX",
+ l_unsecureHomerAddr);
+ }
+
}
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_proc_set_pba_homer_bar exit" );
diff --git a/src/usr/isteps/istep16/call_host_activate_master.C b/src/usr/isteps/istep16/call_host_activate_master.C
index ecbf78325..63a882886 100644
--- a/src/usr/isteps/istep16/call_host_activate_master.C
+++ b/src/usr/isteps/istep16/call_host_activate_master.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -204,7 +204,8 @@ void* call_host_activate_master (void *io_pArgs)
TARGETING::get_huid(l_proc_target));
//In the future possibly move default "waitTime" value to SBEIO code
- uint64_t waitTime = 1000000; // bump the wait time to 1 sec
+ uint64_t waitTime = 10500; // wait time 10.5 sec, anything larger than 10737 ms can cause
+ // overflow on SBE side of the tiemout calculations
l_errl = SBEIO::startDeadmanLoop(waitTime);
if ( l_errl )
diff --git a/src/usr/isteps/istep16/call_host_activate_slave_cores.C b/src/usr/isteps/istep16/call_host_activate_slave_cores.C
index c5f941e8f..1abc215ed 100644
--- a/src/usr/isteps/istep16/call_host_activate_slave_cores.C
+++ b/src/usr/isteps/istep16/call_host_activate_slave_cores.C
@@ -293,7 +293,7 @@ void* call_host_activate_slave_cores (void *io_pArgs)
// Callout and gard core that failed to wake up.
l_errl->addHwCallout(*l_core,
HWAS::SRCI_PRIORITY_HIGH,
- HWAS::DECONFIG,
+ HWAS::DELAYED_DECONFIG,
HWAS::GARD_Predictive);
// Could be an interrupt issue
diff --git a/src/usr/isteps/istep16/call_host_secure_rng.C b/src/usr/isteps/istep16/call_host_secure_rng.C
index 9ca7e0f45..5df147559 100644
--- a/src/usr/isteps/istep16/call_host_secure_rng.C
+++ b/src/usr/isteps/istep16/call_host_secure_rng.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -58,7 +58,6 @@
#include <devicefw/userif.H>
#include <vpd/mvpdenums.H>
-#include <config.h>
#include <fapi2/plat_hwp_invoker.H>
#include <p9_rng_init_phase2.H>
diff --git a/src/usr/isteps/istep16/call_mss_scrub.C b/src/usr/isteps/istep16/call_mss_scrub.C
index e7727a7ee..0d4db2acd 100644
--- a/src/usr/isteps/istep16/call_mss_scrub.C
+++ b/src/usr/isteps/istep16/call_mss_scrub.C
@@ -32,7 +32,8 @@
#include <diag/prdf/prdfMain.H>
#include <plat_hwp_invoker.H> // for FAPI_INVOKE_HWP
-#include <lib/fir/memdiags_fir.H> // for mss::unmask::after_background_scrub
+#include <lib/shared/nimbus_defaults.H> // Needed before unmask.H
+#include <lib/fir/unmask.H> // for mss::unmask::after_background_scrub
using namespace ERRORLOG;
using namespace TARGETING;
@@ -54,6 +55,7 @@ void* call_mss_scrub (void *io_pArgs)
do
{
+
if ( Util::isSimicsRunning() )
{
// There are performance issues and some functional deficiencies
@@ -71,11 +73,12 @@ void* call_mss_scrub (void *io_pArgs)
// Determine which target type runs the maintenance commands.
TARGETING::MODEL masterProcModel = masterProc->getAttr<ATTR_MODEL>();
- TARGETING::TYPE maintTrgtType;
+ TARGETING::TYPE maintTrgtType = TYPE_MBA;
switch ( masterProcModel )
{
case MODEL_CUMULUS: maintTrgtType = TYPE_MBA; break;
case MODEL_NIMBUS: maintTrgtType = TYPE_MCBIST; break;
+ case MODEL_AXONE: maintTrgtType = TYPE_OCMB_CHIP; break;
default:
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, ISTEP_FUNC
"Master PROC model %d not supported",
diff --git a/src/usr/isteps/istep18/establish_system_smp.C b/src/usr/isteps/istep18/establish_system_smp.C
index 2a59046d1..241ab5384 100644
--- a/src/usr/isteps/istep18/establish_system_smp.C
+++ b/src/usr/isteps/istep18/establish_system_smp.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -53,7 +53,6 @@
#include <istep_mbox_msgs.H>
#include <vfs/vfs.H>
-#include <config.h>
// targeting support
#include <targeting/common/commontargeting.H>
@@ -674,6 +673,8 @@ void *host_sys_fab_iovalid_processing(void* io_ptr )
"returned err: plid=0x%X. Deleting err and continuing",
err->plid());
err->collectTrace("ISTEPS_TRACE");
+ // Let the caller know that an error occurred
+ io_pMsg->data[0] = err->plid();
errlCommit(err, SECURE_COMP_ID);
}
diff --git a/src/usr/isteps/istep18/smp_unfencing_inter_enclosure_abus_links.C b/src/usr/isteps/istep18/smp_unfencing_inter_enclosure_abus_links.C
index 4e35e5a48..e21ce54c9 100644
--- a/src/usr/isteps/istep18/smp_unfencing_inter_enclosure_abus_links.C
+++ b/src/usr/isteps/istep18/smp_unfencing_inter_enclosure_abus_links.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -56,7 +56,6 @@
#include <fapi2/plat_hwp_invoker.H>
#include <isteps/hwpf_reasoncodes.H>
#include <isteps/hwpisteperror.H>
-#include <config.h>
#include <vector>
#include "smp_unfencing_inter_enclosure_abus_links.H"
diff --git a/src/usr/isteps/istep20/call_host_load_payload.C b/src/usr/isteps/istep20/call_host_load_payload.C
index 44e7672f4..5190649c9 100644
--- a/src/usr/isteps/istep20/call_host_load_payload.C
+++ b/src/usr/isteps/istep20/call_host_load_payload.C
@@ -38,7 +38,6 @@
#include <arch/ppc.H>
#include <kernel/console.H>
#include <xz/xz.h>
-#include <config.h>
using namespace ERRORLOG;
@@ -121,7 +120,13 @@ void* call_host_load_payload (void *io_pArgs)
// Load payload data in PHYP mode or in Sapphire mode
if(is_sapphire_load() || is_phyp_load())
{
- l_err = load_pnor_section( PNOR::PAYLOAD, payloadBase );
+ PNOR::SectionId l_secID = PNOR::PAYLOAD;
+ if (is_phyp_load())
+ {
+ l_secID = PNOR::BOOTKERNEL;
+ }
+
+ l_err = load_pnor_section( l_secID, payloadBase );
if ( l_err )
{
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
diff --git a/src/usr/isteps/istep21/call_host_runtime_setup.C b/src/usr/isteps/istep21/call_host_runtime_setup.C
index 4a87ddefd..db0fc2d5f 100644
--- a/src/usr/isteps/istep21/call_host_runtime_setup.C
+++ b/src/usr/isteps/istep21/call_host_runtime_setup.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -23,7 +23,6 @@
/* */
/* IBM_PROLOG_END_TAG */
-#include <config.h>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <initservice/isteps_trace.H>
@@ -68,8 +67,12 @@
#ifdef CONFIG_NVDIMM
#include "call_nvdimm_update.H"
+#include <isteps/nvdimm/nvdimm.H>
#endif
+#include <dump/dumpif.H>
+
+
using namespace ERRORLOG;
using namespace ISTEP;
using namespace ISTEP_ERROR;
@@ -290,8 +293,8 @@ errlHndl_t verifyAndMovePayload(void)
break;
}
- // If in Secure Mode Verify PHYP at Temporary TCE-related Memory Location
- if (SECUREBOOT::enabled() && is_phyp)
+ // If in Secure Mode Verify Payload at Temporary TCE-related Memory Location
+ if (SECUREBOOT::enabled())
{
TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,"verifyAndMovePayload() "
"Verifying PAYLOAD: physAddr=0x%.16llX, virtAddr=0x%.16llX",
@@ -736,6 +739,19 @@ void* call_host_runtime_setup (void *io_pArgs)
errlCommit(l_err, ISTEP_COMP_ID);
pmStartSuccess = false;
}
+ else
+ {
+#ifdef CONFIG_NVDIMM
+ // Arm the nvdimms
+ // Only get here if is_sapphire_load and PM started and have NVDIMMs
+ TARGETING::TargetHandleList l_nvdimmTargetList;
+ NVDIMM::nvdimm_getNvdimmList(l_nvdimmTargetList);
+ if (l_nvdimmTargetList.size() != 0)
+ {
+ NVDIMM::nvdimmArm(l_nvdimmTargetList);
+ }
+#endif
+ }
#ifdef CONFIG_HTMGT
// Report PM status to HTMGT
@@ -767,7 +783,7 @@ void* call_host_runtime_setup (void *io_pArgs)
uint8_t l_skip_fir_attr_reset = 1;
// Since we are not leaving the PM complex alive, we will
// explicitly put it into reset and clean up any memory
- l_err = HBPM::resetPMAll(HBPM::RESET_AND_CLEAR_ATTRIBUTES,
+ l_err = HBPM::resetPMAll(HBPM::RESET_AND_CLEAR_ATTRIBUTES,
l_skip_fir_attr_reset);
if (l_err)
{
@@ -846,11 +862,20 @@ void* call_host_runtime_setup (void *io_pArgs)
break;
}
}
-
+
// Update the MDRT Count and PDA Table Entries from Attribute
TargetService& l_targetService = targetService();
Target* l_sys = nullptr;
l_targetService.getTopLevelTarget(l_sys);
+
+ // Default captured data to 0s -- MPIPL if check fills in if
+ // valid
+ uint32_t threadRegSize = sizeof(DUMP::hostArchRegDataHdr)+
+ (95 * sizeof(DUMP::hostArchRegDataEntry));
+ uint8_t threadRegFormat = REG_DUMP_SBE_HB_STRUCT_VER;
+ uint64_t capThreadArrayAddr = 0;
+ uint64_t capThreadArraySize = 0;
+
if(l_sys->getAttr<ATTR_IS_MPIPL_HB>())
{
uint32_t l_mdrtCount =
@@ -862,25 +887,23 @@ void* call_host_runtime_setup (void *io_pArgs)
l_mdrtCount);
}
- // Update PDA Table entries
- if ( !INITSERVICE::spBaseServicesEnabled() )
- {
- uint32_t threadRegSize =
- l_sys->getAttr<TARGETING::ATTR_PDA_THREAD_REG_ENTRY_SIZE>();
- uint8_t threadRegFormat =
- l_sys->getAttr<TARGETING::ATTR_PDA_THREAD_REG_STATE_ENTRY_FORMAT>();
- uint64_t capThreadArrayAddr =
- l_sys->getAttr<TARGETING::ATTR_PDA_CAPTURED_THREAD_REG_ARRAY_ADDR>();
- uint64_t capThreadArraySize =
- l_sys->getAttr<TARGETING::ATTR_PDA_CAPTURED_THREAD_REG_ARRAY_SIZE>();
-
- // Ignore return value
- RUNTIME::updateHostProcDumpActual( RUNTIME::PROC_DUMP_AREA_TBL,
- threadRegSize, threadRegFormat,
- capThreadArrayAddr, capThreadArraySize);
- }
+
+ threadRegSize =
+ l_sys->getAttr<TARGETING::ATTR_PDA_THREAD_REG_ENTRY_SIZE>();
+ threadRegFormat =
+ l_sys->getAttr<TARGETING::ATTR_PDA_THREAD_REG_STATE_ENTRY_FORMAT>();
+ capThreadArrayAddr =
+ l_sys->getAttr<TARGETING::ATTR_PDA_CAPTURED_THREAD_REG_ARRAY_ADDR>();
+ capThreadArraySize =
+ l_sys->getAttr<TARGETING::ATTR_PDA_CAPTURED_THREAD_REG_ARRAY_SIZE>();
}
+ // Ignore return value
+ RUNTIME::updateHostProcDumpActual( RUNTIME::PROC_DUMP_AREA_TBL,
+ threadRegSize, threadRegFormat,
+ capThreadArrayAddr, capThreadArraySize);
+
+
//Update the MDRT value (for MS Dump)
l_err = RUNTIME::writeActualCount(RUNTIME::MS_DUMP_RESULTS_TBL);
if(l_err != NULL)
diff --git a/src/usr/isteps/istep21/call_host_start_payload.C b/src/usr/isteps/istep21/call_host_start_payload.C
index f8cfd3172..85bf3c9f5 100644
--- a/src/usr/isteps/istep21/call_host_start_payload.C
+++ b/src/usr/isteps/istep21/call_host_start_payload.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -54,7 +54,6 @@
#include <p9n2_quad_scom_addresses_fld.H>
#include <p9_quad_scom_addresses.H>
#include <ipmi/ipmiwatchdog.H>
-#include <config.h>
#include <errno.h>
#include <p9_int_scom.H>
#include <sbeio/sbeioif.H>
@@ -110,15 +109,6 @@ errlHndl_t broadcastShutdown ( uint64_t i_hbInstance );
errlHndl_t enableCoreCheckstops();
/**
- * @brief This function will clear the PORE BARs. Needs to be done
- * depending on payload type
- *
- * @return errlHndl_t - nullptr if successful, otherwise a pointer to the error
- * log.
- */
-errlHndl_t clearPoreBars ( void );
-
-/**
* @brief This function will check the Istep mode and send the appropriate
* mailbox message to the Fsp to indicate what we're doing.
*
@@ -479,19 +469,6 @@ errlHndl_t callShutdown ( uint64_t i_masterInstance,
break;
}
- if(is_phyp_load())
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "calling clearPoreBars() in node");
-
- //If PHYP then clear out the PORE BARs
- err = clearPoreBars();
- if( err )
- {
- break;
- }
- }
-
// Get Target Service, and the system target.
TargetService& tS = targetService();
TARGETING::Target* sys = nullptr;
@@ -793,77 +770,6 @@ errlHndl_t enableCoreCheckstops()
return l_errl;
}
-/**
- * @brief This function will clear the PORE BARs. Needs to be done
- * depending on payload type
- *
- * @return errlHndl_t - nullptr if successful, otherwise a pointer to the error
- * log.
- */
-errlHndl_t clearPoreBars ( void )
-{
- errlHndl_t l_errl = nullptr;
-
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "set PORE bars back to 0" );
-
- TARGETING::TargetHandleList l_procTargetList;
- getAllChips(l_procTargetList, TYPE_PROC);
-
- // loop thru all the cpus and reset the pore bars.
- for (TargetHandleList::const_iterator
- l_proc_iter = l_procTargetList.begin();
- l_proc_iter != l_procTargetList.end();
- ++l_proc_iter)
- {
- // make a local copy of the CPU target
- const TARGETING::Target* l_proc_target = *l_proc_iter;
-
- // trace HUID
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "target HUID %.8X", TARGETING::get_huid(l_proc_target));
-
- //@TODO RTC:133848 cast OUR type of target to a FAPI type of target.
-#if 0
- fapi::Target l_fapi_proc_target( TARGET_TYPE_PROC_CHIP,
- (const_cast<TARGETING::Target*>(
- l_proc_target)) );
-
- // reset pore bar notes:
- // A mem_size of 0 means to ignore the image address
- // This image should have been moved to memory after winkle
-
- // call the HWP with each fapi::Target
- FAPI_INVOKE_HWP( l_errl,
- p8_set_pore_bar,
- l_fapi_proc_target,
- 0,
- 0,
- 0,
- SLW_MEMORY
- );
-#endif
- if ( l_errl )
- {
- // capture the target data in the elog
- ERRORLOG::ErrlUserDetailsTarget(l_proc_target).addToLog( l_errl );
-
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR : p8_set_pore_bar, PLID=0x%x",
- l_errl->plid() );
- break;
- }
- else
- {
- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "SUCCESS : p8_set_pore_bar" );
- }
-
- } // end for
-
- return l_errl;
-}
-
//
// Notify the Fsp via Mailbox Message
//
diff --git a/src/usr/isteps/istep21/call_nvdimm_update.C b/src/usr/isteps/istep21/call_nvdimm_update.C
index 1204adb61..be1f5b22d 100644
--- a/src/usr/isteps/istep21/call_nvdimm_update.C
+++ b/src/usr/isteps/istep21/call_nvdimm_update.C
@@ -68,6 +68,9 @@ void call_nvdimm_update()
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
"call_nvdimm_update(): nvdimm update failed");
}
+
+ // Set the threshold warnings
+ NVDIMM::nvdimm_thresholds(l_nvdimmTargetList);
}
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,EXIT_MRK"call_nvdimm_update()");
diff --git a/src/usr/isteps/istep21/call_update_ucd_flash.C b/src/usr/isteps/istep21/call_update_ucd_flash.C
index 46d843579..89032ddd3 100644
--- a/src/usr/isteps/istep21/call_update_ucd_flash.C
+++ b/src/usr/isteps/istep21/call_update_ucd_flash.C
@@ -30,7 +30,6 @@
#include <util/utilmclmgr.H>
#include <errl/errlmanager.H>
#include <hbotcompid.H>
-#include <config.h>
#include <initservice/isteps_trace.H>
#include <isteps/ucd/updateUcdFlash.H>
#include <secureboot/trustedbootif.H>
diff --git a/src/usr/isteps/istep21/freqAttrData.C b/src/usr/isteps/istep21/freqAttrData.C
index 9dc60bfff..ed8c7df4a 100644
--- a/src/usr/isteps/istep21/freqAttrData.C
+++ b/src/usr/isteps/istep21/freqAttrData.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -48,7 +48,6 @@
#include <sys/time.h>
#include <sys/vfs.h>
#include <arch/ppc.H>
-#include <config.h>
#include <mbox/ipc_msg_types.H>
#include <fapi2.H>
diff --git a/src/usr/isteps/makefile b/src/usr/isteps/makefile
index dca7777f7..5a53e3291 100644
--- a/src/usr/isteps/makefile
+++ b/src/usr/isteps/makefile
@@ -50,8 +50,9 @@ SUBDIRS+=tod.d
SUBDIRS+=fab_iovalid.d
SUBDIRS+=nest.d
SUBDIRS+=io.d
-SUBDIRS+=nvdimm.d
+SUBDIRS+=$(if $(CONFIG_NVDIMM),nvdimm.d)
SUBDIRS+=ucd.d
+SUBDIRS+=expupd.d
#TODO: RTC 176018
EXTRAINCDIR += ${ROOTPATH}/src/import/
diff --git a/src/usr/isteps/mem_utils.C b/src/usr/isteps/mem_utils.C
index 89961ef5e..948dbdf17 100644
--- a/src/usr/isteps/mem_utils.C
+++ b/src/usr/isteps/mem_utils.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -28,6 +28,7 @@
#include <errl/hberrltypes.H>
#include <secureboot/smf_utils.H>
#include <stdint.h>
+#include <isteps/nvdimm/nvdimmif.H>
namespace ISTEP
{
@@ -208,6 +209,11 @@ uint64_t get_top_homer_mem_addr()
l_top_homer_addr = get_top_mem_addr();
}
+ // Need to make sure we don't choose a range that is owned by
+ // the NVDIMMs
+ l_top_homer_addr =
+ NVDIMM::get_top_addr_with_no_nvdimms(l_top_homer_addr);
+
}while(0);
return l_top_homer_addr;
diff --git a/src/usr/isteps/mss/HBconfig b/src/usr/isteps/mss/HBconfig
index f48017fe1..56334c98c 100644
--- a/src/usr/isteps/mss/HBconfig
+++ b/src/usr/isteps/mss/HBconfig
@@ -1,4 +1,4 @@
config LRDIMM_CAPABLE
default n
help
- Enable the use of LRDIMM code
+ Enable the use of LRDIMM code \ No newline at end of file
diff --git a/src/usr/isteps/mss/makefile b/src/usr/isteps/mss/makefile
index 40eec68d9..f0901b170 100644
--- a/src/usr/isteps/mss/makefile
+++ b/src/usr/isteps/mss/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2016,2019
+# Contributors Listed Below - COPYRIGHT 2016,2020
# [+] International Business Machines Corp.
#
#
@@ -28,6 +28,7 @@ IMPORT_PATH = ${ROOTPATH}/src/import
PROCEDURES_PATH = ${IMPORT_PATH}/chips/p9/procedures
AXONE_PROCEDURES_PATH = ${IMPORT_PATH}/chips/p9a/procedures
EXPLORER_PROCEDURES_PATH = ${IMPORT_PATH}/chips/ocmb/explorer/procedures
+GEMINI_PROCEDURES_PATH = ${IMPORT_PATH}/chips/ocmb/gemini/procedures
#Add all the extra include paths
EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include
@@ -38,6 +39,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs/
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/include/
EXTRAINCDIR += ${IMPORT_PATH}/chips/ocmb/explorer/common/include/
EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/chips/ocmb/explorer/procedures/hwp/memory/lib/
+EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/chips/p9a/procedures/hwp/memory/lib/
EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/generic/memory/lib/
EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/
@@ -72,6 +74,9 @@ MSS_LIB += ${AXONE_PROCEDURES_PATH}/hwp/memory/lib/
MSS_LIB += ${AXONE_PROCEDURES_PATH}/hwp/memory/lib/eff_config/
MSS_LIB += ${AXONE_PROCEDURES_PATH}/hwp/memory/lib/utils/
MSS_LIB += ${AXONE_PROCEDURES_PATH}/hwp/memory/lib/freq/
+MSS_LIB += ${AXONE_PROCEDURES_PATH}/hwp/memory/lib/workarounds/
+MSS_LIB += ${AXONE_PROCEDURES_PATH}/hwp/memory/lib/fir/
+MSS_LIB += ${AXONE_PROCEDURES_PATH}/hwp/memory/lib/plug_rules/
MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/
MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/
MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/eff_config/
@@ -80,10 +85,18 @@ MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/freq/
MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/power_thermal/
MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/omi/
MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/i2c/
+MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/inband/
MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/fir/
MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/mcbist/
MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/phy/
MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/ecc/
+MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/ccs/
+MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/workarounds/
+MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/plug_rules/
+MSS_LIB += ${EXPLORER_PROCEDURES_PATH}/hwp/memory/lib/mc/
+MSS_LIB += ${GEMINI_PROCEDURES_PATH}/hwp/memory/
+MSS_LIB += ${GEMINI_PROCEDURES_PATH}/hwp/memory/lib/
+
EXTRAINCDIR += ${MSS_LIB}
@@ -170,6 +183,7 @@ FILE_PREFIX = mss_p9a
SOURCES += $(ROOTPATH)/chips/p9/procedures/xml/attribute_info/p9a_io_attributes.xml
SOURCES += $(ROOTPATH)/chips/p9/procedures/xml/attribute_info/p9a_omi_setup_bars.xml
SOURCES += $(ROOTPATH)/chips/p9/procedures/xml/attribute_info/p9a_omi_init.xml
+SOURCES += $(ROOTPATH)/chips/p9/procedures/xml/attribute_info/p9a_omi_train.xml
CLEAN_TARGETS += ${OUTPATH}/mss_p9a_attribute_getters.H
CLEAN_TARGETS += ${OUTPATH}/mss_p9a_attribute_setters.H
@@ -182,6 +196,27 @@ endef
$(call BUILD_GENERATED)
+# Generate pmic_accessors header file
+GENERATED = gen_pmic_accessors
+COMMAND = gen_accessors.pl
+$(GENERATED)_COMMAND_PATH = $(IMPORT_PATH)/generic/memory/tools/
+
+OUTPATH = ${ROOTPATH}/obj/genfiles/chips/ocmb/common/procedures/hwp/pmic/lib/
+FILE_PREFIX = mss_pmic
+
+SOURCES += $(ROOTPATH)/chips/ocmb/common/procedures/xml/attribute_info/pmic_eff_attributes.xml
+
+CLEAN_TARGETS += ${OUTPATH}/mss_pmic_attribute_getters.H
+CLEAN_TARGETS += ${OUTPATH}/mss_pmic_attribute_setters.H
+CLEAN_TARGETS += ${OUTPATH}/.gen_pmic_accessors.built
+
+define gen_pmic_accessors_RUN
+ $(C1) mkdir $(OUTPATH) -p
+ $(C1) $$< --system=AXONE --output-dir=$(OUTPATH) --output-file-prefix=$(FILE_PREFIX) $$(filter-out $$<,$$^)
+endef
+
+$(call BUILD_GENERATED)
+
# Add common and generated parts to object list.
MSS_PATH := $(PROCEDURES_PATH)/hwp/memory/lib
@@ -198,13 +233,16 @@ MSS_MODULE_OBJS += $(if $(CONFIG_AXONE),$(patsubst %.C,%.o,$(MSS_AXONE_SOURCE)),
MSS_PATH_EXPLORER := $(EXPLORER_PROCEDURES_PATH)/hwp/memory/lib
MSS_EXPLORER_SOURCE := $(shell find $(MSS_PATH_EXPLORER) -name '*.C' -exec basename {} \;)
-# TODO RTC: 207832 Remove filter-out commands when new lib files come
-MSS_EXPLORER_SOURCE := $(filter-out memdiags.C,$(MSS_EXPLORER_SOURCE))
-MSS_EXPLORER_SOURCE := $(filter-out mcbist.C,$(MSS_EXPLORER_SOURCE))
-MSS_EXPLORER_SOURCE := $(filter-out memory_size.C,$(MSS_EXPLORER_SOURCE))
#must bring explorer_memory_size.o in even in Nimbus/Cumulus builds because of p9_mss_grouping nest HWP
MSS_MODULE_OBJS += $(if $(CONFIG_AXONE),$(patsubst %.C,%.o,$(MSS_EXPLORER_SOURCE)),explorer_memory_size.o)
+
+MSS_PATH_GEMINI := $(GEMINI_PROCEDURES_PATH)/hwp/memory/lib
+MSS_GEMINI_SOURCE := $(shell find $(MSS_PATH_GEMINI) -name '*.C' -exec basename {} \;)
+MSS_MODULE_OBJS += $(if $(CONFIG_AXONE),$(patsubst %.C,%.o,$(MSS_GEMINI_SOURCE)),)
+
+
MODULE = isteps_mss
+
OBJS += $(MSS_MODULE_OBJS)
$(call BUILD_MODULE)
diff --git a/src/usr/isteps/mss/runtime/makefile b/src/usr/isteps/mss/runtime/makefile
index 400025498..530a68f8d 100644
--- a/src/usr/isteps/mss/runtime/makefile
+++ b/src/usr/isteps/mss/runtime/makefile
@@ -68,6 +68,7 @@ MSS_LIB += ${IMPORT_PATH}/generic/memory/lib/spd/
MSS_LIB += ${IMPORT_PATH}/generic/memory/lib/utils/
MSS_LIB += ${IMPORT_PATH}/generic/memory/lib/utils/shared/
MSS_LIB += ${IMPORT_PATH}/generic/memory/lib/utils/freq/
+MSS_LIB += ${IMPORT_PATH}/generic/memory/lib/utils/mcbist
# Axone
MSS_LIB += ${IMPORT_PATH}/chips/p9a/procedures/hwp/memory/lib/utils/
@@ -86,10 +87,9 @@ OBJS += axone_c_str.o
OBJS += nimbus_c_str.o
OBJS += mcbist.o
OBJS += mcbist_workarounds.o
-OBJS += sim.o
OBJS += rank.o
OBJS += memory_size.o
-OBJS += patterns.o
+OBJS += gen_mss_mcbist_patterns.o
OBJS += axone_pos.o
OBJS += nimbus_pos.o
diff --git a/src/usr/isteps/nest/makefile b/src/usr/isteps/nest/makefile
index aa22887c3..a995b7cd0 100644
--- a/src/usr/isteps/nest/makefile
+++ b/src/usr/isteps/nest/makefile
@@ -41,6 +41,7 @@ EXTRAINCDIR += ${PROCEDURES_PATH}/hwp/initfiles
OBJS += nestHwpHelperFuncs.o
OBJS += p9_io_obus_firmask_save_restore.o
+OBJS += p9_fbc_ioo_dl_npu_scom.o
VPATH += ${PROCEDURES_PATH}/hwp/initfiles
VPATH += ${PROCEDURES_PATH}/hwp/io
diff --git a/src/usr/isteps/nvdimm/ReadMe.md b/src/usr/isteps/nvdimm/ReadMe.md
new file mode 100644
index 000000000..1f98438b2
--- /dev/null
+++ b/src/usr/isteps/nvdimm/ReadMe.md
@@ -0,0 +1,278 @@
+# Battery Power Module (BPM) Updates Overview
+To support different firmware versions released by SMART, the bpm_update.C and
+bpm_update.H files were created to facilitate upgrades and downgrades of the
+firmware version on a BPM attached to an NVDIMM. There are two kinds of BPM, one
+that supports 16GB type NVDIMMs and one that supports 32GB type NVDIMMs.
+Although they have separate image files, the update is functionally the same for
+each. This overview will not go into fine-grain detail on every process of the
+update. For more information see the comments in bpm_update.H, bpm_update.C and
+in the various supporting files.
+
+Supporting Files:
+* Two image files, e.g., SRCA8062IBMH012B_FULL_FW_Rev1.03_02282019.txt or
+SRCA8062IBMH011B_FULL_FW_Rev1.04_05172019.txt
+ * The image file names are important in that they contain information that
+ is not found anywhere else in the files. For example, After SRCA8062IBMH01
+ but right before the B is a number. That signifies which kind of BPM type
+ that image is for. A 1 means 32gb type, a 2 means 16gb type. Also, note that
+ the version Rev1.0x is in the file name. There is no other place where this
+ occurs within the image file. So, to differentiate the updates from each
+ other the file names must be left intact.
+* src/build/buildpnor/buildBpmFlashImages.pl
+ * This perl script is responsible for packaging the image files listed above
+ into binaries that can then be associated with LIDs for use during the BPM
+ update.
+* src/build/buildpnor/bpm-utils/imageCrc.c and
+src/build/buildpnor/bpm-utils/insertBpmFwCrc.py
+ * These are provided by SMART and utilized by buildBpmFlashImages.pl to
+ generate the correct CRC for the firmware image during the fsp build.
+* src/build/mkrules/dist.targets.mk
+ * This file puts src/build/buildpnor/buildBpmFlashImages.pl,
+ src/build/buildpnor/bpm-utils/imageCrc.c,
+ and src/build/buildpnor/bpm-utils/insertBpmFwCrc.py into the fsp.tar which
+ can then be primed over to an FSP sandbox.
+* <fsp_sandbox>/src/engd/nvdimm/makefile
+ * This makefile compiles the src/build/buildpnor/bpm-utils/imageCrc.c and
+ calls src/build/buildpnor/buildBpmFlashImages.pl to do all the necessary
+ work to bring the flash image binaries up-to-date.
+* In <fsp_sandbox>/obj/ppc/engd/nvdimm/bpm/ are 16GB-NVDIMM-BPM-CONFIG.bin,
+16GB-NVDIMM-BPM-FW.bin, 32GB-NVDIMM-BPM-CONFIG.bin, and 32GB-NVDIMM-BPM-FW.bin
+ * These are the output binaries which will be associated to LIDs for
+ hostboot use.
+
+### BPM Update Flow Overview
+The update procedure for the BPM is fairly rigid. There are many steps that must
+occur in a precise order otherwise the update will fail. We aren't able to
+communicate directly to the BPM for these updates. Instead, we send commands to
+the NVDIMM which in-turn passes those along to the BPM. There are a couple
+"modes" that must be enabled to begin the update process and be able to
+communicate with the BPM. These are:
+
+##### Update Mode
+This is a mode for the NVDIMM. To enter this mode a command is sent to the
+NVDIMM so that the NVDIMM can do some house-keeping work to prepare for the BPM
+update. Since the NVDIMM is always doing background scans of the BPM, this mode
+will quiet those scans so that we are able to communicate with the BPM.
+Otherwise, the communication would be too chaotic to perform the update.
+
+##### Boot Strap Loader (BSL) Mode (Currently, only BSL 1.4 is supported)
+This is the mode that the BPM enters in order to perform the update.In order to
+execute many of the commands necessary to perform the update, the BPM **must**
+be in BSL mode. There are varying versions of BSL mode and these versions are
+not coupled with the firmware version at all. In order for the BSL version to be
+updated on a BPM, the device must be shipped back to SMART because it requires a
+specific hardware programmer device to be updated.
+
+The update procedure does vary between BSL versions, so to ensure a successful
+update the code will first read the BSL version on the BPM. If the BSL version
+is not 1.4 (the supported version) then the update process will not occur as it
+is known that BSL versions prior to 1.4 are different enough that the update
+would fail if attempted and it is unknown if future BSL versions will be
+backward compatible with the BSL 1.4 procedure.
+
+If something happens to the firmware during an update such that the firmware on
+the device is missing or invalid, the BPM is designed to always fall back to
+this mode so that valid firmware can be loaded onto the BPM and the device can
+be recovered. However, if the firmware is corrupted by any means outside of an
+update then it is highly likely that the BPM will not be recoverable and it may
+need to be sent back to SMART for recovery.
+
+#### An update in two parts
+The BPM update cannot be done in one single pass. This is because there are two
+sections of data on the BPM that must be modified to successfully update the
+BPM. These are refered to as the Firmware portion of the update and the
+Configuration Data Segment portion of the update.
+
+##### The Firmware Portion
+This is the actual firmware update. Although, when someone says the BPM Firmware
+Update they are often implicitly referring to both parts of the update. In order
+for the full update to be a success, the firmware portion of the update is
+reliant upon another part to have access to all of the features in a given
+update. That is the Configuration Segment Data. It is safe, and advisable, to
+update the firmware part first and then the configuration part second.
+
+##### The Configuration Data Portion
+The Configuration Data Segment portion is commonly referred to as the segment
+update, config update, or any other variation of the name. The config segment
+portion **requires** working firmware on the BPM to succeed. This is because we
+must read out some of the segment data on the BPM and merge it with parts from
+the image. Without working firmware, it will not work and the update will
+_never_ succeed.
+
+The configuration data on the BPM is broken into four segments, A, B, C, and D.
+These are in reverse order in memory such that D has the lowest address offset.
+For our purposes, we only care about Segment D and B. A and C contain logging
+information and are not necessary to touch. Segment D will be completely
+replaced by the data in the image file. Segment B is the critical segment,
+however, because we must splice data from the image into it. Segment B contains
+statistical information and other valuable information that should never be lost
+during an update. If this segment becomes corrupted then it is very likely the
+BPM will be stuck in a bad state.
+
+##### Bpm::runUpdate Flow
+1. Read the current firmware version on the BPM to determine if updates are
+necessary. If this cannot be done, that is to say that an error occurs during
+this process, then updates will not be attempted due to a probable
+communication issue with the BPM.
+2. Read the current BSL mode version to determine if the BSL version on the BPM
+is compatible with the versions we support. If this cannot be done due to some
+kind of error, then the updates will not be attempted since we cannot be sure
+that the BPM has a compatible BSL version.
+3. Perform the firmware portion of the update. If an error occurs during this
+part of the update then the segment portion of the updates will not be attempt
+as per the given requirement above.
+4. Perform the segment portion of the update.
+
+##### Common Operating Processes between functions
+Reading the BSL version, and performing the firmware and segment updates all
+follow a common operating process to do their work successfully. The steps laid
+out in those functions must be followed in the given order otherwise the
+functions will not execute successfully and the BPM may go into a bad state.
+These steps are:
+1. Enter Update Mode
+2. Verify the NVDIMM is in Update Mode
+3. Command the BPM to enter BSL mode
+4. Unlock the BPM so that writing can be performed.
+5. Do function's work.
+6. Reset the BPM, which is the way that BSL mode is exited.
+7. Exit Update Mode
+
+By following these steps, the BPM is able to some background work to verify its
+state. If firmware and config updates are attempted at the same time this will
+introduce unpredicatable behavior. Meaning if only one set of steps 1-4 have
+executed then step 5a and 5b are to perform firmware and config updates, and
+then 6-7 are done that will produce unpredicable behavior. It is best run
+through the whole process for each. Reading the BSL version does not have this
+limitation. As long as steps 1-4 have been executed, the BSL version can be read
+at any time.
+
+-------------------------------------------------------------------------------
+# Node Controller (NC) Update Overview
+To support different firmware versions released by SMART, the nvdimm_update.C
+and nvdimm_update.H files were created to facilitate upgrades and downgrades of
+the firmware version of node controllers for NVDIMM. There are two kinds of
+NVDIMM node controllers: one that supports 16GB type NVDIMMs and one that
+supports 32GB type NVDIMMs. Although they have separate image files, the update
+is functionally the same for each. This overview will not go into fine-grain
+detail on every process of the update. For more information see the comments in
+nvdimm_update.H, nvdimm_update.C and in the various supporting files.
+
+Supporting Files:
+* Two signed image files are provided by SMART.
+ The name contains the NC type (16GB or 32GB) + the version (v##)
+
+ Example:
+ nvc4_fpga_31mm_X4_16GB_A7_2TLC_GA6_IBM_JEDEC_2019_03_22_v30_r29325-SIGNED.bin
+ nvc4_fpga_31mm_X4_32GB_A7_2TLC_GA6_IBM_JEDEC_2019_03_22_v30_r29325-SIGNED.bin
+
+* Files checked into cmvc/build process
+ Note: Each file contains two bytes that describe the NC type and version, so
+ we can use a generic name in CMVC
+ * NVDIMM_SRN7A2G4IBM26MP1SC.bin (16GB one)
+ * NVDIMM_SRN7A4G4IBM24KP2SB.bin (32GB one)
+
+* Build process creates lid files that are loaded on system
+ * 80d00025.lid (secure content LID)
+ * 81e00640.lid (signed 16GB)
+ * 81e00641.lid (signed 32GB)
+
+### NC Update Flow Overview
+The update procedure for the NC is fairly rigid. There are many steps that must
+occur in a precise order otherwise the update will fail.
+
+### Design points
+Three classes are used for the NC update
+* NvdimmsUpdate -- container/driver class
+ This is where all the functional NVDIMM NCs are checked and updated if necessary
+* NvdimmLidImage -- accessors for a given NC LID image (16 or 32)
+ This provides the LID content for easy checking and use during update
+* NvdimmInstalledImage -- accessor to current installed NC image
+ This is the main workhorse. It uses i2c communication to check what is
+ installed and performs the update to a new LID image level
+
+##### NvdimmsUpdate::runUpdate Flow
+1. Build up installed NVDIMM image lists (determine what NC types are installed)
+2. Using secure content lid, now call runUpdateUsingLid() for each LID type
+with the appropriate target NVDIMMs associated with that type.
+3. runUpdateUsingLid() cycles through each NVDIMM target and checks if the
+current NC level is different then the lid version level.
+Only update if the levels do not match to allow upgrade and downgrading.
+4. NvdimmInstalledImage::updateImage() is called on each NVDIMM node controller
+that requires an update
+5. updateImage runs through the steps outlined in 9.7 Firmware Update workflow
+in the JEDEC document JESD245B
+6. Basic steps of the update done one NVDIMM controller at a time
+ 1. Validate module manufacturer ID and module product identifier (done before this)
+ 2. Verify 'Operation In Progress' bit in the NVDIMM_CMD_STATUS0
+ register is cleared (ie. NV controller is NOT busy)
+ 3. Make sure we start from a cleared state
+ 4. Enable firmware update mode
+ 5. Clear the Firmware Operation status
+ 6. Clear the firmware data block to ensure there is no residual data
+ 7. Send the first part (header + SMART signature) of the Firmware Image Data
+ Include sending data and checking checksum after data is sent
+ 8. Command the module to validate that the firmware image is valid for
+ the module based on the header
+ 9. Commit the first firmware data region
+ 10. Send and commit the remaining firmware data in REGION_BLOCK_SIZE regions
+ - each block is 32 bytes
+ - each region contains upto REGION_BLOCK_SIZE blocks (currently 1,024)
+ - each region is verfied by checksum before next region is sent
+ 11. Command the module to validate the firmware data
+ 12. Disable firmware update mode
+ 13. Switch from slot0 to slot1 which contains the new image code
+ 14. Validate running new code level
+
+# NVDIMM Secure Erase Verify Flow
+DS8K lpar -> HBRT NVDIMM operation = factory_default + secure_erase_verify_start
+ HBRT executes factory_default and steps 1) and 2)
+DS8K lpar -> HBRT NVDIMM operation = secure_erase_verify_complete
+ HBRT executes step 3)
+ If secure erase verify has not completed, return status with verify_complete bit = 0
+ DS8K lpar is responsible for monitoring elapsed time (2/4 hours) and restart process (step 6)
+ If secure erase verify has completed
+ HBRT executes steps 4) and 5), generating error logs for any non-zero register values
+ Return status with verify_complete bit = 1
+
+## Procedure Flow for NVDIMM Secure Erase Verify
+ *Note: Secure Erase Verify should only be run after a Factory Default operation.
+ Secure Erase Verify is intended to verify whether all NAND blocks have been erased.
+ *Note: Full breakout of all Page 5 Secure Erase Verify registers can be found in
+ SMART document "JEDEC NVDIMM Vendor Page 2 Extensions".
+ 1) Set Page 5 Register 0x1B to value "0x00"
+ // this clears the status register
+ 2) Set Page 5 Register 0x1A to value "0xC0"
+ // this kicks off the erase verify operation
+ 3) Wait for Page 5 Register 0x1A Bit 7 to be reset to value "0"
+ // i.e., the overall register value should be "0x40";
+ this means that erase verify has completed
+ a. If Page 5 Register 0x1A Bit 7 has not reset to value "0"
+ after 2 hours (16GB NVDIMM) or after 4 hours (32GB NVDIMM),
+ report a timeout error and skip to step (6)
+ 4) Read Page 5 Register 0x1B; value should be "0x00"
+ // this is the erase verify status register
+ a. If Page 5 Register 0x1B value is not "0x00",
+ report any/all errors as outlined in the table at the end of this document,
+ then skip to step (6)
+ 5) Read Page 5 Registers 0x1D (MSB) and 0x1C (LSB);
+ combined the two registers should have a value of "0x0000"
+ // this is the number of chunks failing Secure Erase Verify
+ a. If the combined value of the two registers is not "0x0000",
+ report a threshold exceeded error along with the combined value of the two registers,
+ then skip to step (6)
+ 6) If any errors have been reported in steps (3), (4), or (5),
+ retry the secure erase verify operation starting again from step (1)
+ a. If the secure erase verify operation fails even after retrying,
+ report that secure erase verify operation has failed
+ 7) If no errors have been reported, report that secure erase verify operation
+ has been completed successfully
+ *Addendum: Breakout of Page 5 Register 0x1B Erase Verify Status bit values referenced in step (4) above.
+ All these bits should return as "0". Any bits returning as "1" should be reported with the error name below.
+ Bits 7:6 - Reserved
+ Bit 5 - BAD BLOCK
+ Bit 4 - OTHER
+ Bit 3 - ENCRYPTION LOCKED
+ Bit 2 - INVALID PARAMETER
+ Bit 1 - INTERRUPTED
+ Bit 0 - NAND ERROR
+
diff --git a/src/usr/isteps/nvdimm/bpm_update.C b/src/usr/isteps/nvdimm/bpm_update.C
new file mode 100644
index 000000000..3ffdb595b
--- /dev/null
+++ b/src/usr/isteps/nvdimm/bpm_update.C
@@ -0,0 +1,4108 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/isteps/nvdimm/bpm_update.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include "nvdimm.H"
+#include "bpm_update.H"
+#include "nvdimm_update.H"
+
+#include <isteps/nvdimm/nvdimm.H>
+#include <errl/hberrltypes.H>
+#include <errl/errlmanager.H>
+#include <endian.h>
+#include <sys/time.h>
+#include <hbotcompid.H>
+#include <trace/interface.H>
+#include <initservice/istepdispatcherif.H>
+#include <isteps/nvdimm/bpmreasoncodes.H>
+
+#include <hwas/common/hwasCallout.H>
+
+#include <targeting/common/targetservice.H>
+#include <attributeenums.H>
+
+namespace NVDIMM
+{
+namespace BPM
+{
+
+trace_desc_t* g_trac_bpm = nullptr;
+TRAC_INIT(&g_trac_bpm, BPM_COMP_NAME, 4*KILOBYTE);
+
+// For debug traces
+#define TRACUCOMP(args...)
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUBIN(args...)
+//#define TRACUBIN(args...) TRACUBIN(args)
+
+// These constants are kept out of the header file since they aren't relevant
+// outside of this file.
+const uint16_t BPM_ADDRESS_ZERO = 0;
+const uint16_t BPM_CONFIG_START_ADDRESS = 0x1800;
+// There are two potential start addresses for the firmware section.
+// They are:
+const uint16_t MAIN_PROGRAM_ADDRESS = 0x8000;
+const uint16_t MAIN_PROGRAM_ADDRESS_ALT = 0xA000;
+
+// In order to disable write protection on the BPM to perform updates a sequence
+// of characters must be written. The hex represenation of those characters are
+// defined by this constant. The sequence is SMOD
+const uint8_t BPM_PASSWORD[] = {0x53, 0x4D, 0x4F, 0x44};
+const size_t BPM_PASSWORD_LENGTH = 4;
+
+// These are the segment codes used to dump out a particular config data segment
+// on the BPM.
+const uint16_t DEFAULT_REG_PAGE = 0x905E;
+const uint16_t SEGMENT_A_CODE = 0x9A5E;
+const uint16_t SEGMENT_B_CODE = 0x9B5E;
+const uint16_t SEGMENT_C_CODE = 0x9C5E;
+const uint16_t SEGMENT_D_CODE = 0x9D5E;
+
+// Starting addresses relative to address 0x1800.
+// Segments appear in reverse order on BPM.
+// Each segment is SEGMENT_SIZE long.
+const size_t SEGMENT_D_START_ADDR = 0x000;
+const size_t SEGMENT_C_START_ADDR = 0x080;
+const size_t SEGMENT_B_START_ADDR = 0x100;
+const size_t SEGMENT_A_START_ADDR = 0x180;
+
+const std::map<uint16_t, size_t> segmentMap
+{
+ {SEGMENT_A_CODE, SEGMENT_A_START_ADDR},
+ {SEGMENT_B_CODE, SEGMENT_B_START_ADDR},
+ {SEGMENT_C_CODE, SEGMENT_C_START_ADDR},
+ {SEGMENT_D_CODE, SEGMENT_D_START_ADDR},
+};
+
+const uint8_t MAX_RETRY = 3;
+
+/**
+ * @brief A helper function used in assert statements to verify the correct
+ * BSP commands were passed into the correct function arguments.
+ *
+ * @param[in] i_command The command that will verified to be a BSP command.
+ *
+ * @return bool true if i_command is a BSP command.
+ * false if it's not a BSP command.
+ */
+bool isBspCommand(const uint8_t i_command)
+{
+ bool result = ((i_command == BPM_PASSTHROUGH) || (i_command == BPM_LOCAL))
+ ? true : false;
+
+ return result;
+}
+
+/**
+ * @brief A helper function used in assert statements to verify the correct
+ * BCL commands were passed into the correct function arguments.
+ *
+ * @param[in] i_command The command that will verified to be a BCL command.
+ *
+ * @return bool true if i_command is a BCL command.
+ * false if it's not a BCL command.
+ */
+bool isBclCommand(const uint8_t i_command)
+{
+ bool result = false;
+ switch(i_command)
+ {
+ case BCL_ENTER_BSL_MODE:
+ case BCL_IS_BSL_MODE:
+ case BCL_WRITE_REG:
+ case BCL_START_UPDATE:
+ case BCL_END_UPDATE:
+ case BCL_IS_UPDATE_IN_PROGRESS:
+ {
+ result = true;
+ break;
+ }
+ default:
+ {
+ result = false;
+ break;
+ }
+ }
+
+ return result;
+}
+
+/**
+ * @brief A helper function used in assert statements to verify the correct
+ * BSL commands were passed into the correct function arguments.
+ *
+ * @param[in] i_command The command that will verified to be a BSL command.
+ *
+ * @return bool true if i_command is a BSL command.
+ * false if it's not a BSL command.
+ */
+bool isBslCommand(const uint8_t i_command)
+{
+ bool result = false;
+ switch(i_command)
+ {
+ case BSL_RX_DATA_BLOCK:
+ case BSL_RX_PASSWORD:
+ case BSL_ERASE_SEGMENT:
+ case BSL_TOGGLE_INFO:
+ case BSL_ERASE_BLOCK:
+ case BSL_MASS_ERASE:
+ case BSL_CRC_CHECK:
+ case BSL_LOAD_PC:
+ case BSL_TX_DATA_BLOCK:
+ case BSL_TX_BSL_VERSION:
+ case BSL_TX_BUFFER_SIZE:
+ case BSL_RX_DATA_BLOCK_FAST:
+ case BSL_RESET_DEVICE:
+ case BSL_VERIFY_BLOCK:
+ {
+ result = true;
+ break;
+ }
+ default:
+ {
+ result = false;
+ break;
+ }
+ }
+
+ return result;
+}
+
+/**
+ * @brief Helper function to pull out the BPM address offset in the given
+ * payload.
+ *
+ * @param[in] i_payload The payload from which to extract the address
+ * offset.
+ */
+uint16_t getPayloadAddressBE(payload_t i_payload)
+{
+ // Get the payload address and convert back to big endian.
+ uint16_t payloadAddress = (i_payload[PAYLOAD_ADDRESS_START_INDEX])
+ | (i_payload[PAYLOAD_ADDRESS_START_INDEX + 1] << 8);
+ return payloadAddress;
+}
+
+/**
+ * @brief Helper function to extract the Segement ID from the segment code.
+ *
+ * @param[in] i_segmentCode The Segment code to pull the segment ID from
+ *
+ * @return uint8_t The Segment ID (A, B, C, D) as a hex value.
+ * For example 0xA, 0xB, etc.
+ */
+uint8_t getSegmentIdentifier(uint16_t i_segmentCode)
+{
+ uint8_t segmentId = (i_segmentCode >> 8) & 0xF;
+ return segmentId;
+}
+
+/**
+ * @brief Helper function to sleep for longer durations in 5 second increments.
+ *
+ * @param[in] i_sleepInSeconds How many seconds to sleep.
+ */
+void longSleep(uint8_t const i_sleepInSeconds)
+{
+ int iterations = i_sleepInSeconds / 5;
+ do
+ {
+ // Send progress code.
+ INITSERVICE::sendProgressCode();
+
+ // Sleep for 5 seconds
+ nanosleep(5, 0);
+
+ --iterations;
+ } while (iterations > 0);
+}
+
+void runBpmUpdates(bpmList_t * const i_16gb_BPMs,
+ bpmList_t * const i_32gb_BPMs,
+ BpmFirmwareLidImage * const i_16gb_fwImage,
+ BpmFirmwareLidImage * const i_32gb_fwImage,
+ BpmConfigLidImage * const i_16gb_configImage,
+ BpmConfigLidImage * const i_32gb_configImage)
+{
+
+ assert( (i_16gb_BPMs == nullptr)
+ || i_16gb_BPMs->empty()
+ || ((i_16gb_fwImage != nullptr) && (i_16gb_configImage != nullptr)),
+ "BPM::runBpmUpdates(): Update images for 16gb BPMs was nullptr and "
+ "there are 16gb BPMs in the system to may require updates.");
+ assert( (i_32gb_BPMs == nullptr)
+ || i_32gb_BPMs->empty()
+ || ((i_32gb_fwImage != nullptr) && (i_32gb_configImage != nullptr)),
+ "BPM::runBpmUpdates(): Update images for 32gb BPMs was nullptr and "
+ "there are 32gb BPMs in the system to may require updates.");
+
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ if ( (i_16gb_BPMs != nullptr)
+ && (i_16gb_fwImage != nullptr)
+ && (i_16gb_configImage != nullptr))
+ {
+ TRACFCOMP(g_trac_bpm,
+ "Check/update %d BPMs on 16GB_TYPE NVDIMMs",
+ i_16gb_BPMs->size());
+
+ for(auto& bpm : *i_16gb_BPMs)
+ {
+ errl = bpm.runUpdate(*i_16gb_fwImage, *i_16gb_configImage);
+ if (errl != nullptr)
+ {
+ uint32_t nvdimmHuid = TARGETING::get_huid(bpm.getNvdimm());
+ if (bpm.attemptAnotherUpdate())
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK
+ "An error occurred during a 16GB_TYPE BPM "
+ "update for NVDIMM 0x%.8X. "
+ "Try again.",
+ nvdimmHuid);
+
+ delete errl;
+ errl = bpm.runUpdate(*i_16gb_fwImage,
+ *i_16gb_configImage);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK
+ "Another error occurred while attempting "
+ "to update the same 16GB_TYPE BPM for "
+ "NVDIMM 0x%.8X. Commit and move onto the "
+ "next BPM",
+ nvdimmHuid);
+ }
+ else
+ {
+ continue;
+ }
+ }
+ else
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK
+ "An error occurred during a 16GB_TYPE BPM "
+ "update for NVDIMM 0x%.8X. "
+ "Commit and move onto the next BPM",
+ nvdimmHuid);
+ }
+ ERRORLOG::errlCommit(errl, BPM_COMP_ID);
+ }
+ }
+ }
+
+ if ( (i_32gb_BPMs != nullptr)
+ && (i_32gb_fwImage != nullptr)
+ && (i_32gb_configImage != nullptr))
+ {
+ TRACFCOMP(g_trac_bpm,
+ "Check/update %d BPMs on 32GB_TYPE NVDIMMs",
+ i_32gb_BPMs->size());
+
+ for(auto& bpm : *i_32gb_BPMs)
+ {
+ errl = bpm.runUpdate(*i_32gb_fwImage, *i_32gb_configImage);
+ if (errl != nullptr)
+ {
+ uint32_t nvdimmHuid = TARGETING::get_huid(bpm.getNvdimm());
+ if (bpm.attemptAnotherUpdate())
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK
+ "An error occurred during a 32GB_TYPE BPM "
+ "update for NVDIMM 0x%.8X. "
+ "Try again.",
+ nvdimmHuid);
+
+ delete errl;
+ errl = bpm.runUpdate(*i_32gb_fwImage,
+ *i_32gb_configImage);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK
+ "Another error occurred while attempting "
+ "to update the same 32GB_TYPE BPM for "
+ "NVDIMM 0x%.8X. Commit and move onto the "
+ "next BPM",
+ nvdimmHuid);
+ }
+ else
+ {
+ continue;
+ }
+ }
+ else
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK
+ "An error occurred during a 32GB_TYPE BPM "
+ "update for NVDIMM 0x%.8X. "
+ "Commit and move onto the next BPM",
+ nvdimmHuid);
+ }
+ ERRORLOG::errlCommit(errl, BPM_COMP_ID);
+ }
+ }
+ }
+ } while(0);
+}
+
+// =============================================================================
+// BpmFirmwareLidImage Class Functions
+// =============================================================================
+
+BpmFirmwareLidImage::BpmFirmwareLidImage(void * const i_lidImageAddr,
+ size_t i_size)
+ : iv_lidImage(i_lidImageAddr), iv_lidImageSize(i_size)
+{
+ assert(i_lidImageAddr != nullptr,
+ "BPM::BpmFirmwareLidImage(): Provided LID image must not be nullptr");
+}
+
+uint16_t BpmFirmwareLidImage::getVersion() const
+{
+ uint16_t version = INVALID_VERSION;
+
+ if (iv_lidImageSize >= sizeof(firmware_image_header_t))
+ {
+ const firmware_image_header_t * header =
+ reinterpret_cast<const firmware_image_header_t*>(iv_lidImage);
+
+ version = TWO_UINT8_TO_UINT16(header->iv_versionMajor,
+ header->iv_versionMinor);
+ }
+
+ return version;
+}
+
+uint16_t BpmFirmwareLidImage::getNumberOfBlocks() const
+{
+ uint16_t numberOfBlocks = 0;
+
+ if (iv_lidImageSize >= sizeof(firmware_image_header_t))
+ {
+ const firmware_image_header_t * header =
+ reinterpret_cast<const firmware_image_header_t*>(iv_lidImage);
+
+ numberOfBlocks = header->iv_numberOfBlocks;
+ }
+
+ return numberOfBlocks;
+}
+
+void const * BpmFirmwareLidImage::getFirstBlock() const
+{
+ void * block = nullptr;
+
+ if (getNumberOfBlocks() > 0)
+ {
+ block = reinterpret_cast<uint8_t* const>(iv_lidImage)
+ + sizeof(firmware_image_header_t);
+ }
+
+ return block;
+}
+
+// =============================================================================
+// BpmConfigLidImage Class Functions
+// =============================================================================
+
+BpmConfigLidImage::BpmConfigLidImage(void * const i_lidImageAddr,
+ size_t i_size)
+ : iv_lidImage(i_lidImageAddr), iv_lidImageSize(i_size)
+{
+ assert(i_lidImageAddr != nullptr,
+ "BPM::BpmConfigLidImage(): Provided LID image must not be nullptr");
+}
+
+uint16_t BpmConfigLidImage::getVersion() const
+{
+ uint16_t version = INVALID_VERSION;
+
+ if (iv_lidImageSize >= sizeof(config_image_header_t))
+ {
+ const config_image_header_t * header =
+ reinterpret_cast<const config_image_header_t*>(iv_lidImage);
+
+ version = TWO_UINT8_TO_UINT16(header->iv_versionMajor,
+ header->iv_versionMinor);
+ }
+
+ return version;
+}
+
+uint16_t BpmConfigLidImage::getNumberOfFragments() const
+{
+ uint16_t numberOfFragments = 0;
+
+ if (iv_lidImageSize >= sizeof(config_image_header_t))
+ {
+ const config_image_header_t * header =
+ reinterpret_cast<const config_image_header_t*>(iv_lidImage);
+
+ numberOfFragments = header->iv_numberOfFragments;
+ }
+
+ return numberOfFragments;
+}
+
+void const * BpmConfigLidImage::getFirstFragment() const
+{
+ void * fragment = nullptr;
+
+ if (getNumberOfFragments() > 0)
+ {
+ fragment = reinterpret_cast<uint8_t* const>(iv_lidImage)
+ + sizeof(config_image_header_t);
+ }
+
+ return fragment;
+}
+
+// =============================================================================
+// Bpm Class Functions
+// =============================================================================
+
+Bpm::Bpm(const TARGETING::TargetHandle_t i_nvdimm)
+ : iv_nvdimm(i_nvdimm),
+ iv_bslVersion(0),
+ iv_firmwareStartAddress(0),
+ iv_attemptAnotherUpdate(false),
+ iv_segmentDMerged(false),
+ iv_segmentBMerged(false),
+ iv_updateAttempted(false)
+{
+ assert((i_nvdimm != nullptr) && (isNVDIMM(i_nvdimm)),
+ "BPM::Bpm(): An nvdimm target must be given.");
+
+ memset(&iv_segmentD, 0, SEGMENT_SIZE);
+ memset(&iv_segmentB, 0, SEGMENT_SIZE);
+
+}
+
+bool Bpm::attemptAnotherUpdate()
+{
+ return iv_attemptAnotherUpdate;
+}
+
+bool Bpm::hasAttemptedUpdate()
+{
+ return iv_updateAttempted;
+}
+
+void Bpm::setAttemptAnotherUpdate()
+{
+
+ if (iv_updateAttempted)
+ {
+ // Since iv_updateAttempted is true that means that this function was
+ // called on a subsequent update attempt, meaning we should no longer
+ // attempt updates if the current attempt fails.
+ iv_attemptAnotherUpdate = false;
+ }
+ else
+ {
+ // Since iv_updateAttempted is false that means that this function was
+ // called on the first update attempt because by default
+ // iv_updateAttempted is false and is only set to true as the last part
+ // of the update procedure.
+ iv_attemptAnotherUpdate = true;
+ }
+
+}
+
+const TARGETING::TargetHandle_t Bpm::getNvdimm()
+{
+ return iv_nvdimm;
+}
+
+errlHndl_t Bpm::readBslVersion()
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::readBslVersion()");
+ errlHndl_t errl = nullptr;
+
+ do {
+ // Enter Update mode
+ errl = enterUpdateMode();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Verify in Update mode
+ errl = inUpdateMode();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Enter Bootstrap Loader (BSL) mode
+ errl = enterBootstrapLoaderMode();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Unlock the device. This is a BSL command so we must already be in
+ // BSL mode to execute it.
+ errl = unlockDevice();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Command to get the version is a BSL command, so it has to be sent as
+ // a payload.
+ payload_t payload;
+ errl = setupPayload(payload, BSL_TX_BSL_VERSION, BPM_ADDRESS_ZERO);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Issue the BSL command
+ errl = issueCommand(BPM_PASSTHROUGH,
+ payload,
+ WRITE,
+ NO_DELAY_EXTERNAL_RESPONSE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Get the result from the BPM.
+ errl = getResponse(&iv_bslVersion, sizeof(uint8_t));
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::readBslVersion(): "
+ "Failed to determine BSL Version.");
+ break;
+ }
+
+ TRACFCOMP(g_trac_bpm, "Bpm::readBslVersion(): BSL Version is 0x%X",
+ iv_bslVersion);
+ } while(0);
+
+ // Reset the device. This will exit BSL mode.
+ errlHndl_t exitErrl = resetDevice();
+ if (exitErrl != nullptr)
+ {
+ handleMultipleErrors(errl, exitErrl);
+ }
+
+ // Exit update mode
+ exitErrl = exitUpdateMode();
+ if (exitErrl != nullptr)
+ {
+ handleMultipleErrors(errl, exitErrl);
+ }
+
+ return errl;
+}
+
+errlHndl_t Bpm::getFwVersion(uint16_t & o_fwVersion) const
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::getFwVersion()");
+ errlHndl_t errl = nullptr;
+
+ do {
+ uint8_t bpmMajor = 0, bpmMinor = 0;
+ errl = nvdimmReadReg(iv_nvdimm,
+ ES_FWREV1,
+ bpmMajor);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::getFwVersion(): "
+ "Failed to read BPM major version byte");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ errl = nvdimmReadReg(iv_nvdimm,
+ ES_FWREV0,
+ bpmMinor);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::getFwVersion(): "
+ "Failed to read BPM minor version byte");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ o_fwVersion = TWO_UINT8_TO_UINT16(bpmMajor, bpmMinor);
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::issueCommand(const uint8_t i_bspCommand,
+ const uint8_t i_command,
+ const uint8_t i_opType,
+ const int i_msDelay)
+{
+ assert(isBspCommand(i_bspCommand),
+ "i_bspCommand must be a valid BSP command");
+ assert(isBclCommand(i_command),
+ "i_command must be a valid BCL command");
+ // i_opType gets set in the BPM_CMD_STATUS register where it is only given
+ // two bits. So any value above 3 is not valid.
+ assert(i_opType <= 3, "i_opType can only range between 0 and 3");
+
+ errlHndl_t errl = nullptr;
+
+ // i_command must be sent in BPM_REG_PAYLOAD_START, but it doesn't need to
+ // be formatted into a typical payload since the command isn't a BSL
+ // command. So, just create a payload_t, push_back the command, and let the
+ // issueCommand function that takes a payload_t parameter handle the rest.
+ payload_t payloadCommand;
+ payloadCommand.push_back(i_command);
+
+ errl = issueCommand(i_bspCommand, payloadCommand, i_opType, i_msDelay);
+
+ return errl;
+}
+
+errlHndl_t Bpm::issueCommand(const uint8_t i_command,
+ payload_t i_payload,
+ const uint8_t i_opType,
+ const int i_msDelay)
+{
+ assert(isBspCommand(i_command),
+ "i_bspCommand must be a valid BSP command");
+
+ // i_opType gets set in the BPM_CMD_STATUS register where it is only given
+ // two bits. So any value above 3 is not valid.
+ assert(i_opType <= 3, "i_opType can only range between 0 and 3");
+
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ // Check the full payload size to make sure it's not too large. Add the
+ // size of the SYNC_BYTE that was dropped during payload creation to
+ // verify that the full payload sent by the NVDIMM won't exceed the max
+ // size the BPM is able to receive.
+ if ((i_payload.size() + SYNC_BYTE_SIZE) > MAX_PAYLOAD_SIZE)
+ {
+ uint8_t payloadSize = i_payload.size() + SYNC_BYTE_SIZE;
+ uint8_t payloadHeaderDataSize =
+ i_payload[PAYLOAD_HEADER_DATA_LENGTH_INDEX];
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::issueCommand(): "
+ "payload size %d exceeds max payload size of %d",
+ payloadSize, MAX_PAYLOAD_SIZE);
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_ISSUE_COMMAND
+ * @reasoncode BPM_RC::BPM_INVALID_PAYLOAD_SIZE
+ * @userdata1[00:31] Full Payload Size, including SYNC_BYTE
+ * @userdata1[32:63] MAX_PAYLOAD_SIZE
+ * @userdata2[00:31] Payload Header + Data size
+ * @userdata2[32:63] NVDIMM Target HUID associated with this BPM
+ * @devdesc The maximum payload size to be sent to the BPM
+ * was exceeded.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_ISSUE_COMMAND,
+ BPM_RC::BPM_INVALID_PAYLOAD_SIZE,
+ TWO_UINT16_TO_UINT32(payloadSize,
+ MAX_PAYLOAD_SIZE),
+ TWO_UINT32_TO_UINT64(
+ payloadHeaderDataSize,
+ TARGETING::get_huid(iv_nvdimm))
+ );
+ errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ break;
+ }
+
+ // Load the payload
+ int i = 0;
+ for (const auto& byte : i_payload)
+ {
+ errl = nvdimmWriteReg(iv_nvdimm,
+ (BPM_REG_PAYLOAD_START + (i * sizeof(uint8_t))),
+ byte);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::issueCommand(): "
+ "Failed to write payload to BPM_REG_PAYLOAD_START");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ ++i;
+ }
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Clear the error status register
+ errl = nvdimmWriteReg(iv_nvdimm,
+ BPM_REG_ERR_STATUS,
+ 0x00);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::issueCommand(): "
+ "Failed to clear error status register");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ // Set the payload length. This is the actual length of the payload
+ // excluding the size of the SYNC_BYTE that was dropped during payload
+ // creation which is already missing from size().
+ uint8_t data = i_payload.size();
+ errl = nvdimmWriteReg(iv_nvdimm,
+ BPM_PAYLOAD_LENGTH,
+ data);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::issueCommand(): "
+ "Failed to set payload length");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ // Setup the command status register
+ command_status_register_t commandStatus;
+ commandStatus.bits.Bsp_Cmd_In_Progress = 1;
+ commandStatus.bits.Operator_Type = i_opType;
+ errl = nvdimmWriteReg(iv_nvdimm,
+ BPM_CMD_STATUS,
+ commandStatus.value);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::issueCommand(): "
+ "Failed to setup the command status register");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ // Setup command type. The basically executes the command
+ errl = nvdimmWriteReg(iv_nvdimm,
+ BPM_REG_CMD,
+ i_command);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::issueCommand(): "
+ "Failed to set the command type. "
+ "The command was not issued to the BPM");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ errl = waitForCommandStatusBitReset(commandStatus);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // If a delay was given then wait for the delay and check the response.
+ // Otherwise, do not wait and do not check the response. For a list of
+ // commands and delays, see bpm_update.H for more info.
+ if (i_msDelay > 0)
+ {
+ // Wait the given time in ms. Default 1ms for most commands.
+ nanosleep(0, i_msDelay * NS_PER_MSEC);
+
+ // Check the response from the BPM. A non-zero response value
+ // indicates failure. So, assume a failure and check for success.
+ uint8_t data = 0xFF;
+ errl = getResponse(&data, sizeof(uint8_t));
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // If the data read from the response is a non-zero value then the
+ // issued command failed.
+ if (data != 0)
+ {
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_ISSUE_COMMAND
+ * @reasoncode BPM_RC::BPM_BAD_RESPONSE
+ * @userdata1 The command that failed to execute.
+ * See bpm_update.H for list of commands.
+ * @userdata2 NVDIMM Target HUID associated with this BPM
+ * @devdesc The command sent to the BPM failed.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_ISSUE_COMMAND,
+ BPM_RC::BPM_BAD_RESPONSE,
+ i_payload[PAYLOAD_COMMAND_INDEX],
+ TARGETING::get_huid(iv_nvdimm));
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ break;
+ }
+ }
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::runUpdate(BpmFirmwareLidImage i_fwImage,
+ BpmConfigLidImage i_configImage)
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::runUpdate(): "
+ "Running BPM Update for NVDIMM 0x%.8X",
+ TARGETING::get_huid(iv_nvdimm));
+
+ errlHndl_t errl = nullptr;
+ // Assume an update is necessary for the BPM and determine if it isn't.
+ bool shouldPerformUpdate = true;
+
+ // Get the sys target to check for attribute overrides.
+ TARGETING::Target* sys = nullptr;
+ TARGETING::targetService().getTopLevelTarget(sys);
+
+ auto updateOverride =
+ sys->getAttr<TARGETING::ATTR_BPM_UPDATE_OVERRIDE>();
+ uint16_t firmwareOverrideFlag = (updateOverride & 0xFF00);
+ uint16_t configOverrideFlag = (updateOverride & 0x00FF);
+
+ do {
+
+ // First check if there is a BPM connected
+ errl = verifyGoodBpmState();
+ if (errl != nullptr)
+ {
+ // Either there isn't a BPM connected to this NVDIMM or it's not
+ // functional. Don't bother with updates.
+ shouldPerformUpdate = false;
+ iv_attemptAnotherUpdate = false;
+ break;
+ }
+
+ // Check the version on the BPM against the version in the image.
+ uint16_t bpmFwVersion = INVALID_VERSION;
+ errl = getFwVersion(bpmFwVersion);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::runUpdate(): "
+ "Could not determine firmware version on BPM "
+ "Skipping update.");
+ break;
+ }
+
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::runUpdate(): "
+ "Firmware version on the BPM 0x%.4X, "
+ "Firmware version of image 0x%.4X.",
+ bpmFwVersion, i_fwImage.getVersion());
+
+ if (i_fwImage.getVersion() == bpmFwVersion)
+ {
+ shouldPerformUpdate = false;
+ if (updateOverride == TARGETING::BPM_UPDATE_BEHAVIOR_DEFAULT_ALL)
+ {
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::runUpdate(): "
+ "Firmware version on the BPM matches the version in "
+ "the image. Skipping update.");
+ break;
+ }
+ }
+
+ if (updateOverride == TARGETING::BPM_UPDATE_BEHAVIOR_SKIP_ALL)
+ {
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::runUpdate(): "
+ "ATTR_BPM_UPDATE_OVERRIDE set to SKIP_ALL. "
+ "Skipping update.");
+ break;
+ }
+
+ // Depending on the BSL version a CRC check may be necessary
+ errl = readBslVersion();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // If the BSL version read from the BPM isn't a supported version then
+ // don't perform the updates as the update flow may have changed between
+ // BSL versions.
+ if (iv_bslVersion != BSL_VERSION_1_4)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::runUpdate(): "
+ "Unsupported BSL Version 0x%.2X detected on BPM. "
+ "Cancelling Update.");
+
+ break;
+ }
+
+ if ((shouldPerformUpdate
+ || (firmwareOverrideFlag == TARGETING::BPM_UPDATE_BEHAVIOR_FORCE_FW))
+ && !(firmwareOverrideFlag == TARGETING::BPM_UPDATE_BEHAVIOR_SKIP_FW))
+ {
+ if (firmwareOverrideFlag == TARGETING::BPM_UPDATE_BEHAVIOR_FORCE_FW)
+ {
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::runUpdate(): "
+ "ATTR_BPM_UPDATE_OVERRIDE set to force firmware "
+ "portion of BPM updates. Running Firmware Update...");
+ }
+
+ errl = runFirmwareUpdates(i_fwImage);
+ if (errl != nullptr)
+ {
+ break;
+ }
+ }
+ else
+ {
+ if (firmwareOverrideFlag == TARGETING::BPM_UPDATE_BEHAVIOR_SKIP_FW)
+ {
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::runUpdate(): "
+ "ATTR_BPM_UPDATE_OVERRIDE set to skip firmware "
+ "portion of BPM updates. Skipping Firmware Update...");
+ }
+ else
+ {
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::runUpdate(): "
+ "Firmware Data on BPM already up-to-date. "
+ "Skipping Firmware Update...");
+ }
+ }
+
+ if ((shouldPerformUpdate
+ || (configOverrideFlag == TARGETING::BPM_UPDATE_BEHAVIOR_FORCE_CONFIG))
+ && !(configOverrideFlag == TARGETING::BPM_UPDATE_BEHAVIOR_SKIP_CONFIG))
+ {
+ if (configOverrideFlag == TARGETING::BPM_UPDATE_BEHAVIOR_FORCE_CONFIG)
+ {
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::runUpdate(): "
+ "ATTR_BPM_UPDATE_OVERRIDE set to force config "
+ "portion of BPM updates. Running Config Update...");
+ }
+ errl = runConfigUpdates(i_configImage);
+ if (errl != nullptr)
+ {
+ break;
+ }
+ }
+ else
+ {
+ if (configOverrideFlag == TARGETING::BPM_UPDATE_BEHAVIOR_SKIP_CONFIG)
+ {
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::runUpdate(): "
+ "ATTR_BPM_UPDATE_OVERRIDE set to skip config "
+ "portion of BPM updates. Skipping Config Update...");
+ }
+ else
+ {
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::runUpdate(): "
+ "Configuration Data on BPM already up-to-date. "
+ "Skipping Config Update...");
+ }
+ }
+
+ } while(0);
+
+ if ((shouldPerformUpdate
+ || (configOverrideFlag == TARGETING::BPM_UPDATE_BEHAVIOR_FORCE_CONFIG)
+ || (firmwareOverrideFlag == TARGETING::BPM_UPDATE_BEHAVIOR_FORCE_FW))
+ && (updateOverride != TARGETING::BPM_UPDATE_BEHAVIOR_SKIP_ALL))
+ {
+ // Reset controller and unlock encryption if necessary
+ errlHndl_t exitErrl = nvdimmResetController(iv_nvdimm);
+ if (exitErrl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::runUpdate() "
+ "Couldn't reset NVDIMM controller.");
+ handleMultipleErrors(errl, exitErrl);
+ }
+
+ // If the update was successful then we must wait for 15 seconds before
+ // polling the status of the BPM since it has to finish updating its
+ // firmware and resetting.
+ TRACFCOMP(g_trac_bpm, "Bpm::runUpdate(): "
+ "Wait for the BPM to finish update and reset procedure, "
+ "sleep for 15 seconds");
+ longSleep(15);
+
+ // Poll SCAP_STATUS register for BPM state before we check final
+ // firmware version.
+ exitErrl = verifyGoodBpmState();
+ if (exitErrl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::runUpdate(): "
+ "Could not verify that BPM was present and enabled!");
+ handleMultipleErrors(errl, exitErrl);
+ }
+
+ uint16_t bpmFwVersion = INVALID_VERSION;
+ exitErrl = getFwVersion(bpmFwVersion);
+ if (exitErrl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::runUpdate(): "
+ "Could not determine firmware version on the BPM");
+ handleMultipleErrors(errl, exitErrl);
+ }
+
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::runUpdate(): "
+ "Firmware version on the BPM 0x%.4X, "
+ "Firmware version of image 0x%.4X.",
+ bpmFwVersion, i_fwImage.getVersion());
+
+ if (i_fwImage.getVersion() == bpmFwVersion)
+ {
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::runUpdate(): "
+ "Firmware version on the BPM matches the version in the "
+ "image. Firmware Update Successful.");
+ iv_attemptAnotherUpdate = false;
+ }
+ else
+ {
+ // Attempt another update if one hasn't already been attempted.
+ setAttemptAnotherUpdate();
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::runUpdate(): "
+ "Version on BPM didn't match image. %s ",
+ iv_attemptAnotherUpdate ?
+ "Attempt another update..."
+ : "Attempts to update the BPM have failed.");
+ if (iv_attemptAnotherUpdate == false)
+ {
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid BPM_RC::BPM_RUN_FW_UPDATES
+ * @reasoncode BPM_RC::BPM_VERSION_MISMATCH
+ * @userdata1[00:31] Version on the BPM
+ * @userdata1[32:63] Version of the flash image
+ * @userdata2 NVDIMM Target HUID associated with this BPM
+ * @devdesc The version on the BPM didn't match the
+ * version in the flash image.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ exitErrl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ BPM_RC::BPM_RUN_FW_UPDATES,
+ BPM_RC::BPM_VERSION_MISMATCH,
+ TWO_UINT32_TO_UINT64(bpmFwVersion,
+ i_fwImage.getVersion()),
+ TARGETING::get_huid(iv_nvdimm));
+ exitErrl->collectTrace(BPM_COMP_NAME);
+ handleMultipleErrors(errl, exitErrl);
+ }
+ }
+
+ TRACFCOMP(g_trac_bpm, EXIT_MRK"Bpm::runUpdate(): "
+ "Concluding BPM Update for NVDIMM 0x%.8X %s",
+ TARGETING::get_huid(iv_nvdimm),
+ (errl != nullptr) ? "with errors" : "without errors");
+ }
+
+ // An update has been attempted at least once. Set member variable to true
+ // to dictate future update attempts. This variable should only be set at
+ // the end of the update procedure in order to properly control future
+ // update attempts.
+ iv_updateAttempted = true;
+
+ if (errl == nullptr)
+ {
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_INFORMATIONAL
+ * @moduleid BPM_RC::BPM_RUN_UPDATE
+ * @reasoncode BPM_RC::BPM_UPDATE_SUCCESSFUL
+ * @userdata1 NVDIMM Target HUID associated with this BPM
+ * @devdesc BPM Update finished without errors.
+ * @custdesc Informational log associated with DIMM updates.
+ */
+ errlHndl_t infoErrl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ BPM_RC::BPM_RUN_UPDATE,
+ BPM_RC::BPM_UPDATE_SUCCESSFUL,
+ TARGETING::get_huid(iv_nvdimm));
+ infoErrl->collectTrace(BPM_COMP_NAME);
+ ERRORLOG::errlCommit(infoErrl, BPM_COMP_ID);
+ }
+
+ return errl;
+}
+
+errlHndl_t Bpm::inUpdateMode()
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::inUpdateMode()");
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ errl = issueCommand(BPM_LOCAL,
+ BCL_IS_UPDATE_IN_PROGRESS,
+ READ,
+ NO_DELAY_NO_RESPONSE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ uint8_t isUpdateInProgress = 0;
+ errl = nvdimmReadReg(iv_nvdimm,
+ BPM_REG_ERR_STATUS,
+ isUpdateInProgress);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::inUpdateMode(): "
+ "Failed to read error status register");
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ break;
+ }
+
+ if (!isUpdateInProgress)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::inUpdateMode(): "
+ "Failed to enter update mode");
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_IN_UPDATE_MODE
+ * @reasoncode BPM_RC::BPM_UPDATE_MODE_VERIFICATION_FAIL
+ * @userdata1 NVDIMM Target HUID associated with this BPM
+ * @devdesc Failed to verify update mode was entered using
+ * the BSL interface.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_IN_UPDATE_MODE,
+ BPM_RC::BPM_UPDATE_MODE_VERIFICATION_FAIL,
+ TARGETING::get_huid(iv_nvdimm));
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ break;
+ }
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::enterUpdateMode()
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::enterUpdateMode()");
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ // Disable write protection on the BPM. Otherwise, we can't write the
+ // magic values that enable the nvdimm-bpm interface.
+ errl = disableWriteProtection();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Write the magic values to enable nvdimm-bpm interface
+ errl = writeToMagicRegisters(UPDATE_MODE_MAGIC_VALUES);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::enterUpdateMode(): "
+ "Failed to write magic numbers that enable "
+ "update mode");
+ break;
+ }
+
+ TRACFCOMP(g_trac_bpm, "Bpm::enterUpdateMode(): "
+ "Issuing BPM_LOCAL BCL_START_UPDATE command.");
+
+ errl = issueCommand(BPM_LOCAL,
+ BCL_START_UPDATE,
+ WRITE,
+ NO_DELAY_NO_RESPONSE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ nanosleep(2,0);
+
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_INFORMATIONAL
+ * @moduleid BPM_RC::BPM_START_UPDATE
+ * @reasoncode BPM_RC::BPM_ENTER_UPDATE_MODE
+ * @userdata1 NVDIMM Target HUID associated with this BPM
+ * @devdesc BPM has entered update mode.
+ * @custdesc Informational log associated with DIMM updates.
+ */
+ errlHndl_t infoErrl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ BPM_RC::BPM_START_UPDATE,
+ BPM_RC::BPM_ENTER_UPDATE_MODE,
+ TARGETING::get_huid(iv_nvdimm));
+ infoErrl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ infoErrl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddVendorLog(iv_nvdimm, infoErrl);
+ nvdimmAddPage4Regs(iv_nvdimm, infoErrl);
+ ERRORLOG::errlCommit(infoErrl, BPM_COMP_ID);
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::exitUpdateMode()
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::exitUpdateMode()");
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ errl = writeToMagicRegisters(UPDATE_MODE_MAGIC_VALUES);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::exitUpdateMode(): "
+ "Failed to write the update magic values to "
+ " be able to send BPM_LOCAL commands.");
+ break;
+ }
+
+ errl = issueCommand(BPM_LOCAL,
+ BCL_IS_UPDATE_IN_PROGRESS,
+ READ,
+ NO_DELAY_NO_RESPONSE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ uint8_t isUpdateInProgress = 0;
+ errl = nvdimmReadReg(iv_nvdimm,
+ BPM_REG_ERR_STATUS,
+ isUpdateInProgress);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::exitUpdateMode(): "
+ "Failed to read BPM_REG_ERR_STATUS register to determine "
+ "if BPM is in update mode.");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ // Sending the exit update command when the BPM isn't in update mode can
+ // cause unpredicatable behavior and errors.
+ if (isUpdateInProgress)
+ {
+ errl = issueCommand(BPM_LOCAL,
+ BCL_END_UPDATE,
+ WRITE,
+ NO_DELAY_NO_RESPONSE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+ }
+ else
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::exitUpdateMode(): "
+ "Not in update mode. "
+ "Exit update command will not be sent.");
+ }
+
+ // Write back the production magic values
+ errl = writeToMagicRegisters(PRODUCTION_MAGIC_VALUES);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::exitUpdateMode(): "
+ "Failed to write the production magic values to "
+ "disable update mode.");
+ break;
+ }
+
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_INFORMATIONAL
+ * @moduleid BPM_RC::BPM_END_UPDATE
+ * @reasoncode BPM_RC::BPM_EXIT_UPDATE_MODE
+ * @userdata1 NVDIMM Target HUID associated with this BPM
+ * @devdesc BPM has exited update mode.
+ * @custdesc Informational log associated with DIMM updates.
+ */
+ errlHndl_t infoErrl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ BPM_RC::BPM_END_UPDATE,
+ BPM_RC::BPM_EXIT_UPDATE_MODE,
+ TARGETING::get_huid(iv_nvdimm));
+ infoErrl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ infoErrl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddVendorLog(iv_nvdimm, infoErrl);
+ nvdimmAddPage4Regs(iv_nvdimm, infoErrl);
+ ERRORLOG::errlCommit(infoErrl, BPM_COMP_ID);
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::updateFirmware(BpmFirmwareLidImage i_image)
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::updateFirmware()");
+ errlHndl_t errl = nullptr;
+
+ // The reset vector address is near the end of the firmware section.
+ // We must do a special operation on it when it shows up during the update.
+ const uint16_t RESET_VECTOR_ADDRESS = 0xFFFE;
+
+ bool mainAddressEncountered = false;
+
+ // Get the number of blocks in the image
+ const uint16_t NUMBER_OF_BLOCKS = i_image.getNumberOfBlocks();
+
+ char const * data =
+ reinterpret_cast<char const *>(i_image.getFirstBlock());
+
+ firmware_image_block_t const * block =
+ reinterpret_cast<firmware_image_block_t const *>
+ (data);
+
+ for(size_t i = 0; i < NUMBER_OF_BLOCKS; ++i)
+ {
+ // This is done once at the main program address.
+ if ( ((block->iv_addressOffset == MAIN_PROGRAM_ADDRESS)
+ || (block->iv_addressOffset == MAIN_PROGRAM_ADDRESS_ALT))
+ && !mainAddressEncountered)
+ {
+ // Only execute this once.
+ mainAddressEncountered = true;
+
+ // Save the firmware start address for later. This will be needed
+ // for the final CRC check when the update is completed.
+ iv_firmwareStartAddress = block->iv_addressOffset;
+
+ payload_t payload;
+ errl = setupPayload(payload,
+ BSL_MASS_ERASE,
+ iv_firmwareStartAddress);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ errl = issueCommand(BPM_PASSTHROUGH,
+ payload,
+ WRITE,
+ ERASE_FIRMWARE_DELAY);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ TRACFCOMP(g_trac_bpm, "Bpm::updateFirmware(): "
+ "Performing BSL_MASS_ERASE on BPM, sleep for 5 seconds.");
+ longSleep(5);
+
+ TRACFCOMP(g_trac_bpm, "Bpm::updateFirmware(): "
+ "Begin writing flash image to BPM "
+ "with a starting address of 0x%.4X",
+ iv_firmwareStartAddress);
+
+ }
+
+ if (block->iv_addressOffset % 0x400 == 0)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::updateFirmware(): "
+ "Writing to address offset 0x%.4X. "
+ "Firmware blocks written: %d; Remaining: %d",
+ block->iv_addressOffset,
+ i, (NUMBER_OF_BLOCKS - i));
+ }
+
+ // Construct the payload for this block in the image
+ payload_t payload;
+ errl = setupPayload(payload, block, BSL_RX_DATA_BLOCK);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ if (block->iv_addressOffset == RESET_VECTOR_ADDRESS)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::updateFirmware(): "
+ "Encountered RESET_VECTOR_ADDRESS 0x%.4X. "
+ "Attempt to write RESET_VECTOR to BPM up to %d times.",
+ RESET_VECTOR_ADDRESS,
+ MAX_RETRY);
+ // Attempting to BSL_VERIFY_BLOCK on the reset vector data will
+ // fail. To verify that this data is written correctly we will check
+ // the response packet sent by the BPM.
+ const uint8_t RESET_VECTOR_RECEIVE_SUCCESS = 0x80;
+ uint8_t retry = 1;
+ do
+ {
+ // Issue the write command to the BPM.
+ // The RESET_VECTOR is special in that its response is checked
+ // externally.
+ errl = issueCommand(BPM_PASSTHROUGH,
+ payload,
+ WRITE,
+ NO_DELAY_EXTERNAL_RESPONSE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Get the response packet and verify that the status is
+ // RESET_VECTOR_RECEIVE_SUCCESS.
+ //
+ // Any status besides RESET_VECTOR_RECEIVE_SUCCESS is considered
+ // a fail. So, assume a failure and check.
+ uint8_t status = 0xFF;
+ errl = getResponse(&status,
+ sizeof(uint8_t));
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ if (status != RESET_VECTOR_RECEIVE_SUCCESS)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::updateFirmware(): "
+ "status %d from BPM was not "
+ "RESET_VECTOR_RECEIVE_SUCCESS value of %d. "
+ "Retrying...",
+ status,
+ RESET_VECTOR_RECEIVE_SUCCESS);
+
+ if (++retry > MAX_RETRY)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::updateFirmware(): "
+ "Never received RESET_VECTOR_RECEIVE_SUCCESS "
+ "status from BPM in three attempts. "
+ "Aborting Update");
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_UPDATE_FIRMWARE
+ * @reasoncode BPM_RC::BPM_RESET_VECTOR_NEVER_RECEIVED
+ * @userdata1 NVDIMM Target HUID associated with this BPM
+ * @devdesc RESET_VECTOR_RECEIVE_SUCCESS status was not
+ * received in three attempts.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_UPDATE_FIRMWARE,
+ BPM_RC::BPM_RESET_VECTOR_NEVER_RECEIVED,
+ TARGETING::get_huid(iv_nvdimm));
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+
+ // Change the state of iv_attemptAnotherUpdate to signal
+ // if another update attempt should occur.
+ setAttemptAnotherUpdate();
+
+ break;
+ }
+ }
+ else
+ {
+ // RESET_VECTOR was written and received successfully.
+ // Exit retry loop.
+ break;
+ }
+
+ // Sleep for 0.001 second before attempting again.
+ nanosleep(0, 1 * NS_PER_MSEC);
+
+ } while(retry <= MAX_RETRY);
+ if (errl != nullptr)
+ {
+ break;
+ }
+ }
+ else
+ {
+ // Attempt to write the data using a retry loop. This will also
+ // verify that the data was correctly written to the BPM.
+ errl = blockWrite(payload);
+ if (errl != nullptr)
+ {
+ break;
+ }
+ }
+
+ // Move to the next block
+ // iv_blocksize doesn't include the sizeof itself. So, add another byte
+ // for it.
+ data += block->iv_blockSize + sizeof(uint8_t);
+ block = reinterpret_cast<firmware_image_block_t const *>(data);
+ }
+
+ TRACFCOMP(g_trac_bpm, EXIT_MRK"Bpm::updateFirmware(): "
+ "Firmware flash image write and verification completed "
+ "%s",
+ (errl == nullptr) ? "without errors" : "with errors");
+
+ return errl;
+}
+
+errlHndl_t Bpm::updateConfig()
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::updateConfig()");
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ // Erase Segment D on the BPM via the BSL interface.
+ errl = eraseSegment(SEGMENT_D_CODE);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::updateConfig(): "
+ "Failed to erase Segment D.");
+ break;
+ }
+
+ // Write the updated Segment D buffer to the BPM via the BSL interface.
+ errl = writeSegment(iv_segmentD, SEGMENT_D_CODE);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::updateConfig(): "
+ "Failed to write Segment D.");
+ break;
+ }
+
+
+ // Erase Segment B on the BPM via the BSL interface.
+ errl = eraseSegment(SEGMENT_B_CODE);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::updateConfig(): "
+ "Failed to erase Segment B.");
+ break;
+ }
+
+ // Write the updated Segment B buffer to the BPM via the BSL interface.
+ errl = writeSegment(iv_segmentB, SEGMENT_B_CODE);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::updateConfig(): "
+ "Failed to write Segment B.");
+ break;
+ }
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::enterBootstrapLoaderMode()
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::enterBootstrapLoaderMode()");
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ // Entering BSL mode depends on the state of the BPM and it may need
+ // several retries in order to successfully enter BSL mode.
+ int retry = 5;
+ bool inBslMode = false;
+
+ while (retry != 0)
+ {
+
+ errl = issueCommand(BPM_LOCAL,
+ BCL_IS_BSL_MODE,
+ WRITE,
+ NO_DELAY_NO_RESPONSE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ uint8_t data = 0;
+ errl = nvdimmReadReg(iv_nvdimm,
+ BPM_REG_ERR_STATUS,
+ data);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::enterBootstrapLoaderMode(): "
+ "Failed to read BPM_REG_ERR_STATUS to verify that "
+ "BSL mode was enabled.");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+ // data will be 1 if the BPM successfully entered BSL mode.
+ if (data == 1)
+ {
+ inBslMode = true;
+ TRACFCOMP(g_trac_bpm, "Bpm::enterBootstrapLoaderMode(): "
+ "BSL Mode entered, sleep for 5 seconds.");
+ longSleep(5);
+ break;
+ }
+
+ // Sleep for 0.001 second.
+ nanosleep(0, 1 * NS_PER_MSEC);
+
+ errl = issueCommand(BPM_LOCAL,
+ BCL_ENTER_BSL_MODE,
+ WRITE,
+ NO_DELAY_NO_RESPONSE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ TRACUCOMP(g_trac_bpm, "Bpm::enterBootstrapLoaderMode(): "
+ "Unable to enter BSL Mode, retries remaining %d. "
+ "Sleep for 2 seconds before trying again.",
+ (retry - 1));
+ nanosleep(2,0);
+ --retry;
+
+ }
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ if (!inBslMode)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::enterBootstrapLoaderMode(): "
+ "Failed to enter BSL mode on the BPM");
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_ENTER_BSL_MODE
+ * @reasoncode BPM_RC::BPM_FAILED_TO_ENTER_BSL_MODE
+ * @userdata1[0:63] NVDIMM Target HUID associated with this BPM
+ * @devdesc Failed to enter BSL mode after several attempts.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_ENTER_BSL_MODE,
+ BPM_RC::BPM_FAILED_TO_ENTER_BSL_MODE,
+ TARGETING::get_huid(iv_nvdimm));
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ break;
+ }
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::setupPayload(payload_t & o_payload,
+ const uint8_t i_command,
+ const uint16_t i_address,
+ const uint8_t i_data[],
+ const size_t i_length)
+{
+ // Enforce sane inputs
+ assert(( (i_data == nullptr && i_length == 0)
+ || (i_data != nullptr && i_length != 0)),
+ "if i_length is non-zero then i_data must not be nullptr, otherwise i_data must be nullptr.");
+ assert(isBslCommand(i_command),
+ "i_command must be a valid BSL command");
+
+ errlHndl_t errl = nullptr;
+
+ // Calculate the block size.
+ size_t blockSize = sizeof(uint16_t) + i_length;
+
+ // Allocate memory for the block
+ firmware_image_block_t* myBlock = reinterpret_cast<firmware_image_block_t*>(
+ malloc(sizeof(firmware_image_block_t) + i_length));
+
+ // Setup the block "header" info
+ myBlock->iv_blockSize = blockSize;
+ myBlock->iv_addressOffset = i_address;
+
+ // Copy the data if any exists.
+ if (i_data != nullptr)
+ {
+ memcpy(&myBlock->iv_data, i_data, i_length);
+ }
+
+ // Setup the return payload
+ errl = setupPayload(o_payload, myBlock, i_command);
+
+ // Block is no longer needed.
+ free(myBlock);
+
+ return errl;
+}
+
+errlHndl_t Bpm::setupPayload(payload_t & o_payload,
+ const firmware_image_block_t * i_block,
+ const uint8_t i_command)
+{
+ assert(i_block != nullptr, "i_block must not be nullptr.");
+ assert(isBslCommand(i_command),
+ "i_command must be a valid BSL command");
+
+ errlHndl_t errl = nullptr;
+
+ // The data size in the block is the total block size
+ // minus the 2 bytes for the address offset.
+ const uint8_t blockDataSize = i_block->iv_blockSize - sizeof(uint16_t);
+
+ // The header plus payload data section size. This excludes the address
+ // offset, extra bytes, and CRC bytes.
+ const uint8_t headerDataSize = PAYLOAD_HEADER_SIZE + blockDataSize;
+
+ do {
+
+ if (blockDataSize > MAX_PAYLOAD_DATA_SIZE)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK
+ "Bpm::setupPayload(): Block Data Size %d exceeds max payload "
+ "size of %d",
+ blockDataSize,
+ MAX_PAYLOAD_DATA_SIZE);
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_SETUP_PAYLOAD
+ * @reasoncode BPM_RC::BPM_INVALID_PAYLOAD_DATA_SIZE
+ * @userdata1[0:7] Block Data Size
+ * @userdata1[8:15] MAX_PAYLOAD_DATA_SIZE
+ * @userdata2[0:63] NVDIMM Target HUID associated with this BPM
+ * @devdesc Failed to enter BSL mode after several attempts.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_SETUP_PAYLOAD,
+ BPM_RC::BPM_INVALID_PAYLOAD_DATA_SIZE,
+ TWO_UINT8_TO_UINT16(blockDataSize,
+ MAX_PAYLOAD_DATA_SIZE),
+ TARGETING::get_huid(iv_nvdimm));
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ break;
+ }
+
+ // Create the payload with the exact size needed.
+ payload_t payload(MAX_PAYLOAD_OTHER_DATA_SIZE + blockDataSize);
+
+ // Instead of using push_back, use a pointer to an element in the vector.
+ // Since the size of the vector is declared and intialized to zero ahead of
+ // time push_back will not work. Also, some of the data is larger than
+ // uint8_t and so it's easier to just use memcpy for insertion.
+ // NOTE: Because push_back isn't being used the size() of the vector doesn't
+ // change along with the data being added to the vector. This was
+ // corrected by explicitly setting the payload size in the constructor
+ // call above.
+ uint8_t * payloadIterator = payload.data();
+
+ // According to SMART, we must supply the header + data size twice.
+ uint8_t header[PAYLOAD_HEADER_SIZE] = { SYNC_BYTE,
+ i_command,
+ headerDataSize,
+ headerDataSize };
+
+ memcpy(payloadIterator, &header, PAYLOAD_HEADER_SIZE);
+
+ // Move past the header
+ payloadIterator += PAYLOAD_HEADER_SIZE;
+
+ // Write the address offset in little endian form.
+ uint16_t addressLE = htole16(i_block->iv_addressOffset);
+ uint8_t* addressOffset = reinterpret_cast<uint8_t*>(&addressLE);
+ memcpy(payloadIterator, addressOffset, sizeof(uint16_t));
+
+ // Move past the address
+ payloadIterator += sizeof(uint16_t);
+
+ // The extra bytes vary based on the given command.
+ // These are the extra bytes for their corresponding bootstrap loader
+ // commands. They are arranged in little endian form so that no byte
+ // swapping is required.
+ const uint8_t BSL_ERASE_SEGMENT_EXTRA_BYTES[] = {0x02, 0xA5};
+ const uint8_t BSL_MASS_ERASE_EXTRA_BYTES[] = {0x06, 0xA5};
+ switch(i_command)
+ {
+ case BSL_ERASE_SEGMENT:
+ {
+ memcpy(payloadIterator,
+ &BSL_ERASE_SEGMENT_EXTRA_BYTES,
+ sizeof(uint16_t));
+
+ break;
+ }
+ case BSL_MASS_ERASE:
+ {
+ memcpy(payloadIterator,
+ &BSL_MASS_ERASE_EXTRA_BYTES,
+ sizeof(uint16_t));
+ break;
+ }
+ default:
+ {
+ // Give the size of the data section as a uint16_t in little
+ // endian form.
+ uint8_t dataLength[] = {blockDataSize, 0x0};
+ memcpy(payloadIterator, &dataLength, sizeof(uint16_t));
+ break;
+ }
+ }
+
+ // Move past the payload's extra bytes.
+ payloadIterator += sizeof(uint16_t);
+
+ if (blockDataSize > 0)
+ {
+ // Copy the payload data from the LID image block to the payload's data
+ // section.
+ memcpy(payloadIterator, &i_block->iv_data, blockDataSize);
+
+ // Move past the payload's data section.
+ payloadIterator += blockDataSize;
+ }
+
+ // Calculate the CRC bytes
+ // Pass in the size of the payload excluding the two reserved bytes
+ // for the CRC.
+ uint16_t crc = htole16(crc16_calc(payload.data(), payload.size()-2));
+
+ // Write the CRC bytes
+ uint8_t* crcBytes = reinterpret_cast<uint8_t*>(&crc);
+ memcpy(payloadIterator, crcBytes, sizeof(uint16_t));
+
+ // The sync byte is automatically sent by the NVDIMM to the BPM so
+ // including it in the payload isn't necessary. It is only needed to
+ // calculate the CRC bytes.
+ payload.erase(payload.begin());
+ // Force the returned payload to have the exact capacity and size of the
+ // payload.
+ o_payload.swap(payload);
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::unlockDevice()
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::unlockDevice()");
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ // This is a BSL command, so it must be formatted into a payload.
+ payload_t payload;
+
+ // This command must send the password in order to unlock the device.
+ errl = setupPayload(payload,
+ BSL_RX_PASSWORD,
+ BPM_ADDRESS_ZERO,
+ BPM_PASSWORD,
+ BPM_PASSWORD_LENGTH);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ errl = issueCommand(BPM_PASSTHROUGH, payload, WRITE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::resetDevice()
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::resetDevice()");
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ // Verify we are in BSL mode by checking SCAP_STATUS because if we aren't
+ // then we don't need to do anything.
+ scap_status_register_t status;
+ errl = nvdimmReadReg(iv_nvdimm,
+ SCAP_STATUS,
+ status.full);
+ if (errl != nullptr)
+ {
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ if (status.bit.Bpm_Bsl_Mode)
+ {
+ // This is a BSL command, so it must be formatted into a payload.
+ payload_t payload;
+ errl = setupPayload(payload, BSL_RESET_DEVICE, BPM_ADDRESS_ZERO);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Despite this being a BSL command we cannot check the response
+ // because the BPM will either be offline and cannot respond or
+ // the command will have completed and we won't be in BSL mode
+ // anymore and therefor shouldn't check the response.
+ errl = issueCommand(BPM_PASSTHROUGH,
+ payload,
+ WRITE,
+ NO_DELAY_NO_RESPONSE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // If we wait less than 15 seconds for the reset to occur it is
+ // possible that BPM won't be ready for more commands via the NVDIMM
+ TRACFCOMP(g_trac_bpm, "Bpm::resetDevice(): "
+ "Resetting BPM for NVDIMM 0x%.8X, sleep for 15 seconds.",
+ TARGETING::get_huid(iv_nvdimm));
+ longSleep(15);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::resetDevice(): "
+ "Not in BSL Mode. Don't send the reset command.");
+ break;
+ }
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::readViaScapRegister(uint8_t const i_reg, uint8_t & io_data)
+{
+ TRACUCOMP(g_trac_bpm, ENTER_MRK"Bpm::readViaScapRegister()");
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ // Wait for the SCAP_STATUS Busy bit to be zero.
+ errl = waitForBusyBit();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Write to SCAP register which register we're attempting to access on
+ // the BPM
+ errl = nvdimmWriteReg(iv_nvdimm,
+ SCAP_REG,
+ i_reg);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::readViaScapRegister(): "
+ "Failed to set SCAP_REG to register 0x%.2X",
+ i_reg);
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ // Wait for the SCAP_STATUS Busy bit to be zero.
+ errl = waitForBusyBit();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Read out the data from the requested register
+ errl = nvdimmReadReg(iv_nvdimm,
+ SCAP_DATA,
+ io_data);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "BPM::readViaScapRegister(): "
+ "Failed to read data from SCAP_DATA for register 0x%.2X.",
+ i_reg);
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::writeViaScapRegister(uint8_t const i_reg, uint8_t const i_data)
+{
+ TRACUCOMP(g_trac_bpm, ENTER_MRK"Bpm::writeViaScapRegister()");
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ // The SCAP_REG and SCAP_DATA registers require a few retries to get the
+ // values to stick. This loop sets SCAP_REG to i_reg
+ uint8_t retry = 0;
+ uint8_t data = 0;
+ do {
+
+ // Wait for the SCAP_STATUS Busy bit to be zero.
+ errl = waitForBusyBit();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Write to SCAP register which register we're attempting to access
+ // on the BPM
+ errl = nvdimmWriteReg(iv_nvdimm,
+ SCAP_REG,
+ i_reg);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::writeViaScapRegister(): "
+ "Failed to set SCAP_REG to register 0x%.2X",
+ i_reg);
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ // Wait for the SCAP_STATUS Busy bit to be zero.
+ errl = waitForBusyBit();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Wait 100ms
+ nanosleep(0, 100 * NS_PER_MSEC);
+
+ errl = nvdimmReadReg(iv_nvdimm,
+ SCAP_REG,
+ data);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "BPM::writeViaScapRegister(): "
+ "Failed to read from SCAP_REG to verify that "
+ "requested register 0x%.2X was written successfully.",
+ i_reg);
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ if (data == i_reg)
+ {
+ TRACUCOMP(g_trac_bpm, "Bpm::writeViaScapRegister(): "
+ "REG 0x%X was successfully written to SCAP_REG 0x434. "
+ "Stop retries.",
+ i_reg);
+ break;
+ }
+
+ } while(++retry < MAX_RETRY);
+ if (errl != nullptr)
+ {
+ break;
+ }
+ if ((retry >= MAX_RETRY) && (data != i_reg))
+ {
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_WRITE_VIA_SCAP
+ * @reasoncode BPM_RC::BPM_EXCEEDED_RETRY_LIMIT_REG
+ * @userdata1[0:31] The register that we were attempting to write to
+ * SCAP_REG.
+ * @userdata1[32:63] The data that was found in the register on the
+ * final attempt.
+ * @userdata2 NVDIMM Target HUID associated with this BPM
+ * @devdesc The command sent to the BPM failed.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_WRITE_VIA_SCAP,
+ BPM_RC::BPM_EXCEEDED_RETRY_LIMIT_REG,
+ TWO_UINT32_TO_UINT64(i_reg,
+ data),
+ TARGETING::get_huid(iv_nvdimm));
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ break;
+ }
+
+ // The SCAP_REG and SCAP_DATA registers require a few retries to get the
+ // values to stick. This loop sets SCAP_DATA to i_data
+ retry = 0;
+ data = 0;
+ do {
+
+ // Wait for the SCAP_STATUS Busy bit to be zero.
+ errl = waitForBusyBit();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Write the data to the register we're attempting to access
+ // on the BPM.
+ errl = nvdimmWriteReg(iv_nvdimm,
+ SCAP_DATA,
+ i_data);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"BPM::writeViaScapRegister(): "
+ "Failed to write data 0x%.2X to SCAP_DATA for "
+ "register 0x%.2X.",
+ i_data,
+ i_reg);
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ // Wait for the SCAP_STATUS Busy bit to be zero.
+ errl = waitForBusyBit();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Wait 100ms
+ nanosleep(0, 100 * NS_PER_MSEC);
+
+ errl = nvdimmReadReg(iv_nvdimm,
+ SCAP_DATA,
+ data);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"BPM::writeViaScapRegister(): "
+ "Failed to read from SCAP_DATA to verify "
+ "that requested data 0x%.2X was written successfully.",
+ i_data);
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ if (data == i_data)
+ {
+ TRACUCOMP(g_trac_bpm, "Bpm::writeViaScapRegister(): "
+ "DATA 0x%X was successfully written to SCAP_DATA 0x435."
+ " Stop retries.",
+ i_data);
+ break;
+ }
+
+ } while(++retry < MAX_RETRY);
+ if (errl != nullptr)
+ {
+ break;
+ }
+ if ((retry >= MAX_RETRY) && (data != i_data))
+ {
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_WRITE_VIA_SCAP
+ * @reasoncode BPM_RC::BPM_EXCEEDED_RETRY_LIMIT_DATA
+ * @userdata1[0:31] The data that we were attempting to write to
+ * SCAP_DATA.
+ * @userdata1[32:63] The data that was found in the register on the
+ * final attempt.
+ * @userdata2 NVDIMM Target HUID associated with this BPM
+ * @devdesc The command sent to the BPM failed.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_WRITE_VIA_SCAP,
+ BPM_RC::BPM_EXCEEDED_RETRY_LIMIT_DATA,
+ TWO_UINT32_TO_UINT64(i_data,
+ data),
+ TARGETING::get_huid(iv_nvdimm));
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ break;
+ }
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::disableWriteProtection()
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::disableWriteProtection()");
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ // The following write sequence to the I2C_REG_PROTECT register
+ // indirectly removes write protection from registers 0x40-0x7F on
+ // page 4.
+ for ( size_t i = 0; i < BPM_PASSWORD_LENGTH; ++i)
+ {
+ errl = nvdimmWriteReg(iv_nvdimm,
+ I2C_REG_PROTECT,
+ BPM_PASSWORD[i]);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::disableWriteProtection(): "
+ "Failed to write the unlock sequence to "
+ "I2C_REG_PROTECT");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+ }
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ nanosleep(0, 100 * NS_PER_MSEC);
+
+ // Make sure protection was removed
+ uint8_t data = 0;
+ errl = nvdimmReadReg(iv_nvdimm,
+ I2C_REG_PROTECT,
+ data);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::disableWriteProtection(): "
+ "Failed to verify that write protection was removed");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+ const uint8_t WRITE_PROTECT_DISABLED = 0x80;
+ if (!(data & WRITE_PROTECT_DISABLED))
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::disableWriteProtection(): "
+ "Failed to disable write protection. I2C_REG_PROTECT");
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_DISABLE_WRITE_PROTECTION
+ * @reasoncode BPM_RC::BPM_DISABLE_WRITE_PROTECTION_FAILED
+ * @userdata1 NVDIMM Target HUID associated with this BPM
+ * @devdesc Failed to enter BSL mode after several attempts.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_DISABLE_WRITE_PROTECTION,
+ BPM_RC::BPM_DISABLE_WRITE_PROTECTION_FAILED,
+ TARGETING::get_huid(iv_nvdimm));
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ break;
+ }
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::switchBpmPage(uint16_t const i_segmentCode)
+{
+
+ errlHndl_t errl = nullptr;
+
+ do {
+ const uint8_t SPECIAL_CONTROL_COMMAND1 = 0x3E;
+ const uint8_t SPECIAL_CONTROL_COMMAND2 = 0x3F;
+ // Next, switch to the desired BPM segment by writing the segment code
+ // to the BPM's Special Control Command registers.
+ //
+ // Since the SCAP_DATA register can only hold 1 byte at a time we must
+ // do this in two steps.
+ // According to SMART, the segment code must be written in the following
+ // form to those registers:
+ // Register 0x3E gets LO(i_segmentCode) byte
+ // Register 0x3F gets HI(i_segmentCode) byte
+ // Example: 0x9D5E is the segment code for Segment D. It must be written
+ // as follows
+ // 0x3E, 0x5E
+ // 0x3F, 0x9D
+ const uint8_t loSegCode = i_segmentCode & 0xFF;
+ const uint8_t hiSegCode = (i_segmentCode >> 8) & 0xFF;
+
+ TRACUCOMP(g_trac_bpm, "Bpm::switchBpmPage(): "
+ "Writing 0x%.2X to SPECIAL_CONTROL_COMMAND1 and "
+ "0x%.2X to SPECIAL_CONTROL_COMMAND2",
+ loSegCode,
+ hiSegCode);
+
+ // First, clear the SPECIAL_CONTROL_COMMAND2 register so that we can
+ // write the full sequence without issue.
+ errl = writeViaScapRegister(SPECIAL_CONTROL_COMMAND2, 0x00);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::switchBpmPage(): "
+ "Writing 0x%.2X to SPECIAL_CONTROL_COMMAND2 "
+ "FAILED. BPM page will not have switched properly!!",
+ hiSegCode);
+ break;
+ }
+
+ // Write the LO segment code.
+ errl = writeViaScapRegister(SPECIAL_CONTROL_COMMAND1, loSegCode);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::switchBpmPage(): "
+ "Writing 0x%.2X to SPECIAL_CONTROL_COMMAND1 "
+ "FAILED. BPM page will not have switched properly!!",
+ loSegCode);
+ break;
+ }
+
+ // Write the HI segment code.
+ errl = writeViaScapRegister(SPECIAL_CONTROL_COMMAND2, hiSegCode);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::switchBpmPage(): "
+ "Writing 0x%.2X to SPECIAL_CONTROL_COMMAND2 "
+ "FAILED. BPM page will not have switched properly!!",
+ hiSegCode);
+ break;
+ }
+
+
+ // Request to open segment page is sent.
+ // Wait a few seconds for the operation to complete.
+ nanosleep(2,0);
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::writeToMagicRegisters(
+ uint8_t const (&i_magicValues)[NUM_MAGIC_REGISTERS])
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::writeToMagicRegisters() 0x%.2X 0x%.2X",
+ i_magicValues[0],
+ i_magicValues[1]);
+ errlHndl_t errl = nullptr;
+
+ do {
+ const uint16_t magic_registers[NUM_MAGIC_REGISTERS] =
+ {BPM_MAGIC_REG1, BPM_MAGIC_REG2};
+
+ for (size_t i = 0; i < NUM_MAGIC_REGISTERS; ++i)
+ {
+ errl = nvdimmWriteReg(iv_nvdimm,
+ magic_registers[i],
+ i_magicValues[i]);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::writeToMagicRegisters(): "
+ "Failed to write the magic values to the magic "
+ "registers");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+ }
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Verify the magic values were written
+ uint8_t magic_data[NUM_MAGIC_REGISTERS] = {0};
+ for (size_t i = 0; i < NUM_MAGIC_REGISTERS; ++i)
+ {
+ errl = nvdimmReadReg(iv_nvdimm,
+ magic_registers[i],
+ magic_data[i]);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::writeToMagicRegisters(): "
+ "Failed to read back magic values to verify that "
+ "they were written.");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+ }
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // If either of the magic values stored in magic_data don't match the
+ // corresponding expected values in magic_values then an error occurred.
+ if ( (magic_data[0] != i_magicValues[0])
+ || (magic_data[1] != i_magicValues[1]))
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::writeToMagicRegisters(): "
+ "Magic values read from BPM didn't match expected values "
+ "BPM_MAGIC_REG1 Expected 0x%.2X Actual 0x%.2X "
+ "BPM_MAGIC_REG2 Expected 0x%.2X Actual 0x%.2X",
+ i_magicValues[0], magic_data[0],
+ i_magicValues[1], magic_data[1]);
+
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_WRITE_MAGIC_REG
+ * @reasoncode BPM_RC::BPM_WRITE_TO_MAGIC_REG_FAILED
+ * @userdata1[0:7] BPM_MAGIC_REG1 expected value
+ * @userdata1[8:15] BPM_MAGIC_REG1 actual value
+ * @userdata1[16:23] BPM_MAGIC_REG2 expected value
+ * @userdata1[24:31] BPM_MAGIC_REG2 actual value
+ * @userdata2[0:63] NVDIMM Target HUID associated with this BPM
+ * @devdesc Failed to write values to the magic registers on
+ * the BPM.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_WRITE_MAGIC_REG,
+ BPM_RC::BPM_WRITE_TO_MAGIC_REG_FAILED,
+ TWO_UINT16_TO_UINT32(
+ TWO_UINT8_TO_UINT16(i_magicValues[0],
+ magic_data[0]),
+ TWO_UINT8_TO_UINT16(i_magicValues[1],
+ magic_data[1])),
+ TARGETING::get_huid(iv_nvdimm));
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ break;
+ }
+
+ TRACUCOMP(g_trac_bpm, "Bpm::writeToMagicRegisters(): "
+ "Magic values successfully written to BPM "
+ "BPM_MAGIC_REG1 0x%.2X "
+ "BPM_MAGIC_REG2 0x%.2X ",
+ magic_data[0],
+ magic_data[1]);
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::dumpSegment(uint16_t const i_segmentCode,
+ uint8_t (&o_buffer)[SEGMENT_SIZE])
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::dumpSegment(): Segment %X",
+ getSegmentIdentifier(i_segmentCode));
+ assert(i_segmentCode == SEGMENT_B_CODE, "Bpm::dumpSegment(): Only Segment B is supported.");
+
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ errl = disableWriteProtection();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // We cannot be in BSL mode when dumping the config segments. Verify we
+ // aren't in BSL mode by checking SCAP_STATUS
+ scap_status_register_t status;
+ errl = nvdimmReadReg(iv_nvdimm,
+ SCAP_STATUS,
+ status.full);
+ if (errl != nullptr)
+ {
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ if (status.bit.Bpm_Bsl_Mode)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::dumpSegment(): "
+ "BSL Mode is enabled. Attempting to exit BSL mode.");
+
+ // Try to exit BSL mode. This function will exit BSL.
+ errl = resetDevice();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Exit update mode if on and write back production magic values.
+ errl = exitUpdateMode();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ errl = nvdimmReadReg(iv_nvdimm,
+ SCAP_STATUS,
+ status.full);
+ if (errl != nullptr)
+ {
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+ if (status.bit.Bpm_Bsl_Mode)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::dumpSegment(): "
+ "Couldn't dump Segment %X. BSL Mode is enabled.",
+ getSegmentIdentifier(i_segmentCode));
+
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_DUMP_SEGMENT
+ * @reasoncode BPM_RC::BPM_BSL_MODE_ENABLED
+ * @userdata1[0:63] NVDIMM Target HUID associated with this BPM
+ * @devdesc Couldn't dump segment data because BSL mode
+ * was enabled.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_DUMP_SEGMENT,
+ BPM_RC::BPM_BSL_MODE_ENABLED,
+ TARGETING::get_huid(iv_nvdimm));
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+
+ break;
+ }
+ }
+
+ // First the NVDIMM MAGIC registers BPM_MAGIC_REG1 and BPM_MAGIC_REG2
+ // must be programmed to 0xBA and 0xAB respectively.
+ const uint8_t magic_values[NUM_MAGIC_REGISTERS] = {0xBA, 0xAB};
+ errl = writeToMagicRegisters(magic_values);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::dumpSegment(): "
+ "Failed to write magic numbers that enable "
+ "reading of segment data.");
+ break;
+ }
+
+ uint8_t retry = 1;
+ // Attempt to switch to the correct page and dump data twice.
+ do {
+ // Set buffer to be all zeroes.
+ memset(&o_buffer, 0, SEGMENT_SIZE);
+
+ // Open this segments page on the BPM.
+ errl = switchBpmPage(i_segmentCode);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ TRACFCOMP(g_trac_bpm, "Bpm::dumpSegment(): "
+ "Dumping Segment %X to buffer.",
+ getSegmentIdentifier(i_segmentCode));
+
+ // Dump the segment data
+ bool wrongPage = false;
+ for (uint8_t reg = 0; reg < SEGMENT_SIZE; ++reg)
+ {
+ errl = readViaScapRegister(reg, o_buffer[reg]);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // We can determine if the page switch succeeded based on the
+ // first three bytes from regs 0x10-0x12. If Segment B was
+ // opened, then 0x10-0x1F is serial number for the BPM.
+ // SMART guarantees the first three bytes to be as follows:
+ if ((reg == 0x10) && (o_buffer[reg] != 0x53))
+ {
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::dumpSegment "
+ "data 0x%.2X at offset 0x%.2x wasn't expected "
+ "value 0x53",
+ o_buffer[reg], reg);
+ wrongPage = true;
+ }
+ if ((reg == 0x11) && (o_buffer[reg] != 0x46))
+ {
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::dumpSegment "
+ "data 0x%.2X at offset 0x%.2x wasn't expected "
+ "value 0x46",
+ o_buffer[reg], reg);
+ wrongPage = true;
+ }
+ if ((reg == 0x12) && (o_buffer[reg] != 0x52))
+ {
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::dumpSegment "
+ "data 0x%.2X at offset 0x%.2x wasn't expected "
+ "value 0x52",
+ o_buffer[reg], reg);
+ wrongPage = true;
+ }
+
+ if (wrongPage && (reg == 0x20))
+ {
+ break;
+ }
+
+ }
+
+ TRACUBIN(g_trac_bpm, "Segment BIN DUMP", o_buffer, SEGMENT_SIZE);
+
+ if ((errl != nullptr) || (wrongPage == false))
+ {
+ break;
+ }
+
+ // Close this segments page on the BPM before making another
+ // attempt.
+ errl = switchBpmPage(DEFAULT_REG_PAGE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ } while(++retry < MAX_RETRY);
+ if (errl != nullptr)
+ {
+ break;
+ }
+ if (retry >= MAX_RETRY)
+ {
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_DUMP_SEGMENT
+ * @reasoncode BPM_RC::BPM_EXCEEDED_RETRY_LIMIT
+ * @userdata1 The segment code for the page that failed to
+ * open.
+ * @userdata2 NVDIMM Target HUID associated with this BPM
+ * @devdesc Failed to open the segment page in the given
+ * amount of retries.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_DUMP_SEGMENT,
+ BPM_RC::BPM_EXCEEDED_RETRY_LIMIT,
+ i_segmentCode,
+ TARGETING::get_huid(iv_nvdimm));
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ setAttemptAnotherUpdate();
+ break;
+ }
+
+ } while(0);
+
+ TRACFCOMP(g_trac_bpm, "Bpm::dumpSegment(): "
+ "Closing Segment %X's page.",
+ getSegmentIdentifier(i_segmentCode));
+
+ // Close the Segment page by switching back to the default page.
+ errlHndl_t closeSegmentErrl = switchBpmPage(DEFAULT_REG_PAGE);
+ if (closeSegmentErrl != nullptr)
+ {
+ handleMultipleErrors(errl, closeSegmentErrl);
+ }
+
+ // Write back the production magic values.
+ errlHndl_t magicErrl = writeToMagicRegisters(PRODUCTION_MAGIC_VALUES);
+ if (magicErrl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::dumpSegment(): "
+ "Failed to write update mode magic numbers.");
+ handleMultipleErrors(errl, magicErrl);
+ }
+
+ return errl;
+}
+
+errlHndl_t Bpm::mergeSegment(BpmConfigLidImage const i_configImage,
+ uint16_t const i_segmentCode,
+ uint8_t (&o_buffer)[SEGMENT_SIZE])
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::mergeSegment(): Segment %X",
+ getSegmentIdentifier(i_segmentCode));
+ errlHndl_t errl = nullptr;
+
+ size_t segmentStartOffset = 0;
+ auto it = segmentMap.find(i_segmentCode);
+ if (it != segmentMap.end())
+ {
+ segmentStartOffset = it->second;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::mergeSegment(): "
+ "Couldn't find start offset for Segment %X",
+ getSegmentIdentifier(i_segmentCode));
+ assert(false, "Add the missing Segment %X Start Offset to the offset map", getSegmentIdentifier(i_segmentCode));
+ }
+
+ TRACFCOMP(g_trac_bpm, "Bpm::mergeSegment(): "
+ "Segment %X Start offset: 0x%X",
+ getSegmentIdentifier(i_segmentCode),
+ segmentStartOffset);
+
+ do {
+
+ const size_t NUMBER_OF_FRAGMENTS = i_configImage.getNumberOfFragments();
+ char const * data = reinterpret_cast<char const *>(
+ i_configImage.getFirstFragment());
+
+ config_image_fragment_t const * fragment =
+ reinterpret_cast<config_image_fragment_t const *>(data);
+
+ TRACUCOMP(g_trac_bpm, "mergeSegment(): "
+ "NUMBER_OF_FRAGMENTS = 0x%.4X", NUMBER_OF_FRAGMENTS);
+
+ for(size_t i = 0; i < NUMBER_OF_FRAGMENTS; ++i)
+ {
+ // The fragment offsets are given as offsets within the
+ // configuration segment data. So, if the fragment offset is less
+ // than the starting offset of this segment then the fragment is not
+ // relevant to this segment.
+ if (fragment->iv_offset < segmentStartOffset)
+ {
+ // This fragment is not for the segment we are dealing with.
+ TRACUCOMP(g_trac_bpm, "mergeSegment(): "
+ "Fragment with offset 0x%.4X not related to "
+ "Segment %X, skipping",
+ fragment->iv_offset,
+ getSegmentIdentifier(i_segmentCode));
+
+ // Move to the next fragment
+ data += sizeof(config_image_fragment_t)
+ + fragment->iv_fragmentSize;
+ fragment =
+ reinterpret_cast<config_image_fragment_t const *>(data);
+ continue;
+ }
+ // Each segment is 128 bytes in size. So, if the offset given for
+ // the fragment is greater than the upper boundry then no more
+ // fragments exist for this segment.
+ if (fragment->iv_offset >= segmentStartOffset + SEGMENT_SIZE)
+ {
+ // This fragment and all other fragments afterward are not for
+ // this segment.
+ TRACUCOMP(g_trac_bpm, "mergeSegment(): "
+ "Fragment with offset 0x%.4X greater than/equal to "
+ "Segment %X ending offset, skipping",
+ fragment->iv_offset,
+ getSegmentIdentifier(i_segmentCode));
+ break;
+ }
+
+ // The fragment offset may be out of bounds for the buffer so
+ // scale it down to be within the buffer size.
+ size_t offset = fragment->iv_offset % SEGMENT_SIZE;
+
+ // Overwrite the BPM segment data at the offset specified by the
+ // fragment.
+ memcpy(&o_buffer[offset],
+ &(fragment->iv_data),
+ fragment->iv_fragmentSize);
+
+ // Move to the next fragment
+ data += sizeof(config_image_fragment_t) + fragment->iv_fragmentSize;
+ fragment = reinterpret_cast<config_image_fragment_t const *>(data);
+ }
+
+ TRACUBIN(g_trac_bpm, "Merged Segment", o_buffer, SEGMENT_SIZE);
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::eraseSegment(uint16_t i_segmentCode)
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::eraseSegment(): Segment %X",
+ getSegmentIdentifier(i_segmentCode));
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ payload_t payload;
+
+ size_t segmentStartOffset = 0;
+ auto it = segmentMap.find(i_segmentCode);
+ if (it != segmentMap.end())
+ {
+ segmentStartOffset = it->second;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::mergeSegment(): "
+ "Couldn't find start offset for Segment %X",
+ getSegmentIdentifier(i_segmentCode));
+ assert(false, "Add the missing Segment %X Start Offset to the offset map", getSegmentIdentifier(i_segmentCode));
+ }
+ errl = setupPayload(payload,
+ BSL_ERASE_SEGMENT,
+ BPM_CONFIG_START_ADDRESS + segmentStartOffset);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ errl = issueCommand(BPM_PASSTHROUGH,
+ payload,
+ WRITE,
+ ERASE_SEGMENT_DELAY);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Wait 1 second for the operation to complete.
+ TRACFCOMP(g_trac_bpm, "Bpm::eraseSegment(): "
+ "Erasing Segment %X. "
+ "Waiting 1 second for operation to complete.",
+ getSegmentIdentifier(i_segmentCode));
+ nanosleep(1,0);
+
+ } while(0);
+
+ TRACFCOMP(g_trac_bpm, EXIT_MRK"Bpm::eraseSegment(): "
+ "Segment %X erase operation completed "
+ "%s",
+ getSegmentIdentifier(i_segmentCode),
+ (errl == nullptr) ? "without errors" : "with errors");
+
+ return errl;
+}
+
+errlHndl_t Bpm::writeSegment(uint8_t const (&i_buffer)[SEGMENT_SIZE],
+ uint16_t const i_segmentCode)
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::writeSegment(): Segment %X",
+ getSegmentIdentifier(i_segmentCode));
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ auto it = segmentMap.find(i_segmentCode);
+ size_t segmentStartOffset = 0;
+ if (it != segmentMap.end())
+ {
+ segmentStartOffset = it->second;
+ }
+
+ // To update the given segment, we have to send over the data as
+ // payloads. Since the max size of a payload's data is 16 bytes, there
+ // will be 8 payloads sent to update a given segment because each
+ // segment is 128 bytes.
+ for (size_t offset = 0;
+ offset < SEGMENT_SIZE;
+ offset += MAX_PAYLOAD_DATA_SIZE)
+ {
+ // Construct a payload for the data at this offset up to the
+ // MAX_PAYLOAD_DATA_SIZE.
+ payload_t payload;
+ // Each segment is 128 bytes and the segment start addresses
+ // are their relative position to BPM_CONFIG_START_ADDRESS. To
+ // arrive at the correct address offset for this data we must
+ // calculate the addressOffset in the following way.
+ uint16_t addressOffset = BPM_CONFIG_START_ADDRESS
+ + segmentStartOffset
+ + offset;
+ errl = setupPayload(payload,
+ BSL_RX_DATA_BLOCK,
+ addressOffset,
+ &i_buffer[offset],
+ MAX_PAYLOAD_DATA_SIZE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ if (addressOffset % 0x20 == 0)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::writeSegment(): "
+ "Writing to address offset 0x%.4X. "
+ "Config bytes written: 0x%X; Remaining: 0x%X",
+ addressOffset,
+ offset, (SEGMENT_SIZE - offset));
+ }
+
+ // Attempt to write the payload using a retry loop.
+ errl = blockWrite(payload);
+ if (errl != nullptr)
+ {
+ break;
+ }
+ }
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ } while(0);
+
+ TRACFCOMP(g_trac_bpm, EXIT_MRK"Bpm::writeSegment(): "
+ "Segment %X write and verification completed "
+ "%s",
+ getSegmentIdentifier(i_segmentCode),
+ (errl == nullptr) ? "without errors" : "with errors");
+
+ return errl;
+}
+
+errlHndl_t Bpm::preprocessSegments(BpmConfigLidImage const i_configImage)
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::preprocessSegments()");
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ if (iv_attemptAnotherUpdate && iv_segmentDMerged && iv_segmentBMerged)
+ {
+ // The segment data has already been merged with the flash image
+ // data. Doing it again has the potential to fail depending on where
+ // the last update attempt failed.
+ TRACFCOMP(g_trac_bpm, "Bpm::preprocessSegments(): "
+ "Segment data was merged in a previous update attempt, "
+ "skipping preprocessing and using existing data.");
+ break;
+ }
+
+ // Merge the fragments for D with the data from the BPM. For D, this
+ // will just populate the empty segment with the data from the flash
+ // image.
+ if (!iv_segmentDMerged)
+ {
+ errl = mergeSegment(i_configImage, SEGMENT_D_CODE, iv_segmentD);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::preprocessSegments(): "
+ "Failed to merge Segment D.");
+ break;
+ }
+ iv_segmentDMerged = true;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::preprocessSegments(): "
+ "Segment %X has been merged already. Skipping merge...",
+ getSegmentIdentifier(SEGMENT_D_CODE));
+ }
+
+ // Merge the fragments for B with the data from the BPM.
+ if (!iv_segmentBMerged)
+ {
+ // Dump the segment into a buffer. This is only necessary for
+ // segment B as segment D comes straight from the flash image file.
+ errl = dumpSegment(SEGMENT_B_CODE, iv_segmentB);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ errl = mergeSegment(i_configImage, SEGMENT_B_CODE, iv_segmentB);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::preprocessSegments(): "
+ "Failed to merge Segment B.");
+ break;
+ }
+ iv_segmentBMerged = true;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_bpm, INFO_MRK"Bpm::preprocessSegments(): "
+ "Segment %X has been merged already. Skipping merge...",
+ getSegmentIdentifier(SEGMENT_B_CODE));
+ }
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::getResponse(uint8_t * const o_responseData,
+ uint8_t const i_responseSize)
+{
+ TRACUCOMP(g_trac_bpm, ENTER_MRK"Bpm::getResponse()");
+
+ errlHndl_t errl = nullptr;
+ memset(o_responseData, 0xFF, i_responseSize);
+
+ do {
+
+ // Get the result from the BPM.
+ // First clear the error status register
+ errl = nvdimmWriteReg(iv_nvdimm,
+ BPM_REG_ERR_STATUS,
+ 0x00);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::getResponse(): "
+ "Failed to clear error status register");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ // Set the payload length
+ // The 4 header bytes plus 2 CRC bytes make up the other data size in
+ // the response payload.
+ const uint8_t RESPONSE_PAYLOAD_OTHER_DATA_SIZE = 6;
+ uint8_t responsePayloadSize = RESPONSE_PAYLOAD_OTHER_DATA_SIZE
+ + i_responseSize;
+
+ errl = nvdimmWriteReg(iv_nvdimm,
+ BPM_PAYLOAD_LENGTH,
+ responsePayloadSize);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::getResponse(): "
+ "Failed to set payload length");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ // Setup the command status register
+ command_status_register_t commandStatus;
+ commandStatus.bits.Bsp_Cmd_In_Progress = 1;
+ commandStatus.bits.Operator_Type = READ;
+ errl = nvdimmWriteReg(iv_nvdimm,
+ BPM_CMD_STATUS,
+ commandStatus.value);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::getResponse(): "
+ "Failed to setup command status register");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ // Setup command type.
+ errl = nvdimmWriteReg(iv_nvdimm,
+ BPM_REG_CMD,
+ BPM_PASSTHROUGH);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::getResponse(): "
+ "Failed to setup command type.");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ errl = waitForCommandStatusBitReset(commandStatus);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Read out the response payload.
+ payload_t responsePayload;
+
+ for (size_t i = 0; i < responsePayloadSize; ++i)
+ {
+ uint8_t data = 0;
+ errl = nvdimmReadReg(iv_nvdimm,
+ (BPM_REG_PAYLOAD_START + (i * sizeof(uint8_t))),
+ data);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::getResponse(): "
+ "Failed to read response payload");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ responsePayload.push_back(data);
+ }
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Verify the data from the response was good.
+ uint8_t* responseIterator = responsePayload.data();
+ uint16_t responseCrc = *(reinterpret_cast<uint16_t *>
+ (&responseIterator[PAYLOAD_HEADER_SIZE + i_responseSize]));
+ // The BPM is going to give the response CRC in LE. So convert it to BE.
+ responseCrc = le16toh(responseCrc);
+ uint16_t expectedCrc = crc16_calc(responseIterator,
+ PAYLOAD_HEADER_SIZE + i_responseSize);
+ if (responseCrc != expectedCrc)
+ {
+ memset(o_responseData, 0xFF, i_responseSize);
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::getResponse(): "
+ "Response CRC verification failed. "
+ "Received invalid data from BPM.");
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_GET_RESPONSE
+ * @reasoncode BPM_RC::BPM_RESPONSE_CRC_MISMATCH
+ * @userdata1[00:31] Expected Response CRC (in Big Endian)
+ * @userdata1[32:63] Actual Response CRC (in Big Endian)
+ * @userdata2 NVDIMM Target HUID associated with this BPM
+ * @devdesc The response CRC calculated by the BPM didn't
+ * match the CRC calculated by hostboot.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_GET_RESPONSE,
+ BPM_RC::BPM_RESPONSE_CRC_MISMATCH,
+ TWO_UINT32_TO_UINT64(expectedCrc,
+ responseCrc),
+ TARGETING::get_huid(iv_nvdimm));
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ break;
+ }
+
+ // Write the data to the output buffer
+ for (size_t i = 0; i < i_responseSize; ++i)
+ {
+ // Only copy the response data from the payload to the output buffer
+ o_responseData[i] = responsePayload[i + PAYLOAD_HEADER_SIZE];
+ }
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::verifyBlockWrite(payload_t i_payload,
+ uint8_t i_dataLength,
+ uint8_t & o_status)
+{
+ errlHndl_t errl = nullptr;
+ // Assume a bad status.
+ o_status = 0xFF;
+
+ do {
+
+ // Pull the address to verify out of the payload. It was inserted in
+ // little endian form so it needs to be converted back to big endian
+ // because setupPayload expects an address in big endian.
+ uint16_t address = getPayloadAddressBE(i_payload);
+
+ // The data section of the payload is organized in the following way:
+ // 2 bytes: uint16_t size of data to verify in little endian format
+ // 2 bytes: CRC of the data to be verified on the BPM in little endian.
+ const size_t VERIFY_BLOCK_PAYLOAD_DATA_SIZE = 4;
+ uint8_t data[VERIFY_BLOCK_PAYLOAD_DATA_SIZE] = {0};
+
+ // Since the data length is stored as uint16_t but the length we deal
+ // with is uint8_t we can easily convert this to little endian by
+ // storing our uint8_t data length in the first index of the array and
+ // leaving the next index 0.
+ data[0] = i_dataLength;
+
+ // Calculate the uint16_t CRC for the data that was written to the BPM.
+ // The BPM will compare its calculated CRC with this one to verify if
+ // the block was written correctly.
+ uint16_t crc = htole16(crc16_calc(&i_payload[PAYLOAD_DATA_START_INDEX],
+ i_dataLength));
+
+ memcpy(&data[2], &crc, sizeof(uint16_t));
+
+ payload_t verifyPayload;
+ errl = setupPayload(verifyPayload,
+ BSL_VERIFY_BLOCK,
+ address,
+ data,
+ VERIFY_BLOCK_PAYLOAD_DATA_SIZE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Issue the command to the BPM.
+ errl = issueCommand(BPM_PASSTHROUGH,
+ verifyPayload,
+ WRITE,
+ NO_DELAY_EXTERNAL_RESPONSE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ errl = getResponse(&o_status, sizeof(uint8_t));
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::blockWrite(payload_t i_payload)
+{
+ assert(i_payload[PAYLOAD_COMMAND_INDEX] == BSL_RX_DATA_BLOCK,
+ "Bpm::blockWrite(): "
+ "Can only write BSL_RX_DATA_BLOCK commands");
+
+ errlHndl_t errl = nullptr;
+ uint8_t retry = 0;
+
+ // Get the payload address for trace output.
+ uint16_t payloadAddress = getPayloadAddressBE(i_payload);
+
+ // Any status from verifyBlockWrite that is non-zero is considered a
+ // fail. So, assume a fail and check.
+ uint8_t wasVerified = 0xFF;
+ do {
+
+
+ // Since the write command has its response packet checked within the
+ // issueCommand() function we must attempt to retry the write if we get
+ // a bad response from the BPM.
+ errl = blockWriteRetry(i_payload);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Sleep for 0.001 second
+ nanosleep(0, 1 * NS_PER_MSEC);
+
+ uint8_t dataLength = i_payload[PAYLOAD_HEADER_DATA_LENGTH_INDEX]
+ - PAYLOAD_HEADER_SIZE;
+ errl = verifyBlockWrite(i_payload,
+ dataLength,
+ wasVerified);
+ if ( (errl != nullptr)
+ && (errl->reasonCode() == BPM_RC::BPM_RESPONSE_CRC_MISMATCH)
+ && ((retry + 1) < MAX_RETRY))
+ {
+ // Delete the retryable error and continue
+ TRACFCOMP(g_trac_bpm, "Bpm::blockWrite(): "
+ "Encountered a retryable error. Delete and continue.");
+ delete errl;
+ errl = nullptr;
+ }
+ else if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::blockWrite(): "
+ "BSL_VERIFY_BLOCK failed for address 0x%.4X. "
+ "A non-retryable error occurred on attempt %d/%d",
+ payloadAddress,
+ (retry + 1),
+ MAX_RETRY);
+ // A non-retryable error occurred. Break from retry loop.
+ break;
+ }
+
+ if (wasVerified != 0)
+ {
+ TRACUCOMP(g_trac_bpm, "Bpm::blockWrite(): "
+ "BSL_VERIFY_BLOCK failed for address 0x%.4X. "
+ "Attempt %d/%d",
+ payloadAddress,
+ (retry + 1),
+ MAX_RETRY);
+ }
+ else
+ {
+ // Write verified successfully, stop retries.
+ break;
+ }
+
+ } while (++retry < MAX_RETRY);
+ if ((errl == nullptr) && (retry >= MAX_RETRY) && (wasVerified != 0))
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::blockWrite(): "
+ "Failed to write payload data to BPM after %d retries.",
+ MAX_RETRY);
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_BLOCK_WRITE
+ * @reasoncode BPM_RC::BPM_EXCEEDED_RETRY_LIMIT
+ * @userdata1[0:63] NVDIMM Target HUID associated with this BPM
+ * @devdesc The block of data to be written to the BPM
+ * failed to write successfully in the given number
+ * of retries.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_BLOCK_WRITE,
+ BPM_RC::BPM_EXCEEDED_RETRY_LIMIT,
+ TARGETING::get_huid(iv_nvdimm));
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+
+ }
+
+ if (errl != nullptr)
+ {
+ // Change the state of iv_attemptAnotherUpdate. This will signal
+ // another update attempt or cease further attempts.
+ setAttemptAnotherUpdate();
+ }
+
+ return errl;
+}
+
+errlHndl_t Bpm::blockWriteRetry(payload_t i_payload)
+{
+ assert(i_payload[PAYLOAD_COMMAND_INDEX] == BSL_RX_DATA_BLOCK,
+ "Bpm::blockWriteRetry(): "
+ "Can only retry BSL_RX_DATA_BLOCK commands");
+
+ errlHndl_t errl = nullptr;
+ uint8_t retry = 0;
+
+ // Get the payload address for trace output.
+ uint16_t payloadAddress = getPayloadAddressBE(i_payload);
+
+ do {
+
+ // Send the payload data over as a pass-through command. The response
+ // will be checked internally.
+ errl = issueCommand(BPM_PASSTHROUGH, i_payload, WRITE);
+ if (errl == nullptr)
+ {
+ // Command was a success. Stop retries.
+ break;
+ }
+
+ if ( (errl != nullptr)
+ && (errl->reasonCode() == BPM_RC::BPM_RESPONSE_CRC_MISMATCH)
+ && ((retry + 1) < MAX_RETRY))
+ {
+ // Delete the retryable error and continue
+ TRACFCOMP(g_trac_bpm, "Bpm::blockWriteRetry(): "
+ "Encountered a retryable error. Delete and continue.");
+ delete errl;
+ errl = nullptr;
+ }
+ else if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::blockWriteRetry(): "
+ "BSL_RX_DATA_BLOCK failed for address 0x%.4X. "
+ "A non-retryable error occurred on attempt %d/%d",
+ payloadAddress,
+ (retry + 1),
+ MAX_RETRY);
+ // A non-retryable error occurred. Break from retry loop.
+ break;
+ }
+
+ } while (++retry < MAX_RETRY);
+ if ((errl == nullptr) && (retry >= MAX_RETRY))
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::blockWriteRetry(): "
+ "Failed to write payload data to BPM after %d retries.",
+ MAX_RETRY);
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_RETRY_BLOCK_WRITE
+ * @reasoncode BPM_RC::BPM_EXCEEDED_RETRY_LIMIT
+ * @userdata1[0:63] NVDIMM Target HUID associated with this BPM
+ * @devdesc The block of data to be written to the BPM
+ * failed to write successfully in the given number
+ * of retries.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_RETRY_BLOCK_WRITE,
+ BPM_RC::BPM_EXCEEDED_RETRY_LIMIT,
+ TARGETING::get_huid(iv_nvdimm));
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+
+ }
+
+ if (errl != nullptr)
+ {
+ // Change the state of iv_attemptAnotherUpdate. This will signal
+ // another update attempt or cease further attempts.
+ setAttemptAnotherUpdate();
+ }
+
+ return errl;
+}
+
+errlHndl_t Bpm::waitForCommandStatusBitReset(
+ command_status_register_t i_commandStatus)
+{
+ errlHndl_t errl = nullptr;
+
+ do {
+ // Wait until the COMMAND_IN_PROGRESS bit is reset
+ errl = nvdimmReadReg(iv_nvdimm,
+ BPM_CMD_STATUS,
+ i_commandStatus.value);
+ if (errl != nullptr)
+ {
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ // Give the BPM 20 seconds to complete any given command before we time
+ // out and cancel the update procedure.
+ int retry = 20 * MS_PER_SEC;
+
+ while (i_commandStatus.bits.Bsp_Cmd_In_Progress)
+ {
+ nanosleep(0, 1 * NS_PER_MSEC);
+ errl = nvdimmReadReg(iv_nvdimm,
+ BPM_CMD_STATUS,
+ i_commandStatus.value);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::waitForCommandStatusBitReset(): "
+ "Failed to read BPM_CMD_STATUS register");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ if (--retry <= 0)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK
+ "BPM::waitForCommandStatusBitReset(): "
+ "BSP_CMD_IN_PROGRESS bit has not reset in allotted "
+ "number of retries. Cancel update procedure");
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_WAIT_FOR_CMD_BIT_RESET
+ * @reasoncode BPM_RC::BPM_EXCEEDED_RETRY_LIMIT
+ * @userdata1[0:63] NVDIMM Target HUID associated with this BPM
+ * @devdesc The command status bit failed to reset in
+ * the given number of retries.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_WAIT_FOR_CMD_BIT_RESET,
+ BPM_RC::BPM_EXCEEDED_RETRY_LIMIT,
+ TARGETING::get_huid(iv_nvdimm));
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ break;
+ }
+
+ }
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Check for error
+ if (i_commandStatus.bits.Error_Flag)
+ {
+ uint8_t error = 0;
+ errl = nvdimmReadReg(iv_nvdimm,
+ BPM_REG_ERR_STATUS,
+ error);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::waitForCommandStatusBitReset(): "
+ "Failed to read BPM_REG_ERR_STATUS");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::waitForCommandStatusBitReset(): "
+ "BPM_CMD_STATUS Error Flag is set");
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_WAIT_FOR_CMD_BIT_RESET
+ * @reasoncode BPM_RC::BPM_CMD_STATUS_ERROR_BIT_SET
+ * @userdata1[0:7] Error status code returned by BPM
+ * @userdata2[0:63] NVDIMM Target HUID associated with this BPM
+ * @devdesc The command status register returned an error.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_WAIT_FOR_CMD_BIT_RESET,
+ BPM_RC::BPM_CMD_STATUS_ERROR_BIT_SET,
+ error,
+ TARGETING::get_huid(iv_nvdimm));
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ break;
+
+ }
+
+ } while(0);
+
+ return errl;
+}
+
+errlHndl_t Bpm::verifyGoodBpmState()
+{
+ errlHndl_t errl = nullptr;
+ int retry = 100;
+ scap_status_register_t status;
+ const uint8_t BPM_PRESENT_AND_ENABLED = 0x11;
+
+ while (retry > 0)
+ {
+
+ errl = nvdimmReadReg(iv_nvdimm,
+ SCAP_STATUS,
+ status.full);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::verifyGoodBpmState(): "
+ "Failed to read SCAP_STATUS to determine "
+ "state of BPM.");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ if ((status.full & 0xFF) == BPM_PRESENT_AND_ENABLED)
+ {
+ // BPM is present and enabled. Stop retries.
+ break;
+ }
+
+ --retry;
+ nanosleep(0, 1 * NS_PER_MSEC);
+ }
+ if (retry <= 0)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::verifyGoodBpmState(): "
+ "BPM failed to become present and enabled "
+ "in 100 retries.");
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_VERIFY_GOOD_BPM_STATE
+ * @reasoncode BPM_RC::BPM_EXCEEDED_RETRY_LIMIT
+ * @userdata1 NVDIMM Target HUID associated with this BPM
+ * @userdata2 SCAP_STATUS register contents. See nvdimm.H
+ * for bits associated with this register.
+ * @devdesc The BPM did not become present and enabled
+ * in given number of retries.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_VERIFY_GOOD_BPM_STATE,
+ BPM_RC::BPM_EXCEEDED_RETRY_LIMIT,
+ TARGETING::get_huid(iv_nvdimm),
+ status.full);
+ errl->collectTrace(BPM_COMP_NAME);
+ errl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ }
+
+ return errl;
+}
+
+errlHndl_t Bpm::waitForBusyBit()
+{
+ errlHndl_t errl = nullptr;
+ int retry = 10;
+ scap_status_register_t status;
+
+ while (retry > 0)
+ {
+
+ errl = nvdimmReadReg(iv_nvdimm,
+ SCAP_STATUS,
+ status.full);
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, "Bpm::waitForBusyBit(): "
+ "Failed to read from SCAP_STATUS to determine "
+ "state of Busy bit.");
+ errl->collectTrace(BPM_COMP_NAME);
+ break;
+ }
+
+ if (!status.bit.Busy)
+ {
+ // SCAP Register is no longer busy. Stop retries.
+ break;
+ }
+
+ if (retry <= 0)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::waitForBusyBit(): "
+ "SCAP_STATUS Busy bit failed to reset to 0 "
+ "in 10 retries.");
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_WAIT_FOR_BUSY_BIT_RESET
+ * @reasoncode BPM_RC::BPM_EXCEEDED_RETRY_LIMIT
+ * @userdata1[0:63] NVDIMM Target HUID associated with this BPM
+ * @devdesc The SCAP status register busy bit failed to
+ * reset in given number of retries.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_WAIT_FOR_BUSY_BIT_RESET,
+ BPM_RC::BPM_EXCEEDED_RETRY_LIMIT,
+ TARGETING::get_huid(iv_nvdimm));
+ errl->collectTrace(BPM_COMP_NAME);
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ break;
+ }
+
+ --retry;
+ nanosleep(0, 2 * NS_PER_MSEC);
+ }
+
+ return errl;
+}
+
+errlHndl_t Bpm::runConfigUpdates(BpmConfigLidImage i_configImage)
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::runConfigUpdates()");
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ // Before the entering BSL mode, we must do preprocessing prior to the
+ // config part of the update. Segment B needs to be dumped from the
+ // BPM into a buffer and then the config data from the image needs to be
+ // inserted into it. To dump segment data, it is required to have
+ // working firmware which will not be the case during BSL mode.
+ errl = preprocessSegments(i_configImage);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Enter Update mode
+ errl = enterUpdateMode();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Verify in Update mode
+ errl = inUpdateMode();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Enter Bootstrap Loader (BSL) mode to perform firmware update
+ errl = enterBootstrapLoaderMode();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Unlock the device. This is a BSL command so we must already be in
+ // BSL mode to execute it.
+ errl = unlockDevice();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Perform the configuration data segment updates.
+ // As of BSL 1.4 this is done via the BSL interface instead of SCAP
+ // registers.
+ errl = updateConfig();
+ if (errl != nullptr)
+ {
+ // We are returning with an error. Since the error is from the
+ // config part of the updates it's best to erase the firmware on the
+ // BPM so that updates will be attempted on it in the future.
+ // Because there isn't a way to determine the validity of the config
+ // section on the BPM we're completely reliant on what the firmware
+ // version reports to decide if we need to update or not. If we see
+ // that the firmware version matches the image but for some reason
+ // the config data wasn't updated properly we could believe we
+ // updated successfully when, in fact, we just left the BPM in a bad
+ // state.
+ if ( (iv_firmwareStartAddress == MAIN_PROGRAM_ADDRESS)
+ || (iv_firmwareStartAddress == MAIN_PROGRAM_ADDRESS_ALT))
+ {
+ payload_t payload;
+ errlHndl_t fwEraseErrl = setupPayload(payload,
+ BSL_MASS_ERASE,
+ iv_firmwareStartAddress);
+ if (fwEraseErrl != nullptr)
+ {
+ handleMultipleErrors(errl, fwEraseErrl);
+ break;
+ }
+
+ fwEraseErrl = issueCommand(BPM_PASSTHROUGH,
+ payload,
+ WRITE,
+ ERASE_FIRMWARE_DELAY);
+ if (fwEraseErrl != nullptr)
+ {
+ handleMultipleErrors(errl, fwEraseErrl);
+ break;
+ }
+
+ TRACFCOMP(g_trac_bpm, "Bpm::updateFirmware(): "
+ "Performing BSL_MASS_ERASE on BPM to force full "
+ "update on any subsequent attempt. Sleep for 5 "
+ "seconds.");
+ longSleep(5);
+ }
+ break;
+ }
+
+ } while(0);
+
+ // Reset the device. This will exit BSL mode.
+ errlHndl_t exitErrl = resetDevice();
+ if (exitErrl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::runConfigUpdates(): "
+ "Failed to reset the device");
+ handleMultipleErrors(errl, exitErrl);
+ }
+
+ // Exit update mode
+ exitErrl = exitUpdateMode();
+ if (exitErrl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::runConfigUpdates(): "
+ "Failed to exit update mode");
+ handleMultipleErrors(errl, exitErrl);
+ }
+
+
+ return errl;
+}
+
+errlHndl_t Bpm::runFirmwareUpdates(BpmFirmwareLidImage i_image)
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::runFirmwareUpdates()");
+ errlHndl_t errl = nullptr;
+
+ do {
+
+ // Enter Update mode
+ errl = enterUpdateMode();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Verify in Update mode
+ errl = inUpdateMode();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Enter Bootstrap Loader (BSL) mode to perform firmware update
+ errl = enterBootstrapLoaderMode();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Unlock the device. This is a BSL command so we must already be in
+ // BSL mode to execute it.
+ errl = unlockDevice();
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Run Firmware Update
+ errl = updateFirmware(i_image);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ TRACFCOMP(g_trac_bpm, "Bpm::runFirmwareUpdates(): "
+ "Perform final CRC check on entire BPM flash to load "
+ "new firmware.");
+
+ errl = checkFirmwareCrc();
+ if (errl != nullptr)
+ {
+ setAttemptAnotherUpdate();
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm:: runFirmwareUpdates(): "
+ "Final CRC check failed. %s ",
+ (iv_attemptAnotherUpdate == false) ?
+ "Attempt another update..."
+ : "Attempts to update the BPM have failed. Firmware will not load.");
+ break;
+ }
+
+ } while(0);
+
+ // Reset the device. This will exit BSL mode.
+ errlHndl_t exitErrl = resetDevice();
+ if (exitErrl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::runFirmwareUpdates(): "
+ "Failed to reset the device");
+ handleMultipleErrors(errl, exitErrl);
+ }
+
+ // Exit update mode
+ exitErrl = exitUpdateMode();
+ if (exitErrl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::runFirmwareUpdates(): "
+ "Failed to exit update mode");
+ handleMultipleErrors(errl, exitErrl);
+ }
+
+ return errl;
+}
+
+errlHndl_t Bpm::checkFirmwareCrc()
+{
+ TRACFCOMP(g_trac_bpm, ENTER_MRK"Bpm::checkFirmwareCrc()");
+ errlHndl_t errl = nullptr;
+
+ // The COMMAND_CRC_CHECK would return a 3 byte response in the following
+ // format:
+ //
+ // ========================================================================
+ // [Status Code] [Computed_CRC_Lo] [Computed_CRC_Hi]
+ // ========================================================================
+ // BSL_LOCKED 0x00 0x00
+ // PARAMETER_ERROR 0x00 0x00
+ // MAIN_FW_NOT_SUPPORT_CRC_CHECK 0x00 0x00
+ // MEMORY_WRITE_CHECK_FAILED CRC_Low CRC_Hi
+ // WRITE_FORBIDDEN CRC_Low CRC_Hi
+ // VERIFY_MISMATCH CRC_Low CRC_Hi
+ // SUCCESSFUL_OPERATION CRC_Low CRC_Hi
+ //
+ // For status codes BSL_LOCKED, PARAMETER_ERROR, and
+ // MAIN_FW_NOT_SUPPORT_CRC_CHECK the response CRC values are considered
+ // as DONT CARE.
+ //
+ // For the remainder of the status codes the CRC values are the
+ // computed CRC of the image.
+ //
+ // For SUCCESSFUL_OPERATION, the RESET_VECTOR was written.
+ // See bpm_update.H for more info on the status codes
+ const uint8_t CRC_CHECK_RESPONSE_SIZE = 3;
+ uint8_t responseData[CRC_CHECK_RESPONSE_SIZE] = {0};
+
+ do {
+
+ TRACFCOMP(g_trac_bpm, "Bpm::checkFirmwareCrc(): "
+ "Performing final CRC check.");
+ payload_t crcPayload;
+ errl = setupPayload(crcPayload,
+ BSL_CRC_CHECK,
+ iv_firmwareStartAddress);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ errl = issueCommand(BPM_PASSTHROUGH,
+ crcPayload,
+ WRITE,
+ NO_DELAY_EXTERNAL_RESPONSE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ // Wait 10 seconds for the CRC check to complete.
+ TRACFCOMP(g_trac_bpm, "Bpm::checkFirmwareCrc(): "
+ "Allow CRC check to complete on BPM by waiting 10 seconds.");
+ longSleep(10);
+
+ errl = getResponse(responseData, CRC_CHECK_RESPONSE_SIZE);
+ if (errl != nullptr)
+ {
+ break;
+ }
+
+ TRACFCOMP(g_trac_bpm, "Bpm::checkFirmwareCrc(): "
+ "Response Packet CRC check status = 0x%X, CRC_Low = 0x%X, "
+ "CRC_Hi = 0x%X",
+ responseData[0],
+ responseData[1],
+ responseData[2]);
+
+ if (responseData[0] != SUCCESSFUL_OPERATION)
+ {
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_PREDICTIVE
+ * @moduleid BPM_RC::BPM_CHECK_FIRMWARE_CRC
+ * @reasoncode BPM_RC::BPM_FIRMWARE_CRC_VERIFY_FAILURE
+ * @userdata1[0:7] CRC check response status code. See bpm_update.H
+ * @userdata1[8:15] CRC low byte
+ * @userdata1[16:23] CRC high byte
+ * @userdata2[0:63] NVDIMM Target HUID associated with this BPM
+ * @devdesc The firmware CRC check failed. Cross check the
+ * CRC check response status code for more details.
+ * @custdesc A problem occurred during IPL of the system.
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ BPM_RC::BPM_CHECK_FIRMWARE_CRC,
+ BPM_RC::BPM_FIRMWARE_CRC_VERIFY_FAILURE,
+ FOUR_UINT8_TO_UINT32(responseData[0],
+ responseData[1],
+ responseData[2],
+ 0),
+ TARGETING::get_huid(iv_nvdimm));
+ nvdimmAddPage4Regs(iv_nvdimm,errl);
+ nvdimmAddVendorLog(iv_nvdimm, errl);
+ break;
+ }
+
+ } while(0);
+
+ if (errl != nullptr)
+ {
+ TRACFCOMP(g_trac_bpm, ERR_MRK"Bpm::checkFirmwareCrc(): "
+ "Error occurred during BPM Firmware CRC check. "
+ "Firmware image will not load on BPM and update must be "
+ "attempted again.");
+ errl->collectTrace(BPM_COMP_NAME);
+ }
+
+ return errl;
+}
+
+/**
+ * @brief Helper function to handle two potential errors that might occur in a
+ * function that only returns a single error log. If the return error is
+ * not nullptr then the second error will be linked to it and committed
+ * if this is the final update attempt. Otherwise, it will be deleted
+ * since the update procedure will occur again and may be successful.
+ * If the return error is nullptr then the return error will point to
+ * the second's error and the second error will point to nullptr.
+ *
+ * @param[in/out] io_returnErrl A pointer to the error that would be
+ * returned by the function that called
+ * this one. If nullptr, then it will be
+ * set point to the secondary error and
+ * that error will become nullptr.
+ *
+ * @param[in/out] io_secondErrl The secondary error that occurred which
+ * in addition to the usual returned error.
+ */
+void Bpm::handleMultipleErrors(errlHndl_t& io_returnErrl,
+ errlHndl_t& io_secondErrl)
+{
+ if (iv_updateAttempted && (io_returnErrl != nullptr))
+ {
+ io_secondErrl->plid(io_returnErrl->plid());
+ TRACFCOMP(g_trac_bpm, "Committing second error eid=0x%X with plid of "
+ "returned error: 0x%X",
+ io_secondErrl->eid(),
+ io_returnErrl->plid());
+ io_secondErrl->collectTrace(BPM_COMP_NAME);
+ io_secondErrl->addPartCallout(iv_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ ERRORLOG::errlCommit(io_secondErrl, BPM_COMP_ID);
+ }
+ else if (io_returnErrl == nullptr)
+ {
+ io_returnErrl = io_secondErrl;
+ io_secondErrl = nullptr;
+ }
+ else
+ {
+ // Another update attempt will be made, delete this secondary error.
+ delete io_secondErrl;
+ io_secondErrl = nullptr;
+ }
+}
+
+uint16_t Bpm::crc16_calc(const void* i_ptr, int i_size)
+{
+ uint16_t crc = 0xFFFF;
+ const uint8_t* data = reinterpret_cast<const uint8_t*>(i_ptr);
+
+ while (--i_size >= 0)
+ {
+ crc = crc ^ *(data++) << 8;
+ for (size_t i = 0; i < 8; ++i)
+ {
+ if (crc & 0x8000)
+ {
+ crc = crc << 1 ^ 0x1021;
+ }
+ else
+ {
+ crc = crc << 1;
+ }
+ }
+ }
+
+ return (crc & 0xFFFF);
+}
+
+}; // End of BPM namespace
+}; // End of NVDIMM namespace
diff --git a/src/usr/isteps/nvdimm/bpm_update.H b/src/usr/isteps/nvdimm/bpm_update.H
new file mode 100644
index 000000000..4886a8abd
--- /dev/null
+++ b/src/usr/isteps/nvdimm/bpm_update.H
@@ -0,0 +1,1078 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/isteps/nvdimm/bpm_update.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef BPM_UPDATE_H
+#define BPM_UPDATE_H
+
+/* @file bpm_update.H
+ *
+ *
+ */
+
+#include <vector>
+#include <errl/errlentry.H>
+#include <targeting/common/util.H>
+
+namespace NVDIMM
+{
+namespace BPM
+{
+
+/*
+ * All of the various commands used for the BPM update. All commands can only be
+ * sent after write protection on the BPM has been disabled and the update magic
+ * values have been written to the BPM's magic registers.
+ *
+ * BSL: Bootstrap Loader commands
+ * BPM: Backup Power Module
+*/
+enum COMMAND : uint8_t
+{
+ // A payload sent with this command will be interpreted and processed by the
+ // NVDIMM module.
+ BPM_LOCAL = 0xFF,
+
+ /*
+ * These are LOCAL commands. These commands MUST be sent only outside of BSL
+ * BSL mode and must be paired with the BSP command BPM_LOCAL. Otherwise,
+ * unpredicatable errors will occur.
+ *
+ * When using issueCommand() for these commands they should always be sent
+ * with a 0 ms delay. This will ensure that the response packet is not
+ * checked from the BPM. Since these are processed by the NVDIMM it makes
+ * no sense to get a response from the BPM and attempting to do so will
+ * cause errors.
+ */
+ BCL_ENTER_BSL_MODE = 0x01,
+ BCL_IS_BSL_MODE = 0x02,
+ BCL_WRITE_REG = 0x03,
+ BCL_START_UPDATE = 0x04,
+ BCL_END_UPDATE = 0x05,
+ BCL_IS_UPDATE_IN_PROGRESS = 0x06,
+
+ // A payload sent with this command will be sent transparently to the BPM.
+ // This command must only be used while the BPM is in BSL mode.
+ BPM_PASSTHROUGH = 0xFE,
+
+ /*
+ * These are PASSTHROUGH commands. These commands MUST be sent only while in
+ * BSL mode and must be paired with BSP command BPM_PASSTHROUGH. Otherwise,
+ * unpredicatable errors will occur.
+ */
+ // Writes a block of data to the BPM.
+ // Delay 1ms (default)
+ BSL_RX_DATA_BLOCK = 0x10,
+ // Unlocks the BPM that is in BSL mode so that updates can occur.
+ // Delay 1ms (default)
+ BSL_RX_PASSWORD = 0x11,
+ // Erases 128 bytes at the given address offset.
+ // WARNING: Due to BSL memory limitations, BSL cannot verify the address
+ // is a valid config segment address offset and will blindly
+ // erase 128 bytes of data starting at that offset. If an invalid
+ // address is sent then the BPM will be bricked in a very
+ // unpredicatable/unrecoverable way.
+ // Delay 250ms
+ BSL_ERASE_SEGMENT = 0x12,
+ // Unknown, unused.
+ // Delay 0ms
+ BSL_TOGGLE_INFO = 0x13,
+ // Unknown, unused.
+ // Delay 1ms (default)
+ BSL_ERASE_BLOCK = 0x14,
+ // Erases the full firmware section on the BPM. The start of the firmware
+ // address must be supplied with this command.
+ // WARNING: Due to BSL memory limitations, BSL cannot verify the address
+ // is a valid firmware address offset and will blindly erase 128
+ // data starting at that offset. If an invalid address is sent
+ // then the BPM will be bricked in a very
+ // unpredicatable/unrecoverable way.
+ // Delay 250ms
+ BSL_MASS_ERASE = 0x15,
+ // Sends the command to the BPM to perform the final CRC check on the
+ // firmware written to the BPM. If the CRC check doesn't match the expected
+ // CRC in the flash image then the firmware will not load on the BPM and it
+ // will remain in BSL mode until new firmware is loaded onto it.
+ //
+ // Delay 0
+ // The response packet must be checked externally from the issueCommand()
+ // function because the response packet returned from this command is unique
+ // to this command and will return the results of this command. For more
+ // info see the checkFirmwareCrc() function description, implementation, and
+ // the COMMAND_BSL_CRC_CHECK_RESPONSE_CODES enum.
+ BSL_CRC_CHECK = 0x16,
+ // Unknown, unused.
+ // Delay 1ms (default)
+ BSL_LOAD_PC = 0x17,
+ // Unknown, unused.
+ // Delay 1ms (default)
+ BSL_TX_DATA_BLOCK = 0x18,
+ // Checks the Bootstrap Loader mode version on the BPM. Depending on this
+ // version, some parts of the update procedure may have changed.
+ //
+ // Delay 0ms
+ // The response packet must be checked externally from the issueCommand()
+ // function because the response packet returned from this command is unique
+ // to this command and will return the results of this command. For more
+ // info see the readBslVersion() function description and implementation.
+ BSL_TX_BSL_VERSION = 0x19,
+ // Unknown, unused.
+ // Delay 1ms (default)
+ BSL_TX_BUFFER_SIZE = 0x1A,
+ // Unknown, unused.
+ // Delay 1ms (default)
+ BSL_RX_DATA_BLOCK_FAST = 0x1B,
+ // Resets the BPM and exits BSL mode.
+ // Delay 0ms
+ // Never check for a response packet from the BPM after sending the reset
+ // command because the BPM may not be back up and if it is it will not be
+ // in BSL mode anymore. If the response packet is checked then errors will
+ // occur.
+ BSL_RESET_DEVICE = 0x1C,
+ // Verifies the block of data written to the BPM flash is identical to what
+ // was sent to it in a prior write. For more information see the
+ // verifyBlockWrite() description and implementation.
+ //
+ // Delay 0ms
+ // The response packet must be checked externally from the issueCommand()
+ // function because the response packet returned from this command is unique
+ // to this command and will return the results of this command.
+ BSL_VERIFY_BLOCK = 0x1D,
+};
+
+// These consts serve as reminders in the code for what was explained in the
+// COMMAND enum.
+const int NO_DELAY_NO_RESPONSE = 0;
+const int NO_DELAY_EXTERNAL_RESPONSE = 0;
+const int ERASE_SEGMENT_DELAY = 250;
+const int ERASE_FIRMWARE_DELAY = 250;
+
+// These are the various response codes returned by the BPM after the
+// BSL_CRC_CHECK command is sent at the end of the update procedure.
+enum COMMAND_BSL_CRC_CHECK_RESPONSE_CODES : uint16_t
+{
+ // The updated firmware is set up with all necessary loading parameters to
+ // load and execute upon reset.
+ SUCCESSFUL_OPERATION = 0x00,
+
+ // Error setting up the necessary loading parameters for the updated
+ // firmware image.
+ MEMORY_WRITE_CHECK_FAILED = 0x01,
+
+ // The command was attempted without unlocking the BSL with the password.
+ BSL_LOCKED = 0x04,
+
+ // Error setting up the necessary loading parameters for the updated
+ // firmware image.
+ WRITE_FORBIDDEN = 0x06,
+
+ // The checksum validation of the updated firmware image failed. The
+ // calculated checksum doesn't match the checksum data provided @FF7A in the
+ // firmware image file.
+ VERIFY_MISMATCH = 0x09,
+
+ // The firmware image start address given for the command is wrong.
+ PARAMETER_ERROR = 0x0A,
+
+ // Firmware image file used for the update doesn't hae the checksum data
+ // defined @FF7A
+ MAIN_FW_NOT_SUPPORT_CRC_CHECK = 0x0B,
+};
+
+// BSL versions that this code supports.
+const uint8_t BSL_VERSION_1_4 = 0x14;
+
+// The operator types for the BPM_CMD_STATUS register
+enum COMMAND_STATUS_REGISTER_OP_TYPES : uint8_t
+{
+ NOP = 0x00,
+ READ = 0x01,
+ WRITE = 0x02,
+ NO_TRASFER = 0x03,
+};
+
+// Used to overlay onto the LID image
+struct firmware_image_block
+{
+ // The block size is the sizeof(iv_addressOffset) plus sizeof(iv_data).
+ uint8_t iv_blockSize;
+
+ // The address offset where the first byte in iv_data came from in the
+ // firmware image.
+ uint16_t iv_addressOffset;
+
+ // A variable sized array of firmware data. The size of which is always
+ // iv_blockSize - sizeof(iv_addressOffset) and the max this can be is
+ // MAX_PAYLOAD_SIZE.
+ char iv_data[0];
+
+} PACKED;
+
+typedef firmware_image_block firmware_image_block_t;
+
+
+// Used to overlay onto the LID image
+struct config_image_fragment
+{
+ // The fragment size is the size of iv_data.
+ uint8_t iv_fragmentSize;
+
+ // The offset where the first byte in iv_data should begin overwritting the
+ // BPM config data in the BPM configuration segment dump buffer.
+ uint16_t iv_offset;
+
+ // A variable sized array of config segment data.
+ char iv_data[0];
+
+} PACKED;
+
+typedef config_image_fragment config_image_fragment_t;
+
+
+/* Max payload size is 26 bytes
+ * 4 bytes: header
+ * 1 byte: sync byte
+ * 1 byte: command
+ * 1 byte: header size + data size
+ * 1 byte: header size + data size
+ * 2 bytes: address
+ * 2 bytes: extra
+ * 16 bytes: data
+ * 2 bytes: CRC
+ */
+constexpr size_t MAX_PAYLOAD_SIZE = 26;
+
+// Max number of bytes data section of payload can be.
+constexpr size_t MAX_PAYLOAD_DATA_SIZE = 16;
+
+// Number of bytes for header, address, extra, and CRC
+constexpr size_t MAX_PAYLOAD_OTHER_DATA_SIZE = 10;
+
+// Number of bytes for the header.
+constexpr uint8_t PAYLOAD_HEADER_SIZE = 4;
+
+// Indices of where to find certain data within a constructed payload.
+// These indices have been subtracted by 1 from the given payload format because
+// after a payload is constructed the sync byte is removed from the front.
+constexpr uint8_t PAYLOAD_COMMAND_INDEX = 0;
+constexpr uint8_t PAYLOAD_ADDRESS_START_INDEX = 3;
+constexpr uint8_t PAYLOAD_DATA_START_INDEX = 7;
+constexpr uint8_t PAYLOAD_HEADER_DATA_LENGTH_INDEX = 1;
+
+// The sync byte that must always be at the front of a BPM payload. This is used
+// calculate the CRC of the payload and then removed because the nvdimm
+// automatically sends the sync byte ahead of the payload.
+constexpr uint8_t SYNC_BYTE = 0x80;
+constexpr uint8_t SYNC_BYTE_SIZE = sizeof(uint8_t);
+
+// Maximum size of any segment in the config data section
+constexpr size_t SEGMENT_SIZE = 128;
+
+// Maximum size of the config data section.
+constexpr size_t ALL_SEGMENTS_SIZE = 512;
+
+// Number of magic registers for the BPM
+constexpr size_t NUM_MAGIC_REGISTERS = 2;
+
+// These are the production magic values for the BPM that should be written in
+// BPM_MAGIC_REG1 and BPM_MAGIC_REG2 respectively.
+const uint8_t PRODUCTION_MAGIC_VALUES[NUM_MAGIC_REGISTERS] = {0x55, 0xAA};
+// These magic values to enable nvdimm-bpm interface. They must be written to
+// the magic registers BEFORE writing flash updates to the BPM in BSL mode.
+const uint8_t UPDATE_MODE_MAGIC_VALUES[NUM_MAGIC_REGISTERS] = {0xB0, 0xDA};
+// These are the segment read magic values that allow dumping of the segment
+// data from the BPM.
+const uint8_t SEGMENT_READ_MAGIC_VALUES[NUM_MAGIC_REGISTERS] = {0xBA, 0xAB};
+
+typedef std::vector<uint8_t> payload_t;
+
+
+/**
+ * @brief BPM_CMD_STATUS register bits
+ */
+struct command_status_register_bits
+{
+ uint8_t Abort_Request : 1; // Bit 7
+ uint8_t Abort_Acknowledge : 1; // Bit 6
+ uint8_t Reserved1 : 1; // Bit 5
+ uint8_t Reserved2 : 1; // Bit 4
+ uint8_t Error_Flag : 1; // Bit 3
+ uint8_t Bsp_Cmd_In_Progress : 1; // Bit 2
+ uint8_t Operator_Type : 2; // Bit 1-0
+} PACKED;
+
+/**
+ * @brief Union simplifying manipulation of REG_CMD_STATUS value
+ */
+union command_status_register_union
+{
+ uint8_t value;
+ command_status_register_bits bits;
+
+ /**
+ * @brief Constructor
+ */
+ command_status_register_union()
+ : value(0)
+ {}
+
+} PACKED;
+
+typedef command_status_register_union command_status_register_t;
+
+class BpmFirmwareLidImage
+{
+public:
+
+ /**
+ * @brief Constructor that sets access to LID information
+ *
+ * @param[in] i_lidImageAddr virtual address where LID was loaded
+ * @param[in] i_size size of the loaded LID
+ */
+ BpmFirmwareLidImage(void * const i_lidImageAddr, size_t i_size);
+
+ /**
+ * @brief Returns the version of the firmware binary as a uint16_t
+ *
+ * @return uint16_t version of the firmware image as MMmm.
+ * MM = major version, mm = minor.
+ */
+ uint16_t getVersion() const;
+
+ /**
+ * @brief Returns the number of blocks in the LID image.
+ *
+ */
+ uint16_t getNumberOfBlocks() const;
+
+ /**
+ * @brief Returns a pointer to the first block in LID image.
+ */
+ void const * getFirstBlock() const;
+
+ /* Layout of the BPM Firmware image
+ * Byte 1: Major version number (MM)
+ * Byte 2: Minor version number (mm)
+ * Byte 3-4: N number of blocks in the file (NN NN)
+ * Byte 5-EOF: Blocks of the form:
+ * BLOCK_SIZE Byte 1: X number of bytes in block excluding
+ * this byte. (XX)
+ * ADDRESS_OFFSET Byte 2-3: Original address offset of the
+ * first data byte. (AD DR)
+ * DATA_BYTES Byte 4-X: Firmware data bytes (DD)
+ *
+ * Example file:
+ * 01 03 00 01 06 80 00 6a 14 31 80
+ * MM mm NN NN XX AD DR DD DD DD DD
+ */
+ typedef struct firmware_image_header
+ {
+ uint8_t iv_versionMajor;
+ uint8_t iv_versionMinor;
+ uint16_t iv_numberOfBlocks;
+ } firmware_image_header_t;
+
+private:
+
+ // Pointer to the LID image allocated outside of the class
+ void * const iv_lidImage;
+
+ // The size of the LID image.
+ size_t iv_lidImageSize;
+};
+
+
+class BpmConfigLidImage
+{
+public:
+
+ /**
+ * @brief Constructor that sets access to LID information
+ *
+ * @param[in] i_lidImageAddr virtual address where LID was loaded
+ * @param[in] i_size size of the loaded LID
+ */
+ BpmConfigLidImage(void * const i_lidImageAddr, size_t i_size);
+
+ /**
+ * @brief Returns the version of the config binary as a uint16_t. There isn't
+ * a way to check the version of the config data on the BPM but the
+ * config binary still has the version of the flash image it
+ * originally came from.
+ *
+ * @return uint16_t version of the firmware image as MMmm.
+ * MM = major version, mm = minor.
+ */
+ uint16_t getVersion() const;
+
+ /**
+ * @brief Returns the number of fragments in the LID image.
+ *
+ */
+ uint16_t getNumberOfFragments() const;
+
+ /**
+ * @brief Returns a pointer to the first fragment in LID image.
+ */
+ void const * getFirstFragment() const;
+
+ /* The binary will be organized in the following way:
+ * Byte 1: Major version number (MM)
+ * Byte 2: Minor version number (mm)
+ * Byte 3: N number of fragments in the file (NN)
+ * Byte 4-EOF: Fragments of the form:
+ * FRAGMENT_SIZE Byte 1: X number of bytes in fragment data
+ * section. (XX)
+ * INDEX_OFFSET Byte 2-3: Each BPM's config section is unique
+ * to itself. So, during the update
+ * the contents of a BPM's config data
+ * will be dumped into a buffer.
+ * These two bytes will be used as an
+ * offset into that buffer from which
+ * overwritting will take place.
+ * (IN DX)
+ * DATA_BYTES Byte 4-X: Fragment data bytes to be written
+ * at the INDEX_OFFSET in the dumped
+ * config data buffer. (DD)
+ *
+ * Example file output:
+ * 01 05 01 04 01 28 6a 14 31 80
+ * MM mm NN XX IN DX DD DD DD DD
+ */
+ typedef struct config_image_header
+ {
+ uint8_t iv_versionMajor;
+ uint8_t iv_versionMinor;
+ uint16_t iv_numberOfFragments;
+ } config_image_header_t;
+
+private:
+
+ // Pointer to the LID image allocated outside of the class
+ void * const iv_lidImage;
+
+ // The size of the LID image.
+ size_t iv_lidImageSize;
+};
+
+class Bpm
+{
+ /*
+ * The Bpm can either be in Bootstrap Loader (BSL) mode or not. Many of
+ * member functions utilize BSL mode for the update procedure and must
+ * therefore be in BSL mode to succeed. Other functions perform operations
+ * that will not work in BSL mode since that mode is strictly for updating
+ * the device and turns of some functionality while in that mode. The "mode"
+ * the BPM must be in is given in the function brief description.
+ */
+public:
+
+
+ explicit Bpm(const TARGETING::TargetHandle_t i_nvdimm);
+
+ // Force User to supply a nvdimm target.
+ Bpm() = delete;
+
+ /**
+ * @brief Runs the BPM firmware update using the given image.
+ *
+ * @param[in] i_image The BPM firmware image.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, pointer to an
+ * errlEntry.
+ */
+ errlHndl_t runUpdate(BpmFirmwareLidImage i_fwImage,
+ BpmConfigLidImage i_configImage);
+
+ /**
+ * @brief At most, one full update retry should occur in some
+ * circumstances. If one of those occurances happens then the
+ * member iv_attemptAnotherUpdate will be set to true. Otherwise, it
+ * will remain false.
+ *
+ * @return bool true if another update should be attempted.
+ * Otherwise, false.
+ */
+ bool attemptAnotherUpdate();
+
+ /**
+ * @brief Returns if an update has been attempted on this BPM.
+ *
+ * @return bool true if an update has been attempted before.
+ * Otherwise, false.
+ */
+ bool hasAttemptedUpdate();
+
+ /**
+ * @brief returns the nvdimm that is associated with this BPM.
+ */
+ const TARGETING::TargetHandle_t getNvdimm();
+
+private:
+
+ // The nvdimm whose battery firmware will be updated.
+ const TARGETING::TargetHandle_t iv_nvdimm;
+
+ // The Bootstrap Loader version of the BPM
+ uint8_t iv_bslVersion;
+
+ // The firmware address for the BPM image can be either 0x8000 or 0xA000.
+ // This member will keep track of which one it is.
+ uint16_t iv_firmwareStartAddress;
+
+ // Keeps track of if the update should be attempted again.
+ bool iv_attemptAnotherUpdate;
+
+ // Buffers for the segment data in case another update attempt is needed.
+ // If the first update fails there won't be any running firmware on the
+ // device which is required to dump the segment data.
+ uint8_t iv_segmentD[SEGMENT_SIZE];
+ uint8_t iv_segmentB[SEGMENT_SIZE];
+
+ // Keeps track if the segments have been merged with the flash image data
+ // yet.
+ bool iv_segmentDMerged;
+ bool iv_segmentBMerged;
+
+ // Keeps track of if an update has been attempted at least once.
+ bool iv_updateAttempted;
+
+ /**
+ * @brief Determines if another update attempt should occur for this BPM.
+ */
+ void setAttemptAnotherUpdate();
+
+ /**
+ * @brief Gets the BSL version from the BPM and sets the iv_bslVersion
+ * member. Only needs to be called once.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, pointer to an
+ * errlEntry.
+ */
+ errlHndl_t readBslVersion();
+
+ /**
+ * @brief Gets the Firmware version from the BPM
+ *
+ * @param[out] o_fwVersion The firmware version currently on the BPM.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, pointer to an
+ * errlEntry.
+ */
+ errlHndl_t getFwVersion(uint16_t & o_fwVersion) const;
+
+ /**
+ * @brief This function issues a command to the BPM using a payload as the
+ * means of sending the command.
+ *
+ * @param[in] i_command The BSP command to send to the BPM.
+ * @param[in] i_payload The payload to write to the
+ * BPM_REG_PAYLOAD_START register.
+ * @param[in] i_opType The operation type of the command. Must be one
+ * of the COMMAND_STATUS_REGISTER_OP_TYPES
+ *
+ * @param[in] i_msDelay How long to wait before the response from the
+ * BPM should be checked. Default 1 ms. If a delay
+ * of 0 ms is given then the response will not be
+ * read and it is the caller's responsibilty to
+ * check the response status. See COMMAND enum for
+ * required delays.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, pointer to an
+ * errlEntry.
+ */
+ errlHndl_t issueCommand(uint8_t i_command,
+ payload_t i_payload,
+ uint8_t i_opType,
+ int i_msDelay = 1);
+
+ /**
+ * @brief This function issues a BSP command to the BPM by setting up a
+ * payload containing only that command and then calling the
+ * issueCommand function that accepts a payload as an argument.
+ *
+ * NOTE: Since the BSP command is not a BSL command, it doesn't need
+ * to be formatted as a BSL payload but it still must be written to
+ * the BPM_REG_PAYLOAD_START register.
+ *
+ * @param[in] i_bspCommand The BSP command to send to the BPM.
+ * @param[in] i_command The BCL command to be written to the
+ * BPM_REG_PAYLOAD_START register. Must be one
+ * of the BCL_ commands.
+ * @param[in] i_opType The operation type of the BSP command. Must
+ * be a COMMAND_STATUS_REGISTER_OP_TYPES
+ *
+ * @param[in] i_msDelay How long to wait before the response from the
+ * BPM should be checked. Default 1 ms. If a delay
+ * of 0 ms is given then the response will not be
+ * read and it is the caller's responsibilty to
+ * check the response status. See COMMAND enum for
+ * required delays.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, pointer to an
+ * errlEntry.
+ */
+ errlHndl_t issueCommand(uint8_t i_bspCommand,
+ uint8_t i_command,
+ uint8_t i_opType,
+ int i_msDelay = 1);
+
+ /**
+ * @brief This function checks if the BPM has entered update mode
+ *
+ * @return errlHndl_t nullptr on success.
+ * Otherwise, pointer to an errlEntry.
+ */
+ errlHndl_t inUpdateMode();
+
+ /**
+ * @brief Send the command to the BPM to enter update mode
+ *
+ * @return errlHndl_t nullptr if no errors occurred during command
+ * execution. Otherwise, pointer to an errlEntry.
+ */
+ errlHndl_t enterUpdateMode();
+
+ /**
+ * @brief Send the command to the BPM to exit update mode
+ *
+ * @return errlHndl_t nullptr if no errors occurred during command
+ * execution. Otherwise, pointer to an errlEntry.
+ */
+ errlHndl_t exitUpdateMode();
+
+ /**
+ * @brief Executes the firmware portion of the BPM update.
+ *
+ * @param[in] i_image The BPM firmware LID image to apply to the BPM.
+ *
+ * @return errlHndl_t nullptr if no errors occurred.
+ * Otherwise, pointer to an errlEntry.
+ */
+ errlHndl_t updateFirmware(BpmFirmwareLidImage i_image);
+
+ /**
+ * @brief Helper function that executes the firmware portion of the BPM
+ * update by calling all necessary functions in order.
+ *
+ * @param[in] i_image The BPM firmware LID image to apply to the BPM.
+ *
+ * @return errlHndl_t nullptr if no errors occurred.
+ * Otherwise, pointer to an errlEntry.
+ */
+ errlHndl_t runFirmwareUpdates(BpmFirmwareLidImage i_image);
+
+ /**
+ * @brief Executes the config portion of the BPM update.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an Error.
+ */
+ errlHndl_t updateConfig();
+
+ /**
+ * @brief Helper function that executes the config portion of the BPM
+ * update by calling all necessary functions in order.
+ *
+ * @param[in] i_image The BPM config LID image to apply to the BPM.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an Error.
+ */
+ errlHndl_t runConfigUpdates(BpmConfigLidImage i_image);
+
+ /**
+ * @brief Commands the BPM to enter BSL mode to allow for BSL commands to be
+ * executed.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, pointer to an
+ * errlEntry.
+ */
+ errlHndl_t enterBootstrapLoaderMode();
+
+ /**
+ * @brief Creates a valid BSL payload given a firmware_image_block_t.
+ *
+ * @param[out] o_payload The BSL payload
+ * @param[in] i_block A pointer to a firmware image block.
+ * @param[in] i_command The BSL command to be included with the payload
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, pointer to an
+ * errlEntry.
+ */
+ errlHndl_t setupPayload(payload_t & o_payload,
+ const firmware_image_block_t * i_block,
+ uint8_t i_command);
+
+ /**
+ * @brief Creates a valid BSL payload given a BSL command, address, and
+ * optionally data to include with the command. This function is used
+ * to create firmware_image_block_t objects which are then passed
+ * onto the version of setupPayload that turns them into payloads.
+ *
+ * @param[out] o_payload The BSL payload
+ * @param[in] i_command The BSL command to be included with the payload
+ * @param[in] i_address The address to execute the command from. This
+ * will be zero or the address to execute the
+ * command from.
+ * @param[in] i_data The array of data to be included with the BSL
+ * command. Default nullptr.
+ * @param[in] i_length Length of the i_data array parameter. Default 0.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, pointer to an
+ * errlEntry.
+ */
+ errlHndl_t setupPayload(payload_t & o_payload,
+ uint8_t i_command,
+ uint16_t i_address,
+ const uint8_t i_data[] = nullptr,
+ size_t i_length = 0);
+
+ /**
+ * @brief This function unlocks the BPM.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, pointer to an
+ * errlEntry.
+ */
+ errlHndl_t unlockDevice();
+
+ /**
+ * @brief This function will send the command to reset the BPM. This will
+ * exit BSL mode if the BPM was in that mode.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, pointer to an
+ * errlEntry.
+ */
+ errlHndl_t resetDevice();
+
+ /**
+ * @brief Write to the BPM register via the SCAP registers
+ *
+ * @param[in] i_reg The BPM register to write to.
+ *
+ * @param[in] i_data The data to write to the given register.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error.
+ */
+ errlHndl_t writeViaScapRegister(uint8_t i_reg, uint8_t i_data);
+
+ /**
+ * @brief Reads the BPM register via the SCAP registers
+ *
+ * @param[in] i_reg The BPM register to read from.
+ *
+ * @param[in/out] io_data The data that was in the given register.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error.
+ */
+ errlHndl_t readViaScapRegister(uint8_t i_reg, uint8_t & io_data);
+
+ /**
+ * @brief Disables write protection on the BPM by sending the password
+ * sequence to I2C_REG_PROTECT
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error.
+ */
+ errlHndl_t disableWriteProtection();
+
+ /**
+ * @brief Many operations performed on the BPM require the magic registers
+ * to have specific values written in them. This function acts as a
+ * helper to facilitate that process.
+ *
+ * NOTE: Write protection on the BPM must be disabled, otherwise
+ * this function will fail.
+ *
+ * @param[in] i_magicValues The pair of magic values to be written to
+ * BPM_MAGIC_REG1 and BPM_MAGIC_REG2
+ * respectively.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error.
+ */
+ errlHndl_t writeToMagicRegisters(
+ uint8_t const (&i_magicValues)[NUM_MAGIC_REGISTERS]);
+
+ /**
+ * @brief Switches the page on the BPM to the given page. This function
+ * must be executed only after the segment read magic values have
+ * been written to the BPM's magic registers.
+ *
+ * @param[in] i_segmentCode The segment code that corresponds to the
+ * page to switch to on the BPM.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error
+ *
+ */
+ errlHndl_t switchBpmPage(uint16_t i_segmentCode);
+
+ /**
+ * @brief Dumps the given segment data from the BPM. CANNOT be in BSL mode.
+ *
+ * @param[in] i_segmentCode The segment code that corresponds to the
+ * segment to dump from the BPM.
+ *
+ * @param[out] o_buffer A pointer to the buffer to fill with segment
+ * data. Must be SEGMENT_SIZE in size.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error
+ *
+ */
+ errlHndl_t dumpSegment(uint16_t i_segmentCode,
+ uint8_t (&o_buffer)[SEGMENT_SIZE]);
+
+ /**
+ * @brief Merges the segment data dumped from the BPM with the segment data
+ * fragments present in the BpmConfigLidImage that correspond to the
+ * given segment code.
+ *
+ * @param[in] i_configImage The image that holds the fragments of
+ * segment data.
+ *
+ * @param[in] i_segmentCode The segment code that corresponds to the
+ * segment to dump from the BPM.
+ *
+ * @param[out] o_buffer The merged segment data for the BPM.
+ * Must be SEGMENT_SIZE in length.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error.
+ */
+ errlHndl_t mergeSegment(BpmConfigLidImage i_configImage,
+ uint16_t i_segmentCode,
+ uint8_t (&o_buffer)[SEGMENT_SIZE]);
+
+ /**
+ * @brief Commands the BPM to erase the segment data on the BPM using the
+ * given segment code to tell it which to erase.
+ * The BPM must be in BSL mode for this function to work.
+ *
+ * @param[in] i_segmentCode The segment from the config data section to
+ * erase.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error.
+ */
+ errlHndl_t eraseSegment(uint16_t i_segmentCode);
+
+ /**
+ * @brief Writes the segment data from the buffer to the BPM using the
+ * given segment code to determine which segment the data belongs
+ * to. The BPM must be in BSL mode for this function to work.
+ *
+ * @param[in] i_buffer The segment data to write to the BPM.
+ *
+ * @param[in] i_segmentCode The segment from the config data section the
+ * data belongs to.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error.
+ */
+ errlHndl_t writeSegment(uint8_t const (&i_buffer)[SEGMENT_SIZE],
+ uint16_t i_segmentCode);
+
+ /**
+ * @brief Dumps segment D and B data from the BPM and merges it with the
+ * data from the config image to create the unique updated segments
+ * for this BPM. The BPM CANNOT be in BSL mode for this function to
+ * work because the data is dumped using SCAP registers. There must
+ * also be working firmware on the device otherwise this will fail.
+ *
+ * @param[in] i_configImage The config image that has the fragments to
+ * merge into the BPM's existing segment data.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error.
+ */
+ errlHndl_t preprocessSegments(BpmConfigLidImage i_configImage);
+
+ /**
+ * @brief Verifies that the data written into the flash on the BPM is what
+ * was sent by hostboot in a payload.
+ *
+ * @param[in] i_payload The payload that was just sent to the BPM to
+ * be verified.
+ *
+ * @param[in] i_dataLength The length of the data section of the
+ * payload.
+ *
+ * @param[in] o_status The status code returned from the BPM.
+ * A status of 0 indicates success, all other
+ * values are a failure.
+ *
+ * @return errlHndl_t nullptr if no errors. Otherwise, an error.
+ */
+ errlHndl_t verifyBlockWrite(payload_t i_payload,
+ uint8_t i_dataLength,
+ uint8_t & o_status);
+
+ /**
+ * @brief Attempts a BSL_RX_DATA_BLOCK command up to three times by calling
+ * blockWriteRetry.
+ *
+ * @param[in] i_payload The payload containing the BSL_RX_DATA_BLOCK
+ * command and the data to be attempted to be
+ * written.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error.
+ */
+ errlHndl_t blockWrite(payload_t i_payload);
+
+ /**
+ * @brief Attempts a BSL_RX_DATA_BLOCK command up to three times.
+ *
+ * @param[in] i_payload The payload containing the BSL_RX_DATA_BLOCK
+ * command and the data to be attempted to be
+ * written.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error.
+ */
+ errlHndl_t blockWriteRetry(payload_t i_payload);
+
+ /**
+ * @brief A helper function used to wait for the command status bit to reset
+ * after a command is executed.
+ *
+ * @param[in] i_commandStatus The command status register union made
+ * by the caller to identify the type of
+ * command that was sent.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error.
+ */
+ errlHndl_t waitForCommandStatusBitReset(
+ command_status_register_t i_commandStatus);
+
+ errlHndl_t verifyGoodBpmState();
+
+ /**
+ * @brief Helper function for the SCAP register functions that will poll
+ * the busy bit in SCAP_STATUS until it is zero.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error.
+ */
+ errlHndl_t waitForBusyBit();
+
+ /**
+ * @brief Starting with BSL version 1.4 it is necessary to check the CRC of
+ * the firmware image once it has been written to the BPM. If this
+ * is not done or fails to succeed then the firmware image will not
+ * be loaded and executed by the BPM. If the CRC check fails then
+ * the update must be attempted again.
+ * Must be in BSL mode.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error.
+ */
+ errlHndl_t checkFirmwareCrc();
+
+ /**
+ * @brief After a command is sent to the BPM to request info from it this
+ * function processes the response and returns it to the caller.
+ * A response packet can only be received once per command sent to
+ * the BPM. Which means that the caller must resend the command
+ * again to get another response packet. Simply calling the function
+ * repeatedly will not work. BPM must be in BSL mode.
+ *
+ * @param[in] o_responseData The buffer to be filled with the
+ * response data from the BPM.
+ *
+ * @param[in] i_responseSize The size of the buffer to be filled.
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, an error.
+ */
+ errlHndl_t getResponse(uint8_t * o_responseData,
+ uint8_t i_responseSize);
+
+
+ /**
+ * @brief Helper function to handle two potential errors that might occur in a
+ * function that only returns a single error log. If the return error is
+ * not nullptr then the second error will be linked to it and committed
+ * if this is the final update attempt. Otherwise, it will be deleted
+ * since the update procedure will occur again and may be successful.
+ * If the return error is nullptr then the return error will point to
+ * the second's error and the second error will point to nullptr.
+ *
+ * @param[in/out] io_returnErrl A pointer to the error that would be
+ * returned by the function that called
+ * this one. If nullptr, then it will be
+ * set point to the secondary error and
+ * that error will become nullptr.
+ *
+ * @param[in/out] io_secondErrl The secondary error that occurred which
+ * in addition to the usual returned error.
+ */
+ void handleMultipleErrors(errlHndl_t& io_returnErrl,
+ errlHndl_t& io_secondErrl);
+
+ /**
+ * @brief Calculates the CRC16 bytes for the BSL payload. This CRC differs
+ * from the NVDIMM CRC calculation in that the initial value is
+ * 0xFFFF instead of 0x0000.
+ *
+ * NOTE: To calculate a correct CRC for the BSL payload the SYNC_BYTE
+ * must be included in the payload despite the fact that it
+ * should be removed from the payload before sending to the BPM
+ * because the NVDIMM sends the SYNC_BYTE automatically.
+ *
+ * @param[in] i_ptr A pointer to the start of the data to calculate the
+ * CRC for.
+ * @param[in] i_size This size of the data pointed at by i_ptr.
+ *
+ * @return uint16_t The CRC bytes.
+ */
+ uint16_t crc16_calc(const void* const i_ptr, int i_size);
+
+
+};
+
+typedef std::vector<Bpm> bpmList_t;
+
+/**
+ * @brief Runs the firmware and config updates on the list of BPMs given.
+ *
+ * @param[in] i_16gb_BPMs The list of BPMs sitting on 16gb NVDIMMs that
+ * potentially need to be updated.
+ *
+ * @param[in] i_32gb_BPMs The list of BPMs sitting on 32gb NVDIMMs that
+ * potentially need to be updated.
+ *
+ * @param[in] i_16gb_fwImage The firmware image associated with BPMs sitting
+ * on 16gb NVDIMMs.
+ *
+ * @param[in] i_32gb_fwImage The firmware image associated with BPMs sitting
+ * on 32gb NVDIMMs.
+ *
+ * @param[in] i_16gb_configImage The configuration data associated with BPMs
+ * sitting on 16gb NVDIMMs.
+ *
+ * @param[in] i_32gb_configImage The configuration data associated with BPMs
+ * sitting on 32gb NVDIMMs.
+ *
+ */
+void runBpmUpdates(bpmList_t * const i_16gb_BPMs,
+ bpmList_t * const i_32gb_BPMs,
+ BpmFirmwareLidImage * const i_16gb_fwImage,
+ BpmFirmwareLidImage * const i_32gb_fwImage,
+ BpmConfigLidImage * const i_16gb_configImage,
+ BpmConfigLidImage * const i_32gb_configImage);
+
+}; // end of BPM namespace
+}; // end of NVDIMM namespace
+
+#endif
+
diff --git a/src/usr/isteps/nvdimm/errlud_nvdimm.C b/src/usr/isteps/nvdimm/errlud_nvdimm.C
index 743297b94..07afa187a 100644
--- a/src/usr/isteps/nvdimm/errlud_nvdimm.C
+++ b/src/usr/isteps/nvdimm/errlud_nvdimm.C
@@ -158,9 +158,53 @@ UdNvdimmParms::UdNvdimmParms( uint8_t i_opType,
}
//------------------------------------------------------------------------------
-UdNvdimmParms::~UdNvdimmParms()
-{
+UdNvdimmParms::~UdNvdimmParms() = default;
+//------------------------------------------------------------------------------
+// NVDIMM Dimm Operation Parameters and Errors
+//------------------------------------------------------------------------------
+UdNvdimmOPParms::UdNvdimmOPParms( const nvdimm_reg_t &i_RegInfo )
+{
+ // Version control for ErrorUD struct
+ iv_CompId = NVDIMM_COMP_ID;
+ iv_Version = 3;
+ iv_SubSection = NVDIMM_OP_PARAMETERS;
+
+ //***** Memory Layout *****
+ // 1 byte : MODULE_HEALTH
+ // 1 byte : MODULE_HEALTH_STATUS0
+ // 1 byte : MODULE_HEALTH_STATUS1
+ // 1 byte : CSAVE_STATUS
+ // 1 byte : CSAVE_INFO
+ // 1 byte : CSAVE_FAIL_INFO0
+ // 1 byte : CSAVE_FAIL_INFO1
+ // 1 byte : CSAVE_TIMEOUT_INFO0
+ // 1 byte : CSAVE_TIMEOUT_INFO1
+ // 1 byte : ERROR_THRESHOLD_STATUS
+ // 1 byte : NVDIMM_READY
+ // 1 byte : NVDIMM_CMD_STATUS0
+ // 1 byte : ABORT_CMD_TIMEOUT
+ // 1 byte : ERASE_STATUS
+ // 1 byte : ERASE_FAIL_INFO
+ // 1 byte : ERASE_TIMEOUT0
+ // 1 byte : ERASE_TIMEOUT1
+ // 1 byte : SET_ES_POLICY_STATUS
+ // 1 byte : RESTORE_STATUS
+ // 1 byte : RESTORE_FAIL_INFO
+ // 1 byte : RESTORE_TIMEOUT0
+ // 1 byte : RESTORE_TIMEOUT1
+ // 1 byte : ARM_STATUS
+ // 1 byte : ARM_FAIL_INFO
+ // 1 byte : ARM_TIMEOUT0
+ // 1 byte : ARM_TIMEOUT1
+ // 1 byte : SET_EVENT_NOTIFICATION_STATUS
+ // 1 byte : ENCRYPTION_CONFIG_STATUS
+
+ char * l_pBuf = reinterpret_cast<char *>( reallocUsrBuf(sizeof(i_RegInfo)));
+ memcpy(l_pBuf, &i_RegInfo, sizeof(i_RegInfo));
}
+// Default the deconstructor
+UdNvdimmOPParms::~UdNvdimmOPParms() = default;
+
} // end NVDIMM namespace
diff --git a/src/usr/isteps/nvdimm/errlud_nvdimm.H b/src/usr/isteps/nvdimm/errlud_nvdimm.H
index 55b5f9b20..2041da054 100644
--- a/src/usr/isteps/nvdimm/errlud_nvdimm.H
+++ b/src/usr/isteps/nvdimm/errlud_nvdimm.H
@@ -61,12 +61,37 @@ class UdNvdimmParms : public ERRORLOG::ErrlUserDetails
*/
virtual ~UdNvdimmParms();
- private:
// Disabled
- UdNvdimmParms(UdNvdimmParms &);
- UdNvdimmParms & operator=(UdNvdimmParms &);
+ UdNvdimmParms(UdNvdimmParms &) = delete;
+ UdNvdimmParms & operator=(UdNvdimmParms &) = delete;
};
-} // end NVDIMM namespace
+/**
+ * @class UdNvdimmOPParms
+ *
+ * Adds NVDIMM information to an error log as user detail data
+ */
+class UdNvdimmOPParms : public ERRORLOG::ErrlUserDetails
+{
+ public:
+ /**
+ * @brief Constructor
+ *
+ * @param i_i2cInfo Miscellaneous Parameters
+ */
+ UdNvdimmOPParms( const nvdimm_reg_t &i_RegInfo );
+
+ /**
+ * @brief Destructor
+ */
+ virtual ~UdNvdimmOPParms();
+
+ // Disabled
+ UdNvdimmOPParms() = delete;
+ UdNvdimmOPParms(UdNvdimmOPParms &) = delete;
+ UdNvdimmOPParms & operator=(UdNvdimmOPParms &) = delete;
+};
+
+} // end of namespace NVDIMM
#endif
diff --git a/src/usr/isteps/nvdimm/nvdimm.C b/src/usr/isteps/nvdimm/nvdimm.C
index 79d7b679d..e93271e5e 100644
--- a/src/usr/isteps/nvdimm/nvdimm.C
+++ b/src/usr/isteps/nvdimm/nvdimm.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2019 */
+/* Contributors Listed Below - COPYRIGHT 2014,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -28,6 +28,8 @@
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <errl/errludtarget.H>
+#include <errl/errludlogregister.H>
+#include <errl/errludstring.H>
#include <targeting/common/commontargeting.H>
#include <targeting/common/util.H>
#include <targeting/common/utilFilter.H>
@@ -36,33 +38,39 @@
#include <fapi2.H>
#include <fapi2/plat_hwp_invoker.H>
#include <lib/shared/nimbus_defaults.H>
+#include <lib/ccs/ccs_nimbus.H>
#include <lib/dimm/ddr4/nvdimm_utils.H>
#include <lib/mc/port.H>
#include <isteps/nvdimm/nvdimmreasoncodes.H>
+#include "errlud_nvdimm.H"
+#include "nvdimmErrorLog.H"
#include <isteps/nvdimm/nvdimm.H>
#include <vpd/spdenums.H>
+#include <secureboot/trustedbootif.H>
+#include <targeting/common/targetUtil.H>
+#ifdef __HOSTBOOT_RUNTIME
+#include <runtime/hbrt_utilities.H>
+#include <targeting/runtime/rt_targeting.H>
+#else
+#include <initservice/istepdispatcherif.H>
+#endif
using namespace TARGETING;
using namespace DeviceFW;
using namespace EEPROM;
+using namespace ERRORLOG;
trace_desc_t* g_trac_nvdimm = NULL;
TRAC_INIT(&g_trac_nvdimm, NVDIMM_COMP_NAME, 2*KILOBYTE);
// Easy macro replace for unit testing
-#define TRACUCOMP(args...) TRACFCOMP(args)
-//#define TRACUCOMP(args...)
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
namespace NVDIMM
{
#define NUM_OFFSET 2
-#define NVDIMM_SET_USER_DATA_1(left_32_ops_id, right_32_huid) \
- TWO_UINT32_TO_UINT64(left_32_ops_id, right_32_huid)
-
-#define NVDIMM_SET_USER_DATA_2_TIMEOUT(left_32_polled, right_32_timeout) \
- NVDIMM_SET_USER_DATA_1(left_32_polled, right_32_timeout)
-
typedef struct ops_timeoutInfo{
const char * desc;
@@ -83,6 +91,173 @@ constexpr ops_timeoutInfo_t timeoutInfoTable[] =
{"CHARGE", {ES_CHARGE_TIMEOUT1, ES_CHARGE_TIMEOUT0}, CHARGE , MODULE_HEALTH_STATUS1, CHARGE_IN_PROGRESS},
};
+// Definition of ENCRYPTION_CONFIG_STATUS -- page 5 offset 0x20
+typedef union {
+ uint8_t whole;
+ struct
+ {
+ uint8_t reserved : 1; // [7]
+ uint8_t unsupported_field : 1; // [6]
+ uint8_t erase_pending : 1; // [5]
+ uint8_t encryption_unlocked : 1; // [4]
+ uint8_t encryption_enabled : 1; // [3]
+ uint8_t erase_key_present : 1; // [2]
+ uint8_t random_string_present : 1; // [1]
+ uint8_t encryption_supported : 1; // [0]
+ } PACKED;
+} encryption_config_status_t;
+
+// Valid bits to check against (skips reserved and unsupported)
+static constexpr uint8_t ENCRYPTION_STATUS_CHECK_MASK = 0x3F;
+static constexpr uint8_t ENCRYPTION_STATUS_DISABLED = 0x01;
+static constexpr uint8_t ENCRYPTION_STATUS_ENABLED = 0x1F;
+
+// NV_STATUS masks
+static constexpr uint8_t NV_STATUS_OR_MASK = 0xFB;
+static constexpr uint8_t NV_STATUS_AND_MASK = 0x04;
+static constexpr uint8_t NV_STATUS_UNPROTECTED_SET = 0x01;
+static constexpr uint8_t NV_STATUS_UNPROTECTED_CLR = 0xFE;
+static constexpr uint8_t NV_STATUS_ENCRYPTION_SET = 0x10;
+static constexpr uint8_t NV_STATUS_ENCRYPTION_CLR = 0xEF;
+static constexpr uint8_t NV_STATUS_ERASE_VERIFY_SET = 0x20;
+static constexpr uint8_t NV_STATUS_ERASE_VERIFY_CLR = 0xDF;
+static constexpr uint8_t NV_STATUS_POSSIBLY_UNPROTECTED_SET = 0x40;
+
+// NVDIMM key consts
+static constexpr size_t NUM_KEYS_IN_ATTR = 3;
+static constexpr size_t MAX_TPM_SIZE = 34;
+static constexpr uint8_t KEY_TERMINATE_BYTE = 0x00;
+static constexpr uint8_t KEY_ABORT_BYTE = 0xFF;
+
+// NVDIMM CSAVE_FAIL_INFO1 Bit mask
+// Currently only bits 1:6 need to be checked during init
+static constexpr uint8_t CSAVE_FAIL_BITS_MASK = 0x7E;
+
+// LOG PAGE INFO
+static constexpr size_t VENDOR_LOG_UNIT_SIZE = 256;
+static constexpr size_t VENDOR_LOG_BLOCK_SIZE = 32;
+static constexpr size_t VENDOR_BLOCK_DATA_BYTES = 32;
+
+// TYPED_BLOCK_DATA
+static constexpr uint8_t VENDOR_DATA_TYPE = 0x04;
+static constexpr uint8_t VENDOR_DEFAULT = 0x00;
+static constexpr uint8_t FIRMWARE_IMAGE_DATA = 0x02;
+
+// Commands to OPERATIONAL_UNIT_OPS_CMD
+static constexpr uint8_t GET_OPERATIONAL_UNIT = 0x01;
+static constexpr uint8_t GENERATE_OPERATIONAL_UNIT_CKSUM = 0x08;
+
+static constexpr uint8_t MSBIT_SET_MASK = 0x80;
+static constexpr uint8_t MSBIT_CLR_MASK = 0x7F;
+static constexpr uint8_t OPERATION_SLEEP_SECONDS = 0x1;
+
+// Bit mask for checking the fw slot running
+static constexpr uint8_t RUNNING_FW_SLOT = 0xF0;
+
+// NOTE: If the ARM_MAX_RETRY_COUNT is greater than 1 then
+// previous error logs may be lost and not reported
+static constexpr size_t ARM_MAX_RETRY_COUNT = 1;
+static constexpr uint8_t FW_OPS_UPDATE = 0x04;
+
+// Secure erase verify operations
+static constexpr uint8_t ERASE_VERIFY_CLEAR = 0x00;
+static constexpr uint8_t ERASE_VERIFY_START = 0xC0;
+static constexpr uint8_t ERASE_VERIFY_TRIGGER = 0x80;
+
+#ifndef __HOSTBOOT_RUNTIME
+// Warning thresholds
+static constexpr uint8_t THRESHOLD_ES_LIFETIME = 0x07; // 7%
+static constexpr uint8_t THRESHOLD_NVM_LIFETIME = 0x31; // 49%
+
+// 12 bit fixed point temperature in celsius degrees
+// with following bit format:
+// [15:13]Reserved
+// [12]Sign 0 = positive, 1 = negative The value of 0 C should be expressed as a positive value
+// [11]128 [10]64 [9]32 [8]16 [7]8 [6]4 [5]2 [4]1 [3]0.5 [2]0.25
+// [1]0.125 Optional for temperature reporting fields; not used for temperature threshold fields
+// [0]0.0625 Optional for temperature reporting fields; not used for temperature threshold fields
+static constexpr uint8_t THRESHOLD_ES_TEMP_HIGH_1 = 0x03; // 52.5 C
+static constexpr uint8_t THRESHOLD_ES_TEMP_HIGH_0 = 0x48; // 52.5 C
+static constexpr uint8_t THRESHOLD_ES_TEMP_LOW_1 = 0x00; // 2.5 C
+static constexpr uint8_t THRESHOLD_ES_TEMP_LOW_0 = 0x28; // 2.5 C
+#endif
+
+// Definition of ENCRYPTION_KEY_VALIDATION -- page 5 offset 0x2A
+typedef union {
+ uint8_t whole;
+ struct
+ {
+ uint8_t reserved : 5; // [7:3]
+ uint8_t keys_validated : 1; // [2]
+ uint8_t access_key_valid : 1; // [1]
+ uint8_t erase_key_valid : 1; // [0]
+ } PACKED;
+} encryption_key_validation_t;
+
+/**
+ * @brief Utility function to send the value of
+ * ATTR_NVDIMM_ARMED to the FSP
+ */
+void send_ATTR_NVDIMM_ARMED( Target* i_nvdimm,
+ ATTR_NVDIMM_ARMED_type& i_val );
+
+/**
+ * @brief Utility function to set ATTR_NVDIMM_ENCRYPTION_KEYS_FW
+ * and send the value to the FSP
+ */
+void set_ATTR_NVDIMM_ENCRYPTION_KEYS_FW(
+ ATTR_NVDIMM_ENCRYPTION_KEYS_FW_typeStdArr& i_val )
+{
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "set_ATTR_NVDIMM_ENCRYPTION_KEYS_FW: no TopLevelTarget");
+
+ l_sys->setAttrFromStdArr
+ <ATTR_NVDIMM_ENCRYPTION_KEYS_FW>(i_val);
+
+#ifdef __HOSTBOOT_RUNTIME
+ errlHndl_t l_err = nullptr;
+
+ // Send attr to HWSV if at runtime
+ AttributeTank::Attribute l_attr = {};
+ if( !makeAttributeStdArr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>
+ (l_sys, l_attr) )
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"set_ATTR_NVDIMM_ENCRYPTION_KEYS_FW() Could not create Attribute");
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_CANNOT_MAKE_ATTRIBUTE
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid SET_ATTR_NVDIMM_ENCRYPTION_KEYS_FW
+ *@devdesc Couldn't create an Attribute to send the data
+ * to the FSP
+ *@custdesc NVDIMM encryption error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ SET_ATTR_NVDIMM_ENCRYPTION_KEYS_FW,
+ NVDIMM_CANNOT_MAKE_ATTRIBUTE,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ else
+ {
+ std::vector<TARGETING::AttributeTank::Attribute> l_attrList;
+ l_attrList.push_back(l_attr);
+ l_err = sendAttributes( l_attrList );
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"set_ATTR_NVDIMM_ENCRYPTION_KEYS_FW() Error sending ATTR_NVDIMM_ENCRYPTION_KEYS_FW down to FSP");
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ }
+#endif //__HOSTBOOT_RUNTIME
+
+}
+
/**
* @brief Wrapper to call deviceOp to read the NV controller via I2C
*
@@ -103,8 +278,8 @@ errlHndl_t nvdimmReadReg(Target* i_nvdimm,
uint8_t & o_data,
const bool page_verify)
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"NVDIMM Read HUID %X, addr 0x%X",
- TARGETING::get_huid(i_nvdimm), i_addr);
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"NVDIMM Read HUID 0x%X, addr 0x%X",
+ get_huid(i_nvdimm), i_addr);
errlHndl_t l_err = nullptr;
size_t l_numBytes = 1;
@@ -123,7 +298,7 @@ errlHndl_t nvdimmReadReg(Target* i_nvdimm,
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReadReg() nvdimm[%X] - failed to read the current page",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
break;
}
@@ -134,7 +309,7 @@ errlHndl_t nvdimmReadReg(Target* i_nvdimm,
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReadReg() nvdimm[%X] - failed to verify page",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
break;
}
}
@@ -144,11 +319,16 @@ errlHndl_t nvdimmReadReg(Target* i_nvdimm,
i_nvdimm,
&o_data,
l_numBytes,
- DEVICE_NVDIMM_ADDRESS(l_reg_addr));
+ DEVICE_NVDIMM_RAW_ADDRESS(l_reg_addr));
}while(0);
- TRACUCOMP(g_trac_nvdimm, EXIT_MRK"NVDIMM Read HUID %X, page 0x%X, addr 0x%X = %X",
- TARGETING::get_huid(i_nvdimm), l_reg_page, l_reg_addr, o_data);
+ if (l_err)
+ {
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+ }
+
+ TRACUCOMP(g_trac_nvdimm, EXIT_MRK"NVDIMM Read HUID 0x%X, page 0x%X, addr 0x%X = 0x%X",
+ get_huid(i_nvdimm), l_reg_page, l_reg_addr, o_data);
return l_err;
}
@@ -173,8 +353,8 @@ errlHndl_t nvdimmWriteReg(Target* i_nvdimm,
uint8_t i_data,
const bool page_verify)
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"NVDIMM Write HUID %X, addr 0x%X = %X",
- TARGETING::get_huid(i_nvdimm), i_addr, i_data);
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"NVDIMM Write HUID 0x%X, addr 0x%X = 0x%X",
+ get_huid(i_nvdimm), i_addr, i_data);
errlHndl_t l_err = nullptr;
size_t l_numBytes = 1;
@@ -193,7 +373,7 @@ errlHndl_t nvdimmWriteReg(Target* i_nvdimm,
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmWriteReg() nvdimm[%X] - failed to read the current page",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
break;
}
@@ -204,7 +384,7 @@ errlHndl_t nvdimmWriteReg(Target* i_nvdimm,
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmWriteReg() nvdimm[%X] - failed to verify page",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
break;
}
}
@@ -214,11 +394,16 @@ errlHndl_t nvdimmWriteReg(Target* i_nvdimm,
i_nvdimm,
&i_data,
l_numBytes,
- DEVICE_NVDIMM_ADDRESS(l_reg_addr));
+ DEVICE_NVDIMM_RAW_ADDRESS(l_reg_addr));
}while(0);
- TRACUCOMP(g_trac_nvdimm, EXIT_MRK"NVDIMM Write HUID %X, page = 0x%X, addr 0x%X = %X",
- TARGETING::get_huid(i_nvdimm), l_reg_page, l_reg_addr, i_data);
+ if (l_err)
+ {
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+ }
+
+ TRACUCOMP(g_trac_nvdimm, EXIT_MRK"NVDIMM Write HUID 0x%X, page = 0x%X, addr 0x%X = 0x%X",
+ get_huid(i_nvdimm), l_reg_page, l_reg_addr, i_data);
return l_err;
}
@@ -234,43 +419,48 @@ errlHndl_t nvdimmWriteReg(Target* i_nvdimm,
void nvdimmSetStatusFlag(Target *i_nvdimm, const uint8_t i_status_flag)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmSetStatusFlag() HUID[%X], i_status_flag[%X]"
- ,TARGETING::get_huid(i_nvdimm), i_status_flag);
+ ,get_huid(i_nvdimm), i_status_flag);
- auto l_statusFlag = i_nvdimm->getAttr<TARGETING::ATTR_NV_STATUS_FLAG>();
+ auto l_statusFlag = i_nvdimm->getAttr<ATTR_NV_STATUS_FLAG>();
switch(i_status_flag)
{
- // Make sure NSTD_VAL_PRSV (content preserved) is unset before setting NSTD_VAL_NOPRSV
- // (data not preserved) or NSTD_ERR_NOPRSV (error preserving data)
+ // Make sure NSTD_VAL_RESTORED (content preserved) is unset before setting NSTD_VAL_ERASED
+ // (data not preserved) or NSTD_VAL_SR_FAILED (error preserving data)
case NSTD_ERR:
- case NSTD_VAL_NOPRSV:
- case NSTD_ERR_NOPRSV:
- l_statusFlag &= NSTD_VAL_PRSV_MASK;
+ case NSTD_VAL_ERASED:
+ case NSTD_VAL_SR_FAILED:
+ l_statusFlag &= NSTD_VAL_RESTORED_MASK;
l_statusFlag |= i_status_flag;
break;
// If the content preserved(restore sucessfully), make sure
- // NSTD_VAL_NOPRSV (not preserved) and NSTD_ERR_NOPRSV (error preserving)
+ // NSTD_VAL_ERASED (not preserved) and NSTD_VAL_SR_FAILED (error preserving)
// are unset before setting this flag.
- case NSTD_VAL_PRSV:
- l_statusFlag &= (NSTD_VAL_NOPRSV_MASK & NSTD_ERR_NOPRSV_MASK);
+ case NSTD_VAL_RESTORED:
+ l_statusFlag &= (NSTD_VAL_ERASED_MASK & NSTD_VAL_SR_FAILED_MASK);
l_statusFlag |= i_status_flag;
break;
- case NSTD_ERR_NOBKUP:
+ case NSTD_VAL_DISARMED:
+ l_statusFlag |= i_status_flag;
+ break;
+
+ // Error detected but save/restore might work. May coexsit with other bits.
+ case NSTD_ERR_VAL_SR:
l_statusFlag |= i_status_flag;
break;
default:
assert(0, "nvdimmSetStatusFlag() HUID[%X], i_status_flag[%X] invalid flag!",
- TARGETING::get_huid(i_nvdimm), i_status_flag);
+ get_huid(i_nvdimm), i_status_flag);
break;
}
- i_nvdimm->setAttr<TARGETING::ATTR_NV_STATUS_FLAG>(l_statusFlag);
+ i_nvdimm->setAttr<ATTR_NV_STATUS_FLAG>(l_statusFlag);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmSetStatusFlag() HUID[%X], i_status_flag[%X]"
- ,TARGETING::get_huid(i_nvdimm), i_status_flag);
+ ,get_huid(i_nvdimm), i_status_flag);
}
@@ -284,10 +474,11 @@ void nvdimmSetStatusFlag(Target *i_nvdimm, const uint8_t i_status_flag)
*/
errlHndl_t nvdimmReady(Target *i_nvdimm)
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmReady() HUID[%X]",TARGETING::get_huid(i_nvdimm));
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmReady() HUID[%X]",get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
- uint8_t l_data = 0x0;
+ nvdimm_reg_t l_RegInfo;
+ uint8_t l_data;
uint8_t l_nvm_init_time = 0;
size_t l_numBytes = 1;
@@ -300,17 +491,17 @@ errlHndl_t nvdimmReady(Target *i_nvdimm)
DEVICE_SPD_ADDRESS(SPD::NVM_INIT_TIME));
TRACUCOMP(g_trac_nvdimm, "nvdimmReady() HUID[%X] l_nvm_init_time = %u",
- TARGETING::get_huid(i_nvdimm), l_nvm_init_time);
+ get_huid(i_nvdimm), l_nvm_init_time);
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReady() nvdimm[%X] - failed to retrieve NVM_INIT_TIME from SPD",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
break;
}
- // Convert to ms for polling
- uint32_t l_nvm_init_time_ms = l_nvm_init_time * MS_PER_SEC;
+ // Convert to ms for polling and double the value to avoid edge condition
+ uint32_t l_nvm_init_time_ms = l_nvm_init_time * MS_PER_SEC * 2;
uint32_t l_poll = 0;
do
@@ -320,7 +511,7 @@ errlHndl_t nvdimmReady(Target *i_nvdimm)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReady() nvdimm[%X] - error getting ready status[%d]",
- TARGETING::get_huid(i_nvdimm), l_data);
+ get_huid(i_nvdimm), l_data);
break;
}
@@ -336,8 +527,50 @@ errlHndl_t nvdimmReady(Target *i_nvdimm)
if ((l_data != NV_READY) && !l_err)
{
+
+ // Collect available status registers for error log
+ do
+ {
+ // Read and save NVDIMM_READY for traces
+ l_err = nvdimmReadReg(i_nvdimm, NVDIMM_READY, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ break;
+ }
+ l_RegInfo.NVDimm_Ready = l_data;
+
+ // Read and save MODULE_HEALTH for traces
+ l_err = nvdimmReadReg(i_nvdimm, MODULE_HEALTH, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ break;
+ }
+ l_RegInfo.Module_Health = l_data;
+
+ // Read and save MODULE_HEALTH_STATUS0 for traces
+ l_err = nvdimmReadReg(i_nvdimm, MODULE_HEALTH_STATUS0, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ break;
+ }
+ l_RegInfo.Module_Health_Status0 = l_data;
+
+ // Read and save MODULE_HEALTH_STATUS1 for traces
+ l_err = nvdimmReadReg(i_nvdimm, MODULE_HEALTH_STATUS1, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ break;
+ }
+ l_RegInfo.Module_Health_Status1 = l_data;
+
+ }while(0);
+
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReady() nvdimm[%X] - nvdimm not ready[%d]",
- TARGETING::get_huid(i_nvdimm), l_data);
+ get_huid(i_nvdimm), l_data);
/*@
*@errortype
*@reasoncode NVDIMM_NOT_READY
@@ -350,26 +583,33 @@ errlHndl_t nvdimmReady(Target *i_nvdimm)
* for host access. (userdata1 != 0xA5)
*@custdesc NVDIMM not ready
*/
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- NVDIMM_CHECK_READY,
- NVDIMM_NOT_READY,
- NVDIMM_SET_USER_DATA_1(l_data, TARGETING::get_huid(i_nvdimm)),
- 0x0,
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ NVDIMM_CHECK_READY,
+ NVDIMM_NOT_READY,
+ NVDIMM_SET_USER_DATA_1(l_data, get_huid(i_nvdimm)),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024 );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
// If nvdimm is not ready for access by now, this is
// a failing indication on the NV controller
- l_err->addPartCallout( i_nvdimm,
- HWAS::NV_CONTROLLER_PART_TYPE,
- HWAS::SRCI_PRIORITY_HIGH);
+ l_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DECONFIG,
+ HWAS::GARD_Fatal);
+
+ // Add Register Traces to error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err);
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+ nvdimmAddVendorLog(i_nvdimm, l_err);
}
}while(0);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmReady() HUID[%X] ready[%X]",
- TARGETING::get_huid(i_nvdimm), l_data);
+ get_huid(i_nvdimm), l_data);
return l_err;
}
@@ -386,7 +626,7 @@ errlHndl_t nvdimmReady(Target *i_nvdimm)
*/
errlHndl_t nvdimmResetController(Target *i_nvdimm)
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmResetController() HUID[%X]",TARGETING::get_huid(i_nvdimm));
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmResetController() HUID[%X]",get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
do
@@ -396,7 +636,7 @@ errlHndl_t nvdimmResetController(Target *i_nvdimm)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmResetController() nvdimm[%X] - error reseting the controller",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
break;
}
@@ -404,12 +644,17 @@ errlHndl_t nvdimmResetController(Target *i_nvdimm)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmResetController() nvdimm[%X] - not ready after reset.",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
}
}while(0);
- TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmResetController() HUID[%X]",TARGETING::get_huid(i_nvdimm));
+ // Reset will lock encryption so unlock again
+ TargetHandleList l_nvdimmTargetList;
+ l_nvdimmTargetList.push_back(i_nvdimm);
+ nvdimm_encrypt_unlock(l_nvdimmTargetList);
+
+ TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmResetController() HUID[%X]",get_huid(i_nvdimm));
return l_err;
}
@@ -436,8 +681,8 @@ errlHndl_t nvdimmPollStatus ( Target *i_nvdimm,
bool l_done = false;
// Get the timeout value for ops_id
- assert(i_nvdimm->tryGetAttr<TARGETING::ATTR_NV_OPS_TIMEOUT_MSEC>(l_target_timeout_values),
- "nvdimmPollStatus() HUID[%X], failed reading ATTR_NV_OPS_TIMEOUT_MSEC!", TARGETING::get_huid(i_nvdimm));
+ assert(i_nvdimm->tryGetAttr<ATTR_NV_OPS_TIMEOUT_MSEC>(l_target_timeout_values),
+ "nvdimmPollStatus() HUID[%X], failed reading ATTR_NV_OPS_TIMEOUT_MSEC!", get_huid(i_nvdimm));
uint32_t l_timeout = l_target_timeout_values[i_ops_id];
do
@@ -461,13 +706,13 @@ errlHndl_t nvdimmPollStatus ( Target *i_nvdimm,
o_poll += OPS_POLL_TIME_MS;
- } while (o_poll < l_timeout);
+ } while (o_poll <= l_timeout);
if (!l_done && !l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmPollStatus() nvdimm[%X] - Status timed out ops_id[%d]",
- TARGETING::get_huid(i_nvdimm), i_ops_id);
+ get_huid(i_nvdimm), i_ops_id);
/*@
*@errortype
*@reasoncode NVDIMM_STATUS_TIMEOUT
@@ -481,20 +726,17 @@ errlHndl_t nvdimmPollStatus ( Target *i_nvdimm,
* Refer to userdata1 for which operation it timed out.
*@custdesc NVDIMM timed out
*/
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
- NVDIMM_POLL_STATUS,
- NVDIMM_STATUS_TIMEOUT,
- NVDIMM_SET_USER_DATA_1(i_ops_id, TARGETING::get_huid(i_nvdimm)),
- NVDIMM_SET_USER_DATA_2_TIMEOUT(o_poll, l_timeout),
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
-
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024 );
-
- // May have to move the error handling to the caller
- // as different op could have different error severity
- l_err->addPartCallout( i_nvdimm,
- HWAS::NV_CONTROLLER_PART_TYPE,
- HWAS::SRCI_PRIORITY_HIGH);
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_POLL_STATUS,
+ NVDIMM_STATUS_TIMEOUT,
+ NVDIMM_SET_USER_DATA_1(i_ops_id, get_huid(i_nvdimm)),
+ NVDIMM_SET_USER_DATA_2_TIMEOUT(o_poll, l_timeout),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+ nvdimmAddVendorLog(i_nvdimm, l_err);
}
return l_err;
@@ -516,14 +758,46 @@ errlHndl_t nvdimmPollBackupDone(Target* i_nvdimm,
uint32_t &o_poll)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmPollBackupDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
+ nvdimm_reg_t l_RegInfo = nvdimm_reg_t();
l_err = nvdimmPollStatus ( i_nvdimm, SAVE, o_poll);
+ if (l_err)
+ {
+ errlCommit(l_err, NVDIMM_COMP_ID);
+
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_BACKUP_TIMEOUT
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_POLL_BACKUP
+ *@userdata1[0:31] Related ops (0xff = NA)
+ *@userdata1[32:63] Target Huid
+ *@devdesc Encountered timeout while performing NVDIMM Restore operation
+ *@custdesc NVDIMM timed out
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_POLL_BACKUP,
+ NVDIMM_BACKUP_TIMEOUT,
+ NVDIMM_SET_USER_DATA_1(SAVE, TARGETING::get_huid(i_nvdimm)),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+ nvdimmAddVendorLog(i_nvdimm, l_err);
+
+ // Collect register data for FFDC Traces
+ nvdimmTraceRegs ( i_nvdimm, l_RegInfo );
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err);
+ }
+
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmPollBackupDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
return l_err;
}
@@ -543,18 +817,57 @@ errlHndl_t nvdimmPollRestoreDone(Target* i_nvdimm,
uint32_t &o_poll)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmPollRestoreDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
+ nvdimm_reg_t l_RegInfo = nvdimm_reg_t();
l_err = nvdimmPollStatus ( i_nvdimm, RESTORE, o_poll );
+ if (l_err)
+ {
+ errlCommit(l_err, NVDIMM_COMP_ID);
+
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_RESTORE_TIMEOUT
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_POLL_RESTORE
+ *@userdata1[0:31] Related ops (0xff = NA)
+ *@userdata1[32:63] Target Huid
+ *@devdesc Encountered timeout while performing NVDIMM Restore operation
+ *@custdesc NVDIMM timed out
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_POLL_RESTORE,
+ NVDIMM_RESTORE_TIMEOUT,
+ NVDIMM_SET_USER_DATA_1(RESTORE, TARGETING::get_huid(i_nvdimm)),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+
+ // May have to move the error handling to the caller
+ // as different op could have different error severity
+ l_err->addPartCallout( i_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ // Collect register data for FFDC Traces
+ nvdimmTraceRegs ( i_nvdimm, l_RegInfo );
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+ nvdimmAddVendorLog(i_nvdimm, l_err);
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err);
+ }
+
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmPollRestoreDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
return l_err;
}
+
/**
* @brief This function polls the command status register for erase
* completion (does not indicate success or fail)
@@ -570,14 +883,39 @@ errlHndl_t nvdimmPollEraseDone(Target* i_nvdimm,
uint32_t &o_poll)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmPollEraseDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
- l_err = nvdimmPollStatus ( i_nvdimm, ERASE, o_poll);
+ l_err = nvdimmPollStatus( i_nvdimm, ERASE, o_poll);
+
+ if (l_err)
+ {
+ errlCommit(l_err, NVDIMM_COMP_ID);
+
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ERASE_TIMEOUT
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_POLL_ERASE
+ *@userdata1[0:31] Related ops (0xff = NA)
+ *@userdata1[32:63] Target Huid
+ *@devdesc Encountered timeout while performing NVDIMM Restore operation
+ *@custdesc NVDIMM timed out
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_POLL_ERASE,
+ NVDIMM_ERASE_TIMEOUT,
+ NVDIMM_SET_USER_DATA_1(ERASE, TARGETING::get_huid(i_nvdimm)),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+ nvdimmAddVendorLog(i_nvdimm, l_err);
+ }
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmPollEraseDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
return l_err;
}
@@ -598,14 +936,18 @@ errlHndl_t nvdimmPollESChargeStatus(Target* i_nvdimm,
uint32_t &o_poll)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmPollESChargeDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
- l_err = nvdimmPollStatus ( i_nvdimm, CHARGE, o_poll );
+ l_err = nvdimmPollStatus( i_nvdimm, CHARGE, o_poll );
+
+ l_err->addPartCallout( i_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmPollESChargeDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
return l_err;
}
@@ -623,7 +965,7 @@ errlHndl_t nvdimmPollESChargeStatus(Target* i_nvdimm,
errlHndl_t nvdimmGetRestoreValid(Target* i_nvdimm, uint8_t & o_rstrValid)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmGetRestoreValid() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
@@ -631,11 +973,11 @@ errlHndl_t nvdimmGetRestoreValid(Target* i_nvdimm, uint8_t & o_rstrValid)
if (l_err){
TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X], Error getting restore status!",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
}
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmGetRestoreValid() nvdimm[%X], restore_status[%x],",
- TARGETING::get_huid(i_nvdimm), o_rstrValid);
+ get_huid(i_nvdimm), o_rstrValid);
return l_err;
}
@@ -651,10 +993,11 @@ errlHndl_t nvdimmGetRestoreValid(Target* i_nvdimm, uint8_t & o_rstrValid)
errlHndl_t nvdimmSetESPolicy(Target* i_nvdimm)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmSetESPolicy() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
- uint8_t l_data;
+ uint8_t l_data = 0x0;
+ nvdimm_reg_t l_RegInfo = nvdimm_reg_t();
do
{
@@ -663,9 +1006,9 @@ errlHndl_t nvdimmSetESPolicy(Target* i_nvdimm)
if (l_err)
{
- nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_NOBKUP);
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_VAL_DISARMED);
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmSetESPolicy() nvdimm[%X]"
- "failed to write ES register!",TARGETING::get_huid(i_nvdimm));
+ "failed to write ES register!",get_huid(i_nvdimm));
break;
}
@@ -677,16 +1020,16 @@ errlHndl_t nvdimmSetESPolicy(Target* i_nvdimm)
if (l_err)
{
- nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_NOBKUP);
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_VAL_DISARMED);
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmSetESPolicy() nvdimm[%X]"
- "failed to read ES register!",TARGETING::get_huid(i_nvdimm));
+ "failed to read ES register!",get_huid(i_nvdimm));
break;
}
- if ((l_data & ES_SUCCESS) != ES_SUCCESS)
+ if (((l_data & ES_SUCCESS) != ES_SUCCESS) || ((l_data & ES_POLICY_ERROR) == ES_POLICY_ERROR))
{
TRACFCOMP(g_trac_nvdimm, EXIT_MRK"NDVIMM HUID[%X], nvdimmSetESPolicy() "
- "failed!",TARGETING::get_huid(i_nvdimm));
+ "failed!",get_huid(i_nvdimm));
/*@
*@errortype
*@reasoncode NVDIMM_SET_ES_ERROR
@@ -700,28 +1043,28 @@ errlHndl_t nvdimmSetESPolicy(Target* i_nvdimm)
* NVDIMM is intact
*@custdesc NVDIMM encountered error setting the energy source policy
*/
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
- NVDIMM_SET_ES,
- NVDIMM_SET_ES_ERROR,
- NVDIMM_SET_USER_DATA_1(CHARGE, TARGETING::get_huid(i_nvdimm)),
- 0x0,
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
-
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024 );
-
- // Failure setting the energy source policy could mean error on the
- // battery or even the cabling
- l_err->addPartCallout( i_nvdimm,
- HWAS::BPM_PART_TYPE,
- HWAS::SRCI_PRIORITY_HIGH);
- l_err->addPartCallout( i_nvdimm,
- HWAS::BPM_CABLE_PART_TYPE,
- HWAS::SRCI_PRIORITY_HIGH);
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_SET_ES,
+ NVDIMM_SET_ES_ERROR,
+ NVDIMM_SET_USER_DATA_1(CHARGE, get_huid(i_nvdimm)),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+
+ // Read relevant regs for trace data
+ nvdimmTraceRegs(i_nvdimm, l_RegInfo);
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+ nvdimmAddVendorLog(i_nvdimm, l_err);
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err);
}
}while(0);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"NDVIMM HUID[%X], nvdimmSetESPolicy(),"
- ,TARGETING::get_huid(i_nvdimm));
+ ,get_huid(i_nvdimm));
return l_err;
}
@@ -739,7 +1082,7 @@ errlHndl_t nvdimmSetESPolicy(Target* i_nvdimm)
errlHndl_t nvdimmChangeArmState(Target *i_nvdimm, bool i_state)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmChangeArmState() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
@@ -753,11 +1096,11 @@ errlHndl_t nvdimmChangeArmState(Target *i_nvdimm, bool i_state)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmChangeArmState() nvdimm[%X] error %s nvdimm!!",
- TARGETING::get_huid(i_nvdimm), i_state? "arming" : "disarming");
+ get_huid(i_nvdimm), i_state? "arming" : "disarming");
}
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmChangeArmState() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
return l_err;
}
@@ -774,7 +1117,7 @@ errlHndl_t nvdimmChangeArmState(Target *i_nvdimm, bool i_state)
errlHndl_t nvdimmValidImage(Target *i_nvdimm, bool &o_imgValid)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmValidImage(): nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
uint8_t l_data = 0x0;
@@ -785,7 +1128,7 @@ errlHndl_t nvdimmValidImage(Target *i_nvdimm, bool &o_imgValid)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmValidImage() nvdimm[%X]"
- "failed to for image!",TARGETING::get_huid(i_nvdimm) );
+ "failed to for image!",get_huid(i_nvdimm) );
}
else if(l_data & VALID_IMAGE)
{
@@ -793,55 +1136,70 @@ errlHndl_t nvdimmValidImage(Target *i_nvdimm, bool &o_imgValid)
}
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmValidImage(): nvdimm[%X] ret[%X]",
- TARGETING::get_huid(i_nvdimm), l_data);
+ get_huid(i_nvdimm), l_data);
return l_err;
}
+void maskMbacalfir_eventn(TARGETING::Target* i_nvdimm)
+{
+ errlHndl_t l_err = nullptr;
+ TargetHandleList l_mcaList;
+ uint64_t l_writeData;
+ uint32_t l_writeAddress;
+ size_t l_writeSize = sizeof(l_writeData);
+
+ getParentAffinityTargets(l_mcaList, i_nvdimm, CLASS_UNIT, TYPE_MCA);
+ assert(l_mcaList.size(), "maskMbacalfir_eventn() failed to find parent MCA.");
+
+ l_writeAddress = MBACALFIR_OR_MASK_REG;
+ l_writeData = MBACALFIR_EVENTN_OR_BIT;
+ l_err = deviceWrite(l_mcaList[0], &l_writeData, l_writeSize,
+ DEVICE_SCOM_ADDRESS(l_writeAddress));
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm,
+ ERR_MRK "Failed to mask MBACALFIR EventN using address "
+ "0x%08x on NVDIMM 0x%08X MCA 0x%08X",
+ l_writeAddress, get_huid(i_nvdimm), get_huid(l_mcaList[0]));
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+}
+
#ifndef __HOSTBOOT_RUNTIME
/**
* @brief This function handles all the restore related operations.
* SRE -> restore -> SRX/RCD/MRS
*
- * @param[in] i_nvdimmList - list of nvdimms
+ * @param[in,out] io_nvdimmList - list of nvdimms. Each nvdimm is removed
+ * from the list after a successful restore. Leftover nvdimm
+ * is returned to the caller for error handling.
*
* @param[in] i_mpipl - MPIPL mode
*
* @return errlHndl_t - Null if successful, otherwise a pointer to
* the error log.
*/
-errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
+errlHndl_t nvdimmRestore(TargetHandleList& io_nvdimmList, uint8_t &i_mpipl)
{
errlHndl_t l_err = nullptr;
- bool l_imgValid;
uint8_t l_rstrValid;
uint32_t l_poll = 0;
+ TargetHandleList l_nvdimmList = io_nvdimmList;
do
{
// Put NVDIMM into self-refresh
- for (TargetHandleList::iterator it = i_nvdimmList.begin();
- it != i_nvdimmList.end();)
+ for (TargetHandleList::iterator it = io_nvdimmList.begin();
+ it != io_nvdimmList.end();)
{
- l_err = nvdimmValidImage(*it, l_imgValid);
- // No reason to run if we can't figure out
- // if there is an image or not
- if (l_err)
- {
- nvdimmSetStatusFlag(*it, NSTD_ERR_NOPRSV);
- break;
- }
+ // Default state during boot is unarmed, therefore not preserved
+ nvdimmSetStatusFlag(*it, NSTD_VAL_DISARMED);
- if (!l_imgValid)
- {
- nvdimmSetStatusFlag(*it, NSTD_VAL_NOPRSV);
- i_nvdimmList.erase(it);
- continue;
- }
-
- TARGETING::TargetHandleList l_mcaList;
- getParentAffinityTargets(l_mcaList, *it, TARGETING::CLASS_UNIT, TARGETING::TYPE_MCA);
+ TargetHandleList l_mcaList;
+ getParentAffinityTargets(l_mcaList, *it, CLASS_UNIT, TYPE_MCA);
assert(l_mcaList.size(), "nvdimmRestore() failed to find parent MCA.");
fapi2::Target<fapi2::TARGET_TYPE_MCA> l_fapi_mca(l_mcaList[0]);
@@ -850,21 +1208,40 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
// is de-asserted before kicking off the restore
if (i_mpipl)
{
+ TRACFCOMP(g_trac_nvdimm, "nvdimmRestore(): in MPIPL");
+
+ // To avoid PRD error during mpipl need to Mask MBACALFIR EventN
+ // Note: a regular IPL will already have this masked
+ maskMbacalfir_eventn(*it);
+
+ // Call init for error checking skipped in the SAVE step
+ nvdimm_init(*it);
+
FAPI_INVOKE_HWP(l_err, mss::ddr_resetn, l_fapi_mca, HIGH);
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmRestore() HUID[%X] i_mpipl[%u] failed to de-assert resetn!",
- TARGETING::get_huid(*it), i_mpipl);
-
- nvdimmSetStatusFlag(*it, NSTD_ERR_NOPRSV);
- //@TODO RTC 199645 - add HW callout on dimm target
- // If we failed to de-assert reset_n, the dimm is pretty much useless.
- // Let's not restore if that happens
- // The callout will be added inside the HWP
- // Leaving this comment here as a reminder, will remove later
+ get_huid(*it), i_mpipl);
break;
}
+
+ // In MPIPL, invalidate the BAR to prevent any traffic from stepping on
+ // the restore
+ FAPI_INVOKE_HWP(l_err, mss::nvdimm::change_bar_valid_state, l_fapi_mca, LOW);
+
+ // This should not fail at all (scom read/write). If it does, post an informational log
+ // to leave some breadcrumbs
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmRestore() HUID[%X] i_mpipl[%u] failed to invalidate BAR!",
+ get_huid(*it), i_mpipl);
+
+ l_err->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+ ERRORLOG::errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+
}
// Self-refresh is done at the port level
@@ -873,13 +1250,7 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmRestore() HUID[%X] self_refresh_entry failed!",
- TARGETING::get_huid(*it));
-
- nvdimmSetStatusFlag(*it, NSTD_ERR_NOPRSV);
- //@TODO RTC 199645 - add HW callout on dimm target
- // Without SRE the data could be not reliably restored
- // The callout will be added inside the HWP
- // Leaving this comment here as a reminder, will remove later
+ get_huid(*it));
break;
}
it++;
@@ -890,21 +1261,14 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
break;
}
- // Nothing to do. Move on.
- if (i_nvdimmList.empty())
- {
- break;
- }
-
// Kick off the restore on each nvdimm in the nvdimm list
- for (const auto & l_nvdimm : i_nvdimmList)
+ for (const auto & l_nvdimm : io_nvdimmList)
{
l_err = nvdimmWriteReg(l_nvdimm, NVDIMM_FUNC_CMD, RESTORE_IMAGE);
if (l_err)
{
- nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOPRSV);
TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X], error initiating restore!!",
- TARGETING::get_huid(l_nvdimm));
+ get_huid(l_nvdimm));
break;
}
}
@@ -915,7 +1279,7 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
}
// Make sure the restore completed
- for (const auto & l_nvdimm : i_nvdimmList)
+ for (const auto & l_nvdimm : io_nvdimmList)
{
// Since we kicked off the restore on all the modules at once, the restore
// should complete on all of the modules in one restore window. Use the
@@ -923,10 +1287,8 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
l_err = nvdimmPollRestoreDone(l_nvdimm, l_poll);
if (l_err)
{
- nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOPRSV);
TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X], error restoring!",
- TARGETING::get_huid(l_nvdimm));
- errlCommit(l_err, NVDIMM_COMP_ID);
+ get_huid(l_nvdimm));
break;
}
}
@@ -936,22 +1298,23 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
break;
}
- // Make sure the restore is valid
- for (const auto & l_nvdimm : i_nvdimmList)
+ // Check for restore errors
+ for (TargetHandleList::iterator it = io_nvdimmList.begin();
+ it != io_nvdimmList.end();)
{
- l_err = nvdimmGetRestoreValid(l_nvdimm, l_rstrValid);
+ l_err = nvdimmGetRestoreValid(*it, l_rstrValid);
if (l_err)
{
- nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOPRSV);
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmRestore Target[%X] error validating restore status!",
- TARGETING::get_huid(l_nvdimm));
+ get_huid(*it));
break;
}
- if ((l_rstrValid & RSTR_SUCCESS) != RSTR_SUCCESS){
+ if ((l_rstrValid & RSTR_ERROR) == RSTR_ERROR)
+ {
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X] restoreValid[%d], restore failed!",
- TARGETING::get_huid(l_nvdimm), l_rstrValid);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X] restore failed due to errors",
+ get_huid(*it));
/*@
*@errortype
*@reasoncode NVDIMM_RESTORE_FAILED
@@ -964,36 +1327,21 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
* restore timeout (Controller error)
*@custdesc NVDIMM failed to restore data
*/
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- NVDIMM_RESTORE,
- NVDIMM_RESTORE_FAILED,
- TARGETING::get_huid(l_nvdimm),
- 0x0,
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT);
-
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024 );
- nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOPRSV);
-
- // Invalid restore could be due to dram not in self-refresh
- // or controller issue. Data should not be trusted at this point
- l_err->addPartCallout( l_nvdimm,
- HWAS::NV_CONTROLLER_PART_TYPE,
- HWAS::SRCI_PRIORITY_HIGH);
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ NVDIMM_RESTORE,
+ NVDIMM_RESTORE_FAILED,
+ get_huid(*it),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT);
+ nvdimmAddPage4Regs(*it,l_err);
+ nvdimmAddVendorLog(*it, l_err);
break;
}
- }
-
- if (l_err)
- {
- break;
- }
- // Exit self-refresh
- for (const auto & l_nvdimm : i_nvdimmList)
- {
-
- TARGETING::TargetHandleList l_mcaList;
- getParentAffinityTargets(l_mcaList, l_nvdimm, TARGETING::CLASS_UNIT, TARGETING::TYPE_MCA);
+ // Exit self-refresh
+ TargetHandleList l_mcaList;
+ getParentAffinityTargets(l_mcaList, *it, CLASS_UNIT, TYPE_MCA);
assert(l_mcaList.size(), "nvdimmRestore() failed to find parent MCA.");
fapi2::Target<fapi2::TARGET_TYPE_MCA> l_fapi_mca(l_mcaList[0]);
@@ -1005,16 +1353,48 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmRestore() HUID[%X] post_restore_transition failed!",
- TARGETING::get_huid(l_nvdimm));
-
- // Commit the error from the HWP
- nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOPRSV);
+ get_huid(*it));
+ nvdimmAddPage4Regs(*it,l_err);
break;
}
else
{
// Restore success!
- nvdimmSetStatusFlag(l_nvdimm, NSTD_VAL_PRSV);
+ // Remove dimm from list for error handling
+ it = io_nvdimmList.erase(it);
+ }
+ }
+
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimmRestore() HUID[%X] encounrterd an error during restore");
+ break;
+ }
+
+ if (i_mpipl)
+ {
+ for (const auto & l_nvdimm : l_nvdimmList)
+ {
+ TargetHandleList l_mcaList;
+ errlHndl_t err = nullptr;
+ getParentAffinityTargets(l_mcaList, l_nvdimm, CLASS_UNIT, TYPE_MCA);
+ assert(l_mcaList.size(), "nvdimmRestore() failed to find parent MCA.");
+
+ // Re-validate the BAR after restore
+ fapi2::Target<fapi2::TARGET_TYPE_MCA> l_fapi_mca(l_mcaList[0]);
+ FAPI_INVOKE_HWP(err, mss::nvdimm::change_bar_valid_state, l_fapi_mca, HIGH);
+
+ // This should not fail at all (scom read/write). If it does, post an informational log
+ // to leave some breadcrumbs
+ if (err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmRestore() HUID[%X] i_mpipl[%u] failed to invalidate BAR!",
+ get_huid(l_nvdimm), i_mpipl);
+
+ err->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ err->collectTrace( NVDIMM_COMP_NAME );
+ ERRORLOG::errlCommit(err, NVDIMM_COMP_ID);
+ }
}
}
@@ -1027,66 +1407,124 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
#endif
/**
- * @brief This function checks the erase status register to make sure
- * the last erase completed witout error
+ * @brief This function checks the status and success of an erase
*
* @param[in] i_nvdimm - nvdimm target with NV controller
+ * @param[in] i_statusOnly - check just the status register (not the image)
*
* @return errlHndl_t - Null if successful, otherwise a pointer to
* the error log.
*/
-errlHndl_t nvdimmCheckEraseSuccess(Target *i_nvdimm)
+errlHndl_t nvdimmEraseCheck(Target *i_nvdimm, bool i_statusOnly)
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmCheckEraseSuccess() : nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
-
- uint8_t l_data = 0;
errlHndl_t l_err = nullptr;
+ nvdimm_reg_t l_RegInfo;
+ uint8_t l_data = 0;
+ bool l_valid = false;
- l_err = nvdimmReadReg(i_nvdimm, ERASE_STATUS, l_data);
+ // Erase happens one module at a time. No need to set any offset on the counter
+ uint32_t l_poll = 0;
+ l_err = nvdimmPollEraseDone(i_nvdimm, l_poll);
+ // Add part callout, currently all erase calls have same callout
+ // Dump traces to the error log if error exists
if (l_err)
{
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmCheckEraseSuccess() nvdimm[%X]"
- "failed to read erase status reg!",TARGETING::get_huid(i_nvdimm));
+ // For both Erase timeout and Erase fail
+ // Callout nvdimm on high, gard and deconfig
+ l_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DECONFIG,
+ HWAS::GARD_Fatal);
+
+ // Collect register data for FFDC Traces
+ nvdimmTraceRegs ( i_nvdimm, l_RegInfo );
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err);
}
- else if ((l_data & ERASE_SUCCESS) != ERASE_SUCCESS)
+ else
{
+ do
+ {
+ // Read Erase Status register
+ l_err = nvdimmReadReg ( i_nvdimm, ERASE_STATUS, l_data);
+ if (l_err)
+ {
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_VAL_DISARMED);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm[%X], failed to read erase status",
+ get_huid(i_nvdimm));
+ break;
+ }
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmCheckEraseSuccess() nvdimm[%X]"
- "failed to erase!",TARGETING::get_huid(i_nvdimm));
- /*@
- *@errortype
- *@reasoncode NVDIMM_ERASE_FAILED
- *@severity ERRORLOG_SEV_PREDICTIVE
- *@moduleid NVDIMM_CHECK_ERASE
- *@userdata1[0:31] Related ops (0xff = NA)
- *@userdata1[32:63] Target Huid
- *@userdata2 <UNUSED>
- *@devdesc Encountered error erasing previously stored data image
- * on NVDIMM. Likely due to timeout and/or controller error
- *@custdesc NVDIMM error erasing data image
- */
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
- NVDIMM_CHECK_ERASE,
- NVDIMM_ERASE_FAILED,
- NVDIMM_SET_USER_DATA_1(ERASE, TARGETING::get_huid(i_nvdimm)),
- 0x0,
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ if (i_statusOnly)
+ {
+ // assume image is cleared, do not check
+ TRACFCOMP(g_trac_nvdimm, "nvdimmEraseCheck() - skipping image check for nvdimm[%X]",
+ get_huid(i_nvdimm));
+ l_valid = false;
+ }
+ else
+ {
+ // Check for a valid image
+ l_err = nvdimmValidImage( i_nvdimm, l_valid );
+ if (l_err)
+ {
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_VAL_DISARMED);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm[%X] Failed to detect valid image",
+ get_huid(i_nvdimm));
+ break;
+ }
+ }
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024 );
- errlCommit( l_err, NVDIMM_COMP_ID );
+ if ( (l_data & ERASE_ERROR) || l_valid )
+ {
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_VAL_DISARMED);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm[%X] NVDimm Erase failed due to error (ERASE_STATUS: 0x%02X, Image %s)",
+ get_huid(i_nvdimm), l_data, l_valid?"not erased":"erased");
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ERASE_ERROR
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_CHECK_ERASE
+ *@userdata1[0:31] ERASE_STATUS register
+ *@userdata1[32:63] Target Huid
+ *@userdata2 ERASE_ERROR status bit
+ *@userdata2 Image validity
+ *@devdesc Encountered error during image erase function
+ * on NVDIMM. Check error register trace for details
+ *@custdesc NVDIMM error during nvdimm erase
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_CHECK_ERASE,
+ NVDIMM_ERASE_ERROR,
+ NVDIMM_SET_USER_DATA_1(l_data, get_huid(i_nvdimm)),
+ NVDIMM_SET_USER_DATA_1(ERASE_ERROR, l_valid),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+ break;
+ }
- // Failure to erase could mean internal NV controller error and/or
- // HW error on nand flash. NVDIMM will lose persistency if failed to
- // erase nand flash
- l_err->addPartCallout( i_nvdimm,
- HWAS::NV_CONTROLLER_PART_TYPE,
- HWAS::SRCI_PRIORITY_HIGH);
- }
+ } while(0);
- TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmCheckEraseSuccess(): nvdimm[%X] ret[%X]",
- TARGETING::get_huid(i_nvdimm), l_data);
+ if(l_err)
+ {
+ // Callout nvdimm on high, gard and deconfig
+ l_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DECONFIG,
+ HWAS::GARD_Fatal);
+
+ // Collect register data for FFDC Traces
+ nvdimmTraceRegs ( i_nvdimm, l_RegInfo );
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err);
+ }
+ }
return l_err;
}
@@ -1102,7 +1540,7 @@ errlHndl_t nvdimmCheckEraseSuccess(Target *i_nvdimm)
errlHndl_t nvdimmEraseNF(Target *i_nvdimm)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmEraseNF() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
@@ -1112,22 +1550,17 @@ errlHndl_t nvdimmEraseNF(Target *i_nvdimm)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X] error initiating erase!!",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
break;
}
- // Erase happens one module at a time. No need to set any offset on the counter
- uint32_t l_poll = 0;
- l_err = nvdimmPollEraseDone(i_nvdimm, l_poll);
- if (!l_err)
- {
- l_err = nvdimmCheckEraseSuccess(i_nvdimm);
- }
+ // Poll for success, then check the status and image
+ l_err = nvdimmEraseCheck(i_nvdimm, false);
}while(0);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmEraseNF() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
return l_err;
}
@@ -1146,15 +1579,15 @@ errlHndl_t nvdimmEraseNF(Target *i_nvdimm)
errlHndl_t nvdimmOpenPage(Target *i_nvdimm,
uint8_t i_page)
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmOpenPage nvdimm[%X]", TARGETING::get_huid(i_nvdimm));
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmOpenPage nvdimm[%X]", get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
bool l_success = false;
uint8_t l_data;
uint32_t l_poll = 0;
uint32_t l_target_timeout_values[6];
- assert(i_nvdimm->tryGetAttr<TARGETING::ATTR_NV_OPS_TIMEOUT_MSEC>(l_target_timeout_values),
- "nvdimmOpenPage() HUID[%X], failed reading ATTR_NV_OPS_TIMEOUT_MSEC!", TARGETING::get_huid(i_nvdimm));
+ assert(i_nvdimm->tryGetAttr<ATTR_NV_OPS_TIMEOUT_MSEC>(l_target_timeout_values),
+ "nvdimmOpenPage() HUID[%X], failed reading ATTR_NV_OPS_TIMEOUT_MSEC!", get_huid(i_nvdimm));
uint32_t l_timeout = l_target_timeout_values[PAGE_SWITCH];
@@ -1167,7 +1600,7 @@ errlHndl_t nvdimmOpenPage(Target *i_nvdimm,
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmOpenPage nvdimm[%X]"
- "error writing to page change reg", TARGETING::get_huid(i_nvdimm));
+ "error writing to page change reg", get_huid(i_nvdimm));
break;
}
@@ -1200,7 +1633,7 @@ errlHndl_t nvdimmOpenPage(Target *i_nvdimm,
if (!l_success && !l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmOpenPage nvdimm[%X] openpage_success[%d],"
- "failure to open page!", TARGETING::get_huid(i_nvdimm), static_cast<uint8_t>(l_success));
+ "failure to open page!", get_huid(i_nvdimm), static_cast<uint8_t>(l_success));
/*@
*@errortype
@@ -1215,25 +1648,28 @@ errlHndl_t nvdimmOpenPage(Target *i_nvdimm,
*@custdesc Encountered error performing internal operaiton
* on NVDIMM
*/
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- NVDIMM_POLL_STATUS,
- NVDIMM_STATUS_TIMEOUT,
- NVDIMM_SET_USER_DATA_1(PAGE_SWITCH, TARGETING::get_huid(i_nvdimm)),
- NVDIMM_SET_USER_DATA_2_TIMEOUT(l_poll, l_timeout),
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ NVDIMM_OPEN_PAGE,
+ NVDIMM_OPEN_PAGE_TIMEOUT,
+ NVDIMM_SET_USER_DATA_1(PAGE_SWITCH, get_huid(i_nvdimm)),
+ NVDIMM_SET_USER_DATA_2_TIMEOUT(l_poll, l_timeout),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
l_err->collectTrace(NVDIMM_COMP_NAME, 256 );
+ nvdimmAddVendorLog(i_nvdimm, l_err);
// Failure to open page most likely means problem with
// the NV controller.
l_err->addPartCallout( i_nvdimm,
HWAS::NV_CONTROLLER_PART_TYPE,
HWAS::SRCI_PRIORITY_HIGH);
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
}
}while(0);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmOpenPage nvdimm[%X] nvdimmOpenPage.success[%d],"
- ,TARGETING::get_huid(i_nvdimm), static_cast<uint8_t>(l_success));
+ ,get_huid(i_nvdimm), static_cast<uint8_t>(l_success));
return l_err;
}
@@ -1250,12 +1686,12 @@ errlHndl_t nvdimmOpenPage(Target *i_nvdimm,
errlHndl_t nvdimmGetTimeoutVal(Target* i_nvdimm)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmGetTimeoutVal() HUID[%X]"
- ,TARGETING::get_huid(i_nvdimm));
+ ,get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
uint8_t l_data = 0;
uint32_t timeout_map[6];
- i_nvdimm->tryGetAttr<TARGETING::ATTR_NV_OPS_TIMEOUT_MSEC>(timeout_map);
+ i_nvdimm->tryGetAttr<ATTR_NV_OPS_TIMEOUT_MSEC>(timeout_map);
//Get the 6 main timeout values
for (uint8_t i = SAVE; i <= CHARGE; i++)
@@ -1282,28 +1718,33 @@ errlHndl_t nvdimmGetTimeoutVal(Target* i_nvdimm)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmGetTimeoutVal() HUID[%X] "
- "error reading timeout value for op[%d]!", TARGETING::get_huid(i_nvdimm), i);
+ "error reading timeout value for op[%d]!", get_huid(i_nvdimm), i);
break;
}
//Converting to msec depending on bit 15. 1 = sec, 0 = msec
//except for charge. Charge is only in seconds so convert anyway
+ //Double the timeout values for margins
if (timeout_map[i] >= 0x8000 || i == CHARGE){
timeout_map[i] = timeout_map[i] & 0x7FFF;
- timeout_map[i] = timeout_map[i] * MS_PER_SEC;
+ timeout_map[i] = timeout_map[i] * MS_PER_SEC * 2;
+ }
+ else
+ {
+ timeout_map[i] = timeout_map[i] * 2;
}
TRACUCOMP(g_trac_nvdimm, "nvdimmGetTimeoutVal() HUID[%X], timeout_idx[%d], timeout_ms[%d]"
- ,TARGETING::get_huid(i_nvdimm), timeoutInfoTable[i].idx, timeout_map[i]);
+ ,get_huid(i_nvdimm), timeoutInfoTable[i].idx, timeout_map[i]);
}
if (!l_err)
{
- i_nvdimm->setAttr<TARGETING::ATTR_NV_OPS_TIMEOUT_MSEC>(timeout_map);
+ i_nvdimm->setAttr<ATTR_NV_OPS_TIMEOUT_MSEC>(timeout_map);
}
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmGetTimeoutVal() HUID[%X]"
- ,TARGETING::get_huid(i_nvdimm));
+ ,get_huid(i_nvdimm));
return l_err;
}
@@ -1327,8 +1768,8 @@ errlHndl_t nvdimmEpowSetup(TargetHandleList &i_nvdimmList)
for (TargetHandleList::iterator it = i_nvdimmList.begin();
it != i_nvdimmList.end();)
{
- TARGETING::TargetHandleList l_mcaList;
- getParentAffinityTargets(l_mcaList, *it, TARGETING::CLASS_UNIT, TARGETING::TYPE_MCA);
+ TargetHandleList l_mcaList;
+ getParentAffinityTargets(l_mcaList, *it, CLASS_UNIT, TYPE_MCA);
assert(l_mcaList.size(), "nvdimmEpowSetup() failed to find parent MCA.");
fapi2::Target<fapi2::TARGET_TYPE_MCA> l_fapi_mca(l_mcaList[0]);
@@ -1340,9 +1781,10 @@ errlHndl_t nvdimmEpowSetup(TargetHandleList &i_nvdimmList)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmEpowSetup() HUID[%X] failed to setup epow!",
- TARGETING::get_huid(*it));
+ get_huid(*it));
- nvdimmSetStatusFlag(*it, NSTD_ERR_NOPRSV);
+ nvdimmSetStatusFlag(*it, NSTD_VAL_SR_FAILED);
+ nvdimmAddPage4Regs(*it,l_err);
break;
}
it++;
@@ -1354,6 +1796,7 @@ errlHndl_t nvdimmEpowSetup(TargetHandleList &i_nvdimmList)
return l_err;
}
+
/**
* @brief Entry function to NVDIMM restore
* - Restore image from NVDIMM NAND flash to DRAM
@@ -1365,31 +1808,21 @@ errlHndl_t nvdimmEpowSetup(TargetHandleList &i_nvdimmList)
void nvdimm_restore(TargetHandleList &i_nvdimmList)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_restore()");
+
errlHndl_t l_err = nullptr;
+ bool l_valid = false;
+ bool l_continue = true;
TARGETING::Target* l_sys = nullptr;
TARGETING::targetService().getTopLevelTarget( l_sys );
assert(l_sys, "nvdimm_restore: no TopLevelTarget");
uint8_t l_mpipl = l_sys->getAttr<ATTR_IS_MPIPL_HB>();
+ nvdimm_reg_t l_RegInfo = nvdimm_reg_t();
+ TargetHandleList l_nvdimm_restore_list = i_nvdimmList;
+ uint8_t l_rstrValid;
do
{
- // Set the energy policy to device-managed
- // Don't think this is needed for the supercaps to start charging
- // but do it anyway to get the charging going
- for (const auto & l_nvdimm : i_nvdimmList)
- {
- l_err = nvdimmSetESPolicy(l_nvdimm);
- if (l_err)
- {
- // Failing this is an indication of power pack issue.
- // This will prevent future backup, but let's continue
- // since we can still restore the data if there is any
- nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_restore() - Failing nvdimmSetESPolicy()");
- errlCommit( l_err, NVDIMM_COMP_ID );
- }
- }
-
+ // Check MPIPL case first to make sure any on-going backup is complete
if (l_mpipl)
{
// During MPIPL, make sure any in-progress save is completed before proceeding
@@ -1401,41 +1834,118 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
if (l_err)
{
- nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOPRSV);
+ nvdimmSetStatusFlag(l_nvdimm, NSTD_VAL_ERASED);
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_restore() nvdimm[%X], error backing up the DRAM!",
- TARGETING::get_huid(l_nvdimm));
+ get_huid(l_nvdimm));
errlCommit(l_err, NVDIMM_COMP_ID);
break;
}
}
}
+ // Compile a list of nvdimms with valid image
+ // TODO: Reach out to RAS on how to handle odd number of nvdimms
+ // since we always operate in pairs
+ for (TargetHandleList::iterator it = l_nvdimm_restore_list.begin();
+ it != l_nvdimm_restore_list.end();)
+ {
+ // Check for a valid image
+ l_err = nvdimmValidImage( *it, l_valid );
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_restore() nvdimm[%X] Failed to detect valid image", get_huid(*it));
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+
+ // Remove it from the restore list if there is no valid image
+ if (!l_valid)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_restore() nvdimm[%X] No valid image discovered", get_huid(*it));
+ // Set ATTR NV STATUS FLAG to Erased
+ nvdimmSetStatusFlag(*it, NSTD_VAL_ERASED);
+ it = l_nvdimm_restore_list.erase(it);
+
+ }
+ else
+ {
+ it++;
+ }
+ }
+
+ // Exit if there is nothing to restore
+ if (l_nvdimm_restore_list.empty())
+ {
+ break;
+ }
+
// Start the restore
- l_err = nvdimmRestore(i_nvdimmList, l_mpipl);
+ l_err = nvdimmRestore(l_nvdimm_restore_list, l_mpipl);
+ // Check if restore completed successfully
if (l_err)
{
+ const auto l_nvdimm = l_nvdimm_restore_list.front();
+
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_restore() - Failing nvdimmRestore()");
- errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetStatusFlag(l_nvdimm, NSTD_VAL_SR_FAILED);
+
+ // Invalid restore could be due to dram not in self-refresh
+ // or controller issue. Data should not be trusted at this point
+ l_err->addHwCallout( l_nvdimm,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DECONFIG,
+ HWAS::GARD_Fatal);
+
+ // Collect register data for FFDC Traces
+ nvdimmTraceRegs ( l_nvdimm, l_RegInfo );
+ nvdimmAddPage4Regs(l_nvdimm,l_err);
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err);
break;
}
- // Make sure the energy source is fully charged before erasing the images
- // Doing this on all the nvdimms since the ones w/o image will need
- // to be fully charged before arming the trigger
- uint32_t l_poll = 0;
+ // Check health status registers and exit if required
for (const auto & l_nvdimm : i_nvdimmList)
{
- l_err = nvdimmPollESChargeStatus(l_nvdimm, l_poll);
+ // Post restore health check. l_continue gets set per the health check logic
+ // and used later to determine if boot shall continue on error condition
+ l_err = nvdimmHealthStatusCheck( l_nvdimm, HEALTH_RESTORE, l_continue );
- if (l_err){
- nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_restore() nvdimm[%X] failed during health status check", get_huid(l_nvdimm));
errlCommit( l_err, NVDIMM_COMP_ID );
+ if (!l_continue)
+ {
+ break;
+ }
}
+
+ // Make sure the restore is valid
+ l_err = nvdimmGetRestoreValid(l_nvdimm, l_rstrValid);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_restore Target[%X] error validating restore status!",
+ get_huid(l_nvdimm));
+ break;
+ }
+
+ if ((l_rstrValid & RSTR_SUCCESS) == RSTR_SUCCESS)
+ {
+ // Restore success!
+ nvdimmSetStatusFlag(l_nvdimm, NSTD_VAL_RESTORED);
+ }
+
}
}while(0);
+ if (l_err)
+ {
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+
// At the end, pre-load CCS with commands for EPOW. This will stage the CCS
// with the require commands to trigger the save on NVDIMMs. The actual
// triggering will be done by OCC when EPOW is detected.
@@ -1455,6 +1965,7 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
* - Checks for ready state
* - Gathers timeout values
* - Waits for the ongoing backup to complete
+ * - Unlocks encryption
* - Disarms the trigger for draminit
*
* @param[in] i_nvdimm - nvdimm target
@@ -1463,66 +1974,3903 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
void nvdimm_init(Target *i_nvdimm)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_init() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
+ bool l_continue = true;
+ uint8_t l_data = 0;
+ uint8_t l_failinfo0 = 0;
+ uint8_t l_failinfo1 = 0;
+ nvdimm_reg_t l_RegInfo;
+ uint32_t l_poll = 0;
do
{
- l_err = nvdimmReady(i_nvdimm);
+ // Force a factory reset if told to via attribute override
+ // This will allow us to recover from bad images, lost keys, etc
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "nvdimm_init: no TopLevelTarget");
+ if( l_sys->getAttr<ATTR_FORCE_NVDIMM_RESET>() )
+ {
+ l_err = nvdimm_factory_reset(i_nvdimm);
+ if (l_err)
+ {
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_init() nvdimm[%X], factory reset failed",
+ get_huid(i_nvdimm));
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+ }
+ // Set ATTR_NV_STATUS_FLAG to default disarmed state
+ l_err = notifyNvdimmProtectionChange(i_nvdimm, NVDIMM_DISARMED);
if (l_err)
{
nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR);
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_int() nvdimm[%X], controller not ready",
- TARGETING::get_huid(i_nvdimm));
errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+
+ // Check if the nvdimm ready status
+ l_err = nvdimmReady(i_nvdimm);
+
+ if (l_err)
+ {
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_init() nvdimm[%X], controller not ready",
+ get_huid(i_nvdimm));
break;
}
+ // Check if the firmware slot is 0
+ l_err = nvdimmGetRunningSlot(i_nvdimm, l_data);
+ if (l_err)
+ {
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_init() nvdimm[%X], failed to read slot info",
+ get_huid(i_nvdimm));
+ break;
+ }
+
+ if (l_data == 0)
+ {
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_VAL_SR);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_init() nvdimm[%X], running on fw slot 0",
+ get_huid(i_nvdimm));
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_INVALID_FW_SLOT
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_CHECK_FW_SLOT
+ *@userdata1[0:31] Slot running
+ *@userdata1[32:63] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc Encountered error when checking the firmware slot running
+ * on NVDIMM. Firmware is running on slot 0 instead of 1
+ *@custdesc NVDIMM incorrect firmware slot
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_CHECK_FW_SLOT,
+ NVDIMM_INVALID_FW_SLOT,
+ NVDIMM_SET_USER_DATA_1(l_data, get_huid(i_nvdimm)),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+
+ // Add callout of nvdimm with no deconfig/gard
+ l_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+
// Get the timeout values for the major ops at init
l_err = nvdimmGetTimeoutVal(i_nvdimm);
if (l_err)
{
nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR);
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_int() nvdimm[%X], error retrieving timeout values",
- TARGETING::get_huid(i_nvdimm));
- errlCommit(l_err, NVDIMM_COMP_ID);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_init() nvdimm[%X], error retrieving timeout values",
+ get_huid(i_nvdimm));
break;
}
- //Check save progress
- uint32_t l_poll = 0;
- l_err = nvdimmPollBackupDone(i_nvdimm, l_poll);
+ // Check for Erase in progress and verify good status
+ l_err = nvdimmEraseCheck(i_nvdimm, true);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_init() nvdimm[%X], error checking erase status",
+ get_huid(i_nvdimm));
+ break;
+ }
+ // Check NO_RESET_N bit for power loss without save
+ l_err = nvdimmReadReg ( i_nvdimm, CSAVE_FAIL_INFO1, l_data);
if (l_err)
{
- nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_NOPRSV);
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_int() nvdimm[%X], error backing up the DRAM!",
- TARGETING::get_huid(i_nvdimm));
- errlCommit(l_err, NVDIMM_COMP_ID);
break;
}
+ else if ((l_data & NO_RESET_N) == NO_RESET_N)
+ {
+ // Set ATTR_NV_STATUS_FLAG to partial working as data may persist
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_VAL_SR);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmInit() nvdimm[%X]"
+ "failed to save due to power loss!",get_huid(i_nvdimm));
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_POWER_SAVE_FAILURE
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_CHECK_RESETN
+ *@userdata1[0:31] Related ops (0xff = NA)
+ *@userdata1[32:63] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NO_RESET_N: The NVDIMM experienced a power loss, but no CSAVE
+ * was triggered since the NVDIMM did not detect an asserted
+ * RESET_N. If there is a prior predicitve log for OCC in safe
+ * mode, than this would be the reason for NO_RESET_N. Otherwise
+ * there could be a problem with the RESET_N signal between proc
+ * and NVDIMM.
+ *@custdesc NVDIMM error erasing data image
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_CHECK_RESETN,
+ NVDIMM_POWER_SAVE_FAILURE,
+ NVDIMM_SET_USER_DATA_1(l_data, get_huid(i_nvdimm)),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+ nvdimmAddVendorLog(i_nvdimm, l_err);
+
+ // Failure to erase could mean internal NV controller error and/or
+ // HW error on nand flash. NVDIMM will lose persistency if failed to
+ // erase nand flash
+ l_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Collect register data for FFDC Traces
+ nvdimmTraceRegs ( i_nvdimm, l_RegInfo );
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err);
- // Disarm the ddr_resetn here in case it came in armed. When the nvdimm is
- // armed the reset_n is masked off from the host, meaning the drams won't
- // be able to get reset properly later, causing training to fail.
- l_err = nvdimmChangeArmState(i_nvdimm, DISARM_TRIGGER);
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+ else
+ {
+ // Check save progress
+ l_err = nvdimmPollBackupDone(i_nvdimm, l_poll);
+ if (l_err)
+ {
+ // May have to move the error handling to the caller
+ // as different op could have different error severity
+ l_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DECONFIG,
+ HWAS::GARD_Fatal);
+
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_int() nvdimm[%X], error backing up the DRAM!",
+ get_huid(i_nvdimm));
+ break;
+ }
+ }
+ // Check CSAVE FAIL INFO registers for fail errors
+ l_err = nvdimmReadReg( i_nvdimm, CSAVE_FAIL_INFO0, l_failinfo0 );
+ if (l_err)
+ {
+ break;
+ }
+ l_err = nvdimmReadReg ( i_nvdimm, CSAVE_FAIL_INFO1, l_failinfo1 );
+ if (l_err)
+ {
+ break;
+ }
+ // Apply mask for relevant 1:6 bits to failinfo1
+ l_failinfo1 &= CSAVE_FAIL_BITS_MASK;
+
+ // Check CSAVE_STATUS Register
+ l_err = nvdimmReadReg( i_nvdimm, CSAVE_STATUS, l_data );
if (l_err)
{
- nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_NOPRSV);
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_init() nvdimm[%X], error disarming the nvdimm!",
- TARGETING::get_huid(i_nvdimm));
- errlCommit(l_err, NVDIMM_COMP_ID);
break;
}
+ else if ((l_data == SAVE_ERROR) && ((l_failinfo0 != ZERO) || (l_failinfo1 != ZERO)))
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_CSAVE_ERROR
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_CHECK_CSAVE
+ *@userdata1[0:31] Related ops (0xff = NA)
+ *@userdata1[32:63] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc Encountered error saving during catastrophic save
+ * on NVDIMM. Check error register trace for details
+ *@custdesc NVDIMM error during Catastrophic Save
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_CHECK_CSAVE,
+ NVDIMM_CSAVE_ERROR,
+ NVDIMM_SET_USER_DATA_1(l_data, get_huid(i_nvdimm)),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+
+ // Collect register data for FFDC Traces
+ nvdimmTraceRegs ( i_nvdimm, l_RegInfo );
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+ nvdimmAddVendorLog(i_nvdimm, l_err);
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err);
+
+ // Check if the image is still valid
+ if ( l_RegInfo.CSave_Info != VALID_IMAGE )
+ {
+ // Callout and gard dimm if image is not valid
+ l_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DECONFIG,
+ HWAS::GARD_Fatal);
+ break;
+ }
+ else
+ {
+ // Callout dimm without gard if image is valid
+ l_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Set ATTR_NV_STATUS_FLAG to partial working as data may persist
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_VAL_SR);
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+ }
+
+ // Check Health Status Registers
+ l_err = nvdimmHealthStatusCheck(i_nvdimm, HEALTH_SAVE, l_continue);
+ if(!l_continue)
+ {
+ break;
+ }
+
+ // Unlock encryption if enabled
+ TargetHandleList l_nvdimmTargetList;
+ l_nvdimmTargetList.push_back(i_nvdimm);
+ NVDIMM::nvdimm_encrypt_unlock(l_nvdimmTargetList);
}while(0);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_init() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
+
+ if (l_err)
+ {
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ }
}
+
+
+void nvdimm_thresholds(TARGETING::TargetHandleList &i_nvdimmList)
+{
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_thresholds()");
+
+ errlHndl_t l_err = nullptr;
+
+ for (const auto & l_nvdimm : i_nvdimmList)
+ {
+ // ES_LIFETIME_WARNING_THRESHOLD
+ l_err = nvdimmWriteReg(l_nvdimm,
+ ES_LIFETIME_WARNING_THRESHOLD,
+ THRESHOLD_ES_LIFETIME);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm,
+ ERR_MRK"nvdimm_thresholds() nvdimm[%X] "
+ "error setting ES_LIFETIME_WARNING_THRESHOLD",
+ get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ // NVM_LIFETIME_WARNING_THRESHOLD
+ l_err = nvdimmWriteReg(l_nvdimm,
+ NVM_LIFETIME_WARNING_THRESHOLD,
+ THRESHOLD_NVM_LIFETIME);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm,
+ ERR_MRK"nvdimm_thresholds() nvdimm[%X] "
+ "error setting NVM_LIFETIME_WARNING_THRESHOLD",
+ get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ // ES_TEMP_WARNING_HIGH_THRESHOLD1
+ l_err = nvdimmWriteReg(l_nvdimm,
+ ES_TEMP_WARNING_HIGH_THRESHOLD1,
+ THRESHOLD_ES_TEMP_HIGH_1);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm,
+ ERR_MRK"nvdimm_thresholds() nvdimm[%X] "
+ "error setting ES_TEMP_WARNING_HIGH_THRESHOLD1",
+ get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ // ES_TEMP_WARNING_HIGH_THRESHOLD0
+ l_err = nvdimmWriteReg(l_nvdimm,
+ ES_TEMP_WARNING_HIGH_THRESHOLD0,
+ THRESHOLD_ES_TEMP_HIGH_0);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm,
+ ERR_MRK"nvdimm_thresholds() nvdimm[%X] "
+ "error setting ES_TEMP_WARNING_HIGH_THRESHOLD0",
+ get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ // ES_TEMP_WARNING_LOW_THRESHOLD1
+ l_err = nvdimmWriteReg(l_nvdimm,
+ ES_TEMP_WARNING_LOW_THRESHOLD1,
+ THRESHOLD_ES_TEMP_LOW_1);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm,
+ ERR_MRK"nvdimm_thresholds() nvdimm[%X] "
+ "error setting ES_TEMP_WARNING_LOW_THRESHOLD1",
+ get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ // ES_TEMP_WARNING_LOW_THRESHOLD0
+ l_err = nvdimmWriteReg(l_nvdimm,
+ ES_TEMP_WARNING_LOW_THRESHOLD0,
+ THRESHOLD_ES_TEMP_LOW_0);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm,
+ ERR_MRK"nvdimm_thresholds() nvdimm[%X] "
+ "error setting ES_TEMP_WARNING_LOW_THRESHOLD0",
+ get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ }
+
+ TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_thresholds()");
+}
+
+
+errlHndl_t nvdimm_getRandom(uint8_t* o_genData)
+{
+ errlHndl_t l_err = nullptr;
+ uint8_t l_xtraData[ENC_KEY_SIZE] = {0};
+
+ do
+ {
+ // Get a pointer to the TPM
+ Target* l_tpm = nullptr;
+ l_err = nvdimm_getTPM(l_tpm);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Get a random number from the TPM
+ l_err = TRUSTEDBOOT::GetRandom(l_tpm, ENC_KEY_SIZE, o_genData);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Validate and update the random number
+ // Retry if more randomness required
+ do
+ {
+ //Get replacement data
+ l_err = TRUSTEDBOOT::GetRandom(l_tpm, ENC_KEY_SIZE, l_xtraData);
+ if (l_err)
+ {
+ break;
+ }
+
+ }while (nvdimm_keyifyRandomNumber(o_genData, l_xtraData));
+
+ } while(0);
+
+ return l_err;
+}
+
+
+errlHndl_t nvdimm_getTPM(Target*& o_tpm)
+{
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ // Get all functional TPMs
+ TargetHandleList l_tpmList;
+ TRUSTEDBOOT::getTPMs(l_tpmList,
+ TRUSTEDBOOT::TPM_FILTER::ALL_FUNCTIONAL);
+
+ if (l_tpmList.size())
+ {
+ o_tpm = l_tpmList[0];
+ break;
+ }
+
+ // No TPMs, generate error
+ TRACFCOMP(g_trac_nvdimm,ERR_MRK"nvdimm_getTPM() No functional TPMs found");
+
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_TPM_NOT_FOUND
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_GET_TPM
+ *@devdesc Functional TPM required to generate encryption keys
+ *@custdesc NVDIMM error generating encryption keys
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_GET_TPM,
+ NVDIMM_TPM_NOT_FOUND,
+ 0x0,
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+
+ // Get all TPMs
+ TRUSTEDBOOT::getTPMs(l_tpmList,
+ TRUSTEDBOOT::TPM_FILTER::ALL_IN_BLUEPRINT);
+ if (l_tpmList.size() == 0)
+ {
+ // No TPMs, we probably have nvdimms enabled
+ // when they should not be
+ l_err->addProcedureCallout(
+ HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ }
+ else
+ {
+ // If a TPM exists it must be deconfigured
+ l_err->addProcedureCallout(
+ HWAS::EPUB_PRC_FIND_DECONFIGURED_PART,
+ HWAS::SRCI_PRIORITY_HIGH);
+ l_err->addProcedureCallout(
+ HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_MED);
+ }
+
+ }while(0);
+
+ // Functional TPM not found
+ return l_err;
+}
+
+
+#endif
+
+
+/**
+ * @brief Force a factory reset of the NV logic and flash
+ *
+ * @param[in] i_nvdimm - NVDIMM Target
+ */
+errlHndl_t nvdimm_factory_reset(Target *i_nvdimm)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_factory_reset() nvdimm[%X]",
+ get_huid(i_nvdimm));
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ // Send the reset command
+ l_err = nvdimmWriteReg(i_nvdimm, NVDIMM_FUNC_CMD, FACTORY_DEFAULT);
+ if( l_err )
+ {
+ break;
+ }
+
+ // Poll 2 minutes for completion
+ // We could get the timeout value from the dimm but since we're
+ // doing a hard reset anyway I just want to use a big number that
+ // can handle any lies that the controller might tell us.
+ uint8_t l_data = 0;
+ constexpr uint64_t MAX_POLL_SECONDS = 120;
+ uint64_t poll = 0;
+ for( poll = 0; poll < MAX_POLL_SECONDS; poll++ )
+ {
+ l_err = nvdimmReadReg(i_nvdimm, NVDIMM_CMD_STATUS0, l_data);
+ if( l_err )
+ {
+ break;
+ }
+
+ if( l_data != FACTORY_RESET_IN_PROGRESS )
+ {
+ break;
+ }
+
+#ifndef __HOSTBOOT_RUNTIME
+ // kick the watchdog since this can take awhile
+ INITSERVICE::sendProgressCode();
#endif
+ // sleep 1 second
+ nanosleep(1, 0);
+ }
+ if( l_err ) { break; }
+
+ // Make an error if it never finished
+ if( poll >= MAX_POLL_SECONDS )
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_factory_reset() nvdimm[%X] - factory reset never completed[%d]",
+ get_huid(i_nvdimm), l_data);
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_NOT_READY
+ *@severity ERRORLOG_SEV_UNRECOVERABLE
+ *@moduleid NVDIMM_FACTORY_RESET
+ *@userdata1[0:31] Ret value from ready register
+ *@userdata1[32:63] Target Huid
+ *@userdata2 Number of seconds waited
+ *@devdesc NVDIMM factory reset never completed
+ *@custdesc NVDIMM still in reset
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ NVDIMM_FACTORY_RESET,
+ NVDIMM_NOT_READY,
+ NVDIMM_SET_USER_DATA_1(l_data, get_huid(i_nvdimm)),
+ MAX_POLL_SECONDS,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ nvdimmAddVendorLog(i_nvdimm, l_err);
+
+ // If nvdimm is not ready for access by now, this is
+ // a failing indication on the NV controller
+ l_err->addPartCallout( i_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+ }
+ } while(0);
+
+ return l_err;
+}
+
+
+bool nvdimm_encrypt_unlock(TargetHandleList &i_nvdimmList)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_encrypt_unlock()");
+ errlHndl_t l_err = nullptr;
+ bool l_success = true;
+
+ do
+ {
+ // Do not check ATTR_NVDIMM_ENCRYPTION_ENABLE
+ // The attribute could have been reset by flashing the FSP
+ // Unlock if the keys are valid and NVDIMM hw encryption is enabled
+
+ // Get the sys pointer, attribute keys are system level
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "nvdimm_encrypt_unlock() no TopLevelTarget");
+
+ // Get the FW key attributes
+ auto l_attrKeysFw =
+ l_sys->getAttrAsStdArr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>();
+
+ // Cast to key data struct type for easy access to each key
+ nvdimmKeyData_t* l_keysFw =
+ reinterpret_cast<nvdimmKeyData_t*>(&l_attrKeysFw);
+
+ // Check encryption unlock for all nvdimms
+ for (const auto & l_nvdimm : i_nvdimmList)
+ {
+ // Get encryption state in the config/status reg
+ encryption_config_status_t l_encStatus = {0};
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_encrypt_unlock() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+
+ // Already unlocked or not enabled then exit
+ if (l_encStatus.encryption_unlocked ||
+ !l_encStatus.encryption_enabled)
+ {
+ break;
+ }
+
+ // Check for valid key attribute data
+ l_err = nvdimm_checkValidAttrKeys(l_keysFw);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ break;
+ }
+
+ // Else encryption is enabled but needs unlock
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_encrypt_unlock() nvdimm[%X] enabled, unlocking...",get_huid(l_nvdimm));
+
+ // Set the Unlock Access Key Reg
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_keysFw->ak,
+ ENCRYPTION_ACCESS_KEY_UNLOCK,
+ ENCRYPTION_ACCESS_KEY_VERIFY,
+ false);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+
+ // Verify encryption is unlocked
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_encrypt_unlock() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS after unlock",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+
+ if (!l_encStatus.encryption_unlocked)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_encrypt_unlock() nvdimm[%X] encryption unlock failed, expected ENCRYPTION_CONFIG_STATUS=0x%.02X, expected=0x1F ",get_huid(l_nvdimm),l_encStatus.whole);
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ENCRYPTION_UNLOCK_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_ENCRYPT_UNLOCK
+ *@userdata1 NVDIMM HUID
+ *@userdata2 ENCRYPTION_CONFIG_STATUS
+ *@devdesc NVDIMM failed to unlock encryption
+ *@custdesc NVDIMM encryption error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_ENCRYPT_UNLOCK,
+ NVDIMM_ENCRYPTION_UNLOCK_FAILED,
+ get_huid(l_nvdimm),
+ l_encStatus.whole,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
+ l_err->addPartCallout( l_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ l_err->addHwCallout( l_nvdimm,
+ HWAS::SRCI_PRIORITY_MED,
+ HWAS::DELAYED_DECONFIG,
+ HWAS::GARD_NULL );
+
+ nvdimmAddPage4Regs(l_nvdimm,l_err);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_encrypt_unlock() nvdimm[%X] encryption is unlocked 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ }
+ }
+ }while(0);
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_encrypt_unlock()");
+ return l_success;
+}
+
+
+void nvdimmSetEncryptionError(Target *i_nvdimm)
+{
+ ATTR_NVDIMM_ARMED_type l_armed_state = {};
+ l_armed_state = i_nvdimm->getAttr<ATTR_NVDIMM_ARMED>();
+
+ l_armed_state.encryption_error_detected = 1;
+
+ i_nvdimm->setAttr<ATTR_NVDIMM_ARMED>(l_armed_state);
+}
+
+
+bool nvdimm_keyifyRandomNumber(uint8_t* o_genData, uint8_t* i_xtraData)
+{
+ bool l_failed = false;
+ uint32_t l_xtraByte = 0;
+
+ for (uint32_t l_byte = 0; l_byte < ENC_KEY_SIZE; l_byte++)
+ {
+ if ((o_genData[l_byte] != KEY_TERMINATE_BYTE) &&
+ (o_genData[l_byte] != KEY_ABORT_BYTE))
+ {
+ // This byte is valid
+ continue;
+ }
+
+ // This byte is not valid, replace it
+ // Find a valid byte in the replacement data
+ while ((i_xtraData[l_xtraByte] == KEY_TERMINATE_BYTE) ||
+ (i_xtraData[l_xtraByte] == KEY_ABORT_BYTE))
+ {
+ l_xtraByte++;
+
+ if (l_xtraByte == ENC_KEY_SIZE)
+ {
+ l_failed = true;
+ break;
+ }
+ }
+
+ if (l_failed)
+ {
+ break;
+ }
+
+ // Replace the invalid byte with the valid extra byte
+ o_genData[l_byte] = i_xtraData[l_xtraByte];
+ }
+
+ return l_failed;
+}
+
+
+bool nvdimm_validRandomNumber(uint8_t* i_genData)
+{
+ bool l_valid = true;
+ for (uint32_t l_byte = 0; l_byte < ENC_KEY_SIZE; l_byte++)
+ {
+ if ((i_genData[l_byte] == KEY_TERMINATE_BYTE) ||
+ (i_genData[l_byte] == KEY_ABORT_BYTE))
+ {
+ l_valid = false;
+ break;
+ }
+ }
+ return l_valid;
+}
+
+
+errlHndl_t nvdimm_checkValidAttrKeys( nvdimmKeyData_t* i_attrData )
+{
+ errlHndl_t l_err = nullptr;
+ bool l_valid = false;
+
+ do
+ {
+ l_valid = nvdimm_validRandomNumber(i_attrData->rs);
+ if (!l_valid)
+ {
+ break;
+ }
+ l_valid = nvdimm_validRandomNumber(i_attrData->ek);
+ if (!l_valid)
+ {
+ break;
+ }
+ l_valid = nvdimm_validRandomNumber(i_attrData->ak);
+ if (!l_valid)
+ {
+ break;
+ }
+ }while(0);
+
+ if (!l_valid)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_checkValidAttrKeys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW contains invalid data");
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ENCRYPTION_INVALID_ATTRIBUTE
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_CHECK_VALID_ATTR_DATA
+ *@devdesc ATTR_NVDIMM_ENCRYPTION_KEYS_FW has invalid data
+ *@custdesc NVDIMM encryption error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_CHECK_VALID_ATTR_DATA,
+ NVDIMM_ENCRYPTION_INVALID_ATTRIBUTE,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ }
+
+ return l_err;
+}
+
+
+errlHndl_t nvdimm_handleConflictingKeys(
+ ATTR_NVDIMM_ENCRYPTION_KEYS_FW_typeStdArr& i_attrKeysFw,
+ ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR_typeStdArr& i_attrKeysAnchor)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_handleConflictingKeys()");
+ errlHndl_t l_err = nullptr;
+ bool l_validKeyFound = false;
+
+ // Recast to key data type to simplify parsing
+ nvdimmKeyData_t* l_keysFw =
+ reinterpret_cast<nvdimmKeyData_t*>(&i_attrKeysFw);
+ nvdimmKeyData_t* l_keysAnchor =
+ reinterpret_cast<nvdimmKeyData_t*>(&i_attrKeysAnchor);
+
+ // Get the nvdimm target pointers
+ TargetHandleList l_nvdimmTargetList;
+ nvdimm_getNvdimmList(l_nvdimmTargetList);
+ for (const auto & l_nvdimm : l_nvdimmTargetList)
+ {
+ // Check encryption state in the config/status reg
+ encryption_config_status_t l_encStatus = {0};
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_handleConflictingKeys() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ continue;
+ }
+
+ // Encryption is not enabled
+ // Keys are not in use so could use either set of keys
+ // Use the ANCHOR card keys
+ if (!l_encStatus.encryption_enabled)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_handleConflictingKeys() nvdimm[%X] copying ANCHOR keys to FW",get_huid(l_nvdimm));
+ l_validKeyFound = true;
+ set_ATTR_NVDIMM_ENCRYPTION_KEYS_FW(i_attrKeysAnchor);
+ continue;
+ }
+
+ // Encryption is enabled, test the keys
+ // Write the EK test reg with the FW attr value
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_keysFw->ek,
+ ENCRYPTION_ERASE_KEY_TEST,
+ ENCRYPTION_ERASE_KEY_TEST_VERIFY,
+ false);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Check for erase key valid in the validation reg
+ encryption_key_validation_t l_keyValid = {0};
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_KEY_VALIDATION,
+ l_keyValid.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_handleConflictingKeys() nvdimm[%X] error reading ENCRYPTION_KEY_VALIDATION",get_huid(l_nvdimm));
+ break;
+ }
+ if (l_keyValid.erase_key_valid)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_handleConflictingKeys() nvdimm[%X] ATTR_NVDIMM_ENCRYPTION_KEYS_FW valid",get_huid(l_nvdimm));
+ l_validKeyFound = true;
+ // Re-write the FW keys, this will also update the ANCHOR keys
+ set_ATTR_NVDIMM_ENCRYPTION_KEYS_FW(i_attrKeysFw);
+ break;
+ }
+
+ // Write the EK test reg with the Anchor attr value
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_keysAnchor->ek,
+ ENCRYPTION_ERASE_KEY_TEST,
+ ENCRYPTION_ERASE_KEY_TEST_VERIFY,
+ false);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Check for erase key valid in the validation reg
+ l_keyValid.whole = 0;
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_KEY_VALIDATION,
+ l_keyValid.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_handleConflictingKeys() nvdimm[%X] error reading ENCRYPTION_KEY_VALIDATION",get_huid(l_nvdimm));
+ break;
+ }
+ if (l_keyValid.erase_key_valid)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_handleConflictingKeys() nvdimm[%X] ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR valid",get_huid(l_nvdimm));
+ l_validKeyFound = true;
+ // Copy anchor attr value to FW attribute
+ set_ATTR_NVDIMM_ENCRYPTION_KEYS_FW(i_attrKeysAnchor);
+
+ break;
+ }
+ }
+
+ if (!l_validKeyFound)
+ {
+ // Neither key attribute is valid
+ TRACFCOMP(g_trac_nvdimm,ERR_MRK"nvdimm_handleConflictingKeys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW and ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR invalid.");
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ENCRYPTION_KEY_ATTRS_INVALID
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_HANDLE_CONFLICTING_KEYS
+ *@devdesc NVDIMM encryption key attributes invalid
+ *@custdesc NVDIMM encryption error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_HANDLE_CONFLICTING_KEYS,
+ NVDIMM_ENCRYPTION_KEY_ATTRS_INVALID,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ }
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_handleConflictingKeys()");
+ return l_err;
+}
+
+
+void nvdimm_getNvdimmList(TargetHandleList &o_nvdimmTargetList)
+{
+ // Check for any NVDIMMs after the mss_power_cleanup
+ TargetHandleList l_dimmTargetList;
+ getAllLogicalCards(l_dimmTargetList, TYPE_DIMM);
+
+ // Walk the dimm list and collect all the nvdimm targets
+ for (auto const l_dimm : l_dimmTargetList)
+ {
+ if (isNVDIMM(l_dimm))
+ {
+ o_nvdimmTargetList.push_back(l_dimm);
+ }
+ }
+}
+
+
+bool nvdimm_gen_keys(void)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_gen_keys()");
+ errlHndl_t l_err = nullptr;
+ bool l_success = true;
+
+ do
+ {
+ // Determine if key generation required
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "nvdimm_gen_keys: no TopLevelTarget");
+
+ // Key size must be less that max TPM random generator size
+ static_assert(ENC_KEY_SIZE <= MAX_TPM_SIZE,
+ "nvdimm_gen_keys() ENC_KEY_SIZE is greater than MAX_TPM_SIZE");
+
+ // Key attributes should be same size
+ static_assert( sizeof(ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR_type) ==
+ sizeof(ATTR_NVDIMM_ENCRYPTION_KEYS_FW_type),
+ "nvdimm_gen_keys() size of ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR_type does not match ATTR_NVDIMM_ENCRYPTION_KEYS_FW_type");
+
+ // Get the key attributes
+ auto l_attrKeysFw =
+ l_sys->getAttrAsStdArr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>();
+ auto l_attrKeysAn =
+ l_sys->getAttrAsStdArr<ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR>();
+
+ // Check the attribute sizes
+ static_assert(sizeof(l_attrKeysFw) == (NUM_KEYS_IN_ATTR * ENC_KEY_SIZE),
+ "nvdimm_gen_keys() Size of ATTR_NVDIMM_ENCRYPTION_KEYS_FW does not match NUM_KEYS_IN_ATTR * ENC_KEY_SIZE");
+ static_assert(sizeof(l_attrKeysAn) == (NUM_KEYS_IN_ATTR * ENC_KEY_SIZE),
+ "nvdimm_gen_keys() Size of ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR does not match NUM_KEYS_IN_ATTR * ENC_KEY_SIZE");
+
+ // Compare attributes to zero
+ std::array<uint8_t,sizeof(l_attrKeysFw)> l_zero = {0};
+ bool l_fwZero = (l_attrKeysFw == l_zero);
+ bool l_anZero = (l_attrKeysAn == l_zero);
+
+ // Compare the attribute values
+ if (!l_fwZero && !l_anZero)
+ {
+ if (l_attrKeysFw != l_attrKeysAn)
+ {
+ // Handle conflicting keys
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_gen_keys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW != ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR");
+ l_err = nvdimm_handleConflictingKeys(l_attrKeysFw,l_attrKeysAn);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_gen_keys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW == ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR");
+ }
+ break;
+ }
+ else if (!l_fwZero && l_anZero)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_gen_keys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW != 0 and ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR = 0");
+ break;
+ }
+ else if (l_fwZero && !l_anZero)
+ {
+ // Set FW attr = Anchor attr
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_gen_keys() Setting ATTR_NVDIMM_ENCRYPTION_KEYS_FW = ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR");
+ set_ATTR_NVDIMM_ENCRYPTION_KEYS_FW(l_attrKeysAn);
+ break;
+ }
+
+ // If we get here then both key attributes are zero, generate new keys
+ assert(sizeof(l_attrKeysFw) == sizeof(nvdimmKeyData_t),
+ "nvdimm_gen_keys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW size does not match nvdimmKeyData_t");
+ nvdimmKeyData_t* l_keys =
+ reinterpret_cast<nvdimmKeyData_t*>(&l_attrKeysFw);
+
+ // Generate Random String (RS)
+ l_err = nvdimm_getRandom(l_keys->rs);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Generate Erase Key (EK)
+ l_err = nvdimm_getRandom(l_keys->ek);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Generate Access Key (AK)
+ l_err = nvdimm_getRandom(l_keys->ak);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Set the FW attribute
+ set_ATTR_NVDIMM_ENCRYPTION_KEYS_FW(l_attrKeysFw);
+
+ }while(0);
+
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_gen_keys() Failed to generate keys, will not set ATTR_NVDIMM_ENCRYPTION_KEYS_FW");
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ l_success = false;
+
+ // Set the encryption error for all nvdimms
+ TargetHandleList l_nvdimmTargetList;
+ nvdimm_getNvdimmList(l_nvdimmTargetList);
+ for (const auto & l_nvdimm : l_nvdimmTargetList)
+ {
+ nvdimmSetEncryptionError(l_nvdimm);
+ }
+ }
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_gen_keys()");
+ return l_success;
+}
+
+
+bool nvdimm_remove_keys(void)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_remove_keys()");
+ bool l_success = true;
+
+ // Get the sys pointer, attribute keys are system level
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "nvdimm_remove_keys() no TopLevelTarget");
+
+ // Set the FW attribute = 0
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_remove_keys() Setting ATTR_NVDIMM_ENCRYPTION_KEYS_FW=0");
+ ATTR_NVDIMM_ENCRYPTION_KEYS_FW_typeStdArr l_attrKeysFw = {0};
+ set_ATTR_NVDIMM_ENCRYPTION_KEYS_FW(l_attrKeysFw);
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_remove_keys()");
+ return l_success;
+}
+
+
+errlHndl_t nvdimm_setKeyReg(Target* i_nvdimm,
+ uint8_t* i_keyData,
+ uint32_t i_keyReg,
+ uint32_t i_verifyReg,
+ bool i_secondAttempt)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_setKeyReg(0x%X) reg=0x%X",get_huid(i_nvdimm),i_keyReg);
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ uint32_t l_byte = 0;
+ uint8_t l_verifyData = 0x0;
+
+ // Before setting the key reg we need to
+ // init the verif reg with a random value
+ uint8_t l_genData[ENC_KEY_SIZE] = {0};
+ l_err = nvdimm_getRandom(l_genData);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Write the verif reg one byte at a time
+ for (l_byte = 0; l_byte < ENC_KEY_SIZE; l_byte++)
+ {
+ // Write the verification byte
+ l_err = nvdimmWriteReg(i_nvdimm, i_verifyReg, l_genData[l_byte]);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_setKeyReg() huid=0x%X, error writing verif reg=0x%.03X byte=0x%d", get_huid(i_nvdimm), i_verifyReg, l_byte);
+ break;
+ }
+ }
+
+ // Delay to allow verif write to complete
+ nanosleep(0, KEY_WRITE_DELAY_MS*NS_PER_MSEC);
+
+ // Write the reg, one byte at a time
+ for (l_byte = 0; l_byte < ENC_KEY_SIZE; l_byte++)
+ {
+ // Write the key byte
+ l_err = nvdimmWriteReg(i_nvdimm, i_keyReg, i_keyData[l_byte]);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_setKeyReg() huid=0x%X, error writing key reg 0x%.03X byte=0x%d", get_huid(i_nvdimm), i_keyReg, l_byte);
+ break;
+ }
+
+ // Read the verification byte
+ l_err = nvdimmReadReg(i_nvdimm, i_verifyReg, l_verifyData);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_setKeyReg() huid=0x%X, error reading verif reg=0x%.03X byte=0x%d", get_huid(i_nvdimm), i_verifyReg, l_byte);
+ break;
+ }
+
+ // Verify the key byte
+ if (l_verifyData != i_keyData[l_byte])
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_setKeyReg() huid=0x%X, key verification failed reg=0x%.03X byte=0x%d set=0x%.02x get=0x%.02x", get_huid(i_nvdimm), i_keyReg, l_byte, i_keyData[l_byte], l_verifyData);
+ // Write KEY_ABORT_BYTE to abort the key write sequence
+ l_err = nvdimmWriteReg(i_nvdimm, i_keyReg, KEY_ABORT_BYTE);
+ if (i_secondAttempt)
+ {
+ // Verify check byte failed for the second time
+ TRACFCOMP(g_trac_nvdimm,ERR_MRK"nvdimm_getTPM() Key verification byte check failed on second attempt.");
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_VERIF_BYTE_CHECK_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_SET_KEY_REG
+ *@userdata1 NVDIMM HUID
+ *@userdata2[0:31] Key Register
+ *@userdata2[32:63] Verif Register
+ *@devdesc NVDIMM failed to set encryption register
+ *@custdesc NVDIMM register error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_SET_KEY_REG,
+ NVDIMM_VERIF_BYTE_CHECK_FAILED,
+ get_huid(i_nvdimm),
+ NVDIMM_SET_USER_DATA_1(i_keyReg,i_verifyReg),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ nvdimmAddVendorLog(i_nvdimm, l_err);
+ l_err->addPartCallout( i_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+ }
+ else
+ {
+ // Try writing the reg again
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_setKeyReg() huid=0x%X, writing reg=0x%.03X again", get_huid(i_nvdimm), i_keyReg);
+ l_err = nvdimm_setKeyReg(i_nvdimm,
+ i_keyData,
+ i_keyReg,
+ i_verifyReg,
+ true);
+ }
+ break;
+ }
+ }
+
+ // Delay to allow write to complete
+ nanosleep(0, KEY_WRITE_DELAY_MS*NS_PER_MSEC);
+
+ }while(0);
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_setKeyReg(0x%X) reg=0x%X",get_huid(i_nvdimm),i_keyReg);
+ return l_err;
+}
+
+
+bool nvdimm_encrypt_enable(TargetHandleList &i_nvdimmList)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_encrypt_enable()");
+ errlHndl_t l_err = nullptr;
+ bool l_success = true;
+
+ do
+ {
+ // Get the sys pointer, attribute keys are system level
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "nvdimm_encrypt_enable() no TopLevelTarget");
+
+ // Exit if encryption is not enabled via the attribute
+ if (!l_sys->getAttr<ATTR_NVDIMM_ENCRYPTION_ENABLE>())
+ {
+ TRACFCOMP(g_trac_nvdimm,"ATTR_NVDIMM_ENCRYPTION_ENABLE=0");
+ break;
+ }
+
+ // Get the FW key attributes
+ auto l_attrKeysFw =
+ l_sys->getAttrAsStdArr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>();
+
+ // Cast to key data struct type for easy access to each key
+ nvdimmKeyData_t* l_keysFw =
+ reinterpret_cast<nvdimmKeyData_t*>(&l_attrKeysFw);
+
+ // Check for valid key attribute key data
+ l_err = nvdimm_checkValidAttrKeys(l_keysFw);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Handle encryption for all nvdimms
+ for (const auto & l_nvdimm : i_nvdimmList)
+ {
+ // Check encryption state in the config/status reg
+ encryption_config_status_t l_encStatus = {0};
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_encrypt_enable() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+
+ // Encryption is enabled and unlocked
+ if (l_encStatus.encryption_unlocked &&
+ l_encStatus.encryption_enabled)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_encrypt_enable() nvdimm[%X] enabled and unlocked",get_huid(l_nvdimm));
+ continue;
+ }
+
+ // Need to handle these cases?
+ if (!((l_encStatus.whole & ENCRYPTION_STATUS_CHECK_MASK)
+ == ENCRYPTION_STATUS_DISABLED))
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_encrypt_enable() nvdimm[%X] unsupported state 0x%.02X",get_huid(l_nvdimm),l_encStatus.whole);
+ continue;
+ }
+
+ // Status = 0x01, enable encryption
+ // Set the Random String (RS) reg
+ TRACFCOMP(g_trac_nvdimm,"nvdimm_encrypt_enable() nvdimm[%X] status=0x01 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_keysFw->rs,
+ ENCRYPTION_RAMDOM_STRING_SET,
+ ENCRYPTION_RANDOM_STRING_VERIFY,
+ false);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+
+ // Set the Erase Key (EK) Reg
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_keysFw->ek,
+ ENCRYPTION_ERASE_KEY_SET,
+ ENCRYPTION_ERASE_KEY_VERIFY,
+ false);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+
+ // Set the Access Key (AK) Reg
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_keysFw->ak,
+ ENCRYPTION_ACCESS_KEY_SET,
+ ENCRYPTION_ACCESS_KEY_VERIFY,
+ false);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+
+ // Verify encryption is enabled
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_encrypt_enable() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS after enable",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+ if (!((l_encStatus.whole & ENCRYPTION_STATUS_CHECK_MASK)
+ == ENCRYPTION_STATUS_ENABLED))
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_encrypt_enable() nvdimm[%X] encryption enable failed, ENCRYPTION_CONFIG_STATUS=0x%.02X, expected=0x1F ",get_huid(l_nvdimm),l_encStatus.whole);
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ENCRYPTION_ENABLE_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_ENCRYPT_ENABLE
+ *@userdata1 NVDIMM HUID
+ *@userdata2 ENCRYPTION_CONFIG_STATUS
+ *@devdesc NVDIMM failed to enable encryption
+ *@custdesc NVDIMM encryption error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_ENCRYPT_ENABLE,
+ NVDIMM_ENCRYPTION_ENABLE_FAILED,
+ get_huid(l_nvdimm),
+ l_encStatus.whole,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
+ l_err->addPartCallout( l_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ nvdimmAddPage4Regs(l_nvdimm,l_err);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_encrypt_enable() nvdimm[%X] encryption is enabled 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+
+ l_err = notifyNvdimmProtectionChange(l_nvdimm,
+ ENCRYPTION_ENABLED);
+ if (l_err)
+ {
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+ }
+ }
+ }while(0);
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_encrypt_enable()");
+ return l_success;
+}
+
+
+bool nvdimm_crypto_erase(TargetHandleList &i_nvdimmList)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_crypto_erase()");
+ errlHndl_t l_err = nullptr;
+ bool l_success = true;
+
+ do
+ {
+ // Get the sys pointer, attribute keys are system level
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "nvdimm_crypto_erase: no TopLevelTarget");
+
+ // Exit if encryption is not enabled via the attribute
+ if (!l_sys->getAttr<ATTR_NVDIMM_ENCRYPTION_ENABLE>())
+ {
+ TRACFCOMP(g_trac_nvdimm,"ATTR_NVDIMM_ENCRYPTION_ENABLE=0");
+ break;
+ }
+
+ // Get the FW key attributes
+ auto l_attrKeysFw =
+ l_sys->getAttrAsStdArr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>();
+
+ // Cast to key data struct type for easy access to each key
+ nvdimmKeyData_t* l_keysFw =
+ reinterpret_cast<nvdimmKeyData_t*>(&l_attrKeysFw);
+
+ // Check for valid key attribute key data
+ l_err = nvdimm_checkValidAttrKeys(l_keysFw);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Handle erase for all nvdimms
+ for (const auto & l_nvdimm : i_nvdimmList)
+ {
+ // Check encryption state in the config/status reg
+ encryption_config_status_t l_encStatus = {0};
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_crypto_erase() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+ // Encryption enabled must be set to crypto erase
+ if (!l_encStatus.encryption_enabled)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_crypto_erase() nvdimm[%X] encryption not enabled, will not cypto erase 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ l_success = false;
+ continue;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_crypto_erase() nvdimm[%X] encryption enabled 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ }
+
+ // Set the Erase Key (EK) Reg
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_keysFw->ek,
+ ENCRYPTION_ERASE_KEY_SET,
+ ENCRYPTION_ERASE_KEY_VERIFY,
+ false);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+
+ // Check encryption state in the config/status reg
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_crypto_erase() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+ // Erase pending bit should be set
+ if (!l_encStatus.erase_pending)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_crypto_erase() nvdimm[%X] expected erase pending = 1 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ENCRYPTION_ERASE_PENDING_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_CRYPTO_ERASE
+ *@userdata1 NVDIMM HUID
+ *@userdata2 ENCRYPTION_CONFIG_STATUS
+ *@devdesc NVDIMM failed to set encryption register
+ *@custdesc NVDIMM register error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_CRYPTO_ERASE,
+ NVDIMM_ENCRYPTION_ERASE_PENDING_FAILED,
+ get_huid(l_nvdimm),
+ l_encStatus.whole,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
+ l_err->addPartCallout( l_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ nvdimmAddPage4Regs(l_nvdimm,l_err);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nvdimm,"nvdimm_crypto_erase() nvdimm[%X] erase pending 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ }
+
+ // Generate a generic erase key
+ uint8_t l_genData[ENC_KEY_SIZE] = {0};
+ l_err = nvdimm_getRandom(l_genData);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+
+ // Set the Erase Key (EK) Reg
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_genData,
+ ENCRYPTION_ERASE_KEY_SET,
+ ENCRYPTION_ERASE_KEY_VERIFY,
+ false);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+
+ // Check encryption state in the config/status reg
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_crypto_erase() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+ // Encryption enabled bit should not be set
+ if (l_encStatus.encryption_enabled)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_crypto_erase() nvdimm[%X] expected encryption enabled = 0 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ENCRYPTION_ERASE_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_CRYPTO_ERASE
+ *@userdata1 NVDIMM HUID
+ *@userdata2 ENCRYPTION_CONFIG_STATUS
+ *@devdesc NVDIMM failed to set encryption register
+ *@custdesc NVDIMM register error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_CRYPTO_ERASE,
+ NVDIMM_ENCRYPTION_ERASE_FAILED,
+ get_huid(l_nvdimm),
+ l_encStatus.whole,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
+ l_err->addPartCallout( l_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ nvdimmAddPage4Regs(l_nvdimm,l_err);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmSetEncryptionError(l_nvdimm);
+ l_success = false;
+ continue;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nvdimm,"nvdimm_crypto_erase() nvdimm[%X] erase complete 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+
+ l_err = notifyNvdimmProtectionChange(l_nvdimm,
+ ENCRYPTION_DISABLED);
+ if (l_err)
+ {
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+ }
+ }
+ }while(0);
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_crypto_erase()");
+ return l_success;
+}
+
+
+errlHndl_t notifyNvdimmProtectionChange(Target* i_target,
+ const nvdimm_protection_t i_state)
+{
+ TRACFCOMP( g_trac_nvdimm, ENTER_MRK
+ "notifyNvdimmProtectionChange: Target huid 0x%.8X, state %d",
+ get_huid(i_target), i_state);
+
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ // Get the type of target passed in
+ // It could be proc_type for OCC state
+ // Or dimm_type for ARM/ERROR state
+ ATTR_TYPE_type l_type = i_target->getAttr<ATTR_TYPE>();
+ assert((l_type == TYPE_PROC)||(l_type == TYPE_DIMM),
+ "notifyNvdimmProtectionChange invalid target type");
+
+ // Load the nvdimm list
+ TargetHandleList l_nvdimmTargetList;
+ Target* l_proc = nullptr;
+ if (l_type == TYPE_PROC)
+ {
+ // Get the nvdimms under this proc target
+ l_nvdimmTargetList = getProcNVDIMMs(i_target);
+
+ // Only send command if the processor has an NVDIMM under it
+ if (l_nvdimmTargetList.empty())
+ {
+ TRACFCOMP( g_trac_nvdimm, "notifyNvdimmProtectionChange: "
+ "No NVDIMM found under processor 0x%.8X",
+ get_huid(i_target));
+ break;
+ }
+
+ // The proc target is the passed-in target
+ l_proc = i_target;
+ }
+ else
+ {
+ // Only a list of one but keep consistent with proc type
+ l_nvdimmTargetList.push_back(i_target);
+
+ // Find the proc target from nvdimm target passed in
+ TargetHandleList l_procList;
+ getParentAffinityTargets(l_procList,
+ i_target,
+ CLASS_CHIP,
+ TYPE_PROC,
+ UTIL_FILTER_ALL);
+ assert(l_procList.size() == 1, "notifyNvdimmProtectionChange:"
+ "getParentAffinityTargets size != 1");
+ l_proc = l_procList[0];
+ }
+
+
+ // Update the nvdimm status attributes
+ for (auto const l_nvdimm : l_nvdimmTargetList)
+ {
+ // Get the armed status attr and update it
+ ATTR_NVDIMM_ARMED_type l_armed_state = {};
+ l_armed_state = l_nvdimm->getAttr<ATTR_NVDIMM_ARMED>();
+
+ // If we change the armed state, need to tell FSP
+ bool l_armed_change = false;
+ bool l_set_encryption = false;
+ bool l_clr_encryption = false;
+ bool l_sev_started = false;
+ bool l_sev_completed = false;
+
+ switch (i_state)
+ {
+ case NVDIMM_ARMED:
+ l_armed_state.armed = 1;
+ l_armed_change = true;
+ break;
+ case NVDIMM_DISARMED:
+ l_armed_state.armed = 0;
+ l_armed_change = true;
+ break;
+ case OCC_ACTIVE:
+ l_armed_state.occ_active = 1;
+ break;
+ case OCC_INACTIVE:
+ l_armed_state.occ_active = 0;
+ break;
+ case NVDIMM_FATAL_HW_ERROR:
+ l_armed_state.fatal_error_detected = 1;
+ break;
+ case NVDIMM_RISKY_HW_ERROR:
+ l_armed_state.risky_error_detected = 1;
+ break;
+ case NVDIMM_ENCRYPTION_ERROR:
+ l_armed_state.encryption_error_detected = 1;
+ break;
+ case ENCRYPTION_ENABLED:
+ l_set_encryption = true;
+ break;
+ case ENCRYPTION_DISABLED:
+ l_clr_encryption = true;
+ break;
+ case ERASE_VERIFY_STARTED:
+ l_sev_started = true;
+ break;
+ case ERASE_VERIFY_COMPLETED:
+ l_sev_completed = true;
+ break;
+ case SEND_NV_STATUS:
+ // no action, just send status
+ break;
+ }
+
+ // Set the attribute and send it to the FSP if needed
+ l_nvdimm->setAttr<ATTR_NVDIMM_ARMED>(l_armed_state);
+ if( l_armed_change )
+ {
+ send_ATTR_NVDIMM_ARMED( l_nvdimm, l_armed_state );
+ }
+
+ // Get the nv status flag attr and update it
+ ATTR_NV_STATUS_FLAG_type l_nv_status =
+ l_nvdimm->getAttr<ATTR_NV_STATUS_FLAG>();
+
+ // Clear bit 0 if protected nv state
+ if (l_armed_state.armed &&
+ l_armed_state.occ_active &&
+ !l_armed_state.fatal_error_detected)
+ {
+ l_nv_status &= NV_STATUS_UNPROTECTED_CLR;
+ }
+
+ // Set bit 0 if unprotected nv state
+ else
+ {
+ l_nv_status |= NV_STATUS_UNPROTECTED_SET;
+ }
+
+ // Set bit 4 if encryption enabled
+ if (l_set_encryption)
+ {
+ l_nv_status |= NV_STATUS_ENCRYPTION_SET;
+ }
+
+ // Clear bit 4 if encryption disabled
+ if (l_clr_encryption)
+ {
+ l_nv_status &= NV_STATUS_ENCRYPTION_CLR;
+ }
+
+ // Clear bit 5 if secure erase verify started
+ if (l_sev_started)
+ {
+ l_nv_status &= NV_STATUS_ERASE_VERIFY_CLR;
+ }
+
+ // Set bit 5 if secure erase verify comlpleted
+ if (l_sev_completed)
+ {
+ l_nv_status |= NV_STATUS_ERASE_VERIFY_SET;
+ }
+
+ // Set bit 6 if risky error
+ if (l_armed_state.risky_error_detected)
+ {
+ l_nv_status |= NV_STATUS_POSSIBLY_UNPROTECTED_SET;
+ }
+
+ l_nvdimm->setAttr<ATTR_NV_STATUS_FLAG>(l_nv_status);
+
+ } // for nvdimm list
+
+ // Generate combined nvdimm status for the proc
+ // Bit 2 of NV_STATUS_FLAG is 'Device contents are persisted'
+ // and must be ANDed for all nvdimms
+ // the rest of the bits are ORed for all nvdimms
+ ATTR_NV_STATUS_FLAG_type l_combined_or = 0x00;
+ ATTR_NV_STATUS_FLAG_type l_combined_and = 0xFF;
+ ATTR_NV_STATUS_FLAG_type l_combined_status = 0x00;
+ l_nvdimmTargetList = getProcNVDIMMs(l_proc);
+ for (auto const l_nvdimm : l_nvdimmTargetList)
+ {
+ l_combined_or |= l_nvdimm->getAttr<ATTR_NV_STATUS_FLAG>();
+ l_combined_and &= l_nvdimm->getAttr<ATTR_NV_STATUS_FLAG>();
+ }
+
+ // Bit 2 of NV_STATUS_FLAG is 'Device contents are persisted'
+ l_combined_status =
+ (l_combined_or & NV_STATUS_OR_MASK) |
+ (l_combined_and & NV_STATUS_AND_MASK);
+
+ TRACFCOMP( g_trac_nvdimm,
+ "notifyNvdimmProtectionChange: NV_STATUS for proc %X 0x%.02X",
+ get_huid(l_proc), l_combined_status);
+
+#ifdef __HOSTBOOT_RUNTIME
+
+ // Send combined status notification
+ // Get the Proc Chip Id
+ TARGETING::rtChipId_t l_chipId = 0;
+
+ l_err = TARGETING::getRtTarget(l_proc, l_chipId);
+ if(l_err)
+ {
+ TRACFCOMP( g_trac_nvdimm,
+ ERR_MRK"notifyNvdimmProtectionChange: getRtTarget ERROR" );
+ break;
+ }
+
+ // Check for valid interface
+ if ((nullptr == g_hostInterfaces) ||
+ (nullptr == g_hostInterfaces->firmware_request))
+ {
+ TRACFCOMP( g_trac_nvdimm, ERR_MRK"notifyNvdimmProtectionChange: "
+ "Hypervisor firmware_request interface not linked");
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid NOTIFY_NVDIMM_PROTECTION_CHG
+ * @reasoncode NVDIMM_NULL_FIRMWARE_REQUEST_PTR
+ * @userdata1 HUID of processor target
+ * @userdata2[0:31] NV_STATUS to PHYP
+ * @userdata2[32:63] In state change
+ * @devdesc Unable to inform PHYP of NVDIMM protection
+ * @custdesc Internal firmware error
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NOTIFY_NVDIMM_PROTECTION_CHG,
+ NVDIMM_NULL_FIRMWARE_REQUEST_PTR,
+ get_huid(l_proc),
+ TWO_UINT32_TO_UINT64(
+ l_combined_status,
+ i_state)
+ );
+
+ l_err->addProcedureCallout(HWAS::EPUB_PRC_PHYP_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ break;
+ }
+
+ TRACFCOMP( g_trac_nvdimm,
+ "notifyNvdimmProtectionChange: 0x%.8X "
+ "NV_STATUS to HYP: 0x%02X",
+ get_huid(l_proc),
+ l_combined_status );
+
+ // Create the firmware_request request struct to send data
+ hostInterfaces::hbrt_fw_msg l_req_fw_msg;
+ memset(&l_req_fw_msg, 0, sizeof(l_req_fw_msg)); // clear it all
+
+ // actual msg size (one type of hbrt_fw_msg)
+ uint64_t l_req_fw_msg_size = hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(l_req_fw_msg.nvdimm_protection_state);
+
+ // Populate the firmware_request request struct with given data
+ l_req_fw_msg.io_type =
+ hostInterfaces::HBRT_FW_MSG_TYPE_NVDIMM_PROTECTION;
+ l_req_fw_msg.nvdimm_protection_state.i_procId = l_chipId;
+ l_req_fw_msg.nvdimm_protection_state.i_state = l_combined_status;
+
+ // Create the firmware_request response struct to receive data
+ hostInterfaces::hbrt_fw_msg l_resp_fw_msg;
+ uint64_t l_resp_fw_msg_size = sizeof(l_resp_fw_msg);
+ memset(&l_resp_fw_msg, 0, l_resp_fw_msg_size);
+
+ // Make the firmware_request call
+ l_err = firmware_request_helper(l_req_fw_msg_size,
+ &l_req_fw_msg,
+ &l_resp_fw_msg_size,
+ &l_resp_fw_msg);
+#endif
+
+ } while (0);
+
+ TRACFCOMP( g_trac_nvdimm,
+ EXIT_MRK "notifyNvdimmProtectionChange(%.8X, %d) - ERRL %.8X:%.4X",
+ get_huid(i_target), i_state,
+ ERRL_GETEID_SAFE(l_err), ERRL_GETRC_SAFE(l_err) );
+
+ return l_err;
+}
+
+
+/*
+ * @brief Get operational unit operation timeout
+ */
+errlHndl_t getOperOpsTimeout(TARGETING::Target* i_nvdimm,
+ uint16_t& o_timeout)
+{
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ // Get timeout lsb
+ uint8_t l_lsb = 0;
+ l_err = nvdimmReadReg(i_nvdimm,
+ OPERATIONAL_UNIT_OPS_TIMEOUT0,
+ l_lsb);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "getOperOpsTimeout() nvdimm[%X] error reading 0x%X",
+ get_huid(i_nvdimm), OPERATIONAL_UNIT_OPS_TIMEOUT0);
+ break;
+ }
+
+ // Get timeout msb
+ uint8_t l_msb = 0;
+ l_err = nvdimmReadReg(i_nvdimm,
+ OPERATIONAL_UNIT_OPS_TIMEOUT1,
+ l_msb);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "getOperOpsTimeout() nvdimm[%X] error reading 0x%X",
+ get_huid(i_nvdimm), OPERATIONAL_UNIT_OPS_TIMEOUT1);
+ break;
+ }
+
+ // Bit 7 of the MSB indicates whether the time should
+ // be interpreted in seconds or milliseconds
+ // 0 = millisecond
+ // 1 = second
+ if (l_msb < MSBIT_SET_MASK)
+ {
+ o_timeout = l_msb;
+ o_timeout <<= 8;
+ o_timeout += l_lsb;
+ o_timeout = o_timeout / MS_PER_SEC;
+ }
+ else
+ {
+ l_msb = l_msb & MSBIT_CLR_MASK;
+ o_timeout = l_msb;
+ o_timeout <<= 8;
+ o_timeout += l_lsb;
+ }
+
+ } while(0);
+
+ return l_err;
+}
+
+
+/*
+ * @brief Wait for operational unit operation to complete
+ */
+errlHndl_t waitOperOpsComplete(TARGETING::Target* i_nvdimm, uint8_t i_cmd)
+{
+ errlHndl_t l_err = nullptr;
+ bool l_complete = false;
+ uint16_t l_timeout = 0;
+ uint8_t l_status = 0;
+
+ // Get the timeout
+ l_err = getOperOpsTimeout(i_nvdimm, l_timeout);
+
+ do
+ {
+ // Exit if l_timeout invalid
+ if (l_err)
+ {
+ break;
+ }
+
+ // Delay before reading status
+ nanosleep( OPERATION_SLEEP_SECONDS, 0 );
+ if (OPERATION_SLEEP_SECONDS > l_timeout)
+ {
+ l_timeout = 0;
+ }
+ else
+ {
+ l_timeout = l_timeout - OPERATION_SLEEP_SECONDS;
+ }
+
+ // Get timeout cmd status 1
+ l_err = nvdimmReadReg(i_nvdimm,
+ NVDIMM_CMD_STATUS1,
+ l_status);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "waitOperOpsComplete() nvdimm[%X] error reading 0x%X",
+ get_huid(i_nvdimm), NVDIMM_CMD_STATUS1);
+ break;
+ }
+
+ if (l_status >= 0x01)
+ {
+ // If bit 1 is set that means the command is in progress
+ // Wait for it to become 0
+ }
+ else
+ {
+ l_complete = true;
+ break;
+ }
+
+ } while(l_timeout > 0);
+
+ // Timed out
+ if (!l_err && (l_complete == false) )
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "waitOperOpsComplete() nvdimm[%X] "
+ "Timeout waiting for operation 0x%X to complete, "
+ "NVDIMM_CMD_STATUS1 0x%X",
+ get_huid(i_nvdimm), i_cmd, l_status);
+
+ // Get the timeout value again
+ getOperOpsTimeout(i_nvdimm, l_timeout);
+
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_VENDOR_LOG_TIMEOUT
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_WAIT_OPER_OPS_COMPLETE
+ *@userdata1[0:31] NVDIMM HUID
+ *@userdata1[32:63] OPERATIONAL_UNIT_OPS_CMD
+ *@userdata2[0:31] NVDIMM_CMD_STATUS1
+ *@userdata2[32:63] OPERATIONAL_UNIT_OPS_TIMEOUT
+ *@devdesc NVDIMM timeout reading vendor log
+ *@custdesc NVDIMM logging error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_WAIT_OPER_OPS_COMPLETE,
+ NVDIMM_VENDOR_LOG_TIMEOUT,
+ TWO_UINT32_TO_UINT64(
+ get_huid(i_nvdimm),
+ i_cmd
+ ),
+ TWO_UINT32_TO_UINT64(
+ l_status,
+ l_timeout
+ ),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ l_err->addPartCallout( i_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ }
+
+ return l_err;
+}
+
+
+/*
+ * @brief Get the vendor log unit
+ */
+errlHndl_t getLogPerUnit(TARGETING::Target* i_nvdimm,
+ uint16_t i_unitId,
+ std::vector<uint8_t>& o_unitData)
+{
+ // 3a) write OPERATIONAL_UNIT_ID0 and OPERATIONAL_UNIT_ID1 with unit_id
+ // 3b) set OPERATIONAL_UNIT_OPS_CMD to GET_OPERATIONAL_UNIT
+ // 3c) wait for NVDIMM_CMD_STATUS1 to return 0
+ // 3d) for (block_id = 0;
+ // block_id < VENDOR_LOG_UNIT_SIZE/BLOCKSIZE;
+ // block_id++)
+ // 3da) Write block_id to BLOCK_ID
+ // 3db) Read TYPED_BLOCK_DATA_BYTE0 to TYPED_BLOCK_DATA_BYTE31
+ // 3dc) Save data to buffer
+
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ // 3a)
+ // Write the unit LSB
+ l_err = nvdimmWriteReg(i_nvdimm,
+ OPERATIONAL_UNIT_ID0,
+ i_unitId & 0x00FF);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "getLogPerUnit() nvdimm[%X] error writing reg 0x%X to 0x%X",
+ get_huid(i_nvdimm), OPERATIONAL_UNIT_ID0, (i_unitId & 0x00FF));
+ break;
+ }
+
+ // Write the unit MSB
+ l_err = nvdimmWriteReg(i_nvdimm,
+ OPERATIONAL_UNIT_ID1,
+ i_unitId >> 8);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "getLogPerUnit() nvdimm[%X] error writing reg 0x%X to 0x%X",
+ get_huid(i_nvdimm), OPERATIONAL_UNIT_ID0, (i_unitId >> 8) );
+ break;
+ }
+
+ // 3b)
+ // Write the cmd
+ l_err = nvdimmWriteReg(i_nvdimm,
+ OPERATIONAL_UNIT_OPS_CMD,
+ GET_OPERATIONAL_UNIT);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "getLogPerUnit() nvdimm[%X] error writing reg 0x%X to 0x%X",
+ get_huid(i_nvdimm), OPERATIONAL_UNIT_OPS_CMD,
+ GET_OPERATIONAL_UNIT );
+ break;
+ }
+
+ // 3c
+ l_err = waitOperOpsComplete(i_nvdimm, GET_OPERATIONAL_UNIT);
+ if (l_err)
+ {
+ break;
+ }
+
+ // 3d
+ for (uint8_t l_blockId = 0;
+ l_blockId < (VENDOR_LOG_UNIT_SIZE / VENDOR_LOG_BLOCK_SIZE);
+ l_blockId++)
+ {
+ // 3da
+ // Write the block id
+ l_err = nvdimmWriteReg(i_nvdimm,
+ BLOCK_ID,
+ l_blockId);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "getLogPerUnit() nvdimm[%X] error writing reg 0x%X to 0x%X",
+ get_huid(i_nvdimm), BLOCK_ID, l_blockId );
+ break;
+ }
+
+ // 3db
+ // Read all the block data
+ for (uint16_t l_byteId = TYPED_BLOCK_DATA_BYTE0;
+ l_byteId < (TYPED_BLOCK_DATA_BYTE0 + VENDOR_BLOCK_DATA_BYTES);
+ l_byteId++)
+ {
+ uint8_t l_data = 0;
+ l_err = nvdimmReadReg(i_nvdimm,
+ l_byteId,
+ l_data);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "getLogPerUnit() nvdimm[%X] error reading 0x%X",
+ get_huid(i_nvdimm), l_byteId);
+ break;
+ }
+
+ // 3dc
+ o_unitData.push_back(l_data);
+ } // for byteId
+
+ if (l_err)
+ {
+ break;
+ }
+ } // for blockId
+
+ } while(0);
+
+ return l_err;
+}
+
+
+/*
+ * @brief Calculate CRC
+ */
+uint16_t crc16(const uint8_t * i_data, int i_size)
+{
+ // From JEDEC JESD245B.01 document
+ // https://www.jedec.org/standards-documents/docs/jesd245a
+ int i, crc;
+ crc = 0;
+ while (--i_size >= 0)
+ {
+ crc = crc ^ (int)*i_data++ << 8;
+ for (i = 0; i < 8; ++i)
+ {
+ if (crc & 0x8000)
+ {
+ crc = crc << 1 ^ 0x1021;
+ }
+ else
+ {
+ crc = crc << 1;
+ }
+ }
+ }
+ return (crc & 0xFFFF);
+}
+
+
+/*
+ * @brief Get operational unit crc
+ */
+errlHndl_t getOperUnitCrc(TARGETING::Target* i_nvdimm, uint16_t& o_crc)
+{
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ // Get crc lsb
+ uint8_t l_lsb = 0;
+ l_err = nvdimmReadReg(i_nvdimm,
+ OPERATIONAL_UNIT_CRC0,
+ l_lsb);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "getOperUnitCrc() nvdimm[%X] error reading 0x%X",
+ get_huid(i_nvdimm), OPERATIONAL_UNIT_CRC0);
+ break;
+ }
+
+ // Get crc msb
+ uint8_t l_msb = 0;
+ l_err = nvdimmReadReg(i_nvdimm,
+ OPERATIONAL_UNIT_CRC1,
+ l_msb);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "getOperUnitCrc() nvdimm[%X] error reading 0x%X",
+ get_huid(i_nvdimm), OPERATIONAL_UNIT_CRC1);
+ break;
+ }
+
+ o_crc = l_msb;
+ o_crc <<= 8;
+ o_crc += l_lsb;
+
+ } while(0);
+
+ return l_err;
+}
+
+
+/*
+ * @brief Compare host and nvdimm checksum
+ */
+errlHndl_t compareCksum(TARGETING::Target* i_nvdimm,
+ std::vector<uint8_t>& i_unitData)
+{
+ // 3e) Compare checksum for unit retrieved
+ // 3ea) Write GENERATE_OPERATIONAL_UNIT_CKSUM
+ // to OPERATIONAL_UNIT_OPS_CMD
+ // 3eb) wait for NVDIMM_CMD_STATUS1 to return 0
+ // 3ec) Read OPERATIONAL_UNIT_CRC1(MSB) and OPERATIONAL_UNIT_CRC0(LSB)
+ // 3ed) Calculate host checksum
+ // 3ee) return true if 3ec) == 3ed)
+
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ // 3ea)
+ // Command the nvdimm to calculate the CRC on the unit
+ l_err = nvdimmWriteReg(i_nvdimm,
+ OPERATIONAL_UNIT_OPS_CMD,
+ GENERATE_OPERATIONAL_UNIT_CKSUM);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "compareCksum() nvdimm[%X] error writing reg 0x%X to 0x%X",
+ get_huid(i_nvdimm), OPERATIONAL_UNIT_OPS_CMD,
+ GENERATE_OPERATIONAL_UNIT_CKSUM );
+ break;
+ }
+
+ // 3eb)
+ // Wait for the command to finish
+ l_err = waitOperOpsComplete(i_nvdimm,
+ GENERATE_OPERATIONAL_UNIT_CKSUM);
+ if (l_err)
+ {
+ break;
+ }
+
+ // 3ec)
+ // Read the HW CRC MSB + LSB
+ uint16_t l_nvdimmCrc = 0;
+ l_err = getOperUnitCrc(i_nvdimm, l_nvdimmCrc);
+ if (l_err)
+ {
+ break;
+ }
+
+ // 3ed)
+ // Calculate the host checksum
+ uint8_t* l_hostData = reinterpret_cast<uint8_t*>(i_unitData.data());
+ uint16_t l_hostCrc = crc16(l_hostData, i_unitData.size());
+
+ // 3ee)
+ if (l_hostCrc != l_nvdimmCrc)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "compareCksum() nvdimm[%X] compare cksum failed "
+ "hostCrc 0x%X nvdimmCrc 0x%X",
+ get_huid(i_nvdimm), l_hostCrc, l_nvdimmCrc);
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_VENDOR_LOG_CKSUM_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_COMPARE_CKSUM
+ *@userdata1 NVDIMM HUID
+ *@userdata2[0:31] HOST CRC
+ *@userdata2[32:63] NVDIMM CRC
+ *@devdesc NVDIMM vendor log checksum failed
+ *@custdesc NVDIMM logging error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_COMPARE_CKSUM,
+ NVDIMM_VENDOR_LOG_CKSUM_FAILED,
+ get_huid(i_nvdimm),
+ TWO_UINT32_TO_UINT64(
+ l_hostCrc,
+ l_nvdimmCrc),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ l_err->addPartCallout( i_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ }
+
+ } while(0);
+
+ return l_err;
+}
+
+
+/*
+ * @brief Add vendor log data to FFDC
+ * Added to all NVDIMM HW errors
+ */
+void nvdimmAddVendorLog( TARGETING::Target* i_nvdimm, errlHndl_t& io_err )
+{
+ TRACFCOMP( g_trac_nvdimm, ENTER_MRK
+ "nvdimmAddVendorLog: Target huid 0x%.8X",
+ get_huid(i_nvdimm));
+
+ /*
+ 1) Read VENDOR_LOG_PAGE_SIZE. Multiply the return value with BLOCKSIZE
+ to get the total page size (LOG_PAGE_SIZE)
+ 2) Set TYPED_BLOCK_DATA to VENDOR_DATA_TYPE
+ 3) for (unit_id = 0;
+ unit_id < LOG_PAGE_LENGTH/VENDOR_LOG_UNIT_SIZE;
+ unit_id++)
+ 3a) write OPERATIONAL_UNIT_ID0 and OPERATIONAL_UNIT_ID1 with unit_id
+ 3b) set OPERATIONAL_UNIT_OPS_CMD to GET_OPERATIONAL_UNIT
+ 3c) wait for NVDIMM_CMD_STATUS1 to return 0
+ 3d) for (block_id = 0;
+ block_id < VENDOR_LOG_UNIT_SIZE/BLOCKSIZE;
+ block_id++)
+ 3da) Write block_id to BLOCK_ID
+ 3db) Read TYPED_BLOCK_DATA_BYTE0 to TYPED_BLOCK_DATA_BYTE31
+ 3dc) Save data to buffer
+ 3e) Compare checksum for unit retrieved
+ 3ea) Write GENERATE_OPERATIONAL_UNIT_CKSUM
+ to OPERATIONAL_UNIT_OPS_CMD
+ 3eb) wait for NVDIMM_CMD_STATUS1 to return 0
+ 3ec) Read OPERATIONAL_UNIT_CRC1(MSB) and OPERATIONAL_UNIT_CRC0(LSB)
+ 3ed) Calculate host checksum
+ 3ee) return true if 3ec) == 3ed)
+ */
+
+ errlHndl_t l_err = nullptr;
+
+ // Get the vendor log attribute
+ auto l_vendorLog = i_nvdimm->getAttr<ATTR_NVDIMM_READING_VENDOR_LOG>();
+
+ do
+ {
+ // If attr is set we are already in the process of
+ // reading the vendor log, exit
+ if (l_vendorLog)
+ {
+ break;
+ }
+
+ if (io_err == nullptr)
+ {
+ // A nullptr was given when it should not have been. Emit a trace
+ // and break out of this function.
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmAddVendorLog() io_err was nullptr!! Skip adding additional FFDC.");
+ break;
+ }
+
+
+ // Set the vendor log attribute so we don't recursively
+ // execute the nvdimmAddVendorLog function
+ l_vendorLog = 0x1;
+ i_nvdimm->setAttr<ATTR_NVDIMM_READING_VENDOR_LOG>(l_vendorLog);
+
+ uint8_t l_readData = 0;
+ std::vector<uint8_t> l_fullData;
+
+ // Step 1
+ l_err = nvdimmReadReg(i_nvdimm,
+ VENDOR_LOG_PAGE_SIZE,
+ l_readData);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmAddVendorLog() nvdimm[%X] error reading 0x%X",
+ get_huid(i_nvdimm), VENDOR_LOG_PAGE_SIZE);
+ break;
+ }
+
+ size_t l_logPgeLength = l_readData * VENDOR_LOG_BLOCK_SIZE;
+
+ // Step 2
+ // Some weird bug here - switching directly to VENDOR_DATA_TYPE
+ // would not work. Need to switch to something else first
+ l_err = nvdimmWriteReg(i_nvdimm,
+ TYPED_BLOCK_DATA,
+ FIRMWARE_IMAGE_DATA);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmAddVendorLog() nvdimm[%X] error writing 0x%X to 0x%X",
+ get_huid(i_nvdimm),TYPED_BLOCK_DATA, FIRMWARE_IMAGE_DATA );
+ break;
+ }
+
+ l_err = nvdimmWriteReg(i_nvdimm,
+ TYPED_BLOCK_DATA,
+ VENDOR_DATA_TYPE);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmAddVendorLog() nvdimm[%X] error writing 0x%X to 0x%X",
+ get_huid(i_nvdimm),TYPED_BLOCK_DATA, VENDOR_DATA_TYPE );
+ break;
+ }
+
+ // Step 3
+ // Loop through all the log units.
+ for (uint16_t l_unitId = 0;
+ l_unitId < (l_logPgeLength / VENDOR_LOG_UNIT_SIZE);
+ l_unitId++)
+ {
+ // Step 3a) - 3dc)
+ // Get one log unit
+ std::vector<uint8_t> l_unitData;
+ l_err = getLogPerUnit(i_nvdimm, l_unitId, l_unitData);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Step 3e) - 3ee)
+ // Check the checksum for the entire log unit
+ l_err = compareCksum(i_nvdimm, l_unitData);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Append to full data
+ l_fullData.insert(l_fullData.end(),
+ l_unitData.begin(),
+ l_unitData.end());
+ }
+
+ if (l_err)
+ {
+ break;
+ }
+
+ // Find first NUL char in the vendor log data
+ bool l_foundNull = false;
+ uint32_t l_idx = 0;
+ for (l_idx = 0; l_idx < l_fullData.size(); l_idx++)
+ {
+ if (l_fullData[l_idx] == 0x00)
+ {
+ l_foundNull = true;
+ break;
+ }
+ }
+
+ // If NULL char not found
+ // then this is the old log format
+ if (l_foundNull == false)
+ {
+ // Add NUL terminator to ascii data
+ l_fullData.push_back(0x00);
+ }
+ // Else new log format
+ else
+ {
+ // If the next char is not NULL
+ // then the log has wrapped
+ // Re-arrange the data in chronological order
+ if (l_fullData[l_idx + 1] != 0x00)
+ {
+ // Save the data after the NULL char
+ // This is the start of the log
+ std::vector<uint8_t> l_tmpData;
+ l_tmpData.insert(l_tmpData.begin(),
+ l_fullData.begin() + l_idx + 1,
+ l_fullData.end());
+
+ // Erase this data from the vector
+ l_fullData.erase(l_fullData.begin() + l_idx + 1,
+ l_fullData.end());
+
+ // Place the saved data at the front
+ l_fullData.insert(l_fullData.begin(),
+ l_tmpData.begin(),
+ l_tmpData.end());
+ }
+ // Else log has not wrapped
+ else
+ {
+ // Erase the data at the end of the vector
+ l_fullData.erase(l_fullData.begin() + l_idx + 1,
+ l_fullData.end());
+ }
+ }
+
+ // Add vendor data to error log as string
+ const char* l_fullChar = reinterpret_cast<char*>(l_fullData.data());
+ ERRORLOG::ErrlUserDetailsStringSet l_stringSet;
+ l_stringSet.add("Vendor Log", l_fullChar);
+ l_stringSet.addToLog(io_err);
+
+ // Change back to default
+ l_err = nvdimmWriteReg(i_nvdimm,
+ TYPED_BLOCK_DATA,
+ VENDOR_DEFAULT);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmAddVendorLog() nvdimm[%X] error writing 0x%X to 0x%X",
+ get_huid(i_nvdimm),TYPED_BLOCK_DATA, VENDOR_DEFAULT );
+ break;
+ }
+
+ } while(0);
+
+ if (l_err)
+ {
+ // FFDC error, set as informational
+ l_err->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ // Clear the vendor log attribute before exiting
+ l_vendorLog = 0x0;
+ i_nvdimm->setAttr<ATTR_NVDIMM_READING_VENDOR_LOG>(l_vendorLog);
+
+ TRACFCOMP( g_trac_nvdimm, EXIT_MRK
+ "nvdimmAddVendorLog: Target huid 0x%.8X",
+ get_huid(i_nvdimm));
+}
+
+
+/*
+ * @brief Add NVDIMM Update regs to FFDC for errors encountered
+ * during NVDIMM update process
+ */
+void nvdimmAddUpdateRegs( TARGETING::Target* i_nvdimm, errlHndl_t& io_err )
+{
+ errlHndl_t l_err = nullptr;
+
+ do {
+
+ if (io_err == nullptr)
+ {
+ // A nullptr was given when it should not have been. Emit a trace
+ // and break out of this function.
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmAddUpdateRegs() io_err was nullptr!! Skip adding additional FFDC.");
+ break;
+ }
+
+ ERRORLOG::ErrlUserDetailsLogRegister l_regUD(i_nvdimm);
+ const uint32_t l_regList[] = {
+ NVDIMM_READY,
+ FIRMWARE_OPS_STATUS,
+ NVDIMM_CMD_STATUS0,
+ FIRMWARE_OPS_TIMEOUT0,
+ FIRMWARE_OPS_TIMEOUT1,
+ FW_REGION_CRC0,
+ FW_REGION_CRC1,
+ MODULE_HEALTH,
+ MODULE_HEALTH_STATUS0,
+ MODULE_HEALTH_STATUS1,
+ ERROR_THRESHOLD_STATUS,
+ ENCRYPTION_CONFIG_STATUS,
+ FW_SLOT_INFO,
+ SLOT0_ES_FWREV0,
+ SLOT0_ES_FWREV1,
+ SLOT1_ES_FWREV0,
+ SLOT1_ES_FWREV1,
+ SLOT1_SUBFWREV,
+ CSAVE_INFO,
+ CSAVE_FAIL_INFO1,
+ RESTORE_STATUS,
+ RESTORE_FAIL_INFO,
+ };
+ uint8_t l_readData = 0;
+
+ for (auto l_reg : l_regList)
+ {
+ l_err = nvdimmReadReg(i_nvdimm,
+ l_reg,
+ l_readData);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmAddUpdateRegs() nvdimm[%X] error reading 0x%X",
+ get_huid(i_nvdimm), l_reg);
+
+ // Don't commit, just delete the error and continue
+ delete l_err;
+ l_err = nullptr;
+ continue;
+ }
+
+ l_regUD.addDataBuffer(&l_readData,
+ sizeof(l_readData),
+ DEVICE_NVDIMM_ADDRESS(l_reg));
+ }
+
+ l_regUD.addToLog(io_err);
+
+ } while(0);
+}
+
+
+/*
+ * @brief Add Page 4 regs to FFDC
+ * Added to all NVDIMM HW errors
+ */
+void nvdimmAddPage4Regs( TARGETING::Target* i_nvdimm, errlHndl_t& io_err )
+{
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ if (io_err == nullptr)
+ {
+ // A nullptr was given when it should not have been. Emit a trace
+ // and break out of this function.
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmAddPage4Regs() io_err was nullptr!! Skip adding additional FFDC.");
+ break;
+ }
+
+
+ // Get the page4 attribute, if set we are already
+ // reading the page4 regs, exit
+ auto l_page4 = i_nvdimm->getAttr<ATTR_NVDIMM_READING_PAGE4>();
+ if (l_page4)
+ {
+ break;
+ }
+
+ // Set the page4 attribute so we don't recursively
+ // execute the nvdimmAddPage4Regs function
+ l_page4 = 0x1;
+ i_nvdimm->setAttr<ATTR_NVDIMM_READING_PAGE4>(l_page4);
+
+ ERRORLOG::ErrlUserDetailsLogRegister l_regUD(i_nvdimm);
+ uint32_t l_regList[] = {
+ PANIC_CNT,
+ PARITY_ERROR_COUNT,
+ FLASH_ERROR_COUNT0,
+ FLASH_ERROR_COUNT1,
+ FLASH_ERROR_COUNT2,
+ FLASH_BAD_BLOCK_COUNT0,
+ FLASH_BAD_BLOCK_COUNT1,
+ SCAP_STATUS,
+ STATUS_EVENT_INT_INFO1,
+ STATUS_EVENT_INT_INFO2
+ };
+ uint8_t l_readData = 0;
+
+ for (auto l_reg : l_regList)
+ {
+ l_err = nvdimmReadReg(i_nvdimm,
+ l_reg,
+ l_readData);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmAddPage4Regs() nvdimm[%X] error reading 0x%X",
+ get_huid(i_nvdimm), l_reg);
+
+ // Don't commit, just delete the error and continue
+ delete l_err;
+ l_err = nullptr;
+ continue;
+ }
+
+ l_regUD.addDataBuffer(&l_readData,
+ sizeof(l_readData),
+ DEVICE_NVDIMM_ADDRESS(l_reg));
+ }
+
+ l_regUD.addToLog(io_err);
+
+ // Clear the page4 attribute before exiting
+ l_page4 = 0x0;
+ i_nvdimm->setAttr<ATTR_NVDIMM_READING_PAGE4>(l_page4);
+
+ } while(0);
+}
+
+/*
+ * @brief Utility function to send the value of
+ * ATTR_NVDIMM_ARMED to the FSP
+ */
+void send_ATTR_NVDIMM_ARMED( Target* i_nvdimm,
+ ATTR_NVDIMM_ARMED_type& i_val )
+{
+#ifdef __HOSTBOOT_RUNTIME
+ errlHndl_t l_err = nullptr;
+
+ // Send attr to HWSV if at runtime
+ AttributeTank::Attribute l_attr = {};
+ if( !makeAttribute<ATTR_NVDIMM_ARMED>
+ (i_nvdimm, l_attr) )
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"send_ATTR_NVDIMM_ARMED() Could not create Attribute");
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_CANNOT_MAKE_ATTRIBUTE
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid SEND_ATTR_NVDIMM_ARMED
+ *@devdesc Couldn't create an Attribute to send the data
+ * to the FSP
+ *@custdesc NVDIMM encryption error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ SEND_ATTR_NVDIMM_ARMED,
+ NVDIMM_CANNOT_MAKE_ATTRIBUTE,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ else
+ {
+ std::vector<TARGETING::AttributeTank::Attribute> l_attrList;
+ l_attrList.push_back(l_attr);
+ l_err = sendAttributes( l_attrList );
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"send_ATTR_NVDIMM_ARMED() Error sending ATTR_NVDIMM_ARMED down to FSP");
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ }
+#endif //__HOSTBOOT_RUNTIME
+}
+
+/**
+ * @brief Grab the current slot that NVDIMM code is running
+ */
+errlHndl_t nvdimmGetRunningSlot(TARGETING::Target *i_nvdimm, uint8_t & o_slot)
+{
+ errlHndl_t l_err = nullptr;
+ uint8_t l_data = 0;
+ o_slot = 0; //default to slot 0
+
+ // Check if the firmware slot is 0
+ l_err = nvdimmReadReg ( i_nvdimm, FW_SLOT_INFO, l_data);
+ if (l_err)
+ {
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmGetRunningSlot() nvdimm[%X], failed to read slot info",
+ get_huid(i_nvdimm));
+ }
+ else
+ {
+ // Bits 7-4 = RUNNING_FW_SLOT - slot number of running firmware
+ o_slot = (l_data & RUNNING_FW_SLOT) >> 4;
+ }
+ return l_err;
+}
+
+/**
+ * @brief This function polls the command status register for arm completion
+ *
+ * @param[in] i_nvdimm - nvdimm target with NV controller
+ *
+ * @param[out] o_poll - total polled time in ms
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t nvdimmPollArmDone(Target* i_nvdimm,
+ uint32_t &o_poll)
+{
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmPollArmDone() nvdimm[%X]", get_huid(i_nvdimm) );
+
+ errlHndl_t l_err = nullptr;
+
+ l_err = nvdimmPollStatus ( i_nvdimm, ARM, o_poll);
+
+ TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmPollArmDone() nvdimm[%X]",
+ get_huid(i_nvdimm));
+
+ return l_err;
+}
+
+/**
+ * @brief This function checks the arm status register to make sure
+ * the trigger has been armed to ddr_reset_n
+ *
+ * @param[in] i_nvdimm - nvdimm target with NV controller
+ * @param[in] i_arm_timeout - nvdimm local timeout status
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t nvdimmCheckArmSuccess(Target *i_nvdimm, bool i_arm_timeout)
+{
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmCheckArmSuccess() nvdimm[%X]",
+ get_huid(i_nvdimm));
+
+ errlHndl_t l_err = nullptr;
+ uint8_t l_data = 0;
+
+ l_err = nvdimmReadReg(i_nvdimm, ARM_STATUS, l_data);
+
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmCheckArmSuccess() nvdimm[%X]"
+ "failed to read arm status reg!",get_huid(i_nvdimm));
+ }
+ else if (((l_data & ARM_ERROR) == ARM_ERROR) || ((l_data & RESET_N_ARMED) != RESET_N_ARMED) || i_arm_timeout)
+ {
+
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmCheckArmSuccess() nvdimm[%X]"
+ "failed to arm! ARM status 0x%X ARM timeout %d"
+ ,get_huid(i_nvdimm),l_data,i_arm_timeout);
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ARM_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_SET_ARM
+ *@userdata1[0:31] Related ops (0xff = NA)
+ *@userdata1[32:63] Target Huid
+ *@userdata2[0:31] ARM Status
+ *@userdata2[32:63] ARM Timeout
+ *@devdesc Encountered error arming the catastrophic save
+ * trigger on NVDIMM. Make sure an energy source
+ * is connected to the NVDIMM and the ES policy
+ * is set properly
+ *@custdesc NVDIMM encountered error arming save trigger
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_SET_ARM,
+ NVDIMM_ARM_FAILED,
+ TWO_UINT32_TO_UINT64(ARM, get_huid(i_nvdimm)),
+ TWO_UINT32_TO_UINT64(l_data, i_arm_timeout),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME, 256 );
+ nvdimmAddVendorLog(i_nvdimm, l_err);
+
+ // Failure to arm could mean internal NV controller error or
+ // even error on the battery pack. NVDIMM will lose persistency
+ // if failed to arm trigger
+ l_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_Fatal);
+ }
+
+ TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmCheckArmSuccess() nvdimm[%X] ret[%X]",
+ get_huid(i_nvdimm), l_data);
+
+ return l_err;
+}
+
+/**
+ * @brief This function performs arm precheck.
+ *
+ * @param[in] i_nvdimm - nvdimm target with NV controller
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t nvdimmArmPreCheck(Target* i_nvdimm)
+{
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmArmPreCheck() nvdimm[%X]",
+ get_huid(i_nvdimm));
+
+ errlHndl_t l_err = nullptr;
+ uint8_t l_ready = 0;
+ uint8_t l_fwupdate = 0;
+ uint8_t l_module_health = 0;
+ uint8_t l_continue = true;
+ auto l_RegInfo = nvdimm_reg_t();
+
+ do
+ {
+ // Read out the Module Health status register
+ l_err = nvdimmReadReg(i_nvdimm, MODULE_HEALTH_STATUS0, l_module_health);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmArmPreCheck() nvdimm[%X] - failed to read Module Health Status",
+ get_huid(i_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ l_continue = false;
+ break;
+ }
+
+ // Read out the NVDimm Ready register
+ l_err = nvdimmReadReg(i_nvdimm, NVDIMM_READY, l_ready);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmArmPreCheck() nvdimm[%X] - failed to read NVDimm Ready register",
+ get_huid(i_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ l_continue = false;
+ break;
+ }
+
+ // Read out the FW OPs Status register
+ l_err = nvdimmReadReg(i_nvdimm, FIRMWARE_OPS_STATUS, l_fwupdate);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmArmPreCheck() nvdimm[%X] - failed to read Firmware OPs Status register",
+ get_huid(i_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ l_continue = false;
+ }
+
+ }while(0);
+
+ // Check ARM pre-requisites
+ // All nvdimms in i_nvdimmTargetList must pass the pre-req checks
+ // before continuing with arm.
+ if ((!l_continue) || (l_module_health & NVM_LIFETIME_ERROR)
+ || (l_ready != NV_READY)
+ || (l_fwupdate & FW_OPS_UPDATE))
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmArmPreCheck() nvdimm[%X] - failed NVDimm Arm prechecks",
+ get_huid(i_nvdimm));
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ARM_PRE_CHECK_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_ARM_PRE_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata1[32:39] l_continue
+ *@userdata1[40:47] l_module_health
+ *@userdata1[48:56] l_ready
+ *@userdata1[57:63] l_fwupdate
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed arm precheck. Refer to FFDC for exact reason
+ *@custdesc NVDIMM failed the arm precheck and is unable to arm
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_ARM_PRE_CHECK,
+ NVDIMM_ARM_PRE_CHECK_FAILED,
+ NVDIMM_SET_USER_DATA_1(TARGETING::get_huid(i_nvdimm),
+ FOUR_UINT8_TO_UINT32(l_continue, l_module_health, l_ready, l_fwupdate)),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+
+ // Callout the dimm
+ l_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Read relevant regs for trace data
+ nvdimmTraceRegs(i_nvdimm, l_RegInfo);
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+ nvdimmAddVendorLog(i_nvdimm, l_err);
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err);
+
+ }
+
+ TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmArmPreCheck() nvdimm[%X]",
+ get_huid(i_nvdimm));
+
+ return l_err;
+}
+
+
+bool nvdimmArm(TargetHandleList &i_nvdimmTargetList)
+{
+ bool o_arm_successful = true;
+ bool l_continue = true;
+ bool l_arm_timeout = false;
+ uint8_t l_data;
+ auto l_RegInfo = nvdimm_reg_t();
+ uint64_t l_writeData;
+ uint32_t l_writeAddress;
+ size_t l_writeSize = sizeof(l_writeData);
+
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmArm() numNvdimm[%d]",
+ i_nvdimmTargetList.size());
+
+ errlHndl_t l_err = nullptr;
+ errlHndl_t l_err_t = nullptr;
+
+ // Prerequisite Arm Checks
+ for (auto const l_nvdimm : i_nvdimmTargetList)
+ {
+ l_err = nvdimmArmPreCheck(l_nvdimm);
+
+ // If we are failing the precheck, commit the error then exit
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmArm() failed arm precheck, exiting");
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ return false;
+ }
+ }
+
+ // Encryption unlocked check
+ // Check one nvdimm at a time
+ for (auto const l_nvdimm : i_nvdimmTargetList)
+ {
+ // Unlock function will create an error log
+ // Create another here to make it clear that the arm failed
+ TargetHandleList l_nvdimmTargetList;
+ l_nvdimmTargetList.push_back(l_nvdimm);
+ if (!nvdimm_encrypt_unlock(l_nvdimmTargetList))
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmArm() nvdimm[%X] - failed NVDimm Arm encryption unlock",
+ get_huid(l_nvdimm));
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ARM_ENCRYPTION_UNLOCK_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_ARM
+ *@userdata1 Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed to unlock encryption during arming
+ *@custdesc NVDIMM failed to ARM
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_ARM,
+ NVDIMM_ARM_ENCRYPTION_UNLOCK_FAILED,
+ get_huid(l_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+
+ // Callout the dimm
+ l_err->addHwCallout( l_nvdimm,
+ HWAS::SRCI_PRIORITY_MED,
+ HWAS::DELAYED_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Read relevant regs for trace data
+ nvdimmTraceRegs(l_nvdimm, l_RegInfo);
+ nvdimmAddPage4Regs(l_nvdimm,l_err);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err);
+
+ // Commit the error then exit
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ return false;
+ }
+ }
+
+ // Mask MBACALFIR EventN to separate ARM handling
+ for (TargetHandleList::iterator it = i_nvdimmTargetList.begin();
+ it != i_nvdimmTargetList.end();)
+ {
+ TargetHandleList l_mcaList;
+ getParentAffinityTargets(l_mcaList, *it, CLASS_UNIT, TYPE_MCA);
+ assert(l_mcaList.size(), "nvdimmArm() failed to find parent MCA.");
+
+ l_writeAddress = MBACALFIR_OR_MASK_REG;
+ l_writeData = MBACALFIR_EVENTN_OR_BIT;
+ l_err = deviceWrite(l_mcaList[0], &l_writeData, l_writeSize,
+ DEVICE_SCOM_ADDRESS(l_writeAddress));
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "SCOM to address 0x%08x failed",
+ l_writeAddress);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ it++;
+ }
+
+ for (auto const l_nvdimm : i_nvdimmTargetList)
+ {
+ l_arm_timeout = false;
+
+ // skip if the nvdimm is already armed
+ ATTR_NVDIMM_ARMED_type l_armed_state = {};
+ l_armed_state = l_nvdimm->getAttr<ATTR_NVDIMM_ARMED>();
+ if (l_armed_state.armed)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimmArm() nvdimm[%X] called when already armed", get_huid(l_nvdimm));
+ continue;
+ }
+
+ // Set ES Policy, contains all of its status checks
+ l_err = nvdimmSetESPolicy(l_nvdimm);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimmArm() nvdimm[%X] failed to set ES Policy", get_huid(l_nvdimm));
+ o_arm_successful = false;
+
+ nvdimmDisarm(i_nvdimmTargetList);
+
+ // Committing the error as we don't want this to interrupt
+ // the boot. This will notify the user that action is needed
+ // on this module
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+
+ // Callout the nvdimm on high and gard
+ l_err->addHwCallout( l_nvdimm,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_Fatal);
+
+ errlCommit( l_err, NVDIMM_COMP_ID );
+
+ break;
+ }
+
+ // Clear all status registers in case of leftover bits
+ l_err = nvdimmWriteReg(l_nvdimm, NVDIMM_MGT_CMD0, CLEAR_ALL_STATUS);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmArm() nvdimm[%X] - error clearing all status registers",
+ get_huid(l_nvdimm));
+ o_arm_successful = false;
+ break;
+ }
+
+ bool l_is_retryable = true;
+ //continue flag set by the retry loop to continue on the outer loop
+ bool l_continue_arm = false;
+ //break flag set by the retry loop to break on the outer loop
+ bool l_break = false;
+ errlHndl_t l_err_retry = nullptr;
+
+ // Attempt arm multiple times in case of glitches
+ for (size_t l_retry = 0; l_retry <= ARM_MAX_RETRY_COUNT; l_retry++)
+ {
+
+ l_err = NVDIMM::nvdimmChangeArmState(l_nvdimm, ARM_TRIGGER);
+ // If we run into any error here we will just
+ // commit the error log and move on. Let the
+ // system continue to boot and let the user
+ // salvage the data
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimmArm() nvdimm[%X] failed to trigger arm", get_huid(l_nvdimm));
+
+ nvdimmDisarm(i_nvdimmTargetList);
+
+ // Committing the error as we don't want this to interrupt
+ // the boot. This will notify the user that action is needed
+ // on this module
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ o_arm_successful = false;
+
+ // Cause the main loop to skip the rest of the arm procedure
+ // and move to the next target
+ l_continue_arm = true;
+ break;
+ }
+
+ // Arm happens one module at a time. No need to set any offset on the counter
+ uint32_t l_poll = 0;
+ l_err = nvdimmPollArmDone(l_nvdimm, l_poll);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimmArm() nvdimm[%X] arm command timed out", get_huid(l_nvdimm));
+ l_arm_timeout = true;
+
+ l_err_t = notifyNvdimmProtectionChange(l_nvdimm, NVDIMM_DISARMED);
+ if (l_err_t)
+ {
+ errlCommit( l_err_t, NVDIMM_COMP_ID );
+ }
+
+ // Committing the error as we don't want this to interrupt
+ // the boot. This will notify the user that action is needed
+ // on this module
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ o_arm_successful = false;
+ }
+
+ // Pass l_arm_timeout value in for health status check
+ l_continue = l_arm_timeout;
+
+ // Sleep for 1 second before checking the health status
+ // to let the glitches settle in case there were any
+ nanosleep(1, 0);
+
+ // Check health status registers and exit if required
+ l_err = nvdimmHealthStatusCheck( l_nvdimm, HEALTH_PRE_ARM, l_continue );
+
+ // Check for health status failure
+ // Any fail picked up by the health check is a legit fail
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimmArm() nvdimm[%X] failed first health status check", get_huid(l_nvdimm));
+
+ // The arm timeout variable is used here as the continue variable for the
+ // health status check. This was done to include the timeout for use in the check
+ // If true either the arm timed out with a health status fail or the
+ // health status check failed with another disarm and exit condition
+ if (!l_continue)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+
+ // Disarming all dimms due to error
+ nvdimmDisarm(i_nvdimmTargetList);
+ o_arm_successful = false;
+
+ // Cause the main loop to exit out of the main arm procedure
+ l_break = true;
+ break;
+ }
+ else
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+
+ // Cause the main loop to skip the rest of the arm procedure
+ // and move to the next target
+ l_continue_arm = true;
+ break;
+ }
+ }
+
+ l_err = nvdimmCheckArmSuccess(l_nvdimm, l_arm_timeout);
+
+ // At this point we have passed the health check. If the arm were
+ // to fail now, it is likely it was due to some glitch. Let's retry
+ // the arm again as long as the fail is not due to timeout.
+ // A timeout would mean a charging issue, it would have been caught
+ // by the health check.
+ l_is_retryable = !l_arm_timeout && l_retry < ARM_MAX_RETRY_COUNT;
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimmArm() nvdimm[%X] failed to succesfully arm. %s retryable.",
+ get_huid(l_nvdimm), l_is_retryable? "IS" : "NOT");
+
+ if (l_is_retryable)
+ {
+ // Save the original error
+ // If a previous error was saved then delete it
+ if (l_err_retry)
+ {
+ delete l_err_retry;
+ }
+ l_err_retry = l_err;
+
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ARM_RETRY
+ *@severity ERRORLOG_SEV_INFORMATIONAL
+ *@moduleid NVDIMM_ARM_ERASE
+ *@userdata1[0:31] Target Huid
+ *@userdata1[32:39] l_is_retryable
+ *@userdata1[40:47] MAX arm retry count
+ *@userdata2[0:31] Original errlog plid
+ *@userdata2[32:63] Original errlog reason code
+ *@devdesc NVDIMM encountered a glitch causing the initial
+ * arm to fail. System firmware will retry the arm
+ *@custdesc NVDIMM requires an arm retry
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ NVDIMM_ARM_ERASE,
+ NVDIMM_ARM_RETRY,
+ NVDIMM_SET_USER_DATA_1(TARGETING::get_huid(l_nvdimm),
+ FOUR_UINT8_TO_UINT32(l_is_retryable, ARM_MAX_RETRY_COUNT,0,0)),
+ TWO_UINT32_TO_UINT64(l_err_retry->plid(), l_err_retry->reasonCode()),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+
+ // Callout the dimm
+ l_err->addHwCallout( l_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ else
+ {
+ // Handle retryable error
+ if (l_err_retry)
+ {
+ ERRORLOG::ErrlUserDetailsString("Arm RETRY failed").addToLog(l_err_retry);
+
+ // Delete the current errlog and use the original errlog for callout
+ delete l_err;
+ l_err = l_err_retry;
+ l_err_retry = nullptr;
+ }
+
+ // Disarming all dimms due to error
+ nvdimmDisarm(i_nvdimmTargetList);
+
+ l_err_t = notifyNvdimmProtectionChange(l_nvdimm, NVDIMM_DISARMED);
+ if (l_err_t)
+ {
+ errlCommit( l_err_t, NVDIMM_COMP_ID );
+ }
+
+ // Committing the error as we don't want this to interrupt
+ // the boot. This will notify the user that action is needed
+ // on this module
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+
+ // Dump Traces for error logs
+ nvdimmTraceRegs( l_nvdimm, l_RegInfo );
+ nvdimmAddPage4Regs(l_nvdimm,l_err);
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err);
+
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ o_arm_successful = false;
+
+ // Cause the main loop to exit out of the main arm procedure
+ l_break = true;
+ break;
+ }
+ }
+ else
+ {
+ // Arm worked. Exit the retry loop
+ break;
+ } // close nvdimmCheckArmSuccess check
+ } // close arm retry loop
+
+ if (l_continue_arm)
+ {
+ continue;
+ }
+ else if (l_break)
+ {
+ break;
+ }
+
+ // After arming the trigger, erase the image to prevent the possible
+ // stale image getting the restored on the next boot in case of failed
+ // save.
+ l_err = nvdimmEraseNF(l_nvdimm);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimmArm() nvdimm[%X] failed to erase post arm", get_huid(l_nvdimm));
+
+ // Disarming all dimms due to error
+ nvdimmDisarm(i_nvdimmTargetList);
+
+ // Committing the error as we don't want this to interrupt
+ // the boot. This will notify the user that action is needed
+ // on this module
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ o_arm_successful = false;
+ break;
+ }
+
+ // Arm successful, update armed status
+ l_err = NVDIMM::notifyNvdimmProtectionChange(l_nvdimm,
+ NVDIMM::NVDIMM_ARMED);
+ if (l_err)
+ {
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+
+ // Enable Persistency and Warning Threshold notifications
+ l_err = nvdimmWriteReg(l_nvdimm, SET_EVENT_NOTIFICATION_CMD, ENABLE_NOTIFICATIONS);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X] setting persistency notification",
+ TARGETING::get_huid(l_nvdimm));
+ break;
+ }
+
+ // Check notification status and errors
+ l_err = nvdimmReadReg(l_nvdimm, SET_EVENT_NOTIFICATION_STATUS, l_data);
+ if (l_err)
+ {
+ break;
+ }
+ else if (((l_data & SET_EVENT_NOTIFICATION_ERROR) == SET_EVENT_NOTIFICATION_ERROR)
+ || ((l_data & NOTIFICATIONS_ENABLED) != NOTIFICATIONS_ENABLED))
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimmArm() nvdimm[%X] failed to set event notification",
+ get_huid(l_nvdimm));
+
+ // Set NVDIMM Status flag to partial working, as error detected but data might persist
+ notifyNvdimmProtectionChange(l_nvdimm, NVDIMM_RISKY_HW_ERROR);
+
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_SET_EVENT_NOTIFICATION_ERROR
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_SET_EVENT_NOTIFICATION
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM threw an error or failed to set event
+ * notifications during arming
+ *@custdesc NVDIMM failed to enable event notificaitons
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_SET_EVENT_NOTIFICATION,
+ NVDIMM_SET_EVENT_NOTIFICATION_ERROR,
+ TARGETING::get_huid(l_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+
+ // Callout the dimm
+ l_err->addHwCallout( l_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Read relevant regs for trace data
+ nvdimmTraceRegs(l_nvdimm, l_RegInfo);
+ nvdimmAddPage4Regs(l_nvdimm,l_err);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err);
+
+ errlCommit( l_err, NVDIMM_COMP_ID );
+
+ // We are after the arm step now, so on any error cases let's log it
+ // then move to the next nvdimm
+ continue;
+ }
+
+ // Re-check health status registers
+ l_err = nvdimmHealthStatusCheck( l_nvdimm, HEALTH_POST_ARM, l_continue );
+
+ // Check for health status failure
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimmArm() nvdimm[%X] failed final health status check", get_huid(l_nvdimm));
+
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue;
+ }
+
+ }
+
+ // Check for uncommited i2c fail error logs
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimmArm() failed an i2c read/write");
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ nvdimmDisarm(i_nvdimmTargetList);
+ return false;
+ }
+
+ // Unmask firs if the arm completed successfully
+ if (o_arm_successful)
+ {
+ // Unmask MBACALFIR EventN and set to recoverable
+ for (TargetHandleList::iterator it = i_nvdimmTargetList.begin();
+ it != i_nvdimmTargetList.end();)
+ {
+ TargetHandleList l_mcaList;
+ getParentAffinityTargets(l_mcaList, *it, CLASS_UNIT, TYPE_MCA);
+ assert(l_mcaList.size(), "nvdimmArm() failed to find parent MCA.");
+
+ // Set MBACALFIR_ACTION0 to recoverable
+ l_writeAddress = MBACALFIR_ACTION0_REG;
+ l_writeData = 0;
+ l_err = deviceRead(l_mcaList[0], &l_writeData, l_writeSize,
+ DEVICE_SCOM_ADDRESS(l_writeAddress));
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "SCOM to address 0x%08x failed",
+ l_writeAddress);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+
+ l_writeData &= MBACALFIR_EVENTN_AND_BIT;
+ l_err = deviceWrite(l_mcaList[0], &l_writeData, l_writeSize,
+ DEVICE_SCOM_ADDRESS(l_writeAddress));
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "SCOM to address 0x%08x failed",
+ l_writeAddress);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ // Set MBACALFIR_ACTION1 to recoverable
+ l_writeAddress = MBACALFIR_ACTION1_REG;
+ l_writeData = 0;
+ l_err = deviceRead(l_mcaList[0], &l_writeData, l_writeSize,
+ DEVICE_SCOM_ADDRESS(l_writeAddress));
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "SCOM to address 0x%08x failed",
+ l_writeAddress);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ l_writeData |= MBACALFIR_EVENTN_OR_BIT;
+ l_err = deviceWrite(l_mcaList[0], &l_writeData, l_writeSize,
+ DEVICE_SCOM_ADDRESS(l_writeAddress));
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "SCOM to address 0x%08x failed",
+ l_writeAddress);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ // Unmask MBACALFIR[8]
+ l_writeAddress = MBACALFIR_AND_MASK_REG;
+ l_writeData = MBACALFIR_UNMASK_BIT;
+ l_err = deviceWrite(l_mcaList[0], &l_writeData, l_writeSize,
+ DEVICE_SCOM_ADDRESS(l_writeAddress));
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, "SCOM to address 0x%08x failed",
+ l_writeAddress);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ it++;
+ }
+
+ }
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmArm() returning %d",
+ o_arm_successful);
+ return o_arm_successful;
+}
+
+bool nvdimmDisarm(TargetHandleList &i_nvdimmTargetList)
+{
+ bool o_disarm_successful = true;
+
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmDisarm() %d",
+ i_nvdimmTargetList.size());
+
+ errlHndl_t l_err = nullptr;
+
+ for (auto const l_nvdimm : i_nvdimmTargetList)
+ {
+ l_err = NVDIMM::nvdimmChangeArmState(l_nvdimm, DISARM_TRIGGER);
+ // If we run into any error here we will just
+ // commit the error log and move on. Let the
+ // system continue to boot and let the user
+ // salvage the data
+ if (l_err)
+ {
+ // Committing the error as we don't want this to interrupt
+ // the boot. This will notify the user that action is needed
+ // on this module
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ o_disarm_successful = false;
+ continue;
+ }
+
+ // Disarm successful, update armed status
+ l_err = NVDIMM::notifyNvdimmProtectionChange(l_nvdimm,
+ NVDIMM::NVDIMM_DISARMED);
+ if (l_err)
+ {
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+ }
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmDisarm() returning %d",
+ o_disarm_successful);
+
+ return o_disarm_successful;
+
+}
+
+
+/*
+ * @brief Wrapper function to return NVDIMMs to factory default
+ */
+bool nvdimmFactoryDefault(TargetHandleList &i_nvdimmList)
+{
+ errlHndl_t l_err = nullptr;
+ bool l_success = true;
+
+ // Factory default for all nvdimms in the list
+ for (const auto & l_nvdimm : i_nvdimmList)
+ {
+ l_err = nvdimm_factory_reset(l_nvdimm);
+ if (l_err)
+ {
+ l_success = false;
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue;
+ }
+
+ // Update nvdimm status
+ l_err = notifyNvdimmProtectionChange(l_nvdimm, NVDIMM_DISARMED);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ }
+
+ return l_success;
+}
+
+
+/*
+ * @brief Function to start secure erase verify of NVDIMMs
+ */
+bool nvdimmSecureEraseVerifyStart(TargetHandleList &i_nvdimmList)
+{
+ errlHndl_t l_err = nullptr;
+ bool l_success = true;
+
+ // Secure erase verify for all nvdimms in the list
+ for (const auto & l_nvdimm : i_nvdimmList)
+ {
+ // Clear the erase_verify_status reg
+ l_err = nvdimmWriteReg(l_nvdimm,
+ ERASE_VERIFY_STATUS,
+ ERASE_VERIFY_CLEAR);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmSecureEraseVerifyStart() HUID 0x%X"
+ "Failed to write ERASE_VERIFY_STATUS register",
+ get_huid(l_nvdimm));
+ l_success = false;
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue;
+ }
+
+ // Start the erase verify operation
+ l_err = nvdimmWriteReg(l_nvdimm,
+ ERASE_VERIFY_CONTROL,
+ ERASE_VERIFY_START);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmSecureEraseVerifyStart() HUID 0x%X"
+ "Failed to write ERASE_VERIFY_CONTROL register",
+ get_huid(l_nvdimm));
+ l_success = false;
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue;
+ }
+
+ // Call notify to clear NV_STATUS bit
+ l_err = notifyNvdimmProtectionChange(l_nvdimm,
+ ERASE_VERIFY_STARTED);
+ if (l_err)
+ {
+ l_success = false;
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ continue;
+ }
+ }
+
+ return l_success;
+}
+
+
+/*
+ * @brief Function to check status of secure erase verify of NVDIMMs
+ */
+bool nvdimmSecureEraseVerifyStatus(TargetHandleList &i_nvdimmList)
+{
+ errlHndl_t l_err = nullptr;
+ bool l_success = true;
+ uint8_t l_data = 0;
+
+ // Check secure erase verify status for all nvdimms in the list
+ for (const auto & l_nvdimm : i_nvdimmList)
+ {
+ // Check if secure-erase-verify is already complete for this nvdimm
+ ATTR_NV_STATUS_FLAG_type l_nv_status =
+ l_nvdimm->getAttr<ATTR_NV_STATUS_FLAG>();
+ if (l_nv_status & NV_STATUS_ERASE_VERIFY_SET)
+ {
+ continue;
+ }
+
+ l_err = nvdimmReadReg(l_nvdimm, ERASE_VERIFY_CONTROL, l_data);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmSecureEraseVerifyStatus() HUID 0x%X"
+ "Failed to read ERASE_VERIFY_CONTROL register",
+ get_huid(l_nvdimm));
+ l_success = false;
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue; // Continue to next nvdimm
+ }
+
+ // If trigger is set the operation is not yet complete
+ if (l_data & ERASE_VERIFY_TRIGGER)
+ {
+ continue; // Continue to next nvdimm
+ }
+
+ // Secure erase verify on this nvdimm is complete
+ // Call notify to set NV_STATUS bit
+ l_err = notifyNvdimmProtectionChange(l_nvdimm,
+ ERASE_VERIFY_COMPLETED);
+ if (l_err)
+ {
+ l_success = false;
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+
+
+ // Check the status register
+ l_err = nvdimmReadReg(l_nvdimm, ERASE_VERIFY_STATUS, l_data);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmSecureEraseVerifyStatus() HUID 0x%X"
+ "Failed to read ERASE_VERIFY_STATUS register",
+ get_huid(l_nvdimm));
+ l_success = false;
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue; // Continue to next nvdimm
+ }
+
+ // Non-zero status is an error
+ if (l_data)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmSecureEraseVerifyStatus() "
+ "HUID 0x%X ERASE_VERIFY_STATUS returned non-zero status",
+ get_huid(l_nvdimm));
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ERASE_VERIFY_STATUS_NONZERO
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_SECURE_ERASE_VERIFY_STATUS
+ *@userdata1 NVDIMM HUID
+ *@userdata2 ERASE_VERIFY_STATUS
+ *@devdesc Error detected during secure erase verify
+ *@custdesc NVDIMM erase error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_SECURE_ERASE_VERIFY_STATUS,
+ NVDIMM_ERASE_VERIFY_STATUS_NONZERO,
+ get_huid(l_nvdimm),
+ l_data,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ l_err->addPartCallout( l_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ l_success = false;
+ continue; // Continue to next nvdimm
+ }
+
+
+ // Check the result registers
+ uint16_t l_result = 0;
+ l_err = nvdimmReadReg(l_nvdimm, ERASE_VERIFY_RESULT_MSB, l_data);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmSecureEraseVerifyStatus() HUID 0x%X"
+ "Failed to read ERASE_VERIFY_RESULT_MSB register",
+ get_huid(l_nvdimm));
+ l_success = false;
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue; // Continue to next nvdimm
+ }
+
+ // Save result
+ l_result = l_data << 8;
+
+ l_err = nvdimmReadReg(l_nvdimm, ERASE_VERIFY_RESULT_LSB, l_data);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmSecureEraseVerifyStatus() HUID 0x%X"
+ "Failed to read ERASE_VERIFY_RESULT_LSB register",
+ get_huid(l_nvdimm));
+ l_success = false;
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue; // Continue to next nvdimm
+ }
+
+ // Save result
+ l_result |= l_data;
+
+ // Non-zero result is an error
+ if (l_result)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmSecureEraseVerifyStatus() "
+ "HUID 0x%X ERASE_VERIFY_RESULT returned non-zero data",
+ get_huid(l_nvdimm));
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ERASE_VERIFY_RESULT_NONZERO
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_SECURE_ERASE_VERIFY_STATUS
+ *@userdata1 NVDIMM HUID
+ *@userdata2 ERASE_VERIFY_RESULT
+ *@devdesc Error detected during secure erase verify
+ *@custdesc NVDIMM erase error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_SECURE_ERASE_VERIFY_STATUS,
+ NVDIMM_ERASE_VERIFY_RESULT_NONZERO,
+ get_huid(l_nvdimm),
+ l_result,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ l_err->addPartCallout( l_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ l_success = false;
+ continue; // Continue to next nvdimm
+ }
+
+ }
+
+ return l_success;
+}
+
+
} // end NVDIMM namespace
diff --git a/src/usr/isteps/nvdimm/nvdimm.H b/src/usr/isteps/nvdimm/nvdimm.H
index 4d97a9c66..e66e42470 100644
--- a/src/usr/isteps/nvdimm/nvdimm.H
+++ b/src/usr/isteps/nvdimm/nvdimm.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2019 */
+/* Contributors Listed Below - COPYRIGHT 2014,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,6 +27,7 @@
#define NVDIMM_H__
#include <usr/errl/errlentry.H>
+#include <targeting/common/target.H>
#include <targeting/common/commontargeting.H>
#include <targeting/common/util.H>
#include <targeting/common/utilFilter.H>
@@ -40,6 +41,12 @@ extern trace_desc_t* g_trac_nvdimm;
namespace NVDIMM
{
+#define NVDIMM_SET_USER_DATA_1(left_32_ops_id, right_32_huid) \
+ TWO_UINT32_TO_UINT64(left_32_ops_id, right_32_huid)
+
+#define NVDIMM_SET_USER_DATA_2_TIMEOUT(left_32_polled, right_32_timeout) \
+ NVDIMM_SET_USER_DATA_1(left_32_polled, right_32_timeout)
+
// I2C registers for page 0-3, extracted from JEDEC BAEBI spec
// Refer to BAEBI spec for details
@@ -121,11 +128,13 @@ enum i2cReg : uint16_t
SET_ES_POLICY_STATUS = 0x070,
FIRMWARE_OPS_STATUS = 0x071,
OPERATIONAL_UNIT_OPS_STATUS = 0x072,
- RESTORE_FAIL_INFO = 0x088,
- OPERATIONAL_UNIT_FAIL_INFO = 0x08F,
+ ERASE_FAIL_INFO = 0x073,
+ ARM_FAIL_INFO = 0x076,
CSAVE_INFO = 0x080,
CSAVE_FAIL_INFO0 = 0x084,
CSAVE_FAIL_INFO1 = 0x085,
+ RESTORE_FAIL_INFO = 0x088,
+ OPERATIONAL_UNIT_FAIL_INFO = 0x08F,
NVM_LIFETIME_ERROR_THRESHOLD = 0x090,
ES_LIFETIME_ERROR_THRESHOLD = 0x091,
ES_TEMP_ERROR_HIGH_THRESHOLD0 = 0x094,
@@ -274,6 +283,45 @@ enum i2cReg : uint16_t
TYPED_BLOCK_DATA_BYTE30 = 0x39E,
TYPED_BLOCK_DATA_BYTE31 = 0x39F,
TYPED_BLOCK_DATA_OFFSET = 0x3E0,
+ PANIC_CNT = 0x406,
+ STATUS_EVENT_INT_INFO1 = 0x40A,
+ STATUS_EVENT_INT_INFO2 = 0x40B,
+ FLASH_BAD_BLK_PCT = 0x41D, // Read only; Percentage of flash blocks
+ // in the flash array marked as bad blocks
+ PARITY_ERROR_COUNT = 0x423,
+ FLASH_ERROR_COUNT0 = 0x428, // Read only; LSB[7:0] Flash error count
+ FLASH_ERROR_COUNT1 = 0x429, // Read only; [15:8]
+ FLASH_ERROR_COUNT2 = 0x42A, // Read only; MSB[23:16]
+ FLASH_BAD_BLOCK_COUNT0 = 0x42B,
+ FLASH_BAD_BLOCK_COUNT1 = 0x42C,
+ BPM_MAGIC_REG1 = 0x430,
+ BPM_MAGIC_REG2 = 0x431,
+ SCAP_STATUS = 0x432,
+ SCAP_REG = 0x434,
+ SCAP_DATA = 0x435,
+ I2C_REG_PROTECT = 0x43D,
+ BPM_REG_CMD = 0x440,
+ BPM_CMD_STATUS = 0x441,
+ BPM_PAYLOAD_LENGTH = 0x442,
+ BPM_REG_ERR_STATUS = 0x443,
+ BPM_REG_PAYLOAD_START = 0x444,
+ ERASE_VERIFY_CONTROL = 0x51A,
+ ERASE_VERIFY_STATUS = 0x51B,
+ ERASE_VERIFY_RESULT_LSB = 0x51C,
+ ERASE_VERIFY_RESULT_MSB = 0x51D,
+ ERASE_VERIFY_TEST = 0x51E,
+ ENCRYPTION_COMMAND = 0x51F,
+ ENCRYPTION_CONFIG_STATUS = 0x520,
+ ENCRYPTION_ACCESS_KEY_SET = 0x521,
+ ENCRYPTION_ACCESS_KEY_VERIFY = 0x522,
+ ENCRYPTION_ACCESS_KEY_UNLOCK = 0x523,
+ ENCRYPTION_RAMDOM_STRING_SET = 0x524,
+ ENCRYPTION_RANDOM_STRING_VERIFY = 0x525,
+ ENCRYPTION_ERASE_KEY_SET = 0x526,
+ ENCRYPTION_ERASE_KEY_VERIFY = 0x527,
+ ENCRYPTION_ERASE_KEY_TEST = 0x528,
+ ENCRYPTION_ERASE_KEY_TEST_VERIFY = 0x529,
+ ENCRYPTION_KEY_VALIDATION = 0x52A,
};
// i2cReg macros
@@ -292,6 +340,7 @@ enum page : uint8_t
TWO = 0x02,
THREE = 0x03,
FOUR = 0x04,
+ FIVE = 0x05,
};
// Enums for inputs/expected output to/from the i2c registers
@@ -306,6 +355,7 @@ enum i2c_in_values : uint8_t
RESET_CTRLR = 0x01,
VALID_IMAGE = 0x01,
RESET_CONTROLLER = 0x01,
+ FACTORY_DEFAULT = 0x01,
};
enum i2c_out_values : uint8_t
@@ -317,11 +367,20 @@ enum i2c_out_values : uint8_t
CHARGE_IN_PROGRESS = 0x01,
SAVE_SUCCESS = 0x01,
RSTR_SUCCESS = 0X01,
- ARM_SUCCESS = 0X09,
+ ARM_SUCCESS = 0X01,
ERASE_SUCCESS = 0X01,
ES_SUCCESS = 0x05,
CHARGE_SUCCESS = 0x00,
NV_READY = 0xA5,
+ FACTORY_RESET_IN_PROGRESS = 0x03,
+ NO_RESET_N = 0x20,
+ RESET_N_ARMED = 0x08,
+ ES_POLICY_ERROR = 0x02,
+ ARM_ERROR = 0X02,
+ RSTR_ERROR = 0x02,
+ SAVE_ERROR = 0x02,
+ ERASE_ERROR = 0x02,
+ CLEAR_ALL_STATUS = 0x3C, //Clears CAVE, RESTORE, ERASE, and ARM status regs
};
// Timeout-related enum
@@ -330,6 +389,7 @@ enum timeout : uint32_t
OPS_POLL_TIME_MS = 5000,
NV_READY_POLL_TIME_MS = 1000,
PAGE_SWITCH_POLL_TIME_NS = 100,
+ KEY_WRITE_DELAY_MS = 100,
};
// Assign an id to each of the 6 major ops
@@ -354,6 +414,119 @@ enum misc
};
/**
+ * @brief Encryption key data
+ */
+static constexpr size_t ENC_KEY_SIZE = 32;
+struct nvdimmKeyData_t
+{
+ uint8_t rs[ENC_KEY_SIZE]; // Random String (RS)
+ uint8_t ek[ENC_KEY_SIZE]; // Erase Key (EK)
+ uint8_t ak[ENC_KEY_SIZE]; // Access Key (AK)
+};
+
+struct scap_status_bits
+{
+ uint8_t Reserved1 : 1; // Bit 7
+ uint8_t Bpm_Bsl_Mode : 1; // Bit 6
+ uint8_t Reserved2 : 1; // Bit 5
+ uint8_t Present : 1; // Bit 4
+ uint8_t Delay : 1; // Bit 3
+ uint8_t Error : 1; // Bit 2
+ uint8_t Busy : 1; // Bit 1
+ uint8_t Enable : 1; // Bit 0
+} PACKED;
+
+/**
+ * @brief Union simplifying manipulation of SCAP_STATUS bits
+ */
+union scap_status_union
+{
+ uint8_t full;
+ scap_status_bits bit;
+
+ /**
+ * @brief Constructor
+ */
+ scap_status_union()
+ : full(0)
+ {}
+} PACKED;
+
+typedef scap_status_union scap_status_register_t;
+
+// Bits in Health Status Check Registers
+enum health_status : uint8_t
+{
+ // Module Health Status0
+ VOLTAGE_REGULATOR_FAILED = 0x01,
+ VDD_LOST = 0x02,
+ VPP_LOST = 0x04,
+ VTT_LOST = 0x08,
+ DRAM_NOT_SELF_REFRESH = 0x10,
+ CONTROLLER_HARDWARE_ERROR = 0x20,
+ NVM_CONTROLLER_ERROR = 0x40,
+ NVM_LIFETIME_ERROR = 0x80,
+ // Module Health Status1
+ NOT_ENOUGH_ENERGY_FOR_CSAVE = 0x01,
+ INVALID_FIRMWARE_ERROR = 0x02,
+ CONFIG_DATA_ERROR = 0x04,
+ NO_ES_PRESENT = 0x08,
+ ES_POLICY_NOT_SET = 0x10,
+ ES_HARDWARE_FAILURE = 0x20,
+ ES_HEALTH_ASSESSMENT_ERROR = 0x40,
+ // Error Threshold Status
+ ES_LIFETIME_ERROR = 0x02,
+ ES_TEMP_ERROR = 0x04,
+};
+
+// Int representation for health status function call
+enum health_function : uint8_t
+{
+ HEALTH_SAVE = 0x01,
+ HEALTH_RESTORE = 0x02,
+ HEALTH_UPDATE = 0x03,
+ HEALTH_PRE_ARM = 0x04,
+ HEALTH_POST_ARM = 0x05,
+};
+
+// Event notification register values
+enum event_n : uint8_t
+{
+ PERSISTENCY_NOTIFICATION = 0x01,
+ SET_EVENT_NOTIFICATION_ERROR = 0x02,
+ WARNING_THRESHOLD_NOTIFICATION = 0x02,
+ PERSISTENCY_ENABLED = 0x04,
+ WARNING_THRESHOLD_ENABLED = 0x08,
+ ENABLE_NOTIFICATIONS = 0x03,
+ NOTIFICATIONS_ENABLED = 0x0C,
+};
+
+// MBACALFIR register addresses
+enum mbacal_addresses : uint32_t
+{
+ MBACALFIR_AND_MASK_REG = 0x07010904,
+ MBACALFIR_OR_MASK_REG = 0x07010905,
+ MBACALFIR_ACTION0_REG = 0x07010906,
+ MBACALFIR_ACTION1_REG = 0x07010907,
+};
+
+// MBACALFIR bit masks for event n
+enum mbacal_bitmask_values : uint64_t
+{
+ MBACALFIR_EVENTN_AND_BIT = 0xff7fffffffffffff,
+ MBACALFIR_EVENTN_OR_BIT = 0x0080000000000000,
+ MBACALFIR_UNMASK_BIT = 0xff7fffffffffffff,
+};
+
+
+/**
+ * @brief Mask MCBACALFIR Event N to prevent PRD from handling event
+ *
+ * @param[in] - i_nvdimm - nvdimm target for operation on its parent MCA
+ */
+void maskMbacalfir_eventn(TARGETING::Target* i_nvdimm);
+
+/**
* @brief Wrapper to call deviceOp to read the NV controller via I2C
*
* @param[in] i_nvdimm - nvdimm target with NV controller
@@ -434,6 +607,169 @@ errlHndl_t nvdimmPollStatus(TARGETING::Target *i_nvdimm, ops_id i_ops_id, uint32
* the error log.
*/
errlHndl_t nvdimmSetESPolicy(TARGETING::Target* i_nvdimm);
+
+/**
+ * @brief Helper function to handle conflicting attribute keys
+ *
+ * @param[in] i_attrKeysFw - firmware key attribute
+ *
+ * @param[in] i_attrKeysAnchor - anchor key attribute
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log
+ */
+errlHndl_t nvdimm_handleConflictingKeys(
+ TARGETING::ATTR_NVDIMM_ENCRYPTION_KEYS_FW_typeStdArr& i_attrKeysFw,
+ TARGETING::ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR_typeStdArr& i_attrKeysAnchor);
+
+
+/**
+ * @brief Helper function to validate attribute keys
+ *
+ * @param[in] i_attrData - pointer to attribute key data
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log
+ */
+errlHndl_t nvdimm_checkValidAttrKeys( nvdimmKeyData_t* i_attrData );
+
+
+/**
+ * @brief Helper function to write encryption key regs (RS/EK/AK)
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[in] i_keyData - data to write to the key reg
+ *
+ * @param[in] i_keyReg - enum register to write key
+ *
+ * @param[in] i_verifyReg - enum register to verify key written
+ *
+ * @param[in] i_secondAttempt - normally false, true if verif check failed
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log
+ */
+errlHndl_t nvdimm_setKeyReg(TARGETING::Target* i_nvdimm,
+ uint8_t* i_keyData,
+ uint32_t i_keyReg,
+ uint32_t i_verifyReg,
+ bool i_secondAttempt);
+
+
+/**
+ * @brief Helper function to generate randon number for encryption keys
+ * Generates ENC_KEY_SIZE bytes of data
+ * Different implementations for boot vs runtime
+ *
+ * @param[out] o_genData - pointer to generated data
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log
+ */
+errlHndl_t nvdimm_getRandom(uint8_t* o_genData);
+
+
+/**
+ * @brief Helper function to make a random number valid for keys
+ * Keys must not contain 0x00 or 0xFF
+ * - 0x00 KEY_TERMINATE_BYTE terminates a key < 32 bytes
+ * - 0xFF KEY_ABORT_BYTE aborts the key reg write process
+ * This function finds invalid bytes in the first random number
+ * and replaces with bytes from the second random number
+ *
+ * @param[out] o_genData - pointer to final generated data
+ *
+ * @param[in] i_xtraData - pointer to extra generated data
+ *
+ * @return - false if successful, true if failed
+ *
+ */
+bool nvdimm_keyifyRandomNumber(uint8_t* o_genData, uint8_t* i_xtraData);
+
+
+/**
+ * @brief Helper function to validate a random number
+ *
+ * @param[in] i_genData - pointer to generated data
+ *
+ * @return - true if valid, false if invalid
+ *
+ */
+bool nvdimm_validRandomNumber(uint8_t* i_genData);
+
+
+/**
+ * @brief Helper function to set encryption error
+ * in ATTR_NVDIMM_ARMED
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ */
+void nvdimmSetEncryptionError(TARGETING::Target *i_nvdimm);
+
+
+/**
+ * @brief Helper function to reset the NVDIMM controller
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log
+ */
+errlHndl_t nvdimmResetController(TARGETING::Target *i_nvdimm);
+
+
+/**
+ * @brief Helper function to factory reset NVDIMM
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log
+ */
+errlHndl_t nvdimm_factory_reset(TARGETING::Target *i_nvdimm);
+
+
+#ifndef __HOSTBOOT_RUNTIME
+
+/**
+ * @brief Helper function to get TPM pointer for random number generation
+ *
+ * @param[out] - pointer to a functional TPM or nullptr if no TPM found
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log
+ */
+errlHndl_t nvdimm_getTPM(TARGETING::Target*& o_tpm);
+
+#endif
+
+/**
+ * @brief This function checks for valid image on the given target
+ *
+ * @param[in] i_nvdimm - nvdimm target with NV controller
+ *
+ * @param[out] o_imgValid - return true if the target has a valid image
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t nvdimmValidImage(TARGETING::Target *i_nvdimm, bool &o_imgValid);
+
+
+/**
+ * @brief This function grabs the current slot NVDIMM code is running
+ * Slot 0 is the failure slot, Slot 1 is the updateable slot
+ *
+ * @param[in] i_nvdimm - nvdimm target with NV controller
+ * @param[out] o_slot - 0 or 1
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t nvdimmGetRunningSlot(TARGETING::Target *i_nvdimm, uint8_t & o_slot);
+
} //End NVDIMM namespace
diff --git a/src/usr/isteps/nvdimm/nvdimm.mk b/src/usr/isteps/nvdimm/nvdimm.mk
index 397b27814..d9418b414 100644
--- a/src/usr/isteps/nvdimm/nvdimm.mk
+++ b/src/usr/isteps/nvdimm/nvdimm.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -47,11 +47,14 @@ EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/ffdc/
OBJS += nvdimm.o
OBJS += nvdimmdd.o
OBJS += errlud_nvdimm.o
+OBJS += nvdimmErrorLog.o
ifneq (${HOSTBOOT_RUNTIME},1)
# code update path for NVDIMMs (not at RUNTIME)
OBJS += nvdimm_update.o
+# code update path for BPMs (not at runtime)
+OBJS += bpm_update.o
endif
diff --git a/src/usr/isteps/nvdimm/nvdimmErrorLog.C b/src/usr/isteps/nvdimm/nvdimmErrorLog.C
new file mode 100644
index 000000000..9fbd27d14
--- /dev/null
+++ b/src/usr/isteps/nvdimm/nvdimmErrorLog.C
@@ -0,0 +1,1317 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/isteps/nvdimm/nvdimmErrorLog.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include "nvdimm.H"
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/util.H>
+#include <targeting/common/utilFilter.H>
+#include <fapi2.H>
+#include <isteps/nvdimm/nvdimmreasoncodes.H>
+#include <isteps/nvdimm/nvdimm.H>
+#include "errlud_nvdimm.H"
+
+using namespace TARGETING;
+
+namespace NVDIMM
+{
+
+/**
+ * @brief Read and save various status registers needed for error log traces
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[out] o_RegInfo - struct to hold register data
+ *
+ */
+void nvdimmTraceRegs(Target *i_nvdimm, nvdimm_reg_t& o_RegInfo)
+{
+ uint8_t l_data = 0x0;
+ errlHndl_t l_err = nullptr;
+
+ // Read MODULE HEALTH register
+ l_err = nvdimmReadReg(i_nvdimm, MODULE_HEALTH, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Module_Health = l_data;
+
+ // Read MODULE HEALTH STATUS0 register
+ l_err = nvdimmReadReg(i_nvdimm, MODULE_HEALTH_STATUS0, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Module_Health_Status0 = l_data;
+
+ // Read MODULE HEALTH STATUS1 register
+ l_err = nvdimmReadReg(i_nvdimm, MODULE_HEALTH_STATUS1, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Module_Health_Status1 = l_data;
+
+ // Read CSAVE STATUS register
+ l_err = nvdimmReadReg(i_nvdimm, CSAVE_STATUS, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.CSave_Status = l_data;
+
+ // Read CSAVE INFO register
+ l_err = nvdimmReadReg(i_nvdimm, CSAVE_INFO, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.CSave_Info = l_data;
+
+ // Read CSAVE FAIL INFO0 register
+ l_err = nvdimmReadReg(i_nvdimm, CSAVE_FAIL_INFO0, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.CSave_Fail_Info0 = l_data;
+
+ // Read CSAVE FAIL INFO1 register
+ l_err = nvdimmReadReg(i_nvdimm, CSAVE_FAIL_INFO1, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.CSave_Fail_Info1 = l_data;
+
+ // Read CSAVE TIMEOUT0 register
+ l_err = nvdimmReadReg(i_nvdimm, CSAVE_TIMEOUT0, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.CSave_Timeout0 = l_data;
+
+ // Read CSAVE TIMEOUT1 register
+ l_err = nvdimmReadReg(i_nvdimm, CSAVE_TIMEOUT1, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.CSave_Timeout1 = l_data;
+
+ // Read ERROR THRESHOLD STATUS register
+ l_err = nvdimmReadReg(i_nvdimm, ERROR_THRESHOLD_STATUS, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Error_Threshold_Status = l_data;
+
+ // Read NVDIMM READY register
+ l_err = nvdimmReadReg(i_nvdimm, NVDIMM_READY, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.NVDimm_Ready = l_data;
+
+ // Read NVDIMM CMD STATUS0 register
+ l_err = nvdimmReadReg(i_nvdimm, NVDIMM_CMD_STATUS0, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.NVDimm_CMD_Status0 = l_data;
+
+ // Read ERASE STATUS register
+ l_err = nvdimmReadReg(i_nvdimm, ERASE_STATUS, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Erase_Status = l_data;
+
+ // Read ERASE FAIL INFO register
+ l_err = nvdimmReadReg(i_nvdimm, ERASE_FAIL_INFO, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Erase_Fail_Info = l_data;
+
+ // Read ERASE TIMEOUT0 register
+ l_err = nvdimmReadReg(i_nvdimm, ERASE_TIMEOUT0, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Erase_Timeout0 = l_data;
+
+ // Read ERASE TIMEOUT1 register
+ l_err = nvdimmReadReg(i_nvdimm, ERASE_TIMEOUT1, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Erase_Timeout1 = l_data;
+
+ // Read ABORT CMD TIMEOUT register
+ l_err = nvdimmReadReg(i_nvdimm, ABORT_CMD_TIMEOUT, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Abort_CMD_Timeout = l_data;
+
+ // Read SET ES POLICY STATUS register
+ l_err = nvdimmReadReg(i_nvdimm, SET_ES_POLICY_STATUS, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Set_ES_Policy_Status = l_data;
+
+ // Read RESTORE STATUS register
+ l_err = nvdimmReadReg(i_nvdimm, RESTORE_STATUS, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Restore_Status = l_data;
+
+ // Read RESTORE FAIL INFO register
+ l_err = nvdimmReadReg(i_nvdimm, RESTORE_FAIL_INFO, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Restore_Fail_Info = l_data;
+
+ // Read RESTORE TIMEOUT0 register
+ l_err = nvdimmReadReg(i_nvdimm, RESTORE_TIMEOUT0, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Restore_Timeout0 = l_data;
+
+ // Read RESTORE TIMEOUT1 register
+ l_err = nvdimmReadReg(i_nvdimm, RESTORE_TIMEOUT1, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Restore_Timeout1 = l_data;
+
+ // Read ARM STATUS register
+ l_err = nvdimmReadReg(i_nvdimm, ARM_STATUS, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Arm_Status = l_data;
+
+ // Read ARM FAIL INFO register
+ l_err = nvdimmReadReg(i_nvdimm, ARM_FAIL_INFO, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Arm_Fail_Info = l_data;
+
+ // Read ARM TIMEOUT0 register
+ l_err = nvdimmReadReg(i_nvdimm, ARM_TIMEOUT0, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Arm_Timeout0 = l_data;
+
+ // Read ARM TIMEOUT1 register
+ l_err = nvdimmReadReg(i_nvdimm, ARM_TIMEOUT1, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Arm_Timeout1 = l_data;
+
+ // Read SET EVENT NOTIFICATION STATUS register
+ l_err = nvdimmReadReg(i_nvdimm, SET_EVENT_NOTIFICATION_STATUS, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Set_Event_Notification_Status = l_data;
+
+ // Read NVDIMM Encryption Configuration and Status Register for Security Errors
+ l_err = nvdimmReadReg(i_nvdimm, ENCRYPTION_CONFIG_STATUS, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ o_RegInfo.Encryption_Config_Status = l_data;
+}
+
+/**
+ * @brief Helper function for standard callout of an NVDIMM
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[in] i_step - the nvdimm function calling the health check
+ *
+ * @param[out] o_err - error log handler to be modified
+ *
+ * @return bool - true to commit log and continue, false to return
+ * the error log to caller and exit.
+ */
+bool nvdimmCalloutDimm(Target *i_nvdimm, uint8_t i_step, errlHndl_t& o_err)
+{
+ bool l_continue = true;
+ uint8_t l_data;
+ errlHndl_t l_err = nullptr;
+
+ // Check which callout check is necessary
+ switch(i_step)
+ {
+ // Post save errors always continue with callouts
+ case HEALTH_SAVE:
+ {
+ // Check to see if the nvdimm image is still valid
+ l_err = nvdimmValidImage(i_nvdimm, l_continue);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ // Checkout image validity and set dimm status accordingly
+ if(l_continue)
+ {
+ // Set ATTR_NV_STATUS_FLAG to partially working as data may still persist
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_VAL_SR);
+
+ // Callout dimm but do not deconfig or gard
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+ }
+ else
+ {
+ // Callout, deconfig and gard the dimm
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DECONFIG,
+ HWAS::GARD_Fatal);
+ }
+
+ break;
+ }
+
+ // Post restore errors always continue with callouts
+ case HEALTH_RESTORE:
+ {
+ // Check restore status
+ l_err = nvdimmReadReg(i_nvdimm, RESTORE_STATUS, l_data);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ else if ((l_data & RSTR_SUCCESS) != RSTR_SUCCESS)
+ {
+ l_continue = false;
+ }
+
+ // Check restore status and set dimm status accordingly
+ if(l_continue)
+ {
+ // Set ATTR_NV_STATUS_FLAG to partially working as data may still persist
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_VAL_SR);
+
+ // Callout dimm but do not deconfig or gard
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+ }
+ else
+ {
+ // Callout, deconfig and gard the dimm
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DECONFIG,
+ HWAS::GARD_Fatal);
+ }
+
+ break;
+ }
+
+ // Post ARM errors need check for arm success
+ case HEALTH_PRE_ARM:
+ {
+
+ // Check arm status
+ l_err = nvdimmReadReg(i_nvdimm, ARM_STATUS, l_data);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ else if (((l_data & ARM_SUCCESS) != ARM_SUCCESS) || ((l_data & RESET_N_ARMED) != RESET_N_ARMED))
+ {
+ l_continue = false;
+ }
+
+ // Check arm status and set dimm status accordingly
+ if(l_continue)
+ {
+ // Set ATTR_NV_STATUS_FLAG to partially working as data may still persist
+ notifyNvdimmProtectionChange(i_nvdimm,NVDIMM_RISKY_HW_ERROR);
+
+ // Callout dimm without deconfig or gard
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+ }
+ else
+ {
+ // Set ATTR_NV_STATUS_FLAG to dimm diarmed
+ l_err = notifyNvdimmProtectionChange(i_nvdimm, NVDIMM_DISARMED);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ // Callout and gard the dimm
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_Fatal);
+ }
+
+ break;
+ }
+
+ // Post ARM errors need check for arm success
+ case HEALTH_POST_ARM:
+ {
+ // Callout dimm but do not deconfig or gard
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Set ATTR_NV_STATUS_FLAG to partially working as data may persist despite errors
+ notifyNvdimmProtectionChange(i_nvdimm,NVDIMM_RISKY_HW_ERROR);
+
+ break;
+ }
+
+ }
+
+ return l_continue;
+}
+
+/**
+ * @brief Helper function for BPM/Cable high, NVDIMM low callout
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[in] i_step - the nvdimm function calling the health check
+ *
+ * @param[out] o_err - error log handler to be modified
+ *
+ * @return bool - true to commit log and continue, false to return
+ * the error log to caller and exit.
+ */
+bool nvdimmBPMCableCallout(Target *i_nvdimm, uint8_t i_step, errlHndl_t& o_err)
+{
+ bool l_continue = true;
+ uint8_t l_data;
+ errlHndl_t l_err = nullptr;
+
+ // Check which callout check is necessary
+ switch(i_step)
+ {
+ // Post save errors always continue with callouts
+ case HEALTH_SAVE:
+ {
+ // Check to see if the nvdimm image is still valid
+ l_err = nvdimmValidImage(i_nvdimm, l_continue);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ // Callout BPM and Cable but cannot deconfig or gard
+ o_err->addPartCallout( i_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ o_err->addPartCallout( i_nvdimm,
+ HWAS::BPM_CABLE_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ // Check image validity and set dimm status accordingly
+ if(l_continue)
+ {
+ // Set ATTR_NV_STATUS_FLAG to partially working as data may still persist
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_VAL_SR);
+
+ // Callout dimm but do not deconfig or gard
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+ }
+ else
+ {
+ // Callout dimm, deconfig and gard
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::DECONFIG,
+ HWAS::GARD_Fatal);
+ }
+
+ break;
+ }
+
+ // Post restore errors always continue with callouts
+ case HEALTH_RESTORE:
+ {
+ // Check restore status
+ l_err = nvdimmReadReg(i_nvdimm, RESTORE_STATUS, l_data);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ else if ((l_data & RSTR_SUCCESS) != RSTR_SUCCESS)
+ {
+ l_continue = false;
+ }
+
+ // Callout dimm but do not deconfig or gard
+ o_err->addPartCallout( i_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ o_err->addPartCallout( i_nvdimm,
+ HWAS::BPM_CABLE_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ // Callout dimm but do not deconfig or gard
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Check restore status and set dimm status accordingly
+ if(l_continue)
+ {
+ // Set ATTR_NV_STATUS_FLAG to partially working as data may still persist
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_VAL_SR);
+ }
+
+ break;
+ }
+
+ // Post ARM errors need check for arm success
+ case HEALTH_PRE_ARM:
+ {
+ // Check arm status
+ l_err = nvdimmReadReg(i_nvdimm, ARM_STATUS, l_data);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ else if (((l_data & ARM_SUCCESS) != ARM_SUCCESS) || ((l_data & RESET_N_ARMED) != RESET_N_ARMED))
+ {
+ l_continue = false;
+ }
+
+ // Callout BPM and Cable but cannot deconfig or gard
+ o_err->addPartCallout( i_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ o_err->addPartCallout( i_nvdimm,
+ HWAS::BPM_CABLE_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ // Check arm status and set dimm status accordingly
+ if(l_continue)
+ {
+ // Set ATTR_NV_STATUS_FLAG to partially working as data may still persist
+ notifyNvdimmProtectionChange(i_nvdimm,NVDIMM_RISKY_HW_ERROR);
+ }
+
+ // Callout dimm but do not deconfig or gard
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+ break;
+ }
+
+ // Post ARM errors need check for arm success
+ case HEALTH_POST_ARM:
+ {
+ // Callout dimm but do not deconfig or gard
+ o_err->addPartCallout( i_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ o_err->addPartCallout( i_nvdimm,
+ HWAS::BPM_CABLE_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Set ATTR_NV_STATUS_FLAG to partially working as data may still persist
+ notifyNvdimmProtectionChange(i_nvdimm,NVDIMM_RISKY_HW_ERROR);
+
+ break;
+ }
+
+ }
+
+ return l_continue;
+}
+
+/**
+ * @brief Helper function for BPM high, NVDIMM low callout
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[in] i_step - the nvdimm function calling the health check
+ *
+ * @param[out] o_err - error log handler to be modified
+ *
+ * @return bool - true to commit log and continue, false to return
+ * the error log to caller and exit.
+ */
+bool nvdimmBPMCallout(Target *i_nvdimm, uint8_t i_step, errlHndl_t& o_err)
+{
+ bool l_continue = true;
+ uint8_t l_data;
+ errlHndl_t l_err = nullptr;
+
+ // Check which callout check is necessary
+ switch(i_step)
+ {
+ // Post save errors always continue with callouts
+ case HEALTH_SAVE:
+ {
+ // Callout BPM on high
+ o_err->addPartCallout( i_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ // Callout dimm but do not deconfig or gard
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Set ATTR_NV_STATUS_FLAG to partially working as data may still persist
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_VAL_SR);
+
+ break;
+ }
+
+ // Post restore errors always continue with callouts
+ case HEALTH_RESTORE:
+ {
+ // Callout BPM on high
+ o_err->addPartCallout( i_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ // Callout dimm but do not deconfig or gard
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Set ATTR_NV_STATUS_FLAG to partially working as data may still persist
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_VAL_SR);
+
+ break;
+ }
+
+ // Post ARM errors need check for arm success
+ case HEALTH_PRE_ARM:
+ {
+ // Check arm status
+ l_err = nvdimmReadReg(i_nvdimm, ARM_STATUS, l_data);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ else if (((l_data & ARM_SUCCESS) != ARM_SUCCESS) || ((l_data & RESET_N_ARMED) != RESET_N_ARMED))
+ {
+ l_continue = false;
+ }
+
+ // Callout BPM on high
+ o_err->addPartCallout( i_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ // Callout dimm but do not deconfig or gard
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Check arm status and set dimm status accordingly
+ if(l_continue)
+ {
+ // Set ATTR_NV_STATUS_FLAG to partially working as data may still persist
+ notifyNvdimmProtectionChange(i_nvdimm,NVDIMM_RISKY_HW_ERROR);
+ }
+ else
+ {
+ // Set ATTR_NV_STATUS_FLAG to dimm diarmed
+ l_err = notifyNvdimmProtectionChange(i_nvdimm, NVDIMM_DISARMED);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ }
+
+ break;
+ }
+
+ // Post ARM errors need check for arm success
+ case HEALTH_POST_ARM:
+ {
+ // Callout BPM on high
+ o_err->addPartCallout( i_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+
+ // Callout dimm but do not deconfig or gard
+ o_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Set ATTR_NV_STATUS_FLAG to partially working as data may still persist
+ notifyNvdimmProtectionChange(i_nvdimm,NVDIMM_RISKY_HW_ERROR);
+
+ break;
+ }
+
+ }
+
+ return l_continue;
+}
+
+/**
+ * @brief Function checking the Health Status Registers for an nvdimm
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[in] i_step - the nvdimm step calling the check
+ *
+ * @param[out] o_continue - bool to signal a return to caller fail
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t nvdimmHealthStatusCheck(Target *i_nvdimm, uint8_t i_step, bool& o_continue)
+{
+ uint8_t l_data = 0x0;
+ errlHndl_t l_err = nullptr;
+ errlHndl_t l_err_t = nullptr;
+ nvdimm_reg_t l_RegInfo;
+ bool l_arm_timeout = false;
+
+ if (i_step == HEALTH_PRE_ARM)
+ {
+ l_arm_timeout = o_continue;
+ }
+
+ //Collect Register data for parsing and traces
+ nvdimmTraceRegs(i_nvdimm, l_RegInfo);
+
+ // Read SET_EVENT_NOTIFICATION_STATUS register
+ l_err = nvdimmReadReg(i_nvdimm, SET_EVENT_NOTIFICATION_STATUS, l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ l_RegInfo.Set_Event_Notification_Status = l_data;
+
+ // Read RESTORE STATUS register
+ l_err = nvdimmReadReg(i_nvdimm, RESTORE_STATUS , l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ l_RegInfo.Restore_Status = l_data;
+
+ // Read RESTORE_FAIL_INFO register
+ l_err = nvdimmReadReg(i_nvdimm, RESTORE_FAIL_INFO , l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ l_RegInfo.Restore_Fail_Info = l_data;
+
+ // Read NVDIMM_CMD_STATUS0 register
+ l_err = nvdimmReadReg(i_nvdimm, NVDIMM_CMD_STATUS0 , l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ l_RegInfo.NVDimm_CMD_Status0 = l_data;
+
+ // Read ARM_STATUS register
+ l_err = nvdimmReadReg(i_nvdimm, ARM_STATUS , l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ l_RegInfo.Arm_Status = l_data;
+
+ // Read SET_ES_POLICY_STATUS register
+ l_err = nvdimmReadReg(i_nvdimm, SET_ES_POLICY_STATUS , l_data);
+ if(l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ l_RegInfo.Set_ES_Policy_Status = l_data;
+
+ // Check all nvdimm deconfig cases
+ do
+ {
+ // Check MODULE_HEALTH_STATUS0[0]
+ if ((l_RegInfo.Module_Health_Status0 & VOLTAGE_REGULATOR_FAILED) == VOLTAGE_REGULATOR_FAILED)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_VOLTAGE_REGULATOR_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * voltage regulator failure
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_VOLTAGE_REGULATOR_FAILED,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+ // Check MODULE_HEALTH_STATUS0[1]
+ if ((l_RegInfo.Module_Health_Status0 & VDD_LOST) == VDD_LOST)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_VDD_LOST
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * vdd loss
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_VDD_LOST,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+ // Check MODULE_HEALTH_STATUS0[2]
+ if ((l_RegInfo.Module_Health_Status0 & VPP_LOST) == VPP_LOST)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_VPP_LOST
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * vpp loss
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_VPP_LOST,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+ // Check MODULE_HEALTH_STATUS0[3]
+ if ((l_RegInfo.Module_Health_Status0 & VTT_LOST) == VTT_LOST)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_VTT_LOST
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * vtt loss
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_VTT_LOST,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+ // Check MODULE_HEALTH_STATUS0[4]
+ if ((l_RegInfo.Module_Health_Status0 & DRAM_NOT_SELF_REFRESH) == DRAM_NOT_SELF_REFRESH)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_DRAM_NOT_SELF_REFRESH
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * no self refresh on the nvdimm
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_DRAM_NOT_SELF_REFRESH,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+ // Check MODULE_HEALTH_STATUS0[5]
+ if ((l_RegInfo.Module_Health_Status0 & CONTROLLER_HARDWARE_ERROR) == CONTROLLER_HARDWARE_ERROR)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_CONTROLLER_HARDWARE_ERROR
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * error with the hardware controller
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_CONTROLLER_HARDWARE_ERROR,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+ // Check MODULE_HEALTH_STATUS0[6]
+ if ((l_RegInfo.Module_Health_Status0 & NVM_CONTROLLER_ERROR) == NVM_CONTROLLER_ERROR)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_NVM_CONTROLLER_ERROR
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * error with the nvdimm controller
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_NVM_CONTROLLER_ERROR,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+
+ // Check MODULE_HEALTH_STATUS0[7]
+ if ((l_RegInfo.Module_Health_Status0 & NVM_LIFETIME_ERROR) == NVM_LIFETIME_ERROR)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_NVM_LIFETIME_ERROR
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * an nvdimm lifetime error
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_NVM_LIFETIME_ERROR,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+ // Check MODULE_HEALTH_STATUS1[1]
+ if ((l_RegInfo.Module_Health_Status1 & INVALID_FIRMWARE_ERROR) == INVALID_FIRMWARE_ERROR)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_INVALID_FIRMWARE_ERROR
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * an invalid firmware image
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_INVALID_FIRMWARE_ERROR,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+ // Check MODULE_HEALTH_STATUS1[2]
+ if ((l_RegInfo.Module_Health_Status1 & CONFIG_DATA_ERROR) == CONFIG_DATA_ERROR)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_CONFIG_DATA_ERROR
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * invalid configuration data
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_CONFIG_DATA_ERROR,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+ }while(0);
+
+ if (l_err)
+ {
+ // Setup Trace
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err);
+
+ // Callout nvdimm depending on istep call
+ o_continue &= nvdimmCalloutDimm(i_nvdimm, i_step, l_err);
+
+ if(l_arm_timeout)
+ {
+ // Callout and gard the dimm
+ l_err->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_Fatal);
+ }
+ }
+
+ // Check all BPM and Cable high, nvdimm low cases
+ do
+ {
+ // If function calling is SAVE, ignore NOT_ENOUGH_ENERGY_FOR_CSAVE
+ if (i_step != HEALTH_SAVE)
+ {
+ // Check MODULE_HEALTH_STATUS1[0]
+ if ((l_RegInfo.Module_Health_Status1 & NOT_ENOUGH_ENERGY_FOR_CSAVE) == NOT_ENOUGH_ENERGY_FOR_CSAVE)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_NOT_ENOUGH_ENERGY_FOR_CSAVE
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * insufficient energy for csave
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err_t = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_NOT_ENOUGH_ENERGY_FOR_CSAVE,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+ }
+
+ // Check MODULE_HEALTH_STATUS1[3]
+ if ((l_RegInfo.Module_Health_Status1 & NO_ES_PRESENT) == NO_ES_PRESENT)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_NO_ES_PRESENT
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * no ES active
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err_t = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_NO_ES_PRESENT,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+ // Check MODULE_HEALTH_STATUS1[5]
+ if ((l_RegInfo.Module_Health_Status1 & ES_HARDWARE_FAILURE) == ES_HARDWARE_FAILURE)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ES_HARDWARE_FAILURE
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * ES hardware failure
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err_t = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_ES_HARDWARE_FAILURE,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+ // Check MODULE_HEALTH_STATUS1[6]
+ if ((l_RegInfo.Module_Health_Status1 & ES_HEALTH_ASSESSMENT_ERROR) == ES_HEALTH_ASSESSMENT_ERROR)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ES_HEALTH_ASSESSMENT_ERROR
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * ES error during health assessment
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err_t = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_ES_HEALTH_ASSESSMENT_ERROR,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+ }while(0);
+
+ if (l_err_t)
+ {
+ // Setup Trace
+ l_err_t->collectTrace( NVDIMM_COMP_NAME );
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err_t);
+
+ // Callout BPM, Cable, and nvdimm
+ o_continue &= nvdimmBPMCableCallout(i_nvdimm, i_step, l_err_t);
+ }
+
+ // Check for multiple errors and commit old error
+ if ((l_err) && (l_err_t))
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ // If there was a new error, save off to l_err
+ if (l_err_t)
+ {
+ l_err = l_err_t;
+ l_err_t = nullptr;
+ }
+
+ // Check all BPM high, nvdimm low cases
+ do
+ {
+ // Check ERROR_THRESHOLD_STATUS[1]
+ if ((l_RegInfo.Error_Threshold_Status & ES_LIFETIME_ERROR) == ES_LIFETIME_ERROR)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ES_LIFETIME_ERROR
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * ES lifetime error
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err_t = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_ES_LIFETIME_ERROR,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+ // Check ERROR_THRESHOLD_STATUS[2]
+ if ((l_RegInfo.Error_Threshold_Status & ES_TEMP_ERROR) == ES_TEMP_ERROR)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ES_TEMP_ERROR
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * ES temporary error
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err_t = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_ES_TEMP_ERROR,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ break;
+ }
+
+ }while(0);
+
+ if (l_err_t)
+ {
+ // Setup Trace
+ l_err_t->collectTrace( NVDIMM_COMP_NAME );
+
+ // Add reg traces to the error log
+ NVDIMM::UdNvdimmOPParms( l_RegInfo ).addToLog(l_err_t);
+
+ // Callout nvdimm
+ o_continue &= nvdimmBPMCallout(i_nvdimm, i_step, l_err_t);
+ }
+
+ // Check for multiple errors and commit old error
+ if ((l_err) && (l_err_t))
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ // If there was a new error, save off to l_err
+ if (l_err_t)
+ {
+ l_err = l_err_t;
+ l_err_t = nullptr;
+ }
+
+ // Check special pre arm case
+ if (i_step == HEALTH_PRE_ARM)
+ {
+ // Check ES_POLICY_NOT_SET[4]
+ if ((l_RegInfo.Set_ES_Policy_Status & ES_POLICY_NOT_SET) == ES_POLICY_NOT_SET)
+ {
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ES_POLICY_NOT_SET
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_MODULE_HEALTH_STATUS_CHECK
+ *@userdata1[0:31] Target Huid
+ *@userdata2 <UNUSED>
+ *@devdesc NVDIMM failed module health status check due to
+ * ES policy not being set during an arm
+ *@custdesc NVDIMM failed module health status check
+ */
+ l_err_t = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_MODULE_HEALTH_STATUS_CHECK,
+ NVDIMM_ES_POLICY_NOT_SET,
+ TARGETING::get_huid(i_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ o_continue = false;
+ // Callout dimm but no deconfig and gard
+ l_err_t->addHwCallout( i_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+ }
+ }
+
+ // Check for multiple errors and commit old error
+ if ((l_err) && (l_err_t))
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+
+ // If there was a new error, save off to l_err
+ if (l_err_t)
+ {
+ l_err = l_err_t;
+ l_err_t = nullptr;
+ }
+
+ return l_err;
+}
+
+} // end NVDIMM namespace
diff --git a/src/usr/isteps/nvdimm/nvdimmErrorLog.H b/src/usr/isteps/nvdimm/nvdimmErrorLog.H
new file mode 100644
index 000000000..dae8e2f2f
--- /dev/null
+++ b/src/usr/isteps/nvdimm/nvdimmErrorLog.H
@@ -0,0 +1,108 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/isteps/nvdimm/nvdimmErrorLog.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef NVDIMM_ERROR_LOG_H__
+#define NVDIMM_ERROR_LOG_H__
+
+#include <usr/errl/errlentry.H>
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/util.H>
+#include <targeting/common/utilFilter.H>
+#include <i2c/eepromif.H>
+#include <map>
+#include "nvdimmdd.H"
+#include "nvdimm.H"
+
+using namespace TARGETING;
+using namespace EEPROM;
+
+// Trace definition
+extern trace_desc_t* g_trac_nvdimm;
+
+namespace NVDIMM
+{
+
+/**
+ * @brief Function to read and save status registers for traces
+ *
+ * @param[in] i_nvdimm - nvdimm target with NV controller
+ *
+ * @param[out] o_RegInfo - the structure holding the register data
+ *
+ */
+void nvdimmTraceRegs(Target *i_nvdimm, nvdimm_reg_t& o_RegInfo);
+
+/**
+ * @brief Helper function for standard callout of an NVDIMM
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[out] o_err - error log handler to be modified
+ *
+ * @return bool - true to commit log and continue, false to return
+ * the error log to caller and exit.
+ */
+bool nvdimmCalloutDimm(Target *i_nvdimm, uint8_t i_step, errlHndl_t& o_err);
+
+/**
+ * @brief Helper function for BPM/Cable high, NVDIMM low callout
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[out] o_err - error log handler to be modified
+ *
+ * @return bool - true to commit log and continue, false to return
+ * the error log to caller and exit.
+ */
+bool nvdimmBPMCableCallout(Target *i_nvdimm, uint8_t i_step, errlHndl_t& o_err);
+
+/**
+ * @brief Helper function for BPM high, NVDIMM low callout
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[out] o_err - error log handler to be modified
+ *
+ * @return bool - true to commit log and continue, false to return
+ * the error log to caller and exit.
+ */
+bool nvdimmBPMCallout(Target *i_nvdimm, uint8_t i_step, errlHndl_t& o_err);
+
+/**
+ * @brief Function checking the Health Status Registers for an nvdimm
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[out] o_exit - bool to signify exit procedure
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t nvdimmHealthStatusCheck(Target *i_nvdimm, uint8_t i_step, bool& o_continue);
+
+} //End NVDIMM namespace
+
+
+#endif // NVDIMM_ERROR_LOG_H__
diff --git a/src/usr/isteps/nvdimm/nvdimm_update.C b/src/usr/isteps/nvdimm/nvdimm_update.C
index 2e1f61c8c..6075a660f 100644
--- a/src/usr/isteps/nvdimm/nvdimm_update.C
+++ b/src/usr/isteps/nvdimm/nvdimm_update.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -26,6 +26,7 @@
#include "nvdimm.H"
#include <isteps/nvdimm/nvdimm.H>
#include <isteps/nvdimm/nvdimmreasoncodes.H>
+#include "bpm_update.H"
#include <initservice/istepdispatcherif.H> // sendProgressCode
#include <util/utilmclmgr.H> // secure LID manager
@@ -33,6 +34,7 @@
#include <devicefw/userif.H>
#include <vpd/spdenums.H>
#include <sys/time.h>
+#include <vector>
// Unique tracing for nvdimm update process
const char NVDIMM_UPD[] = "NVDIMM_UPD";
@@ -41,7 +43,7 @@ TRAC_INIT(&g_trac_nvdimm_upd, NVDIMM_UPD, 2*KILOBYTE);
// Easy macro replace for unit testing
-// #define TRACUCOMP(args...) TRACFCOMP(args)
+//#define TRACUCOMP(args...) TRACFCOMP(args)
#define TRACUCOMP(args...)
namespace NVDIMM
@@ -144,8 +146,10 @@ typedef union {
} nvdimm_cmd_status0_t;
// A code update block is composed of this many bytes
-const uint8_t BYTES_PER_BLOCK = 32;
+constexpr uint8_t BYTES_PER_BLOCK = 32;
+// Maximum allowed region write retries
+constexpr uint8_t MAX_REGION_WRITE_RETRY_ATTEMPTS = 3;
///////////////////////////////////////////////////////////////////////////////
// NVDIMM LID Image
@@ -182,6 +186,7 @@ uint16_t NvdimmLidImage::getVersion()
return o_version;
}
+
const uint8_t * NvdimmLidImage::getHeaderAndSmartSignature(uint16_t & o_size)
{
o_size = 0;
@@ -264,7 +269,10 @@ NvdimmInstalledImage::NvdimmInstalledImage(TARGETING::Target * i_nvDimm) :
iv_dimm(i_nvDimm), iv_version(INVALID_VERSION),
iv_manufacturer_id(INVALID_ID), iv_product_id(INVALID_ID),
iv_timeout(INVALID_TIMEOUT),
- iv_max_blocks_per_region(INVALID_REGION_BLOCK_SIZE)
+ iv_max_blocks_per_region(INVALID_REGION_BLOCK_SIZE),
+ iv_fw_update_mode_enabled(false),
+ iv_region_write_retries(0),
+ iv_blockSizeSupported(INVALID_BLOCK_SIZE)
{
// initialize to invalid values
}
@@ -350,12 +358,50 @@ errlHndl_t NvdimmInstalledImage::getVersion(uint16_t & o_version,
return l_err;
}
+errlHndl_t NvdimmInstalledImage::getBlockWriteSizeSupported(uint64_t & o_blockSize)
+{
+ errlHndl_t l_err = nullptr;
+
+ do {
+ if (iv_blockSizeSupported == INVALID_BLOCK_SIZE)
+ {
+ uint16_t version = INVALID_VERSION;
+ l_err = getVersion(version, 0);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm_upd, ERR_MRK"getBlockWriteSizeSupported: "
+ "Failed to get version for 0x%.8X NVDIMM",
+ TARGETING::get_huid(iv_dimm));
+ break;
+ }
+
+ // The block write is more prone to random system interrupt
+ // which does something funny to the i2c bus.
+ // v3.A has the timeout increased to mitigate that
+ if (version >= 0x3A00)
+ {
+ // version supports 32-byte block size
+ iv_blockSizeSupported = 32;
+ }
+ else
+ {
+ // default to word size max write
+ iv_blockSizeSupported = sizeof(uint16_t);
+ }
+ TRACFCOMP( g_trac_nvdimm_upd, ERR_MRK"getBlockWriteSizeSupported: "
+ "block size %d supported for 0x%.8X NVDIMM (version 0x%04X)",
+ iv_blockSizeSupported, TARGETING::get_huid(iv_dimm),
+ version );
+ }
+ } while (0);
+ o_blockSize = iv_blockSizeSupported;
+ return l_err;
+}
errlHndl_t NvdimmInstalledImage::updateImage(NvdimmLidImage * i_lidImage)
{
errlHndl_t l_err = nullptr;
- // need to always disable this after it gets enabled
- bool l_fw_update_mode_enabled = false;
+
do {
INITSERVICE::sendProgressCode();
////////////////////////////////////////////////////////////////////////
@@ -381,7 +427,7 @@ errlHndl_t NvdimmInstalledImage::updateImage(NvdimmLidImage * i_lidImage)
TRACFCOMP(g_trac_nvdimm_upd,ERR_MRK"updateImage: "
"NV controller is busy (0x%08X) for NVDIMM 0x%.8X",
l_status.whole, TARGETING::get_huid(iv_dimm));
- /*
+ /*@
*@errortype
*@moduleid UPDATE_IMAGE
*@reasoncode NVDIMM_OPERATION_IN_PROGRESS
@@ -398,11 +444,14 @@ errlHndl_t NvdimmInstalledImage::updateImage(NvdimmLidImage * i_lidImage)
l_status.whole,
ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
l_err->collectTrace( NVDIMM_COMP_NAME, 256 );
+ nvdimmAddVendorLog(iv_dimm, l_err);
l_err->addPartCallout( iv_dimm,
HWAS::NV_CONTROLLER_PART_TYPE,
HWAS::SRCI_PRIORITY_HIGH );
l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
HWAS::SRCI_PRIORITY_LOW );
+ nvdimmAddPage4Regs(iv_dimm,l_err);
+ nvdimmAddUpdateRegs(iv_dimm,l_err);
break;
}
@@ -427,8 +476,6 @@ errlHndl_t NvdimmInstalledImage::updateImage(NvdimmLidImage * i_lidImage)
TARGETING::get_huid(iv_dimm));
break;
}
- // Set this flag so we will disable the update mode on error
- l_fw_update_mode_enabled = true;
// 5. Clear the Firmware Operation status
TRACUCOMP(g_trac_nvdimm_upd, "updateImage: step 5");
@@ -549,7 +596,7 @@ errlHndl_t NvdimmInstalledImage::updateImage(NvdimmLidImage * i_lidImage)
"NVDIMM 0x%.8X: data checksums mismatch (calc host: 0x%X "
"and nv: 0x%X) for first part (header + SMART signature)",
TARGETING::get_huid(iv_dimm), hostCksm, nvCksm);
- /*
+ /*@
*@errortype
*@moduleid UPDATE_IMAGE
*@reasoncode NVDIMM_CHECKSUM_ERROR
@@ -571,6 +618,7 @@ errlHndl_t NvdimmInstalledImage::updateImage(NvdimmLidImage * i_lidImage)
0x0000),
ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
l_err->collectTrace( NVDIMM_COMP_NAME, 256 );
+ nvdimmAddVendorLog(iv_dimm, l_err);
// maybe some data was altered on the NV controller
l_err->addPartCallout( iv_dimm,
@@ -579,6 +627,8 @@ errlHndl_t NvdimmInstalledImage::updateImage(NvdimmLidImage * i_lidImage)
// possible code issue
l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
HWAS::SRCI_PRIORITY_LOW );
+ nvdimmAddPage4Regs(iv_dimm,l_err);
+ nvdimmAddUpdateRegs(iv_dimm,l_err);
break;
}
@@ -641,7 +691,6 @@ errlHndl_t NvdimmInstalledImage::updateImage(NvdimmLidImage * i_lidImage)
// 12. Disable firmware update mode
TRACUCOMP(g_trac_nvdimm_upd, "updateImage: step 12");
- l_fw_update_mode_enabled = false; // don't retry the disable on error
l_err = changeFwUpdateMode(FW_UPDATE_MODE_DISABLED);
if (l_err)
{
@@ -668,7 +717,7 @@ errlHndl_t NvdimmInstalledImage::updateImage(NvdimmLidImage * i_lidImage)
// Reset controller to activate new firmware
TRACUCOMP(g_trac_nvdimm_upd, "updateImage: resetController");
- l_err = resetController();
+ l_err = nvdimmResetController(iv_dimm);
if (l_err)
{
TRACFCOMP(g_trac_nvdimm_upd, ERR_MRK "updateImage: "
@@ -701,7 +750,7 @@ errlHndl_t NvdimmInstalledImage::updateImage(NvdimmLidImage * i_lidImage)
} while (0);
// If update operation is aborted, we need to disable update mode
- if (l_fw_update_mode_enabled)
+ if (iv_fw_update_mode_enabled)
{
TRACFCOMP(g_trac_nvdimm_upd, "updateImage: update was aborted, so disable FW_UPDATE_MODE");
errlHndl_t l_err2 = changeFwUpdateMode(FW_UPDATE_MODE_DISABLED);
@@ -765,7 +814,7 @@ errlHndl_t NvdimmInstalledImage::updateImageData(NvdimmLidImage * i_lidImage)
}
if (fw_img_total_regions == 0)
{
- /*
+ /*@
*@errortype
*@moduleid UPDATE_IMAGE_DATA
*@reasoncode NVDIMM_ZERO_TOTAL_REGIONS
@@ -787,6 +836,8 @@ errlHndl_t NvdimmInstalledImage::updateImageData(NvdimmLidImage * i_lidImage)
0x00000000),
ERRORLOG::ErrlEntry::ADD_SW_CALLOUT );
l_err->collectTrace( NVDIMM_COMP_NAME, 256 );
+ nvdimmAddPage4Regs(iv_dimm,l_err);
+ nvdimmAddUpdateRegs(iv_dimm,l_err);
break;
}
@@ -812,11 +863,15 @@ errlHndl_t NvdimmInstalledImage::updateImageData(NvdimmLidImage * i_lidImage)
break;
}
+ uint8_t l_region_write_retries = 0; // local region write retry count
uint16_t region = 0;
while (region < fw_img_total_regions)
{
- if (region % 10 == 0)
+ if (region % 100 == 0)
{
+ TRACFCOMP(g_trac_nvdimm_upd,
+ "updateImage: progress code for sending region %d",
+ region);
INITSERVICE::sendProgressCode();
}
TRACUCOMP(g_trac_nvdimm_upd, "updateImage: step 10.a - region 0x%04X",
@@ -914,15 +969,17 @@ errlHndl_t NvdimmInstalledImage::updateImageData(NvdimmLidImage * i_lidImage)
if (hostCksm != nvCksm)
{
TRACFCOMP(g_trac_nvdimm_upd, ERR_MRK"updateImageData: "
- "Region %d of NVDIMM 0x%.8X: data checksums mismatch "
+ "Region %d out of %d on NVDIMM 0x%.8X: data checksums mismatch "
"(calc host: 0x%X and nv: 0x%X)",
- region, TARGETING::get_huid(iv_dimm), hostCksm, nvCksm);
+ region, fw_img_total_regions,
+ TARGETING::get_huid(iv_dimm), hostCksm, nvCksm);
- /*
+ /*@
*@errortype
*@moduleid UPDATE_IMAGE_DATA
*@reasoncode NVDIMM_CHECKSUM_ERROR
- *@userdata1 NVDIMM Target Huid
+ *@userdata1[0:31] NVDIMM Target Huid
+ *@userdata1[32:63] Retry count for this region
*@userdata2[0:15] Host checksum calculated
*@userdata2[16:31] NV checksum returned
*@userdata2[32:47] size of data for checksum
@@ -934,18 +991,44 @@ errlHndl_t NvdimmInstalledImage::updateImageData(NvdimmLidImage * i_lidImage)
ERRORLOG::ERRL_SEV_PREDICTIVE,
UPDATE_IMAGE_DATA,
NVDIMM_CHECKSUM_ERROR,
- TARGETING::get_huid(iv_dimm),
+ TWO_UINT32_TO_UINT64(
+ TARGETING::get_huid(iv_dimm),
+ l_region_write_retries),
FOUR_UINT16_TO_UINT64(
hostCksm, nvCksm,
region, data_len),
ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
- l_err->collectTrace( NVDIMM_COMP_NAME, 256 );
+ nvdimmAddVendorLog(iv_dimm, l_err);
l_err->addPartCallout( iv_dimm,
HWAS::NV_CONTROLLER_PART_TYPE,
HWAS::SRCI_PRIORITY_HIGH );
l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
HWAS::SRCI_PRIORITY_LOW );
+ nvdimmAddPage4Regs(iv_dimm,l_err);
+ nvdimmAddUpdateRegs(iv_dimm,l_err);
+
+ // Under the total retry attempts per region?
+ if (l_region_write_retries < MAX_REGION_WRITE_RETRY_ATTEMPTS)
+ {
+ TRACFCOMP(g_trac_nvdimm_upd, ERR_MRK"updateImageData: "
+ "Region %d on NVDIMM 0x%.8X failed, retry %d",
+ region, TARGETING::get_huid(iv_dimm),l_region_write_retries);
+ l_err->collectTrace(NVDIMM_UPD, 512);
+
+ // Change PREDICTIVE to INFORMATIONAL as this might be recoverable
+ l_err->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);
+
+ // Commit this log and retry region write
+ ERRORLOG::errlCommit(l_err, NVDIMM_COMP_ID);
+ l_err = nullptr;
+
+ // Update total for this region
+ l_region_write_retries++;
+ // update total retries for entire NVDIMM
+ iv_region_write_retries++;
+ continue;
+ }
break;
}
@@ -989,7 +1072,7 @@ errlHndl_t NvdimmInstalledImage::changeFwUpdateMode(fw_update_mode i_mode)
((i_mode == FW_UPDATE_MODE_DISABLED) &&
(opStatus.fw_ops_update_mode == 0))) )
{
- /*
+ /*@
*@errortype
*@moduleid CHANGE_FW_UPDATE_MODE
*@reasoncode NVDIMM_UPDATE_MODE_UNCHANGED
@@ -1009,11 +1092,25 @@ errlHndl_t NvdimmInstalledImage::changeFwUpdateMode(fw_update_mode i_mode)
0x00, 0x00),
ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
l_err->collectTrace( NVDIMM_COMP_NAME, 256 );
+ nvdimmAddVendorLog(iv_dimm, l_err);
l_err->addPartCallout( iv_dimm,
HWAS::NV_CONTROLLER_PART_TYPE,
HWAS::SRCI_PRIORITY_HIGH );
l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
HWAS::SRCI_PRIORITY_LOW );
+ nvdimmAddPage4Regs(iv_dimm,l_err);
+ nvdimmAddUpdateRegs(iv_dimm,l_err);
+ }
+ else
+ {
+ if (opStatus.fw_ops_update_mode == 1)
+ {
+ iv_fw_update_mode_enabled = true;
+ }
+ else
+ {
+ iv_fw_update_mode_enabled = false;
+ }
}
}
}
@@ -1025,8 +1122,9 @@ errlHndl_t NvdimmInstalledImage::waitFwOpsBlockReceived()
{
errlHndl_t l_err = nullptr;
- // retry for a total of 100ms
- uint32_t timeout_ms_val = 100;
+ // retry for a total of 500ms
+ const uint32_t MAX_WAIT_FOR_OPS_BLOCK_RECEIVED = 500;
+ uint32_t timeout_ms_val = MAX_WAIT_FOR_OPS_BLOCK_RECEIVED;
bool blockReceived = false;
fw_ops_status_t opStatus;
@@ -1042,6 +1140,7 @@ errlHndl_t NvdimmInstalledImage::waitFwOpsBlockReceived()
TARGETING::get_huid(iv_dimm), timeout_ms_val);
break;
}
+
if (!opStatus.fw_ops_block_received)
{
// wait 1 millisecond between checking status
@@ -1066,7 +1165,13 @@ errlHndl_t NvdimmInstalledImage::waitFwOpsBlockReceived()
if (!blockReceived && !l_err)
{
- /*
+ TRACFCOMP(g_trac_nvdimm_upd, ERR_MRK"waitFwOpsBlockReceived: "
+ "NVDIMM 0x%.8X FIRMWARE_OPS_STATUS (timeout: %d ms) "
+ "-- Last status: 0x%02X",
+ TARGETING::get_huid(iv_dimm), MAX_WAIT_FOR_OPS_BLOCK_RECEIVED,
+ opStatus.whole);
+
+ /*@
*@errortype
*@moduleid WAIT_FW_OPS_BLOCK_RECEIVED
*@reasoncode NVDIMM_BLOCK_NOT_RECEIVED
@@ -1086,16 +1191,19 @@ errlHndl_t NvdimmInstalledImage::waitFwOpsBlockReceived()
(
TWO_UINT8_TO_UINT16( 0x00,
opStatus.whole),
- 100,
+ MAX_WAIT_FOR_OPS_BLOCK_RECEIVED,
timeout_ms_val
),
ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
l_err->collectTrace(NVDIMM_COMP_NAME, 512 );
+ nvdimmAddVendorLog(iv_dimm, l_err);
l_err->addPartCallout( iv_dimm,
HWAS::NV_CONTROLLER_PART_TYPE,
HWAS::SRCI_PRIORITY_HIGH );
l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
HWAS::SRCI_PRIORITY_LOW );
+ nvdimmAddPage4Regs(iv_dimm,l_err);
+ nvdimmAddUpdateRegs(iv_dimm,l_err);
}
return l_err;
@@ -1145,7 +1253,7 @@ errlHndl_t NvdimmInstalledImage::waitFwOpsComplete()
if (!opsComplete && !l_err)
{
- /*
+ /*@
*@errortype
*@moduleid WAIT_FW_OPS_COMPLETE
*@reasoncode NVDIMM_FW_OPS_IN_PROGRESS_TIMEOUT
@@ -1169,11 +1277,14 @@ errlHndl_t NvdimmInstalledImage::waitFwOpsComplete()
),
ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
l_err->collectTrace(NVDIMM_COMP_NAME, 256 );
+ nvdimmAddVendorLog(iv_dimm, l_err);
l_err->addPartCallout( iv_dimm,
HWAS::NV_CONTROLLER_PART_TYPE,
HWAS::SRCI_PRIORITY_HIGH );
l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
HWAS::SRCI_PRIORITY_LOW );
+ nvdimmAddPage4Regs(iv_dimm,l_err);
+ nvdimmAddUpdateRegs(iv_dimm,l_err);
}
}
return l_err;
@@ -1234,6 +1345,103 @@ errlHndl_t NvdimmInstalledImage::clearFwOpsStatus()
"NVDIMM 0x%.8X clear FIRMWARE_OPS_STATUS register failed",
TARGETING::get_huid(iv_dimm));
}
+ else
+ {
+ // Verify expected bits cleared
+
+ // Setup expected cleared status byte
+ fw_ops_status_t l_cleared_ops_status;
+ l_cleared_ops_status.whole = 0x00;
+ if (iv_fw_update_mode_enabled)
+ {
+ // set BIT 2 -- this should not be cleared by the command
+ l_cleared_ops_status.fw_ops_update_mode = 1;
+ }
+
+ // Set some timeout so this doesn't cause endless loop
+ uint16_t timeout_val = INVALID_TIMEOUT;
+ l_err = getFwOpsTimeout(timeout_val);
+ // Note: potential error will just exit the while loop and be returned
+
+ // convert seconds to ms value
+ // double the timeout to ensure enough time has elapsed for the clear
+ // note: doubling here instead of just doubling timeout_val since that
+ // variable is only a bit16 vs bit32
+ uint32_t timeout_ms_val = timeout_val * 1000 * 2;
+
+ fw_ops_status_t l_ops_status;
+
+ while (!l_err)
+ {
+ l_err = nvdimmReadReg(iv_dimm, FIRMWARE_OPS_STATUS, l_ops_status.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm_upd, ERR_MRK"clearFwOpsStatus: "
+ "NVDIMM 0x%.8X read FIRMWARE_OPS_STATUS register failed "
+ " (0x%02X)",
+ TARGETING::get_huid(iv_dimm), l_ops_status.whole);
+ break;
+ }
+
+ // Exit if expected cleared status is found
+ if (l_ops_status.whole == l_cleared_ops_status.whole)
+ {
+ break;
+ }
+
+ // wait 1 millisecond between checking status
+ if (timeout_ms_val > 0)
+ {
+ timeout_ms_val -= 1;
+ nanosleep(0, NS_PER_MSEC);
+ }
+ else
+ {
+ // timeout hit
+ TRACFCOMP(g_trac_nvdimm_upd, ERR_MRK"clearFwOpsStatus: "
+ "NVDIMM 0x%.8X FIRMWARE_OPS_STATUS register reads 0x%02X "
+ "instead of cleared value of 0x%02X after %lld seconds",
+ TARGETING::get_huid(iv_dimm), l_ops_status.whole,
+ l_cleared_ops_status.whole, timeout_val*2);
+
+ /*@
+ *@errortype
+ *@moduleid CLEAR_FW_OPS_STATUS
+ *@reasoncode NVDIMM_CLEAR_FW_OPS_STATUS_TIMEOUT
+ *@userdata1 NVDIMM Target Huid
+ *@userdata2[0:7] Last FIRMWARE_OPS_STATUS read
+ *@userdata2[8:15] Expected cleared status
+ *@userdata2[16:31] Reserved
+ *@userdata2[32:63] Timeout (seconds)
+ *@devdesc FIRMWARE_OPS_STATUS not cleared
+ *@custdesc NVDIMM not updated
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ CLEAR_FW_OPS_STATUS,
+ NVDIMM_CLEAR_FW_OPS_STATUS_TIMEOUT,
+ TARGETING::get_huid(iv_dimm),
+ TWO_UINT16_ONE_UINT32_TO_UINT64
+ (
+ TWO_UINT8_TO_UINT16(
+ l_ops_status.whole,
+ l_cleared_ops_status.whole),
+ 0x0000,
+ timeout_val * 2
+ ),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ l_err->collectTrace(NVDIMM_COMP_NAME, 256);
+ l_err->addPartCallout( iv_dimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH );
+ l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_LOW );
+
+ break;
+ }
+ } // end of while (!l_err) loop
+ } // end of Verify expected bits cleared
+
return l_err;
}
@@ -1317,7 +1525,7 @@ errlHndl_t NvdimmInstalledImage::byteRegionBlockTransfer(const uint8_t * i_data,
}
if (blocks_per_region > max_blocks_per_region)
{
- /*
+ /*@
*@errortype
*@moduleid BYTE_REGION_BLOCK_TRANSFER
*@reasoncode NVDIMM_DATA_SIZE_TOO_LARGE
@@ -1352,7 +1560,7 @@ errlHndl_t NvdimmInstalledImage::byteRegionBlockTransfer(const uint8_t * i_data,
if (i_data_size > (BYTES_PER_BLOCK*blocks_per_region))
{
- /*
+ /*@
*@errortype
*@moduleid BYTE_REGION_BLOCK_TRANSFER
*@reasoncode NVDIMM_DATA_SIZE_INVALID
@@ -1421,15 +1629,29 @@ errlHndl_t NvdimmInstalledImage::byteRegionBlockTransfer(const uint8_t * i_data,
TRACFCOMP(g_trac_nvdimm_upd, ERR_MRK"byteRegionBlockTransfer: "
"Unable to open page for BLOCK %d transfer of NVDIMM "
"0x%.8X", blockNum, TARGETING::get_huid(iv_dimm));
+ break;
}
size_t l_numBytes = BYTES_PER_BLOCK;
uint8_t l_reg_addr = ADDRESS(TYPED_BLOCK_DATA_BYTE0);
+
+ // Grab whether word or 32-byte block write is supported
+ uint64_t blockSizeSupported = INVALID_BLOCK_SIZE;
+ l_err = getBlockWriteSizeSupported(blockSizeSupported);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm_upd, ERR_MRK"byteRegionBlockTransfer: "
+ "Unable to grab maximum block write size for NVDIMM 0x%.8X",
+ TARGETING::get_huid(iv_dimm));
+ break;
+ }
+
l_err = DeviceFW::deviceOp( DeviceFW::WRITE,
iv_dimm,
pCurrentBlockData,
l_numBytes,
- DEVICE_NVDIMM_ADDRESS(l_reg_addr) );
+ DEVICE_NVDIMM_RAW_ADDRESS_WITH_BLOCKSIZE(l_reg_addr, blockSizeSupported)
+ );
if (l_err)
{
TRACFCOMP(g_trac_nvdimm_upd, ERR_MRK"byteRegionBlockTransfer: "
@@ -1437,8 +1659,6 @@ errlHndl_t NvdimmInstalledImage::byteRegionBlockTransfer(const uint8_t * i_data,
blockNum, l_reg_addr, TARGETING::get_huid(iv_dimm));
break;
}
- // increment to next block
- pCurrentBlockData += BYTES_PER_BLOCK;
// After a block has been transferred, verify that the 32-byte block
// was received by polling FIRMWARE_OPS_STATUS offset for
@@ -1449,10 +1669,39 @@ errlHndl_t NvdimmInstalledImage::byteRegionBlockTransfer(const uint8_t * i_data,
TRACFCOMP(g_trac_nvdimm_upd, ERR_MRK"byteRegionBlockTransfer: "
"Block %d read of FIRMWARE_OPS_STATUS failed on NVDIMM "
" 0x%.8X", blockNum, TARGETING::get_huid(iv_dimm));
+
+ size_t tmpNumBytes = l_numBytes;
+ uint8_t tmpBuffer[tmpNumBytes];
+ errlHndl_t l_err2 = DeviceFW::deviceOp( DeviceFW::READ,
+ iv_dimm,
+ tmpBuffer,
+ tmpNumBytes,
+ DEVICE_NVDIMM_ADDRESS(l_reg_addr) );
+ if (l_err2)
+ {
+ TRACFCOMP(g_trac_nvdimm_upd, ERR_MRK"byteRegionBlockTransfer: "
+ "Block %d read from 0x%02X failed on NVDIMM 0x%.8X",
+ blockNum, l_reg_addr, TARGETING::get_huid(iv_dimm));
+ l_err2->plid(l_err->plid());
+ l_err2->collectTrace(NVDIMM_COMP_NAME);
+ l_err2->collectTrace(NVDIMM_UPD);
+ errlCommit(l_err2, NVDIMM_COMP_ID);
+ break;
+ }
+ else
+ {
+ TRACFBIN(g_trac_nvdimm_upd, "byteRegionBlockTransfer: Wrote block", pCurrentBlockData, l_numBytes);
+ TRACFBIN(g_trac_nvdimm_upd, "byteRegionBlockTransfer: Read-back block", tmpBuffer, l_numBytes);
+ }
+
break;
}
+
// block of data successfully sent to NV controller
TRACUCOMP(g_trac_nvdimm_upd,"byteRegionBlockTransfer: block 0x%02X successfully sent to NV controller", blockNum);
+
+ // increment to next block
+ pCurrentBlockData += BYTES_PER_BLOCK;
blockNum++;
}
@@ -1516,7 +1765,7 @@ errlHndl_t NvdimmInstalledImage::validateFwHeader()
l_err = isFwOpsSuccess(opsSuccessful);
if (!l_err && !opsSuccessful)
{
- /*
+ /*@
*@errortype
*@moduleid VALIDATE_FW_HEADER
*@reasoncode NVDIMM_FW_OPS_NOT_SUCCESSFUL
@@ -1533,11 +1782,14 @@ errlHndl_t NvdimmInstalledImage::validateFwHeader()
opsCmd.whole,
ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
l_err->collectTrace(NVDIMM_COMP_NAME, 256 );
+ nvdimmAddVendorLog(iv_dimm, l_err);
l_err->addPartCallout( iv_dimm,
HWAS::NV_CONTROLLER_PART_TYPE,
HWAS::SRCI_PRIORITY_HIGH );
l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
HWAS::SRCI_PRIORITY_LOW );
+ nvdimmAddPage4Regs(iv_dimm,l_err);
+ nvdimmAddUpdateRegs(iv_dimm,l_err);
}
}
}
@@ -1565,7 +1817,7 @@ errlHndl_t NvdimmInstalledImage::commitFwRegion()
l_err = isFwOpsSuccess(opsSuccessful);
if (!l_err && !opsSuccessful)
{
- /*
+ /*@
*@errortype
*@moduleid COMMIT_FW_REGION
*@reasoncode NVDIMM_FW_OPS_NOT_SUCCESSFUL
@@ -1582,11 +1834,14 @@ errlHndl_t NvdimmInstalledImage::commitFwRegion()
opsCmd.whole,
ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
l_err->collectTrace(NVDIMM_COMP_NAME, 256 );
+ nvdimmAddVendorLog(iv_dimm, l_err);
l_err->addPartCallout( iv_dimm,
HWAS::NV_CONTROLLER_PART_TYPE,
HWAS::SRCI_PRIORITY_HIGH );
l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
HWAS::SRCI_PRIORITY_LOW );
+ nvdimmAddPage4Regs(iv_dimm,l_err);
+ nvdimmAddUpdateRegs(iv_dimm,l_err);
}
}
}
@@ -1615,7 +1870,7 @@ errlHndl_t NvdimmInstalledImage::clearFwDataBlock()
l_err = isFwOpsSuccess(ops_success);
if (!l_err && !ops_success)
{
- /*
+ /*@
*@errortype
*@moduleid CLEAR_FW_DATA_BLOCK
*@reasoncode NVDIMM_FW_OPS_NOT_SUCCESSFUL
@@ -1632,11 +1887,14 @@ errlHndl_t NvdimmInstalledImage::clearFwDataBlock()
opsCmd.whole,
ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
l_err->collectTrace(NVDIMM_COMP_NAME, 256 );
+ nvdimmAddVendorLog(iv_dimm, l_err);
l_err->addPartCallout( iv_dimm,
HWAS::NV_CONTROLLER_PART_TYPE,
HWAS::SRCI_PRIORITY_HIGH );
l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
HWAS::SRCI_PRIORITY_LOW );
+ nvdimmAddPage4Regs(iv_dimm,l_err);
+ nvdimmAddUpdateRegs(iv_dimm,l_err);
}
}
}
@@ -1664,7 +1922,7 @@ errlHndl_t NvdimmInstalledImage::validateFwImage()
// create an error if operation not successful
if (!l_err && !opsSuccessful)
{
- /*
+ /*@
*@errortype
*@moduleid VALIDATE_FW_IMAGE
*@reasoncode NVDIMM_FW_OPS_NOT_SUCCESSFUL
@@ -1681,12 +1939,14 @@ errlHndl_t NvdimmInstalledImage::validateFwImage()
opsCmd.whole,
ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
l_err->collectTrace(NVDIMM_COMP_NAME, 256 );
+ nvdimmAddVendorLog(iv_dimm, l_err);
l_err->addPartCallout( iv_dimm,
HWAS::NV_CONTROLLER_PART_TYPE,
HWAS::SRCI_PRIORITY_HIGH );
l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
HWAS::SRCI_PRIORITY_LOW );
-
+ nvdimmAddPage4Regs(iv_dimm,l_err);
+ nvdimmAddUpdateRegs(iv_dimm,l_err);
}
}
}
@@ -1694,41 +1954,6 @@ errlHndl_t NvdimmInstalledImage::validateFwImage()
return l_err;
}
-errlHndl_t NvdimmInstalledImage::resetController()
-{
- errlHndl_t l_err = nullptr;
-
- // If bit 0 is set, the module shall start a Reset Controller operation
- l_err = nvdimmWriteReg(iv_dimm, NVDIMM_MGT_CMD0, 0x01);
- if (l_err)
- {
- TRACFCOMP(g_trac_nvdimm_upd,ERR_MRK"resetController: NVDIMM 0x%.8X "
- "write of 0x01 to NVDIMM_MGT_CMD0 register failed",
- TARGETING::get_huid(iv_dimm));
- }
- else
- {
- TRACUCOMP(g_trac_nvdimm_upd,"resetController: waiting 5 seconds after controller 0x%.8X reset",
- TARGETING::get_huid(iv_dimm));
-
- // sleep 5 seconds to allow for i2c controller to come back online
- nanosleep(5,0);
-
- TRACUCOMP(g_trac_nvdimm_upd,"resetController: now check if NV controller is ready again",
- TARGETING::get_huid(iv_dimm));
-
- // Now wait until NV controller is ready again after reset
- l_err = nvdimmReady(iv_dimm);
- if (l_err)
- {
- TRACFCOMP(g_trac_nvdimm_upd,ERR_MRK"resetController: NV controller for "
- "NVDIMM 0x%.8X is not reporting as ready after reset",
- TARGETING::get_huid(iv_dimm));
- }
- }
- return l_err;
-}
-
uint16_t NvdimmInstalledImage::crc16(const uint8_t * i_data, int i_data_size)
{
// From JEDEC JESD245B.01 document
@@ -1769,6 +1994,9 @@ bool NvdimmsUpdate::runUpdateUsingLid(NvdimmLidImage * i_lidImage,
errlHndl_t l_err = nullptr;
for (auto pInstalledImage : i_list)
{
+ TARGETING::Target * l_nvdimm = pInstalledImage->getNvdimmTarget();
+ uint64_t l_nvdimm_huid = TARGETING::get_huid(l_nvdimm);
+
INITSERVICE::sendProgressCode();
bool updateNeeded = false;
l_err = isUpdateNeeded(updateNeeded, i_lidImage, pInstalledImage);
@@ -1785,14 +2013,69 @@ bool NvdimmsUpdate::runUpdateUsingLid(NvdimmLidImage * i_lidImage,
}
else if (updateNeeded)
{
+ // shared trace variables
+ uint32_t l_installed_type = INVALID_TYPE;
+ l_err = pInstalledImage->getType(l_installed_type);
+ if (l_err)
+ {
+ // Continue updating other dimms
+ TRACFCOMP(g_trac_nvdimm_upd,
+ ERR_MRK"NvdimmsUpdate::runUpdateUsingLid() - "
+ "Unable to get nvdimm[0x%.8X] installed image type. "
+ "RC=0x%X, PLID=0x%.8X", l_nvdimm_huid,
+ ERRL_GETRC_SAFE(l_err), ERRL_GETPLID_SAFE(l_err));
+ commitPredictiveNvdimmError(l_err);
+ l_err = nullptr;
+ continue;
+ }
+
+ uint16_t l_oldVersion = INVALID_VERSION;
+ l_err = pInstalledImage->getVersion(l_oldVersion);
+ if (l_err)
+ {
+ // This shouldn't happen as getVersion should return a
+ // cached version
+ TRACFCOMP(g_trac_nvdimm_upd,
+ ERR_MRK"NvdimmsUpdate::runUpdateUsingLid() - "
+ "Failed to find current NVDIMM level of %.8X. "
+ "RC=0x%X, PLID=0x%.8X", l_nvdimm_huid,
+ ERRL_GETRC_SAFE(l_err), ERRL_GETPLID_SAFE(l_err));
+ commitPredictiveNvdimmError(l_err);
+ l_err = nullptr;
+ o_no_error_found = false;
+ continue;
+ }
+
// perform update for this DIMM with the current LID image
TRACFCOMP(g_trac_nvdimm_upd, "NvdimmsUpdate::runUpdateUsingLid() - "
- "now update nvdimm[0x%.8X]",
- TARGETING::get_huid(pInstalledImage->getNvdimmTarget()));
+ "now update nvdimm[0x%.8X]", l_nvdimm_huid);
TRACFCOMP(g_trac_nvdimm_upd,"Updating with flash size: 0x%08X",
i_lidImage->getFlashImageSize());
+ /*@
+ *@errortype INFORMATIONAL
+ *@reasoncode NVDIMM_START_UPDATE
+ *@moduleid NVDIMM_RUN_UPDATE_USING_LID
+ *@userdata1 NVDIMM Target Huid
+ *@userdata2[0:15] Old level (current)
+ *@userdata2[16:31] Update image level (new)
+ *@userdata2[32:63] Installed type (manufacturer and product)
+ *@devdesc Start of the NVDIMM update of this controller
+ *@custdesc NVDIMM update started
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ NVDIMM_RUN_UPDATE_USING_LID,
+ NVDIMM_START_UPDATE,
+ l_nvdimm_huid,
+ TWO_UINT16_ONE_UINT32_TO_UINT64(
+ l_oldVersion, i_lidImage->getVersion(),
+ l_installed_type),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_err->collectTrace(NVDIMM_UPD, 256);
+ ERRORLOG::errlCommit(l_err, NVDIMM_COMP_ID);
+ l_err = nullptr;
+
l_err = pInstalledImage->updateImage(i_lidImage);
if (l_err)
{
@@ -1803,14 +2086,150 @@ bool NvdimmsUpdate::runUpdateUsingLid(NvdimmLidImage * i_lidImage,
TRACFCOMP(g_trac_nvdimm_upd,
ERR_MRK"NvdimmsUpdate::runUpdateUsingLid() - "
"NVDIMM 0x%.8X NV controller update failed. "
- "RC=0x%X, PLID=0x%.8X",
- TARGETING::get_huid(pInstalledImage->getNvdimmTarget()),
+ "RC=0x%X, PLID=0x%.8X", l_nvdimm_huid,
ERRL_GETRC_SAFE(l_err), ERRL_GETPLID_SAFE(l_err));
commitPredictiveNvdimmError(l_err);
l_err = nullptr;
o_no_error_found = false;
+ continue;
+ }
+ else
+ {
+ // successfully updated this NVDIMM
+
+ // Note: call for version should just return a saved value
+ uint16_t curVersion = INVALID_VERSION;
+ l_err = pInstalledImage->getVersion(curVersion);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm_upd,
+ ERR_MRK"NvdimmsUpdate::runUpdateUsingLid() - "
+ "Failed to find current NVDIMM level of %.8X after "
+ "successful update. RC=0x%X, PLID=0x%.8X",
+ l_nvdimm_huid,
+ ERRL_GETRC_SAFE(l_err), ERRL_GETPLID_SAFE(l_err));
+ commitPredictiveNvdimmError(l_err);
+ l_err = nullptr;
+ }
+
+ /*@
+ *@errortype INFORMATIONAL
+ *@reasoncode NVDIMM_UPDATE_COMPLETE
+ *@moduleid NVDIMM_RUN_UPDATE_USING_LID
+ *@userdata1[0:31] NVDIMM Target Huid
+ *@userdata1[32:63] Total region write retries
+ *@userdata2[0:15] Previous level
+ *@userdata2[16:31] Current updated level
+ *@userdata2[32:63] Installed type (manufacturer and product)
+ *@devdesc Successful update of NVDIMM code
+ *@custdesc NVDIMM was successfully updated
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ NVDIMM_RUN_UPDATE_USING_LID,
+ NVDIMM_UPDATE_COMPLETE,
+ TWO_UINT32_TO_UINT64(
+ l_nvdimm_huid,
+ pInstalledImage->getRegionWriteRetries()),
+ TWO_UINT16_ONE_UINT32_TO_UINT64(
+ l_oldVersion, curVersion,
+ l_installed_type),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT );
+ l_err->collectTrace(NVDIMM_UPD, 512);
+ ERRORLOG::errlCommit(l_err, NVDIMM_COMP_ID);
}
} // end of updateNeeded
+
+ /////////////////////////////////////////////////////////////////
+ // Should not exit the nvdimm update stage until each nvdimm
+ // is running at the lid's code level
+ // (or a predictive error was logged for that nvdimm)
+ /////////////////////////////////////////////////////////////////
+
+ // Check NVDIMM is at the latest level and it is running from slot 1
+ uint16_t l_curVersion = INVALID_VERSION;
+ l_err = pInstalledImage->getVersion(l_curVersion, true);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm_upd,
+ ERR_MRK"NvdimmsUpdate::runUpdateUsingLid() - "
+ "Failed to find current level of NVDIMM %.8X. "
+ "RC=0x%X, PLID=0x%.8X", l_nvdimm_huid,
+ ERRL_GETRC_SAFE(l_err), ERRL_GETPLID_SAFE(l_err));
+ commitPredictiveNvdimmError(l_err);
+ l_err = nullptr;
+ o_no_error_found = false;
+ continue;
+ }
+ uint8_t l_slot_running = 0;
+ l_err = nvdimmGetRunningSlot(l_nvdimm, l_slot_running);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm_upd,
+ ERR_MRK"NvdimmsUpdate::runUpdateUsingLid() - "
+ "Failed to find running slot of NVDIMM %.8X. "
+ "RC=0x%X, PLID=0x%.8X", l_nvdimm_huid,
+ ERRL_GETRC_SAFE(l_err), ERRL_GETPLID_SAFE(l_err));
+ commitPredictiveNvdimmError(l_err);
+ l_err = nullptr;
+ o_no_error_found = false;
+ continue;
+ }
+
+ if ((l_slot_running == 0) || (l_curVersion != i_lidImage->getVersion()))
+ {
+ // Not running latest code on this NVDIMM
+ TRACFCOMP(g_trac_nvdimm_upd,
+ ERR_MRK"NvdimmsUpdate::runUpdateUsingLid() - "
+ "NVDIMM %.8X running from slot %d with code level "
+ "0x%04X (lid level: 0x%04X)",
+ l_nvdimm_huid, l_slot_running, l_curVersion,
+ i_lidImage->getVersion());
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_NOT_RUNNING_LATEST_LEVEL
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_RUN_UPDATE_USING_LID
+ *@userdata1 NVDIMM Target Huid
+ *@userdata2[0:15] NVDIMM slot
+ *@userdata2[16:31] slot1 version
+ *@userdata2[32:47] latest version from lid
+ *@devdesc Encountered error after update while checking
+ * if NVDIMM is running latest code level
+ *@custdesc NVDIMM not running latest firmware level
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_RUN_UPDATE_USING_LID,
+ NVDIMM_NOT_RUNNING_LATEST_LEVEL,
+ l_nvdimm_huid,
+ FOUR_UINT16_TO_UINT64(
+ l_slot_running,
+ l_curVersion,
+ i_lidImage->getVersion(),
+ 0x0000),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace( NVDIMM_COMP_NAME );
+
+ // Add callout of nvdimm with no deconfig/gard
+ l_err->addHwCallout( l_nvdimm,
+ HWAS::SRCI_PRIORITY_LOW,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Maybe vendor log will tell why it isn't running latest code level
+ nvdimmAddVendorLog(l_nvdimm, l_err);
+ commitPredictiveNvdimmError(l_err);
+ l_err = nullptr;
+ o_no_error_found = false;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nvdimm_upd,
+ "NvdimmsUpdate::runUpdateUsingLid() - "
+ "NVDIMM %.8X running from slot %d with latest level 0x%04X",
+ l_nvdimm_huid, l_slot_running, l_curVersion);
+ }
}
return o_no_error_found;
}
@@ -1826,12 +2245,15 @@ bool NvdimmsUpdate::runUpdate(void)
// List of each installed NVDIMM type
std::vector<NvdimmInstalledImage*> v_NVDIMM_16GB_list;
std::vector<NvdimmInstalledImage*> v_NVDIMM_32GB_list;
+ BPM::bpmList_t NVDIMM_BPM_16GB_list;
+ BPM::bpmList_t NVDIMM_BPM_32GB_list;
// Build up installed NVDIMM image lists
for (auto l_nvdimm : iv_nvdimmList)
{
NvdimmInstalledImage * l_installed_image =
new NvdimmInstalledImage(l_nvdimm);
+
l_err = l_installed_image->getType(l_installed_type);
if (l_err)
{
@@ -1843,6 +2265,10 @@ bool NvdimmsUpdate::runUpdate(void)
ERRL_GETPLID_SAFE(l_err));
commitPredictiveNvdimmError(l_err);
o_no_error_found = false;
+
+ // Delete the unused NvdimmInstalledImage pointer
+ delete l_installed_image;
+
continue;
}
@@ -1852,6 +2278,10 @@ bool NvdimmsUpdate::runUpdate(void)
"0x%.8X NVDIMM is SMART_NVDIMM_16GB_TYPE",
get_huid(l_nvdimm));
v_NVDIMM_16GB_list.push_back(l_installed_image);
+
+ BPM::Bpm l_16gbBpm(l_nvdimm);
+ NVDIMM_BPM_16GB_list.push_back(l_16gbBpm);
+
}
else if (l_installed_type == SMART_NVDIMM_32GB_TYPE)
{
@@ -1859,6 +2289,9 @@ bool NvdimmsUpdate::runUpdate(void)
"0x%.8X NVDIMM is SMART_NVDIMM_32GB_TYPE",
get_huid(l_nvdimm));
v_NVDIMM_32GB_list.push_back(l_installed_image);
+
+ BPM::Bpm l_32gbBpm(l_nvdimm);
+ NVDIMM_BPM_32GB_list.push_back(l_32gbBpm);
}
else
{
@@ -1866,7 +2299,7 @@ bool NvdimmsUpdate::runUpdate(void)
TRACFCOMP(g_trac_nvdimm_upd, "NvdimmsUpdate::runUpdate() - unknown "
"nvdimm[%X] installed type 0x%04X, skipping update",
TARGETING::get_huid(l_nvdimm), l_installed_type);
- /*
+ /*@
*@errortype
*@reasoncode NVDIMM_UNSUPPORTED_NVDIMM_TYPE
*@moduleid NVDIMM_RUN_UPDATE
@@ -1889,36 +2322,34 @@ bool NvdimmsUpdate::runUpdate(void)
ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
l_err->collectTrace(NVDIMM_COMP_NAME, 256 );
l_err->collectTrace(NVDIMM_UPD, 256);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
l_err->addPartCallout( l_nvdimm,
HWAS::NV_CONTROLLER_PART_TYPE,
HWAS::SRCI_PRIORITY_HIGH );
l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
HWAS::SRCI_PRIORITY_LOW );
+ nvdimmAddPage4Regs(l_nvdimm,l_err);
+ nvdimmAddUpdateRegs(l_nvdimm,l_err);
ERRORLOG::errlCommit(l_err, NVDIMM_COMP_ID);
+
+ // Delete the unused NvdimmInstalledImage object
+ delete l_installed_image;
+
continue;
}
}
do {
- // First check that updatable NVDIMMs exist on the system
- if ((v_NVDIMM_16GB_list.size() == 0) &&
- (v_NVDIMM_32GB_list.size() == 0))
- {
- TRACFCOMP(g_trac_nvdimm_upd, "NvdimmsUpdate::runUpdate() - "
- "No updatable NVDIMMs present on the system");
- break;
- }
-
- /////////////////////////
- // @todo: remove this check when SMART provides updated 32GB image
- // The current 32GB image will cause the future updating to fail
- if (v_NVDIMM_16GB_list.size() == 0)
+ // First check that updatable NVDIMMs or BPMs exist on the system
+ if ( (v_NVDIMM_16GB_list.size() == 0)
+ && (v_NVDIMM_32GB_list.size() == 0)
+ && (NVDIMM_BPM_16GB_list.size() == 0)
+ && (NVDIMM_BPM_32GB_list.size() == 0))
{
TRACFCOMP(g_trac_nvdimm_upd, "NvdimmsUpdate::runUpdate() - "
- "Only 16GB NVDIMM type is supported right now for update");
+ "No updatable NVDIMMs or BPMs present on the system");
break;
}
- /////////////////////////
if (INITSERVICE::spBaseServicesEnabled())
{
@@ -1935,7 +2366,15 @@ bool NvdimmsUpdate::runUpdate(void)
break;
}
- for(const auto& lid : info.lidIds)
+ // Both the config and firmware images are needed to perform an
+ // update on a BPM. So, get pointers to each in the CompInfo
+ // struct's vector of LID IDs.
+ MCL::LidInfo * bpm_16gb_fw = nullptr;
+ MCL::LidInfo * bpm_16gb_config = nullptr;
+ MCL::LidInfo * bpm_32gb_fw = nullptr;
+ MCL::LidInfo * bpm_32gb_config = nullptr;
+
+ for(auto& lid : info.lidIds)
{
TRACFCOMP(g_trac_nvdimm,"LID ID=0x%08X, size=%d, vAddr=%p",
lid.id, lid.size, lid.vAddr);
@@ -1966,6 +2405,22 @@ bool NvdimmsUpdate::runUpdate(void)
v_NVDIMM_32GB_list);
}
}
+ else if (lid.id == NVDIMM_32GB_BPM_FW_LIDID)
+ {
+ bpm_32gb_fw = &lid;
+ }
+ else if (lid.id == NVDIMM_32GB_BPM_CONFIG_LIDID)
+ {
+ bpm_32gb_config = &lid;
+ }
+ else if (lid.id == NVDIMM_16GB_BPM_FW_LIDID)
+ {
+ bpm_16gb_fw = &lid;
+ }
+ else if (lid.id == NVDIMM_16GB_BPM_CONFIG_LIDID)
+ {
+ bpm_16gb_config = &lid;
+ }
else if (lid.id != NVDIMM_SIGNATURE_LIDID)
{
TRACFCOMP(g_trac_nvdimm, "NvdimmsUpdate::runUpdate() - "
@@ -1975,6 +2430,26 @@ bool NvdimmsUpdate::runUpdate(void)
}
}
+ // Run BPM updates on NVDIMMs
+ BPM::BpmFirmwareLidImage fwImage_16gb(bpm_16gb_fw->vAddr,
+ bpm_16gb_fw->size);
+
+ BPM::BpmFirmwareLidImage fwImage_32gb(bpm_32gb_fw->vAddr,
+ bpm_32gb_fw->size);
+
+ BPM::BpmConfigLidImage configImage_16gb(bpm_16gb_config->vAddr,
+ bpm_16gb_config->size);
+
+ BPM::BpmConfigLidImage configImage_32gb(bpm_32gb_config->vAddr,
+ bpm_32gb_config->size);
+
+ BPM::runBpmUpdates(&NVDIMM_BPM_16GB_list,
+ &NVDIMM_BPM_32GB_list,
+ &fwImage_16gb,
+ &fwImage_32gb,
+ &configImage_16gb,
+ &configImage_32gb);
+
// Destructor automatically unloads the NVDIMM flash binary
}
else
@@ -1987,6 +2462,16 @@ bool NvdimmsUpdate::runUpdate(void)
}
} while (0); // end of flash update section
+ // Clean up the pointers used in v_NVDIMM_16GB_list and v_NVDIMM_32GB_list
+ for (const auto& pInstalledImage : v_NVDIMM_16GB_list)
+ {
+ delete pInstalledImage;
+ }
+ for (const auto& pInstalledImage : v_NVDIMM_32GB_list)
+ {
+ delete pInstalledImage;
+ }
+
return o_no_error_found;
}
@@ -2001,7 +2486,7 @@ errlHndl_t NvdimmsUpdate::isUpdateNeeded(bool & o_update_needed,
uint32_t curType = INVALID_TYPE;
do {
- const TARGETING::Target * l_dimm = i_cur_image->getNvdimmTarget();
+ TARGETING::Target * l_dimm = i_cur_image->getNvdimmTarget();
// check Types match (same manufacturer and product)
lidType = i_lid_image->getType();
@@ -2038,7 +2523,7 @@ errlHndl_t NvdimmsUpdate::isUpdateNeeded(bool & o_update_needed,
"isUpdateNeeded(): non-updatable SMART NVDIMM 0x%.8X "
"(0x%04X)",
TARGETING::get_huid(l_dimm), le16toh(curVersion));
- /*
+ /*@
*@errortype
*@reasoncode NVDIMM_UPDATE_NOT_SUPPORTED
*@moduleid NVDIMM_IS_UPDATE_NEEDED
@@ -2046,9 +2531,9 @@ errlHndl_t NvdimmsUpdate::isUpdateNeeded(bool & o_update_needed,
*@userdata1[32:63] NVDIMM Target Huid
*@userdata2 NVDIMM type (manufacturer and product)
*@devdesc Unable to update an NVDIMM at this code level
- *@custdesc NVDIMM not updated
+ *@custdesc Unsupported level of NVDIMM hardware
*/
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
NVDIMM_IS_UPDATE_NEEDED,
NVDIMM_UPDATE_NOT_SUPPORTED,
TWO_UINT32_TO_UINT64(
@@ -2057,9 +2542,15 @@ errlHndl_t NvdimmsUpdate::isUpdateNeeded(bool & o_update_needed,
curType,
ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
l_err->collectTrace( NVDIMM_UPD, 256 );
+ nvdimmAddVendorLog(const_cast<TARGETING::Target*>(l_dimm),
+ l_err);
+ l_err->addHwCallout( l_dimm,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DECONFIG,
+ HWAS::GARD_Fatal);
l_err->addPartCallout( l_dimm,
HWAS::NV_CONTROLLER_PART_TYPE,
- HWAS::SRCI_PRIORITY_HIGH );
+ HWAS::SRCI_PRIORITY_MED );
l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE,
HWAS::SRCI_PRIORITY_LOW );
break;
diff --git a/src/usr/isteps/nvdimm/nvdimm_update.H b/src/usr/isteps/nvdimm/nvdimm_update.H
index 37153b9c2..3f71dff56 100644
--- a/src/usr/isteps/nvdimm/nvdimm_update.H
+++ b/src/usr/isteps/nvdimm/nvdimm_update.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,6 +42,7 @@ const uint16_t INVALID_ID = 0xFFFF;
const uint16_t INVALID_VERSION = 0xFFFF;
const uint16_t INVALID_TIMEOUT = 0xFFFF;
const uint32_t INVALID_TYPE = 0xFFFFFFFF;
+const uint8_t INVALID_BLOCK_SIZE = 0x00;
// Type is combination of manufacturer id and product id
const uint32_t SMART_NVDIMM_16GB_TYPE = 0x01945377;
@@ -56,8 +57,13 @@ const uint32_t NVDIMM_SIGNATURE_LIDID = 0x80D00025; // ignore this one
const uint32_t NVDIMM_16GB_LIDID = 0x81e00640;
const uint32_t NVDIMM_32GB_LIDID = 0x81e00641;
+const uint32_t NVDIMM_16GB_BPM_FW_LIDID = 0x81e00642;
+const uint32_t NVDIMM_16GB_BPM_CONFIG_LIDID = 0x81e00644;
+
+const uint32_t NVDIMM_32GB_BPM_FW_LIDID = 0x81e00643;
+const uint32_t NVDIMM_32GB_BPM_CONFIG_LIDID = 0x81e00645;
+
-// Firmware Update Mode settings for FIRMWARE_OPS_CMD
enum fw_update_mode : uint8_t
{
FW_UPDATE_MODE_DISABLED = 0x00,
@@ -215,15 +221,40 @@ class NvdimmInstalledImage
const bool i_force_recollect = false);
/**
+ * @brief Read the current slot that is running
+ * @param o_slot - 0 or 1
+ * @return error if read operation fails
+ */
+ errlHndl_t getRunningSlot(uint8_t & o_slot);
+
+ /**
* @brief Accessor to grab the current NVDIMM target
* @return NVDIMM target
*/
- const TARGETING::Target * getNvdimmTarget(void)
+ TARGETING::Target * getNvdimmTarget(void)
{
return iv_dimm;
}
/**
+ * @brief Accessor to grab the amount of retries it took to write regions
+ * @return Cumulative total region write retries
+ */
+ uint8_t getRegionWriteRetries(void)
+ {
+ return iv_region_write_retries;
+ }
+
+ /**
+ * @brief Accessor for what write size is supported for this installed nvdimm
+ * Prior to level 0x3A, only word size supported
+ * Level 0x3A and beyond support 32 byte block writes
+ * @param[out] maximum number of bytes allowed per write
+ * @return block write size supported for this current nvdimm level
+ */
+ errlHndl_t getBlockWriteSizeSupported(uint64_t & o_blockSize);
+
+ /**
* @brief Update the current NV Controller
* @param Update using this image
* @return error pointer if failure to update, else nullptr
@@ -250,6 +281,16 @@ class NvdimmInstalledImage
// maximum blocks allowed per region (REGION_BLOCK_SIZE)
uint8_t iv_max_blocks_per_region;
+ // set to true when doing update
+ bool iv_fw_update_mode_enabled;
+
+ // retry attempts for all regions
+ uint8_t iv_region_write_retries;
+
+ // what size block can be written (2 or 32 byte)
+ uint64_t iv_blockSizeSupported;
+
+
// Helper functions for updating the installed lid
/**
* @brief Transfer a region of bytes in multiple 32-byte blocks
@@ -318,13 +359,6 @@ class NvdimmInstalledImage
errlHndl_t isFwOpsSuccess(bool & o_success);
/**
- * @brief Reset NV controller. Resets controller and waits for it to
- * come back online
- * @return error if reset failed, else nullptr
- */
- errlHndl_t resetController();
-
- /**
* @brief Updates the NV controller with the lid's image data
* (minus header and signature)
* @param i_lidImage - lid object with image data
diff --git a/src/usr/isteps/nvdimm/nvdimmdd.C b/src/usr/isteps/nvdimm/nvdimmdd.C
index 730fe0271..044be454b 100755
--- a/src/usr/isteps/nvdimm/nvdimmdd.C
+++ b/src/usr/isteps/nvdimm/nvdimmdd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2019 */
+/* Contributors Listed Below - COPYRIGHT 2011,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -35,6 +35,7 @@
// Includes
// ----------------------------------------------
#include <string.h>
+#include <time.h>
#include <sys/time.h>
#include <trace/interface.H>
#include <errl/errlentry.H>
@@ -67,16 +68,18 @@ TRAC_INIT( & g_trac_nvdimmr, "NVDIMMR", KILOBYTE );
// Easy macro replace for unit testing
-#define TRACUCOMP(args...) TRACFCOMP(args)
-//#define TRACUCOMP(args...)
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
// ----------------------------------------------
// Defines
// ----------------------------------------------
#define MAX_BYTE_ADDR 2
#define NVDIMM_MAX_RETRIES 2
+#define MAX_READ_RETRY_SECS 30
// ----------------------------------------------
+using namespace TARGETING;
namespace
{
@@ -95,13 +98,83 @@ static bool errorIsRetryable(uint16_t reasonCode)
namespace NVDIMM
{
-// Register the perform Op with the routing code for DIMMs.
+// Register the perform Op router with the routing code for DIMMs.
DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
DeviceFW::NVDIMM,
TARGETING::TYPE_DIMM,
+ nvdimmPerformOpRouter );
+
+// Register the perform Op with the routing code for DIMMs.
+DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
+ DeviceFW::NVDIMM_RAW,
+ TARGETING::TYPE_DIMM,
nvdimmPerformOp );
// ------------------------------------------------------------------
+// nvdimmPerformOpRouter
+// ------------------------------------------------------------------
+errlHndl_t nvdimmPerformOpRouter( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args )
+{
+ errlHndl_t l_err(nullptr);
+
+ TRACDCOMP( g_trac_nvdimm,
+ ENTER_MRK"nvdimmPerformOpRouter()" );
+
+ // Get the NVDIMM register's address, where data will be accessed from
+ // Although the data is being retrieved as a 64 bit value
+ // it is really a 16 bit value. Data passed via an arg list
+ // are retrieved in 64 bit chunks.
+ uint16_t l_registerAddress =
+ static_cast<uint16_t>(va_arg(i_args, uint64_t));
+
+ // Get a handle to the data buffer for easy referencing
+ uint8_t* l_data = static_cast<uint8_t*>(io_buffer);
+
+ TRACUCOMP(g_trac_nvdimm, INFO_MRK"nvdimmPerformOpRouter(): "
+ "operation type=%d, target HUID=0x%.8X, access type=%d, "
+ "buffer length=%d, buffer data=0x%.8X, register address=0x%.8X",
+ static_cast<uint64_t>(i_opType), get_huid(i_target), i_accessType,
+ io_buflen, *l_data, l_registerAddress);
+
+ // Make the right read/write call based on operation type
+ if( i_opType == DeviceFW::READ )
+ {
+ l_err = nvdimmReadReg( i_target,
+ l_registerAddress,
+ *l_data,
+ PAGE_VERIFY);
+ if (!l_err)
+ {
+ TRACUCOMP (g_trac_nvdimm, INFO_MRK"nvdimmPerformOpRouter(): "
+ "Read data(0x%X) from register(0x%X)",
+ *l_data, l_registerAddress);
+ }
+ }
+ else if( i_opType == DeviceFW::WRITE )
+ {
+ TRACUCOMP (g_trac_nvdimm, INFO_MRK"nvdimmPerformOpRouter(): "
+ "Writing data(0x%X) to register(0x%X) ...",
+ *l_data, l_registerAddress);
+
+ l_err = nvdimmWriteReg( i_target,
+ l_registerAddress,
+ *l_data,
+ PAGE_VERIFY);
+ }
+
+ TRACDCOMP(g_trac_nvdimm,
+ EXIT_MRK"nvdimmPerformOpRouter() returning with %s",
+ (l_err == nullptr ? "no error, success" : "an error, failure") );
+
+ return l_err;
+}
+
+// ------------------------------------------------------------------
// nvdimmPerformOp
// ------------------------------------------------------------------
errlHndl_t nvdimmPerformOp( DeviceFW::OperationType i_opType,
@@ -116,6 +189,7 @@ errlHndl_t nvdimmPerformOp( DeviceFW::OperationType i_opType,
nvdimm_addr_t i2cInfo;
i2cInfo.offset = va_arg( i_args, uint64_t );
+ i2cInfo.blockSize = va_arg( i_args, uint64_t );
TRACDCOMP( g_trac_nvdimm,
ENTER_MRK"nvdimmPerformOp()" );
@@ -206,7 +280,7 @@ errlHndl_t nvdimmPerformOp( DeviceFW::OperationType i_opType,
l_currentOpLen = l_snglChipSize - i2cInfo.offset;
}
- TRACFCOMP( g_trac_nvdimm,
+ TRACUCOMP( g_trac_nvdimm,
"nvdimmPerformOp(): i_opType=%d "
"e/p/dA=%d/%d/0x%X, offset=0x%X, len=0x%X, "
"snglChipKB=0x%X, chipCount=0x%X, devSizeKB=0x%X", i_opType,
@@ -216,7 +290,7 @@ errlHndl_t nvdimmPerformOp( DeviceFW::OperationType i_opType,
// Printing mux info separately, if combined, nothing is displayed
char* l_muxPath = i2cInfo.i2cMuxPath.toString();
- TRACFCOMP(g_trac_nvdimm, "nvdimmPerformOp(): "
+ TRACUCOMP(g_trac_nvdimm, "nvdimmPerformOp(): "
"muxSelector=0x%X, muxPath=%s",
i2cInfo.i2cMuxBusSelector,
l_muxPath);
@@ -326,7 +400,7 @@ errlHndl_t crossesNvdimmPageBoundary( uint64_t i_offset,
errlHndl_t err = nullptr;
- if(i_offset >= NVDIMM_PAGE_SIZE || (i_offset+i_buflen) >= NVDIMM_PAGE_SIZE)
+ if(i_offset >= NVDIMM_PAGE_SIZE || (i_offset+i_buflen) > NVDIMM_PAGE_SIZE)
{
TRACFCOMP( g_trac_nvdimm,
ERR_MRK"crossesNvdimmPageBoundary() - offset 0x%X, buflen 0x%X"
@@ -425,7 +499,7 @@ errlHndl_t nvdimmRead ( TARGETING::Target * i_target,
if( err )
{
TRACFCOMP(g_trac_nvdimm,
- "Failed reading data: original read");
+ ERR_MRK"nvdimmRead(): Failed reading data: original read");
break;
}
@@ -462,12 +536,13 @@ errlHndl_t nvdimmReadData( TARGETING::Target * i_target,
ENTER_MRK"nvdimmReadData()");
do
{
+ timespec_t l_CurTime, l_PrevTime;
+ clock_gettime(CLOCK_MONOTONIC, &l_PrevTime);
+ int retry = 0;
/************************************************************/
/* Attempt read multiple times ONLY on retryable fails */
/************************************************************/
- for (uint8_t retry = 0;
- retry <= NVDIMM_MAX_RETRIES;
- retry++)
+ do
{
// Only write the byte address if we have data to write
if( 0 != i_byteAddressSize )
@@ -488,12 +563,10 @@ errlHndl_t nvdimmReadData( TARGETING::Target * i_target,
if( l_err )
{
- TRACFCOMP(g_trac_nvdimm,
- ERR_MRK"nvdimmReadData(): I2C Read-Offset failed on "
- "%d/%d/0x%X, aS=%d",
- i_i2cInfo.port, i_i2cInfo.engine,
- i_i2cInfo.devAddr,
- i_byteAddressSize);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReadData(): "
+ "I2C Read-Offset failed on %d/%d/0x%X, aS=%d",
+ i_i2cInfo.port, i_i2cInfo.engine,
+ i_i2cInfo.devAddr, i_byteAddressSize);
// Printing mux info separately, if combined, nothing is displayed
char* l_muxPath = i_i2cInfo.i2cMuxPath.toString();
@@ -526,7 +599,7 @@ errlHndl_t nvdimmReadData( TARGETING::Target * i_target,
if( l_err )
{
- TRACFCOMP(g_trac_nvdimm,
+ TRACUCOMP(g_trac_nvdimm,
ERR_MRK"nvdimmReadData(): I2C Read failed on "
"%d/%d/0x%0X",
i_i2cInfo.port, i_i2cInfo.engine,
@@ -534,7 +607,7 @@ errlHndl_t nvdimmReadData( TARGETING::Target * i_target,
// Printing mux info separately, if combined, nothing is displayed
char* l_muxPath = i_i2cInfo.i2cMuxPath.toString();
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReadData(): "
+ TRACUCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReadData(): "
"muxSelector=0x%X, muxPath=%s",
i_i2cInfo.i2cMuxBusSelector,
l_muxPath);
@@ -567,64 +640,35 @@ errlHndl_t nvdimmReadData( TARGETING::Target * i_target,
else // Handle retryable error
{
// If op will be attempted again: save log and continue
- if ( retry < NVDIMM_MAX_RETRIES )
+ // Only save original retryable error
+ if ( err_retryable == nullptr )
{
- // Only save original retryable error
- if ( err_retryable == nullptr )
- {
- // Save original retryable error
- err_retryable = l_err;
-
- TRACFCOMP( g_trac_nvdimm, ERR_MRK"nvdimmReadData(): "
- "Retryable Error rc=0x%X, eid=0x%X, tgt=0x%X, "
- "retry/MAX=%d/%d. Save error and retry",
- err_retryable->reasonCode(),
- err_retryable->eid(),
- TARGETING::get_huid(i_target),
- retry, NVDIMM_MAX_RETRIES);
-
- err_retryable->collectTrace(NVDIMM_COMP_NAME);
- }
- else
- {
- // Add data to original retryable error
- TRACFCOMP( g_trac_nvdimm, ERR_MRK"nvdimmReadData(): "
- "Another Retryable Error rc=0x%X, eid=0x%X "
- "plid=0x%X, tgt=0x%X, retry/MAX=%d/%d. "
- "Delete error and retry",
- l_err->reasonCode(), l_err->eid(), l_err->plid(),
- TARGETING::get_huid(i_target),
- retry, NVDIMM_MAX_RETRIES);
-
- ERRORLOG::ErrlUserDetailsString(
- "Another Retryable ERROR found")
- .addToLog(err_retryable);
-
- // Delete this new retryable error
- delete l_err;
- l_err = nullptr;
- }
+ // Save original retryable error
+ err_retryable = l_err;
+
+ TRACUCOMP( g_trac_nvdimm, ERR_MRK"nvdimmReadData(): "
+ "Retryable Error rc=0x%X, eid=0x%X, tgt=0x%X, "
+ "retry=%d. Save error and retry",
+ err_retryable->reasonCode(),
+ err_retryable->eid(),
+ TARGETING::get_huid(i_target),
+ retry);
- // continue to retry
- continue;
+ err_retryable->collectTrace(NVDIMM_COMP_NAME);
}
- else // no more retries: trace and break
+ else
{
- TRACFCOMP( g_trac_nvdimm, ERR_MRK"nvdimmReadData(): "
- "Error rc=0x%X, eid=%d, tgt=0x%X. No More "
- "Retries (retry/MAX=%d/%d). Returning Error",
- l_err->reasonCode(), l_err->eid(),
- TARGETING::get_huid(i_target),
- retry, NVDIMM_MAX_RETRIES);
-
- l_err->collectTrace(NVDIMM_COMP_NAME);
-
- // break from retry loop
- break;
+ // Delete this new retryable error
+ delete l_err;
+ l_err = nullptr;
}
- }
+ } // retryable error
+ // update current time
+ clock_gettime(CLOCK_MONOTONIC, &l_CurTime);
+ retry++;
} // end of retry loop
+ while( (l_CurTime.tv_sec - l_PrevTime.tv_sec) < MAX_READ_RETRY_SECS );
// Handle saved retryable error, if any
if (err_retryable)
@@ -641,13 +685,29 @@ errlHndl_t nvdimmReadData( TARGETING::Target * i_target,
.addToLog(err_retryable);
errlCommit(err_retryable, NVDIMM_COMP_ID);
+
+ // Add trace of what operation failed for returned error
+ TRACFCOMP(g_trac_nvdimm,
+ ERR_MRK"nvdimmReadData(): I2C Read failed on "
+ "%d/%d/0x%0X",
+ i_i2cInfo.port, i_i2cInfo.engine, i_i2cInfo.devAddr );
+
+ // Printing mux info separately, if combined, nothing is displayed
+ char* l_muxPath = i_i2cInfo.i2cMuxPath.toString();
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReadData(): "
+ "muxSelector=0x%X, muxPath=%s",
+ i_i2cInfo.i2cMuxBusSelector,
+ l_muxPath);
+ free(l_muxPath);
+ l_muxPath = nullptr;
}
else
{
// Since we eventually succeeded, delete original retryable error
- TRACFCOMP(g_trac_nvdimm, "nvdimmReadData(): Op successful, "
- "deleting saved retryable err eid=0x%X, plid=0x%X",
- err_retryable->eid(), err_retryable->plid());
+ TRACUCOMP(g_trac_nvdimm, "nvdimmReadData(): Op successful, "
+ "after %d retries. Deleting saved retryable err eid="
+ "0x%X, plid=0x%X",
+ retry, err_retryable->eid(), err_retryable->plid());
delete err_retryable;
err_retryable = nullptr;
@@ -676,8 +736,6 @@ errlHndl_t nvdimmWrite ( TARGETING::Target * i_target,
size_t byteAddrSize = 0;
uint8_t * newBuffer = nullptr;
bool needFree = false;
- uint32_t data_left = 0;
- uint32_t diff_wps = 0;
TRACDCOMP( g_trac_nvdimm,
ENTER_MRK"nvdimmWrite()" );
@@ -742,6 +800,17 @@ errlHndl_t nvdimmWrite ( TARGETING::Target * i_target,
// Setup a max-size buffer of writePageSize
size_t newBufLen = i_i2cInfo.writePageSize;
+
+ // Break data into max supported i2c transfer size, if possible
+ // (speeds up i2c operation)
+ if ( (i_i2cInfo.blockSize != 0) &&
+ (io_buflen >= i_i2cInfo.blockSize) &&
+ ((io_buflen % i_i2cInfo.blockSize) == 0) )
+ {
+ newBufLen = i_i2cInfo.blockSize;
+ }
+ assert(newBufLen > 0, "Unable to allocate 0 buffer size for nvdimmWrite()");
+
newBuffer = static_cast<uint8_t*>(malloc( newBufLen ));
needFree = true;
@@ -756,16 +825,6 @@ errlHndl_t nvdimmWrite ( TARGETING::Target * i_target,
while( total_bytes_written < io_buflen )
{
- // Determine how much data can be written in this loop
- // Can't go over a writePageSize boundary
-
- // Total data left to write
- data_left = io_buflen - total_bytes_written;
-
- // Difference to next writePageSize boundary
- diff_wps = i_i2cInfo.writePageSize -
- (i_i2cInfo.offset % i_i2cInfo.writePageSize);
-
// Add the data the user wanted to write
memcpy( newBuffer,
&l_data_ptr[total_bytes_written],
@@ -785,15 +844,13 @@ errlHndl_t nvdimmWrite ( TARGETING::Target * i_target,
}
TRACUCOMP(g_trac_nvdimm,"nvdimmWrite() Loop: %d/%d/0x%X "
- "writeBuflen=%d, offset=0x%X, "
- "bAS=%d, diffs=%d/%d",
+ "writeBuflen=%d, offset=0x%X, bAS=%d",
i_i2cInfo.port, i_i2cInfo.engine, i_i2cInfo.devAddr,
- newBufLen, i_i2cInfo.offset, byteAddrSize,
- data_left, diff_wps);
+ newBufLen, i_i2cInfo.offset, byteAddrSize);
// Printing mux info separately, if combined, nothing is displayed
char* l_muxPath = i_i2cInfo.i2cMuxPath.toString();
- TRACFCOMP(g_trac_nvdimm, "nvdimmWrite(): "
+ TRACUCOMP(g_trac_nvdimm, "nvdimmWrite(): "
"muxSelector=0x%X, muxPath=%s",
i_i2cInfo.i2cMuxBusSelector,
l_muxPath);
@@ -815,6 +872,14 @@ errlHndl_t nvdimmWrite ( TARGETING::Target * i_target,
// for this loop
TRACFCOMP(g_trac_nvdimm,
"Failed writing data: original nvdimm write");
+ // total writes for the data size (divide by each write size)
+ size_t totalWritesNeeded = io_buflen/newBufLen;
+ // current write number (writes done + next one)
+ size_t currentWrite = total_bytes_written/newBufLen + 1;
+ TRACFCOMP( g_trac_nvdimm,ERR_MRK"nvdimmWrite(): "
+ "Tried to write out %d bytes out of %d total: "
+ "Failed on the %d of %d writes", newBufLen, io_buflen,
+ currentWrite, totalWritesNeeded );
break;
}
@@ -842,7 +907,7 @@ errlHndl_t nvdimmWrite ( TARGETING::Target * i_target,
io_buflen = total_bytes_written;
- TRACSCOMP( g_trac_nvdimmr,
+ TRACUCOMP( g_trac_nvdimmr,
"NVDIMM WRITE END : Offset %.2X : Len %d",
i_i2cInfo.offset, io_buflen );
} while( 0 );
@@ -874,30 +939,70 @@ errlHndl_t nvdimmWriteData( TARGETING::Target * i_target,
ENTER_MRK"nvdimmWriteData()");
errlHndl_t err = nullptr;
errlHndl_t err_retryable = nullptr;
+ size_t data_length;
+
do
{
- /***********************************************************/
- /* Attempt write multiple times ONLY on retryable fails */
- /***********************************************************/
- for (uint8_t retry = 0;
- retry <= NVDIMM_MAX_RETRIES;
- retry++)
- {
- // Do the actual data write
- err = deviceOp( DeviceFW::WRITE,
- i_target,
- i_dataToWrite,
- i_dataLen,
- DEVICE_I2C_ADDRESS_OFFSET(
- i_i2cInfo.port,
- i_i2cInfo.engine,
- i_i2cInfo.devAddr,
- i_byteAddressSize,
- reinterpret_cast<uint8_t*>(
- i_byteAddress),
- i_i2cInfo.i2cMuxBusSelector,
- &(i_i2cInfo.i2cMuxPath) ));
+ /***********************************************************/
+ /* Attempt write multiple times ONLY on retryable fails */
+ /***********************************************************/
+ for ( uint8_t retry = 0; retry <= NVDIMM_MAX_RETRIES; retry++)
+ {
+ // use a temporary variable to allow retry as the
+ // data_length could be altered by deviceOp() failure
+ data_length = i_dataLen;
+ // Do the actual data write
+ if ( i_dataLen == sizeof(uint16_t) )
+ {
+ err = deviceOp( DeviceFW::WRITE,
+ i_target,
+ i_dataToWrite,
+ data_length,
+ DeviceFW::I2C,
+ I2C_SMBUS_RW_W_CMD_PARAMS(
+ DeviceFW::I2C_SMBUS_WORD_NO_PEC,
+ i_i2cInfo.engine,
+ i_i2cInfo.port,
+ i_i2cInfo.devAddr,
+ *(reinterpret_cast<uint8_t*>(i_byteAddress)
+ + (i_byteAddressSize-1)),
+ i_i2cInfo.i2cMuxBusSelector,
+ &(i_i2cInfo.i2cMuxPath)) );
+ }
+ else if ( i_dataLen == 32 )
+ {
+ err = deviceOp( DeviceFW::WRITE,
+ i_target,
+ i_dataToWrite,
+ data_length,
+ DeviceFW::I2C,
+ I2C_SMBUS_RW_W_CMD_PARAMS(
+ DeviceFW::I2C_SMBUS_BLOCK_NO_BYTE_COUNT,
+ i_i2cInfo.engine,
+ i_i2cInfo.port,
+ i_i2cInfo.devAddr,
+ *(reinterpret_cast<uint8_t*>(i_byteAddress)
+ + (i_byteAddressSize-1)),
+ i_i2cInfo.i2cMuxBusSelector,
+ &(i_i2cInfo.i2cMuxPath)) );
+ }
+ else
+ {
+ err = deviceOp( DeviceFW::WRITE,
+ i_target,
+ i_dataToWrite,
+ data_length,
+ DEVICE_I2C_ADDRESS_OFFSET(
+ i_i2cInfo.port,
+ i_i2cInfo.engine,
+ i_i2cInfo.devAddr,
+ i_byteAddressSize,
+ reinterpret_cast<uint8_t*>(
+ i_byteAddress),
+ i_i2cInfo.i2cMuxBusSelector,
+ &(i_i2cInfo.i2cMuxPath) ));
+ }
if ( err == nullptr )
{
// Operation completed successfully
@@ -911,7 +1016,7 @@ errlHndl_t nvdimmWriteData( TARGETING::Target * i_target,
"Write Non-Retryable fail %d/%d/0x%X, "
"ldl=%d, offset=0x%X, aS=%d, retry=%d",
i_i2cInfo.port, i_i2cInfo.engine,
- i_i2cInfo.devAddr, i_dataLen,
+ i_i2cInfo.devAddr, data_length,
i_i2cInfo.offset, i_i2cInfo.addrSize, retry);
// Printing mux info separately, if combined, nothing is displayed
@@ -930,7 +1035,7 @@ errlHndl_t nvdimmWriteData( TARGETING::Target * i_target,
}
else // Handle retryable error
{
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmWriteData(): I2C "
+ TRACUCOMP(g_trac_nvdimm, ERR_MRK"nvdimmWriteData(): I2C "
"Write retryable fail %d/%d/0x%X, "
"ldl=%d, offset=0x%X, aS=%d, writePageSize = %x",
i_i2cInfo.port, i_i2cInfo.engine,
@@ -940,7 +1045,7 @@ errlHndl_t nvdimmWriteData( TARGETING::Target * i_target,
// Printing mux info separately, if combined, nothing is displayed
char* l_muxPath = i_i2cInfo.i2cMuxPath.toString();
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmWriteData(): "
+ TRACUCOMP(g_trac_nvdimm, ERR_MRK"nvdimmWriteData(): "
"muxSelector=0x%X, muxPath=%s",
i_i2cInfo.i2cMuxBusSelector,
l_muxPath);
@@ -956,7 +1061,7 @@ errlHndl_t nvdimmWriteData( TARGETING::Target * i_target,
// Save original retryable error
err_retryable = err;
- TRACFCOMP( g_trac_nvdimm, ERR_MRK"nvdimmWriteData(): "
+ TRACUCOMP( g_trac_nvdimm, ERR_MRK"nvdimmWriteData(): "
"Error rc=0x%X, eid=0x%X plid=0x%X, "
"tgt=0x%X, retry/MAX=%d/%d. Save error "
"and retry",
@@ -971,7 +1076,7 @@ errlHndl_t nvdimmWriteData( TARGETING::Target * i_target,
else
{
// Add data to original retryable error
- TRACFCOMP( g_trac_nvdimm, ERR_MRK"nvdimmWriteData(): "
+ TRACUCOMP( g_trac_nvdimm, ERR_MRK"nvdimmWriteData(): "
"Another Retryable Error rc=0x%X, eid=0x%X "
"plid=0x%X, tgt=0x%X, retry/MAX=%d/%d. "
"Delete error and retry",
@@ -1016,6 +1121,24 @@ errlHndl_t nvdimmWriteData( TARGETING::Target * i_target,
{
if (err)
{
+ // Trace failure write parameters
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmWriteData(): I2C "
+ "Write retryable fail %d/%d/0x%X, "
+ "ldl=%d, offset=0x%X, aS=%d, writePageSize = %x",
+ i_i2cInfo.port, i_i2cInfo.engine,
+ i_i2cInfo.devAddr, i_dataLen,
+ i_i2cInfo.offset, i_i2cInfo.addrSize,
+ i_i2cInfo.writePageSize);
+
+ // Printing mux info separately, if combined, nothing is displayed
+ char* l_muxPath = i_i2cInfo.i2cMuxPath.toString();
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmWriteData(): "
+ "muxSelector=0x%X, muxPath=%s",
+ i_i2cInfo.i2cMuxBusSelector,
+ l_muxPath);
+ free(l_muxPath);
+ l_muxPath = nullptr;
+
// commit original retryable error with new err PLID
err_retryable->plid(err->plid());
TRACFCOMP(g_trac_nvdimm, "nvdimmWriteData(): Committing saved "
@@ -1031,7 +1154,7 @@ errlHndl_t nvdimmWriteData( TARGETING::Target * i_target,
else
{
// Since we eventually succeeded, delete original retryable error
- TRACFCOMP(g_trac_nvdimm, "nvdimmWriteData(): Op successful, "
+ TRACUCOMP(g_trac_nvdimm, "nvdimmWriteData(): Op successful, "
"deleting saved retryable err eid=0x%X, plid=0x%X",
err_retryable->eid(), err_retryable->plid());
@@ -1221,7 +1344,7 @@ errlHndl_t nvdimmReadAttributes ( TARGETING::Target * i_target,
// Printing mux info separately, if combined, nothing is displayed
char* l_muxPath = o_i2cInfo.i2cMuxPath.toString();
- TRACFCOMP(g_trac_nvdimm, "nvdimmReadAttributes(): "
+ TRACUCOMP(g_trac_nvdimm, "nvdimmReadAttributes(): "
"muxSelector=0x%X, muxPath=%s",
o_i2cInfo.i2cMuxBusSelector,
l_muxPath);
@@ -1481,4 +1604,175 @@ void getNVDIMMs( std::list<EEPROM::EepromInfo_t>& o_info )
o_info.size());
}
+/**
+ * @brief Helper structure to keep track of memory ranges
+ */
+typedef struct memGroups_t
+{
+ Target* proc;
+ uint64_t membottom;
+ uint64_t memtop;
+ size_t group;
+} memGroups_t;
+
+/**
+ * @brief Comparator for memGroups_t to allow sorting, sorts big-to-small
+ * @param[in] Left-side of compare
+ * @param[in] Right-side of compare
+ * @return true:left-side is bigger, false:right-side is bigger
+ */
+bool compare_memGroups(memGroups_t& i_ls,
+ memGroups_t& i_rs)
+{
+ return (i_ls.memtop > i_rs.memtop);
+}
+
+/**
+ * @brief Check if given address is owned by nvdimms and return
+ * a new address that isn't if it was
+ */
+uint64_t get_top_addr_with_no_nvdimms( uint64_t i_topAddr )
+{
+ // Default to just returning the same value we got (no nvdimms)
+ uint64_t o_topAddr = i_topAddr;
+
+ // On a NVDIMM system we need to make sure that we don't
+ // use the NV memory for the HOMER (or other reserved
+ // memory). Depending on the specific memory layout
+ // the NV memory could be placed at the top of memory
+ // where we would normally land.
+
+ // NVDIMMs are only on Nimbus systems
+ if( TARGETING::MODEL_NIMBUS
+ !=TARGETING::targetService().getProcessorModel() )
+ {
+ return o_topAddr;
+ }
+
+ // Skip all of this checking if the input value is weird
+ if( i_topAddr == 0 )
+ {
+ return o_topAddr;
+ }
+
+ // Build up a list of possible memory ranges
+ std::vector<memGroups_t> l_memGroups;
+
+ ATTR_PROC_MEM_BASES_type l_memBases = {0};
+ ATTR_PROC_MEM_SIZES_type l_memSizes = {0};
+ const size_t l_numGroups = sizeof(ATTR_PROC_MEM_SIZES_type)
+ /sizeof(l_memSizes[0]);
+
+ TARGETING::TargetHandleList l_procList;
+ TARGETING::getAllChips(l_procList, TARGETING::TYPE_PROC);
+ assert(l_procList.size() != 0, "Empty proc list returned!");
+ for (auto l_pProc : l_procList)
+ {
+ // Get the memory group ranges under this proc
+ assert(l_pProc->tryGetAttr<ATTR_PROC_MEM_BASES>(l_memBases),
+ "Unable to get ATTR_PROC_MEM_BASES attribute");
+ assert(l_pProc->tryGetAttr<ATTR_PROC_MEM_SIZES>(l_memSizes),
+ "Unable to get ATTR_PROC_MEM_SIZES attribute");
+
+ for (size_t l_grp=0; l_grp < l_numGroups; l_grp++)
+ {
+ // Non-zero size means that there is memory present
+ if (l_memSizes[l_grp])
+ {
+ memGroups_t l_mg;
+ l_mg.proc = l_pProc;
+ l_mg.membottom = l_memBases[l_grp];
+ l_mg.memtop = l_memBases[l_grp] + l_memSizes[l_grp];
+ l_mg.group = l_grp;
+ l_memGroups.push_back(l_mg);
+ }
+ }
+ }
+
+
+ // Loop through the groups from biggest to smallest
+ // l_top_homer_addr should hit the biggest one first, then we'll
+ // find the next biggest if the first match has a nvdimm in it.
+ std::sort( l_memGroups.begin(), l_memGroups.end(), compare_memGroups );
+ for( auto l_memGroup : l_memGroups )
+ {
+ bool l_foundNvdimm = false;
+
+ // Get the array of mcas/group from the attribute
+ // The attr contains 8 8-bit entries, one entry per group
+ // The bits specify which mcas are included in the group
+ ATTR_MSS_MEM_MC_IN_GROUP_type l_memMcGroup = {0};
+ assert(l_memGroup.proc->tryGetAttr<ATTR_MSS_MEM_MC_IN_GROUP>
+ (l_memMcGroup),
+ "Unable to get ATTR_MSS_MEM_MC_IN_GROUP attribute");
+
+ // Get list of mcas under this proc
+ TargetHandleList l_mcaList;
+ getChildAffinityTargets( l_mcaList,
+ l_memGroup.proc,
+ CLASS_UNIT,
+ TYPE_MCA );
+
+ // Loop through the mcas on this proc
+ for (const auto & l_mcaTarget : l_mcaList)
+ {
+ // Get the chip unit for this mca
+ ATTR_CHIP_UNIT_type l_mcaUnit = 0;
+ l_mcaUnit = l_mcaTarget->getAttr<ATTR_CHIP_UNIT>();
+
+ // Check if this mca is included in the memory group
+ const uint8_t l_mcMask = 0x80;
+ if (l_memMcGroup[l_memGroup.group] & (l_mcMask >> l_mcaUnit))
+ {
+ // Get the list of dimms under this mca
+ TargetHandleList l_dimmList;
+ getChildAffinityTargets( l_dimmList,
+ l_mcaTarget,
+ CLASS_NA,
+ TYPE_DIMM );
+ for (const auto & l_dimmTarget : l_dimmList)
+ {
+ if( isNVDIMM(l_dimmTarget) )
+ {
+ l_foundNvdimm = true;
+ break;
+ }
+ }
+ if( l_foundNvdimm ) { break; }
+ }
+ } // for all MCAs
+
+ // If we didn't find a nvdimm, we have a candidate for a valid
+ // top address
+ if( l_foundNvdimm )
+ {
+ // Check if top addr is in this group's memory range
+ if( (o_topAddr >= l_memGroup.membottom) &&
+ (o_topAddr <= l_memGroup.memtop) )
+ {
+ TRACFCOMP(g_trac_nvdimm,"get_top_addr_with_no_nvdimms> Chosen address 0x%llX has nvdimms, cannot be used",
+ o_topAddr);
+ o_topAddr = 0;
+ }
+ }
+ else
+ {
+ // Since we are sorted by size, this must be the
+ // largest group without a nvdimm
+ if( o_topAddr != l_memGroup.memtop )
+ {
+ o_topAddr = l_memGroup.memtop;
+ TRACFCOMP(g_trac_nvdimm,"get_top_addr_with_no_nvdimms> Choosing address 0x%llX as new top",
+ o_topAddr);
+ break;
+ }
+ }
+ } //for all memgroups
+
+ assert( o_topAddr != 0, "get_top_addr_with_no_nvdimms> No valid memory group found without a NVDIMM" );
+
+ return o_topAddr;
+}
+
+
} // end namespace NVDIMM
diff --git a/src/usr/isteps/nvdimm/nvdimmdd.H b/src/usr/isteps/nvdimm/nvdimmdd.H
index 4d599b38a..88bc388c0 100755
--- a/src/usr/isteps/nvdimm/nvdimmdd.H
+++ b/src/usr/isteps/nvdimm/nvdimmdd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -69,6 +69,7 @@ struct nvdimm_addr_t
uint64_t devSize_KB; // in kilobytes
uint64_t chipCount; // number of chips making up nvdimm device
uint64_t writeCycleTime; // in milliseconds
+ uint8_t blockSize; // size of write block supported for this nvdimm
uint8_t i2cMuxBusSelector;
TARGETING::EntityPath i2cMuxPath;
@@ -86,12 +87,90 @@ struct nvdimm_addr_t
devSize_KB(0),
chipCount(0),
writeCycleTime(0),
+ blockSize(0),
i2cMuxBusSelector(I2C_MUX::NOT_APPLICABLE),
i2cMuxPath()
{
}
};
+/**
+ * @brief Structure of registers for error log traces
+ */
+struct nvdimm_reg_t
+{
+ uint8_t Module_Health;
+ uint8_t Module_Health_Status0;
+ uint8_t Module_Health_Status1;
+ uint8_t CSave_Status;
+ uint8_t CSave_Info;
+ uint8_t CSave_Fail_Info0;
+ uint8_t CSave_Fail_Info1;
+ uint8_t CSave_Timeout0;
+ uint8_t CSave_Timeout1;
+ uint8_t Error_Threshold_Status;
+ uint8_t NVDimm_Ready;
+ uint8_t NVDimm_CMD_Status0;
+ uint8_t Erase_Status;
+ uint8_t Erase_Fail_Info;
+ uint8_t Erase_Timeout0;
+ uint8_t Erase_Timeout1;
+ uint8_t Abort_CMD_Timeout;
+ uint8_t Set_ES_Policy_Status;
+ uint8_t Restore_Status;
+ uint8_t Restore_Fail_Info;
+ uint8_t Restore_Timeout0;
+ uint8_t Restore_Timeout1;
+ uint8_t Arm_Status;
+ uint8_t Arm_Fail_Info;
+ uint8_t Arm_Timeout0;
+ uint8_t Arm_Timeout1;
+ uint8_t Set_Event_Notification_Status;
+ uint8_t Encryption_Config_Status;
+
+ /**
+ * @brief Construct a default nvdimm_reg_t
+ */
+ nvdimm_reg_t()
+ : Module_Health(0),
+ Module_Health_Status0(0),
+ Module_Health_Status1(0),
+ CSave_Status(0),
+ CSave_Info(0),
+ CSave_Fail_Info0(0),
+ CSave_Fail_Info1(0),
+ CSave_Timeout0(0),
+ CSave_Timeout1(0),
+ Error_Threshold_Status(0),
+ NVDimm_Ready(0),
+ NVDimm_CMD_Status0(0),
+ Erase_Status(0),
+ Erase_Fail_Info(0),
+ Erase_Timeout0(0),
+ Erase_Timeout1(0),
+ Abort_CMD_Timeout(0),
+ Set_ES_Policy_Status(0),
+ Restore_Status(0),
+ Restore_Fail_Info(0),
+ Restore_Timeout0(0),
+ Restore_Timeout1(0),
+ Arm_Status(0),
+ Arm_Fail_Info(0),
+ Arm_Timeout0(0),
+ Arm_Timeout1(0),
+ Set_Event_Notification_Status(0),
+ Encryption_Config_Status(0)
+ {
+ }
+
+ /**
+ * @brief Default deconstructor of nvdimm_reg_t
+ */
+ ~nvdimm_reg_t() = default;
+
+};
+
+
/*
* @brief Miscellaneous enums for NVDIMM
*/
@@ -138,6 +217,49 @@ errlHndl_t nvdimmPerformOp( DeviceFW::OperationType i_opType,
int64_t i_accessType,
va_list i_args );
+/**
+*
+* @brief Route the read/write operator (i_opType) to the correct
+* nvdimmReadReg/nvdimmWriteReg call.
+*
+* @details This is essentially a wrapper around the nvdimmPerformOp method
+* which is called via the nvdimmReadReg/nvdimmWriteReg call. This
+* ensures that the page is set correctly whenever a NVDIMM register
+* is accessed.
+*
+* @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
+* driververif.H
+*
+* @param[in] i_target - Target device.
+*
+* @param[in/out] io_buffer
+* INPUT: Pointer to the data that will be written to the target
+* device.
+* OUTPUT: Pointer to the data that was read from the target device.
+*
+* @param[in/out] io_buflen
+* INPUT: Length of the buffer to be written to target device.
+* OUTPUT: Length of buffer that was written, or length of buffer
+* to be read from target device.
+*
+* @param [in] i_accessType - Access Type - See DeviceFW::AccessType in
+* usrif.H
+*
+* @param [in] i_args - This is an argument list for the device driver
+* framework. This argument list consists of the internal offset
+* to use on the slave I2C device.
+*
+* @return errlHndl_t - NULL if successful, otherwise a pointer to the
+* error log.
+*
+*/
+errlHndl_t nvdimmPerformOpRouter( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args );
+
/*
* @brief On the NV Controller, the page is selected by writing to offset
* 0x00 with the page you would like to switch too. e.g. to activate
diff --git a/src/usr/isteps/nvdimm/plugins/errludP_nvdimm.H b/src/usr/isteps/nvdimm/plugins/errludP_nvdimm.H
index 460add6f3..fdd94e01d 100644
--- a/src/usr/isteps/nvdimm/plugins/errludP_nvdimm.H
+++ b/src/usr/isteps/nvdimm/plugins/errludP_nvdimm.H
@@ -7,6 +7,7 @@
/* */
/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
+/* [+] YADRO */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -164,6 +165,84 @@ private:
UdParserNvdimmParms & operator=(const UdParserNvdimmParms&);
};
+/**
+ * @class UdParserNvdimmOPParms
+ *
+ * Parses UdNvdimmOPParms
+ */
+class UdParserNvdimmOPParms : public ERRORLOG::ErrlUserDetailsParser
+{
+public:
+ /**
+ * @brief Constructor
+ */
+ UdParserNvdimmOPParms() {}
+
+ /**
+ * @brief Destructor
+ */
+ virtual ~UdParserNvdimmOPParms() = default;
+
+ /**
+ * @brief Parses string user detail data from an error log
+ *
+ * @param i_version Version of the data
+ * @param i_parse ErrlUsrParser object for outputting information
+ * @param i_pBuffer Pointer to buffer containing detail data
+ * @param i_buflen Length of the buffer
+ */
+ virtual void parse(errlver_t i_version,
+ ErrlUsrParser & i_parser,
+ void * i_pBuffer,
+ const uint32_t i_buflen) const
+ {
+ const uint8_t* l_databuf = static_cast<const uint8_t*>(i_pBuffer);
+ i_parser.PrintHeading("NVDIMM I2C Register Traces");
+
+ // Memory Layout (1 byte each)
+ static const char* l_registers[] = {
+ "MODULE_HEALTH",
+ "MODULE_HEALTH_STATUS0",
+ "MODULE_HEALTH_STATUS1",
+ "CSAVE_STATUS",
+ "CSAVE_INFO",
+ "CSAVE_FAIL_INFO0",
+ "CSAVE_FAIL_INFO1",
+ "CSAVE_TIMEOUT_INFO0",
+ "CSAVE_TIMEOUT_INFO1",
+ "ERROR_THRESHOLD_STATUS",
+ "NVDIMM_READY",
+ "NVDIMM_CMD_STATUS0",
+ "ERASE_STATUS",
+ "ERASE_FAIL_INFO",
+ "ERASE_TIMEOUT0",
+ "ERASE_TIMEOUT1",
+ "ABORT_CMD_TIMEOUT",
+ "SET_ES_POLICY_STATUS",
+ "RESTORE_STATUS",
+ "RESTORE_FAIL_INFO",
+ "RESTORE_TIMEOUT0",
+ "RESTORE_TIMEOUT1",
+ "ARM_STATUS",
+ "ARM_FAIL_INFO",
+ "ARM_TIMEOUT0",
+ "ARM_TIMEOUT1",
+ "SET_EVENT_NOTIFICATION_STATUS",
+ "ENCRYPTION_CONFIG_STATUS"
+ };
+
+ for (uint32_t i = 0; i < i_buflen &&
+ i < sizeof(l_registers) / sizeof(l_registers[0]); ++i)
+ {
+ i_parser.PrintNumber(l_registers[i], "%02X", l_databuf[i]);
+ }
+ }
+
+ // Disabled
+ UdParserNvdimmOPParms(const UdParserNvdimmOPParms&) = delete;
+ UdParserNvdimmOPParms & operator=(UdParserNvdimmOPParms &) = delete;
+};
+
} // end NVDIMM namespace
#endif
diff --git a/src/usr/isteps/nvdimm/plugins/nvdimmUdParserFactory.H b/src/usr/isteps/nvdimm/plugins/nvdimmUdParserFactory.H
index b27774b13..f208ac060 100644
--- a/src/usr/isteps/nvdimm/plugins/nvdimmUdParserFactory.H
+++ b/src/usr/isteps/nvdimm/plugins/nvdimmUdParserFactory.H
@@ -38,14 +38,14 @@ namespace NVDIMM
{
registerParser<NVDIMM::UdParserNvdimmParms>
(NVDIMM_UDT_PARAMETERS);
+ registerParser<NVDIMM::UdParserNvdimmOPParms>
+ (NVDIMM_OP_PARAMETERS);
}
- private:
-
- UserDetailsParserFactory(const UserDetailsParserFactory &);
- UserDetailsParserFactory & operator=
- (const UserDetailsParserFactory &);
+ UserDetailsParserFactory(const UserDetailsParserFactory &) = delete;
+ UserDetailsParserFactory & operator=(UserDetailsParserFactory &) = delete;
};
+
};
#endif
diff --git a/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C b/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C
index 267fab07c..e8ad1d9e9 100644
--- a/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C
+++ b/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C
@@ -25,446 +25,1032 @@
/**
* @file nvdimm_rt.C
*
- * @brief NVDIMM functions only needed for runtime
+ * @brief NVDIMM functions only needed for runtime. These functions include
+ * but are not limited to arming/disarming the NVDIMM along with methods
+ * to poll the arming and check the status of the arming. Checking the
+ * error state of the NVDIMM, getting a random number with the darn
+ * instruction and checking the ES or NVM health status.
*/
+
+/// BPM - Backup Power Module
+
#include <trace/interface.H>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
+#include <errl/errludstring.H>
#include <util/runtime/rt_fwreq_helper.H>
#include <targeting/common/attributes.H>
#include <targeting/common/commontargeting.H>
#include <targeting/common/util.H>
#include <targeting/common/utilFilter.H>
-#include <usr/runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <runtime/interface.h>
+#include <arch/ppc.H>
#include <isteps/nvdimm/nvdimmreasoncodes.H>
+#include "../errlud_nvdimm.H"
+#include "../nvdimmErrorLog.H"
#include <isteps/nvdimm/nvdimm.H> // implements some of these
#include "../nvdimm.H" // for g_trac_nvdimm
+#include <sys/time.h>
//#define TRACUCOMP(args...) TRACFCOMP(args)
#define TRACUCOMP(args...)
+using namespace TARGETING;
+using namespace ERRORLOG;
+
namespace NVDIMM
{
+static constexpr uint64_t DARN_ERROR_CODE = 0xFFFFFFFFFFFFFFFFull;
+static constexpr uint32_t MAX_DARN_ERRORS = 10;
+
/**
-* @brief Notify PHYP of NVDIMM OCC protection status
-*/
-errlHndl_t notifyNvdimmProtectionChange(TARGETING::Target* i_target,
- const nvdimm_protection_t i_state)
+ * @brief Check nvdimm error state
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @return bool - true if nvdimm is in any error state, false otherwise
+ */
+bool nvdimmInErrorState(Target *i_nvdimm)
{
- errlHndl_t l_err = nullptr;
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmInErrorState() HUID[%X]",get_huid(i_nvdimm));
- // default to send a not protected status
- uint64_t l_nvdimm_protection_state =
- hostInterfaces::HBRT_FW_NVDIMM_NOT_PROTECTED;
+ uint8_t l_statusFlag = i_nvdimm->getAttr<ATTR_NV_STATUS_FLAG>();
+ bool l_ret = true;
- TRACFCOMP( g_trac_nvdimm, ENTER_MRK
- "notifyNvdimmProtectionChange: Target huid 0x%.8X, state %d",
- get_huid(i_target), i_state);
- do
+ // Just checking bit 1 for now, need to investigate these
+ // Should be checking NVDIMM_ARMED instead
+ if ((l_statusFlag & NSTD_VAL_ERASED) == 0)
{
- TARGETING::TargetHandleList l_nvdimmTargetList =
- TARGETING::getProcNVDIMMs(i_target);
+ l_ret = false;
+ }
- // Only send command if the processor has an NVDIMM under it
- if (l_nvdimmTargetList.empty())
+ // Also check the encryption error status
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "nvdimmInErrorState: no TopLevelTarget");
+ if (l_sys->getAttr<ATTR_NVDIMM_ENCRYPTION_ENABLE>())
+ {
+ ATTR_NVDIMM_ARMED_type l_armed_state = {};
+ l_armed_state = i_nvdimm->getAttr<ATTR_NVDIMM_ARMED>();
+ if (l_armed_state.encryption_error_detected)
{
- TRACFCOMP( g_trac_nvdimm,
- "notifyNvdimmProtectionChange: No NVDIMM found under processor 0x%.8X",
- get_huid(i_target));
- break;
+ l_ret = true;
}
+ }
+
+ TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmInErrorState() HUID[%X]",get_huid(i_nvdimm));
+ return l_ret;
+}
+
- TARGETING::ATTR_NVDIMM_ARMED_type l_nvdimm_armed_state =
- i_target->getAttr<TARGETING::ATTR_NVDIMM_ARMED>();
+// This could be made a generic utility
+errlHndl_t nvdimm_getDarnNumber(size_t i_genSize, uint8_t* o_genData)
+{
+ assert(i_genSize % sizeof(uint64_t) == 0,"nvdimm_getDarnNumber() bad i_genSize");
- // Only notify protected state if NVDIMM controllers are
- // armed and no error was or is detected
- if (i_state == NVDIMM::PROTECTED)
+ errlHndl_t l_err = nullptr;
+ uint64_t* l_darnData = reinterpret_cast<uint64_t*>(o_genData);
+
+ for (uint32_t l_loop = 0; l_loop < (i_genSize / sizeof(uint64_t)); l_loop++)
+ {
+ // Darn could return an error code
+ uint32_t l_darnErrors = 0;
+
+ while (l_darnErrors < MAX_DARN_ERRORS)
{
- // Exit without notifying phyp if in error state
- if (l_nvdimm_armed_state.error_detected)
+ // Get a 64-bit random number with the darn instruction
+ l_darnData[l_loop] = getDarn();
+
+ if ( l_darnData[l_loop] != DARN_ERROR_CODE )
{
- // State can't go to protected after error is detected
break;
}
- // check if we need to rearm the NVDIMM(s)
- else if (!l_nvdimm_armed_state.armed)
- {
- bool nvdimms_armed =
- NVDIMM::nvdimmArm(l_nvdimmTargetList);
- if (nvdimms_armed)
- {
- // NVDIMMs are now armed and ready for backup
- l_nvdimm_armed_state.armed = 1;
- i_target->setAttr<TARGETING::ATTR_NVDIMM_ARMED>(l_nvdimm_armed_state);
-
- l_nvdimm_protection_state = hostInterfaces::HBRT_FW_NVDIMM_PROTECTED;
- }
- else
- {
- // If nvdimm arming failed,
- // do NOT post that the dimms are now protected.
-
- // Remember this error, only try arming once
- if (!l_nvdimm_armed_state.error_detected)
- {
- l_nvdimm_armed_state.error_detected = 1;
- i_target->setAttr<TARGETING::ATTR_NVDIMM_ARMED>(l_nvdimm_armed_state);
- }
-
- // Exit without notifying phyp of any protection change
- break;
- }
- }
else
{
- // NVDIMM already armed and no error found
- l_nvdimm_protection_state = hostInterfaces::HBRT_FW_NVDIMM_PROTECTED;
+ l_darnErrors++;
}
}
- else if (i_state == NVDIMM::UNPROTECTED_BECAUSE_ERROR)
+
+ if (l_darnErrors == MAX_DARN_ERRORS)
{
- // Remember that this NV controller has an error so
- // we don't rearm this until next IPL
- if (!l_nvdimm_armed_state.error_detected)
- {
- l_nvdimm_armed_state.error_detected = 1;
- i_target->setAttr<TARGETING::ATTR_NVDIMM_ARMED>(l_nvdimm_armed_state);
- }
- // still notify phyp that NVDIMM is Not Protected
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_getDarnNumber() reached MAX_DARN_ERRORS");
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ENCRYPTION_MAX_DARN_ERRORS
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_GET_DARN_NUMBER
+ *@userdata1 MAX_DARN_ERRORS
+ *@devdesc Error using darn instruction
+ *@custdesc NVDIMM encryption error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_GET_DARN_NUMBER,
+ NVDIMM_ENCRYPTION_MAX_DARN_ERRORS,
+ MAX_DARN_ERRORS,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ break;
}
+ }
+ return l_err;
+}
- // Get the Proc Chip Id
- RT_TARG::rtChipId_t l_chipId = 0;
- l_err = RT_TARG::getRtTarget(i_target, l_chipId);
- if(l_err)
+errlHndl_t nvdimm_getRandom(uint8_t* o_genData)
+{
+ errlHndl_t l_err = nullptr;
+ uint8_t l_xtraData[ENC_KEY_SIZE] = {0};
+
+ do
+ {
+ // Get a random number with the darn instruction
+ l_err = nvdimm_getDarnNumber(ENC_KEY_SIZE, o_genData);
+ if (l_err)
{
- TRACFCOMP( g_trac_nvdimm,
- ERR_MRK"notifyNvdimmProtectionChange: getRtTarget ERROR" );
break;
}
- // send the notification msg
- if ((nullptr == g_hostInterfaces) ||
- (nullptr == g_hostInterfaces->firmware_request))
+ // Validate and update the random number
+ // Retry if more randomness required
+ do
{
- TRACFCOMP( g_trac_nvdimm, ERR_MRK"notifyNvdimmProtectionChange: "
- "Hypervisor firmware_request interface not linked");
+ //Get replacement data
+ l_err = nvdimm_getDarnNumber(ENC_KEY_SIZE, l_xtraData);
+ if (l_err)
+ {
+ break;
+ }
+
+ }while (nvdimm_keyifyRandomNumber(o_genData, l_xtraData));
+
+ }while (0);
+
+ return l_err;
+}
+
+/*
+ * @brief Check the ES (enery source)/backup power module(BPM) health status of
+ * the individual NVDIMMs supplied in list
+ *
+ * @param[in] i_nvdimmTargetList - list of NVDIMMs to check the ES health of
+ *
+ * @return false if one or more NVDIMMs fail ES health check, else true
+ */
+bool nvDimmEsCheckHealthStatus(const TargetHandleList &i_nvdimmTargetList)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvDimmEsCheckHealthStatus(): "
+ "Target list size(%d)", i_nvdimmTargetList.size());
+
+ // The minimum ES lifetime value
+ const uint8_t ES_LIFETIME_MINIMUM_REQUIREMENT = 0x62; // > 97%
+
+ // The ES health check status flags for the different states of an
+ // ES health check
+ const uint8_t ES_HEALTH_CHECK_IN_PROGRESS_FLAG = 0x01; // bit 0
+ const uint8_t ES_HEALTH_CHECK_SUCCEEDED_FLAG = 0x02; // bit 1
+ const uint8_t ES_HEALTH_CHECK_FAILED_FLAG = 0x04; // bit 2
- // need to safely convert struct type into uint32_t
- union {
- TARGETING::ATTR_NVDIMM_ARMED_type tNvdimmArmed;
- uint32_t nvdimmArmed_int;
- } armed_state_union;
- armed_state_union.tNvdimmArmed = l_nvdimm_armed_state;
+ // Handle to catch any errors
+ errlHndl_t l_err(nullptr);
+
+ // The ES health check status from an ES health check call
+ uint8_t l_esHealthCheck(0);
+
+ // Status of the accumulation of all calls related to the ES health check.
+ // If any one call is bad/fails, then this will be false, else it stays true
+ bool l_didEsHealthCheckPass(true);
+
+ // Iterate thru the NVDIMMs checking the ES health status of each one.
+ // Going with the assumption that the caller waited the allotted time,
+ // roughly 20 to 30 minutes, after the start of an IPL.
+ // Success case:
+ // * ES health check initiated at start of the IPL, caller waited the
+ // allotted time (20 to 30 mins) before doing a health check, health
+ // check returned success and the lifetime meets the minimum threshold
+ // for a new BPM.
+ // Error cases are:
+ // * ES health check is in progress, will assume BPM is hung
+ // * ES health check failed
+ // * ES health check succeeded but lifetime does not meet a
+ // certain threshold
+ // * If none of the above apply (success case and other error cases),
+ // then assume the ES health check was never initiated at the start
+ // of the IPL
+ // For each of these error cases do a predictive callout
+ for (auto const l_nvdimm : i_nvdimmTargetList)
+ {
+ // Retrieve the Health Check status from the BPM
+ TRACFCOMP(g_trac_nvdimm, INFO_MRK"nvDimmEsCheckHealthStatus(): "
+ "Reading NVDIMM(0x%.8X) ES health check data, "
+ "register ES_CMD_STATUS0(0x%.2X)",
+ get_huid(l_nvdimm), ES_CMD_STATUS0);
+
+ l_err = nvdimmReadReg(l_nvdimm, ES_CMD_STATUS0, l_esHealthCheck);
+
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvDimmEsCheckHealthStatus(): "
+ "NVDIMM(0x%X) failed to read the ES health check "
+ "data, register ES_CMD_STATUS0(0x%.2X)",
+ get_huid(l_nvdimm), ES_CMD_STATUS0);
+
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit(l_err, NVDIMM_COMP_ID);
+
+ // Let the caller know something went amiss
+ l_didEsHealthCheckPass = false;
+
+ // Proceed to next NVDIMM, better luck next time
+ continue;
+ }
+
+ // Trace out the returned data for inspection
+ TRACFCOMP(g_trac_nvdimm, INFO_MRK"nvDimmEsCheckHealthStatus(): "
+ "NVDIMM(0x%X) returned value(0x%.2X) from the ES health "
+ "check data, register ES_CMD_STATUS0(0x%.2X)",
+ get_huid(l_nvdimm), l_esHealthCheck, ES_CMD_STATUS0);
+
+ if (l_esHealthCheck & ES_HEALTH_CHECK_IN_PROGRESS_FLAG)
+ {
+ TRACFCOMP( g_trac_nvdimm, ERR_MRK"nvDimmEsCheckHealthStatus(): "
+ "Assuming caller waited the allotted time before "
+ "doing an ES health check on NVDIMM(0x%.8X), the BPM "
+ "is hung doing the ES health check.",
+ get_huid(l_nvdimm) );
/*@
* @errortype
- * @severity ERRL_SEV_PREDICTIVE
- * @moduleid NOTIFY_NVDIMM_PROTECTION_CHG
- * @reasoncode NVDIMM_NULL_FIRMWARE_REQUEST_PTR
- * @userdata1 HUID of processor target
- * @userdata2[0:31] Requested protection state
- * @userdata2[32:63] Current armed state
- * @devdesc Unable to inform PHYP of NVDIMM protection
- * @custdesc Internal firmware error
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid NVDIMM_ES_HEALTH_CHECK
+ * @reasoncode NVDIMM_ES_HEALTH_CHECK_IN_PROGRESS_FAILURE
+ * @userdata1 HUID of NVDIMM target
+ * @userdata2 ES health check status
+ * @devdesc Assuming caller waited the allotted time before
+ * doing an ES health check, then the BPM is hung doing
+ * the ES health check.
+ * @custdesc NVDIMM ES health check failed.
*/
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
- NOTIFY_NVDIMM_PROTECTION_CHG,
- NVDIMM_NULL_FIRMWARE_REQUEST_PTR,
- get_huid(i_target),
- TWO_UINT32_TO_UINT64(
- l_nvdimm_protection_state,
- armed_state_union.nvdimmArmed_int)
- );
-
- l_err->addProcedureCallout(HWAS::EPUB_PRC_PHYP_CODE,
+ l_err = new ErrlEntry( ERRL_SEV_PREDICTIVE,
+ NVDIMM_ES_HEALTH_CHECK,
+ NVDIMM_ES_HEALTH_CHECK_IN_PROGRESS_FAILURE,
+ get_huid(l_nvdimm),
+ l_esHealthCheck,
+ ErrlEntry::NO_SW_CALLOUT );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
+
+ // Add a BPM callout
+ l_err->addPartCallout( l_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ nvdimmAddPage4Regs(l_nvdimm,l_err);
+ // Collect the error
+ errlCommit(l_err, NVDIMM_COMP_ID);
+
+ // Let the caller know something went amiss
+ l_didEsHealthCheckPass = false;
+ }
+ else if (l_esHealthCheck & ES_HEALTH_CHECK_FAILED_FLAG)
+ {
+ TRACFCOMP( g_trac_nvdimm, ERR_MRK"nvDimmEsCheckHealthStatus(): "
+ "Assuming caller waited the allotted time before "
+ "doing an ES health check on NVDIMM(0x%.8X), the BPM "
+ "reported a failure.",
+ get_huid(l_nvdimm) );
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid NVDIMM_ES_HEALTH_CHECK
+ * @reasoncode NVDIMM_ES_HEALTH_CHECK_REPORTED_FAILURE
+ * @userdata1 HUID of NVDIMM target
+ * @userdata2 ES health check status
+ * @devdesc Assuming caller waited the allotted time before
+ * doing an ES health check, the BPM reported a failure
+ * while doing an ES health check.
+ * @custdesc NVDIMM ES health check failed.
+ */
+ l_err = new ErrlEntry( ERRL_SEV_PREDICTIVE,
+ NVDIMM_ES_HEALTH_CHECK,
+ NVDIMM_ES_HEALTH_CHECK_REPORTED_FAILURE,
+ get_huid(l_nvdimm),
+ l_esHealthCheck,
+ ErrlEntry::NO_SW_CALLOUT );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
+
+ // Add a BPM callout
+ l_err->addPartCallout( l_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ nvdimmAddPage4Regs(l_nvdimm,l_err);
+ // Collect the error
+ errlCommit(l_err, NVDIMM_COMP_ID);
+
+ // Let the caller know something went amiss
+ l_didEsHealthCheckPass = false;
+ }
+ else if (l_esHealthCheck & ES_HEALTH_CHECK_SUCCEEDED_FLAG)
+ {
+ TRACFCOMP(g_trac_nvdimm, INFO_MRK"nvDimmEsCheckHealthStatus(): "
+ "Reading NVDIMM(0x%.8X) ES lifetime data, "
+ "register ES_LIFETIME(0x%.2X)",
+ get_huid(l_nvdimm), ES_LIFETIME);
+
+ // The lifetime percentage
+ uint8_t l_lifetimePercentage(0);
+
+ // Retrieve the Lifetime Percentage from the BPM
+ l_err = nvdimmReadReg(l_nvdimm, ES_LIFETIME, l_lifetimePercentage);
+
+ if (l_err)
+ {
+ TRACFCOMP( g_trac_nvdimm, ERR_MRK"nvDimmEsCheckHealthStatus(): "
+ "NVDIMM(0x%.8X) failed to read the "
+ "ES_LIFETIME(0x%.2X) data",
+ get_huid(l_nvdimm),
+ ES_LIFETIME );
+
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit(l_err, NVDIMM_COMP_ID);
+
+ // Let the caller know something went amiss
+ l_didEsHealthCheckPass = false;
+ }
+ else if (l_lifetimePercentage < ES_LIFETIME_MINIMUM_REQUIREMENT)
+ {
+ TRACFCOMP( g_trac_nvdimm, ERR_MRK"nvDimmEsCheckHealthStatus(): "
+ "ES health check on NVDIMM(0x%.8X) succeeded but "
+ "the BPM's lifetime(%d) does not meet the minimum "
+ "requirement(%d) needed to qualify as a new BPM.",
+ get_huid(l_nvdimm),
+ l_lifetimePercentage,
+ ES_LIFETIME_MINIMUM_REQUIREMENT );
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid NVDIMM_ES_HEALTH_CHECK
+ * @reasoncode NVDIMM_ES_LIFETIME_MIN_REQ_NOT_MET
+ * @userdata1[00:31] HUID of NVDIMM target
+ * @userdata1[32:63] ES health check status
+ * @userdata2[00:31] Retrieved lifetime percentage
+ * @userdata2[32:63] lifetime minimum requirement
+ * @devdesc ES health check succeeded but the BPM's
+ * lifetime does not meet the minimum
+ * requirement needed to qualify as a
+ * new BPM.
+ * @custdesc NVDIMM ES health check failed
+ */
+ l_err = new ErrlEntry( ERRL_SEV_PREDICTIVE,
+ NVDIMM_ES_HEALTH_CHECK,
+ NVDIMM_ES_LIFETIME_MIN_REQ_NOT_MET,
+ TWO_UINT32_TO_UINT64(
+ get_huid(l_nvdimm),
+ l_esHealthCheck),
+ TWO_UINT32_TO_UINT64(
+ l_lifetimePercentage,
+ ES_LIFETIME_MINIMUM_REQUIREMENT),
+ ErrlEntry::NO_SW_CALLOUT );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
+
+ // Add a BPM callout
+ l_err->addPartCallout( l_nvdimm,
+ HWAS::BPM_PART_TYPE,
HWAS::SRCI_PRIORITY_HIGH);
+ nvdimmAddPage4Regs(l_nvdimm,l_err);
+ // Collect the error
+ errlCommit(l_err, NVDIMM_COMP_ID);
+
+ // Let the caller know something went amiss
+ l_didEsHealthCheckPass = false;
+ } // end else if (l_lifetimePercentage ...
+ else
+ {
+ TRACFCOMP( g_trac_nvdimm, ERR_MRK"nvDimmEsCheckHealthStatus(): "
+ "Success: ES health check on NVDIMM(0x%.8X) "
+ "succeeded and the BPM's lifetime(%d) meet's the "
+ "minimum requirement(%d) needed to qualify as "
+ "a new BPM.",
+ get_huid(l_nvdimm),
+ l_lifetimePercentage,
+ ES_LIFETIME_MINIMUM_REQUIREMENT );
+ }
+ } // end else if (l_esHealthCheck & ES_HEALTH_CHECK_SUCCEEDED_FLAG)
+ else // Assume the ES health check was never initiated at
+ // the start of the IPL.
+ {
+ TRACFCOMP( g_trac_nvdimm, ERR_MRK"nvDimmEsCheckHealthStatus(): "
+ "The ES health check on NVDIMM(0x%.8X) shows no status "
+ "(in progress, fail or succeed) so assuming it was "
+ "never initiated at the start of the IPL.",
+ get_huid(l_nvdimm) );
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid NVDIMM_ES_HEALTH_CHECK
+ * @reasoncode NVDIMM_ES_HEALTH_CHECK_NEVER_INITIATED
+ * @userdata1 HUID of NVDIMM target
+ * @userdata2 ES health check status
+ * @devdesc The ES health check shows no status (in progress,
+ * fail or succeed) so assuming it was never initiated
+ * at the start of the IPL.
+ * @custdesc NVDIMM ES health check failed.
+ */
+ l_err = new ErrlEntry( ERRL_SEV_PREDICTIVE,
+ NVDIMM_ES_HEALTH_CHECK,
+ NVDIMM_ES_HEALTH_CHECK_NEVER_INITIATED,
+ get_huid(l_nvdimm),
+ l_esHealthCheck,
+ ErrlEntry::NO_SW_CALLOUT );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
- break;
+ // Add a BPM callout
+ l_err->addPartCallout( l_nvdimm,
+ HWAS::BPM_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ nvdimmAddPage4Regs(l_nvdimm,l_err);
+ // Collect the error
+ errlCommit(l_err, NVDIMM_COMP_ID);
+
+ // Let the caller know something went amiss
+ l_didEsHealthCheckPass = false;
}
+ } // end for (auto const l_nvdimm : i_nvdimmTargetList)
- TRACFCOMP( g_trac_nvdimm,
- "notifyNvdimmProtectionChange: 0x%.8X processor NVDIMMS are "
- "%s protected (current armed_state: 0x%02X)",
- get_huid(i_target),
- (l_nvdimm_protection_state == hostInterfaces::HBRT_FW_NVDIMM_PROTECTED)?"now":"NOT",
- l_nvdimm_armed_state );
-
- // Create the firmware_request request struct to send data
- hostInterfaces::hbrt_fw_msg l_req_fw_msg;
- memset(&l_req_fw_msg, 0, sizeof(l_req_fw_msg)); // clear it all
-
- // actual msg size (one type of hbrt_fw_msg)
- uint64_t l_req_fw_msg_size = hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
- sizeof(l_req_fw_msg.nvdimm_protection_state);
-
- // Populate the firmware_request request struct with given data
- l_req_fw_msg.io_type =
- hostInterfaces::HBRT_FW_MSG_TYPE_NVDIMM_PROTECTION;
- l_req_fw_msg.nvdimm_protection_state.i_procId = l_chipId;
- l_req_fw_msg.nvdimm_protection_state.i_state =
- l_nvdimm_protection_state;
-
- // Create the firmware_request response struct to receive data
- hostInterfaces::hbrt_fw_msg l_resp_fw_msg;
- uint64_t l_resp_fw_msg_size = sizeof(l_resp_fw_msg);
- memset(&l_resp_fw_msg, 0, l_resp_fw_msg_size);
-
- // Make the firmware_request call
- l_err = firmware_request_helper(l_req_fw_msg_size,
- &l_req_fw_msg,
- &l_resp_fw_msg_size,
- &l_resp_fw_msg);
-
- } while (0);
-
- TRACFCOMP( g_trac_nvdimm,
- EXIT_MRK "notifyNvdimmProtectionChange(%.8X, %d) - ERRL %.8X:%.4X",
- get_huid(i_target), i_state,
- ERRL_GETEID_SAFE(l_err), ERRL_GETRC_SAFE(l_err) );
+ // Should not have any uncommitted errors
+ assert(l_err == NULL, "nvDimmEsCheckHealthStatus() - unexpected "
+ "uncommitted error found" );
- return l_err;
-}
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvDimmEsCheckHealthStatus(): "
+ "Returning %s", l_didEsHealthCheckPass == true ? "true" : "false");
+
+ return l_didEsHealthCheckPass;
+} // end nvDimmEsCheckHealthStatus
/**
- * @brief This function polls the command status register for arm completion
- * (does not indicate success or fail)
+ * @brief A wrapper around the call to nvDimmEsCheckHealthStatus
*
- * @param[in] i_nvdimm - nvdimm target with NV controller
+ * @see nvDimmEsCheckHealthStatus for more details
*
- * @param[out] o_poll - total polled time in ms
- *
- * @return errlHndl_t - Null if successful, otherwise a pointer to
- * the error log.
+ * @return false if one or more NVDIMMs fail an ES health check, else true
*/
-errlHndl_t nvdimmPollArmDone(TARGETING::Target* i_nvdimm,
- uint32_t &o_poll)
+bool nvDimmEsCheckHealthStatusOnSystem()
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmPollArmDone() nvdimm[%X]", TARGETING::get_huid(i_nvdimm) );
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvDimmEsCheckHealthStatusOnSystem()");
- errlHndl_t l_err = nullptr;
+ // Get the list of NVDIMM Targets from the system
+ TargetHandleList l_nvDimmTargetList;
+ nvdimm_getNvdimmList(l_nvDimmTargetList);
- l_err = nvdimmPollStatus ( i_nvdimm, ARM, o_poll);
+ // Return status of doing a check health status
+ bool l_didEsHealthCheckPass = nvDimmEsCheckHealthStatus(l_nvDimmTargetList);
- TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmPollArmDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvDimmEsCheckHealthStatusOnSystem(): "
+ "Returning %s", l_didEsHealthCheckPass == true ? "true" : "false" );
- return l_err;
-}
+ return l_didEsHealthCheckPass;
+} // end nvDimmCheckHealthStatusOnSystem
-/**
- * @brief This function checks the arm status register to make sure
- * the trigger has been armed to ddr_reset_n
+/*
+ * @brief Check the bad flash block percentage against a given maximum allowed.
*
- * @param[in] i_nvdimm - nvdimm target with NV controller
+ * @details This returns a tristate - 1 pass, 2 different fails
+ * If true is returned, then the check passed and
+ * o_badFlashBlockPercentage will contain what the retrieved
+ * flash block percentage is.
+ * If false is returned and the o_badFlashBlockPercentage is zero, then
+ * the check failed because of a register read fail
+ * If false is returned and the o_badFlashBlockPercentage is not zero,
+ * then the check failed because the retrieved bad flash block
+ * percentage exceeds the given maximum allowed
*
- * @return errlHndl_t - Null if successful, otherwise a pointer to
- * the error log.
+ * @param[in] i_nvDimm - The NVDIMM to check
+ * @param[in] i_maxPercentageAllowed - The maximum percentage of bad flash
+ * block allowed
+ * @param[out] o_badFlashBlockPercentage - The retrieved bad flash block
+ * percentage from i_nvDimm, if no
+ * register read error.
+ *
+ * @return false if check failed or register read failed, else true
*/
-errlHndl_t nvdimmCheckArmSuccess(TARGETING::Target *i_nvdimm)
+bool nvDimmCheckBadFlashBlockPercentage(TargetHandle_t i_nvDimm,
+ const uint8_t i_maxPercentageAllowed,
+ uint8_t &o_badFlashBlockPercentage)
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmCheckArmSuccess() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ // Cache the HUID of the NVDIMM
+ uint32_t l_nvDimmHuid = get_huid( i_nvDimm );
- errlHndl_t l_err = nullptr;
- uint8_t l_data = 0;
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvDimmCheckBadFlashBlockPercentage(): "
+ "NVDIMM(0x%.4X), max bad flash blocks allowed(%d)",
+ l_nvDimmHuid,
+ i_maxPercentageAllowed);
+
+ // The status of the check on the bad block percentage
+ bool l_didBadFlashBlockPercentageCheckPass(true);
+
+ // The retrieved flash block percentage from register, initialize to zero
+ o_badFlashBlockPercentage = 0;
+
+ // Handle to catch any errors
+ errlHndl_t l_err(nullptr);
+
+ // Retrieve the percentage of bad blocks and validate
+ TRACDCOMP(g_trac_nvdimm, INFO_MRK"nvDimmCheckBadFlashBlockPercentage(): "
+ "Reading NVDIMM(0x%.8X) percentage of bad blocks from "
+ "register FLASH_BAD_BLK_PCT(0x%.4X)",
+ l_nvDimmHuid, FLASH_BAD_BLK_PCT);
- l_err = nvdimmReadReg(i_nvdimm, ARM_STATUS, l_data);
+ l_err = nvdimmReadReg(i_nvDimm,
+ FLASH_BAD_BLK_PCT,
+ o_badFlashBlockPercentage);
if (l_err)
{
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmCheckArmSuccess() nvdimm[%X]"
- "failed to read arm status reg!",TARGETING::get_huid(i_nvdimm));
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvDimmCheckBadFlashBlockPercentage(): "
+ "FAIL: NVDIMM(0x%.8X) failed to read the percentage of "
+ "bad blocks from register FLASH_BAD_BLK_PCT(0x%.4X), "
+ "marking as a fail",
+ l_nvDimmHuid, FLASH_BAD_BLK_PCT);
+
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit(l_err, NVDIMM_COMP_ID);
+
+ // Set up the fail state, so caller can determine that the fail was
+ // due to a register read error
+ l_didBadFlashBlockPercentageCheckPass = false;
+ o_badFlashBlockPercentage = 0;
}
- else if ((l_data & ARM_SUCCESS) != ARM_SUCCESS)
+ else
{
+ // Trace out the returned data for inspection
+ TRACDCOMP(g_trac_nvdimm, INFO_MRK"nvDimmCheckBadFlashBlockPercentage(): "
+ "NVDIMM(0x%.8X) returned value (%d) from the "
+ "percentage of bad blocks, register "
+ "FLASH_BAD_BLK_PCT(0x%.4X)",
+ l_nvDimmHuid,
+ o_badFlashBlockPercentage,
+ FLASH_BAD_BLK_PCT);
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmCheckArmSuccess() nvdimm[%X]"
- "failed to arm!",TARGETING::get_huid(i_nvdimm));
- /*@
- *@errortype
- *@reasoncode NVDIMM_ARM_FAILED
- *@severity ERRORLOG_SEV_PREDICTIVE
- *@moduleid NVDIMM_SET_ARM
- *@userdata1[0:31] Related ops (0xff = NA)
- *@userdata1[32:63] Target Huid
- *@userdata2 <UNUSED>
- *@devdesc Encountered error arming the catastrophic save
- * trigger on NVDIMM. Make sure an energy source
- * is connected to the NVDIMM and the ES policy
- * is set properly
- *@custdesc NVDIMM encountered error arming save trigger
- */
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
- NVDIMM_SET_ARM,
- NVDIMM_ARM_FAILED,
- TWO_UINT32_TO_UINT64(ARM, TARGETING::get_huid(i_nvdimm)),
- 0x0,
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
-
- l_err->collectTrace(NVDIMM_COMP_NAME, 256 );
-
- // Failure to arm could mean internal NV controller error or
- // even error on the battery pack. NVDIMM will lose persistency
- // if failed to arm trigger
- l_err->addPartCallout( i_nvdimm,
- HWAS::NV_CONTROLLER_PART_TYPE,
- HWAS::SRCI_PRIORITY_HIGH);
- l_err->addPartCallout( i_nvdimm,
- HWAS::BPM_PART_TYPE,
- HWAS::SRCI_PRIORITY_MED);
- l_err->addPartCallout( i_nvdimm,
- HWAS::BPM_CABLE_PART_TYPE,
- HWAS::SRCI_PRIORITY_MED);
- }
+ // Check to see if the bad flash block percentage
+ // exceeds maximum allowed.
+ if (o_badFlashBlockPercentage > i_maxPercentageAllowed)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvDimmCheckBadFlashBlockPercentage(): "
+ "FAIL: For NVDIMM (0x%.8X), the percentage of bad "
+ "flash blocks (%d), read from register "
+ "FLASH_BAD_BLK_PCT(0x%.4X), exceeds the maximum "
+ "percentage of bad flash blocks allowed (%d), marking "
+ "this as a fail",
+ l_nvDimmHuid,
+ o_badFlashBlockPercentage,
+ FLASH_BAD_BLK_PCT,
+ i_maxPercentageAllowed);
- TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmCheckArmSuccess() nvdimm[%X] ret[%X]",
- TARGETING::get_huid(i_nvdimm), l_data);
+ // Set up the fail state, so caller can determine that the fail was
+ // due to percentage exceeding the max percentage allowed.
+ // Note: Leave the value in o_badFlashBlockPercentage so caller
+ // can inspect, if they wish
+ l_didBadFlashBlockPercentageCheckPass = false;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nvdimm, INFO_MRK"nvDimmCheckBadFlashBlockPercentage(): "
+ "SUCCESS: For NVDIMM (0x%.8X), the percentage of bad "
+ "flash blocks (%d) is less than or meets the maximum "
+ "percentage of bad flash blocks allowed (%d), "
+ "marking this as a pass",
+ l_nvDimmHuid,
+ o_badFlashBlockPercentage,
+ i_maxPercentageAllowed);
- return l_err;
+ // Set up the pass state
+ // Note: Leave the value in o_badFlashBlockPercentage so caller
+ // can inspect, if they wish
+ l_didBadFlashBlockPercentageCheckPass = true;
+ } // end if (l_badFlashBlockPercentage > i_maxPercentageAllowed)
+ } // end if (l_err) ... else
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvDimmCheckBadFlashBlockPercentage(): "
+ "Returning %s",
+ l_didBadFlashBlockPercentageCheckPass == true ? "true" : "false" );
+
+ return l_didBadFlashBlockPercentageCheckPass;
}
-bool nvdimmArm(TARGETING::TargetHandleList &i_nvdimmTargetList)
+/*
+ * @brief Check the flash error count against a given maximum allowed.
+ *
+ * @details This returns a tristate - 1 pass, 2 different fails
+ * If true is returned, then the check passed and
+ * o_readFlashErrorCount will contain what the retrieved
+ * flash error count is.
+ * If false is returned and the o_readFlashErrorCount is zero, then
+ * the check failed because of a register read fail
+ * If false is returned and the o_readFlashErrorCount is not zero,
+ * then the check failed because the retrieved flash error
+ * count exceeds the given maximum allowed
+ *
+ * @param[in] i_nvDimm - The NVDIMM to check
+ * @param[in] i_maxFlashErrorsAllowed - The maximum number of flash errors
+ * allowed
+ * @param[out] o_readFlashErrorCount - The retrieved bad flash error
+ * count from i_nvDimm, if no
+ * register read error.
+ *
+ * @return false if check failed or register read failed, else true
+ */
+bool nvDimmCheckFlashErrorCount(TargetHandle_t i_nvDimm,
+ const uint32_t i_maxFlashErrorsAllowed,
+ uint32_t &o_readFlashErrorCount)
{
- bool o_arm_successful = true;
+ // Cache the HUID of the NVDIMM
+ uint32_t l_nvDimmHuid = get_huid( i_nvDimm );
- TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmArm() %d",
- i_nvdimmTargetList.size());
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvDimmCheckFlashErrorCount(): "
+ "NVDIMM(0x%.4X), max flash errors allowed(%d)",
+ l_nvDimmHuid,
+ i_maxFlashErrorsAllowed);
- errlHndl_t l_err = nullptr;
+ // The status of the check on the flash error count
+ bool l_didFlashErrorCountCheckPass(true);
- for (auto const l_nvdimm : i_nvdimmTargetList)
+ // The retrieved flash error count from register, initialize to zero
+ o_readFlashErrorCount = 0;
+
+ // Handle to catch any errors
+ errlHndl_t l_err(nullptr);
+
+ // The retrieved flash error count from a register
+ uint8_t l_readFlashErrorCountByte(0);
+
+ // Read the flash error count registers starting from MSB to LSB
+ for (int16_t l_flashErrorRegister = FLASH_ERROR_COUNT2;
+ l_flashErrorRegister >= FLASH_ERROR_COUNT0;
+ --l_flashErrorRegister)
{
- // skip if the nvdimm is in error state
- if (NVDIMM::nvdimmInErrorState(l_nvdimm))
- {
- // error state means arming not successful
- o_arm_successful = false;
- continue;
- }
+ // Reset this for every iteration, may be redundant
+ l_readFlashErrorCountByte = 0;
+
+ TRACDCOMP(g_trac_nvdimm, INFO_MRK"nvDimmCheckFlashErrorCount(): "
+ "Reading NVDIMM(0x%.8X) flash error count from "
+ "register FLASH_ERROR_COUNT(0x%.4X)",
+ l_nvDimmHuid, l_flashErrorRegister);
+
+ l_err = nvdimmReadReg(i_nvDimm,
+ static_cast<i2cReg >(l_flashErrorRegister),
+ l_readFlashErrorCountByte);
- l_err = nvdimmSetESPolicy(l_nvdimm);
if (l_err)
{
- o_arm_successful = false;
- nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvDimmCheckFlashErrorCount(): "
+ "FAIL: NVDIMM(0x%.8X) failed to read flash error "
+ "count from register FLASH_ERROR_COUNT(0x%.4X) "
+ "marking as a fail",
+ l_nvDimmHuid, l_flashErrorRegister);
- // Committing the error as we don't want this to interrupt
- // the boot. This will notify the user that action is needed
- // on this module
l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024);
- errlCommit( l_err, NVDIMM_COMP_ID );
- continue;
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit(l_err, NVDIMM_COMP_ID);
+
+ // Set up the fail state, so caller can determine that the fail was
+ // due to a register read error
+ l_didFlashErrorCountCheckPass = false;
+ o_readFlashErrorCount = 0;
+
+ break;
}
- l_err = NVDIMM::nvdimmChangeArmState(l_nvdimm, ARM_TRIGGER);
- // If we run into any error here we will just
- // commit the error log and move on. Let the
- // system continue to boot and let the user
- // salvage the data
- if (l_err)
+ // If we get here, then the read was successful
+ // Append the read flash error count byte to the LSB of the
+ // aggregated flash error count bytes.
+ o_readFlashErrorCount = (o_readFlashErrorCount << 8) |
+ l_readFlashErrorCountByte;
+
+ TRACDCOMP(g_trac_nvdimm, INFO_MRK"nvDimmCheckFlashErrorCount(): "
+ "NVDIMM(0x%.8X) returned value (0x%.2X) from the "
+ "partial flash error count, register "
+ "FLASH_ERROR_COUNT(0x%.4X)",
+ l_nvDimmHuid,
+ l_readFlashErrorCountByte,
+ l_flashErrorRegister);
+
+ } // end for (int16_t l_flashErrorRegister = FLASH_ERROR_COUNT2; ...
+
+ // If o_readFlashErrorCount is not zero, then register read was successful
+ if (o_readFlashErrorCount)
+ {
+ TRACDCOMP(g_trac_nvdimm, INFO_MRK"nvDimmCheckFlashErrorCount(): "
+ "NVDIMM(0x%.8X) flash error count = %d ",
+ l_nvDimmHuid, o_readFlashErrorCount);
+
+ // Check the validity of the flash error count
+ if (o_readFlashErrorCount > i_maxFlashErrorsAllowed)
{
- NVDIMM::nvdimmSetStatusFlag(l_nvdimm, NVDIMM::NSTD_ERR_NOBKUP);
- // Committing the error as we don't want this to interrupt
- // the boot. This will notify the user that action is needed
- // on this module
- l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024);
- errlCommit( l_err, NVDIMM_COMP_ID );
- o_arm_successful = false;
- continue;
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvDimmCheckFlashErrorCount(): "
+ "FAIL: For NVDIMM (0x%.8X), the flash error count (%d), "
+ "read from registers FLASH_ERROR_COUNT0(0x%.4X), "
+ "FLASH_ERROR_COUNT1(0x%.4X) and FLASH_ERROR_COUNT2(0x%.4X), "
+ "exceeds the maximum number of flash "
+ "errors allowed (%d), marking this as a fail",
+ l_nvDimmHuid,
+ o_readFlashErrorCount,
+ FLASH_ERROR_COUNT0,
+ FLASH_ERROR_COUNT1,
+ FLASH_ERROR_COUNT2,
+ i_maxFlashErrorsAllowed);
+
+ // Set up the fail state, so caller can determine that the fail was
+ // due to error count exceeding the max errors allowed.
+ // Note: Leave the value in o_readFlashErrorCount so caller
+ // can inspect, if they wish
+ l_didFlashErrorCountCheckPass = false;
}
+ else
+ {
+ TRACFCOMP(g_trac_nvdimm, INFO_MRK"nvDimmCheckFlashErrorCount(): "
+ "SUCCESS: For NVDIMM(0x%.8X), the flash error counts "
+ "(%d) is less than or meets the maximum number of "
+ "errors allowed (%d), marking this as a pass",
+ l_nvDimmHuid,
+ o_readFlashErrorCount,
+ i_maxFlashErrorsAllowed);
- // Arm happens one module at a time. No need to set any offset on the counter
- uint32_t l_poll = 0;
- l_err = nvdimmPollArmDone(l_nvdimm, l_poll);
- if (l_err)
+ // Set up the pass state
+ // Note: Leave the value in o_readFlashErrorCount so caller
+ // can inspect, if they wish
+ l_didFlashErrorCountCheckPass = true;
+ }
+ } // end if (o_readFlashErrorCount)
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvDimmCheckFlashErrorCount(): "
+ "Returning %s",
+ l_didFlashErrorCountCheckPass == true ? "true" : "false" );
+
+ return l_didFlashErrorCountCheckPass;
+}
+
+/*
+ * @brief Check the NVM (non-volatile memory)/flash health of the individual
+ * NVDIMMs supplied in list.
+ *
+ * @param[in] i_nvdimmTargetList - list of NVDIMMs to check the health of flash
+ *
+ * @return false if one or more NVDIMMs fail NVM health check, else true
+ */
+bool nvDimmNvmCheckHealthStatus(const TargetHandleList &i_nvDimmTargetList)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvDimmNvmCheckHealthStatus(): "
+ "Target list size(%d)", i_nvDimmTargetList.size());
+
+ // The following maximums are the same values used by SMART's
+ // manufacturing and recommended that we use.
+ // The maximum percentage of bad flash blocks
+ // Fail if over 19% of bad flash blocks is encountered
+ const uint8_t MAXIMUM_PERCENTAGE_OF_BAD_FLASH_BLOCKS_ALLOWED = 19;
+ // The maximum number of flash memory errors allowed
+ // Fail if over 300 flash memory errors is encountered
+ const uint32_t MAXIMUM_NUMBER_OF_FLASH_MEMORY_ERRORS_ALLOWED = 300;
+
+ // Status of the accumulation of all calls related to the NVM health check.
+ // If any one call is bad/fails, then this will be false, else it stays true
+ bool l_didNvmHealthCheckPass(true);
+
+ // Handle to catch any errors
+ errlHndl_t l_err(nullptr);
+
+ // The retrieved flash block percentage from register
+ uint8_t l_badFlashBlockPercentage(0);
+ // The retrieved flash error count from register
+ uint32_t l_flashErrorCount(0);
+
+ // The status of the checks on the percentage of bad blocks and
+ // flash error count
+ // Default to true
+ bool l_badFlashBlockPercentageCheckPassed(true);
+ bool l_flashErrorCountCheckPassed(true);
+
+ // Iterate thru the supplied NVDIMMs checking the health of the NVM
+ for (auto const l_nvDimm : i_nvDimmTargetList)
+ {
+ // Cache the HUID of the NVDIMM
+ uint32_t l_nvDimmHuid = get_huid( l_nvDimm );
+
+ // Reset these for every NVDIMM that is checked
+ l_badFlashBlockPercentage = 0;
+ l_flashErrorCount = 0;
+ l_badFlashBlockPercentageCheckPassed = true;
+ l_flashErrorCountCheckPassed = true;
+
+ // Check the validity of bad flash block percentage
+ if (!nvDimmCheckBadFlashBlockPercentage(
+ l_nvDimm,
+ MAXIMUM_PERCENTAGE_OF_BAD_FLASH_BLOCKS_ALLOWED,
+ l_badFlashBlockPercentage))
{
- NVDIMM::nvdimmSetStatusFlag(l_nvdimm, NVDIMM::NSTD_ERR_NOBKUP);
- // Committing the error as we don't want this to interrupt
- // the boot. This will notify the user that action is needed
- // on this module
- l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024);
- errlCommit( l_err, NVDIMM_COMP_ID );
- o_arm_successful = false;
- continue;
+ // Set this to false to indicate that the overall check on the
+ // NVDIMMs had at least one failure
+ l_didNvmHealthCheckPass = false;
+
+ // If no data in the variable l_badFlashBlockPercentage, then
+ // this is a read register fail. Move onto the next NVDIMM
+ // this is a dud
+ if (!l_badFlashBlockPercentage)
+ {
+ continue;
+ }
+
+ // Set the check to false, to facilitate error reporting
+ l_badFlashBlockPercentageCheckPassed = false;
}
- l_err = nvdimmCheckArmSuccess(l_nvdimm);
- if (l_err)
+ // Check the validity of the flash error count
+ if (!nvDimmCheckFlashErrorCount(
+ l_nvDimm,
+ MAXIMUM_NUMBER_OF_FLASH_MEMORY_ERRORS_ALLOWED,
+ l_flashErrorCount))
{
- NVDIMM::nvdimmSetStatusFlag(l_nvdimm, NVDIMM::NSTD_ERR_NOBKUP);
- // Committing the error as we don't want this to interrupt
- // the boot. This will notify the user that action is needed
- // on this module
- l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024);
- errlCommit( l_err, NVDIMM_COMP_ID );
- o_arm_successful = false;
- continue;
+ // Set this to false to indicate that the overall check on the
+ // NVDIMMs had at least one failure
+ l_didNvmHealthCheckPass = false;
+
+ // If no data in the variable l_flashErrorCount, then
+ // this is a read register fail. Move onto the next NVDIMM
+ // this is a dud
+ if (!l_flashErrorCount)
+ {
+ continue;
+ }
+
+ // Set the check to false, to facilitate error reporting
+ l_flashErrorCountCheckPassed = false;
}
- // After arming the trigger, erase the image to prevent the possible
- // stale image getting the restored on the next boot in case of failed
- // save.
- l_err = nvdimmEraseNF(l_nvdimm);
- if (l_err)
+ /// Now we assess the health of the flash based on data gathered above
+ if ( !l_badFlashBlockPercentageCheckPassed ||
+ !l_flashErrorCountCheckPassed )
{
- NVDIMM::nvdimmSetStatusFlag(l_nvdimm, NVDIMM::NSTD_ERR_NOBKUP);
- // Committing the error as we don't want this to interrupt
- // the boot. This will notify the user that action is needed
- // on this module
- l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024);
- errlCommit( l_err, NVDIMM_COMP_ID );
- o_arm_successful = false;
+ // First set the NVDIMM HUID to the first 32 bits of user data 1
+ uint64_t l_badFlashBlockPercentageUserData1 =
+ TWO_UINT32_TO_UINT64(l_nvDimmHuid, 0);
- // If the erase failed let's disarm the trigger
- l_err = nvdimmChangeArmState(l_nvdimm, DISARM_TRIGGER);
- if (l_err)
+ // If an issue with the bad flash block percentage, then append
+ // data to user data 1
+ if (!l_badFlashBlockPercentageCheckPassed &&
+ l_badFlashBlockPercentage)
{
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmArm() nvdimm[%X], error disarming the nvdimm!",
- TARGETING::get_huid(l_nvdimm));
- l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024);
- errlCommit(l_err, NVDIMM_COMP_ID);
+ // Setting the HUID here is redundant but easier than trying to
+ // do some clever code that will set the HUID for user data 1
+ // when this path is not taken, but the next check on the flash
+ // error count is taken
+ l_badFlashBlockPercentageUserData1 =
+ TWO_UINT32_TO_UINT64(l_nvDimmHuid,
+ TWO_UINT16_TO_UINT32(
+ l_badFlashBlockPercentage,
+ MAXIMUM_PERCENTAGE_OF_BAD_FLASH_BLOCKS_ALLOWED));
}
- continue;
+ // If an issue with the flash error count, then set user
+ // data 2 to contain the flash error count value
+ uint64_t l_flashErrorCountUserData2(0);
+ if (!l_flashErrorCountCheckPassed &&
+ l_flashErrorCount)
+ {
+ l_flashErrorCountUserData2 =
+ TWO_UINT32_TO_UINT64(l_flashErrorCount,
+ MAXIMUM_NUMBER_OF_FLASH_MEMORY_ERRORS_ALLOWED);
+ }
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid NVDIMM_NVM_HEALTH_CHECK
+ * @reasoncode NVDIMM_NVM_HEALTH_CHECK_FAILED
+ * @userdata1[0:31] HUID of NVDIMM target
+ * @userdata1[32:47] The retrieved bad flash block percentage,
+ * if error with, else 0
+ * @userdata1[48:63] The maximum percentage of bad flash blocks
+ * allowed, if bad flash block percentage
+ * exceeds this maximum, else 0
+ * @userdata2[0:31] The retrieved flash error count,
+ * if error with, else 0
+ * @userdata2[32:63] The maximum number of flash errors
+ * allowed, if flash error exceeds this
+ * maximum, else 0
+ * @devdesc Either the NVDIMM NVM bad flash block
+ * percentage exceeded the maximum percentage
+ * allowed or the NVDIMM NVM number of flash
+ * error exceeds the maximum count allowed
+ * or both.
+ * @custdesc NVDIMM NVM health check failed.
+ */
+ l_err = new ErrlEntry( ERRL_SEV_PREDICTIVE,
+ NVDIMM_NVM_HEALTH_CHECK,
+ NVDIMM_NVM_HEALTH_CHECK_FAILED,
+ l_badFlashBlockPercentageUserData1,
+ l_flashErrorCountUserData2,
+ ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ nvdimmAddVendorLog(l_nvDimm, l_err);
+
+ // Add a DIMM callout
+ l_err->addHwCallout( l_nvDimm,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::NO_DECONFIG,
+ HWAS::GARD_NULL );
+
+ // Collect the error
+ errlCommit(l_err, NVDIMM_COMP_ID);
+
+ // Let the caller know something went amiss
+ l_didNvmHealthCheckPass = false;
}
- }
+ else
+ {
+ // This NVDIMM passed the NVM health check
+ TRACFCOMP(g_trac_nvdimm, INFO_MRK"nvDimmNvmCheckHealthStatus(): "
+ "Success: NVDIMM (0x%.8X) passed the NVM health check.",
+ l_nvDimmHuid);
+ } // end if ( !l_badFlashBlockPercentageCheckPassed .. else
+ } // end for (auto const l_nvdimm : i_nvdimmTargetList)
- TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmArm() returning %d",
- o_arm_successful);
- return o_arm_successful;
-}
+ // Should not have any uncommitted errors
+ assert(l_err == NULL, "nvDimmNvmCheckHealthStatus() - unexpected "
+ "uncommitted error found");
+
+ TRACFCOMP(g_trac_nvdimm,EXIT_MRK"nvDimmNvmCheckHealthStatus(): Returning %s",
+ l_didNvmHealthCheckPass == true ? "true" : "false" );
+
+ return l_didNvmHealthCheckPass;
+} // end nvDimmNvmCheckHealthStatus
/**
- * @brief Check nvdimm error state
+ * @brief A wrapper around the call to nvDimmNvmCheckHealthStatus
*
- * @param[in] i_nvdimm - nvdimm target
+ * @see nvDimmNvmCheckHealthStatus for more details
*
- * @return bool - true if nvdimm is in any error state, false otherwise
+ * @return false if one or more NVDIMMs fail an NVM health check, else true
*/
-bool nvdimmInErrorState(TARGETING::Target *i_nvdimm)
+bool nvDimmNvmCheckHealthStatusOnSystem()
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmInErrorState() HUID[%X]",TARGETING::get_huid(i_nvdimm));
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvDimmNvmCheckHealthStatusOnSystem()");
- uint8_t l_statusFlag = i_nvdimm->getAttr<TARGETING::ATTR_NV_STATUS_FLAG>();
- bool l_ret = true;
+ // Get the list of NVDIMM Targets from the system
+ TargetHandleList l_nvDimmTargetList;
+ nvdimm_getNvdimmList(l_nvDimmTargetList);
- if ((l_statusFlag & NSTD_ERR) == 0)
- l_ret = false;
+ // Return status of doing a check health status
+ bool l_didNvmHealthCheckPass = nvDimmNvmCheckHealthStatus(l_nvDimmTargetList);
- TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmInErrorState() HUID[%X]",TARGETING::get_huid(i_nvdimm));
- return l_ret;
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvDimmNvmCheckHealthStatusOnSystem(): "
+ "Returning %s", l_didNvmHealthCheckPass == true ? "true" : "false" );
+
+ return l_didNvmHealthCheckPass;
+} // end nvDimmCheckHealthStatusOnSystem
+
+
+/**
+ * @brief Send NV_STATUS to host
+ */
+void nvdimmSendNvStatus()
+{
+ // Send NV_STATUS for all nvdimms
+ TargetHandleList l_nvdimmTargetList;
+ nvdimm_getNvdimmList(l_nvdimmTargetList);
+ for (const auto & l_nvdimm : l_nvdimmTargetList)
+ {
+ errlHndl_t l_err = nullptr;
+ l_err = notifyNvdimmProtectionChange(l_nvdimm,SEND_NV_STATUS);
+ if (l_err)
+ {
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+ }
}
+
+struct registerNvdimmRt
+{
+ registerNvdimmRt()
+ {
+ // Register function to call at end of RT init
+ postInitCalls_t * rt_post = getPostInitCalls();
+ rt_post->callSendNvStatus = &nvdimmSendNvStatus;
+ }
+};
+
+registerNvdimmRt g_registerNvdimmRt;
+
} // end NVDIMM namespace
diff --git a/src/usr/isteps/openpower_vddr.C b/src/usr/isteps/openpower_vddr.C
index e05c1fd1d..9fdfe19e3 100644
--- a/src/usr/isteps/openpower_vddr.C
+++ b/src/usr/isteps/openpower_vddr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2016 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -27,7 +27,6 @@
// VDDR is enabled/disabled via a GPIO on the hammock card.
// A separate GPIO selects between 1.35V and 1.25V output from the VR.
-#include <config.h>
#include "platform_vddr.H"
diff --git a/src/usr/isteps/pm/occCheckstop.C b/src/usr/isteps/pm/occCheckstop.C
index 44b7296f0..a9154e2c6 100644
--- a/src/usr/isteps/pm/occCheckstop.C
+++ b/src/usr/isteps/pm/occCheckstop.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -59,6 +59,7 @@
#include <pnorif.H>
#include <pnor_const.H>
#include <utillidmgr.H>
+#include <secureboot/smf_utils.H>
#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS
#include <diag/prdf/prdfWriteHomerFirData.H>
@@ -476,6 +477,16 @@ namespace HBOCC
l_errl = PRDF::writeHomerFirData( config_data->firdataConfig,
sizeof(config_data->firdataConfig),
i_curHw);
+
+ if (SECUREBOOT::SMF::isSmfEnabled())
+ {
+ config_data->smfMode = SMF_MODE_ENABLED;
+ }
+ else
+ {
+ config_data->smfMode = SMF_MODE_DISABLED;
+ }
+
if (l_errl)
{
TRACFCOMP( g_fapiImpTd,
diff --git a/src/usr/isteps/pm/pm_common.C b/src/usr/isteps/pm/pm_common.C
index 376ec0278..a4c197621 100644
--- a/src/usr/isteps/pm/pm_common.C
+++ b/src/usr/isteps/pm/pm_common.C
@@ -82,6 +82,7 @@
#include <p9_stop_api.H>
#include <scom/scomif.H>
#include <p9_quad_scom_addresses.H>
+#include <secureboot/smf_utils.H>
#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS
@@ -242,6 +243,15 @@ namespace HBPM
l_config_data->firMaster = 0;
#endif
+ if (SECUREBOOT::SMF::isSmfEnabled())
+ {
+ l_config_data->smfMode = SMF_MODE_ENABLED;
+ }
+ else
+ {
+ l_config_data->smfMode = SMF_MODE_DISABLED;
+ }
+
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
EXIT_MRK"loadHostDataToHomer: RC=0x%X, PLID=0x%lX",
ERRL_GETRC_SAFE(l_errl), ERRL_GETPLID_SAFE(l_errl) );
@@ -275,9 +285,23 @@ namespace HBPM
do
{
- bool l_isNimbus = (i_target->getAttr<ATTR_MODEL>() == MODEL_NIMBUS);
- uint32_t l_lidId = (l_isNimbus) ? Util::NIMBUS_HCODE_LIDID
- : Util::CUMULUS_HCODE_LIDID;
+ uint32_t l_lidId = 0;
+ auto l_model = i_target->getAttr<ATTR_MODEL>();
+ switch( l_model )
+ {
+ case(MODEL_AXONE):
+ // Axone just reuses the Nimbus LIDID since it is only
+ // used to lookup a common partition in PNOR
+ case(MODEL_NIMBUS):
+ l_lidId = Util::NIMBUS_HCODE_LIDID;
+ break;
+ case(MODEL_CUMULUS):
+ l_lidId = Util::CUMULUS_HCODE_LIDID;
+ break;
+ default:
+ assert(false,"Unsupported proc type");
+ }
+
if(g_pHcodeLidMgr.get() == nullptr)
{
g_pHcodeLidMgr = std::shared_ptr<UtilLidMgr>
@@ -1005,7 +1029,7 @@ namespace HBPM
#if defined(__HOSTBOOT_RUNTIME) && defined(CONFIG_NVDIMM)
// Notify PHYP that NVDIMMs are not protected from power off event
- l_errl = NVDIMM::notifyNvdimmProtectionChange(i_target, NVDIMM::NOT_PROTECTED);
+ l_errl = NVDIMM::notifyNvdimmProtectionChange(i_target, NVDIMM::OCC_INACTIVE);
if (l_errl)
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
diff --git a/src/usr/isteps/pm/pm_common.H b/src/usr/isteps/pm/pm_common.H
index 6d167dbda..c8354e5d0 100644
--- a/src/usr/isteps/pm/pm_common.H
+++ b/src/usr/isteps/pm/pm_common.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -48,6 +48,10 @@ namespace HBPM
NOT_FIR_MASTER = 0x00000000,
IS_FIR_MASTER = 0x00000001,
+ // SMF Mode
+ SMF_MODE_DISABLED = 0x00000000,
+ SMF_MODE_ENABLED = 0x00000001,
+
// Mask off bit zero
PHYSICAL_ADDR_MASK = 0x7FFFFFFFFFFFFFFF,
VER_EYECATCH = 0x56455253494F4E00, //'VERSION\0'
diff --git a/src/usr/isteps/pm/runtime/rt_pm.C b/src/usr/isteps/pm/runtime/rt_pm.C
index 7ee9e0924..58930bc67 100644
--- a/src/usr/isteps/pm/runtime/rt_pm.C
+++ b/src/usr/isteps/pm/runtime/rt_pm.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,7 +37,6 @@
#include <runtime/interface.h> // g_hostInterfaces
#include <runtime/rt_fwreq_helper.H> // firmware_request_helper
-#include <runtime/rt_targeting.H>
#include <runtime/runtime_reasoncodes.H>
#include <initservice/isteps_trace.H>
@@ -46,6 +45,7 @@
#include <targeting/common/util.H>
#include <targeting/common/utilFilter.H>
#include <targeting/common/targetservice.H>
+#include <targeting/runtime/rt_targeting.H>
#include <scom/scomif.H>
#include <scom/wakeup.H>
@@ -400,9 +400,9 @@ namespace RTPM
}
// Get the Proc Chip Id
- RT_TARG::rtChipId_t l_chipId = 0;
+ TARGETING::rtChipId_t l_chipId = 0;
- l_err = RT_TARG::getRtTarget(l_pChipTarget, l_chipId);
+ l_err = TARGETING::getRtTarget(l_pChipTarget, l_chipId);
if(l_err)
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
diff --git a/src/usr/isteps/pm/runtime/test/firmwareRequestTest.H b/src/usr/isteps/pm/runtime/test/firmwareRequestTest.H
index bf1e28c06..3b6a1a7ac 100644
--- a/src/usr/isteps/pm/runtime/test/firmwareRequestTest.H
+++ b/src/usr/isteps/pm/runtime/test/firmwareRequestTest.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -23,31 +23,96 @@
/* */
/* IBM_PROLOG_END_TAG */
-#include <cxxtest/TestSuite.H>
-#include <runtime/interface.h>
-#include <runtime/hbrt_utilities.H>
-#include <errl/hberrltypes.H>
-#include <string.h>
+#include <cxxtest/TestSuite.H> // CxxTest::TestSuite
+#include <runtime/interface.h> // g_hostInterfaces, etc
+#include <runtime/hbrt_utilities.H> // createGenericFspMsg
+#include <vector>
-extern trace_desc_t* g_trac_pnor;
+extern trace_desc_t* g_trac_test;
class FirmwareRequestTest : public CxxTest::TestSuite
{
public:
+
+ /**
+ * @brief: testFirmwareRequestHcodeUpdate
+ * test the firmware_request's Send Attributes
+ */
+ void testFirmwareRequestSendAttributes (void)
+ {
+ TRACFCOMP(g_trac_test, ENTER_MRK
+ "FirmwareRequestTest::testFirmwareRequestSendAttributes" );
+
+ if (g_hostInterfaces == NULL ||
+ g_hostInterfaces->firmware_request == NULL)
+ {
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSendAttributes: "
+ "Hypervisor firmware_request interface not linked");
+ }
+ else
+ {
+ std::vector<TARGETING::AttributeTank::Attribute> l_attributeList;
+
+ uint32_t l_dataSize(0);
+
+ // Test 1: Create a default attribute and add to list
+ TARGETING::AttributeTank::Attribute l_attribute;
+ l_attributeList.push_back(l_attribute);
+ l_dataSize += l_attribute.getSize();
+ sendAttributes(l_attributeList);
+
+ // Test 2: Modify some of the Attributes data and add to list
+ l_attribute.setId(0x1001);
+ l_attribute.setTargetType(0x2002);
+ l_attribute.setPosition(0x3003);
+ l_attribute.setUnitPosition(0x4);
+ l_attribute.setNode(0x5);
+ l_attribute.setFlags(0x6);
+ l_attributeList.push_back(l_attribute);
+ l_dataSize += l_attribute.getSize();
+ sendAttributes(l_attributeList);
+
+ // Create a buffer to be used to update Value in the Attribute
+ uint32_t l_bufferSize(3);
+ uint8_t l_buffer[l_bufferSize];
+ l_buffer[0] = 0xAA;
+ l_buffer[1] = 0xBB;
+ l_buffer[2] = 0xCC;
+
+ // Test 3: Update the Attribute Values in the Attribute
+ // and add to list
+ l_attribute.setValue(l_buffer, 1);
+ l_attributeList.push_back(l_attribute);
+ l_dataSize += l_attribute.getSize();
+ sendAttributes(l_attributeList);
+
+ // Test 4: Update the Attribute Values in the Attribute
+ // and add to list
+ l_buffer[0] = 0xDD;
+ l_attribute.setValue(l_buffer, l_bufferSize);
+ l_attributeList.push_back(l_attribute);
+ l_dataSize += l_attribute.getSize();
+ sendAttributes(l_attributeList);
+ }
+
+ TRACFCOMP(g_trac_test, EXIT_MRK
+ "FirmwareRequestTest::testFirmwareRequestSendAttributes");
+ }
+
/**
* @brief: testFirmwareRequestHcodeUpdate
* test the firmware_request's HCODE update call
*/
void testFirmwareRequestHcodeUpdate (void)
{
- TRACFCOMP(g_trac_pnor, ENTER_MRK
+ TRACFCOMP(g_trac_test, ENTER_MRK
"FirmwareRequestTest::testFirmwareRequestHcodeUpdate");
if (g_hostInterfaces == NULL ||
g_hostInterfaces->firmware_request == NULL)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHcodeUpdate: "
- "Hypervisor firmware_request interface not linked");
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestHcodeUpdate: "
+ "Hypervisor firmware_request interface not linked");
}
else
{
@@ -62,14 +127,14 @@ class FirmwareRequestTest : public CxxTest::TestSuite
l_req_fw_msg.req_hcode_update.i_scomAddr = 0x400;
l_req_fw_msg.req_hcode_update.i_scomData = 0x500;
-
hostInterfaces::hbrt_fw_msg l_resp_fw_msg;
- size_t l_resp_fw_msg_size = sizeof(l_resp_fw_msg);
+ size_t l_resp_fw_msg_size = hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(l_resp_fw_msg);
size_t rc = g_hostInterfaces->firmware_request(
sizeof(l_req_fw_msg), &l_req_fw_msg,
&l_resp_fw_msg_size, &l_resp_fw_msg);
- TRACFCOMP(g_trac_pnor,
+ TRACDCOMP(g_trac_test,
"FirmwareRequestTest::testFirmwareRequestHcodeUpdate: "
"rc:%d, type:%d, resp:%d",
rc, l_resp_fw_msg.io_type,
@@ -97,9 +162,8 @@ class FirmwareRequestTest : public CxxTest::TestSuite
"received incorrect resp");
}
} // end else
- TRACFCOMP(g_trac_pnor, EXIT_MRK
+ TRACFCOMP(g_trac_test, EXIT_MRK
"FirmwareRequestTest::testFirmwareRequestHcodeUpdate");
-
} // end testFirmwareRequestHcodeUpdate
/**
@@ -108,7 +172,7 @@ class FirmwareRequestTest : public CxxTest::TestSuite
*/
void testFirmwareRequestErrLogToFsp (void)
{
- TRACFCOMP(g_trac_pnor, ENTER_MRK
+ TRACFCOMP(g_trac_test, ENTER_MRK
"FirmwareRequestTest::testFirmwareRequestErrLogToFsp");
if (g_hostInterfaces == NULL ||
@@ -128,12 +192,13 @@ class FirmwareRequestTest : public CxxTest::TestSuite
l_req_fw_msg.error_log.i_data = 0xAA;
hostInterfaces::hbrt_fw_msg l_resp_fw_msg;
- size_t l_resp_fw_msg_size = sizeof(l_resp_fw_msg);
+ size_t l_resp_fw_msg_size = hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(l_resp_fw_msg);
size_t rc = g_hostInterfaces->firmware_request(
sizeof(l_req_fw_msg), &l_req_fw_msg,
&l_resp_fw_msg_size, &l_resp_fw_msg);
- TRACFCOMP(g_trac_pnor,
+ TRACDCOMP(g_trac_test,
"FirmwareRequestTest::testFirmwareRequestErrLogToFsp: "
"rc:%d, type:%d, resp:%d",
rc, l_resp_fw_msg.io_type,
@@ -161,29 +226,29 @@ class FirmwareRequestTest : public CxxTest::TestSuite
"received incorrect resp");
}
} // end else
- TRACFCOMP(g_trac_pnor, EXIT_MRK
+ TRACFCOMP(g_trac_test, EXIT_MRK
"FirmwareRequestTest::testFirmwareRequestErrLogToFsp");
} // end testFirmwareRequestErrLogToFsp
/**
- * @brief: testFirmwareRequestHbrtToFsp
- * test the firmware_request's HBRT to FSP call
+ * @brief: testFirmwareRequestSbeRetry
+ * test the firmware_request's SBE retry
*/
- void testFirmwareRequestHbrtToFsp (void)
+ void testFirmwareRequestSbeRetry (void)
{
- TRACFCOMP(g_trac_pnor, ENTER_MRK
- "FirmwareRequestTest::testFirmwareRequestHbrtToFsp");
+ TRACFCOMP(g_trac_test, ENTER_MRK
+ "FirmwareRequestTest::testFirmwareRequestSbeRetry");
if (g_hostInterfaces == NULL ||
g_hostInterfaces->firmware_request == NULL)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"Hypervisor firmware_request interface not linked");
}
else
{
- // Test HBRT to FSP
+ // Test Request SBE Retry
// Handles to the firmware messages
hostInterfaces::hbrt_fw_msg *l_req_fw_msg = nullptr;
@@ -204,7 +269,7 @@ class FirmwareRequestTest : public CxxTest::TestSuite
// Populate the firmware_request request struct with given data
l_req_fw_msg->generic_msg.msgq = 0x300;
l_req_fw_msg->generic_msg.msgType =
- GenericFspMboxMessage_t::MSG_DECONFIG_TARGET;
+ GenericFspMboxMessage_t::MSG_SBE_ERROR;
// Create a useful struct to populate the generic_msg::data field
// Setting the PLID and userData
@@ -217,26 +282,26 @@ class FirmwareRequestTest : public CxxTest::TestSuite
if (l_req_fw_msg->generic_msg.magic !=
GenericFspMboxMessage_t::MAGIC_NUMBER)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"magic was not properly initialized");
}
if (l_req_fw_msg->generic_msg.dataSize != l_fsp_data_size)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"dataSize was not properly initialized");
}
if (l_req_fw_msg->generic_msg.structVer !=
GenericFspMboxMessage_t::STRUCT_VERSION_LATEST)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"structVer was not properly initialized");
}
if (l_req_fw_msg->generic_msg.seqnum != SeqId_t::getCurrentSeqId())
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"seqnum was not properly initialized");
}
@@ -245,23 +310,27 @@ class FirmwareRequestTest : public CxxTest::TestSuite
l_req_fw_msg->generic_msg.dataSize = l_fsp_data_size;
l_req_fw_msg->generic_msg.structVer = 0x20;
l_req_fw_msg->generic_msg.seqnum = 0x300;
- l_req_fw_msg->generic_msg.msgq = 0x400;
- l_req_fw_msg->generic_msg.msgType = 0x500;
l_req_fw_msg->generic_msg.__req = GenericFspMboxMessage_t::REQUEST;
l_req_fw_msg->generic_msg.__onlyError =
GenericFspMboxMessage_t::ERROR_ONLY;
- TRACFCOMP(g_trac_pnor,
- "FirmwareRequestTest::testFirmwareRequestHbrtToFsp req: "
- "type:%d, magic:0x%.8X, dataSize:%d, structVer:0x%.8X, "
- "seqnum:%.8X, msgq:0x%.8X, msgType:0x%.8X, __req:%d, "
- "__onlyError:%d, data:0x%.8X, plid:0x%.8X, huid:0x%.8X",
+ TRACDCOMP(g_trac_test,
+ "FirmwareRequestTest::testFirmwareRequestSbeRetry "
+ "Request data set 1/2: "
+ "type:%d, magic:0x%.8X, dataSize:%d, "
+ "structVer:0x%.8X,seqnum:%.8X, msgq:0x%.8X",
l_req_fw_msg->io_type,
l_req_fw_msg->generic_msg.magic,
l_req_fw_msg->generic_msg.dataSize,
l_req_fw_msg->generic_msg.structVer,
l_req_fw_msg->generic_msg.seqnum,
- l_req_fw_msg->generic_msg.msgq,
+ l_req_fw_msg->generic_msg.msgq);
+
+ TRACDCOMP(g_trac_test,
+ "FirmwareRequestTest::testFirmwareRequestSbeRetry "
+ "Request data set 2/2: "
+ "msgType:0x%.8X, __req:%d, __onlyError:%d, "
+ "data:0x%.8X, plid:0x%.8X, huid:0x%.8X",
l_req_fw_msg->generic_msg.msgType,
l_req_fw_msg->generic_msg.__req,
l_req_fw_msg->generic_msg.__onlyError,
@@ -269,23 +338,29 @@ class FirmwareRequestTest : public CxxTest::TestSuite
l_req_fw_msg->generic_msg.data >> 32,
0x0000FFFF & l_req_fw_msg->generic_msg.data);
+
size_t rc = g_hostInterfaces->firmware_request(l_req_fw_msg_size,
l_req_fw_msg,
&l_resp_fw_msg_size,
l_resp_fw_msg);
- TRACFCOMP(g_trac_pnor,
- "FirmwareRequestTest::testFirmwareRequestHbrtToFsp resp: "
- "type:%d, magic:0x%.8X, dataSize:%d, structVer:0x%.8X, "
- "seqnum:%.8X, msgq:0x%.8X, msgType:0x%.8X, __req:%d, "
- "__onlyError:%d, data:0x%.8X, plid:0x%.8X, huid:0x%.8X, "
- "rc=%d",
+ TRACDCOMP(g_trac_test,
+ "FirmwareRequestTest::testFirmwareRequestSbeRetry "
+ "Response data set 1/2: "
+ "type:%d, magic:0x%.8X, dataSize:%d, "
+ "structVer:0x%.8X, seqnum:%.8X, msgq:0x%.8X",
l_resp_fw_msg->io_type,
l_resp_fw_msg->generic_msg.magic,
l_resp_fw_msg->generic_msg.dataSize,
l_resp_fw_msg->generic_msg.structVer,
l_resp_fw_msg->generic_msg.seqnum,
- l_resp_fw_msg->generic_msg.msgq,
+ l_resp_fw_msg->generic_msg.msgq);
+
+ TRACDCOMP(g_trac_test,
+ "FirmwareRequestTest::testFirmwareRequestSbeRetry "
+ "Response data set 2/2: "
+ "msgType:0x%.8X, __req:%d, __onlyError:%d, "
+ "data:0x%.8X, plid:0x%.8X, huid:0x%.8X, rc=%d",
l_resp_fw_msg->generic_msg.msgType,
l_resp_fw_msg->generic_msg.__req,
l_resp_fw_msg->generic_msg.__onlyError,
@@ -294,9 +369,10 @@ class FirmwareRequestTest : public CxxTest::TestSuite
0x0000FFFF & l_resp_fw_msg->generic_msg.data,
rc);
+
if (rc != 5)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"firmware_request - HBRT to FSP failed - "
"returned wrong value");
}
@@ -304,7 +380,7 @@ class FirmwareRequestTest : public CxxTest::TestSuite
if (l_resp_fw_msg->io_type !=
hostInterfaces::HBRT_FW_MSG_HBRT_FSP_RESP)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"firmware_request - HBRT to FSP failed - "
"received incorrect msg_type");
}
@@ -312,56 +388,56 @@ class FirmwareRequestTest : public CxxTest::TestSuite
if (l_resp_fw_msg->generic_msg.magic !=
GenericFspMboxMessage_t::MAGIC_NUMBER)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"firmware_request - HBRT to FSP failed - "
"received incorrect magic");
}
if (l_resp_fw_msg->generic_msg.dataSize != 32)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"firmware_request - HBRT to FSP failed - "
"received incorrect datSize");
}
if (l_resp_fw_msg->generic_msg.structVer != 0x020)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"firmware_request - HBRT to FSP failed - "
"received incorrect structVer");
}
if (l_resp_fw_msg->generic_msg.seqnum != 0x301)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"firmware_request - HBRT to FSP failed - "
"received incorrect seqnum");
}
- if (l_resp_fw_msg->generic_msg.msgq != 0x400)
+ if (l_resp_fw_msg->generic_msg.msgq != 0x300)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"firmware_request - HBRT to FSP failed - "
"received incorrect msgq");
}
-
- if (l_resp_fw_msg->generic_msg.msgType != 0x500)
+ if (l_resp_fw_msg->generic_msg.msgType !=
+ GenericFspMboxMessage_t::MSG_SBE_ERROR)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"firmware_request - HBRT to FSP failed - "
"received incorrect msgType");
}
if (l_resp_fw_msg->generic_msg.data >> 32 != 0x60)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"firmware_request - HBRT to FSP failed - "
"received incorrect errPlid");
}
if ((0x0000FFFF & l_resp_fw_msg->generic_msg.data) != 0x70)
{
- TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
+ TS_FAIL("FirmwareRequestTest::testFirmwareRequestSbeRetry: "
"firmware_request - HBRT to FSP failed - "
"received incorrect huid");
}
@@ -370,8 +446,8 @@ class FirmwareRequestTest : public CxxTest::TestSuite
delete[] l_resp_fw_msg;
l_req_fw_msg = l_resp_fw_msg = nullptr;
}
- TRACFCOMP(g_trac_pnor, EXIT_MRK
- "FirmwareRequestTest::testFirmwareRequestHbrtToFsp");
+ TRACFCOMP(g_trac_test, EXIT_MRK
+ "FirmwareRequestTest::testFirmwareRequestSbeRetry");
- } // end testFirmwareRequestHbrtToFsp
+ } // end testFirmwareRequestSbeRetry
}; // end class FirmwareRequestTest
diff --git a/src/usr/isteps/pm/runtime/test/pmtestRt.H b/src/usr/isteps/pm/runtime/test/pmtestRt.H
index 1c29f7ab8..235cb8cec 100644
--- a/src/usr/isteps/pm/runtime/test/pmtestRt.H
+++ b/src/usr/isteps/pm/runtime/test/pmtestRt.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,7 +33,7 @@
#include <cxxtest/TestSuite.H>
#include <runtime/interface.h>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <targeting/common/utilFilter.H>
#include <errl/errlmanager.H>
#include <devicefw/userif.H>
diff --git a/src/usr/isteps/tod/runtime/rt_todintf.C b/src/usr/isteps/tod/runtime/rt_todintf.C
index 180049d18..e5c537cd3 100644
--- a/src/usr/isteps/tod/runtime/rt_todintf.C
+++ b/src/usr/isteps/tod/runtime/rt_todintf.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2017 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -31,7 +31,7 @@
#include <runtime/interface.h> // g_hostInterfaces
#include <util/runtime/rt_fwreq_helper.H> // firmware_request_helper
#include <tod_init_reasoncodes.H> // TOD_RT_TOPOLOGY_RESET_BACKUP, etc
-#include <errlmanager_common.C> // errlCommit
+#include <errl/errlentry.H>
using namespace ERRORLOG;
diff --git a/src/usr/isteps/ucd/updateUcdFlash.C b/src/usr/isteps/ucd/updateUcdFlash.C
index 5a261c57f..2a8b117bf 100644
--- a/src/usr/isteps/ucd/updateUcdFlash.C
+++ b/src/usr/isteps/ucd/updateUcdFlash.C
@@ -23,7 +23,6 @@
/* */
/* IBM_PROLOG_END_TAG */
-#include <config.h>
#include <isteps/ucd/updateUcdFlash.H>
#include <ucd/ucd_reasoncodes.H>
#include <devicefw/driverif.H>
diff --git a/src/usr/lpc/lpcdd.C b/src/usr/lpc/lpcdd.C
index c5691d7b9..48fd7a1b8 100644
--- a/src/usr/lpc/lpcdd.C
+++ b/src/usr/lpc/lpcdd.C
@@ -48,7 +48,6 @@
#include <kernel/bltohbdatamgr.H>
#include <errl/errludlogregister.H>
#include <initservice/taskargs.H>
-#include <config.h>
#include <arch/memorymap.H>
#include <util/misc.H>
#include <errl/errlreasoncodes.H>
diff --git a/src/usr/makefile b/src/usr/makefile
index 5f4e94cf3..4566d6941 100644
--- a/src/usr/makefile
+++ b/src/usr/makefile
@@ -38,6 +38,7 @@ SUBDIRS += errl.d
SUBDIRS += errldisplay.d
SUBDIRS += expaccess.d
SUBDIRS += fapi2.d
+SUBDIRS += fapiwrap.d
SUBDIRS += fsi.d
SUBDIRS += fsiscom.d
SUBDIRS += gpio.d
diff --git a/src/usr/mbox/mailboxsp.C b/src/usr/mbox/mailboxsp.C
index 7ce3b9e25..a25922f56 100644
--- a/src/usr/mbox/mailboxsp.C
+++ b/src/usr/mbox/mailboxsp.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -31,7 +31,6 @@
#include "mailboxsp.H"
#include "mboxdd.H"
#include "ipcSp.H"
-#include <config.h>
#include <sys/task.h>
#include <initservice/taskargs.H>
#include <initservice/initserviceif.H>
diff --git a/src/usr/mmio/makefile b/src/usr/mmio/makefile
index cea686f85..2cc5fd76a 100644
--- a/src/usr/mmio/makefile
+++ b/src/usr/mmio/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2018
+# Contributors Listed Below - COPYRIGHT 2013,2019
# [+] International Business Machines Corp.
#
#
@@ -25,12 +25,22 @@
ROOTPATH = ../../..
MODULE = mmio
+SUBDIRS += test.d
+SUBDIRS += runtime.d
+
EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/include/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/
+EXTRAINCDIR += ${ROOTPATH}/src/import/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/procedures/hwp/memory/
EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include/
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2/
#include unique object modules
OBJS += mmio.o
+OBJS += mmio_explorer.o
VPATH += ..
include $(ROOTPATH)/config.mk
diff --git a/src/usr/mmio/mmio.C b/src/usr/mmio/mmio.C
index 1b84660f8..ff7eec661 100644
--- a/src/usr/mmio/mmio.C
+++ b/src/usr/mmio/mmio.C
@@ -27,6 +27,7 @@
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <errl/errludtarget.H>
+#include <errl/errludlogregister.H>
#include <targeting/common/predicates/predicates.H>
#include <targeting/common/utilFilter.H>
#include <targeting/common/targetservice.H>
@@ -41,30 +42,48 @@
#include <p9a_mc_scom_addresses_fld.H>
#include <error_info_defs.H>
+#include "mmio_explorer.H"
+#include <utils/chipids.H>
+
// Trace definition
trace_desc_t* g_trac_mmio = NULL;
TRAC_INIT(&g_trac_mmio, MMIO_COMP_NAME, 2*KILOBYTE, TRACE::BUFFER_SLOW);
#define OMI_PER_MC 8
+using namespace TARGETING;
+
namespace MMIO
{
+// TODO RTC 201493 - Remove these consts once HW group has defined them.
+static const uint8_t P9A_MC_DSTLFIR_SUBCHANNEL_A_FAIL_ACTION = 20;
+static const uint8_t P9A_MC_DSTLFIR_SUBCHANNEL_B_FAIL_ACTION = 21;
+
// Helper function declarations (definitions at the bottom of this file)
static
-TARGETING::TargetHandle_t getParentProc(TARGETING::TargetHandle_t i_target);
+TargetHandle_t getParentProc(TargetHandle_t i_ocmbTarget);
static
-errlHndl_t getProcScom(TARGETING::TargetHandle_t i_target,
+errlHndl_t getProcScom(TargetHandle_t i_ocmbTarget,
uint64_t i_scomAddr,
uint64_t &o_scomData);
-static
-errlHndl_t setProcScom(TARGETING::TargetHandle_t i_target,
+
+// NOTE: removed static qualifier to prevent compiler from complaining about
+// the function not being used.
+errlHndl_t setProcScom(TargetHandle_t i_ocmbTarget,
uint64_t i_scomAddr,
uint64_t i_scomData);
static
void *mmio_memcpy(void *vdest, const void *vsrc, size_t len);
+/*******************************************************************************
+ *
+ * @brief Setup the MMIO BAR registers for all OCMB chips in the system
+ *
+ * @return nullptr on success, failure otherwise.
+ *
+ */
errlHndl_t mmioSetup()
{
errlHndl_t l_err = nullptr;
@@ -77,39 +96,50 @@ errlHndl_t mmioSetup()
//
// loop through all the Memory Channels (MC Targets)
// call allocate of 32 GB virtual memory space with mmio_dev_map() for each MC
- TARGETING::TargetHandleList l_mcTargetList;
- getAllChiplets(l_mcTargetList, TARGETING::TYPE_MC);
+ TargetHandleList l_mcTargetList;
+ getAllChiplets(l_mcTargetList, TYPE_MC);
for (auto & l_mcTarget: l_mcTargetList)
{
uint32_t l_mcChipUnit =
- l_mcTarget->getAttr<TARGETING::ATTR_CHIP_UNIT>();
+ l_mcTarget->getAttr<ATTR_CHIP_UNIT>();
- // Get the base BAR address for OpenCapi Memory Interfaces (OMIs) of the this Memory Channel (MC)
+ // Get the base BAR address for OpenCapi Memory Interfaces (OMIs) of this Memory Controller (MC)
auto l_omiBaseAddr =
- l_mcTarget->getAttr<TARGETING::ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET>();
-
- // Apply the MMIO base offset so we get the real address
- uint64_t l_realAddr = ( l_omiBaseAddr | MMIO_BASE );
-
- // Map the device with a kernal call, each device, the MC, is 32 GB
+ l_mcTarget->getAttr<ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET>();
+
+ // Build up the full address with group/chip address considerations
+ auto l_procType = TARGETING::TYPE_PROC;
+ TARGETING::Target* l_parentChip = getParent(l_mcTarget, l_procType);
+ uint8_t l_groupId =
+ l_parentChip->getAttr<ATTR_PROC_EFF_FABRIC_GROUP_ID>();
+ uint8_t l_chipId =
+ l_parentChip->getAttr<ATTR_PROC_EFF_FABRIC_CHIP_ID>();
+ uint64_t l_realAddr = computeMemoryMapOffset( MMIO_BASE,
+ l_groupId,
+ l_chipId );
+
+ // Apply the MMIO base offset so we get the final address
+ l_realAddr += l_omiBaseAddr;
+
+ // Map the device with a kernel call, each device, the MC, is 32 GB
uint64_t l_virtAddr = reinterpret_cast<uint64_t>
(mmio_dev_map(reinterpret_cast<void *>(l_realAddr),
THIRTYTWO_GB));
- TRACFCOMP ( g_trac_mmio, "MC%.02x (0x%.08X) MMIO BAR PHYSICAL ADDR = 0x%lx VIRTUAL ADDR = 0x%lx" ,
- l_mcChipUnit ? 0x23 : 0x01, TARGETING::get_huid(l_mcTarget),
+ TRACFCOMP ( g_trac_mmio, "MC%.02X (0x%.08X) MMIO BAR PHYSICAL ADDR = 0x%lX VIRTUAL ADDR = 0x%lX" ,
+ l_mcChipUnit ? 0x23 : 0x01, get_huid(l_mcTarget),
l_realAddr, l_virtAddr);
// set VM_ADDR on each OCMB
- TARGETING::TargetHandleList l_omiTargetList;
- getChildChiplets(l_omiTargetList, l_mcTarget, TARGETING::TYPE_OMI);
+ TargetHandleList l_omiTargetList;
+ getChildChiplets(l_omiTargetList, l_mcTarget, TYPE_OMI);
for (auto & l_omiTarget: l_omiTargetList)
{
// ATTR_CHIP_UNIT is relative to other OMI under this PROC
uint32_t l_omiChipUnit =
- l_omiTarget->getAttr<TARGETING::ATTR_CHIP_UNIT>();
+ l_omiTarget->getAttr<ATTR_CHIP_UNIT>();
// Get the OMI position relative to other OMIs under its parent MC chiplet
uint32_t l_omiPosRelativeToMc = l_omiChipUnit % OMI_PER_MC;
@@ -123,10 +153,10 @@ errlHndl_t mmioSetup()
// paired OCMB spaces get interleaved as follows :
// ocmb | BAR ATTRIBUTE | Type | Base reg - end addr | size | sub-ch
// +-----+--------------------+------+-----------------------------------------+------+-------
- // ocmb0 | 0x0006030200000000 | cnfg | 0x0006030200000000 - 0x000603027FFFFFFF | 2GB | 0
- // ocmb1 | 0x0006030280000000 | cnfg | 0x0006030280000000 - 0x00060302FFFFFFFF | 2GB | 1
- // ocmb0 | N/A | mmio | 0x0006030300000000 - 0x000603037FFFFFFF | 2GB | 0
- // ocmb1 | N/A | mmio | 0x0006030380000000 - 0x00060303FFFFFFFF | 2GB | 1
+ // ocmb0 | 0xYYYYYYY000000000 | cnfg | 0xYYYYYYY000000000 - 0xYYYYYYY07FFFFFFF | 2GB | 0
+ // ocmb1 | 0xYYYYYYY080000000 | cnfg | 0xYYYYYYY080000000 - 0xYYYYYYY0FFFFFFFF | 2GB | 1
+ // ocmb0 | N/A | mmio | 0xYYYYYYY100000000 - 0xYYYYYYY17FFFFFFF | 2GB | 0
+ // ocmb1 | N/A | mmio | 0xYYYYYYY180000000 - 0xYYYYYYY1FFFFFFFF | 2GB | 1
// +-----+--------------------+------+-----------------------------------------+------+-------
// Calculate CNFG space BAR to write to OCMB attribute
@@ -136,14 +166,16 @@ errlHndl_t mmioSetup()
// Calculated real address for this OMI is (BAR from MC attribute) + (currentOmiOffset)
uint64_t l_calulatedRealAddr = l_omiBaseAddr + l_currentOmiOffset;
- // Grab bar value from attribute to verify it matches our calculations
- auto l_omiBarAttrVal = l_omiTarget->getAttr<TARGETING::ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET>();
+ // Grab bar value from attribute to verify it matches
+ // our calculations
+ auto l_omiBarAttrVal = l_omiTarget->
+ getAttr<ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET>();
if(l_omiBarAttrVal != l_calulatedRealAddr)
{
TRACFCOMP(g_trac_mmio,
"Discrepancy found between calculated OMI MMIO bar offset and what we found in ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET");
- TRACFCOMP(g_trac_mmio, "Calculated Offset: 0x%lx, Attribute Value : 0x%lx", l_calulatedRealAddr, l_omiBarAttrVal);
+ TRACFCOMP(g_trac_mmio, "Calculated Offset: 0x%lX, Attribute Value : 0x%lX", l_calulatedRealAddr, l_omiBarAttrVal);
/*@
* @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE
@@ -151,7 +183,7 @@ errlHndl_t mmioSetup()
* @reasoncode MMIO::RC_BAR_OFFSET_MISMATCH
* @userdata1 Calculated Bar Offset
* @userdata2 Bar offset from attribute
- * @devdesc mmioSetup> Mismatch between calculated map value
+ * @devdesc Mismatch between calculated map value
* and what is in attribute xml
* @custdesc Unexpected memory subsystem firmware error.
*/
@@ -172,16 +204,21 @@ errlHndl_t mmioSetup()
uint64_t l_currentOmiVirtAddr = l_virtAddr + l_currentOmiOffset;
// set VM_ADDR the associated OCMB
- TARGETING::TargetHandleList l_ocmbTargetList;
+ TargetHandleList l_ocmbTargetList;
getChildAffinityTargets(l_ocmbTargetList, l_omiTarget,
- TARGETING::CLASS_CHIP, TARGETING::TYPE_OCMB_CHIP);
+ CLASS_CHIP, TYPE_OCMB_CHIP);
assert(l_ocmbTargetList.size() == 1 , "OCMB chips list found for a given OMI != 1 as expected");
- TRACFCOMP(g_trac_mmio, "Setting HUID 0x%.08X MMIO vm addr to be 0x%lx , real address is 0x%lx", TARGETING::get_huid(l_ocmbTargetList[0]),
- l_currentOmiVirtAddr, l_calulatedRealAddr | MMIO_BASE );
+ TRACFCOMP(g_trac_mmio,
+ "Setting HUID 0x%.08X MMIO vm addr to be 0x%lX, real"
+ " address is 0x%lX",
+ get_huid(l_ocmbTargetList[0]),
+ l_currentOmiVirtAddr,
+ l_calulatedRealAddr | MMIO_BASE );
- l_ocmbTargetList[0]->setAttr<TARGETING::ATTR_MMIO_VM_ADDR>(l_currentOmiVirtAddr);
+ l_ocmbTargetList[0]->
+ setAttr<ATTR_MMIO_VM_ADDR>(l_currentOmiVirtAddr);
}
}
} while(0);
@@ -194,42 +231,372 @@ errlHndl_t mmioSetup()
// Direct OCMB reads and writes to the device's memory mapped memory.
DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
DeviceFW::MMIO,
- TARGETING::TYPE_OCMB_CHIP,
+ TYPE_OCMB_CHIP,
ocmbMmioPerformOp);
-errlHndl_t ocmbMmioPerformOp(DeviceFW::OperationType i_opType,
- TARGETING::TargetHandle_t i_target,
- void* io_buffer,
- size_t& io_buflen,
- int64_t i_accessType,
- va_list i_args)
+/*******************************************************************************
+ *
+ * @brief Switch to using I2C instead of MMIO SCOMs for an OCMB
+ *
+ * @param[in] i_ocmbTarget Which OCMB to switch to using I2C
+ *
+ */
+void disableInbandScomsOcmb(const TargetHandle_t i_ocmbTarget)
{
- errlHndl_t l_err = nullptr;
- uint64_t l_offset = va_arg(i_args, uint64_t);
- uint64_t l_accessLimit = va_arg(i_args, uint64_t);
+ mutex_t* l_mutex = NULL;
- TRACDCOMP(g_trac_mmio, ENTER_MRK"ocmbMmioPerformOp");
- TRACDCOMP(g_trac_mmio, INFO_MRK"op=%d, target=0x%.8X",
- i_opType, TARGETING::get_huid(i_target));
- TRACDCOMP(g_trac_mmio, INFO_MRK"buffer=%p, length=%d, accessType=%ld",
- io_buffer, io_buflen, i_accessType);
- TRACDCOMP(g_trac_mmio, INFO_MRK"offset=0x%lX, accessLimit=%ld",
- l_offset, l_accessLimit);
+ TRACFCOMP(g_trac_mmio,
+ "disableInbandScomsOcmb: switching to use I2C on OCMB 0x%08x",
+ get_huid(i_ocmbTarget));
- do
+ //don't mess with attributes without the mutex (just to be safe)
+ l_mutex = i_ocmbTarget->getHbMutexAttr<ATTR_IBSCOM_MUTEX>();
+ mutex_lock(l_mutex);
+
+ ScomSwitches l_switches = i_ocmbTarget->getAttr<ATTR_SCOM_SWITCHES>();
+ l_switches.useInbandScom = 0;
+ l_switches.useI2cScom = 1;
+
+ // Modify attribute
+ i_ocmbTarget->setAttr<ATTR_SCOM_SWITCHES>(l_switches);
+ mutex_unlock(l_mutex);
+}
+
+/*******************************************************************************
+ *
+ * @brief Determine if we are on sub-channel A (OMI-0) or not.
+ *
+ * @param[in] Which OCMB target to query
+ *
+ * @return True if the OCMB target is on sub-channel A (OMI-0). False
+ * Otherwise.
+ *
+ */
+bool isSubChannelA(const TargetHandle_t i_ocmbTarget)
+{
+ const auto l_parentOMI = getImmediateParentByAffinity(i_ocmbTarget);
+ return (l_parentOMI->getAttr<ATTR_REL_POS>() == 0);
+}
+
+/*******************************************************************************
+ *
+ * @brief Adds default callouts to error log for when further isolation
+ * cannot be performed.
+ *
+ * @param[in] Error log to add callouts to.
+ * @param[in] OCMB target to callout
+ *
+ */
+void addDefaultCallouts(errlHndl_t i_err,
+ const TargetHandle_t i_ocmbTarget)
+{
+ // Add OCMB as high priority
+ i_err->addHwCallout(i_ocmbTarget,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Add OMI bus
+ i_err->addHwCallout(getImmediateParentByAffinity(i_ocmbTarget),
+ HWAS::SRCI_PRIORITY_MED,
+ HWAS::DECONFIG,
+ HWAS::GARD_NULL);
+
+ // Add code as low priority callout
+ i_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_LOW);
+}
+
+/*******************************************************************************
+ *
+ * @brief Determine if the OCMB detected a failure on a specific MMIO
+ * transaction to the specified OCMB target.
+ *
+ * @param[in] i_ocmbTarget Handle for the target OCMB chip.
+ * @param[in] i_va Virtual address of the transaction to check
+ * @param[in] i_accessLimit The byte range of the transaction
+ * @param[in] i_offset The offset from the base address of the OCMB chip
+ * @param[in] i_opType The operation type (read or write)
+ * @param[out] o_errorAddressMatches Set to true if the OCMB chip detected a
+ * failure on our transaction.
+ * @param[out] o_errorAddressIsZero Set to true if no error has been detected
+ * yet.
+ * @return nullptr on succesful read of OCMB error status, non-null otherwise.
+ *
+ */
+errlHndl_t checkOcmbError(const TargetHandle_t i_ocmbTarget,
+ const uint64_t i_va,
+ const uint64_t i_accessLimit,
+ const uint64_t i_offset,
+ DeviceFW::OperationType i_opType,
+ bool& o_errorAddressMatches,
+ bool& o_errorAddressIsZero)
+{
+ errlHndl_t l_err = nullptr;
+ const auto l_ocmbChipId = i_ocmbTarget->getAttr<TARGETING::ATTR_CHIP_ID>();
+ switch(l_ocmbChipId)
{
- uint64_t l_addr = i_target->getAttr<TARGETING::ATTR_MMIO_VM_ADDR>();
+ case POWER_CHIPID::EXPLORER_16:
+ case POWER_CHIPID::GEMINI_16:
+ l_err = MMIOEXP::checkExpError(i_ocmbTarget,
+ i_va,
+ i_accessLimit,
+ i_offset,
+ i_opType,
+ o_errorAddressMatches,
+ o_errorAddressIsZero);
+ break;
- TRACDCOMP(g_trac_mmio, INFO_MRK"MMIO Op l_addr=0x%lX ", l_addr);
+ default:
+ // Should never get here, but just in case...
+ TRACFCOMP(g_trac_mmio, ERR_MRK
+ "checkOcmbError: Unsupported chip ID[0x%08x] on OCMB[0x%08x]",
+ l_ocmbChipId, get_huid(i_ocmbTarget));
+ /*@
+ * @errortype
+ * @moduleid MMIO::MOD_CHECK_OCMB_ERROR
+ * @reasoncode MMIO::RC_UNSUPPORTED_CHIPID
+ * @userdata1 OCMB HUID
+ * @userdata2 OCMB chip ID
+ * @devdesc A MMIO operation was attempted
+ * on an unsupported OCMB chip.
+ * @custdesc Unexpected memory subsystem firmware error.
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MMIO::MOD_CHECK_OCMB_ERROR,
+ MMIO::RC_UNSUPPORTED_CHIPID,
+ get_huid(i_ocmbTarget),
+ l_ocmbChipId,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+ return l_err;
+}
+
+/*******************************************************************************
+ *
+ * @brief Collect additional failure data from the target OCMB chip and add
+ * appropriate FRU/Procedure callouts.
+ *
+ * @note Must call checkOcmbError to determine that a transaction failed before
+ * calling this function.
+ *
+ * @param[in] i_ocmbTarget Handle of OCMB to collect extra FFDC from
+ * @param[in] i_offset The offset of the transaction address
+ * on the OCMB chip.
+ * @param[in] i_opType The operation type (read or write)
+ * @param[in] i_err The error log for adding callouts/FFDC
+ *
+ */
+void determineCallouts(const TargetHandle_t i_ocmbTarget,
+ const uint64_t i_offset,
+ DeviceFW::OperationType i_opType,
+ errlHndl_t i_err)
+{
+ bool l_fwFailure = false;
+ errlHndl_t l_err = nullptr;
+
+ const auto l_ocmbChipId = i_ocmbTarget->getAttr<TARGETING::ATTR_CHIP_ID>();
+ switch(l_ocmbChipId)
+ {
+ case POWER_CHIPID::EXPLORER_16:
+ case POWER_CHIPID::GEMINI_16:
+ l_err = MMIOEXP::determineExpCallouts(i_ocmbTarget,
+ i_offset,
+ i_opType,
+ i_err,
+ l_fwFailure);
+ break;
+ default:
+ // Should never get here, but just in case...
+ TRACFCOMP(g_trac_mmio, ERR_MRK
+ "determineCallouts: Unsupported chip ID[0x%08x] on OCMB[0x%08x]",
+ l_ocmbChipId, get_huid(i_ocmbTarget));
+ /*@
+ * @errortype
+ * @moduleid MMIO::MOD_DETERMINE_CALLOUTS
+ * @reasoncode MMIO::RC_UNSUPPORTED_CHIPID
+ * @userdata1 OCMB HUID
+ * @userdata2 OCMB chip ID
+ * @devdesc A MMIO operation was attempted
+ * on an unsupported OCMB chip.
+ * @custdesc Unexpected memory subsystem firmware error.
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MMIO::MOD_DETERMINE_CALLOUTS,
+ MMIO::RC_UNSUPPORTED_CHIPID,
+ get_huid(i_ocmbTarget),
+ l_ocmbChipId,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_mmio,
+ "determineCallouts: Couldn't isolate failure on"
+ " OCMB[0x%08x]",
+ get_huid(i_ocmbTarget));
+
+ // This error is secondary to the actual error. Log as informational
+ // and add default callouts
+ l_err->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ l_err->plid(i_err->plid());
+ ERRORLOG::errlCommit(l_err, MMIO_COMP_ID);
+ addDefaultCallouts(i_err, i_ocmbTarget);
+ }
+ else
+ {
+ if(l_fwFailure)
+ {
+ TRACFCOMP(g_trac_mmio,
+ "determineCallouts: firmware error detected on"
+ " OCMB[0x%08x]",
+ get_huid(i_ocmbTarget));
+
+ // Add HB code as high priority callout
+ i_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_mmio,
+ "determineCallouts: hardware error detected on"
+ " OCMB[0x%08x]",
+ get_huid(i_ocmbTarget));
+
+ // Add OCMB as high priority callout
+ i_err->addHwCallout(i_ocmbTarget,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DECONFIG,
+ HWAS::GARD_NULL);
+ }
+ }
+}
- if (l_addr == 0)
+/*******************************************************************************
+ *
+ * @brief Checks for a channel failure
+ *
+ * @param[in] i_ocmbTarget The OCMB to check for a channel failure
+ * @param[out] o_checkstopExists true if channel failed, false otherwise.
+ *
+ * @return nullptr if we were able to read the status. Non-nullptr if there
+ * was a SCOM failure in reading status.
+ */
+errlHndl_t checkChannelCheckstop(const TargetHandle_t i_ocmbTarget,
+ bool& o_checkstopExists)
+{
+ bool l_checkstopExists = false;
+ uint64_t l_scom_data = 0;
+ uint64_t l_scom_mask = 0;
+
+ auto l_err = getProcScom(i_ocmbTarget,
+ P9A_MCC_DSTLFIR,
+ l_scom_data);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_mmio, ERR_MRK
+ "checkChannelCheckstop: getscom(P9A_MCC_DSTLFIR) failed"
+ " on OCMB[0x%08x]", get_huid(i_ocmbTarget));
+ }
+ else
+ {
+ // Check for channel checkstop on our sub-channel
+ l_scom_mask = (isSubChannelA(i_ocmbTarget))?
+ (1ull << P9A_MC_DSTLFIR_SUBCHANNEL_A_FAIL_ACTION):
+ (1ull << P9A_MC_DSTLFIR_SUBCHANNEL_B_FAIL_ACTION);
+ if (l_scom_data & l_scom_mask)
{
+ // A channel checkstop has occurred. (our bus is down)
TRACFCOMP(g_trac_mmio, ERR_MRK
- "ocmbMmioPerformOp: MMIO has not been initialized!");
+ "checkChannelCheckstop: there was a channel checkstop on"
+ " OCMB[0x%08x], P9A_MCC_DSTLFIR=0x%llX",
+ get_huid(i_ocmbTarget), l_scom_data);
+ l_checkstopExists = true;
+ }
+ }
+ o_checkstopExists = l_checkstopExists;
+ return l_err;
+}
+
+/*******************************************************************************
+ *
+ * @brief Validates input parameters and state for an OCMB MMIO operation
+ *
+ * @param[in] i_opType Operation type, see DeviceFW::OperationType
+ * in driverif.H
+ * @param[in] i_ocmbTarget inband scom target
+ * @param[in] i_buffer pointer to read/write buffer
+ * @param[in] i_buflen size of i_buffer (in bytes)
+ * @param[in] i_addr The base virtual address of the the OCMB MMIO space
+ * @param[in] i_offset The offset of the config reg, scom reg, MSCC reg or
+ * SRAM to be accessed.
+ * @param[in/out] io_accessLimit The number of bytes to read/write per MMIO
+ * transaction. Will be set to i_buflen if
+ * io_accessLimit is zero.
+ *
+ * @return nullptr on success, failure otherwise.
+ */
+errlHndl_t validateOcmbMmioOp(DeviceFW::OperationType i_opType,
+ const TargetHandle_t i_ocmbTarget,
+ void* i_buffer,
+ size_t i_buflen,
+ const uint64_t i_addr,
+ const uint64_t i_offset,
+ uint64_t& io_accessLimit)
+{
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ // Check that this is a supported OCMB chip
+ const auto l_ocmbChipId =
+ i_ocmbTarget->getAttr<TARGETING::ATTR_CHIP_ID>();
+ switch(l_ocmbChipId)
+ {
+ case POWER_CHIPID::EXPLORER_16:
+ case POWER_CHIPID::GEMINI_16:
+ break;
+ default:
+ TRACFCOMP(g_trac_mmio, ERR_MRK
+ "validateOcmbMmioOp: Unsupported chip ID[0x%08x] "
+ "on OCMB[0x%08x]",
+ l_ocmbChipId, get_huid(i_ocmbTarget));
/*@
* @errortype
- * @moduleid MMIO::MOD_MMIO_PERFORM_OP
+ * @moduleid MMIO::MOD_VALIDATE_OCMB_MMIO_OP
+ * @reasoncode MMIO::RC_UNSUPPORTED_CHIPID
+ * @userdata1 OCMB HUID
+ * @userdata2 OCMB chip ID
+ * @devdesc A MMIO operation was attempted
+ * on an unsupported OCMB chip.
+ * @custdesc Unexpected memory subsystem firmware error.
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MMIO::MOD_VALIDATE_OCMB_MMIO_OP,
+ MMIO::RC_UNSUPPORTED_CHIPID,
+ get_huid(i_ocmbTarget),
+ l_ocmbChipId,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+ if(l_err)
+ {
+ break;
+ }
+
+ if (i_addr == 0)
+ {
+ TRACFCOMP(g_trac_mmio, ERR_MRK
+ "validateOcmbMmioOp: MMIO has not been initialized!");
+
+ /*@
+ * @errortype
+ * @moduleid MMIO::MOD_VALIDATE_OCMB_MMIO_OP
* @reasoncode MMIO::RC_INVALID_SETUP
* @userdata1[0:31] Target huid
* @userdata1[32:63] Data Offset, if >= 4GB then subtract 2GB
@@ -237,35 +604,35 @@ errlHndl_t ocmbMmioPerformOp(DeviceFW::OperationType i_opType,
* @userdata2[0:0] Operation Type
* @userdata2[28:31] Access Limit
* @userdata2[32:63] Buffer Length
- * @devdesc mmioPerformOp> A MMIO operation was attempted
+ * @devdesc A MMIO operation was attempted
* before MMIO was initialized.
* @custdesc Unexpected memory subsystem firmware error.
*/
l_err = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MMIO::MOD_MMIO_PERFORM_OP,
+ MMIO::MOD_VALIDATE_OCMB_MMIO_OP,
MMIO::RC_INVALID_SETUP,
TWO_UINT32_TO_UINT64(
- i_target->getAttr<TARGETING::ATTR_HUID>(),
- (l_offset < (4 * GIGABYTE)) ?
- (l_offset) :
- (l_offset - (2 * GIGABYTE))),
+ get_huid(i_ocmbTarget),
+ (i_offset < (4 * GIGABYTE)) ?
+ (i_offset) :
+ (i_offset - (2 * GIGABYTE))),
TWO_UINT32_TO_UINT64(
- (i_opType << 31) | l_accessLimit,
- io_buflen),
+ (i_opType << 31) | io_accessLimit,
+ i_buflen),
ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
break;
}
- if (io_buffer == nullptr)
+ if (i_buffer == nullptr)
{
TRACFCOMP(g_trac_mmio, ERR_MRK
- "ocmbMmioPerformOp: buffer is invalid!");
+ "validateOcmbMmioOp: buffer is invalid!");
/*@
* @errortype
- * @moduleid MMIO::MOD_MMIO_PERFORM_OP
+ * @moduleid MMIO::MOD_VALIDATE_OCMB_MMIO_OP
* @reasoncode MMIO::RC_INVALID_BUFFER
* @userdata1[0:31] Target huid
* @userdata1[32:63] Data Offset, if >= 4GB then subtract 2GB
@@ -273,41 +640,41 @@ errlHndl_t ocmbMmioPerformOp(DeviceFW::OperationType i_opType,
* @userdata2[0:0] Operation Type
* @userdata2[28:31] Access Limit
* @userdata2[32:63] Buffer Length
- * @devdesc mmioPerformOp> Invalid data buffer for a MMIO
+ * @devdesc Invalid data buffer for a MMIO
* operation.
* @custdesc Unexpected memory subsystem firmware error.
*/
l_err = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MMIO::MOD_MMIO_PERFORM_OP,
+ MMIO::MOD_VALIDATE_OCMB_MMIO_OP,
MMIO::RC_INVALID_BUFFER,
TWO_UINT32_TO_UINT64(
- i_target->getAttr<TARGETING::ATTR_HUID>(),
- (l_offset < (4 * GIGABYTE)) ?
- (l_offset) :
- (l_offset - (2 * GIGABYTE))),
+ get_huid(i_ocmbTarget),
+ (i_offset < (4 * GIGABYTE)) ?
+ (i_offset) :
+ (i_offset - (2 * GIGABYTE))),
TWO_UINT32_TO_UINT64(
- (i_opType << 31) | l_accessLimit,
- io_buflen),
+ (i_opType << 31) | io_accessLimit,
+ i_buflen),
ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
break;
}
- switch (l_accessLimit) {
+ switch (io_accessLimit) {
case 0:
- l_accessLimit = io_buflen; // no access size restriction
+ io_accessLimit = i_buflen; // no access size restriction
case 4:
case 8:
break; // expected values
default:
TRACFCOMP(g_trac_mmio, ERR_MRK
- "ocmbMmioPerformOp: accessLimit(%ld) should be 0, 4 or 8!!!",
- l_accessLimit);
+ "validateOcmbMmioOp: accessLimit(%ld) should be 0, 4 or 8!!!",
+ io_accessLimit);
/*@
* @errortype
- * @moduleid MMIO::MOD_MMIO_PERFORM_OP
+ * @moduleid MMIO::MOD_VALIDATE_OCMB_MMIO_OP
* @reasoncode MMIO::RC_INVALID_ACCESS_LIMIT
* @userdata1[0:31] Target huid
* @userdata1[32:63] Data Offset, if >= 4GB then subtract 2GB
@@ -315,22 +682,22 @@ errlHndl_t ocmbMmioPerformOp(DeviceFW::OperationType i_opType,
* @userdata2[0:0] Operation Type
* @userdata2[28:31] Access Limit
* @userdata2[32:63] Buffer Length
- * @devdesc mmioPerformOp> Specified access limit was
+ * @devdesc Specified access limit was
* invalid for a MMIO operation.
* @custdesc Unexpected memory subsystem firmware error.
*/
l_err = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MMIO::MOD_MMIO_PERFORM_OP,
+ MMIO::MOD_VALIDATE_OCMB_MMIO_OP,
MMIO::RC_INVALID_ACCESS_LIMIT,
TWO_UINT32_TO_UINT64(
- i_target->getAttr<TARGETING::ATTR_HUID>(),
- (l_offset < (4 * GIGABYTE)) ?
- (l_offset) :
- (l_offset - (2 * GIGABYTE))),
+ get_huid(i_ocmbTarget),
+ (i_offset < (4 * GIGABYTE)) ?
+ (i_offset) :
+ (i_offset - (2 * GIGABYTE))),
TWO_UINT32_TO_UINT64(
- (i_opType << 31) | l_accessLimit,
- io_buflen),
+ (i_opType << 31) | io_accessLimit,
+ i_buflen),
ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
break;
}
@@ -340,16 +707,16 @@ errlHndl_t ocmbMmioPerformOp(DeviceFW::OperationType i_opType,
break;
}
- if (io_buflen < l_accessLimit)
+ if (i_buflen < io_accessLimit)
{
TRACFCOMP(g_trac_mmio, ERR_MRK
- "ocmbMmioPerformOp: buffer is too small for the"
+ "validateOcmbMmioOp: buffer is too small for the"
" request, buflen=%d, accessLimit=%ld",
- io_buflen, l_accessLimit);
+ i_buflen, io_accessLimit);
/*@
* @errortype
- * @moduleid MMIO::MOD_MMIO_PERFORM_OP
+ * @moduleid MMIO::MOD_VALIDATE_OCMB_MMIO_OP
* @reasoncode MMIO::RC_INSUFFICIENT_BUFFER
* @userdata1[0:31] Target huid
* @userdata1[32:63] Data Offset, if >= 4GB then subtract 2GB
@@ -357,38 +724,38 @@ errlHndl_t ocmbMmioPerformOp(DeviceFW::OperationType i_opType,
* @userdata2[0:0] Operation Type
* @userdata2[28:31] Access Limit
* @userdata2[32:63] Buffer Length
- * @devdesc mmioPerformOp> Data buffer too small for a
+ * @devdesc Data buffer too small for a
* MMIO operation.
* @custdesc Unexpected memory subsystem firmware error.
*/
l_err = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MMIO::MOD_MMIO_PERFORM_OP,
+ MMIO::MOD_VALIDATE_OCMB_MMIO_OP,
MMIO::RC_INSUFFICIENT_BUFFER,
TWO_UINT32_TO_UINT64(
- i_target->getAttr<TARGETING::ATTR_HUID>(),
- (l_offset < (4 * GIGABYTE)) ?
- (l_offset) :
- (l_offset - (2 * GIGABYTE))),
+ get_huid(i_ocmbTarget),
+ (i_offset < (4 * GIGABYTE)) ?
+ (i_offset) :
+ (i_offset - (2 * GIGABYTE))),
TWO_UINT32_TO_UINT64(
- (i_opType << 31) | l_accessLimit,
- io_buflen),
+ (i_opType << 31) | io_accessLimit,
+ i_buflen),
ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
break;
}
- if (io_buflen % l_accessLimit)
+ if (i_buflen % io_accessLimit)
{
TRACFCOMP(g_trac_mmio, ERR_MRK
- "ocmbMmioPerformOp: buffer length must be a"
+ "validateOcmbMmioOp: buffer length must be a"
" multiple of the access limit,"
" buflen=%d, accessLimit=%ld",
- io_buflen, l_accessLimit);
+ i_buflen, io_accessLimit);
/*@
* @errortype
- * @moduleid MMIO::MOD_MMIO_PERFORM_OP
+ * @moduleid MMIO::MOD_VALIDATE_OCMB_MMIO_OP
* @reasoncode MMIO::RC_INCORRECT_BUFFER_LENGTH
* @userdata1[0:31] Target huid
* @userdata1[32:63] Data Offset, if >= 4GB then subtract 2GB
@@ -396,38 +763,37 @@ errlHndl_t ocmbMmioPerformOp(DeviceFW::OperationType i_opType,
* @userdata2[0:0] Operation Type
* @userdata2[28:31] Access Limit
* @userdata2[32:63] Buffer Length
- * @devdesc mmioPerformOp> Buffer length not a multiple
- * of access limit.
+ * @devdesc Buffer length not a multiple of access limit.
* @custdesc Unexpected memory subsystem firmware error.
*/
l_err = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MMIO::MOD_MMIO_PERFORM_OP,
+ MMIO::MOD_VALIDATE_OCMB_MMIO_OP,
MMIO::RC_INCORRECT_BUFFER_LENGTH,
TWO_UINT32_TO_UINT64(
- i_target->getAttr<TARGETING::ATTR_HUID>(),
- (l_offset < (4 * GIGABYTE)) ?
- (l_offset) :
- (l_offset - (2 * GIGABYTE))),
+ get_huid(i_ocmbTarget),
+ (i_offset < (4 * GIGABYTE)) ?
+ (i_offset) :
+ (i_offset - (2 * GIGABYTE))),
TWO_UINT32_TO_UINT64(
- (i_opType << 31) | l_accessLimit,
- io_buflen),
+ (i_opType << 31) | io_accessLimit,
+ i_buflen),
ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
break;
}
- if (!(((l_offset >= 0) && (l_offset < (2 * GIGABYTE))) ||
- ((l_offset >= (4 * GIGABYTE)) && (l_offset < (6 * GIGABYTE)))))
+ if (!(((i_offset >= 0) && (i_offset < (2 * GIGABYTE))) ||
+ ((i_offset >= (4 * GIGABYTE)) && (i_offset < (6 * GIGABYTE)))))
{
TRACFCOMP(g_trac_mmio, ERR_MRK
- "ocmbMmioPerformOp: offset(0x%lX) must be"
+ "validateOcmbMmioOp: offset(0x%lX) must be"
" either 0-2G or 4G-6G!",
- l_offset);
+ i_offset);
/*@
* @errortype
- * @moduleid MMIO::MOD_MMIO_PERFORM_OP
+ * @moduleid MMIO::MOD_VALIDATE_OCMB_MMIO_OP
* @reasoncode MMIO::RC_INVALID_OFFSET
* @userdata1[0:31] Target huid
* @userdata1[32:63] Data Offset, if >= 4GB then subtract 2GB
@@ -435,38 +801,38 @@ errlHndl_t ocmbMmioPerformOp(DeviceFW::OperationType i_opType,
* @userdata2[0:0] Operation Type
* @userdata2[28:31] Access Limit
* @userdata2[32:63] Buffer Length
- * @devdesc mmioPerformOp> Invalid offset, requested
+ * @devdesc Invalid offset, requested
* address was out of range for a MMIO operation.
* @custdesc Unexpected memory subsystem firmware error.
*/
l_err = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MMIO::MOD_MMIO_PERFORM_OP,
+ MMIO::MOD_VALIDATE_OCMB_MMIO_OP,
MMIO::RC_INVALID_OFFSET,
TWO_UINT32_TO_UINT64(
- i_target->getAttr<TARGETING::ATTR_HUID>(),
- (l_offset < (4 * GIGABYTE)) ?
- (l_offset) :
- (l_offset - (2 * GIGABYTE))),
+ get_huid(i_ocmbTarget),
+ (i_offset < (4 * GIGABYTE)) ?
+ (i_offset) :
+ (i_offset - (2 * GIGABYTE))),
TWO_UINT32_TO_UINT64(
- (i_opType << 31) | l_accessLimit,
- io_buflen),
+ (i_opType << 31) | io_accessLimit,
+ i_buflen),
ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
break;
}
- if ( ((l_accessLimit == 4) || (l_accessLimit == 8)) &&
- ((l_offset % l_accessLimit) != 0) )
+ if ( ((io_accessLimit == 4) || (io_accessLimit == 8)) &&
+ ((i_offset % io_accessLimit) != 0) )
{
TRACFCOMP(g_trac_mmio, ERR_MRK
- "ocmbMmioPerformOp: offset must be aligned with access limit,"
+ "validateOcmbMmioOp: offset must be aligned with access limit,"
" offset=0x%lX, accessLimit=%ld",
- l_offset, l_accessLimit);
+ i_offset, io_accessLimit);
/*@
* @errortype
- * @moduleid MMIO::MOD_MMIO_PERFORM_OP
+ * @moduleid MMIO::MOD_VALIDATE_OCMB_MMIO_OP
* @reasoncode MMIO::RC_INVALID_OFFSET_ALIGNMENT
* @userdata1[0:31] Target huid
* @userdata1[32:63] Data Offset, if >= 4GB then subtract 2GB
@@ -474,73 +840,141 @@ errlHndl_t ocmbMmioPerformOp(DeviceFW::OperationType i_opType,
* @userdata2[0:0] Operation Type
* @userdata2[28:31] Access Limit
* @userdata2[32:63] Buffer Length
- * @devdesc mmioPerformOp> Requested MMIO address was not
+ * @devdesc Requested MMIO address was not
* aligned properly for the associated device.
* @custdesc Unexpected memory subsystem firmware error.
*/
l_err = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MMIO::MOD_MMIO_PERFORM_OP,
+ MMIO::MOD_VALIDATE_OCMB_MMIO_OP,
MMIO::RC_INVALID_OFFSET_ALIGNMENT,
TWO_UINT32_TO_UINT64(
- i_target->getAttr<TARGETING::ATTR_HUID>(),
- (l_offset < (4 * GIGABYTE)) ?
- (l_offset) :
- (l_offset - (2 * GIGABYTE))),
+ get_huid(i_ocmbTarget),
+ (i_offset < (4 * GIGABYTE)) ?
+ (i_offset) :
+ (i_offset - (2 * GIGABYTE))),
TWO_UINT32_TO_UINT64(
- (i_opType << 31) | l_accessLimit,
- io_buflen),
+ (i_opType << 31) | io_accessLimit,
+ i_buflen),
ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
break;
}
+ }while(0);
+ return l_err;
+}
- // TODO RTC 201493 - Remove these consts once HW group has defined them.
- static const uint8_t P9A_MC_DSTLFIR_SUBCHANNEL_A_FAIL_ACTION = 20;
- static const uint8_t P9A_MC_DSTLFIR_SUBCHANNEL_B_FAIL_ACTION = 21;
+
+/*******************************************************************************
+ *
+ * See comments in header file
+ *
+ */
+errlHndl_t ocmbMmioPerformOp(DeviceFW::OperationType i_opType,
+ TargetHandle_t i_ocmbTarget,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ va_list i_args)
+{
+ errlHndl_t l_err = nullptr;
+ uint64_t l_offset = va_arg(i_args, uint64_t);
+ uint64_t l_accessLimit = va_arg(i_args, uint64_t);
+ bool invalidParmError = false;
+
+ TRACDCOMP(g_trac_mmio, ENTER_MRK"ocmbMmioPerformOp");
+ TRACDCOMP(g_trac_mmio, INFO_MRK"op=%d, target=0x%.8X",
+ i_opType, get_huid(i_ocmbTarget));
+ TRACDCOMP(g_trac_mmio, INFO_MRK"buffer=%p, length=%d, accessType=%ld",
+ io_buffer, io_buflen, i_accessType);
+ TRACDCOMP(g_trac_mmio, INFO_MRK"offset=0x%lX, accessLimit=%ld",
+ l_offset, l_accessLimit);
+
+ do
+ {
+ uint64_t l_addr = i_ocmbTarget->getAttr<ATTR_MMIO_VM_ADDR>();
+
+ TRACDCOMP(g_trac_mmio, INFO_MRK"MMIO Op l_addr=0x%lX ", l_addr);
+
+ // Validate parameters for MMIO operation
+ l_err = validateOcmbMmioOp(i_opType,
+ i_ocmbTarget,
+ io_buffer,
+ io_buflen,
+ l_addr,
+ l_offset,
+ l_accessLimit);
+ if(l_err)
+ {
+ invalidParmError = true;
+ break;
+ }
// read or write io_buflen bytes, l_accessLimit bytes at a time
- uint8_t *mm_ptr = reinterpret_cast<uint8_t *>(l_addr + l_offset);
- uint8_t *io_ptr = reinterpret_cast<uint8_t *>(io_buffer);
- size_t bytes_read_or_written = 0;
- for (size_t i = 0;i < io_buflen;i += l_accessLimit)
+ uint8_t* l_mmPtr = reinterpret_cast<uint8_t *>(l_addr + l_offset);
+ uint8_t* l_ioPtr = reinterpret_cast<uint8_t *>(io_buffer);
+ size_t l_bytesCopied = 0;
+ for (;l_bytesCopied < io_buflen; l_bytesCopied += l_accessLimit)
{
if (i_opType == DeviceFW::READ)
{
- mmio_memcpy(io_ptr + i, mm_ptr + i, l_accessLimit);
+ // Perform requested MMIO read
+ mmio_memcpy(l_ioPtr + l_bytesCopied,
+ l_mmPtr + l_bytesCopied,
+ l_accessLimit);
eieio();
- if (!memcmp(io_ptr + i,
+
+ // If there was a UE detected by the processor, a Load UE
+ // exception will be raised. Kernel code will detect
+ // that the exception occurred during an OCMB read and
+ // will write a unique pattern, MMIO_OCMB_UE_DETECTED, into
+ // the read buffer so that we can quickly know that the MMIO
+ // read failed.
+ if (memcmp(l_ioPtr + l_bytesCopied,
&MMIO_OCMB_UE_DETECTED,
sizeof(MMIO_OCMB_UE_DETECTED)))
{
- uint64_t scom_data = 0;
- uint64_t scom_mask = 0;
+ //No read failure detected. Keep going.
+ continue;
+ }
- TRACFCOMP(g_trac_mmio, ERR_MRK
- "ocmbMmioPerformOp: unable to complete"
- " MMIO read, SUE detected");
+ //MMIO Read failed!
+ TRACFCOMP(g_trac_mmio, ERR_MRK
+ "ocmbMmioPerformOp: unable to complete"
+ " MMIO read of offset 0x%08x from OCMB 0x%08x",
+ l_offset, get_huid(i_ocmbTarget));
+
+ // Check for channel checkstops (this reads a processor reg)
+ bool l_checkstopExists = false;
+ l_err = checkChannelCheckstop(i_ocmbTarget, l_checkstopExists);
+ if(l_err)
+ {
+ // Couldn't deterimine if checkstop exists.
+ break;
+ }
+ if(l_checkstopExists)
+ {
/*@
* @errortype
* @moduleid MMIO::MOD_MMIO_PERFORM_OP
- * @reasoncode MMIO::RC_BAD_MMIO_READ
+ * @reasoncode MMIO::RC_MMIO_CHAN_CHECKSTOP
* @userdata1[0:31] Target huid
* @userdata1[32:63] Data Offset, if >= 4GB then subtract
* 2GB (allows offsets to fit in 32 bits)
* @userdata2[0:0] Operation Type
* @userdata2[28:31] Access Limit
* @userdata2[32:63] Buffer Length
- * @devdesc mmioPerformOp> MMIO read of an OCMB
- * failed.
- * @custdesc Unexpected memory subsystem firmware
- * error.
+ * @devdesc OCMB MMIO read failed due to
+ * channel checkstop
+ * @custdesc Unexpected memory subsystem error.
*/
l_err = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MMIO::MOD_MMIO_PERFORM_OP,
+ MMIO::MOD_MMIO_CHAN_CHECKSTOP,
MMIO::RC_BAD_MMIO_READ,
TWO_UINT32_TO_UINT64(
- i_target->getAttr<TARGETING::ATTR_HUID>(),
+ get_huid(i_ocmbTarget),
(l_offset < (4 * GIGABYTE)) ?
(l_offset) :
(l_offset - (2 * GIGABYTE))),
@@ -548,198 +982,286 @@ errlHndl_t ocmbMmioPerformOp(DeviceFW::OperationType i_opType,
(i_opType << 31) | l_accessLimit,
io_buflen),
ERRORLOG::ErrlEntry::NO_SW_CALLOUT);
- // add OCMB to error log
- l_err->addHwCallout(i_target,
- HWAS::SRCI_PRIORITY_HIGH,
- HWAS::DECONFIG,
- HWAS::GARD_NULL);
- l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_LOW);
- const auto plid = l_err->plid();
-
- auto l_err2 = getProcScom(i_target,
- P9A_MCC_USTLFIR,
- scom_data);
- if (l_err2)
- {
- l_err2->plid(plid);
- errlCommit(l_err2, MMIO_COMP_ID);
- }
- else
- {
- scom_mask = (1ull << P9A_MC_USTLFIR_CHANA_BAD_DATA) |
- (1ull << P9A_MC_USTLFIR_CHANB_BAD_DATA);
- if (scom_data & scom_mask)
- {
- // TODO RTC 201588 - Error checking on Explorer side
- TRACFCOMP(g_trac_mmio, ERR_MRK
- "ocmbMmioPerformOp: there was an error on"
- " the Explorer side, P9A_MCC_USTLFIR=0x%lX",
- scom_data);
-
- // Clear FIR bits
- scom_data &= ~scom_mask;
- l_err2 = setProcScom(i_target,
- P9A_MCC_USTLFIR,
- scom_data);
- if (l_err2)
- {
- l_err2->plid(plid);
- errlCommit(l_err2, MMIO_COMP_ID);
- }
- }
- }
- l_err2 = getProcScom(i_target,
- P9A_MCC_DSTLFIR,
- scom_data);
- if (l_err2)
- {
- l_err2->plid(plid);
- errlCommit(l_err2, MMIO_COMP_ID);
- }
- else
+ addDefaultCallouts(l_err, i_ocmbTarget);
+
+ // Switch to I2C to allow collection of registers on
+ // OCMB.
+ disableInbandScomsOcmb(i_ocmbTarget);
+
+ // TODO RTC 201778 - Channel fail handling for Explorer
+ // dump some registers to the error log here?
+
+ // Look for a better PRD error
+ //
+ // TODO RTC 92971
+ // There is a potential deadlock if we call PRD here since
+ // we could recursively call PRD and they are locking a
+ // mutex. Skip this call for now.
+ //
+ //errlHndl_t l_prd_err = ATTN::checkForIplAttentions();
+ errlHndl_t l_prd_err = NULL;
+ if(l_prd_err)
{
- scom_mask =
- (1ull << P9A_MC_DSTLFIR_SUBCHANNEL_A_FAIL_ACTION) |
- (1ull << P9A_MC_DSTLFIR_SUBCHANNEL_B_FAIL_ACTION);
- if (scom_data & scom_mask)
- {
- // A channel checkstop has occurred.
- // TODO RTC 201778 - Channel Fail Handling for
- // Explorer
- TRACFCOMP(g_trac_mmio, ERR_MRK
- "ocmbMmioPerformOp: there was an error on"
- " the Explorer channel, P9A_MCC_DSTLFIR=0x%lX",
- scom_data);
- }
+ TRACFCOMP(g_trac_mmio,
+ ERR_MRK"Error from checkForIplAttentions: "
+ "PLID=%X",
+ l_prd_err->plid());
+
+ //connect up the plids
+ l_err->plid(l_prd_err->plid());
+
+ //commit my log as info because PRD's log is better
+ l_err->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ ERRORLOG::errlCommit(l_err, MMIO_COMP_ID);
+ l_err = l_prd_err;
}
break;
}
+
+ /*@
+ * @errortype
+ * @moduleid MMIO::MOD_MMIO_PERFORM_OP
+ * @reasoncode MMIO::RC_BAD_MMIO_READ
+ * @userdata1[0:31] Target huid
+ * @userdata1[32:63] Data Offset, if >= 4GB then subtract
+ * 2GB (allows offsets to fit in 32 bits)
+ * @userdata2[0:0] Operation Type
+ * @userdata2[28:31] Access Limit
+ * @userdata2[32:63] Buffer Length
+ * @devdesc OCMB MMIO read failed
+ * @custdesc Unexpected memory subsystem firmware
+ * error.
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MMIO::MOD_MMIO_PERFORM_OP,
+ MMIO::RC_BAD_MMIO_READ,
+ TWO_UINT32_TO_UINT64(
+ get_huid(i_ocmbTarget),
+ (l_offset < (4 * GIGABYTE)) ?
+ (l_offset) :
+ (l_offset - (2 * GIGABYTE))),
+ TWO_UINT32_TO_UINT64(
+ (i_opType << 31) | l_accessLimit,
+ io_buflen),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT);
+
+ // NOTE: Explorer error regs cannot be cleared without resetting
+ // the chip. Error regs may contain failure data from
+ // previous write transaction.
+ //
+ // Check if OCMB has failure data for this transaction.
+ bool l_errorAddressMatches = false;
+ bool l_errorAddressIsZero = false;
+ auto l_err2 = checkOcmbError(
+ i_ocmbTarget,
+ reinterpret_cast<uint64_t>(l_mmPtr +
+ l_bytesCopied),
+ l_accessLimit,
+ l_offset,
+ i_opType,
+ l_errorAddressMatches,
+ l_errorAddressIsZero);
+ if (l_err2)
+ {
+ // Failed to read ocmb status register after
+ // we just determined that there was not
+ // a channel checkstop? Commit this error
+ // as informational and add default callouts
+ // to l_err.
+ l_err2->plid(l_err->plid());
+ ERRORLOG::errlCommit(l_err2, MMIO_COMP_ID);
+ addDefaultCallouts(l_err, i_ocmbTarget);
+ break;
+ }
+ else if(l_errorAddressMatches)
+ {
+ // Read additional OCMB regs to determine if this was
+ // a HW or SW error.
+ determineCallouts(i_ocmbTarget, l_offset, i_opType, l_err);
+ break;
+ }
+ else if(l_errorAddressIsZero)
+ {
+ // P9A disagrees with OCMB?
+ TRACFCOMP(g_trac_mmio,
+ "ocmbMmioPerformOp(read): No Error found on OCMB??"
+ " 0x%08x", get_huid(i_ocmbTarget));
+ addDefaultCallouts(l_err, i_ocmbTarget);
+ break;
+ }
+
+ // Address does not match ours and is not zero.
+ // This was probably caused by an MMIO write failure
+ // doing an MMIO read to detect if the MMIO write
+ // was successful or not.
+ TRACFCOMP(g_trac_mmio,
+ "ocmbMmioPerformOp(read): Previous error detected on"
+ " OCMB 0x%08x", get_huid(i_ocmbTarget));
+ break;
}
- else if (i_opType == DeviceFW::WRITE)
+ else // i_opType == DeviceFW::WRITE
{
- mmio_memcpy(mm_ptr + i, io_ptr + i, l_accessLimit);
+ // Perform the MMIO write
+ mmio_memcpy(l_mmPtr + l_bytesCopied,
+ l_ioPtr + l_bytesCopied,
+ l_accessLimit);
eieio();
- // TODO RTC 201901 - find a better OCMB register to read, should
- // be able to optimize error handling.
-
- // do a read on the OCMB after writing to it, since writes and
- // reads are sequential, the read won't complete until after the
- // write.
- uint64_t scom_addr = (4 * GIGABYTE) + 4; // RTC 201901
- uint8_t l_ocmbReg[8] = {0};
-
- mmio_memcpy(l_ocmbReg, mm_ptr + scom_addr, sizeof(l_ocmbReg));
- eieio();
- if (!memcmp(io_ptr + i,
- &MMIO_OCMB_UE_DETECTED,
- sizeof(MMIO_OCMB_UE_DETECTED)))
+ // MMIO write failures will not cause an exception
+ // to be raised on the host processor. Instead, code
+ // needs to check a register on the OCMB to determine
+ // if a specific write failed.
+ bool l_errorAddressMatches = false;
+ bool l_errorAddressIsZero = false;
+ l_err = checkOcmbError(
+ i_ocmbTarget,
+ reinterpret_cast<uint64_t>(l_mmPtr +
+ l_bytesCopied),
+ l_accessLimit,
+ l_offset,
+ i_opType,
+ l_errorAddressMatches,
+ l_errorAddressIsZero);
+
+ // Check that we were able to read the error register
+ // and that it doesn't contain our address.
+ if(!l_err && !l_errorAddressMatches)
{
- uint64_t scom_data = 0;
- uint64_t scom_mask = 0;
+ // No errors detected. Keep going.
+ continue;
+ }
- TRACFCOMP(g_trac_mmio, ERR_MRK
- "ocmbMmioPerformOp: unable to complete MMIO"
- " write, SUE detected");
+ // At this point, we know that the write or status read failed.
+ // Go ahead and create a basic MMIO Write error log.
+ TRACFCOMP(g_trac_mmio, ERR_MRK
+ "ocmbMmioPerformOp: unable to complete"
+ " MMIO write to offset 0x%08x on OCMB 0x%08x",
+ l_offset, get_huid(i_ocmbTarget));
- /*@
- * @errortype
- * @moduleid MMIO::MOD_MMIO_PERFORM_OP
- * @reasoncode MMIO::RC_BAD_MMIO_WRITE
- * @userdata1[0:31] Target huid
- * @userdata1[32:63] Data Offset, if >= 4GB then subtract
- * 2GB (allows offsets to fit in 32 bits)
- * @userdata2[0:0] Operation Type
- * @userdata2[28:31] Access Limit
- * @userdata2[32:63] Buffer Length
- * @devdesc mmioPerformOp> MMIO write of an OCMB
- * failed.
- * @custdesc Unexpected memory subsystem firmware
- * error.
- */
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MMIO::MOD_MMIO_PERFORM_OP,
- MMIO::RC_BAD_MMIO_WRITE,
- TWO_UINT32_TO_UINT64(
- i_target->getAttr<TARGETING::ATTR_HUID>(),
- (l_offset < (4 * GIGABYTE)) ?
- (l_offset) :
- (l_offset - (2 * GIGABYTE))),
- TWO_UINT32_TO_UINT64(
- (i_opType << 31) | l_accessLimit,
- io_buflen),
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT);
- // add OCMB to error log
- l_err->addHwCallout(i_target,
- HWAS::SRCI_PRIORITY_HIGH,
- HWAS::DECONFIG,
- HWAS::GARD_NULL);
- l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_LOW);
- const auto plid = l_err->plid();
-
- auto l_err2 = getProcScom(i_target,
- P9A_MCC_DSTLFIR,
- scom_data);
- if (l_err2)
+ /*@
+ * @errortype
+ * @moduleid MMIO::MOD_MMIO_PERFORM_OP
+ * @reasoncode MMIO::RC_BAD_MMIO_WRITE
+ * @userdata1[0:31] Target huid
+ * @userdata1[32:63] Data Offset, if >= 4GB then subtract
+ * 2GB (allows offsets to fit in 32 bits)
+ * @userdata2[0:0] Operation Type
+ * @userdata2[28:31] Access Limit
+ * @userdata2[32:63] Buffer Length
+ * @devdesc OCMB MMIO write failed
+ * @custdesc Unexpected memory subsystem firmware
+ * error.
+ */
+ auto l_writeErr = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MMIO::MOD_MMIO_PERFORM_OP,
+ MMIO::RC_BAD_MMIO_WRITE,
+ TWO_UINT32_TO_UINT64(
+ get_huid(i_ocmbTarget),
+ (l_offset < (4 * GIGABYTE)) ?
+ (l_offset) :
+ (l_offset - (2 * GIGABYTE))),
+ TWO_UINT32_TO_UINT64(
+ (i_opType << 31) | l_accessLimit,
+ io_buflen),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT);
+
+ // Check if the register read failed
+ if(l_err)
+ {
+ // We were not able to read the error register on the
+ // OCMB. The most likely scenario here is that there
+ // was a HW failure (possibly a channel checkstop).
+ //
+ // NOTE: If we only logged this error as-is and no
+ // other error, we wouldn't know that the read was
+ // a result of a write. Instead, log both errors
+ // and set the PLID's to be the same.
+ TRACFCOMP(g_trac_mmio,
+ "ocmbMmioPerformOp(write): Fail to read status on"
+ " OCMB 0x%08x", get_huid(i_ocmbTarget));
+ l_writeErr->plid(l_err->plid());
+
+ // Set severity of write error to match the read
+ // error if there is a channel checkstop.
+ bool l_checkstopExists = false;
+ errlHndl_t l_xstopErr = nullptr;
+ l_xstopErr = checkChannelCheckstop(i_ocmbTarget,
+ l_checkstopExists);
+ if(l_xstopErr)
{
- l_err2->plid(plid);
- errlCommit(l_err2, MMIO_COMP_ID);
+ // Couldn't deterimine if checkstop exists.
+ // Commit the xstop error and assume no checkstop.
+ l_xstopErr->collectTrace(MMIO_COMP_NAME);
+ ERRORLOG::errlCommit(l_xstopErr, MMIO_COMP_ID);
}
- else
+ if(l_checkstopExists)
{
- scom_mask =
- (1ull << P9A_MC_DSTLFIR_SUBCHANNEL_A_FAIL_ACTION) |
- (1ull << P9A_MC_DSTLFIR_SUBCHANNEL_B_FAIL_ACTION);
- if (scom_data & scom_mask)
- {
- // A channel checkstop has occurred.
- // TODO RTC 201778 - Channel Fail Handling for
- // Explorer
- TRACFCOMP(g_trac_mmio, ERR_MRK
- "ocmbMmioPerformOp: there was an error on"
- " the Explorer channel, P9A_MCC_DSTLFIR=0x%lX",
- scom_data);
- }
+ l_writeErr->setSev(l_err->sev());
}
-
+ ERRORLOG::errlCommit(l_err, MMIO_COMP_ID);
+ l_err = l_writeErr;
break;
}
- }
- bytes_read_or_written += l_accessLimit;
- }
+ l_err = l_writeErr;
+ l_writeErr = nullptr;
+
+ // At this point, we were able to read the error register
+ // and determined that it matched the address of our
+ // transaction. No need to check for a channel checkstop
+ // on the write operation since we already did that in the
+ // read path when we tried to read the OCMB status register.
- io_buflen = bytes_read_or_written;
+ // Read additional OCMB regs to determine if this was
+ // a HW or SW error.
+ determineCallouts(i_ocmbTarget, l_offset, i_opType, l_err);
+ break;
+ } // end of write block
+
+ } // end of for loop
+
+ io_buflen = l_bytesCopied;
} while(0);
if (l_err)
{
+ // Only disable if HW error, not for user parameter failures
+ if (!invalidParmError)
+ {
+ // Switch over to using I2C to prevent further MMIO access
+ // to this OCMB (error regs cannot be cleared on Explorer).
+ disableInbandScomsOcmb(i_ocmbTarget);
+ }
+
l_err->collectTrace(MMIO_COMP_NAME);
}
- TRACDCOMP(g_trac_mmio, EXIT_MRK"mmioPerformOp");
+ TRACDCOMP(g_trac_mmio, EXIT_MRK"ocmbMmioPerformOp");
return l_err;
}
+/*******************************************************************************
+ *
+ * @brief Finds the processor connected to the target OCMB chip.
+ *
+ */
static
-TARGETING::TargetHandle_t getParentProc(TARGETING::TargetHandle_t i_target)
+TargetHandle_t getParentProc(
+ const TargetHandle_t i_ocmbTarget)
{
- TARGETING::TargetHandle_t proc = nullptr;
- TARGETING::TargetHandleList list;
- TARGETING::PredicateCTM pred(TARGETING::CLASS_CHIP,
- TARGETING::TYPE_PROC);
-
- TARGETING::targetService().getAssociated(
- list,
- i_target,
- TARGETING::TargetService::PARENT_BY_AFFINITY,
- TARGETING::TargetService::ALL,
+ TargetHandle_t proc = nullptr;
+ TargetHandleList list;
+ PredicateCTM pred(CLASS_CHIP, TYPE_PROC);
+
+ targetService().getAssociated( list,
+ i_ocmbTarget,
+ TargetService::PARENT_BY_AFFINITY,
+ TargetService::ALL,
&pred);
if (list.size() == 1)
@@ -750,19 +1272,25 @@ TARGETING::TargetHandle_t getParentProc(TARGETING::TargetHandle_t i_target)
return proc;
}
+/*******************************************************************************
+ *
+ * @brief Reads a scom register on the processor connected to the target OCMB
+ * chip.
+ *
+ */
static
-errlHndl_t getProcScom(TARGETING::TargetHandle_t i_target,
+errlHndl_t getProcScom(const TargetHandle_t i_ocmbTarget,
uint64_t i_scomAddr,
uint64_t &o_scomData)
{
errlHndl_t l_err = nullptr;
- auto proc = getParentProc(i_target);
+ auto proc = getParentProc(i_ocmbTarget);
if (proc == nullptr)
{
TRACFCOMP(g_trac_mmio, ERR_MRK
"getProcScom: Unable to find parent processor for target(0x%X)",
- i_target->getAttr<TARGETING::ATTR_HUID>());
+ get_huid(i_ocmbTarget));
/*@
* @errortype
@@ -770,14 +1298,14 @@ errlHndl_t getProcScom(TARGETING::TargetHandle_t i_target,
* @reasoncode MMIO::RC_PROC_NOT_FOUND
* @userdata1 Target huid
* @userdata2 SCOM address
- * @devdesc getProcScom> Unable to find parent processor for target.
+ * @devdesc Unable to find parent processor for target.
* @custdesc Unexpected memory subsystem firmware error.
*/
l_err = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
MMIO::MOD_MMIO_GET_PROC_SCOM,
MMIO::RC_PROC_NOT_FOUND,
- i_target->getAttr<TARGETING::ATTR_HUID>(),
+ get_huid(i_ocmbTarget),
i_scomAddr,
ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
}
@@ -794,19 +1322,26 @@ errlHndl_t getProcScom(TARGETING::TargetHandle_t i_target,
return l_err;
}
-static
-errlHndl_t setProcScom(TARGETING::TargetHandle_t i_target,
+/*******************************************************************************
+ *
+ * @brief Writes a scom register on the processor connected to the target OCMB
+ * chip.
+ *
+ */
+// NOTE: removed static qualifier to prevent compiler from complaining about
+// the function not being used.
+errlHndl_t setProcScom(const TargetHandle_t i_ocmbTarget,
uint64_t i_scomAddr,
uint64_t i_scomData)
{
errlHndl_t l_err = nullptr;
- auto proc = getParentProc(i_target);
+ auto proc = getParentProc(i_ocmbTarget);
if (proc == nullptr)
{
TRACFCOMP(g_trac_mmio, ERR_MRK
"setProcScom: Unable to find parent processor for target(0x%X)",
- i_target->getAttr<TARGETING::ATTR_HUID>());
+ get_huid(i_ocmbTarget));
/*@
* @errortype
@@ -814,14 +1349,14 @@ errlHndl_t setProcScom(TARGETING::TargetHandle_t i_target,
* @reasoncode MMIO::RC_PROC_NOT_FOUND
* @userdata1 Target huid
* @userdata2 SCOM address
- * @devdesc setProcScom> Unable to find parent processor for target.
+ * @devdesc Unable to find parent processor for target.
* @custdesc Unexpected memory subsystem firmware error.
*/
l_err = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
MMIO::MOD_MMIO_SET_PROC_SCOM,
MMIO::RC_PROC_NOT_FOUND,
- i_target->getAttr<TARGETING::ATTR_HUID>(),
+ get_huid(i_ocmbTarget),
i_scomAddr,
ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
}
@@ -838,6 +1373,13 @@ errlHndl_t setProcScom(TARGETING::TargetHandle_t i_target,
return l_err;
}
+
+/*******************************************************************************
+ *
+ * @brief Copies len bytes of data from location pointed to by vsrc to location
+ * pointed to by vdest.
+ *
+ */
static
void *mmio_memcpy(void *vdest, const void *vsrc, size_t len)
{
diff --git a/src/usr/mmio/mmio.H b/src/usr/mmio/mmio.H
index d69ade6f7..96ea25e8d 100644
--- a/src/usr/mmio/mmio.H
+++ b/src/usr/mmio/mmio.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -25,6 +25,10 @@
#ifndef __MMIO_H
#define __MMIO_H
+#include <errl/errlentry.H>
+#include <devicefw/driverif.H>
+#include <targeting/common/target.H>
+
/** @file mmio.H
* @brief Provides interface to perform MMIO operations to Explorer chips
* */
diff --git a/src/usr/mmio/mmio_explorer.C b/src/usr/mmio/mmio_explorer.C
new file mode 100644
index 000000000..9565c8341
--- /dev/null
+++ b/src/usr/mmio/mmio_explorer.C
@@ -0,0 +1,474 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/mmio/mmio_explorer.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <devicefw/driverif.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <errl/errludlogregister.H>
+#include <explorer_scom_addresses.H>
+#include <lib/inband/exp_inband.H>
+#include <mmio/mmio_reasoncodes.H>
+
+// Trace definition
+extern trace_desc_t* g_trac_mmio;
+
+using namespace TARGETING;
+
+namespace MMIOEXP
+{
+
+#define MMIOEXP_SCOM2OFFSET(_SCOM_ADDR) \
+ (mss::exp::ib::EXPLR_IB_MMIO_OFFSET | (_SCOM_ADDR << 3))
+
+/**
+ * @brief Possible Open CAPI response codes for config operations
+ */
+enum
+{
+ OCAPI_RETRY_REQUEST = 0x2,
+ OCAPI_DATA_ERROR = 0x8,
+ OCAPI_UNSUPPORTED_OP_LENGTH = 0x9,
+ OCAPI_BAD_ADDRESS = 0xB,
+ OCAPI_FAILED = 0xE,
+};
+
+/**
+ * @brief Possible PCB error codes for non-config operations
+ */
+enum
+{
+ PCB_OK = 0x0,
+ PCB_INVALID_ADDRESS = 0x4,
+ PCB_PARITY_ERROR = 0x6,
+ PCB_TIMEOUT = 0x7,
+};
+
+/**
+ * @brief bit-field definitions for MCFGERR register
+ */
+typedef union mcfgerrReg
+{
+ struct
+ {
+ uint64_t reserved :16;
+ uint64_t resp_code :4;
+ uint64_t bdi :1;
+ uint64_t error_type :3;
+ uint64_t device :5;
+ uint64_t function :3;
+ uint64_t dev_func_mismatch :1;
+ uint64_t detect_bad_op :1;
+ uint64_t tbit_is_1 :1;
+ uint64_t data_is_bad :1;
+ uint64_t pl_is_invalid :1;
+ uint64_t bad_op_or_align :1;
+ uint64_t addr_no_implemented:1;
+ uint64_t rdata_vld :1;
+ uint64_t tbit :1;
+ uint64_t plen :3;
+ uint64_t portnun :2;
+ uint64_t dl :2;
+ uint64_t capptag :16;
+ };
+ uint64_t word64;
+}mcfgerrReg_t;
+
+/**
+ * @brief bit-field definitions for GIF2PCB_ERROR register
+ */
+typedef union gif2pcbErrorReg
+{
+ struct
+ {
+ uint64_t parity_error_rsp_info :1;
+ uint64_t parity_error_rsp_data_0 :1;
+ uint64_t parity_error_rsp_data_1 :1;
+ uint64_t parity_error_rsp_data_2 :1;
+ uint64_t parity_error_rsp_data_3 :1;
+ uint64_t timeout_error :1;
+ uint64_t int_addr_access_error :1;
+ uint64_t invalid_access :1;
+ uint64_t pcb_err_code :3;
+ uint64_t axi_read_addr_parity_error :1;
+ uint64_t axi_write_addr_parity_error :1;
+ uint64_t axi_write_data_parity_error_31_24 :1;
+ uint64_t axi_write_data_parity_error_23_16 :1;
+ uint64_t axi_write_data_parity_error_15_8 :1;
+ uint64_t axi_write_data_parity_error_7_0 :1;
+ uint64_t pib2gif_parity_error :1;
+ uint64_t reserved :46;
+ };
+ struct
+ {
+ uint64_t used_bits :18;
+ uint64_t unused_bits :46;
+ };
+ uint64_t word64;
+}gif2pcbErrorReg_t;
+
+/**
+ * @brief bit-field definitions for PIB2GIF_ERROR register
+ */
+typedef union pib2gifErrorReg
+{
+ struct
+ {
+ uint64_t parity_error_req_data_0:1;
+ uint64_t parity_error_req_data_1:1;
+ uint64_t parity_error_req_data_2:1;
+ uint64_t parity_error_req_data_3:1;
+ uint64_t parity_error_req_addr_0:1;
+ uint64_t parity_error_req_addr_1:1;
+ uint64_t parity_error_req_ctrl:1;
+ uint64_t timeout_error:1;
+ uint64_t int_addr_access_error:1;
+ uint64_t parity_error_on_fsm:1;
+ uint64_t parity_error_on_reg0:1;
+ uint64_t parity_error_on_reg1:1;
+ uint64_t parity_error_on_reg2:1;
+ uint64_t parity_error_on_reg3:1;
+ uint64_t parity_error_on_reg4:1;
+ uint64_t parity_error_on_reg5:1;
+ uint64_t invalid_address_error:1;
+ uint64_t reserved1:15;
+ uint64_t gif2pcb_error:18;
+ uint64_t reserved2:14;
+ };
+ uint64_t word64;
+}pib2gifErrorReg_t;
+
+// Explorer MMIO addresses only have 35 bits
+constexpr uint64_t MASK_35BITS = 0x7FFFFFFFFull;
+
+
+/*******************************************************************************
+ *
+ * See header file for comments
+ */
+errlHndl_t checkExpError(const TargetHandle_t i_expTarget,
+ const uint64_t i_va,
+ const uint64_t i_accessLimit,
+ const uint64_t i_offset,
+ DeviceFW::OperationType i_opType,
+ bool& o_errorAddressMatches,
+ bool& o_errorAddressIsZero)
+{
+ errlHndl_t l_err = nullptr;
+ uint64_t l_errAddr = 0;
+ bool l_errorAddressMatches = false;
+ bool l_errorAddressIsZero = false;
+ const char* l_regStr = nullptr;
+
+ // NOTE: mmio_memcpy could be doing multiple transactions. This means
+ // we need to test the explorer error address register against a
+ // range of values instead of a single value.
+ // NOTE: Explorer only uses the low 35 bits of the address for MMIO access
+ const uint64_t l_mmioAddr35Lo = i_va & MASK_35BITS;
+ const uint64_t l_mmioAddr35Hi = (i_va + i_accessLimit) & MASK_35BITS;
+
+ do
+ {
+ // For access to CONFIG space, the MCFGERRA scom register
+ // contains the first failing address.
+ if(i_offset < mss::exp::ib::EXPLR_IB_MMIO_OFFSET)
+ {
+ auto l_reqSize = sizeof(l_errAddr);
+ l_err = DeviceFW::deviceRead(
+ i_expTarget,
+ &l_errAddr,
+ l_reqSize,
+ DEVICE_SCOM_ADDRESS(EXPLR_MMIO_MCFGERRA));
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_mmio, ERR_MRK
+ "checkExpError: getscom(MCFGERRA) failed."
+ " huid[0x%08x]", get_huid(i_expTarget));
+ break;
+ }
+ l_regStr = "MCFGERRA";
+ }
+ // Otherwise, we are accessing a non-config address and, if there
+ // is a failure, the MMIO address will show up in the lower 35 bits of
+ // the MMIOERR register
+ else
+ {
+ // If the transaction was a read to this error register then
+ // we already know that it failed. Don't keep trying to
+ // read it or we could end up in a recursive loop.
+ if((i_opType == DeviceFW::READ) &&
+ (i_offset == MMIOEXP_SCOM2OFFSET(EXPLR_MMIO_MMIOERR)))
+ {
+ break;
+ }
+ auto l_reqSize = sizeof(l_errAddr);
+ l_err = DeviceFW::deviceRead(
+ i_expTarget,
+ &l_errAddr,
+ l_reqSize,
+ DEVICE_SCOM_ADDRESS(EXPLR_MMIO_MMIOERR));
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_mmio, ERR_MRK
+ "checkExpError: getscom(MMIOERR) failed."
+ " huid[0x%08x]", get_huid(i_expTarget));
+ break;
+ }
+ l_regStr = "MMIOERR";
+ }
+
+ // Check if error address from explorer is zero, meaning that
+ // explorer did not detect an error.
+ if(l_errAddr == 0)
+ {
+ l_errorAddressIsZero = true;
+ }
+
+ // Check if 35-bit error address is outside our transaction
+ // access range
+ const uint64_t l_errAddr35 = l_errAddr & MASK_35BITS;
+ if((l_errAddr35 < l_mmioAddr35Lo) ||
+ (l_errAddr35 >= l_mmioAddr35Hi))
+ {
+ TRACDCOMP(g_trac_mmio,
+ "checkExpError: %s: 0x%09llx is not between 0x%09llx and"
+ " 0x%09llx on huid[0x%08x]",
+ l_regStr, l_errAddr, l_mmioAddr35Lo,
+ l_mmioAddr35Hi, get_huid(i_expTarget));
+ // Error address is outside our transaction range so this error
+ // was not caused by our transaction.
+ break;
+ }
+
+ TRACFCOMP(g_trac_mmio, ERR_MRK
+ "checkExpError: %s: 0x%09llx is between 0x%09llx and"
+ " 0x%09llx on huid[0x%08x]",
+ l_regStr, l_errAddr35, l_mmioAddr35Lo,
+ l_mmioAddr35Hi, get_huid(i_expTarget));
+ l_errorAddressMatches = true;
+
+ // NOTE: These registers cannot be cleared without resetting the chip.
+
+ }while(0);
+
+ o_errorAddressMatches = l_errorAddressMatches;
+ o_errorAddressIsZero = l_errorAddressIsZero;
+ return l_err;
+}
+
+/*******************************************************************************
+ *
+ * See header file for comments
+ */
+errlHndl_t determineExpCallouts(const TargetHandle_t i_expTarget,
+ const uint64_t i_offset,
+ DeviceFW::OperationType i_opType,
+ errlHndl_t i_err,
+ bool& o_fwFailure)
+{
+ bool l_fwFailure = false; //default to a hw failure
+ errlHndl_t l_err = nullptr;
+ size_t l_reqSize = 0;
+ ERRORLOG::ErrlUserDetailsLogRegister l_regDump(i_expTarget);
+
+ do
+ {
+ // If the transaction was a read to any of these error registers,
+ // that we're about to read then we know that it already failed.
+ // Don't keep trying to read it or we could end up in a recursive
+ // loop.
+ if(i_opType == DeviceFW::READ)
+ {
+ switch(i_offset)
+ {
+ case MMIOEXP_SCOM2OFFSET(EXPLR_MMIO_MCFGERR):
+ case MMIOEXP_SCOM2OFFSET(EXPLR_MMIO_MCFGERRA):
+ case MMIOEXP_SCOM2OFFSET(EXPLR_MMIO_MMIOERR):
+ case MMIOEXP_SCOM2OFFSET(EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG):
+ case MMIOEXP_SCOM2OFFSET(EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG):
+ case MMIOEXP_SCOM2OFFSET(EXPLR_MMIO_MFIR):
+ case MMIOEXP_SCOM2OFFSET(EXPLR_MMIO_MFIRWOF):
+ TRACFCOMP(g_trac_mmio,
+ "determineExpCallouts: recursive loop detected:"
+ " OCMB[0x%08x] offset[0x%016llx]",
+ TARGETING::get_huid(i_expTarget), i_offset);
+ /*@
+ * @errortype
+ * @moduleid MMIO::MOD_DETERMINE_EXP_CALLOUTS
+ * @reasoncode MMIO::RC_BAD_MMIO_READ
+ * @userdata1 OCMB huid
+ * @userdata2 Address offset
+ * @devdesc OCMB MMIO read failed
+ * @custdesc Unexpected memory subsystem firmware
+ * error.
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MMIO::MOD_DETERMINE_EXP_CALLOUTS,
+ MMIO::RC_BAD_MMIO_READ,
+ TARGETING::get_huid(i_expTarget),
+ i_offset,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT);
+ break;
+
+ default:
+ break;
+ }
+ if(l_err)
+ {
+ break;
+ }
+ }
+
+ // Check if this is an access to config space
+ if(i_offset < mss::exp::ib::EXPLR_IB_MMIO_OFFSET)
+ {
+ mcfgerrReg_t l_reg;
+
+ TRACFCOMP(g_trac_mmio,
+ "determineExpCallouts: getting callouts for failed config"
+ " space transaction on OCMB[0x%08x]", get_huid(i_expTarget));
+
+ // Read the Explorer MCFGERR register
+ // NOTE: This register is not clearable
+ l_reqSize = sizeof(l_reg.word64);
+ l_err = DeviceFW::deviceRead(
+ i_expTarget,
+ &l_reg.word64,
+ l_reqSize,
+ DEVICE_SCOM_ADDRESS(EXPLR_MMIO_MCFGERR));
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_mmio, ERR_MRK
+ "determineExpCallouts: getscom(MCFGERR) failed"
+ " on OCMB[0x%08x]", get_huid(i_expTarget));
+ break;
+ }
+
+ TRACFCOMP(g_trac_mmio,
+ "determineExpCallouts: MCFGERR: 0x%016llx on"
+ " OCMB[0x%08x]", l_reg.word64, get_huid(i_expTarget));
+
+ // Extract the OCAPI response code from the register
+ switch(l_reg.resp_code)
+ {
+ // Firmware Errors
+ case OCAPI_UNSUPPORTED_OP_LENGTH:
+ case OCAPI_BAD_ADDRESS:
+ l_fwFailure = true;
+ break;
+
+ // This one could be caused by a bad address (FW) if there is
+ // a device/function mismatch. Otherwise, it's bad HW.
+ case OCAPI_FAILED:
+ if(l_reg.dev_func_mismatch)
+ {
+ l_fwFailure = true;
+ break;
+ }
+ break;
+
+ // Everything else is HW failure
+ default:
+ break;
+ }
+
+ // Dump some regs specific to config failures
+ l_regDump.addDataBuffer(&l_reg.word64, sizeof(l_reg.word64),
+ DEVICE_SCOM_ADDRESS(EXPLR_MMIO_MCFGERR));
+ l_regDump.addData(DEVICE_SCOM_ADDRESS(EXPLR_MMIO_MCFGERRA));
+ break;
+ }
+
+ // We were accessing a SCOM reg, MSCC reg, or SRAM
+
+ pib2gifErrorReg_t l_pib2gif;
+ gif2pcbErrorReg_t l_gif2pcb;
+
+ TRACFCOMP(g_trac_mmio,
+ "determineExpCallouts: getting callouts for failed MMIO space"
+ " transaction on OCMB[0x%08x]", get_huid(i_expTarget));
+
+ // Read the PIB2GIF error reg
+ // NOTE: This register is ONLY accessible through MMIO path, not I2C.
+ l_reqSize = sizeof(l_pib2gif.word64);
+ l_err = DeviceFW::deviceRead(
+ i_expTarget,
+ &l_pib2gif.word64,
+ l_reqSize,
+ DEVICE_SCOM_ADDRESS(EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG));
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_mmio, ERR_MRK
+ "determineExpCallouts: getscom(PIB2GIF_ERROR_REG) failed"
+ " on OCMB[0x%08x]", get_huid(i_expTarget));
+ break;
+ }
+
+ TRACFCOMP(g_trac_mmio,
+ "determineExpCallouts: PIB2GIF_ERROR_REG: 0x%016llx"
+ " on OCMB[0x%08x]", l_pib2gif.word64, get_huid(i_expTarget));
+
+ // The pib2gif error register contains a copy of the gif2pcb error reg.
+ // No need to read it again, just copy it into our struct.
+ l_gif2pcb.word64 = 0;
+ l_gif2pcb.used_bits = l_pib2gif.gif2pcb_error;
+
+ TRACFCOMP(g_trac_mmio,
+ "determineExpCallouts: GIF2PCB_ERROR_REG: 0x%016llx"
+ " on OCMB[0x%08x]", l_gif2pcb.word64, get_huid(i_expTarget));
+
+ // Check for software errors
+ if((l_pib2gif.invalid_address_error) ||
+ (l_gif2pcb.invalid_access) ||
+ (l_gif2pcb.pcb_err_code == PCB_INVALID_ADDRESS))
+ {
+ l_fwFailure = true;
+ }
+
+ // dump some regs specific to MMIO failures
+ l_regDump.addDataBuffer(&l_pib2gif.word64, sizeof(l_pib2gif.word64),
+ DEVICE_SCOM_ADDRESS(EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG));
+ l_regDump.addData(
+ DEVICE_SCOM_ADDRESS(EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG));
+ l_regDump.addData(DEVICE_SCOM_ADDRESS(EXPLR_MMIO_MMIOERR));
+ break;
+ }while(0);
+
+ if(!l_err)
+ {
+ // Dump some registers common to both types of transaction types
+ l_regDump.addData(DEVICE_SCOM_ADDRESS(EXPLR_MMIO_MFIR));
+ l_regDump.addData(DEVICE_SCOM_ADDRESS(EXPLR_MMIO_MFIRWOF));
+
+ // Add our register dump to the error log.
+ l_regDump.addToLog(i_err);
+ }
+
+ // Notify caller of HW or FW failure
+ o_fwFailure = l_fwFailure;
+ return l_err;
+}
+
+}; // End MMIOEXP namespace
diff --git a/src/usr/mmio/mmio_explorer.H b/src/usr/mmio/mmio_explorer.H
new file mode 100644
index 000000000..a7b6b1d04
--- /dev/null
+++ b/src/usr/mmio/mmio_explorer.H
@@ -0,0 +1,90 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/mmio/mmio_explorer.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __MMIO_EXPLORER_H
+#define __MMIO_EXPLORER_H
+
+/** @file mmio_explorer.H
+ * @brief Provides interface to perform Explorer MMIO operations
+ */
+
+#include <errl/errlentry.H>
+#include <targeting/common/target.H>
+
+namespace MMIOEXP
+{
+
+/**
+ *
+ * @brief Determine if the OCMB detected a failure on a specific MMIO
+ * transaction to the specified OCMB target.
+ *
+ * @param[in] i_expTarget Handle for the target OCMB chip.
+ * @param[in] i_va Virtual address of the transaction to check
+ * @param[in] i_accessLimit The byte range of the transaction
+ * @param[in] i_offset The offset of the config reg, scom reg, MSCC reg or
+ * SRAM to be accessed on the explorer chip.
+ * @param[in] i_opType The operation type (read or write)
+ * @param[out] o_errorAddressMatches Set to true if the OCMB chip detected a
+ * failure on our transaction.
+ * @param[out] o_errorAddressIsZero Set to true if no error has been detected
+ * yet.
+ * @return nullptr on succesful read of OCMB error status, non-null otherwise.
+ *
+ */
+errlHndl_t checkExpError(const TARGETING::TargetHandle_t i_expTarget,
+ const uint64_t i_va,
+ const uint64_t i_accessLimit,
+ const uint64_t i_offset,
+ DeviceFW::OperationType i_opType,
+ bool& o_errorAddressMatches,
+ bool& o_errorAddressIsZero);
+
+/**
+ *
+ * @brief Collect additional failure data from the target explorer chip and add
+ * appropriate FRU/Procedure callouts.
+ *
+ * @note Must call checkExpError to determine that a transaction failed before
+ * calling this function.
+ *
+ * @param[in] i_expTarget Handle of explorer to collect extra FFDC from
+ * @param[in] i_offset The offset of the config reg, scom reg, MSCC reg or
+ * SRAM that was accessed on the explorer chip.
+ * @param[in] i_opType The operation type (read or write)
+ * @param[in] i_err There error log for adding additional FFDC
+ * @param[out] o_fwFailure The failure was a firmware failure if true,
+ * otherwise, it was a hardware failure.
+ *
+ * @return non-nullptr if unable to determine failure type, nullptr otherwise.
+ */
+errlHndl_t determineExpCallouts(const TARGETING::TargetHandle_t i_expTarget,
+ const uint64_t i_offset,
+ DeviceFW::OperationType i_opType,
+ errlHndl_t i_err,
+ bool& o_fwFailure);
+
+}; // End MMIOEXP namespace
+
+#endif
diff --git a/src/usr/mmio/runtime/makefile b/src/usr/mmio/runtime/makefile
new file mode 100644
index 000000000..c61c68c39
--- /dev/null
+++ b/src/usr/mmio/runtime/makefile
@@ -0,0 +1,33 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/mmio/runtime/makefile $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+HOSTBOOT_RUNTIME = 1
+ROOTPATH = ../../../..
+MODULE = mmio_rt
+
+#include unique object modules
+OBJS += rt_mmio.o
+
+VPATH += ..
+include $(ROOTPATH)/config.mk
diff --git a/src/usr/mmio/runtime/rt_mmio.C b/src/usr/mmio/runtime/rt_mmio.C
new file mode 100644
index 000000000..620dff855
--- /dev/null
+++ b/src/usr/mmio/runtime/rt_mmio.C
@@ -0,0 +1,108 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/mmio/runtime/rt_mmio.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// @file src/usr/mmio/runtime/rt_mmio.C
+// @brief Runtime mmio operations -- particularly for scom operations
+
+#include "../mmio.H"
+#include <scom/runtime/rt_scomif.H>
+#include <devicefw/driverif.H>
+#include <errl/errlentry.H>
+#include <limits.h>
+#include <usr/mmio/mmio_reasoncodes.H>
+
+// Trace definition
+trace_desc_t* g_trac_mmio = NULL;
+TRAC_INIT(&g_trac_mmio, MMIO_COMP_NAME, 2*KILOBYTE, TRACE::BUFFER_SLOW);
+
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
+
+namespace MMIO
+{
+// Direct OCMB reads and writes to the device's memory mapped memory.
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::MMIO,
+ TARGETING::TYPE_OCMB_CHIP,
+ ocmbMmioPerformOp);
+
+/*******************************************************************************
+ *
+ * See comments in header file
+ *
+ */
+errlHndl_t ocmbMmioPerformOp(DeviceFW::OperationType i_opType,
+ TARGETING::TargetHandle_t i_ocmbTarget,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ va_list i_args)
+{
+ errlHndl_t l_err = nullptr;
+ uint64_t l_offset = va_arg(i_args, uint64_t);
+
+ TRACUCOMP(g_trac_mmio, ENTER_MRK"runtime ocmbMmioPerformOp");
+ TRACUCOMP(g_trac_mmio, INFO_MRK"op=%d, target=0x%.8X",
+ i_opType, TARGETING::get_huid(i_ocmbTarget));
+ TRACUCOMP(g_trac_mmio, INFO_MRK"buffer=%p, length=%d, accessType=%ld",
+ io_buffer, io_buflen, i_accessType);
+ TRACUCOMP(g_trac_mmio, INFO_MRK"offset=0x%lX", l_offset);
+
+ // Verify offset is within scom mmio range
+ if ( (l_offset >= (4 * GIGABYTE)) && (l_offset < (6 * GIGABYTE)) )
+ {
+ // send message to hypervisor level to do the mmio operation
+ l_err = SCOM::sendScomToHyp(i_opType, i_ocmbTarget,
+ l_offset, io_buffer);
+ }
+ else
+ {
+ // Only Scom range is supported for MMIO runtime context
+ /*@
+ * @errortype
+ * @moduleid MMIO::RT_OCMB_MMIO_PERFORM_OP
+ * @reasoncode MMIO::RC_INVALID_OFFSET
+ * @userdata1[0:31] Target huid
+ * @userdata1[32:63] Data Offset
+ * @userdata2[0:31] Operation Type
+ * @userdata2[32:63] Buffer Length
+ * @devdesc Invalid offset, requested
+ * address was out of range for a MMIO operation.
+ * @custdesc Unexpected memory subsystem firmware error.
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MMIO::RT_OCMB_MMIO_PERFORM_OP,
+ MMIO::RC_INVALID_OFFSET,
+ TWO_UINT32_TO_UINT64(
+ TARGETING::get_huid(i_ocmbTarget),
+ l_offset),
+ TWO_UINT32_TO_UINT64(i_opType, io_buflen),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ }
+
+ return l_err;
+}
+
+}; // end namespace MMIO
diff --git a/src/usr/mmio/test/makefile b/src/usr/mmio/test/makefile
index 133f3ca44..3a9af5d71 100644
--- a/src/usr/mmio/test/makefile
+++ b/src/usr/mmio/test/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2011,2018
+# Contributors Listed Below - COPYRIGHT 2011,2019
# [+] International Business Machines Corp.
#
#
@@ -25,6 +25,11 @@
ROOTPATH = ../../../..
MODULE = testmmio
+
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/ocmb/explorer/common/include/
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/
+EXTRAINCDIR += ${ROOTPATH}/src/usr/expaccess/
+
TESTS = *.H
diff --git a/src/usr/mmio/test/mmiotest.H b/src/usr/mmio/test/mmiotest.H
index f7abd7816..984e94925 100644
--- a/src/usr/mmio/test/mmiotest.H
+++ b/src/usr/mmio/test/mmiotest.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,83 +27,238 @@
#include <errl/errlentry.H>
#include <limits.h>
#include <devicefw/driverif.H>
-#include <mmio/mmio.H>
+#include "../mmio.H"
+#include <targeting/common/utilFilter.H>
+#include <explorer_scom_addresses.H>
+#include <exp_oc_regs.H>
+#include <sys/mmio.h>
+#include <utils/chipids.H>
+#include <test/exptest_utils.H>
-extern trace_desc_t* g_trac_mmio;
+#define SCOM2MMIO_ADDR(_ADDR) (EXPLR_IB_MMIO_OFFSET | (_ADDR << 3))
+#define CNFG2MMIO_ADDR(_ADDR) (EXPLR_IB_CONFIG_OFFSET | _ADDR)
+#define BYTESWAP64(_DATA) (__builtin_bswap64(_DATA))
+
+static const uint64_t EXPLR_IB_CONFIG_OFFSET = 0x0000000000000000ull;
+static const uint64_t EXPLR_IB_MMIO_OFFSET = 0x0000000100000000ull; // 4GB
+
+// NOTE: changing this address requires changes
+// to src/build/simics/standalone.simics
+static const uint64_t EXPLR_INVALID_SCOM_ADDR =
+ EXPLR_TP_MB_UNIT_TOP_TRACE_TRDATA_CONFIG_0;
+
+using namespace TARGETING;
class MmioTest : public CxxTest::TestSuite
{
public:
/**
- * @brief Test valid MMIO calls
+ * @brief Test MMIO calls
*/
- void test_Valid(void)
+ void testExplrMMIO(void)
{
- TRACFCOMP( g_trac_mmio, "MmioTest::test_Valid> Start" );
+ TS_INFO("testExplrMMIO> Start" );
- uint64_t fails = 0;
- uint64_t total = 0;
errlHndl_t l_err = nullptr;
- uint64_t regdata = 0;
- size_t op_size = sizeof(uint64_t);
-
-// TODO RTC 202533 - enable this test once the Axone model is IPLing
-// successfully in Simics.
-#if 0
- // Get OCMB target, return if there is no OCMB
- TARGETING::TargetHandle_t ocmb_target = nullptr;
- TARGETING::TargetHandleList ocmb_target_list;
- getAllChips(ocmb_target_list, TARGETING::TYPE_OCMB_CHIP);
- if (ocmb_target_list.size() == 0)
+ uint32_t regdata4 = 0;
+ size_t op_size = 0;
+ uint64_t l_buffer64;
+
+ // Needed since the device operations could be using inband communication in error path
+ HB_MUTEX_SERIALIZE_TEST_LOCK_ATTR l_mutex = exptest::getTestMutex();
+ if (l_mutex == nullptr)
{
- TRACFCOMP(g_trac_fsiscom, "MmioTest::test_Valid> Target is NULL");
- TS_INFO("MmioTest::test_Valid> Target is NULL");
+ TS_FAIL("testExplrMMIO: unable to get test mutex");
return;
}
- ocmb_target = ocmb_target_list[0];
-
- // read
- ++total;
- l_err = MMIO::mmioPerformOp(
- DeviceFW::READ,
- ocmb_target,
- &regdata,
- op_size,
- 0x0,
- op_size);
- if(l_err != nullptr)
- {
- TRACFCOMP(g_trac_mmio,
- "MmioTest::test_Valid> Error for read, RC=0x%04X",
- ERRL_GETRC_SAFE(l_err));
- TS_FAIL("MmioTest::test_Valid> Error for read, RC=0x%04X",
- ERRL_GETRC_SAFE(l_err));
- ++fails;
- errlCommit(l_err, MMIO_COMP_ID);
- }
- // write
- ++total;
- l_err = MMIO::mmioPerformOp(
- DeviceFW::WRITE,
- ocmb_target,
- &regdata,
- op_size,
- 0x08,
- op_size);
- if(l_err != nullptr)
+ // >> atomic section
+ mutex_lock(l_mutex);
+
+ TargetHandle_t explr_target = nullptr;
+
+ do {
+
+ // Get OCMB target, return if there is no OCMB
+ TargetHandleList ocmb_target_list;
+ getAllChips(ocmb_target_list, TYPE_OCMB_CHIP);
+ if (ocmb_target_list.size() == 0)
+ {
+ TS_INFO("testExplrMMIO> No OCMB targets found. Exiting.");
+ break;
+ }
+ explr_target = ocmb_target_list[0];
+ if(explr_target->getAttr<ATTR_CHIP_ID>() !=
+ POWER_CHIPID::EXPLORER_16)
+ {
+ TS_INFO("testExplrMMIO> No explorer targets found. Exiting.");
+ break;
+ }
+
+ // Make sure we're using MMIO to this explorer chip
+ exptest::enableInbandScomsOcmb(explr_target);
+
+ // valid read from config space register
+ op_size = sizeof(regdata4);
+ l_err = DeviceFW::deviceRead(
+ explr_target,
+ &regdata4,
+ op_size,
+ DEVICE_MMIO_ADDRESS(
+ CNFG2MMIO_ADDR(EXPLR_OC_O0MBIT_O0DID_LSB),
+ op_size));
+
+ if(l_err != nullptr)
+ {
+ errlCommit(l_err, CXXTEST_COMP_ID);
+ TS_FAIL("testExplrMMIO> Error for config read, RC=0x%04X",
+ ERRL_GETRC_SAFE(l_err));
+ }
+
+ // valid write to config space register
+ op_size = sizeof(regdata4);
+ l_err = DeviceFW::deviceWrite(
+ explr_target,
+ &regdata4,
+ op_size,
+ DEVICE_MMIO_ADDRESS(
+ CNFG2MMIO_ADDR(EXPLR_OC_O0CCD_LSB),
+ op_size));
+ if(l_err != nullptr)
+ {
+ errlCommit(l_err, CXXTEST_COMP_ID);
+ TS_FAIL("testExplrMMIO> Error for config write, RC=0x%04X",
+ ERRL_GETRC_SAFE(l_err));
+ }
+
+ // 1st valid write to SCOM register (also sets up
+ // tests for forcing HW read/write failures)
+ // Set the PCB error bits (8:10) to binary 100, which means
+ // 'invalid address'
+ // NOTE: must byteswap to little endian before writing
+ uint64_t GIF2PCB_INVALID_SCOM_ADDR_ERROR = 0x0080000000000000ull;
+ l_buffer64 = BYTESWAP64(GIF2PCB_INVALID_SCOM_ADDR_ERROR);
+ op_size = sizeof(l_buffer64);
+ l_err = DeviceFW::deviceWrite(
+ explr_target,
+ &l_buffer64,
+ op_size,
+ DEVICE_MMIO_ADDRESS(
+ SCOM2MMIO_ADDR(
+ EXPLR_TP_MB_UNIT_TOP_GIF2PCB_ERROR_REG),
+ op_size));
+
+ if(l_err != nullptr)
+ {
+ errlCommit(l_err, CXXTEST_COMP_ID);
+ TS_FAIL("testExplrMMIO> Error for gif2pcb write, RC=0x%04X",
+ ERRL_GETRC_SAFE(l_err));
+ break;
+ }
+
+ // 2nd valid write to SCOM register (also sets up
+ // tests for forcing HW read/write failures)
+ // This register should contain a copy of the GIF2PCB error register
+ // starting at bit 32
+ // NOTE: must byteswap to little endian before writing data
+ uint64_t PIB2GIF_INVALID_SCOM_ADDR_ERROR =
+ 0x0000000000000000ull |
+ ((GIF2PCB_INVALID_SCOM_ADDR_ERROR &
+ 0xffffc00000000000ull) >> 32);
+ l_buffer64 = BYTESWAP64(PIB2GIF_INVALID_SCOM_ADDR_ERROR);
+ op_size = sizeof(l_buffer64);
+ l_err = DeviceFW::deviceWrite(
+ explr_target,
+ &l_buffer64,
+ op_size,
+ DEVICE_MMIO_ADDRESS(
+ SCOM2MMIO_ADDR(
+ EXPLR_TP_MB_UNIT_TOP_PIB2GIF_ERROR_REG),
+ op_size));
+
+ if(l_err != nullptr)
+ {
+ errlCommit(l_err, CXXTEST_COMP_ID);
+ TS_FAIL("testExplrMMIO> Error for pib2gif write, RC=0x%04X",
+ ERRL_GETRC_SAFE(l_err));
+ break;
+ }
+
+ // Write to an "invalid" scom address. Should
+ // return with failure (now that we've set up the error regs).
+ // NOTE: Also, writing MMIO_OCMB_UE_DETECTED to this register
+ // sets up the following read to the same register
+ // to fail.
+ l_buffer64 = MMIO_OCMB_UE_DETECTED;
+ op_size = sizeof(l_buffer64);
+ l_err = DeviceFW::deviceWrite(
+ explr_target,
+ &l_buffer64,
+ op_size,
+ DEVICE_MMIO_ADDRESS(
+ SCOM2MMIO_ADDR(EXPLR_INVALID_SCOM_ADDR),
+ op_size));
+ if(l_err == nullptr)
+ {
+ ScomSwitches l_switches =
+ explr_target->getAttr<ATTR_SCOM_SWITCHES>();
+ TS_INFO("testExplrMMIO: Current SCOM mode: %s",
+ (l_switches.useInbandScom)? "MMIO": "I2C");
+ TS_FAIL("testExplrMMIO> "
+ "did not recieve expected failure on mmio write");
+ break;
+ }
+ else
+ {
+ TS_INFO("testExplrMMIO> "
+ "received expected failure on mmio write");
+ errlCommit(l_err, CXXTEST_COMP_ID);
+ }
+
+ // Re-enable inband scoms after failure disables it
+ exptest::enableInbandScomsOcmb(explr_target);
+
+ // Read from an "invalid" scom address. Should
+ // return with failure (now that we've set up the error regs).
+ op_size = sizeof(l_buffer64);
+ l_err = DeviceFW::deviceRead(
+ explr_target,
+ &l_buffer64,
+ op_size,
+ DEVICE_MMIO_ADDRESS(
+ SCOM2MMIO_ADDR(EXPLR_INVALID_SCOM_ADDR),
+ op_size));
+
+ if(l_err == nullptr)
+ {
+ ScomSwitches l_switches =
+ explr_target->getAttr<ATTR_SCOM_SWITCHES>();
+ TS_INFO("testExplrMMIO> "
+ "data read from invalid address: 0x%016llx",
+ l_buffer64);
+ TS_INFO("testExplrMMIO: Current SCOM mode: %s",
+ (l_switches.useInbandScom)? "MMIO": "I2C");
+ TS_FAIL("testExplrMMIO> "
+ "did not recieve expected failure on mmio read");
+ }
+ else
+ {
+ TS_INFO("testExplrMMIO> "
+ "received expected failure on mmio read");
+ errlCommit(l_err, CXXTEST_COMP_ID);
+ }
+
+ } while (0);
+
+ // Re-enable inband scoms after failure disables it
+ if(explr_target != nullptr)
{
- TRACFCOMP(g_trac_mmio,
- "MmioTest::test_Valid> Error for write, RC=0x%04X",
- ERRL_GETRC_SAFE(l_err));
- TS_FAIL("MmioTest::test_Valid> Error for write, RC=0x%04X",
- ERRL_GETRC_SAFE(l_err));
- ++fails;
- errlCommit(l_err, MMIO_COMP_ID);
+ exptest::enableInbandScomsOcmb(explr_target);
}
-#endif
- TRACFCOMP(g_trac_mmio, "Mmio::test_Valid> %d/%d fails", fails, total);
+ // << atomic section
+ mutex_unlock(l_mutex);
+ TS_INFO("testExplrMMIO> Done");
};
};
diff --git a/src/usr/pnor/ast_mboxdd.C b/src/usr/pnor/ast_mboxdd.C
index 5b6e58300..9a7c45e9b 100644
--- a/src/usr/pnor/ast_mboxdd.C
+++ b/src/usr/pnor/ast_mboxdd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -51,7 +51,6 @@
#include <initservice/initserviceif.H>
#include <util/align.H>
#include <lpc/lpcif.H>
-#include <config.h>
// Initialized in pnorrp.C
extern trace_desc_t* g_trac_pnor;
diff --git a/src/usr/pnor/ast_mboxdd.H b/src/usr/pnor/ast_mboxdd.H
index 2d1aa48ad..44c745cab 100644
--- a/src/usr/pnor/ast_mboxdd.H
+++ b/src/usr/pnor/ast_mboxdd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -26,7 +26,6 @@
#define __AST_MBOXDD_H
#include <limits.h>
-#include <config.h>
/** @file ast_mboxdd.H
* @brief Provides the interfaces Aspeed MBOX hardware
diff --git a/src/usr/pnor/norflash.H b/src/usr/pnor/norflash.H
index 29ac2f8f0..e7e61f389 100644
--- a/src/usr/pnor/norflash.H
+++ b/src/usr/pnor/norflash.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2016 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -25,7 +25,6 @@
/* IBM_PROLOG_END_TAG */
#ifndef __PNOR_NORFLASH_H
#define __PNOR_NORFLASH_H
-#include <config.h>
#include <errl/errlentry.H>
class SfcDD;
diff --git a/src/usr/pnor/pnor_common.C b/src/usr/pnor/pnor_common.C
index 3b642a6e6..41f17ff7e 100644
--- a/src/usr/pnor/pnor_common.C
+++ b/src/usr/pnor/pnor_common.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -34,7 +34,6 @@
#include <initservice/initserviceif.H>
#include <util/align.H>
#include <errl/errlmanager.H>
-#include <config.h> // @FIXME RTC 132398
#include <secureboot/trustedbootif.H>
#include <devicefw/driverif.H>
@@ -144,12 +143,16 @@ errlHndl_t PNOR::parseTOC( uint8_t* i_tocBuffer,SectionData_t * o_TOC,
// Zero out my table
PNOR::initializeSections(o_TOC);
- uint32_t l_errCode = 0;
- ffs_hdr* l_ffs_hdr = NULL;
+ uint32_t l_errCode(0);
+ ffs_hdr* l_ffs_hdr(reinterpret_cast<ffs_hdr*>(i_tocBuffer));
TRACDCOMP(g_trac_pnor, "PNOR::parseTOC verifying TOC");
+ if (!l_ffs_hdr)
+ {
+ l_errCode = PNOR::BUFF_IS_NULL;
+ l_ffs_hdr = nullptr;
+ }
- PNOR::checkForNullBuffer(i_tocBuffer, l_errCode, l_ffs_hdr);
//Check if the buffer is null
if(l_errCode != NO_ERROR)
{
@@ -160,16 +163,16 @@ errlHndl_t PNOR::parseTOC( uint8_t* i_tocBuffer,SectionData_t * o_TOC,
"Null TOC Buffer found while checking TOC"
" during pnor initialization");
/*@
- * @errortype
- * @moduleid PNOR::MOD_PNORRP_READTOC
- * @reasoncode PNOR::RC_NULL_TOC_BUFFER
- * @userdata1 Address of toc buffer
- * @userdata2 Error code
- * @devdesc Expected buffer to have contents of TOC,
- * instead was NULL
- * @custdesc A problem occurred while reading
- * Processor NOR flash partition table
- */
+ * @errortype
+ * @moduleid PNOR::MOD_PNORRP_READTOC
+ * @reasoncode PNOR::RC_NULL_TOC_BUFFER
+ * @userdata1 Address of toc buffer
+ * @userdata2 Error code
+ * @devdesc Expected buffer to have contents of TOC,
+ * instead was NULL
+ * @custdesc A problem occurred while reading
+ * Processor NOR flash partition table
+ */
l_errhdl = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
PNOR::MOD_PNORRP_READTOC,
@@ -197,15 +200,16 @@ errlHndl_t PNOR::parseTOC( uint8_t* i_tocBuffer,SectionData_t * o_TOC,
"PNOR::parseTOC Found checksum error in TOC's header"
" during pnor initialization");
- /* @errortype
- * @moduleid PNOR::MOD_PNORRP_READTOC
- * @reasoncode PNOR::RC_TOC_HDR_CHECKSUM_ERR
- * @userdata1 Address of toc buffer
- * @userdata2 Error Code
- * @devdesc Hdr of TOC of PNOR failed checksum
- * @custdesc A problem occurred while reading
- * Processor NOR flash partition table
- */
+ /*@
+ * @errortype
+ * @moduleid PNOR::MOD_PNORRP_READTOC
+ * @reasoncode PNOR::RC_TOC_HDR_CHECKSUM_ERR
+ * @userdata1 Address of toc buffer
+ * @userdata2 Error Code
+ * @devdesc Hdr of TOC of PNOR failed checksum
+ * @custdesc A problem occurred while reading
+ * Processor NOR flash partition table
+ */
l_errhdl = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
PNOR::MOD_PNORRP_READTOC,
@@ -230,15 +234,16 @@ errlHndl_t PNOR::parseTOC( uint8_t* i_tocBuffer,SectionData_t * o_TOC,
assert(i_pnorInitialized,
"PNOR::parseTOC Error found parsing hdr of TOC"
" during pnor initialization");
- /* @errortype
- * @moduleid PNOR::MOD_PNORRP_READTOC
- * @reasoncode PNOR::RC_BAD_TOC_HEADER
- * @userdata1 Address of toc buffer
- * @userdata2 Error Code
- * @devdesc Hdr of TOC of PNOR failed series of tests
- * @custdesc A problem occurred while reading
- * Processor NOR flash partition table
- */
+ /*@
+ * @errortype
+ * @moduleid PNOR::MOD_PNORRP_READTOC
+ * @reasoncode PNOR::RC_BAD_TOC_HEADER
+ * @userdata1 Address of toc buffer
+ * @userdata2 Error Code
+ * @devdesc Hdr of TOC of PNOR failed series of tests
+ * @custdesc A problem occurred while reading
+ * Processor NOR flash partition table
+ */
l_errhdl = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
PNOR::MOD_PNORRP_READTOC,
@@ -276,15 +281,16 @@ errlHndl_t PNOR::parseTOC( uint8_t* i_tocBuffer,SectionData_t * o_TOC,
"PNOR::parseTOC parseEntries returned an error code"
" during pnor initialization");
- /* @errortype
- * @moduleid PNOR::MOD_PNORRP_READTOC
- * @reasoncode PNOR::RC_PNOR_PARSE_ENTRIES_ERR
- * @userdata1 Address of toc buffer
- * @userdata2 Error Code
- * @devdesc Error while parsing pnor TOC entries
- * @custdesc A problem occurred while reading
- * Processor NOR flash partition table
- */
+ /*@
+ * @errortype
+ * @moduleid PNOR::MOD_PNORRP_READTOC
+ * @reasoncode PNOR::RC_PNOR_PARSE_ENTRIES_ERR
+ * @userdata1 Address of toc buffer
+ * @userdata2 Error Code
+ * @devdesc Error while parsing pnor TOC entries
+ * @custdesc A problem occurred while reading
+ * Processor NOR flash partition table
+ */
l_errhdl = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
PNOR::MOD_PNORRP_READTOC,
diff --git a/src/usr/pnor/pnor_ipmidd.C b/src/usr/pnor/pnor_ipmidd.C
index 078195dad..43df5adfe 100644
--- a/src/usr/pnor/pnor_ipmidd.C
+++ b/src/usr/pnor/pnor_ipmidd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -58,7 +58,6 @@
#include <initservice/initserviceif.H>
#include <util/align.H>
#include <lpc/lpcif.H>
-#include <config.h>
#include "sfcdd.H"
#include <ipmi/ipmiif.H>
diff --git a/src/usr/pnor/pnor_ipmidd.H b/src/usr/pnor/pnor_ipmidd.H
index fc843db6a..5c99607fe 100644
--- a/src/usr/pnor/pnor_ipmidd.H
+++ b/src/usr/pnor/pnor_ipmidd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -31,7 +31,6 @@
*/
#include <limits.h>
-#include <config.h>
#include "pnorif.H"
diff --git a/src/usr/pnor/pnor_mboxdd.C b/src/usr/pnor/pnor_mboxdd.C
index a156ffb8f..92819143d 100644
--- a/src/usr/pnor/pnor_mboxdd.C
+++ b/src/usr/pnor/pnor_mboxdd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -54,7 +54,6 @@
#include <initservice/initserviceif.H>
#include <util/align.H>
#include <lpc/lpcif.H>
-#include <config.h>
#include "sfcdd.H"
// Initialized in pnorrp.C
diff --git a/src/usr/pnor/pnor_mboxdd.H b/src/usr/pnor/pnor_mboxdd.H
index 16105efe2..6095dce35 100644
--- a/src/usr/pnor/pnor_mboxdd.H
+++ b/src/usr/pnor/pnor_mboxdd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -26,7 +26,6 @@
#define __PNOR_MBOXDD_H
#include <limits.h>
-#include <config.h>
#include "pnorif.H"
namespace PNOR
diff --git a/src/usr/pnor/pnor_sfcdd.C b/src/usr/pnor/pnor_sfcdd.C
index fe3f0cbae..9acea977b 100644
--- a/src/usr/pnor/pnor_sfcdd.C
+++ b/src/usr/pnor/pnor_sfcdd.C
@@ -53,7 +53,6 @@
#include <initservice/initserviceif.H>
#include <util/align.H>
#include <lpc/lpcif.H>
-#include <config.h>
#include "sfcdd.H"
/*****************************************************************************/
@@ -251,7 +250,7 @@ errlHndl_t PnorSfcDD::writeFlash(void* i_buffer,
size_t& io_buflen,
uint64_t i_address)
{
- TRACFCOMP(g_trac_pnor, ENTER_MRK"PnorSfcDD::writeFlash(i_address=0x%llx)> ", i_address);
+ TRACDCOMP(g_trac_pnor, ENTER_MRK"PnorSfcDD::writeFlash(i_address=0x%llx)> ", i_address);
errlHndl_t l_err = NULL;
do{
@@ -339,7 +338,7 @@ errlHndl_t PnorSfcDD::writeFlash(void* i_buffer,
{
io_buflen = 0;
}
- TRACFCOMP(g_trac_pnor,EXIT_MRK"PnorSfcDD::writeFlash(i_address=0x%llx)> io_buflen=%.8X", i_address, io_buflen);
+ TRACDCOMP(g_trac_pnor,EXIT_MRK"PnorSfcDD::writeFlash(i_address=0x%llx)> io_buflen=%.8X", i_address, io_buflen);
return l_err;
}
diff --git a/src/usr/pnor/pnor_sfcdd.H b/src/usr/pnor/pnor_sfcdd.H
index bfd3140a7..ba7f0aa0d 100644
--- a/src/usr/pnor/pnor_sfcdd.H
+++ b/src/usr/pnor/pnor_sfcdd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -27,7 +27,6 @@
#define __PNOR_PNORDD_H
#include <limits.h>
-#include <config.h>
#include <pnor/pnor_const.H>
namespace PNOR { class UdPnorDDParms; }
diff --git a/src/usr/pnor/pnor_utils.C b/src/usr/pnor/pnor_utils.C
index cd7c9f98f..83ff90450 100644
--- a/src/usr/pnor/pnor_utils.C
+++ b/src/usr/pnor/pnor_utils.C
@@ -53,7 +53,6 @@ extern trace_desc_t* g_trac_pnor;
#include "common/ffs_hb.H"
#include <util/align.H>
-#include <config.h>
#include <securerom/ROM.H>
#include <pnor/pnorif.H>
@@ -110,30 +109,6 @@ void PNOR::initializeSections(PNOR::SectionData_t io_toc[NUM_SECTIONS])
}
}
-
-
-/**
- * @brief Ensure the buffer is not NULL, if it is, then return
- * the appropriate err code from the o_errCode param.
- * if the buffer is not NULL then cast it to a ffs_hdr
- * and return that out through the respective o_param
- */
-void PNOR::checkForNullBuffer(uint8_t* i_tocBuffer,
- uint32_t& o_errCode,
- ffs_hdr*& o_ffs_hdr)
-{
- if(!i_tocBuffer)
- {
- o_errCode |= BUFF_IS_NULL;
- o_ffs_hdr = NULL;
- }
- else
- {
- o_ffs_hdr = (ffs_hdr*)i_tocBuffer;
- }
-}
-
-
/**
* @brief Perform a series of checks on the header of the table of contents
* These checks include: looking for valid magic #, valid block size,
@@ -369,6 +344,7 @@ bool PNOR::isEnforcedSecureSection(const uint32_t i_section)
i_section == HB_DATA ||
i_section == SBE_IPL ||
i_section == PAYLOAD ||
+ i_section == BOOTKERNEL ||
i_section == SBKT ||
i_section == OCC ||
i_section == HCODE ||
@@ -378,7 +354,8 @@ bool PNOR::isEnforcedSecureSection(const uint32_t i_section)
i_section == MEMD ||
i_section == CAPP ||
i_section == TESTLOAD ||
- i_section == VERSION;
+ i_section == VERSION ||
+ i_section == OCMBFW;
#endif
#else
return false;
@@ -415,7 +392,6 @@ const char * PNOR::SectionIdToString( uint32_t i_secIdIndex )
"part", /**< PNOR::TOC : Table of Contents */
#ifndef BOOTLOADER
"HBI", /**< PNOR::HB_EXT_CODE : Hostboot Extended Image */
- "GLOBAL", /**< PNOR::GLOBAL_DATA : Global Data */
#endif
"HBB", /**< PNOR::HB_BASE_CODE : Hostboot Base Image */
#ifndef BOOTLOADER
@@ -451,6 +427,7 @@ const char * PNOR::SectionIdToString( uint32_t i_secIdIndex )
"HDAT", /**< PNOR::HDAT : Hdat Data */
"EECACHE", /**< PNOR::EECACHE : Cached data from various EEPROMs */
"OCMBFW", /**< PNOR::OCMBFW : OCMB image */
+ "BOOTKERNEL", /**< PNOR::BOOTKERNEL : OPAL == petitboot,PHYP == PowerVM */
#endif
};
diff --git a/src/usr/pnor/pnor_utils.H b/src/usr/pnor/pnor_utils.H
index 53a402f97..d529c8c6c 100644
--- a/src/usr/pnor/pnor_utils.H
+++ b/src/usr/pnor/pnor_utils.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -29,7 +29,6 @@
#include <pnor/pnor_const.H>
#include "limits.h"
#include "ffs.h"
-#include <config.h>
#ifndef BOOTLOADER
#include <errl/errlentry.H>
diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C
index af6ccf3fa..fa35be627 100644
--- a/src/usr/pnor/pnorrp.C
+++ b/src/usr/pnor/pnorrp.C
@@ -44,7 +44,6 @@
#include <kernel/console.H>
#include <endian.h>
#include <util/align.H>
-#include <config.h>
#include <pnor/pnorif.H>
#include "pnor_common.H"
#include <hwas/common/hwasCallout.H>
@@ -214,6 +213,13 @@ void PnorRP::init( errlHndl_t &io_rtaskRetErrl )
#ifdef CONFIG_SECUREBOOT
// Extend the base image to the TPM, regardless of how it was obtained
l_errl = TRUSTEDBOOT::extendBaseImage();
+
+ // Cache the VERSION partition data for future use by the errl commit
+ // code.
+ if(!l_errl)
+ {
+ l_errl = ERRORLOG::cacheVersionPartition();
+ }
#endif
#endif
}
@@ -522,6 +528,7 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
#ifdef CONFIG_SECUREBOOT
o_info.secure = iv_TOC[id].secure;
+ o_info.size = iv_TOC[id].size;
o_info.secureProtectedPayloadSize = 0; // for non secure sections
// the protected payload size
// defaults to zero
@@ -591,6 +598,17 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
// was done previously in pnor_common.C
o_info.size -= PAGESIZE;
+ // Need to change size to accommodate for hash table
+ if (l_conHdr.sb_flags()->sw_hash)
+ {
+ o_info.vaddr += payloadTextSize;
+ // Hash page table needs to use containerSize as the base
+ // and subtract off header and hash table size
+ o_info.size = l_conHdr.totalContainerSize() - PAGE_SIZE -
+ payloadTextSize;
+ o_info.hasHashTable = true;
+ }
+
// cache the value in SectionInfo struct so that we can
// parse the container header less often
o_info.secureProtectedPayloadSize = payloadTextSize;
@@ -598,11 +616,11 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
else
#endif
{
+ o_info.size = iv_TOC[id].size;
o_info.vaddr = iv_TOC[id].virtAddr;
}
o_info.flashAddr = iv_TOC[id].flashAddr;
- o_info.size = iv_TOC[id].size;
o_info.eccProtected = ((iv_TOC[id].integrity & FFS_INTEG_ECC_PROTECT)
!= 0) ? true : false;
o_info.sha512Version = ((iv_TOC[id].version & FFS_VERS_SHA512)
diff --git a/src/usr/pnor/pnorrp.H b/src/usr/pnor/pnorrp.H
index 1fe3c088c..650b62126 100644
--- a/src/usr/pnor/pnorrp.H
+++ b/src/usr/pnor/pnorrp.H
@@ -34,7 +34,6 @@
#include <map>
#include "pnor_common.H"
#include "ffs.h"
-#include <config.h>
#include "pnor_utils.H"
/**
diff --git a/src/usr/pnor/runtime/rt_pnor.C b/src/usr/pnor/runtime/rt_pnor.C
index f3e969f2e..0d40a60c3 100644
--- a/src/usr/pnor/runtime/rt_pnor.C
+++ b/src/usr/pnor/runtime/rt_pnor.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -29,7 +29,7 @@
#include <initservice/taskargs.H>
#include <initservice/initserviceif.H>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <runtime/interface.h> // g_hostInterfaces, postInitCalls_t
#include <pnor/pnorif.H>
@@ -42,7 +42,6 @@
#include <util/align.H>
#include <runtime/customize_attrs_for_payload.H>
#include <securerom/ROM.H>
-#include <config.h>
#include "../pnor_utils.H"
#include <runtime/common/runtime_utils.H>
@@ -924,7 +923,7 @@ errlHndl_t RtPnor::getMasterProcId()
TRACFCOMP(g_trac_pnor, "RtPnor::getMasterProcId: queryMasterProcChipTargetHandle failed");
break;
}
- l_err = RT_TARG::getRtTarget(l_masterProc, iv_masterProcId);
+ l_err = TARGETING::getRtTarget(l_masterProc, iv_masterProcId);
if (l_err)
{
TRACFCOMP(g_trac_pnor, "RtPnor::getMasterProcId: getRtTarget failed for master proc");
diff --git a/src/usr/pnor/sfc_ast2400.H b/src/usr/pnor/sfc_ast2400.H
index c83db94c0..937435332 100644
--- a/src/usr/pnor/sfc_ast2400.H
+++ b/src/usr/pnor/sfc_ast2400.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2016 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -31,7 +31,6 @@
#include <errl/errlentry.H>
#include "sfcdd.H"
#include "sfc_ast2X00.H"
-#include <config.h>
/** @file sfc_ast2400.H
* @brief Provides the logic to access and configure the
diff --git a/src/usr/pnor/sfc_ast2500.H b/src/usr/pnor/sfc_ast2500.H
index 73f07c58a..83607a5b9 100644
--- a/src/usr/pnor/sfc_ast2500.H
+++ b/src/usr/pnor/sfc_ast2500.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -30,7 +30,6 @@
#include <errl/errlentry.H>
#include "sfcdd.H"
#include "sfc_ast2X00.H"
-#include <config.h>
/** @file sfc_ast2500.H
* @brief Provides the logic to access and configure the
diff --git a/src/usr/pnor/sfc_ast2X00.H b/src/usr/pnor/sfc_ast2X00.H
index 2847b75d3..aceed1c30 100644
--- a/src/usr/pnor/sfc_ast2X00.H
+++ b/src/usr/pnor/sfc_ast2X00.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -29,7 +29,6 @@
#include <targeting/common/targetservice.H>
#include <errl/errlentry.H>
#include "sfcdd.H"
-#include <config.h>
/** @file sfc_ast2X00.H
* @brief Provides the base logic to access and configure the
diff --git a/src/usr/pnor/spnorrp.C b/src/usr/pnor/spnorrp.C
index 5b1ef5b03..fe2998756 100644
--- a/src/usr/pnor/spnorrp.C
+++ b/src/usr/pnor/spnorrp.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,7 +33,6 @@
#include <sys/mm.h>
#include <errno.h>
#include <util/align.H>
-#include <config.h>
#include "pnor_common.H"
#include <console/consoleif.H>
#include <secureboot/service.H>
@@ -41,6 +40,7 @@
#include <secureboot/trustedbootif.H>
#include <secureboot/header.H>
#include <sys/task.h>
+#include <arch/ppc.H>
extern trace_desc_t* g_trac_pnor;
@@ -363,6 +363,15 @@ uint64_t SPnorRP::verifySections(SectionId i_id,
PNOR::SectionIdToString(i_id));
}
+ // If hash table exists, need to adjust sizes
+ if (l_info.hasHashTable)
+ {
+ io_rec->hasHashTable = true;
+ l_info.vaddr -= l_info.secureProtectedPayloadSize;
+ l_info.size += l_info.secureProtectedPayloadSize;
+ io_rec->hashTableVaddr = l_info.vaddr;
+ }
+
l_info.vaddr -= PAGESIZE; // back up a page to expose the secure header
l_info.size += PAGESIZE; // add a page to size to account for the header
@@ -643,13 +652,23 @@ uint64_t SPnorRP::verifySections(SectionId i_id,
SHA512_DIGEST_LENGTH);
}
- // set permissions on the secured pages to writable
+ // set permissions to be writable
+ // in the case of HPT this is the header + HPT
+ // in the case of no HPT this is the header + text region
l_errhdl = setPermission(io_rec->secAddr, l_protectedSizeWithHdr,
WRITABLE);
- if(l_errhdl)
+ if (l_errhdl)
{
- TRACFCOMP(g_trac_pnor,"SPnorRP::verifySections set permissions "
- "failed on text section");
+ if (l_info.hasHashTable)
+ {
+ TRACFCOMP(g_trac_pnor, ERR_MRK"SPnorRP::verifySections set permissions "
+ "failed on header + hash page table");
+ }
+ else
+ {
+ TRACFCOMP(g_trac_pnor, ERR_MRK"SPnorRP::verifySections set permissions "
+ "failed on header + text section");
+ }
break;
}
@@ -691,10 +710,18 @@ uint64_t SPnorRP::verifySections(SectionId i_id,
break;
}
-
- l_errhdl = setPermission(io_rec->secAddr + l_protectedSizeWithHdr,
- unprotectedPayloadSize,
- WRITABLE | WRITE_TRACKED);
+ if (l_info.hasHashTable)
+ {
+ l_errhdl = setPermission(io_rec->secAddr + l_protectedSizeWithHdr,
+ unprotectedPayloadSize,
+ READ_ONLY);
+ }
+ else
+ {
+ l_errhdl = setPermission(io_rec->secAddr + l_protectedSizeWithHdr,
+ unprotectedPayloadSize,
+ WRITABLE | WRITE_TRACKED);
+ }
if(l_errhdl)
{
TRACFCOMP(g_trac_pnor,"SPnorRP::verifySections set permissions "
@@ -704,8 +731,11 @@ uint64_t SPnorRP::verifySections(SectionId i_id,
// Register the write tracked memory range to be flushed on
// shutdown.
- INITSERVICE::registerBlock(io_rec->secAddr + l_protectedSizeWithHdr,
- unprotectedPayloadSize, SPNOR_PRIORITY);
+ if (!l_info.hasHashTable)
+ {
+ INITSERVICE::registerBlock(io_rec->secAddr + l_protectedSizeWithHdr,
+ unprotectedPayloadSize, SPNOR_PRIORITY);
+ }
}
else
{
@@ -738,6 +768,83 @@ uint64_t SPnorRP::verifySections(SectionId i_id,
return l_rc;
}
+int64_t getHashPageTableIndex(const int64_t i_vaddr)
+{
+ return (i_vaddr / static_cast<int64_t>(PAGE_SIZE)) + 1;
+}
+
+
+PAGE_TABLE_ENTRY_t* getHashPageTableEntry(const int64_t i_vaddr,
+ const uint64_t i_hash_vaddr)
+{
+ int64_t l_index = getHashPageTableIndex(i_vaddr);
+ int64_t l_offset = l_index * HASH_PAGE_TABLE_ENTRY_SIZE;
+
+ // l_offset is the offset for the start of the hash page table
+ // i_hash_vaddr is the vaddr for the start of the hash in SECURE
+ // subtract off DELTA of 3GB to get into TEMP space
+ return reinterpret_cast<PAGE_TABLE_ENTRY_t*>(l_offset + i_hash_vaddr -
+ VMM_VADDR_SPNOR_DELTA);
+}
+
+errlHndl_t verify_page(const int64_t i_offset_vaddr, const uint64_t i_hash_vaddr,
+ const uint64_t i_hash_size)
+{
+ errlHndl_t l_errl = nullptr;
+
+ // Get current hash page table entry in TEMP space
+ PAGE_TABLE_ENTRY_t* l_pageTableEntry =
+ getHashPageTableEntry(i_offset_vaddr, i_hash_vaddr);
+
+ // Get previous hash page table entry in TEMP space
+ PAGE_TABLE_ENTRY_t* l_prevPageTableEntry =
+ getHashPageTableEntry(i_offset_vaddr - PAGE_SIZE, i_hash_vaddr);
+
+ // Concatenate previous hash with current page data
+ std::vector< std::pair<void*,size_t> > l_blobs;
+ l_blobs.push_back(std::make_pair<void*,size_t>(l_prevPageTableEntry,
+ HASH_PAGE_TABLE_ENTRY_SIZE));
+
+ // To get to PNOR space, we have the address of the hash in SECURE space and
+ // we add hash table size to get passed the hash page table. Then we add
+ // i_offset_vaddr, the offset of the requested vaddr, to end up at the
+ // requested vaddr in SECURE space. Finally we subtract off 2 DELTAS of
+ // 3GB each to get to the requested vaddr in PNOR space
+ l_blobs.push_back(std::make_pair<void*,size_t>(
+ reinterpret_cast<void*>(i_offset_vaddr +
+ i_hash_vaddr + i_hash_size -
+ 2 * VMM_VADDR_SPNOR_DELTA),
+ PAGE_SIZE));
+ SHA512_t l_curPageHash = {0};
+ SECUREBOOT::hashConcatBlobs(l_blobs, l_curPageHash);
+
+ // Compare existing hash page table entry with the derived one.
+ if (memcmp(l_pageTableEntry,l_curPageHash,HASH_PAGE_TABLE_ENTRY_SIZE) != 0)
+ {
+ TRACFCOMP(g_trac_pnor, "ERROR:>PNOR::verify_page secureboot verify fail on vaddr 0x%016llX",
+ i_hash_vaddr + i_hash_size + i_offset_vaddr);
+ /*@
+ * @severity ERRL_SEV_CRITICAL_SYS_TERM
+ * @moduleid MOD_SPNORRP_VERIFY_PAGE
+ * @reasoncode RC_VERIFY_PAGE_FAILED
+ * @userdata1 Kernel RC
+ * @userdata2 Virtual address accessed
+ *
+ * @devdesc Secureboot page verify failure
+ * @custdesc Corrupted flash image or firmware error during system boot
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM,
+ MOD_SPNORRP_VERIFY_PAGE,
+ RC_VERIFY_PAGE_FAILED,
+ TO_UINT64(EACCES),
+ i_offset_vaddr,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_errl->collectTrace(PNOR_COMP_NAME);
+ l_errl->collectTrace(SECURE_COMP_NAME);
+ }
+ return l_errl;
+}
+
/**
@@ -769,6 +876,7 @@ void SPnorRP::waitForMessage()
// data[0] = virtual address requested
// data[1] = address to place contents
+ uint64_t requested_vaddr = message->data[0];
eff_addr = reinterpret_cast<uint8_t*>(message->data[0]);
user_addr = reinterpret_cast<uint8_t*>(message->data[1]);
@@ -819,10 +927,34 @@ void SPnorRP::waitForMessage()
TRACDCOMP( g_trac_pnor, "SPnorRP::waitForMessage got a"
" request to read from secure space - "
"message : user_addr=%p, eff_addr=%p, msgtype=%d, "
- "textSize=0x%.16llX secAddr0x%.16llX", user_addr,
+ "textSize=0x%.16llX secAddr=0x%.16llX", user_addr,
eff_addr, message->type, l_rec.textSize,
l_rec.secAddr);
+ // If record has an associated hash page table, then we
+ // want to verify the page with the hash table in temp
+ if (SECUREBOOT::enabled() && l_rec.hasHashTable)
+ {
+ // Pass in the offset of just the data
+ int64_t offset_vaddr = requested_vaddr -
+ l_rec.hashTableVaddr - l_rec.textSize;
+
+ // There is no hash table entry when we try to
+ // verify the header
+ if (offset_vaddr >= 0) {
+ l_errhdl = verify_page(offset_vaddr,
+ l_rec.hashTableVaddr,
+ l_rec.textSize);
+ }
+
+ if (l_errhdl)
+ {
+ SECUREBOOT::handleSecurebootFailure(l_errhdl, false, true);
+ status_rc = -EFAULT;
+ break;
+ }
+ }
+
// determine the source of the data depending on
// whether it is part of the secure payload.
// by the way, this if could be removed to make this
@@ -843,8 +975,8 @@ void SPnorRP::waitForMessage()
// if the page came from temp space then free up
// the temp page now that we're done with it
// NOTE: secAddr points to Secure Header
- if (eff_addr < ( (l_rec.secAddr + PAGESIZE) +
- l_rec.textSize))
+ if (!l_rec.hasHashTable && (eff_addr < ( (l_rec.secAddr + PAGESIZE) +
+ l_rec.textSize)))
{
mm_remove_pages(RELEASE, eff_addr - delta,
PAGESIZE);
@@ -924,7 +1056,6 @@ void SPnorRP::waitForMessage()
// cache the record to use fields later as hints
l_rec = *l_record;
-
} while (0);
}
break;
@@ -936,7 +1067,7 @@ void SPnorRP::waitForMessage()
do {
// Disallow unload of HBB, HBI and Targeting
if (l_id == HB_BASE_CODE ||
- l_id == HB_EXT_CODE ||
+ l_id == HB_EXT_CODE ||
l_id == HB_DATA)
{
TRACFCOMP( g_trac_pnor, ERR_MRK"SPnorRP::waitForMessage> Secure unload of HBB, HBI, and targeting is not allowed secId=%d", l_id);
@@ -998,7 +1129,7 @@ void SPnorRP::waitForMessage()
size_t l_sizeWithHdr = PAGESIZE + l_rec->textSize;
// if the section has an unsecured portion
- if (l_sizeWithHdr != l_rec->infoSize)
+ if (l_sizeWithHdr != l_rec->infoSize && !l_rec->hasHashTable)
{
TRACFCOMP( g_trac_pnor, ERR_MRK"SPnorRP::waitForMessage> Attempting to unload an unsupported section: 0x%X textsize+hdr: 0x%llX infosize: 0x%llX (the two sizes must be equal)", l_id, l_sizeWithHdr, l_rec->infoSize);
/*@
@@ -1031,6 +1162,40 @@ void SPnorRP::waitForMessage()
}
TRACDCOMP(g_trac_pnor,"Completely unloading %s", PNOR::SectionIdToString(l_id));
+ if (l_rec->hasHashTable)
+ {
+ // remove unprotected pages
+ l_errhdl = removePages(l_rec->secAddr + PAGE_SIZE + l_rec->textSize,
+ l_rec->infoSize - PAGE_SIZE - l_rec->textSize);
+ if (l_errhdl)
+ {
+ TRACFCOMP(g_trac_pnor,
+ ERR_MRK"SPnorRP::waitForMessage> "
+ "removePages failed for address "
+ "0x%11X of length 0x%11X",
+ l_rec->secAddr + PAGE_SIZE + l_rec->textSize,
+ l_rec->infoSize - PAGE_SIZE - l_rec->textSize);
+ status_rc = -EFAULT;
+ break;
+ }
+
+ l_errhdl = setPermission(l_rec->secAddr + PAGE_SIZE + l_rec->textSize,
+ l_rec->infoSize - PAGE_SIZE - l_rec->textSize,
+ NO_ACCESS);
+ if (l_errhdl)
+ {
+ TRACFCOMP(g_trac_pnor,
+ ERR_MRK"SPnorRP::waitForMessage> "
+ "setPermission failed for address "
+ "0x%11X of length 0x%11X",
+ l_rec->secAddr + PAGE_SIZE + l_rec->textSize,
+ l_rec->infoSize - PAGE_SIZE - l_rec->textSize);
+
+ status_rc = -EFAULT;
+ break;
+ }
+ }
+
l_errhdl = removePages(l_rec->secAddr,
l_sizeWithHdr);
if (l_errhdl)
@@ -1039,21 +1204,21 @@ void SPnorRP::waitForMessage()
ERR_MRK"SPnorRP::waitForMessage> "
"removePages failed for address "
"0x%llX of length 0x%llX", l_rec->secAddr,
- l_sizeWithHdr);
+ l_sizeWithHdr);
status_rc = -EFAULT;
break;
}
l_errhdl = setPermission(l_rec->secAddr,
- l_sizeWithHdr,
- NO_ACCESS);
+ l_sizeWithHdr,
+ NO_ACCESS);
if (l_errhdl)
{
TRACFCOMP( g_trac_pnor,
ERR_MRK"SPnorRP::waitForMessage> "
"setPermission failed for address "
"0x%llX of length 0x%llX", l_rec->secAddr,
- l_sizeWithHdr);
+ l_sizeWithHdr);
status_rc = -EFAULT;
break;
@@ -1067,7 +1232,7 @@ void SPnorRP::waitForMessage()
l_sizeWithHdr);
if (l_errhdl)
{
- TRACFCOMP( g_trac_pnor,
+ TRACFCOMP(g_trac_pnor,
ERR_MRK"SPnorRP::waitForMessage> "
"removePages failed for address "
"0x%llX of length 0x%llX", l_tempAddr,
@@ -1083,16 +1248,15 @@ void SPnorRP::waitForMessage()
l_sizeWithHdr);
l_errhdl = setPermission(l_tempAddr,
- l_sizeWithHdr,
- NO_ACCESS);
+ l_sizeWithHdr,
+ NO_ACCESS);
if (l_errhdl)
{
- TRACFCOMP( g_trac_pnor,
+ TRACFCOMP(g_trac_pnor,
ERR_MRK"SPnorRP::waitForMessage> "
"setPermission failed for address "
"0x%llX of length 0x%llX", l_tempAddr,
l_sizeWithHdr);
-
status_rc = -EFAULT;
break;
}
diff --git a/src/usr/pnor/spnorrp.H b/src/usr/pnor/spnorrp.H
index 11da539ef..daaa3ffb7 100644
--- a/src/usr/pnor/spnorrp.H
+++ b/src/usr/pnor/spnorrp.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,7 +33,6 @@
#include <map>
#include "pnor_common.H"
#include "ffs.h"
-#include <config.h>
#include <securerom/ROM.H>
namespace SECUREBOOT
@@ -113,13 +112,16 @@ class SPnorRP
* Keep track of secured payload size and secure section addresses
*/
struct LoadRecord{
- uint8_t* secAddr;
- size_t textSize;
- size_t infoSize;
+ uint8_t* secAddr; // virtual address of the start of the record
+ uint64_t hashTableVaddr; // virtual address of the hash table (if it exists)
+ size_t textSize; // size of the protected payload, not including header
+ size_t infoSize; // size of the entire partition
size_t refCount;
+ bool hasHashTable; // indicates if the record has a hash table
+
SHA512_t payloadTextHash;
LoadRecord()
- :secAddr(nullptr), textSize(0), infoSize(0), refCount(0)
+ :secAddr(nullptr), hashTableVaddr(0), textSize(0), infoSize(0), refCount(0), hasHashTable(false)
{
memset(&payloadTextHash[0], 0, SHA512_DIGEST_LENGTH);
}
diff --git a/src/usr/pnor/test/pnorrptest.H b/src/usr/pnor/test/pnorrptest.H
index 9d9dd95c1..54ed5f1cc 100644
--- a/src/usr/pnor/test/pnorrptest.H
+++ b/src/usr/pnor/test/pnorrptest.H
@@ -42,7 +42,6 @@
#include <sys/task.h>
#include <targeting/common/targetservice.H>
#include <devicefw/userif.H>
-#include <config.h>
#include <pnor/ecc.H>
#include "../pnorrp.H"
#include "../pnor_common.H"
@@ -90,11 +89,13 @@ class PnorRpTest : public CxxTest::TestSuite
continue;
}
- if(( testSections[idx] == PNOR::DIMM_JEDEC_VPD ) &&
+ if(( testSections[idx] == PNOR::DIMM_JEDEC_VPD ||
+ testSections[idx] == PNOR::MODULE_VPD) &&
( TARGETING::MODEL_AXONE ==
TARGETING::targetService().getProcessorModel() ))
{
- TRACFCOMP(g_trac_pnor, "PnorRpTest::test_sectionInfo> Skipping non-existent DIMM_JEDEC_VPD section for Axone");
+ TRACFCOMP(g_trac_pnor, "PnorRpTest::test_sectionInfo> "
+ "Skipping non-existent MODULE_VPD and DIMM_JEDEC_VPD section for Axone");
continue;
}
diff --git a/src/usr/pnor/test/pnorutilsTest.H b/src/usr/pnor/test/pnorutilsTest.H
index a2258c622..b273665c7 100644
--- a/src/usr/pnor/test/pnorutilsTest.H
+++ b/src/usr/pnor/test/pnorutilsTest.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2017 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -62,7 +62,7 @@ class pnorutilsTest : public CxxTest::TestSuite
l_tocBuffer[17] = 0x41;
ffs_hdr* l_ffs_hdr = NULL;
- PNOR::checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
+ checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
PNOR::checkHeader(l_ffs_hdr, l_errCode);
if((l_errCode & PNOR::INVALID_MAGIC) == PNOR::INVALID_MAGIC)
@@ -92,7 +92,7 @@ class pnorutilsTest : public CxxTest::TestSuite
l_tocBuffer[7] = 0x0;
ffs_hdr* l_ffs_hdr = NULL;
- PNOR::checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
+ checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
PNOR::checkHeader(l_ffs_hdr, l_errCode);
@@ -122,7 +122,7 @@ class pnorutilsTest : public CxxTest::TestSuite
l_tocBuffer[31] = 0x80;
ffs_hdr* l_ffs_hdr = NULL;
- PNOR::checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
+ checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
PNOR::checkHeader(l_ffs_hdr, l_errCode);
@@ -153,7 +153,7 @@ class pnorutilsTest : public CxxTest::TestSuite
l_tocBuffer[35] = 0x12;
ffs_hdr* l_ffs_hdr = NULL;
- PNOR::checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
+ checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
PNOR::checkHeader(l_ffs_hdr, l_errCode);
@@ -183,7 +183,7 @@ class pnorutilsTest : public CxxTest::TestSuite
l_tocBuffer[38] = 0x10;
ffs_hdr* l_ffs_hdr = NULL;
- PNOR::checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
+ checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
PNOR::checkHeader(l_ffs_hdr, l_errCode);
@@ -213,7 +213,7 @@ class pnorutilsTest : public CxxTest::TestSuite
l_tocBuffer[42] = 0x40;
ffs_hdr* l_ffs_hdr = NULL;
- PNOR::checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
+ checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
PNOR::checkHeader(l_ffs_hdr, l_errCode);
@@ -246,7 +246,7 @@ class pnorutilsTest : public CxxTest::TestSuite
l_tocBuffer[39] = 0x33;
ffs_hdr* l_ffs_hdr = NULL;
- PNOR::checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
+ checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
PNOR::checkHeader(l_ffs_hdr, l_errCode);
@@ -276,7 +276,7 @@ class pnorutilsTest : public CxxTest::TestSuite
l_tocBuffer[208] = 0xFF;
PNOR::SectionData_t l_TOC[PNOR::NUM_SECTIONS];
ffs_hdr* l_ffs_hdr = NULL;
- PNOR::checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
+ checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
PNOR::checkHeader(l_ffs_hdr, l_errCode);
//parse through the entries and check for any errors
ffs_entry* l_err_entry = NULL;
@@ -317,7 +317,7 @@ class pnorutilsTest : public CxxTest::TestSuite
PNOR::SectionData_t l_TOC[PNOR::NUM_SECTIONS];
ffs_hdr* l_ffs_hdr = NULL;
- PNOR::checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
+ checkForNullBuffer(l_tocBuffer, l_errCode, l_ffs_hdr);
PNOR::checkHeader(l_ffs_hdr, l_errCode);
//parse through the entries and check for any errors
ffs_entry* l_err_entry = NULL;
@@ -336,6 +336,29 @@ class pnorutilsTest : public CxxTest::TestSuite
TRACFCOMP(g_trac_pnor, "pnorutilsTest::test_entryExtendsBeyondFlash: complete, Failed = %d", l_failed);
}
+
+ private:
+
+ /**
+ * @brief Ensure the buffer is not NULL, if it is, then return
+ * the appropriate err code from the o_errCode param.
+ * If the buffer is not NULL then cast it to a ffs_hdr
+ * and return that out through the o_ffs_hdr param.
+ */
+ void checkForNullBuffer(uint8_t* i_tocBuffer,
+ uint32_t& o_errCode,
+ ffs_hdr*& o_ffs_hdr)
+ {
+ if(!i_tocBuffer)
+ {
+ o_errCode |= PNOR::BUFF_IS_NULL;
+ o_ffs_hdr = NULL;
+ }
+ else
+ {
+ o_ffs_hdr = reinterpret_cast<ffs_hdr*>(i_tocBuffer);
+ }
+ }
};
#endif
diff --git a/src/usr/runtime/customize_attrs_for_payload.C b/src/usr/runtime/customize_attrs_for_payload.C
index 1846512b7..273596b12 100644
--- a/src/usr/runtime/customize_attrs_for_payload.C
+++ b/src/usr/runtime/customize_attrs_for_payload.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,10 +36,10 @@
#include <targeting/common/target.H>
#include <targeting/common/targetservice.H>
#include <targeting/common/utilFilter.H>
+#include <targeting/runtime/rt_targeting.H>
#include <runtime/runtime_reasoncodes.H>
#include <runtime/runtime.H>
#include <errl/errlmanager.H>
-#include <runtime/rt_targeting.H>
#include <arch/pirformat.H>
#include <targeting/common/util.H>
#include <errl/errludtarget.H>
@@ -78,7 +78,8 @@ errlHndl_t createProcNotFoundError(
* @reasoncode RUNTIME::RT_NO_PROC_TARGET
* @userdata1 Input targeting target's HUID
* @devdesc No processor targeting target was found for the given
- * targeting target
+ * targeting target
+ * @custdesc Unexpected internal firmware error
*/
pError = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_INFORMATIONAL,
@@ -86,7 +87,7 @@ errlHndl_t createProcNotFoundError(
RUNTIME::RT_NO_PROC_TARGET,
huid,
0,
- true);
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
ERRORLOG::ErrlUserDetailsTarget(i_pTarget,"Targeting target").
addToLog(pError);
@@ -109,7 +110,7 @@ errlHndl_t createProcNotFoundError(
*/
errlHndl_t computeNonPhypRtTarget(
const TARGETING::Target* i_pTarget,
- RT_TARG::rtChipId_t& o_rtTargetId)
+ TARGETING::rtChipId_t& o_rtTargetId)
{
assert(i_pTarget != NULL);
@@ -165,6 +166,7 @@ errlHndl_t computeNonPhypRtTarget(
* @userdata1 MEMBUF targeting target's HUID
* @devdesc No associated DMI targeting target(s) found for
* given MEMBUF targeting target
+ * @custdesc Unexpected internal firmware error
*/
pError = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_INFORMATIONAL,
@@ -172,7 +174,7 @@ errlHndl_t computeNonPhypRtTarget(
RUNTIME::RT_UNIT_TARGET_NOT_FOUND,
huid,
0,
- true);
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
ERRORLOG::ErrlUserDetailsTarget(i_pTarget,"Targeting Target").
addToLog(pError);
@@ -229,6 +231,80 @@ errlHndl_t computeNonPhypRtTarget(
o_rtTargetId = PIR_t::createCoreId(o_rtTargetId,pos);
o_rtTargetId |= HBRT_CORE_TYPE;
}
+ else if( targetingTargetType == TARGETING::TYPE_OCMB_CHIP)
+ {
+ // OCMB (This layout mimics MEMBUF)
+ // 0b1000.0000.0000.0000.0000.0GGG.GCCC.UUUU
+ // where GGGG is group, CCC is chip, UUUU is OMI chip unit
+ //
+ TARGETING::TargetHandleList targetList;
+
+ getParentAffinityTargets(targetList,
+ i_pTarget,
+ TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_OMI,
+ TARGETING::UTIL_FILTER_ALL);
+
+ if( targetList.empty() )
+ {
+ auto huid = get_huid(i_pTarget);
+ TRACFCOMP(g_trac_runtime, ERR_MRK
+ "No associated OMI targeting target(s) found for OCMB_CHIP "
+ "targeting target with HUID of 0x%08X",
+ huid);
+ /*@
+ * @error
+ * @moduleid RUNTIME::MOD_CUST_COMP_NON_PHYP_RT_TARGET
+ * @reasoncode RUNTIME::RT_NO_OMI_TARGET_FOUND
+ * @userdata1 OCMB targeting target's HUID
+ * @devdesc No associated OMI targeting target(s) found for
+ * given OCMB targeting target
+ * @custdesc Unexpected internal firmware error
+ */
+ pError = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ RUNTIME::MOD_CUST_COMP_NON_PHYP_RT_TARGET,
+ RUNTIME::RT_NO_OMI_TARGET_FOUND,
+ huid,
+ 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ ERRORLOG::ErrlUserDetailsTarget(i_pTarget,"Targeting Target").
+ addToLog(pError);
+
+ break;
+ }
+
+ auto target = targetList[0];
+ auto pos = target->getAttr<TARGETING::ATTR_CHIP_UNIT>();
+
+ targetList.clear();
+ getParentAffinityTargets(targetList,
+ target,
+ TARGETING::CLASS_CHIP,
+ TARGETING::TYPE_PROC,
+ TARGETING::UTIL_FILTER_ALL);
+
+ if(targetList.empty())
+ {
+ pError = createProcNotFoundError(target);
+ break;
+ }
+
+ auto procTarget = targetList[0];
+ pError = computeNonPhypRtTarget(procTarget, o_rtTargetId);
+ if(pError)
+ {
+ break;
+ }
+
+ // GGGG = 0 by default, CCC = o_rtTargetId, UUUU = pos
+ // HBRT_MEMBUF_TYPE distinguishes this target as a MEMBUF/OCMB
+ // Reusing MEMBUF for OCMB type as the two can't coexist
+ o_rtTargetId = (o_rtTargetId << RT_TARG::MEMBUF_ID_SHIFT);
+ o_rtTargetId += pos; // OMI chip unit acts as unique target position
+ o_rtTargetId |= HBRT_MEMBUF_TYPE;
+ }
else
{
auto huid = get_huid(i_pTarget);
@@ -246,6 +322,7 @@ errlHndl_t computeNonPhypRtTarget(
* @userdata2 Targeting target's type
* @devdesc The targeting type of the input targeting target is
* not supported by runtime code
+ * @custdesc Unexpected internal firmware error
*/
pError = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_INFORMATIONAL,
@@ -253,7 +330,7 @@ errlHndl_t computeNonPhypRtTarget(
RUNTIME::RT_TARGET_TYPE_NOT_SUPPORTED,
huid,
targetingTargetType,
- true);
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
ERRORLOG::ErrlUserDetailsTarget(i_pTarget,"Targeting Target").
addToLog(pError);
@@ -277,7 +354,7 @@ errlHndl_t computeNonPhypRtTarget(
*/
errlHndl_t getRtTypeForTarget(
const TARGETING::Target* i_pTarget,
- RT_TARG::rtChipId_t& o_rtType)
+ TARGETING::rtChipId_t& o_rtType)
{
assert(i_pTarget != NULL);
@@ -305,6 +382,10 @@ errlHndl_t getRtTypeForTarget(
case TARGETING::TYPE_CORE:
rtType = HBRT_CORE_TYPE;
break;
+ case TARGETING::TYPE_OCMB_CHIP:
+ // reusing MEMBUF type as it is not present
+ rtType = HBRT_MEMBUF_TYPE;
+ break;
default:
found = false;
break;
@@ -325,6 +406,7 @@ errlHndl_t getRtTypeForTarget(
* @userdata1 Target's HUID
* @userdata2 Target's targeting type
* @devdesc Targeting target's type not supported by runtime code
+ * @custdesc Unexpected internal firmware error
*/
pError = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_INFORMATIONAL,
@@ -332,7 +414,7 @@ errlHndl_t getRtTypeForTarget(
RUNTIME::RT_TARGET_TYPE_NOT_SUPPORTED,
huid,
targetingTargetType,
- true);
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
ERRORLOG::ErrlUserDetailsTarget(i_pTarget,"Targeting Target").
addToLog(pError);
@@ -355,13 +437,15 @@ errlHndl_t configureHbrtHypIds(const bool i_configForPhyp)
TARGETING::CLASS_CHIP, TARGETING::TYPE_MEMBUF);
TARGETING::PredicateCTM isaCore(
TARGETING::CLASS_UNIT, TARGETING::TYPE_CORE);
- TARGETING::PredicatePostfixExpr isaProcMembufOrCore;
- isaProcMembufOrCore.push(&isaProc).push(&isaMembuf).Or()
- .push(&isaCore).Or();
+ TARGETING::PredicateCTM isanOcmbChip(
+ TARGETING::CLASS_CHIP, TARGETING::TYPE_OCMB_CHIP);
+ TARGETING::PredicatePostfixExpr isaProcMembufCoreorOcmb;
+ isaProcMembufCoreorOcmb.push(&isaProc).push(&isaMembuf).Or()
+ .push(&isaCore).Or().push(&isanOcmbChip).Or();
TARGETING::TargetRangeFilter pIt(
TARGETING::targetService().begin(),
TARGETING::targetService().end(),
- &isaProcMembufOrCore);
+ &isaProcMembufCoreorOcmb);
for (; pIt; ++pIt)
{
auto hbrtHypId = HBRT_HYP_ID_UNKNOWN;
@@ -376,61 +460,128 @@ errlHndl_t configureHbrtHypIds(const bool i_configForPhyp)
break;
}
- if( (*pIt)->getAttr<TARGETING::ATTR_TYPE>()
- == TARGETING::TYPE_CORE)
+ switch ((*pIt)->getAttr<TARGETING::ATTR_TYPE>())
{
- if(TARGETING::is_fused_mode())
+ case TARGETING::TYPE_CORE:
{
- // If we're in fused core mode, all core ID's must
- // match that of the parent EX
- auto type = TARGETING::TYPE_EX;
- const TARGETING::Target* pEx =
- TARGETING::getParent(*pIt,type);
-
- // If this fails, everything is already hosed
- assert(pEx != NULL);
-
- hbrtHypId = (pEx)->getAttr<TARGETING::ATTR_ORDINAL_ID>();
- }else
+ if(TARGETING::is_fused_mode())
+ {
+ // If we're in fused core mode, all core ID's must
+ // match that of the parent EX
+ auto type = TARGETING::TYPE_EX;
+ const TARGETING::Target* pEx =
+ TARGETING::getParent(*pIt,type);
+
+ // If this fails, everything is already hosed
+ assert(pEx != NULL);
+
+ hbrtHypId = (pEx)->getAttr<TARGETING::ATTR_ORDINAL_ID>();
+ }
+ else
+ {
+ hbrtHypId = (*pIt)->getAttr<TARGETING::ATTR_ORDINAL_ID>();
+ }
+ break;
+ }
+ case TARGETING::TYPE_MEMBUF:
+ {
+ //MEMBUF
+ // 0b1000.0000.0000.0000.0000.0PPP.PPPP.MMMM
+ // where PP is the parent proc's id, MMMM is memory channel
+ //
+ TARGETING::TargetHandleList targetList;
+
+ getParentAffinityTargets(targetList,
+ (*pIt),
+ TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_DMI, false);
+ assert( !targetList.empty() );
+
+ auto dmi_target = targetList[0];
+ auto pos = dmi_target->getAttr<TARGETING::ATTR_CHIP_UNIT>();
+
+ targetList.clear();
+ getParentAffinityTargets(targetList,
+ dmi_target,
+ TARGETING::CLASS_CHIP,
+ TARGETING::TYPE_PROC, false);
+ assert( !targetList.empty() );
+
+ auto procTarget = targetList[0];
+ hbrtHypId = procTarget->getAttr<TARGETING::ATTR_ORDINAL_ID>();
+ hbrtHypId = (hbrtHypId << RT_TARG::MEMBUF_ID_SHIFT);
+ hbrtHypId += pos;
+ break;
+ }
+ case TARGETING::TYPE_OCMB_CHIP:
+ {
+ TRACDCOMP( g_trac_runtime, "configureHbrtHypIds> "
+ "Set ATTR_HBRT_HYP_ID attribute for OCMB target "
+ "with HUID of 0x%08X", TARGETING::get_huid(*pIt));
+
+ // TYPE_OCMB_CHIP (mimics MEMBUF layout)
+ // 0b1000.0000.0000.0000.0000.0PPP.PPPP.UUUU
+ // where PP is the parent proc's id, UUUU is OMI chip unit
+ //
+ TARGETING::TargetHandleList targetList;
+
+ getParentAffinityTargets(targetList,
+ (*pIt),
+ TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_OMI, false);
+ assert( !targetList.empty() );
+
+ auto omi_target = targetList[0];
+ auto pos = omi_target->getAttr<TARGETING::ATTR_CHIP_UNIT>();
+
+ targetList.clear();
+ getParentAffinityTargets(targetList,
+ omi_target,
+ TARGETING::CLASS_CHIP,
+ TARGETING::TYPE_PROC, false);
+ assert( !targetList.empty() );
+
+ auto procTarget = targetList[0];
+ // Reusing MEMBUF for OCMB Chip communication
+ hbrtHypId = procTarget->getAttr<TARGETING::ATTR_ORDINAL_ID>();
+ hbrtHypId = (hbrtHypId << RT_TARG::MEMBUF_ID_SHIFT);
+ hbrtHypId += pos; // Add OMI chip unit to end
+ break;
+ }
+ case TARGETING::TYPE_PROC:
{
hbrtHypId = (*pIt)->getAttr<TARGETING::ATTR_ORDINAL_ID>();
+ break;
}
- }
- else if( (*pIt)->getAttr<TARGETING::ATTR_TYPE>()
- == TARGETING::TYPE_MEMBUF )
- {
- //MEMBUF
- // 0b1000.0000.0000.0000.0000.0PPP.PPPP.MMMM
- // where PP is the parent proc's id, MMMM is memory channel
- //
- TARGETING::TargetHandleList targetList;
-
- getParentAffinityTargets(targetList,
- (*pIt),
- TARGETING::CLASS_UNIT,
- TARGETING::TYPE_DMI, false);
- assert( !targetList.empty() );
-
- auto dmi_target = targetList[0];
- auto pos = dmi_target->getAttr<TARGETING::ATTR_CHIP_UNIT>();
-
- targetList.clear();
- getParentAffinityTargets(targetList,
- dmi_target,
- TARGETING::CLASS_CHIP,
- TARGETING::TYPE_PROC, false);
- assert( !targetList.empty() );
-
- auto procTarget = targetList[0];
- hbrtHypId = procTarget->getAttr<TARGETING::ATTR_ORDINAL_ID>();
- hbrtHypId = (hbrtHypId << RT_TARG::MEMBUF_ID_SHIFT);
- hbrtHypId += pos;
- }
- else // just PROC
- {
- hbrtHypId = (*pIt)->getAttr<TARGETING::ATTR_ORDINAL_ID>();
- }
-
+ default:
+ {
+ auto huid = get_huid(*pIt);
+ auto targetType = (*pIt)->getAttr<TARGETING::ATTR_TYPE>();
+ TRACFCOMP(g_trac_runtime, ERR_MRK
+ "configureHbrtHypIds> 0x%08X is not a supported type. "
+ "HUID: 0x%08X", targetType, huid);
+ /*@
+ * @errortype
+ * @moduleid RUNTIME::MOD_CONFIGURE_HBRT_HYP_IDS
+ * @reasoncode RUNTIME::RT_TARGET_TYPE_NOT_SUPPORTED
+ * @userdata1 Target's HUID
+ * @userdata2 Target's targeting type
+ * @devdesc Targeting target's type not supported by runtime code
+ * @custdesc Unexpected internal firmware error
+ */
+ pError = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ RUNTIME::MOD_CONFIGURE_HBRT_HYP_IDS,
+ RUNTIME::RT_TARGET_TYPE_NOT_SUPPORTED,
+ huid,
+ targetType,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ ERRORLOG::ErrlUserDetailsTarget(*pIt,"Targeting Target").
+ addToLog(pError);
+ break;
+ }
+ } // end of ATTR_TYPE switch
hbrtHypId |= rtType;
}
else
@@ -442,6 +593,12 @@ errlHndl_t configureHbrtHypIds(const bool i_configForPhyp)
}
}
+ // Only set HBRT_HYP_ID attribute if no error found
+ if (pError)
+ {
+ break;
+ }
+
(*pIt)->setAttr<TARGETING::ATTR_HBRT_HYP_ID>(hbrtHypId);
TRACDCOMP( g_trac_runtime, "configureHbrtHypIds> "
"Set ATTR_HBRT_HYP_ID attribute to 0x%016llX on targeting target "
diff --git a/src/usr/runtime/hdatstructs.H b/src/usr/runtime/hdatstructs.H
index 94f4c1b71..46cde05f7 100644
--- a/src/usr/runtime/hdatstructs.H
+++ b/src/usr/runtime/hdatstructs.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -453,7 +453,10 @@ typedef struct sysSecSets
// NOTE: This bit is labeled "Platform Security Overrides Allowed"
// in the section 6.1.1 of HDAT spec.
uint16_t sbeSecBackdoor : 1;
- uint16_t reserved : 13;
+
+ // bit 3: "System Physical Presence has been asserted"
+ uint16_t physicalPresenceAsserted : 1;
+ uint16_t reserved : 12;
} SysSecSets;
#endif
diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C
index 371c3bee8..5ead63b3e 100644
--- a/src/usr/runtime/populate_hbruntime.C
+++ b/src/usr/runtime/populate_hbruntime.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
+/* Contributors Listed Below - COPYRIGHT 2016,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -56,7 +56,6 @@
#include <secureboot/trustedbootif.H>
#include <secureboot/service.H>
#include <hdat/hdat.H>
-#include <config.h>
#include "../hdat/hdattpmdata.H"
#include "../hdat/hdatpcrd.H"
#include "../secureboot/trusted/tpmLogMgr.H"
@@ -854,9 +853,18 @@ errlHndl_t fill_RsvMem_hbData(uint64_t & io_start_address,
}
#ifdef CONFIG_SECUREBOOT
- memcpy(reinterpret_cast<uint8_t*>(l_prevDataAddr),
- reinterpret_cast<uint8_t *>(l_memd_info.vaddr),
- l_memd_info.secureProtectedPayloadSize);
+ if (l_memd_info.hasHashTable)
+ {
+ memcpy(reinterpret_cast<uint8_t*>(l_prevDataAddr),
+ reinterpret_cast<uint8_t *>(l_memd_info.vaddr),
+ l_memd_info.size);
+ }
+ else
+ {
+ memcpy(reinterpret_cast<uint8_t*>(l_prevDataAddr),
+ reinterpret_cast<uint8_t *>(l_memd_info.vaddr),
+ l_memd_info.secureProtectedPayloadSize);
+ }
#else
memcpy(reinterpret_cast<uint8_t*>(l_prevDataAddr),
reinterpret_cast<uint8_t *>(l_memd_info.vaddr),
@@ -905,10 +913,15 @@ errlHndl_t fill_RsvMem_hbData(uint64_t & io_start_address,
l_elog->collectTrace(RUNTIME_COMP_NAME);
break;
}
+ // break out of for-loop if
+ if(l_elog)
+ {
+ break;
+ }
i++;
}
- // exit if we hit an error
+ // break out of do-while if we hit an error
if(l_elog)
{
break;
@@ -1009,7 +1022,16 @@ errlHndl_t hbResvLoadSecureSection (const PNOR::SectionId i_sec,
if (i_secHdrExpected)
{
// If section is signed, only the protected size was loaded into memory
- l_imgSize = l_info.secureProtectedPayloadSize;
+ if (!l_info.hasHashTable)
+ {
+ l_imgSize = l_info.secureProtectedPayloadSize;
+ }
+ else
+ {
+ // Need to expose header and hash table
+ l_pnorVaddr -= l_info.secureProtectedPayloadSize;
+ l_imgSize += l_info.secureProtectedPayloadSize;
+ }
// Include secure header
// NOTE: we do not preserve the header in virtual memory when SB
// is compiled out. So "-PAGESIZE" only works when SB is compiled in
@@ -1257,51 +1279,10 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId, bool i_master_node)
break;
}
- ////////////////////////////////////////////////////////////////////
- // Set the Architected Reserve area in OPAL and pass it down to SBE
- uint64_t l_memBase = l_topMemAddr
- - VMM_ALL_HOMER_OCC_MEMORY_SIZE
- - VMM_ARCH_REG_DATA_SIZE_ALL_PROC;
-
- l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_HBRT,
- i_nodeId,
- l_memBase,
- VMM_ARCH_REG_DATA_SIZE_ALL_PROC,
- HBRT_RSVD_MEM__ARCH_REG);
- if(l_elog)
- {
- break;
- }
- // Loop through all functional Procs
- for (const auto & l_procChip: l_procChips)
- {
- uint32_t l_procNum =
- l_procChip->getAttr<TARGETING::ATTR_POSITION>();
- l_homerAddr = l_memBase +
- (l_procNum * VMM_ARCH_REG_DATA_PER_PROC_SIZE);
-
- //Pass start address down to SBE via chipop
- l_elog = SBEIO::sendPsuStashKeyAddrRequest(
- SBEIO::ARCH_REG_DATA_ADDR,
- l_homerAddr,
- l_procChip);
- if (l_elog)
- {
- TRACFCOMP( g_trac_runtime, "sendPsuStashKeyAddrRequest "
- "failed for target: %x",TARGETING::get_huid(l_procChip));
- break;
- }
- }
-
- if(l_elog)
- {
- break;
- }
- ////////////////////////////////////////////////////////////////////
-
#ifdef CONFIG_START_OCC_DURING_BOOT
///////////////////////////////////////////////////
// OCC Common entry
+ ///////////////////////////////////////////////////
if( !(TARGETING::is_phyp_load()) )
{
TARGETING::Target * l_sys = nullptr;
@@ -1324,6 +1305,69 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId, bool i_master_node)
#endif
}
+ ///////////////////////////////////////////////////
+ // Set the SBE Architected Dump area
+ // Note that this is right after HOMER areas
+ // PHYP goes up, OPAL goes down. Save this away
+ // Into targeting so dumpCollect can find later
+ // on the MPIPL
+ //
+ // Note that this works for PHYP multinode (as it
+ // grabs location from HRMOR), but OPAL only
+ // supports a single node style system (absolute
+ // address)
+ //////////////////////////////////////////////////
+ uint64_t l_archAddr = 0;
+ if(TARGETING::is_phyp_load())
+ {
+ l_archAddr = cpu_spr_value(CPU_SPR_HRMOR)
+ + l_mirrorBase
+ + VMM_ARCH_REG_DATA_START_OFFSET;
+ }
+ else if(TARGETING::is_sapphire_load())
+ {
+ l_archAddr = l_topMemAddr
+ - VMM_ALL_HOMER_OCC_MEMORY_SIZE
+ - VMM_ARCH_REG_DATA_SIZE_ALL_PROC;
+ }
+ l_sys->setAttr<TARGETING::ATTR_SBE_ARCH_DUMP_ADDR>(l_archAddr);
+
+ // SBE Architected Dump area is a single chunk of data
+ // to OPAL/PHYP -- so reserve once, but need to inform
+ // individual SBEs of their location
+ l_elog = setNextHbRsvMemEntry(HDAT::RHB_TYPE_HBRT,
+ i_nodeId,
+ l_archAddr,
+ VMM_ARCH_REG_DATA_SIZE_ALL_PROC,
+ HBRT_RSVD_MEM__ARCH_REG);
+ if(l_elog)
+ {
+ break;
+ }
+
+ // Loop through all functional Procs
+ uint32_t l_procNum = 0;
+ for (const auto & l_procChip: l_procChips)
+ {
+ uint64_t l_addr = l_archAddr +
+ (l_procNum++ * VMM_ARCH_REG_DATA_PER_PROC_SIZE);
+
+ //Pass start address down to SBE via chipop
+ l_elog = SBEIO::sendPsuStashKeyAddrRequest(
+ SBEIO::ARCH_REG_DATA_ADDR,
+ l_addr,
+ l_procChip);
+ if (l_elog)
+ {
+ TRACFCOMP( g_trac_runtime, "Arch dump sendPsuStashKeyAddrRequest "
+ "failed for target: %x",TARGETING::get_huid(l_procChip));
+ break;
+ }
+ }
+ if(l_elog)
+ {
+ break;
+ }
////////////////////////////////////////////////////
// HB Data area
@@ -1856,6 +1900,13 @@ errlHndl_t populate_hbSecurebootData ( void )
// populate security override setting
l_sysSecSets->sbeSecBackdoor = SECUREBOOT::getSbeSecurityBackdoor();
+ // populate "System Physical Presence has been asserted"
+ TARGETING::Target* sys = nullptr;
+ TARGETING::targetService().getTopLevelTarget( sys );
+ assert(sys != nullptr, "populate_hbSecurebootData() - Could not obtain top level target");
+ l_sysSecSets->physicalPresenceAsserted =
+ sys->getAttr<TARGETING::ATTR_PHYS_PRES_ASSERTED>();
+
// populate TPM config bits in hdat
bool tpmRequired = false;
#ifdef CONFIG_TPMDD
@@ -2863,6 +2914,12 @@ errlHndl_t populate_hbTpmInfo()
// if single node system
if (!hb_images)
{
+ // TODO RTC: 214260 Remove workaround skipping the population
+ // of the TPM info for runtime on single node on Axone systems
+ #ifdef CONFIG_AXONE_BRING_UP
+ TRACFCOMP( g_trac_runtime, "SKIPPING populate_hbTpmInfo: Single node system");
+ break;
+ #endif
TRACDCOMP( g_trac_runtime, "populate_hbTpmInfo: Single node system");
l_elog = populate_TpmInfoByNode(0); // 0 for single node
if(l_elog != nullptr)
diff --git a/src/usr/runtime/test/makefile b/src/usr/runtime/test/makefile
index ec316244f..fbba18a7d 100644
--- a/src/usr/runtime/test/makefile
+++ b/src/usr/runtime/test/makefile
@@ -24,7 +24,7 @@
# IBM_PROLOG_END_TAG
ROOTPATH = ../../../..
MODULE = testruntime
-TESTS += $(if $(or $(CONFIG_EARLY_TESTCASES),${CONFIG_AXONE_BRING_UP}) ,,testpreverifiedlidmgr.H)
+TESTS += $(if $(CONFIG_EARLY_TESTCASES) ,,testpreverifiedlidmgr.H)
TESTS += test_checkHbResMemLimit.H
#@TODO RTC 132750
#TESTS += hdatservicetest.H
diff --git a/src/usr/runtime/test/testpreverifiedlidmgr.H b/src/usr/runtime/test/testpreverifiedlidmgr.H
index 7b47bf98f..955550c8b 100644
--- a/src/usr/runtime/test/testpreverifiedlidmgr.H
+++ b/src/usr/runtime/test/testpreverifiedlidmgr.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -118,12 +118,12 @@ class PreVerifiedLidMgrTest : public CxxTest::TestSuite
// RINGOVD not permitted in secure mode. Meaning the Header and
// Content lid will be missing.
l_expectedLids -= 2;
-
- // VERSION is only an OpenPOWER partition so we need to adjust for
- // it here since it doesn't exist for standalone.
- l_expectedLids -= 2;
}
+ // VERSION is only an OpenPOWER partition so we need to adjust for
+ // it here since it doesn't exist for standalone.
+ l_expectedLids -= 2;
+
// Ensure the expected number of lids were loaded.
if (l_preVerLidMgr.cv_lidsLoaded.size() != l_expectedLids)
{
diff --git a/src/usr/sbe/sbe_update.C b/src/usr/sbe/sbe_update.C
index ef222e04d..ccbbe2480 100644
--- a/src/usr/sbe/sbe_update.C
+++ b/src/usr/sbe/sbe_update.C
@@ -52,7 +52,6 @@
#include <hwas/common/hwas.H>
#include <initservice/initserviceif.H>
#include <console/consoleif.H>
-#include <config.h>
#include <sbe/sbeif.H>
#include <sbeio/sbeioif.H>
#include <sbe/sbereasoncodes.H>
@@ -1204,74 +1203,80 @@ namespace SBE
procIOMask ); // Bits(8:31) = EC00:EC23
// Check for no error and use of input cores
- if ( (NULL == err) && (procIOMask == coreMask))
+ if (nullptr == err)
{
- // Procedure was successful
- procedure_success = true;
-
- o_actImgSize = static_cast<size_t>(tmpImgSize);
-
- TRACUCOMP( g_trac_sbe, "procCustomizeSbeImg(): "
- "p9_xip_customize success=%d, procIOMask=0x%X "
- "o_actImgSize=0x%X",
- procedure_success, procIOMask, o_actImgSize);
-
- // exit inner loop
- break;
- }
- // Check if p9_xip_customize returned a different core mask
- else if ( procIOMask != coreMask )
- {
- // A different core mask is returned from p9_xip_customize
- // when the cores sent in couldn't fit, but possibly
- // a different procIOMask would work
+ // FAPI_INVOKE_HWP returned with no error, check input cores
+ if (procIOMask == coreMask)
+ {
+ // Procedure was successful
+ procedure_success = true;
- TRACFCOMP( g_trac_sbe,
- ERR_MRK"procCustomizeSbeImg(): FAPI_INVOKE_HWP("
- "p9_xip_customize) returned rc=0x%X, "
- "XIPC_IMAGE_WOULD_OVERFLOW-Retry "
- "MaxCores=0x%.8X. HUID=0x%X. coreMask=0x%.8X, "
- "procIOMask=0x%.8X. coreCount=%d",
- ERRL_GETRC_SAFE(err), maxCores,
- TARGETING::get_huid(i_target),
- coreMask, procIOMask, coreCount);
+ o_actImgSize = static_cast<size_t>(tmpImgSize);
- // Setup for next loop - update coreMask
- err = selectBestCores(i_target,
- --coreCount,
- coreMask);
+ TRACUCOMP( g_trac_sbe, "procCustomizeSbeImg(): "
+ "p9_xip_customize success=%d, procIOMask=0x%X "
+ "o_actImgSize=0x%X",
+ procedure_success, procIOMask, o_actImgSize);
- if ( err )
- {
- TRACFCOMP(g_trac_sbe,
- ERR_MRK"procCustomizeSbeImg() - "
- "selectBestCores() failed rc=0x%X. "
- "coreCount=0x%.8X. HUID=0x%X. Aborting "
- "Customization of SBE Image",
- err->reasonCode(), coreCount,
- TARGETING::get_huid(i_target));
-
- // break from inner while loop
+ // exit inner loop
break;
- }
+ } // end if (procIOMask == coreMask)
+ // p9_xip_customize returned a different core mask:
+ // procIOMask != coreMask
+ else
+ {
+ // A different core mask is returned from
+ // p9_xip_customize, when the cores sent in couldn't
+ // fit, but possibly a different procIOMask would work
- TRACFCOMP( g_trac_sbe, "procCustomizeSbeImg(): for "
- "next loop: coreMask=0x%.8X, coreCount=%d",
- coreMask, coreCount);
+ TRACFCOMP( g_trac_sbe,
+ ERR_MRK"procCustomizeSbeImg(): FAPI_INVOKE_HWP("
+ "p9_xip_customize) returned rc=0x%X, "
+ "XIPC_IMAGE_WOULD_OVERFLOW-Retry "
+ "MaxCores=0x%.8X. HUID=0x%X. coreMask=0x%.8X, "
+ "procIOMask=0x%.8X. coreCount=%d",
+ ERRL_GETRC_SAFE(err), maxCores,
+ TARGETING::get_huid(i_target),
+ coreMask, procIOMask, coreCount);
+
+ // Setup for next loop - update coreMask
+ err = selectBestCores(i_target,
+ --coreCount,
+ coreMask);
+
+ if ( err )
+ {
+ TRACFCOMP(g_trac_sbe,
+ ERR_MRK"procCustomizeSbeImg() - "
+ "selectBestCores() failed rc=0x%X. "
+ "coreCount=0x%.8X. HUID=0x%X. Aborting "
+ "Customization of SBE Image",
+ err->reasonCode(), coreCount,
+ TARGETING::get_huid(i_target));
+
+ // break from inner while loop
+ break;
+ }
- // Check if loop will execute again
- // Clean up some data if it will
- if( coreCount >= min_cores )
- {
- // Reset size and clear image buffer
- tmpImgSize = static_cast<uint32_t>(i_maxImgSize);
- memset ( io_imgPtr,
- 0,
- tmpImgSize);
- }
+ TRACFCOMP( g_trac_sbe, "procCustomizeSbeImg(): for "
+ "next loop: coreMask=0x%.8X, coreCount=%d",
+ coreMask, coreCount);
+
+ // Check if loop will execute again
+ // Clean up some data if it will
+ if( coreCount >= min_cores )
+ {
+ // Reset size and clear image buffer
+ tmpImgSize = static_cast<uint32_t>(i_maxImgSize);
+ memset ( io_imgPtr,
+ 0,
+ tmpImgSize);
+ }
+ } // end if (procIOMask == coreMask) ... else ...
// No break - keep looping
- }
+
+ } // end if (nullptr == err)
else
{
// Unexpected return code - create err and fail
@@ -1292,7 +1297,7 @@ namespace SBE
// break from inner while loop
break;
- }
+ } // end if (nullptr == err) ... else ...
} // end of inner while loop
if(err)
diff --git a/src/usr/sbe/test/sbeupdatetest.H b/src/usr/sbe/test/sbeupdatetest.H
index cf482c053..e8c508414 100644
--- a/src/usr/sbe/test/sbeupdatetest.H
+++ b/src/usr/sbe/test/sbeupdatetest.H
@@ -38,7 +38,6 @@
#include <devicefw/driverif.H>
#include <vfs/vfs.H>
#include <targeting/common/utilFilter.H>
-#include <config.h>
#include <sbe/sbeif.H>
#include <sbe/sbe_update.H>
#include <secureboot/service.H>
diff --git a/src/usr/sbeio/runtime/makefile b/src/usr/sbeio/runtime/makefile
index 37792b554..e50153946 100644
--- a/src/usr/sbeio/runtime/makefile
+++ b/src/usr/sbeio/runtime/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2017,2018
+# Contributors Listed Below - COPYRIGHT 2017,2019
# [+] International Business Machines Corp.
#
#
@@ -37,6 +37,7 @@ include ../common/common.mk
## Objects unique to HBRT
OBJS += rt_sbeio.o
OBJS += sbeio_attr_override.o
+OBJS += sbeio_nvdimm_operation.o
OBJS += sbeio_vital_attn.o
## sbeio_rt's sub directories
diff --git a/src/usr/sbeio/runtime/rt_sbeio.C b/src/usr/sbeio/runtime/rt_sbeio.C
index 3aed96db6..1c95596a5 100644
--- a/src/usr/sbeio/runtime/rt_sbeio.C
+++ b/src/usr/sbeio/runtime/rt_sbeio.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -29,6 +29,7 @@
#include <sys/misc.h>
#include <sbeio/runtime/sbe_msg_passing.H>
#include <sbeio/runtime/sbeio_attr_override.H>
+#include <sbeio/runtime/sbeio_nvdimm_operation.H>
#include <sbeio/sbeioreasoncodes.H>
#include <errno.h>
#include <errl/errlentry.H>
@@ -40,7 +41,7 @@
#include <targeting/common/target.H>
#include <targeting/common/commontargeting.H>
#include <targeting/common/utilFilter.H>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
using namespace TARGETING;
@@ -782,6 +783,10 @@ namespace RT_SBEIO
#endif
SBE_MSG::setProcessCmdFunction(PASSTHRU_HBRT_OVERRIDE_ATTR,
sbeApplyAttrOverrides);
+#ifdef CONFIG_NVDIMM
+ SBE_MSG::setProcessCmdFunction(PASSTHRU_HBRT_NVDIMM_OP,
+ sbeNvdimmOperation);
+#endif
}
};
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/fir/memdiags_fir.H b/src/usr/sbeio/runtime/sbeio_nvdimm_operation.C
index c3a8e6c8c..f41cd01a5 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/fir/memdiags_fir.H
+++ b/src/usr/sbeio/runtime/sbeio_nvdimm_operation.C
@@ -1,11 +1,11 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/fir/memdiags_fir.H $ */
+/* $Source: src/usr/sbeio/runtime/sbeio_nvdimm_operation.C $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,47 +22,43 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+#include <sbeio/runtime/sbeio_nvdimm_operation.H>
-///
-/// @file memdiags_fir.H
-/// @brief Subroutines for memdiags/prd FIR
-///
-// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP HWP Backup: Marc Gollub <gollub@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
+#include <runtime/interface.h>
+#include <util/runtime/rt_fwnotify.H>
+#include <sbeio/sbeioreasoncodes.H>
+#include <errl/errlentry.H>
-#ifndef _MSS_MEMDIAGS_FIR_H_
-#define _MSS_MEMDIAGS_FIR_H_
+extern trace_desc_t* g_trac_sbeio;
-#include <fapi2.H>
-#include <lib/fir/fir.H>
+using namespace ERRORLOG;
-namespace mss
+namespace SBE_MSG
{
-namespace unmask
+//-------------------------------------------------------------------------
+errlHndl_t sbeNvdimmOperation( TARGETING::TargetHandle_t i_procTgt,
+ uint32_t i_reqDataSize,
+ uint8_t * i_reqData,
+ uint32_t * o_rspStatus,
+ uint32_t * o_rspDataSize,
+ uint8_t * o_rspData )
{
+ errlHndl_t errl{};
-///
-/// @brief Unmask and setup actions for memdiags related FIR
-/// @tparam T the fapi2::TargetType which hold the FIR bits
-/// @param[in] i_target the fapi2::Target
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode after_memdiags( const fapi2::Target<T>& i_target );
+ do
+ {
+ *o_rspDataSize = 0; //No return data
+ o_rspData = nullptr;
-///
-/// @brief Unmask and setup actions for scrub related FIR
-/// @tparam T the fapi2::TargetType which hold the FIR bits
-/// @param[in] i_target the fapi2::Target
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode after_background_scrub( const fapi2::Target<T>& i_target );
+ // doNvDimmOperation will take care of handling errors it encounters.
+ hostInterfaces::nvdimm_operation_t* l_nvdimmOp =
+ reinterpret_cast<hostInterfaces::nvdimm_operation_t*>(i_reqData);
+ *o_rspStatus = doNvDimmOperation(*l_nvdimmOp);
+ }
+ while(0);
+ return errl;
}
-}
-#endif
+
+}//End namespace
diff --git a/src/usr/sbeio/runtime/test/sbeioAttrOverrideTests.H b/src/usr/sbeio/runtime/test/sbeioAttrOverrideTests.H
index d99acfe8b..5c58078c5 100644
--- a/src/usr/sbeio/runtime/test/sbeioAttrOverrideTests.H
+++ b/src/usr/sbeio/runtime/test/sbeioAttrOverrideTests.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,7 +27,6 @@
#include <cxxtest/TestSuite.H>
#include <runtime/interface.h>
-#include <runtime/rt_targeting.H>
#include <sbeio/runtime/sbe_msg_passing.H>
#include <sbeio/sbeioreasoncodes.H>
#include <secureboot/service.H>
@@ -35,6 +34,7 @@
#include <targeting/common/target.H>
#include <targeting/common/targetservice.H>
#include <targeting/common/utilFilter.H>
+#include <targeting/runtime/rt_targeting.H>
#include <errl/errlmanager.H>
#include <devicefw/userif.H>
@@ -173,8 +173,8 @@ public:
}
l_proc = procList[0];
- RT_TARG::rtChipId_t l_chipId = 0;
- errlHndl_t l_err = RT_TARG::getRtTarget(l_proc, l_chipId);
+ TARGETING::rtChipId_t l_chipId = 0;
+ errlHndl_t l_err = TARGETING::getRtTarget(l_proc, l_chipId);
if(nullptr != l_err)
{
diff --git a/src/usr/sbeio/runtime/test/sbeiotestRt.H b/src/usr/sbeio/runtime/test/sbeiotestRt.H
index a2a4b1996..c91a663bb 100644
--- a/src/usr/sbeio/runtime/test/sbeiotestRt.H
+++ b/src/usr/sbeio/runtime/test/sbeiotestRt.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -35,7 +35,7 @@
#include <runtime/interface.h>
#include <sbeio/runtime/sbe_msg_passing.H>
#include <sbeio/sbeioreasoncodes.H>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <targeting/common/attributes.H>
#include <targeting/common/utilFilter.H>
#include <errl/errlmanager.H>
@@ -88,7 +88,7 @@ class SbeMessagePassingRtTest : public CxxTest::TestSuite
*/
int initSbeMessagePassing(sbeMessage_t& o_request,
sbeMessage_t& o_expected_response,
- RT_TARG::rtChipId_t& o_chipId,
+ TARGETING::rtChipId_t& o_chipId,
uint64_t& o_sbeCommAddr,
runtimeInterfaces_t **o_rt_intf)
{
@@ -142,8 +142,8 @@ class SbeMessagePassingRtTest : public CxxTest::TestSuite
TargetHandle_t proc = procList[0];
// Get the chip ID for the proc
- RT_TARG::rtChipId_t o_chipId = 0;
- errlHndl_t err = RT_TARG::getRtTarget(proc, o_chipId);
+ TARGETING::rtChipId_t o_chipId = 0;
+ errlHndl_t err = TARGETING::getRtTarget(proc, o_chipId);
if(nullptr != err)
{
rc = -1;
@@ -311,7 +311,7 @@ class SbeMessagePassingRtTest : public CxxTest::TestSuite
*
* @return Return Code O if Successful, otherwise not 0.
*/
- int checkResetSbeMessagePassingCFAM(RT_TARG::rtChipId_t i_procChipId,
+ int checkResetSbeMessagePassingCFAM(TARGETING::rtChipId_t i_procChipId,
uint32_t i_checkMask = SBE_MSG_MASK)
{
// Test check / reset CFAM entry
@@ -402,7 +402,7 @@ class SbeMessagePassingRtTest : public CxxTest::TestSuite
"testSbeMessagePassingVersions");
sbeMessage_t l_request;
sbeMessage_t l_expected_response;
- RT_TARG::rtChipId_t chipId = 0;
+ TARGETING::rtChipId_t chipId = 0;
uint64_t l_sbeCommAddr = 0;
runtimeInterfaces_t *rt_intf = nullptr;
@@ -501,7 +501,7 @@ class SbeMessagePassingRtTest : public CxxTest::TestSuite
sbeMessage_t l_request;
sbeMessage_t l_expected_response;
- RT_TARG::rtChipId_t chipId = 0;
+ TARGETING::rtChipId_t chipId = 0;
uint64_t l_sbeCommAddr = 0;
runtimeInterfaces_t *rt_intf = nullptr;
@@ -567,7 +567,7 @@ class SbeMessagePassingRtTest : public CxxTest::TestSuite
sbeMessage_t l_request;
sbeMessage_t l_expected_response;
- RT_TARG::rtChipId_t chipId = 0;
+ TARGETING::rtChipId_t chipId = 0;
uint64_t l_sbeCommAddr = 0;
runtimeInterfaces_t *rt_intf = nullptr;
@@ -741,7 +741,7 @@ class SbeMessagePassingRtTest : public CxxTest::TestSuite
sbeMessage_t l_request;
sbeMessage_t l_expected_response;
- RT_TARG::rtChipId_t chipId = 0;
+ TARGETING::rtChipId_t chipId = 0;
uint64_t l_sbeCommAddr = 0;
runtimeInterfaces_t *rt_intf = nullptr;
@@ -832,7 +832,7 @@ class SbeMessagePassingRtTest : public CxxTest::TestSuite
sbeMessage_t l_request;
sbeMessage_t l_expected_response;
- RT_TARG::rtChipId_t chipId = 0;
+ TARGETING::rtChipId_t chipId = 0;
uint64_t l_sbeCommAddr = 0;
runtimeInterfaces_t *rt_intf = nullptr;
@@ -984,7 +984,7 @@ class SbeMessagePassingRtTest : public CxxTest::TestSuite
sbeMessage_t l_request;
sbeMessage_t l_expected_response;
- RT_TARG::rtChipId_t chipId = 0;
+ TARGETING::rtChipId_t chipId = 0;
uint64_t l_sbeCommAddr = 0;
runtimeInterfaces_t *rt_intf = nullptr;
@@ -1142,7 +1142,7 @@ class SbeMessagePassingRtTest : public CxxTest::TestSuite
sbeMessage_t l_request;
sbeMessage_t l_expected_response;
uint32_t l_hdrsSize = sizeof(sbeHeader_t) + sizeof(cmdHeader_t);
- RT_TARG::rtChipId_t chipId = 0;
+ TARGETING::rtChipId_t chipId = 0;
uint64_t l_sbeCommAddr = 0;
runtimeInterfaces_t *rt_intf = nullptr;
diff --git a/src/usr/sbeio/sbe_continueMpipl.C b/src/usr/sbeio/sbe_continueMpipl.C
index d791fce1a..ce2c584cc 100644
--- a/src/usr/sbeio/sbe_continueMpipl.C
+++ b/src/usr/sbeio/sbe_continueMpipl.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -28,7 +28,6 @@
procs in the system.
*/
-#include <config.h>
#include <trace/interface.H>
#include <errl/errlmanager.H>
#include <sbeio/sbeioif.H>
diff --git a/src/usr/sbeio/sbe_coreStateControl.C b/src/usr/sbeio/sbe_coreStateControl.C
index 6c102d755..cf912e7b8 100644
--- a/src/usr/sbeio/sbe_coreStateControl.C
+++ b/src/usr/sbeio/sbe_coreStateControl.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,7 +27,6 @@
* @brief Core State Control Messages to control the deadmap loop
*/
-#include <config.h>
#include <trace/interface.H>
#include <errl/errlmanager.H>
#include <sbeio/sbeioif.H>
diff --git a/src/usr/sbeio/sbe_getSBEFFDC.C b/src/usr/sbeio/sbe_getSBEFFDC.C
index 2ccd6451c..d77d6e40d 100644
--- a/src/usr/sbeio/sbe_getSBEFFDC.C
+++ b/src/usr/sbeio/sbe_getSBEFFDC.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,7 +27,6 @@
* @brief Get SBE FFDC.
*/
-#include <config.h>
#include <trace/interface.H>
#include <errl/errlmanager.H>
#include "sbe_fifodd.H"
diff --git a/src/usr/sbeio/sbe_memRegionMgr.C b/src/usr/sbeio/sbe_memRegionMgr.C
index a5692549d..790924812 100644
--- a/src/usr/sbeio/sbe_memRegionMgr.C
+++ b/src/usr/sbeio/sbe_memRegionMgr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,7 +27,6 @@
* @brief Opens and Closes Unsecure Memory Regions via the SBE
*/
-#include <config.h>
#include <trace/interface.H>
#include <errl/errlmanager.H>
#include <sbeio/sbeioif.H>
diff --git a/src/usr/sbeio/sbe_psuQuiesce.C b/src/usr/sbeio/sbe_psuQuiesce.C
index a10f5e8c3..7e1ced443 100644
--- a/src/usr/sbeio/sbe_psuQuiesce.C
+++ b/src/usr/sbeio/sbe_psuQuiesce.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,7 +27,6 @@
* @brief Send command to quiesce the SBE
*/
-#include <config.h>
#include <trace/interface.H>
#include <errl/errlmanager.H>
#include <sbeio/sbeioif.H>
diff --git a/src/usr/sbeio/sbe_psuReadSeeprom.C b/src/usr/sbeio/sbe_psuReadSeeprom.C
index bb8171716..5ccb87bca 100644
--- a/src/usr/sbeio/sbe_psuReadSeeprom.C
+++ b/src/usr/sbeio/sbe_psuReadSeeprom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,7 +27,6 @@
* @brief Send command to request Seeprom read on SBE
*/
-#include <config.h>
#include <trace/interface.H>
#include <errl/errlmanager.H>
#include <sbeio/sbeioif.H>
diff --git a/src/usr/sbeio/sbe_secureHwp.C b/src/usr/sbeio/sbe_secureHwp.C
index 246935e78..b115f3533 100644
--- a/src/usr/sbeio/sbe_secureHwp.C
+++ b/src/usr/sbeio/sbe_secureHwp.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,7 +27,6 @@
* @brief Send request to perform a HWP securely on SBE
*/
-#include <config.h>
#include <trace/interface.H>
#include <errl/errlmanager.H>
#include <sbeio/sbeioif.H>
diff --git a/src/usr/sbeio/sbe_securityListBinDump.C b/src/usr/sbeio/sbe_securityListBinDump.C
index 973d48046..b2c0f70d9 100644
--- a/src/usr/sbeio/sbe_securityListBinDump.C
+++ b/src/usr/sbeio/sbe_securityListBinDump.C
@@ -28,7 +28,6 @@
* for the whitelist/blacklist algorithm.
*/
-#include <config.h>
#include <trace/interface.H>
#include <errl/errlmanager.H>
#include <sbeio/sbeioif.H>
diff --git a/src/usr/sbeio/sbe_setFFDCAddr.C b/src/usr/sbeio/sbe_setFFDCAddr.C
index 5988336f9..526b3224d 100644
--- a/src/usr/sbeio/sbe_setFFDCAddr.C
+++ b/src/usr/sbeio/sbe_setFFDCAddr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -28,7 +28,6 @@
procs in the system.
*/
-#include <config.h>
#include <trace/interface.H>
#include <errl/errlmanager.H>
#include <sbeio/sbeioif.H>
diff --git a/src/usr/sbeio/sbe_stashKeyAddr.C b/src/usr/sbeio/sbe_stashKeyAddr.C
index 8ce3e6833..6ad410b2a 100644
--- a/src/usr/sbeio/sbe_stashKeyAddr.C
+++ b/src/usr/sbeio/sbe_stashKeyAddr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,7 +27,6 @@
* @brief Send command to stash key-value pair in the SBE
*/
-#include <config.h>
#include <trace/interface.H>
#include <errl/errlmanager.H>
#include <sbeio/sbeioif.H>
diff --git a/src/usr/sbeio/sbe_systemConfig.C b/src/usr/sbeio/sbe_systemConfig.C
index 1b0409b2b..c5733429c 100644
--- a/src/usr/sbeio/sbe_systemConfig.C
+++ b/src/usr/sbeio/sbe_systemConfig.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -28,7 +28,6 @@
procs in the system.
*/
-#include <config.h>
#include <trace/interface.H>
#include <errl/errlmanager.H>
#include <sbeio/sbeioif.H>
diff --git a/src/usr/sbeio/test/sbe_getsbeffdctest.H b/src/usr/sbeio/test/sbe_getsbeffdctest.H
index 431d81696..100c8254f 100644
--- a/src/usr/sbeio/test/sbe_getsbeffdctest.H
+++ b/src/usr/sbeio/test/sbe_getsbeffdctest.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -103,6 +103,14 @@ class GetSBEFFDCTest : public CxxTest::TestSuite
continue;
}
+ //TODO RTC:214913 -- Need to debug errors associated with
+ // this testcase being executed
+ if (1)
+ {
+ TS_TRACE("getSBEFFDCTest: Skipping testing because it doesn't work ");
+ continue;
+ }
+
l_errl = SBEIO::getFifoSBEFFDC(l_cpu_target,
l_pFifoResponse,
l_responseSize);
diff --git a/src/usr/sbeio/test/sbe_retry_handler_test.H b/src/usr/sbeio/test/sbe_retry_handler_test.H
index 9a3719895..56a721972 100644
--- a/src/usr/sbeio/test/sbe_retry_handler_test.H
+++ b/src/usr/sbeio/test/sbe_retry_handler_test.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -78,6 +78,8 @@ class SbeRetryHandlerTest : public CxxTest::TestSuite
// we are just looking at Slave SBE's
continue;
}
+ /* TODO RTC:214913 -- Re-enable/Fixup as in its current state
+ it causes an infinite loop
SbeRetryHandler l_SBEobj = SbeRetryHandler(
SbeRetryHandler::SBE_MODE_OF_OPERATION::ATTEMPT_REBOOT);
@@ -85,6 +87,7 @@ class SbeRetryHandlerTest : public CxxTest::TestSuite
SBE_TRACF_RHT("testSBEReturns: returned from main_sbe_handler "
"SUCCESS");
+ **/
}
}
@@ -117,6 +120,9 @@ class SbeRetryHandlerTest : public CxxTest::TestSuite
// we are just looking at Slave SBE's
continue;
}
+ /* TODO RTC:214913 -- Re-enable/Fixup as in its current state
+ it causes an infinite loop
+
SbeRetryHandler l_SBEobj = SbeRetryHandler(
SbeRetryHandler::SBE_MODE_OF_OPERATION::ATTEMPT_REBOOT);
@@ -136,6 +142,7 @@ class SbeRetryHandlerTest : public CxxTest::TestSuite
"that the SBE started is false, then the SBE attribute "
"also needs to be false");
}
+ **/
}
}
diff --git a/src/usr/scom/handleSpecialWakeup.C b/src/usr/scom/handleSpecialWakeup.C
index 07bab3a1b..e202e9bdb 100644
--- a/src/usr/scom/handleSpecialWakeup.C
+++ b/src/usr/scom/handleSpecialWakeup.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,7 +37,7 @@
#include <initservice/initserviceif.H>
#ifdef __HOSTBOOT_RUNTIME
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <runtime/interface.h>
#endif // __HOSTBOOT_RUNTIME
@@ -156,8 +156,8 @@ errlHndl_t callWakeupHyp(TARGETING::Target* i_target,
++pCore_it )
{
// Runtime target id
- RT_TARG::rtChipId_t rtTargetId = 0;
- l_errl = RT_TARG::getRtTarget(*pCore_it, rtTargetId);
+ TARGETING::rtChipId_t rtTargetId = 0;
+ l_errl = TARGETING::getRtTarget(*pCore_it, rtTargetId);
if(l_errl)
{
break;
diff --git a/src/usr/scom/runtime/rt_scom.C b/src/usr/scom/runtime/rt_scom.C
index a27dfe81e..4507b435f 100644
--- a/src/usr/scom/runtime/rt_scom.C
+++ b/src/usr/scom/runtime/rt_scom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -30,7 +30,7 @@
#include <scom/scomif.H>
#include <scom/runtime/rt_scomif.H>
#include <runtime/interface.h>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <xscom/piberror.H>
#include <runtime/hbrt_utilities.H>
@@ -169,9 +169,9 @@ errlHndl_t sendScomToHyp(DeviceFW::OperationType i_opType,
do
{
// Convert target to something Sapphire understands
- RT_TARG::rtChipId_t proc_id = 0;
- l_err = RT_TARG::getRtTarget(i_target,
- proc_id);
+ TARGETING::rtChipId_t target_id = 0;
+ l_err = TARGETING::getRtTarget(i_target,
+ target_id);
if(l_err)
{
break;
@@ -185,7 +185,7 @@ errlHndl_t sendScomToHyp(DeviceFW::OperationType i_opType,
if(i_opType == DeviceFW::READ)
{
l_hostRC =
- g_hostInterfaces->scom_read(proc_id,
+ g_hostInterfaces->scom_read(target_id,
i_scomAddr,
io_buffer
);
@@ -193,7 +193,7 @@ errlHndl_t sendScomToHyp(DeviceFW::OperationType i_opType,
else if (i_opType == DeviceFW::WRITE)
{
l_hostRC =
- g_hostInterfaces->scom_write(proc_id,
+ g_hostInterfaces->scom_write(target_id,
i_scomAddr,
io_buffer
);
@@ -203,8 +203,8 @@ errlHndl_t sendScomToHyp(DeviceFW::OperationType i_opType,
{
TRACFCOMP(g_trac_scom,ERR_MRK
"Hypervisor scom read/write failed. "
- "rc 0x%X target 0x%llX proc_id 0x%llX addr 0x%llX r/w %d",
- l_hostRC, get_huid(i_target), proc_id, i_scomAddr, i_opType);
+ "rc 0x%X target 0x%llX target_id 0x%llX addr 0x%llX r/w %d",
+ l_hostRC, get_huid(i_target), target_id, i_scomAddr, i_opType);
// Use an unused bit in the 64-bit scom range to indicate
// read/write. Cannot use bit0 since that is part of an
diff --git a/src/usr/scom/runtime/test/testscom_rt.H b/src/usr/scom/runtime/test/testscom_rt.H
index f0a14fe1b..e39d06d96 100644
--- a/src/usr/scom/runtime/test/testscom_rt.H
+++ b/src/usr/scom/runtime/test/testscom_rt.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -1242,29 +1242,6 @@ public:
TS_FAIL( "ScomTest::test__MultiChipScomWrite_proc> ERROR : Data mismatch between read and expected data" );
fails++;
}
-
- // Read the data back using FSIscom to make sure the data is the same.
- l_err = deviceOp( DeviceFW::READ,
- test_data[x].target,
- &(read_data[x]),
- op_size,
- DEVICE_FSISCOM_ADDRESS(test_data[x].addr) );
-
-
- if( l_err )
- {
- TRACFCOMP(g_trac_scom, "ScomTest::test__MultiChipScomWrite_proc> [%d] FSISCOM Read: Error from device : addr=0x%X, RC=%X", x, test_data[x].addr, l_err->reasonCode() );
- TS_FAIL( "ScomTest::test__MultiChipScomWrite_proc> ERROR : Unexpected error log from write1" );
- fails++;
- errlCommit(l_err,SCOM_COMP_ID);
- }
- else if(read_data[x] != test_data[x].data)
- {
- TRACFCOMP(g_trac_scom, "ScomTest::test__MultiChipScomWrite_proc> [%d] FSISCOM Read: Data mismatch : addr=0x%X, read_data=0x%llx, write_data=0x%llx", x, test_data[x].addr, read_data[x], test_data[x].data);
- TS_FAIL( "ScomTest::test__MultiChipScomWrite_proc> ERROR : Data mismatch between read and expected data" );
- fails++;
- }
-
}
TRACFCOMP( g_trac_scom, "ScomTest::test__MultiChipScomWrite_proc> %d/%d fails", fails, total );
diff --git a/src/usr/scom/scom.C b/src/usr/scom/scom.C
index 22567fb49..d8d696c52 100644
--- a/src/usr/scom/scom.C
+++ b/src/usr/scom/scom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -50,7 +50,6 @@
#include <targeting/common/utilFilter.H>
#include <targeting/namedtarget.H>
-#include <config.h>
#ifndef __HOSTBOOT_RUNTIME
#ifdef CONFIG_SECUREBOOT
diff --git a/src/usr/scom/scomtrans.C b/src/usr/scom/scomtrans.C
index bb5d8b282..6f0275e33 100644
--- a/src/usr/scom/scomtrans.C
+++ b/src/usr/scom/scomtrans.C
@@ -187,6 +187,16 @@ DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
TARGETING::TYPE_OMI,
startScomProcess);
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::SCOM,
+ TARGETING::TYPE_NPU,
+ startScomProcess);
+
+DEVICE_REGISTER_ROUTE(DeviceFW::WILDCARD,
+ DeviceFW::SCOM,
+ TARGETING::TYPE_MEM_PORT,
+ startScomProcess);
+
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
errlHndl_t startScomProcess(DeviceFW::OperationType i_opType,
@@ -296,9 +306,10 @@ errlHndl_t scomTranslate(TARGETING::Target * &i_target,
// Get the type attribute.
TARGETING::TYPE l_type = i_target->getAttr<TARGETING::ATTR_TYPE>();
- centaurChipUnits_t l_chipUnit = CENTAUR_CHIP;
+ centaurChipUnits_t l_cenChipUnit = CENTAUR_CHIP;
+ p9ChipUnits_t l_p9ChipUnit = NONE;
- if(false == getChipUnitCentaur(l_type,l_chipUnit))
+ if(false == getChipUnitCentaur(l_type,l_cenChipUnit))
{
l_err = centaur_translation(i_target,
l_type,
@@ -306,14 +317,21 @@ errlHndl_t scomTranslate(TARGETING::Target * &i_target,
i_opMode);
o_needsWakeup = false;
}
- else
+ else if(false == getChipUnitP9(l_type,l_p9ChipUnit))
{
l_err = p9_translation(i_target,
- l_type,
- io_addr,
- o_needsWakeup,
- i_opMode);
+ l_type,
+ io_addr,
+ o_needsWakeup,
+ i_opMode);
+ }
+ else
+ {
+ // The only type leftover should be mem_port, and there is
+ // no translation required for that
+ assert( TARGETING::TYPE_MEM_PORT == l_type );
}
+
return l_err;
}
@@ -960,6 +978,11 @@ bool getChipUnitP9 (TARGETING::TYPE i_type,
o_chipUnit = PU_OMIC_CHIPUNIT;
break;
}
+ case(TARGETING::TYPE_NPU) :
+ {
+ o_chipUnit = PU_NPU_CHIPUNIT;
+ break;
+ }
default:
{
l_isError = true;
diff --git a/src/usr/scom/test/scomtest.H b/src/usr/scom/test/scomtest.H
index 87444367b..0ad82d625 100644
--- a/src/usr/scom/test/scomtest.H
+++ b/src/usr/scom/test/scomtest.H
@@ -39,7 +39,6 @@
#include <targeting/common/util.H>
#include <targeting/common/utilFilter.H>
#include <scom/scomif.H>
-#include <config.h>
#include <devicefw/driverif.H>
@@ -449,9 +448,7 @@ public:
{ scom_targets[myPROC0], 0x80000C010D010C3F ,0x1234432112344321, false, TARGETING::MODEL_POWER9 },
{ scom_targets[myPROC0], 0x80000C0107011C3F, 0x123443211234ABAB, false, TARGETING::MODEL_NIMBUS },
{ scom_targets[myPROC0], 0x80000C0107011C3F, 0x123443211234ABAB, false, TARGETING::MODEL_CUMULUS },
-#ifndef CONFIG_AXONE_BRING_UP
{ scom_targets[myPROC0], 0x800040000701103F, 0x123443211234ABAB, false, TARGETING::MODEL_AXONE },
-#endif
{ scom_targets[myPROC0], 0x8FFFFFFFFFFFFFFF, 0x123443211234ABAB, true, TARGETING::MODEL_POWER9 },
};
const uint64_t NUM_ADDRS = sizeof(test_data)/sizeof(test_data[0]);
@@ -1190,10 +1187,8 @@ public:
{ scom_targets[myMC1],0x07010008, 0x08010008, false, TARGETING::MODEL_AXONE},
{ scom_targets[myMC0],0x0FFFFFFF, 0x0FFFFFFF, true, TARGETING::MODEL_AXONE},
{ scom_targets[myMC1],0x0FFFFFFF, 0x0FFFFFFF, true, TARGETING::MODEL_AXONE},
-#ifndef CONFIG_AXONE_BRING_UP
- { scom_targets[myMI0],0x02010803, 0x02010803, false, TARGETING::MODEL_AXONE},
- { scom_targets[myMI3],0x02010803, 0x03010803, false, TARGETING::MODEL_AXONE},
-#endif
+ { scom_targets[myMI0],0x05010810, 0x05010810, false, TARGETING::MODEL_AXONE},
+ { scom_targets[myMI3],0x05010810, 0x06010810, false, TARGETING::MODEL_AXONE},
{ scom_targets[myMI0],0x0FFFFFFF, 0x0FFFFFFF, true, TARGETING::MODEL_AXONE},
{ scom_targets[myMI3],0x0FFFFFFF, 0x0FFFFFFF, true, TARGETING::MODEL_AXONE},
{ scom_targets[myMCC0],0x07010900, 0x07010900, false, TARGETING::MODEL_AXONE},
diff --git a/src/usr/secureboot/HBconfig b/src/usr/secureboot/HBconfig
index af987887c..4f1a179b4 100644
--- a/src/usr/secureboot/HBconfig
+++ b/src/usr/secureboot/HBconfig
@@ -22,3 +22,17 @@ config TPM_NVIDX_VALIDATE
depends on TPMDD
help
Validate TPM MFG NV Index Provisioning during IPL
+
+config PHYS_PRES_PWR_BUTTON
+ default n
+ depends on !PHYS_PRES_JUMPER
+ help
+ Support asserting Physical Presence via pushing the Power Button
+ on the system
+
+config PHYS_PRES_JUMPER
+ default n
+ depends on !PHYS_PRES_PRW_BUTTON
+ help
+ Support asserting Physical Presence via a jumper on the TPM Card
+ Currently not supported.
diff --git a/src/usr/secureboot/README.md b/src/usr/secureboot/README.md
new file mode 100644
index 000000000..979cada54
--- /dev/null
+++ b/src/usr/secureboot/README.md
@@ -0,0 +1,64 @@
+# Secureboot Services in Hostboot
+Hostboot provides multiple services to help secure the system and
+ ensure that only 'trusted' code is running on it. The multiple sub-directories
+ implement the various interfaces defined in the
+ [src/include/usr/secureboot/](../../include/usr/secureboot/) directory.
+
+## Directories
+* __base__
+ * The modules here define the core secureboot support: **defining and
+ implementing interfaces to retrieve the security state of the system**
+ * The directory is called 'base' because its contents are included in the
+ Hostboot Base Image (HBB) partition
+ * See [base/README.md](base/README.md) for more details
+
+* __common__
+ * The modules here provide common support like tracing, error callouts,
+ definitions of the secure "container" header, etc, that is used by the
+ secureboot modules in the peer directories
+ * See [common/README.md](common/README.md) for more details
+
+* __ext__
+ * The modules here provide some additional secureboot capabilities that are
+ beyond the core secureboot functionality found in the "base" directory
+ * This directory is called 'ext' because its contents are included in the
+ Hostboot Extended Image (HBI)
+ * Any module here can call into the Hostboot Base Image (ie the 'base' code
+ in the HBB partition)), but Hostboot Base Image modules cannot call into
+ these extended image modules
+ * See [ext/README.md](ext/README.md) for more details
+
+* __node_comm__
+ * The modules here implement a node-to-node communication protocol that is
+ used on multinode systems to share secureboot data between the nodes
+ * See [node_comm/README.md](node_comm/README.md) for more details
+
+* __runtime__
+ * The modules here implement a small subset of secureboot code that is used by
+ Hostboot runtime services.
+ * See [runtime/README.md](runtime/README.md) for more details
+
+* __smf__
+ * The modules here distribute different amounts of Secure SMF memory between
+ the available processors on the system based on a user-configurable petitboot
+ setting
+ * If we ever supported this on P9 FSP-based systems, the SMF memory amount
+ would be passed from the FSP to Hostboot using attributes.
+ * See [smf/README.md](smf/README.md) for more details
+
+* __trusted__
+ * The modules here define the trusted boot support which uses TPMs (Trusted
+ Platform Modules) to track what code is running on the system
+ * See [trusted/README.md](trusted/README.md) for more details
+
+## Other Files
+* __HBconfig__
+ * Standard HBconfig file that defines secureboot- and trustedboot-related
+ Hostboot compile variables
+
+* __makefile__
+ * Standard Hostboot makefile
+
+* __[README.md](./README.md)__
+ * This file
+
diff --git a/src/usr/secureboot/base/README.md b/src/usr/secureboot/base/README.md
new file mode 100644
index 000000000..e761c1f2f
--- /dev/null
+++ b/src/usr/secureboot/base/README.md
@@ -0,0 +1,60 @@
+# **'base'** Secureboot Services in Hostboot
+This directory implements the core of the secureboot-related functionality
+ that Hostboot provides.
+It is available in the Hostboot Base Image (ie the HBB partition) and all
+ non-runtime Hostboot code can invoke functions provided by it.
+
+## Key Points
+* The **libsecureboot_base.so** module created here is available in Hostboot's
+ base image and is used to securely bringup the rest of the Hostboot.
+* It implements the functions in these header files:
+ * [service.H](../../../include/usr/secureboot/service.H)
+ * [settings.H](../../../include/usr/secureboot/settings.H)
+* It is used to tell if security is enabled at the system or processor level
+* It is used to determine the state of the secureboot jumper on the different
+ processors
+* It provides the interface into the SecureRom to verify code packages run
+ on the system
+
+## Files
+
+* __header.C__
+ * Implements functions related to loading and retrieving the
+ Hostboot Base header from Hostboot Base (HBB) PNOR partition
+
+* __makefile__
+ * Standard Hostboot makefile
+
+* __purge.H__
+ * Defines a special purge function
+
+* __[README.md](./README.md)__
+ * This file
+
+* __securerommgr.C, securerommgr.H__
+ * Defines and implements the SecureRomManager class and its member functions
+ * These functions call into the securerom and takes advantage of
+ its functionality
+
+* __service.C__
+ * Retrieves the secureboot registers on the processors in the system
+ * These functions are then used to add information to errorlogs and traces
+ * Initliaizes the SecureRomManager class
+ * Function to handle special secureboot failures
+ * Retrieves some global secureboot settings taken from Hostboot's bootloader
+ * NOTE: Functions in this file call into functions in settings.C when
+ appropriate
+
+* __settings.C__
+ * Gets and Sets the two primary Secureboot-related SCOM registers:
+ * ProcSecurity (aka Proc Security Switch)
+ * ProcCbsControl
+ * Also applies knowledge of key bits of these two registers, like returning
+ if a processor is set in 'secureboot enabled mode' and what the state of its
+ secureboot jumper is
+
+
+## sub-directories
+* __test__
+ * Standard Hostboot test directory that implements CXX Unit Tests
+
diff --git a/src/usr/secureboot/base/securerommgr.C b/src/usr/secureboot/base/securerommgr.C
index 17becb6b6..c9e6789cd 100644
--- a/src/usr/secureboot/base/securerommgr.C
+++ b/src/usr/secureboot/base/securerommgr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,7 +39,6 @@
#include "securerommgr.H"
#include <secureboot/settings.H>
-#include <config.h>
#include <console/consoleif.H>
#include <secureboot/containerheader.H>
#include "../common/errlud_secure.H"
diff --git a/src/usr/secureboot/base/service.C b/src/usr/secureboot/base/service.C
index 4f115c219..ad6ec691c 100644
--- a/src/usr/secureboot/base/service.C
+++ b/src/usr/secureboot/base/service.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,7 +27,6 @@
#include <sys/mm.h>
#include <util/singleton.H>
#include <secureboot/secure_reasoncodes.H>
-#include <config.h>
#include <devicefw/userif.H>
#include <targeting/common/utilFilter.H>
#include <targeting/common/targetservice.H>
diff --git a/src/usr/secureboot/base/settings.C b/src/usr/secureboot/base/settings.C
index 2ecf45b4a..ec873c47c 100644
--- a/src/usr/secureboot/base/settings.C
+++ b/src/usr/secureboot/base/settings.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -31,7 +31,6 @@
#include <targeting/common/target.H>
#include <initservice/initserviceif.H>
#include <secureboot/settings.H>
-#include <config.h>
#include <console/consoleif.H>
#include <kernel/console.H>
diff --git a/src/usr/secureboot/common/README.md b/src/usr/secureboot/common/README.md
new file mode 100644
index 000000000..56ff15953
--- /dev/null
+++ b/src/usr/secureboot/common/README.md
@@ -0,0 +1,33 @@
+# **'common'** Secureboot Services in Hostboot
+This directory implements utility functions for tracing and error logging
+ that other secureboot modules in the peer directories can use.
+For example, the secureboot_base, secureboot_rt (runtime), secureboot_trusted,
+secureboot_ext, and node_comm modules use these functions.
+
+## Files
+
+* __common.mk__
+ * Makefile that other makefiles can call to include the generated .o files
+
+* __containerheader.C__
+ * Implements the ContainerHeader class's member functions
+ * Functions are defined in
+ [containerheader.H](../../../include/usr/secureboot/containerheader.H)
+
+* __errlud_secure.C, errlud_secure.H__
+ * These files define and implement custom error log user detail sections to
+ capture security information on the system
+
+* __[README.md](./README.md)__
+ * This file
+
+* __securetrace.C, securetrace.H__
+ * Defines and implements standard Hostboot trace descriptors for the
+ secureboot component
+
+## sub-directories
+* __plugins__
+ * Standard Hostboot 'plugins' directory where the errorlog parser finds the
+ information to properly parse the custom error log user detail sections
+ defined in errlud_secure.H
+
diff --git a/src/usr/secureboot/common/containerheader.C b/src/usr/secureboot/common/containerheader.C
index 53baa5afc..28c2c551f 100644
--- a/src/usr/secureboot/common/containerheader.C
+++ b/src/usr/secureboot/common/containerheader.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -514,6 +514,7 @@ void ContainerHeader::parseFlags()
& LAB_OVERRIDE_FLAG);
iv_sbFlags.hw_key_transition =( iv_headerInfo.hw_prefix_hdr.flags
& KEY_TRANSITION_FLAG);
+ iv_sbFlags.sw_hash = iv_headerInfo.sw_hdr.flags & HASH_PAGE_TABLE_FLAG;
}
#ifndef __HOSTBOOT_RUNTIME
diff --git a/src/usr/secureboot/ext/README.md b/src/usr/secureboot/ext/README.md
new file mode 100644
index 000000000..797905b0d
--- /dev/null
+++ b/src/usr/secureboot/ext/README.md
@@ -0,0 +1,24 @@
+# **'ext'** Secureboot Services in Hostboot
+This directory implements additional (or 'extended') secureboot functionality
+ that is not considered part of the 'base' secureboot support.
+
+## Files
+
+* __makefile__
+ * Standard Hostboot makefile
+
+* __phys_presence.C__
+ * Implements the 'physical presence'-related functions, which are used to
+ assert that a system owner is physically present at the site of a system.
+ * This is done by using GPIO devices on the system's power button to
+ capture that the button was physically pressed.
+ * Functions are defined in
+ [phys_presence_if.H](../../../include/usr/secureboot/phys_presence_if.H)
+
+* __[README.md](./README.md)__
+ * This file
+
+* __service_ext.C__
+ * Implements some additional (or 'extended') functionality as defined in
+ [service_ext.H](../../../include/usr/secureboot/service_ext.H)
+
diff --git a/src/usr/secureboot/ext/drtm.C b/src/usr/secureboot/ext/drtm.C
index bec207b7d..c897f0749 100644
--- a/src/usr/secureboot/ext/drtm.C
+++ b/src/usr/secureboot/ext/drtm.C
@@ -24,7 +24,6 @@
/* IBM_PROLOG_END_TAG */
#include <stdint.h>
-#include <config.h>
#include <builtins.h>
#include <limits.h>
#include <string.h>
diff --git a/src/usr/secureboot/ext/makefile b/src/usr/secureboot/ext/makefile
index 9b5adeaf7..d573515c6 100644
--- a/src/usr/secureboot/ext/makefile
+++ b/src/usr/secureboot/ext/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2018
+# Contributors Listed Below - COPYRIGHT 2013,2019
# [+] International Business Machines Corp.
#
#
@@ -30,6 +30,7 @@ PERV_HWP_PATH = $(ROOTPATH)/src/import/chips/p9/procedures/hwp/perv
OBJS += $(if $(CONFIG_DRTM),drtm.o)
OBJS += $(if $(CONFIG_SECUREBOOT), service_ext.o)
+OBJS += $(if $(CONFIG_PHYS_PRES_PWR_BUTTON), phys_presence.o)
VPATH += $(PERV_HWP_PATH)
diff --git a/src/usr/secureboot/ext/phys_presence.C b/src/usr/secureboot/ext/phys_presence.C
new file mode 100644
index 000000000..a9e0231bf
--- /dev/null
+++ b/src/usr/secureboot/ext/phys_presence.C
@@ -0,0 +1,479 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/ext/phys_presence.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file phys_presence.C
+ *
+ * @brief Implements Interfaces to Detect and Open Physical Presence Windows
+ *
+ */
+
+#include <config.h>
+#include <targeting/common/util.H>
+#include <targeting/common/target.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <devicefw/driverif.H>
+#include <console/consoleif.H>
+#include <util/misc.H>
+#include <initservice/initserviceif.H>
+#include <initservice/istepdispatcherif.H>
+#include <secureboot/secure_reasoncodes.H>
+#include <secureboot/phys_presence_if.H>
+#include "../common/securetrace.H"
+#include <gpio/gpioif.H>
+
+using namespace TARGETING;
+using namespace GPIO;
+
+namespace SECUREBOOT
+{
+
+errlHndl_t detectPhysPresence(void)
+{
+ errlHndl_t err = nullptr;
+
+ SB_ENTER("detectPhysPresence");
+
+ // Not supported in simics
+ if (Util::isSimicsRunning())
+ {
+ SB_ERR("detectPhysPresence: Skipping as not supported in simics");
+
+ // Normally don't have multiple return statements, but
+ // this solves having 2 do-while loops
+ return err;
+ }
+
+ // Declare local variables here as there might be an operation
+ // after the do-while() loop
+ Target * mproc = nullptr;
+ uint8_t led_data = 0;
+ ATTR_GPIO_INFO_PHYS_PRES_type gpioInfo = {};
+ uint8_t led_window_open = 0;
+ uint8_t led_phys_pres_asserted = 0;
+ bool is_window_open = false;
+ bool is_phys_pres_asserted = false;
+
+ // Get the attributes associated with Physical Presence
+ TargetService& tS = targetService();
+ Target* sys = nullptr;
+ (void) tS.getTopLevelTarget( sys );
+ assert(sys, "detectPhysPresence: system target is nullptr");
+
+ do
+ {
+ uint8_t attr_open_window =
+ sys->getAttr<ATTR_PHYS_PRES_REQUEST_OPEN_WINDOW>();
+
+ uint8_t attr_fake_assert = sys->getAttr<ATTR_PHYS_PRES_FAKE_ASSERT>();
+ // NOTE: Using attributes to request opening the physical presence window
+ // and/or fake the assertion of physical presence is only for testing
+ // purposes. Both attributes will default to 'no' and cannot be changed
+ // when security is enabled in a production driver since attribute
+ // overrides are not allowed in that scenario.
+ SB_INF("detectPhysPresence: attr_open_window=%d (0x%X), "
+ "attr_fake_assert=%d (0x%X)",
+ attr_open_window, attr_open_window,
+ attr_fake_assert, attr_fake_assert);
+
+ // The PCA9551 device that controls the "window open" and
+ // "physical presence asserted" logic is connected to the master processor
+ err = targetService().queryMasterProcChipTargetHandle(mproc);
+ if(err)
+ {
+ SB_ERR("detectPhysPresence: call to queryMasterProcChipTargetHandle "
+ "failed. err_plid=0x%X, err_rc=0x%X",
+ ERRL_GETPLID_SAFE(err),
+ ERRL_GETRC_SAFE(err));
+
+ err->collectTrace(SECURE_COMP_NAME);
+ break;
+ }
+
+ // Get the attribute with the needed GPIO information
+ if (mproc->tryGetAttr<ATTR_GPIO_INFO_PHYS_PRES>(gpioInfo))
+ {
+ SB_INF("detectPhysPresence: gpioInfo: e%d/p%d/devAddr=0x%X, "
+ "windowOpenPin=%d, physPresPin=%d",
+ gpioInfo.engine, gpioInfo.port, gpioInfo.devAddr,
+ gpioInfo.windowOpenPin, gpioInfo.physicalPresencePin);
+ }
+ else
+ {
+ SB_ERR("detectPhysPresence: couldn't find GPIO_INFO_PHYS_PRES "
+ "on mproc 0x%.08X", get_huid(mproc));
+
+ /*@
+ * @errortype
+ * @reasoncode RC_PHYS_PRES_ATTR_NOT_FOUND
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_PHYS_PRES_DETECT
+ * @userdata1 HUID of Master Processor Target
+ * @userdata2 ATTR_GPIO_INFO_PHYS_PRES hash value
+ * @devdesc Master processor target did not have
+ * ATTR_GPIO_INFO_PHYS_PRES associated with it
+ * @custdesc A problem occurred during the IPL
+ * of the system.
+ */
+ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_PHYS_PRES_DETECT,
+ RC_PHYS_PRES_ATTR_NOT_FOUND,
+ get_huid(mproc),
+ ATTR_GPIO_INFO_PHYS_PRES,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ err->collectTrace( SECURE_COMP_NAME );
+ break;
+ }
+
+ // Get "window open" and "physical presence asserted" LEDs/Pins
+ led_window_open = PCA9551_LED0 << gpioInfo.windowOpenPin;
+ led_phys_pres_asserted = PCA9551_LED0 << gpioInfo.physicalPresencePin;
+
+ // Read PCA9551 INPUT Register to get LED Values
+ led_data = 0;
+ err = gpioPca9551GetLeds(mproc, led_data);
+ if(err)
+ {
+ SB_ERR("detectPhysPresence: Reading LEDs failed");
+ break;
+ }
+
+ // Look for "window open" and "physical presence asserted"
+ // LEDs/PINs represent "WINDOW_OPEN_N" and "PHYS_PRESENCE_N" so need
+ // to invert their values to get their true meaning
+ is_window_open = ! (led_window_open & led_data);
+
+ // Only care if its asserted if the window is open
+ // (technically it's not supposed to be asserted unless the window is open)
+ is_phys_pres_asserted = is_window_open &&
+ (! (led_phys_pres_asserted & led_data));
+
+
+ // Look for special case to fake assertion
+ if ((is_window_open == true ) &&
+ (is_phys_pres_asserted == false) &&
+ (attr_fake_assert != 0 ))
+ {
+ is_phys_pres_asserted = true;
+ SB_INF("detectPhysPresence: FAKING Physical Assertion: "
+ "is_WO=%d, is_PPA=%d, attr_FA=0x%X",
+ is_window_open, is_phys_pres_asserted,
+ attr_fake_assert);
+
+ // Write the attribute so faking the assert only happens once
+ sys->setAttr<ATTR_PHYS_PRES_FAKE_ASSERT>(0x00);
+ }
+
+ SB_INF("detectPhysPresence: LEDs=0x%.2X, led_WO=0x%X, led_PPA=0x%X, "
+ "attrWO=0x%X, attr_FA=0x%X, is_WO=%d, is_PPA=%d",
+ led_data, led_window_open, led_phys_pres_asserted,
+ attr_open_window, attr_fake_assert,
+ is_window_open, is_phys_pres_asserted);
+
+ } while(0);
+
+ // Regardless of any previous error, attempt to close the window here
+ // if it was already opened
+ if (is_window_open == true)
+ {
+ errlHndl_t err_close = nullptr;
+ err_close = gpioPca9551SetLed(mproc,
+ static_cast<GPIO::PCA9551_LEDS_t>
+ (led_window_open),
+ PCA9551_OUTPUT_HIGH_IMPEDANCE,
+ led_data);
+
+ if (err_close == nullptr)
+ {
+ // Verify that window was closed
+ // LEDs/PIN represents "WINDOW_OPEN_N" so looking for a "1" in
+ // that position
+ if (!(led_data & led_window_open))
+ {
+ SB_ERR("detectPhysPresence: Closed Window LEDs = 0x%.2X "
+ "indicated that LED %d is showing window is still open",
+ led_data, led_window_open);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_PHYS_PRES_WINDOW_NOT_CLOSED
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_PHYS_PRES_DETECT
+ * @userdata1 HUID of Master Processor Target
+ * @userdata2[0:31] LED Data from PCA9551
+ * @userdata[32:63] LED Windoow Open LED (aka PIN)
+ * @devdesc Attempt to close physical presence window
+ * did not close the window
+ * @custdesc A problem occurred during the IPL
+ * of the system.
+ */
+ err_close = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_PHYS_PRES_DETECT,
+ RC_PHYS_PRES_WINDOW_NOT_CLOSED,
+ get_huid(mproc),
+ TWO_UINT32_TO_UINT64(
+ led_data,
+ led_window_open),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ }
+ else
+ {
+ SB_INF("detectPhysPresence: Closed Window LEDs = 0x%.2X",
+ led_data);
+ }
+
+ }
+
+ if (err_close)
+ {
+ if (err)
+ {
+ // commit new erro with PLID or original err
+ err_close->plid(err->plid());
+ SB_ERR("detectPhysPresence: Error in closing window. "
+ "Committing err_close eid=0x%X "
+ "with plid of original err: 0x%X",
+ err_close->eid(), err_close->plid());
+
+ err_close->collectTrace( SECURE_COMP_NAME );
+ errlCommit(err_close, SECURE_COMP_ID);
+ }
+ else
+ {
+ SB_ERR("detectPhysPresence: Error in closing window. "
+ "err_close eid=0x%X plid=0x%X",
+ err_close->eid(), err_close->plid());
+ err_close->collectTrace( SECURE_COMP_NAME );
+ err = err_close;
+ err_close = nullptr;
+ }
+ }
+ } // end of 'must close window'
+
+ if (err == nullptr)
+ {
+ // If no error, including in closing the window, then write attribute
+ // for Physical Presence Assertion
+ sys->setAttr<ATTR_PHYS_PRES_ASSERTED>(is_phys_pres_asserted);
+ }
+
+ SB_EXIT("detectPhysPresence: err rc=0x%X",
+ ERRL_GETRC_SAFE(err));
+
+ return err;
+}
+
+errlHndl_t handlePhysPresenceWindow(void)
+{
+ errlHndl_t err = nullptr;
+
+ SB_ENTER("handlePhysPresenceWindow");
+
+ // Declare local variables here as there might be an operation
+ // after the do-while() loop
+ Target * mproc = nullptr;
+ uint8_t led_data = 0;
+ ATTR_GPIO_INFO_PHYS_PRES_type gpioInfo = {};
+ uint8_t led_window_open = 0;
+ bool is_window_open = false;
+
+ do
+ {
+
+ // Not supported in simics
+ if (Util::isSimicsRunning())
+ {
+ SB_INF("handlePhysPresenceWindow: Skipping as not supported in simics");
+ break;
+ }
+
+ // Get the attributes associated with Physical Presence
+ TargetService& tS = targetService();
+ Target* sys = nullptr;
+ (void) tS.getTopLevelTarget( sys );
+ assert(sys, "handlePhysPresenceWindow: system target is nullptr");
+
+ // NOTE: Using attributes to request opening the physical presence window
+ // and/or fake the assertion of physical presence is only for testing
+ // purposes. Both attributes will default to 'no' and cannot be changed
+ // when security is enabled in a production driver since attribute
+ // overrides are not allowed in that scenario.
+ uint8_t attr_open_window =
+ sys->getAttr<ATTR_PHYS_PRES_REQUEST_OPEN_WINDOW>();
+ uint8_t attr_phys_pres_asserted = sys->getAttr<ATTR_PHYS_PRES_ASSERTED>();
+
+ if (attr_open_window == 0)
+ {
+ SB_INF("handlePhysPresenceWindow: attr_open_window=0x%.2X: "
+ "no need to open window (attr_phys_pres_asserted=0x%.2X)",
+ attr_open_window, attr_phys_pres_asserted);
+ break;
+ }
+ // This solves the issue of using attribute overrides to open the window,
+ // as they don't always get cleared on re-IPLs and attr_open_window might
+ // still != 0
+ else if (attr_phys_pres_asserted != 0)
+ {
+ SB_INF("handlePhysPresenceWindow: attr_open_window=0x%.2X, but "
+ "attr_phys_pres_asserted=0x%.2X, so no need to open window. "
+ "Clearing open window request",
+ attr_open_window, attr_phys_pres_asserted);
+
+ // Close request to open the window
+ sys->setAttr<ATTR_PHYS_PRES_REQUEST_OPEN_WINDOW>(0x00);
+ break;
+ }
+ else
+ {
+ SB_INF("handlePhysPresenceWindow: attr_open_window=0x%.2X, "
+ "attr_phys_pres_asserted=0x%.2X: "
+ "Will Open Window To Detect Physical Presence",
+ attr_open_window, attr_phys_pres_asserted);
+ }
+
+ // The PCA9551 device that controls the "window open" and
+ // "physical presence asserted" logic is connected to the master processor
+ err = targetService().queryMasterProcChipTargetHandle(mproc);
+ if(err)
+ {
+ SB_ERR("handlePhysPresenceWindow: call to queryMasterProcChipTargetHandle "
+ "failed. err_plid=0x%X, err_rc=0x%X",
+ ERRL_GETPLID_SAFE(err),
+ ERRL_GETRC_SAFE(err));
+
+ err->collectTrace(SECURE_COMP_NAME);
+ break;
+ }
+
+ // Get "window open" LED/Pin
+ led_window_open = PCA9551_LED0 << gpioInfo.windowOpenPin;
+
+
+ // Open The Window
+ led_data=0; // For INPUT register read-back
+ err = gpioPca9551SetLed(mproc,
+ static_cast<GPIO::PCA9551_LEDS_t>
+ (led_window_open),
+ PCA9551_OUTPUT_LOW,
+ led_data);
+
+ // Verify that the "window open" LED is set
+ // LEDs/PINs represent "WINDOW_OPEN_N" and "PHYS_PRESENCE_N" so need
+ // to invert their values to get their true meaning
+ is_window_open = ! (led_window_open & led_data);
+ if (is_window_open == true)
+ {
+ SB_INF("handlePhysPresenceWindow: Window is Opened: "
+ "led_window_open=0x%X, led_data=0x%.2X",
+ led_window_open, led_data);
+ }
+ else
+ {
+ SB_ERR("handlePhysPresenceWindow: ERROR: Window is NOT Opened: "
+ "led_window_open=0x%X, led_data=0x%.2X",
+ led_window_open, led_data);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_PHYS_PRES_WINDOW_NOT_OPENED
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_PHYS_PRES_OPEN_WINDOW
+ * @userdata1 HUID of Master Processor Target
+ * @userdata2[0:31] LED Data from PCA9551
+ * @userdata2[32:63] LED Windoow Open LED (aka PIN)
+ * @devdesc Attempt to open physical presence window
+ * did not close the window
+ * @custdesc A problem occurred during the IPL
+ * of the system.
+ */
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_PHYS_PRES_OPEN_WINDOW,
+ RC_PHYS_PRES_WINDOW_NOT_OPENED,
+ get_huid(mproc),
+ TWO_UINT32_TO_UINT64(
+ led_data,
+ led_window_open),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ err->collectTrace( SECURE_COMP_NAME );
+ break;
+ }
+
+ // Close request to open the window and sync attributes
+ sys->setAttr<ATTR_PHYS_PRES_REQUEST_OPEN_WINDOW>(0x00);
+
+ if(INITSERVICE::spBaseServicesEnabled())
+ {
+ // Sync all attributes to FSP before powering off
+ err = TARGETING::AttrRP::syncAllAttributesToFsp();
+ if( err )
+ {
+ // Failed to sync all attributes to FSP; this is not
+ // necessarily fatal. The power off will continue,
+ // but this issue will be logged.
+ SB_ERR("handlePhysPresenceWindow: Error syncing "
+ "attributes to FSP, RC=0x%04X, PLID=0x%08X",
+ ERRL_GETRC_SAFE(err),
+ ERRL_GETPLID_SAFE(err));
+ errlCommit(err,SECURE_COMP_ID );
+ }
+ }
+
+ // Alert the users that the system will power off
+#ifdef CONFIG_CONSOLE
+ CONSOLE::displayf(SECURE_COMP_NAME, "Opened Physical Presence Detection Window\n");
+ CONSOLE::displayf(SECURE_COMP_NAME, "System Will Power Off and Wait For Manual Power On\n");
+ CONSOLE::flush();
+#endif
+
+ // Power Off the System
+#ifdef CONFIG_BMC_IPMI
+ // Initiate a graceful power off
+ SB_INF("handlePhysPresenceWindow: Opened Physical Presence Detection Window. "
+ "System Will Power Off and Wait For Manual Power On. "
+ "Requesting power off");
+ INITSERVICE::requestPowerOff();
+#else //non-IPMI
+ SB_INF("handlePhysPresenceWindow: Opened Physical Presence Detection Window. "
+ "Calling INITSERVICE::doShutdown() with "
+ "RC_PHYS_PRES_WINDOW_OPENED_SHUTDOWN = 0x%08X",
+ RC_PHYS_PRES_WINDOW_OPENED_SHUTDOWN);
+ INITSERVICE::doShutdown(RC_PHYS_PRES_WINDOW_OPENED_SHUTDOWN);
+#endif
+
+
+ } while (0);
+
+ SB_EXIT("handlePhysPresenceWindow: err_rc=0x%X",
+ ERRL_GETRC_SAFE(err));
+
+ return err;
+}
+
+} // namespace SECUREBOOT
diff --git a/src/usr/secureboot/ext/service_ext.C b/src/usr/secureboot/ext/service_ext.C
index 1f8595a71..b9050af43 100644
--- a/src/usr/secureboot/ext/service_ext.C
+++ b/src/usr/secureboot/ext/service_ext.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,7 +36,6 @@
#include <fapi2/plat_hwp_invoker.H>
#include <p9_update_security_ctrl.H>
-#include <config.h>
namespace SECUREBOOT
{
@@ -69,7 +68,7 @@ void lockAbusSecMailboxes()
ERRORLOG::ErrlUserDetailsTarget(*l_pProc).addToLog(l_errl);
ERRORLOG::errlCommit(l_errl, SECURE_COMP_ID);
- /*
+ /*@
* @errortype
* @reasoncode RC_LOCK_MAILBOXES_FAILED
* @moduleid MOD_LOCK_ABUS_SEC_MAILBOXES
diff --git a/src/usr/secureboot/node_comm/README.md b/src/usr/secureboot/node_comm/README.md
new file mode 100644
index 000000000..0def94860
--- /dev/null
+++ b/src/usr/secureboot/node_comm/README.md
@@ -0,0 +1,97 @@
+# **'node\_comm'** Secureboot Services in Hostboot
+This directory implements the Hostboot functions necessary to create a
+ secure channel between nodes using a series of a-bus mailbox registers
+ enabled after a-bus training but before the iovalid drop.
+This secure channel is used in a multi-node evironment for nodes to exchange
+ cryptographic material that can later be used for internode authentication
+ higher up the firmware stack.
+
+## Key Points
+* This code implements device driver-like functionality to send messages
+ across the a-bus connection from one node to another
+ * This functionality is based on a-bus mailbox registers which are used to
+ detect incoming messages, retrieve data, and send data messages to/from
+ specific nodes
+* This code establishes a master node which then starts the process of exchanging
+ information with each of the other slave nodes
+* The files are built into libnode_comm.so
+* This module implements the interfaces defined in
+ [nodecommif.H](../../../include/usr/secureboot/nodecommif.H)
+* NOTE: The P9 code references "OBUS" a lot which is the specific processor
+ chiplet that the a-bus messaging system runs through.
+
+## Algorithm
+* First, each node does the following:
+ * Determine the nodes in the system
+ * Determine the master processor of this node
+ * Determine the a-bus connection to its master processor peers on the
+ other nodes
+
+* ***The Master Processor on Master Node*** does the following
+ (see node_comm_exchange.C's nodeCommAbusExchangeMaster()):
+ * **Loop 1:** Exchange SBID/nonces between Master and each of the Slave Nodes
+ * Generate SBID/nonce and send to slave node
+ * Look for return SBID/nonce from the slave
+ * **Loop 2:** Master Node requests quotes from each Slave Node
+ * Generate and send Quote Request to a slave
+ * Look for Quote Response from the slave node
+ * Process the Quote Response that was returned from the slave node
+ * NOTE:
+ * Nonces are encoded 64-bytes of data: part random number, part node ID
+ * Quotes are a form of attestation between two TPMs on the system. See
+ TrustedComputingGroup.org's Trusted Platform Module Library Specification,
+ Family "2.0" for more details.
+
+* ***The Master Processor on each Slave Node*** does the following
+ (see node_comm_exchange.C's nodeCommAbusExchangeSlave()):
+
+ * Wait for SBID/nonce from the master node
+ * Send a SBID/nonce back to the master node
+ * Wait for Quote Request from master node
+ * Generate the Quote Response
+ * Send the Quote Response to the master node
+
+
+* NOTE: Generating the SBID/Nonces, Quote Requests, and Quote Responses above
+ all require interacting with the TPMs on the different nodes in specific
+ ways
+ * The devil is truly in the details, and the details can be found in the
+ supporting functions of node_comm_exchange.C
+* NOTE: In the event that one node fails in this process there will be an
+ attempt to poison the TPMs on that node and move on in most cases. This is
+ to prevent an entire system from failing to boot with one bad node.
+
+## Files
+
+* __makefile__
+ * Standard Hostboot makefile
+
+* __node_comm.C, node_comm.H__
+ * The majority of the sub-functions used to implement the algorithm are
+ defined and implemented here, including the a-bus mapping details between
+ the nodes
+
+* __node_comm_dd.C, node_comm_dd.H__
+ * Defines and implements the "NODECOMM" device driver that interacts directly
+ with the a-bus mailbox registers
+
+* __node_comm_exchange.C__
+ * The core of this module - the primary function nodeCommAbusExchange()
+ is implemented here and shows the high-level data flow between the nodes
+ * The procedure for the master node is defined in nodeCommAbusExchangeMaster()
+ * The procedure for the slave nodes is defiend in nodeCommAbusExchangeSlave()
+ * The interactions with the TPM - generating and logging SBID/Nonces, Quote
+ Requests, Quote Responses - are all in this file
+
+* __node_comm_test.C__
+ * Implements the proof-of-concept "nodeCommXbus2ProcTest" test to transfer
+ data across the x-bus between processors using a similar method to the a-bus
+ mechanism
+
+* __node_comm_transfer.C, node_comm_transfer.H__
+ * Defines and implements the different types of messages that can be sent
+ between the nodes, including the actual send and receive functions
+
+* __[README.md](./README.md)__
+ * This file
+
diff --git a/src/usr/secureboot/node_comm/node_comm.H b/src/usr/secureboot/node_comm/node_comm.H
index e44893683..227d53ac2 100644
--- a/src/usr/secureboot/node_comm/node_comm.H
+++ b/src/usr/secureboot/node_comm/node_comm.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -28,11 +28,10 @@
// ----------------------------------------------
// Includes
// ----------------------------------------------
-#include <config.h>
#include <time.h>
#include <devicefw/userif.H>
#include <trace/interface.H>
-#include <scom/centaurScomCache.H> // for TRACE_ERR_FMT, TRACE_ERR_ARGS
+#include <errl/errlentry.H> // for TRACE_ERR_FMT, TRACE_ERR_ARGS
#include <secureboot/nodecommif.H>
#include "../trusted/trustedboot.H"
#include <secureboot/trustedbootif.H>
diff --git a/src/usr/secureboot/node_comm/node_comm_dd.H b/src/usr/secureboot/node_comm/node_comm_dd.H
index 212ab24df..f8b057bcd 100644
--- a/src/usr/secureboot/node_comm/node_comm_dd.H
+++ b/src/usr/secureboot/node_comm/node_comm_dd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -28,7 +28,6 @@
// ----------------------------------------------
// Includes
// ----------------------------------------------
-#include <config.h>
#include <devicefw/userif.H>
#include <secureboot/nodecommif.H>
diff --git a/src/usr/secureboot/node_comm/node_comm_exchange.C b/src/usr/secureboot/node_comm/node_comm_exchange.C
index ff8ff8a31..ccbd973d3 100644
--- a/src/usr/secureboot/node_comm/node_comm_exchange.C
+++ b/src/usr/secureboot/node_comm/node_comm_exchange.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -51,7 +51,6 @@
#include <targeting/targplatutil.H>
#include <sys/internode.h>
#include <util/misc.H>
-#include <config.h>
#include "node_comm.H"
#include "node_comm_transfer.H"
@@ -133,6 +132,7 @@ errlHndl_t nodeCommAbusGetRandom(uint64_t & o_nonce)
{
errlHndl_t err = nullptr;
o_nonce = NODE_COMM_DEFAULT_NONCE;
+#ifdef CONFIG_TPMDD
Target* tpm_tgt = nullptr;
TRACUCOMP(g_trac_nc,ENTER_MRK"nodeCommAbusGetRandom:");
@@ -144,9 +144,7 @@ errlHndl_t nodeCommAbusGetRandom(uint64_t & o_nonce)
// This function call requires the CONFIG check for compilation purposes,
// but no extra error handling is needed as it should not have gotten this
// far if CONFIG_TPMDD wasn't set
-#ifdef CONFIG_TPMDD
TRUSTEDBOOT::getPrimaryTpm(tpm_tgt);
-#endif
HwasState hwasState{};
if(tpm_tgt)
{
@@ -192,11 +190,9 @@ errlHndl_t nodeCommAbusGetRandom(uint64_t & o_nonce)
// This function call requires the CONFIG check for compilation purposes,
// but no extra error handling is needed as it should not have gotten this
// far if CONFIG_TPMDD wasn't set
-#ifdef CONFIG_TPMDD
err = TRUSTEDBOOT::GetRandom(tpm_tgt,
sizeof(o_nonce),
reinterpret_cast<uint8_t*>(&o_nonce));
-#endif
if (err)
{
// Reset just to make sure above call didn't change it
@@ -208,18 +204,30 @@ errlHndl_t nodeCommAbusGetRandom(uint64_t & o_nonce)
get_huid(tpm_tgt),
TRACE_ERR_ARGS(err),
o_nonce);
- // err commited outside of do-while loop below
-
// break to be safe in case code gets added later
break;
}
} while( 0 );
- if (err)
+ if(err)
{
- err->collectTrace(TRBOOT_COMP_NAME);
- err->collectTrace(NODECOMM_TRACE_NAME);
+ if(!TRUSTEDBOOT::isTpmRequired())
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommAbusGetRandom: Error occurred; "
+ "RC: 0x%.04X; PLID: 0x%.08X. TPM Required policy is off; "
+ "deleting the error and trying to continue.",
+ err->reasonCode(),
+ err->plid());
+ // TPM is not required - do not return the error
+ delete err;
+ err = nullptr;
+ }
+ else
+ {
+ err->collectTrace(TRBOOT_COMP_NAME);
+ err->collectTrace(NODECOMM_TRACE_NAME);
+ }
}
TRACFCOMP(g_trac_nc,EXIT_MRK"nodeCommAbusGetRandom: "
@@ -228,6 +236,7 @@ errlHndl_t nodeCommAbusGetRandom(uint64_t & o_nonce)
o_nonce, get_huid(tpm_tgt),
TRACE_ERR_ARGS(err));
+#endif
return err;
} // end of nodeCommAbusGetRandom
@@ -618,17 +627,19 @@ errlHndl_t nodeCommGenSlaveQuoteResponse(const MasterQuoteRequestBlob* const i_r
{
l_poisonTpmErr->plid(l_errl->plid());
}
- errlCommit(l_poisonTpmErr, SECURE_COMP_ID);
- }
- }
-
- if(l_errl)
- {
- if(!l_tpmRequired)
- {
- // TPM is not required, so no need to propagate the error up and
- // fail the boot.
- errlCommit(l_errl, SECURE_COMP_ID);
+ if(l_tpmRequired)
+ {
+ errlCommit(l_poisonTpmErr, SECURE_COMP_ID);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommGenSlaveQuoteResponse: "
+ "Could not poison TPMs. Errl PLID: 0x%.08X "
+ "Deleting the error log and continuing anyway.",
+ l_poisonTpmErr->plid());
+ delete l_poisonTpmErr;
+ l_poisonTpmErr = nullptr;
+ }
}
}
@@ -721,14 +732,19 @@ errlHndl_t nodeCommGenMasterQuoteRequest(MasterQuoteRequestBlob* const o_request
{
l_poisonTpmErr->plid(l_errl->plid());
}
- errlCommit(l_poisonTpmErr, SECURE_COMP_ID);
- }
-
- if(!l_tpmRequired)
- {
- // TPM is not required, so no need to propagate the error up and
- // fail the boot.
- errlCommit(l_errl, SECURE_COMP_ID);
+ if(l_tpmRequired)
+ {
+ errlCommit(l_poisonTpmErr, SECURE_COMP_ID);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommGenMasterQuoteRequest: "
+ "Could not poison TPMs. Errl PLID: 0x%.08X. "
+ "Deleting the error log and continuing anyway.",
+ l_poisonTpmErr->plid());
+ delete l_poisonTpmErr;
+ l_poisonTpmErr = nullptr;
+ }
}
}
@@ -814,13 +830,19 @@ errlHndl_t nodeCommProcessSlaveQuote(uint8_t* const i_slaveQuote,
{
l_poisonTpmErr->plid(l_errl->plid());
}
- errlCommit(l_poisonTpmErr, SECURE_COMP_ID);
- }
-
- if(!TRUSTEDBOOT::isTpmRequired())
- {
- // TPM is not required - do not propagate the error
- errlCommit(l_errl, SECURE_COMP_ID);
+ if(TRUSTEDBOOT::isTpmRequired())
+ {
+ errlCommit(l_poisonTpmErr, SECURE_COMP_ID);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nc, ERR_MRK"nodeCommProcessSlaveQuote: "
+ "Could not poison TPMs. Errl PLID: 0x%.08X. "
+ "Deleting the error log and continuing.",
+ l_poisonTpmErr->plid());
+ delete l_poisonTpmErr;
+ l_poisonTpmErr = nullptr;
+ }
}
}
@@ -1738,9 +1760,24 @@ errlHndl_t nodeCommAbusExchange(void)
if (err)
{
- err->collectTrace(SECURE_COMP_NAME);
- err->collectTrace(NODECOMM_TRACE_NAME);
- err->collectTrace(TRBOOT_COMP_NAME);
+ if(!TRUSTEDBOOT::isTpmRequired())
+ {
+ TRACFCOMP(g_trac_nc,EXIT_MRK"nodeCommAbusExchange:An error occurred"
+ " during secure node communication, but the TPM required "
+ "policy is not set, so the error will not be propagated."
+ " Original error RC: 0x%.04X; PLID: 0x%.08X."
+ " Deleting the error log and continuing.",
+ err->reasonCode(),
+ err->plid());
+ delete err;
+ err = nullptr;
+ }
+ else
+ {
+ err->collectTrace(SECURE_COMP_NAME);
+ err->collectTrace(NODECOMM_TRACE_NAME);
+ err->collectTrace(TRBOOT_COMP_NAME);
+ }
}
if (l_phys_path_str != nullptr)
diff --git a/src/usr/secureboot/node_comm/node_comm_transfer.C b/src/usr/secureboot/node_comm/node_comm_transfer.C
index b7afb02ef..4b82688f0 100644
--- a/src/usr/secureboot/node_comm/node_comm_transfer.C
+++ b/src/usr/secureboot/node_comm/node_comm_transfer.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -26,11 +26,10 @@
// ----------------------------------------------
// Includes
// ----------------------------------------------
-#include <config.h>
#include <time.h>
#include <devicefw/userif.H>
#include <trace/interface.H>
-#include <scom/centaurScomCache.H> // for TRACE_ERR_FMT, TRACE_ERR_ARGS
+#include <errl/errlentry.H> // for TRACE_ERR_FMT, TRACE_ERR_ARGS
#include <targeting/targplatutil.H>
#include <secureboot/nodecommif.H>
#include <secureboot/secure_reasoncodes.H>
diff --git a/src/usr/secureboot/node_comm/node_comm_transfer.H b/src/usr/secureboot/node_comm/node_comm_transfer.H
index 201661447..93f45a512 100644
--- a/src/usr/secureboot/node_comm/node_comm_transfer.H
+++ b/src/usr/secureboot/node_comm/node_comm_transfer.H
@@ -28,7 +28,6 @@
// ----------------------------------------------
// Includes
// ----------------------------------------------
-#include <config.h>
#include "node_comm.H"
#include <map>
diff --git a/src/usr/secureboot/runtime/README.md b/src/usr/secureboot/runtime/README.md
new file mode 100644
index 000000000..552ca9b6f
--- /dev/null
+++ b/src/usr/secureboot/runtime/README.md
@@ -0,0 +1,21 @@
+# **'runtime'** Secureboot Services in Hostboot
+This directory implements a small, select subset of core secureboot-related
+ functionality that Hostboot provides at runtime, ie as part of
+ Hostboot runtime services.
+
+## Files
+
+* __makefile__
+ * Standard Hostboot makefile
+
+* __[README.md](./README.md)__
+ * This file
+
+* __rt_secureboot.C__
+ * This file implements several secureboot functions for hostboot runtime
+ services
+
+## sub-directories
+* __test__
+ * Standard Hostboot test directory that implements CXX Unit Tests
+
diff --git a/src/usr/secureboot/runtime/rt_secureboot.C b/src/usr/secureboot/runtime/rt_secureboot.C
index 7c297be9e..c1608fa73 100644
--- a/src/usr/secureboot/runtime/rt_secureboot.C
+++ b/src/usr/secureboot/runtime/rt_secureboot.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -29,14 +29,13 @@
*/
#include <runtime/interface.h>
-#include <config.h>
#include "common/securetrace.H"
#include <secureboot/service.H>
#include <secureboot/secure_reasoncodes.H>
#include <errl/errlmanager.H>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <targeting/common/commontargeting.H>
#include <targeting/common/targetservice.H>
#include <devicefw/userif.H>
diff --git a/src/usr/secureboot/runtime/test/testsecureboot_rt.H b/src/usr/secureboot/runtime/test/testsecureboot_rt.H
index 380b9eb0c..5a690d3fa 100644
--- a/src/usr/secureboot/runtime/test/testsecureboot_rt.H
+++ b/src/usr/secureboot/runtime/test/testsecureboot_rt.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -33,9 +33,8 @@
#include <cxxtest/TestSuite.H>
#include <runtime/interface.h>
-#include <config.h>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <errl/errlmanager.H>
#include <devicefw/userif.H>
diff --git a/src/usr/secureboot/smf/test/testsmf.H b/src/usr/secureboot/smf/test/testsmf.H
index 81a50a6e0..fb3993724 100644
--- a/src/usr/secureboot/smf/test/testsmf.H
+++ b/src/usr/secureboot/smf/test/testsmf.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -29,6 +29,7 @@
#include <errl/errlmanager.H>
#include <targeting/common/target.H>
#include <targeting/common/targetservice.H>
+#include <targeting/common/utilFilter.H>
#include <hbotcompid.H>
#include <secureboot/smf.H>
#include <secureboot/secure_reasoncodes.H>
@@ -346,9 +347,14 @@ public:
break;
}
- if(l_smfBarSize != DISTRIBUTE_EXACT_SMF_AMT)
+ // Memory is distributed across processors so need to divide the
+ // expected results by the number of processors
+ TARGETING::TargetHandleList l_procList;
+ TARGETING::getAllChips(l_procList, TARGETING::TYPE_PROC, true);
+
+ if(l_smfBarSize != (DISTRIBUTE_EXACT_SMF_AMT/l_procList.size()))
{
- TS_FAIL("testDistributeExactAmt: Unexpected amount of memory allocated. Expected: 0x%x, actual 0x%x", DISTRIBUTE_EXACT_SMF_AMT, l_smfBarSize);
+ TS_FAIL("testDistributeExactAmt: Unexpected amount of memory allocated. Expected: 0x%x, actual 0x%x", (DISTRIBUTE_EXACT_SMF_AMT/l_procList.size()), l_smfBarSize);
}
} while(0);
@@ -400,9 +406,14 @@ public:
break;
}
- if(l_smfBarSize != DISTRIBUTE_EXACT_SMF_AMT)
+ // Memory is distributed across processors so need to divide the
+ // expected results by the number of processors
+ TARGETING::TargetHandleList l_procList;
+ TARGETING::getAllChips(l_procList, TARGETING::TYPE_PROC, true);
+
+ if(l_smfBarSize != (DISTRIBUTE_EXACT_SMF_AMT/l_procList.size()))
{
- TS_FAIL("testDistributeNotExactAmt: Unexpected amount of memory allocated. Expected: 0x%x, actual 0x%x", DISTRIBUTE_EXACT_SMF_AMT, l_smfBarSize);
+ TS_FAIL("testDistributeNotExactAmt: Unexpected amount of memory allocated. Expected: 0x%x, actual 0x%x", (DISTRIBUTE_EXACT_SMF_AMT/l_procList.size()), l_smfBarSize);
}
} while(0);
diff --git a/src/usr/secureboot/trusted/README.md b/src/usr/secureboot/trusted/README.md
new file mode 100644
index 000000000..effe75f44
--- /dev/null
+++ b/src/usr/secureboot/trusted/README.md
@@ -0,0 +1,74 @@
+# **'trusted'** Secureboot Services in Hostboot
+This directory implements the 'trusted' boot functionality that Hostboot
+ provides.
+It primarily does this by measuring and storing firmware images and system
+ data into the system's TPMs (Trusted Platform Modules).
+
+## Key Points
+* This code measures specific information on the system, including different
+ firmware images that are loaded onto the system by hostboot
+* These mesasurements, along with other system data, are stored in the TPMs
+ on the system
+* This code also determines which TPMs exist on the system, if they are
+ functional, and initializes them
+* To directly talk to the TPMs this code uses the TPM Device Driver, which
+ is built on top of the I2C Device Driver:
+ * [src/usr/i2c/tmpdd.C](../../i2c/tpmdd.C)
+ * [src/usr/i2c/tpmdd.H](../../i2c/tpmdd.H)
+
+* The **libsecureboot_trusted.so** module created here is available in
+ Hostboot's extended image
+* However, the code in the 'base' sub-directory is built into
+ libsecureboot_base.so and is available in Hostboot's base image
+* This module implements the interfaces defined in
+ [trustedbootif.H](../../../include/usr/secureboot/trustedbootif.H)
+
+## Files
+
+* __makefile__
+ * Standard Hostboot makefile
+
+* __[README.md](./README.md)__
+ * This file
+
+* __tpmLogMgr.C, tpmLogMgr.H__
+ * Defines and implements functions around the TPM Event Log, including
+ adding new events, extending the log to the TPM, and moving the log to
+ different memory locations
+
+* __trustedTypes.C, trustedTypes.H__
+ * Defines different structures and methods for sending and receiving data
+ to and from the TPM
+
+* __trustedboot.C, trustedboot.H__
+ * Defines and implements the majority of the functions that interact with the
+ TPMs
+ * Implements the majority of the functions that verify and initialize the TPMs
+
+* __trustedbootCmds.C, trustedbootCmds.H__
+ * Defines and implements commands sent to the TPM and then processes (aka
+ marshall and unmarshall) the data appropriately
+
+* __trustedbootUtils.C, trustedbootUtils.H__
+ * Defines and implements a few utility functions like a wrapper to the TPM
+ Device Driver and creating trustedboot error logs.
+
+
+## sub-directories
+* __base__
+ * These files create a message queue to reserve operations that can be
+ implemented once the full Hostboot extended code, including
+ libsecureboot_trusted.so, is available to process them
+ * These files also take the basic operations that the Hostboot base code
+ needs and sends them to the message queue
+ * __trustedboot_base.C__
+ * Implements early trustedboot/TPM calls be calling into a message
+ queue so that they can be processed later
+
+ * __trustedbootMsg.C, trustedbootMsg.H__
+ * Defines and implements the message queue so that commands can be
+ processed later when libsecureboot_trusted.so is available
+
+* __test__
+ * Standard Hostboot test directory that implements CXX Unit Tests
+
diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.C b/src/usr/secureboot/trusted/base/trustedboot_base.C
index 2e5182d2f..eb889131c 100644
--- a/src/usr/secureboot/trusted/base/trustedboot_base.C
+++ b/src/usr/secureboot/trusted/base/trustedboot_base.C
@@ -45,7 +45,6 @@
#include <secureboot/header.H>
#include <secureboot/containerheader.H>
#include <pnor/pnorif.H>
-#include <config.h>
#include "../trustedboot.H"
#include "../trustedbootCmds.H"
#include "../trustedbootUtils.H"
@@ -1165,7 +1164,7 @@ errlHndl_t expandTpmLog(TpmTarget* i_target)
int l_rc = msg_sendrecv(systemData.msgQ, l_msg->iv_msg);
if(l_rc)
{
- /**
+ /*@
* @errortype ERRL_SEV_UNRECOVERABLE
* @moduleid MOD_EXPAND_TPM_LOG
* @reasoncode RC_SENDRECV_FAIL
diff --git a/src/usr/secureboot/trusted/test/trustedbootTest.H b/src/usr/secureboot/trusted/test/trustedbootTest.H
index cbf221e57..50564f12d 100755
--- a/src/usr/secureboot/trusted/test/trustedbootTest.H
+++ b/src/usr/secureboot/trusted/test/trustedbootTest.H
@@ -45,7 +45,6 @@
#include "../trustedboot.H"
#include "../trustedbootCmds.H"
#include "../tpmLogMgr.H"
-#include <config.h>
using namespace TRUSTEDBOOT;
diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C
index 6046a76df..d0ec76030 100644
--- a/src/usr/secureboot/trusted/trustedboot.C
+++ b/src/usr/secureboot/trusted/trustedboot.C
@@ -53,7 +53,6 @@
#ifdef CONFIG_BMC_IPMI
#include <ipmi/ipmisensor.H>
#endif
-#include <config.h>
#include <devicefw/driverif.H>
#include <i2c/tpmddif.H>
#include "trustedboot.H"
diff --git a/src/usr/secureboot/trusted/trustedbootCmds.C b/src/usr/secureboot/trusted/trustedbootCmds.C
index 604757b7a..fe2956929 100644
--- a/src/usr/secureboot/trusted/trustedbootCmds.C
+++ b/src/usr/secureboot/trusted/trustedbootCmds.C
@@ -37,7 +37,6 @@
// ----------------------------------------------
#include <string.h>
#include <stdlib.h>
-#include <config.h>
#ifdef __HOSTBOOT_MODULE
#include <secureboot/trustedboot_reasoncodes.H>
diff --git a/src/usr/targeting/attrPlatOverride.C b/src/usr/targeting/attrPlatOverride.C
index 7e1025d40..46f50e566 100644
--- a/src/usr/targeting/attrPlatOverride.C
+++ b/src/usr/targeting/attrPlatOverride.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -28,6 +28,7 @@
#include <targeting/common/targreasoncodes.H>
#include <errl/errlmanager.H>
#include <secureboot/service.H>
+#include <console/consoleif.H>
namespace TARGETING
{
@@ -291,6 +292,103 @@ errlHndl_t getAttrOverrides(PNOR::SectionInfo_t &i_sectionInfo,
break;
}
+ // Print out the contents of all attribute tanks
+ for( size_t i=0; i<AttributeTank::TANK_LAYER_LAST; i++ )
+ {
+ if( l_pOverTanks[i]->attributesExist() )
+ {
+ /* Display output like this
+
+ **Found 3 attribute overrides in Tank TARG(2)
+ - type:n1:p2:c3
+ ATTR 12345678 = 0011223344
+ ATTR 10102020 = 223344
+ - type:nall:pall:call
+ ATTR 02395414 = 07
+ */
+
+ CONSOLE::displayf("TARG","**Found %d attribute overrides in Tank %s(%d)",
+ l_pOverTanks[i]->size(),
+ AttributeTank::layerToString(
+ static_cast<AttributeTank::TankLayer>(i)),
+ i);
+
+ AttributeTank::AttributeHeader last_hdr;
+ std::list<AttributeTank::Attribute*> l_attrList;
+ l_pOverTanks[i]->getAllAttributes(l_attrList);
+ for( auto l_attr : l_attrList )
+ {
+ constexpr size_t MAX_DISPLAY = 100;
+ char outstr[MAX_DISPLAY];
+ outstr[0] = '\0';
+
+ // Only print out the target string once if possible
+ AttributeTank::AttributeHeader hdr = l_attr->getHeader();
+ if( (hdr.iv_targetType != last_hdr.iv_targetType)
+ || (hdr.iv_node != last_hdr.iv_node)
+ || (hdr.iv_pos != last_hdr.iv_pos)
+ || (hdr.iv_unitPos != last_hdr.iv_unitPos) )
+ {
+ EntityPath epath; //func should be static but isn't
+ sprintf( outstr, "- %s",
+ epath.pathElementTypeAsString(
+ static_cast<TARGETING::TYPE>(hdr.iv_targetType)) );
+ if( AttributeTank::ATTR_NODE_NA == hdr.iv_node )
+ {
+ strcat( outstr, ":nall" );
+ }
+ else
+ {
+ char tmpstr[10]={};
+ sprintf( tmpstr, ":n%d", hdr.iv_node );
+ strcat( outstr, tmpstr );
+ }
+ if( AttributeTank::ATTR_POS_NA == hdr.iv_pos )
+ {
+ strcat( outstr, ":pall" );
+ }
+ else
+ {
+ char tmpstr[10]={};
+ sprintf( tmpstr, ":p%d", hdr.iv_pos );
+ strcat( outstr, tmpstr );
+ }
+ if( AttributeTank::ATTR_UNIT_POS_NA == hdr.iv_unitPos )
+ {
+ strcat( outstr, ":call" );
+ }
+ else
+ {
+ char tmpstr[10]={};
+ sprintf( tmpstr, ":c%d", hdr.iv_unitPos );
+ strcat( outstr, tmpstr );
+ }
+ CONSOLE::displayf("TARG",outstr);
+ last_hdr = hdr;
+ }
+
+ // Now print out the attribute values
+ sprintf( outstr, " ATTR %.8X [%d] = ",
+ hdr.iv_attrId,
+ hdr.iv_valSize );
+ size_t max_data = (MAX_DISPLAY - strlen(outstr))/2 - 4;
+ const char* dataval =
+ reinterpret_cast<const char*>(l_attr->getValue());
+ for( size_t s=0; s<hdr.iv_valSize && s<max_data; s++ )
+ {
+ char datastr[4]={};
+ sprintf( datastr, "%.2X", dataval[s] );
+ strcat( outstr, datastr );
+ }
+ if( hdr.iv_valSize > max_data )
+ {
+ strcat( outstr, "..." );
+ }
+ CONSOLE::displayf("TARG",outstr);
+ }
+ CONSOLE::flush();
+ }
+ }
} while(0);
TRACFCOMP(g_trac_targeting,"attrPlatOverride::getAttrOverrides EXIT");
diff --git a/src/usr/targeting/attrrp.C b/src/usr/targeting/attrrp.C
index 1f7c359d7..7f0782a39 100755
--- a/src/usr/targeting/attrrp.C
+++ b/src/usr/targeting/attrrp.C
@@ -51,7 +51,6 @@
#include <sys/misc.h>
#include <fapi2/plat_attr_override_sync.H>
#include <targeting/attrPlatOverride.H>
-#include <config.h>
#include <secureboot/service.H>
#include <kernel/bltohbdatamgr.H>
#include <bootloader/bootloaderif.H>
diff --git a/src/usr/targeting/common/Targets.pm b/src/usr/targeting/common/Targets.pm
index aa1e07f7d..c106ef0fc 100644
--- a/src/usr/targeting/common/Targets.pm
+++ b/src/usr/targeting/common/Targets.pm
@@ -22,6 +22,7 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+
package Targets;
use strict;
@@ -78,12 +79,18 @@ my %maxInstance = (
"NPU" => 1,
"MC" => 2,
"MI" => 4,
+ "MCC" => 8,
+ "OMI" => 16,
+ "OCMB_CHIP" => 16,
+ "MEM_PORT" => 16,
+ "DDIMM" => 16,
"DMI" => 8,
"OCC" => 1,
"NV" => 6,
"NX" => 1,
"MEMBUF" => 8,
"SMPGROUP" => 8,
+ "OMIC" => 6,
);
sub new
{
@@ -94,6 +101,7 @@ sub new
targeting => undef,
enumerations => undef,
MAX_MCS => 0,
+ master_proc => undef,
UNIT_COUNTS => undef,
huid_idx => undef,
mru_idx => undef,
@@ -223,9 +231,17 @@ sub printTarget
return;
}
+ my $target_TYPE = $self->getAttribute($target, "TYPE");
+
+ # Only allow OMI types with MCC parent
+ # OMIC_PARENT only exists on an OMI target with MCC parent
+ if ($target_TYPE eq "OMI" && !defined($target_ptr->{ATTRIBUTES}->{"OMIC_PARENT"}->{default}))
+ {
+ return;
+ }
+
print $fh "<targetInstance>\n";
my $target_id = $self->getAttribute($target, "PHYS_PATH");
- my $target_TYPE = $self->getAttribute($target, "TYPE");
$target_id = substr($target_id, 9);
$target_id =~ s/\///g;
$target_id =~ s/\-//g;
@@ -545,6 +561,13 @@ sub buildHierarchy
},
$b
);
+ push(
+ @{
+ $self->{data}->{TARGETS}->{$source_target}->{CONNECTION}
+ ->{BUS_PARENT}
+ },
+ $key
+ );
my %bus_entry;
$bus_entry{SOURCE_TARGET} = $source_target;
$bus_entry{DEST_TARGET} = $dest_target;
@@ -643,9 +666,17 @@ sub buildAffinity
my $tpm = -1;
my $ucd = -1;
my $bmc = -1;
+ my $mcc = -1;
+ my $omi = -1;
+ my $ocmb = -1;
+ my $mem_port = -1;
+ my $i2c_mux = -1;
+ my $dimm = -1;
+ my $pmic = -1;
my $sys_phys = "";
my $node_phys = "";
my $node_aff = "";
+ my $proc_fapi = "";
my $sys_pos = 0; # There is always a single system target
my $mcbist = -1;
my $num_mc = 0 ;
@@ -776,6 +807,64 @@ sub buildAffinity
$self->deleteAttribute($target, "POSITION");
$self->deleteAttribute($target, "FRU_ID");
}
+ elsif ($type eq "MCC")
+ {
+ $mcc++;
+
+ # For a given proc, there are 2 MCs, 4 MIs, 8 MCCs, and 16 OMIs
+ # To get the corresponding proc, MC, or MI number for a given MCC
+ # divide the MCC number by the number of MCCs per unit, then mod 2
+ # to get the relative path in terms of 0 or 1
+ my $numOfMccsPerProc = $maxInstance{$type};
+ my $numOfMccsPerMc = 4;
+ my $numOfMccsPerMi = 2;
+ my $proc_num = ($mcc / $numOfMccsPerProc) % 2;
+ my $mc_num = ($mcc / $numOfMccsPerMc) % 2;
+ my $mi_num = ($mcc / $numOfMccsPerMi) % 2;
+ my $mcc_num = $mcc % 2;
+ my $path = "/proc-$proc_num/mc-$mc_num/mi-$mi_num/mcc-$mcc_num";
+ my $mcc_aff = $node_aff . $path;
+ my $mcc_phys = $node_phys . $path;
+ $self->setAttribute($target, "AFFINITY_PATH", $mcc_aff);
+ $self->setAttribute($target, "PHYS_PATH", $mcc_phys);
+
+ $self->setAttribute($target, "REL_POS", $mcc_num);
+ my $pos = $self->getAttribute($target, "CHIP_UNIT");
+ my $fapi_pos = $pos + $numOfMccsPerProc * $proc_fapi;
+ $self->setAttribute($target, "FAPI_POS", $fapi_pos);
+ $self->setAttribute($target, "ORDINAL_ID", $mcc);
+ }
+ elsif ($type eq "OMI")
+ {
+ # We only want OMIs with MCC parent, skip over the ones with OMIC parent
+ my $parent = $self->getTargetParent($target);
+ my $parent_type = $self->getType($parent);
+ if ($parent_type eq "MCC")
+ {
+ $omi++;
+
+ # Same logic for MCC, but for OMI instead
+ my $numOfOmisPerProc = $maxInstance{$type};
+ my $numOfOmisPerMc = 8;
+ my $numOfOmisPerMi = 4;
+ my $numOfOmisPerMcc = 2;
+ my $proc_num = ($omi / $numOfOmisPerProc) % 2;
+ my $mc_num = ($omi / $numOfOmisPerMc) % 2;
+ my $mi_num = ($omi / $numOfOmisPerMi) % 2;
+ my $mcc_num = ($omi / $numOfOmisPerMcc) % 2;
+ my $omi_num = $omi % 2;
+ my $path = "/proc-$proc_num/mc-$mc_num/mi-$mi_num/mcc-$mcc_num/omi-$omi_num";
+ my $omi_aff = $node_aff . $path;
+ my $omi_phys = $node_phys . $path;
+ $self->setAttribute($target, "AFFINITY_PATH", $omi_aff);
+ $self->setAttribute($target, "PHYS_PATH", $omi_phys);
+
+ my $pos = $self->getAttribute($target, "CHIP_UNIT");
+ my $fapi_pos = $pos + $numOfOmisPerProc * $proc_fapi;
+ $self->setAttribute($target, "FAPI_POS", $fapi_pos);
+ $self->setAttribute($target, "ORDINAL_ID", $omi);
+ }
+ }
elsif ($type eq "BMC")
{
$bmc++;
@@ -801,7 +890,322 @@ sub buildAffinity
my $ddrs = $self->findConnections($target,"DDR4","");
$self->processMcaDimms($ddrs, $sys_pos, $node_phys, $node, $proc);
}
+ elsif ($type eq "OCMB_CHIP")
+ {
+ # Ocmbs are not in order, so we take the parent dimm's POSITION as
+ # our current ocmb number
+ # Ex. dimm19 = ocmb19
+ my $parent = $self->getTargetParent($target);
+ $ocmb = $self->getAttribute($parent, "POSITION");
+ $self->{targeting}{SYS}[0]{NODES}[$node]{OCMB_CHIPS}[$ocmb]{KEY} = $target;
+ $self->setHuid($target, $sys_pos, $node);
+
+ my $ocmb_phys = $node_phys . "/ocmb_chip-$ocmb";
+
+ # Find the OMI bus connection to determine target values
+ my $proc_num = -1;
+ my $mc_num = -1;
+ my $mi_num = -1;
+ my $mcc_num = -1;
+ my $omi_num = -1;
+ my $conn = $self->findConnectionsByDirection($target, "OMI", "", 1);
+
+ my $omi_chip_unit = -1;
+ if ($conn ne "")
+ {
+ foreach my $conn (@{$conn->{CONN}})
+ {
+ my $source = $conn->{SOURCE};
+ if ($source =~ /omic/i)
+ {
+ next;
+ }
+ my @targets = split(/\//, $source);
+ # Split the source into proc#, mc#, mi#, mcc#, omi#
+ # Source example:
+ # /sys-#/node-#/Pallid-#/proc_socket-#/Hopper-#/p9_axone/mc#/mi#/mcc#/omi#
+ foreach my $target (@targets)
+ {
+ $target =~ s/\D//g;
+ }
+
+ # Splitting on "/" makes the first array index empty string
+ # so every value here is shifted over by 1
+ # There are only ever two targets per parent in this case,
+ # so to get the relative positions for each target, we take
+ # mod two of the source value
+ $proc_num = $targets[4] % 2;
+ $mc_num = $targets[7] % 2;
+ $mi_num = $targets[8] % 2;
+ $mcc_num = $targets[9] % 2;
+
+ # omi_num indicates the chip_unit of the corresponding omi
+ $omi_num = $targets[10];
+ $omi_chip_unit = $omi_num;
+ $omi_num %= 2;
+ }
+ }
+
+ my $ocmb_aff = $node_aff . "/proc-$proc_num/mc-$mc_num/mi-$mi_num/mcc-$mcc_num/omi-$omi_num/ocmb_chip-0";
+ $self->setAttribute($target, "AFFINITY_PATH", $ocmb_aff);
+ $self->setAttribute($target, "PHYS_PATH", $ocmb_phys);
+
+ # The standard fapi_pos calculation uses the relative position to
+ # the proc instead of omi_chip_unit. However, in this case, there is
+ # no direct way to get the relative position to the proc. The
+ # relationship between ocmb and omi is 1:1, so we take the chip unit
+ # of the corresponding omi as the relative position to the proc
+ my $fapi_pos = $omi_chip_unit + ($maxInstance{$type} * $proc_num);
+ $self->setAttribute($target, "FAPI_POS", $fapi_pos);
+
+ my $ocmb_num = $fapi_pos;
+ # The norm for FAPI_NAME has a two digit number at the end
+ if ($fapi_pos < 10)
+ {
+ $ocmb_num = "0$fapi_pos";
+ }
+
+ $self->setAttribute($target, "MRU_ID", "0x00060000");
+ $self->setAttribute($target, "POSITION", $ocmb);
+
+ # chipunit:system:node:slot:position
+ $self->setAttribute($target, "FAPI_NAME", "ocmb:k0:n0:s0:p$ocmb_num");
+
+ $self->setAttribute($target, "REL_POS", "0");
+
+ my $fapi_name = "FAPI_I2C_CONTROL_INFO";
+ my $master_path = "physical:sys-0/node-0/proc-$proc_num";
+ $self->setAttributeField($target, $fapi_name, "i2cMasterPath", $master_path);
+
+ my $eeprom_name = "EEPROM_VPD_PRIMARY_INFO";
+ $self->setAttributeField($target, $eeprom_name, "i2cMasterPath", $master_path);
+ $self->setAttributeField($target, $eeprom_name, "chipCount", "0x01");
+ }
+ elsif ($type eq "I2C_MUX")
+ {
+ $i2c_mux++;
+
+ $self->{targeting}{SYS}[0]{NODES}[$node]{I2C_MUXS}[$i2c_mux]{KEY} = $target;
+
+ # There exists 1 i2c_mux per MC, so 2 i2c_mux per proc
+ my $numOfMuxesPerProc = 2;
+ my $proc_num = ($i2c_mux / $numOfMuxesPerProc) % 2;
+ my $i2c_aff = $node_aff . "/proc-$proc_num/i2c_mux-$i2c_mux";
+ $self->setAttribute($target, "AFFINITY_PATH", $i2c_aff);
+
+ my $i2c_phys = $node_phys . "/i2c_mux-$i2c_mux";
+ $self->setAttribute($target, "PHYS_PATH", $i2c_phys);
+ $self->setHuid($target, $sys_pos, $node);
+
+ my $fapi_name = "FAPI_I2C_CONTROL_INFO";
+ my $master_path = $node_phys . "/proc-$proc_num";
+ $self->setAttributeField($target, $fapi_name, "i2cMasterPath", $master_path);
+ my $conn = $self->findConnectionsByDirection($target, "I2C",
+ "", 1);
+ if ($conn ne "")
+ {
+ # Get the i2c-master-omi which has the engine and port values
+ # The endpoint mux has the devAddr
+ foreach my $conn (@{$conn->{CONN}})
+ {
+ my $source = $conn->{SOURCE};
+ my $dest = $conn->{DEST};
+ if ($self->getTargetParent($conn->{DEST}) eq $target)
+ {
+ $self->setAttributeField($target, $fapi_name, "engine",
+ $self->getAttribute($source, "I2C_ENGINE"));
+ $self->setAttributeField($target, $fapi_name, "port",
+ $self->getAttribute($source, "I2C_PORT"));
+ $self->setAttributeField($target, $fapi_name, "devAddr",
+ $self->getAttribute($dest, "I2C_ADDRESS"));
+ }
+ }
+ }
+ }
+ elsif ($type eq "MEM_PORT")
+ {
+ my $parent = $self->getTargetParent($target);
+ my $ocmb_num = $self->getAttribute($parent, "POSITION");
+ my $ocmb_affinity = $self->getAttribute($parent, "AFFINITY_PATH");
+ $self->setAttribute($target, "AFFINITY_PATH", "$ocmb_affinity/mem_port-0");
+ my $ocmb_phys = $self->getAttribute($parent, "PHYS_PATH");
+ $self->setAttribute($target, "PHYS_PATH", "$ocmb_phys/mem_port-0");
+ $self->setHuid($target, $sys_pos, $node);
+ $self->deleteAttribute($target, "EXP_SAFEMODE_MEM_THROTTLED_N_COMMANDS_PER_PORT");
+
+ $self->{targeting}{SYS}[0]{NODES}[$node]{OCMB_CHIPS}[$ocmb_num]{MEM_PORTS}[0]{KEY} = $target;
+ }
+ # Witherspoon has its own DIMM parsing mechanism so don't want to
+ # interfere with it
+ elsif ($type eq "DIMM" && $self->getTargetType($target) eq "lcard-dimm-ddimm")
+ {
+ # Dimms are not posted in order, so need to get the dimm's position
+ $dimm = $self->getAttribute($target, "POSITION");
+
+ # Find the OMI bus connection to determine target values
+ my $proc_num = -1;
+ my $mc_num = -1;
+ my $mi_num = -1;
+ my $mcc_num = -1;
+ my $omi_num = -1;
+ my $conn = $self->findConnectionsByDirection($target, "OMI", "", 1);
+
+ my $omi_chip_unit = -1;
+ if ($conn ne "")
+ {
+ foreach my $conn (@{$conn->{CONN}})
+ {
+ my $source = $conn->{SOURCE};
+ my @targets = split(/\//, $source);
+
+ if ($source =~ /omic/i)
+ {
+ next;
+ }
+
+ # Split the source into proc#, mc#, mi#, mcc#, omi#
+ # Source example:
+ # /sys-#/node-#/Pallid-#/proc_socket-#/Hopper-#/p9_axone/mc#/mi#/mcc#/omi#
+ foreach my $target (@targets)
+ {
+ $target =~ s/\D//g;
+ }
+
+ # Splitting on "/" makes the first array index empty string
+ # so every value here is shifted over by 1
+ # There are only ever two targets per parent in this case,
+ # so to get the relative positions for each target, we take
+ # mod two of the source value
+ $proc_num = $targets[4] % 2;
+ $mc_num = $targets[7] % 2;
+ $mi_num = $targets[8] % 2;
+ $mcc_num = $targets[9] % 2;
+ $omi_num = $targets[10];
+
+ # omi_num indicates the chip_unit of the corresponding omi
+ $omi_chip_unit = $omi_num;
+ $omi_num %= 2;
+ }
+ }
+
+ $self->{targeting}{SYS}[0]{NODES}[$node]{DIMMS}[$dimm]{KEY} = $target;
+ $self->setAttribute($target, "PHYS_PATH", $node_phys . "/dimm-$dimm");
+ $self->setHuid($target, $sys_pos, $node);
+
+ # The standard fapi_pos calculation uses the relative position to
+ # the proc instead of omi_chip_unit. However, in this case, there is
+ # no direct way to get the relative position to the proc. The
+ # relationship between dimm and omi is 1:1, so we take the chip unit
+ # of the corresponding omi as the relative position to the proc
+ my $fapi_pos = $omi_chip_unit + ($maxInstance{"DDIMM"} * $proc_num);
+ $self->setAttribute($target, "FAPI_POS", $fapi_pos);
+ $self->setAttribute($target, "ORDINAL_ID", $dimm);
+ $self->setAttribute($target, "REL_POS", 0);
+ $self->setAttribute($target, "VPD_REC_NUM", $dimm);
+
+ my $dimm_num = $fapi_pos;
+ if ($fapi_pos < 10)
+ {
+ $dimm_num = "0$fapi_pos";
+ }
+ # chipunit:slot:node:system:position
+ $self->setAttribute($target, "FAPI_NAME", "dimm:k0:n0:s0:p$dimm_num");
+
+ my $ocmb_num = 0;
+ my $mem_num = 0;
+ $dimm_num = 0;
+ my $dimm_aff = $node_aff . "/proc-$proc_num/mc-$mc_num/mi-$mi_num/mcc-$mcc_num/omi-$omi_num/ocmb_chip-$ocmb_num/mem_port-$mem_num/dimm-$dimm_num";
+ $self->setAttribute($target, "AFFINITY_PATH", $dimm_aff);
+
+ my $eeprom_name = "EEPROM_VPD_PRIMARY_INFO";
+ $self->setAttributeField($target, $eeprom_name, "chipCount", "0x01");
+ $self->setAttributeField($target, $eeprom_name, "i2cMasterPath", "physical:sys-0/node-0/proc-$proc_num");
+ }
+ elsif ($type eq "PMIC")
+ {
+ # Pmics are not in order, so we take the parent dimm's
+ # POSITION * 4 as our current pmic number, adding one
+ # if it's a pmic1, two if it's a pmic2, three if it's a
+ # pmic3
+ # Ex. on a pmic0, dimm19 = pmic76
+ # Ex. on a pmic1, dimm19 = pmic77
+ # Ex. on a pmic2, dimm19 = pmic78
+ # Ex. on a pmic3, dimm19 = pmic79
+ my $instance_name = $self->getInstanceName($target);
+ my $parent = $self->getTargetParent($target);
+ my $parent_fapi_pos = $self->getAttribute($parent, "FAPI_POS");
+ my $parent_pos = $self->getAttribute($parent, "POSITION");
+ my $position = $self->getAttribute($target, "POSITION");
+ $pmic = ($parent_pos * 4) + $position;
+
+ $self->{targeting}{SYS}[0]{NODES}[$node]{PMICS}[$pmic]{KEY} = $target;
+ $self->setAttribute($target, "PHYS_PATH", $node_phys . "/pmic-$pmic");
+ $self->setAttribute($target, "ORDINAL_ID", $pmic);
+ $self->setAttribute($target, "REL_POS", $pmic % 2);
+
+ # Same logic with the position, but with FAPI_POS instead
+ my $fapi_pos = ($parent_fapi_pos * 4) + $position;
+ $self->setAttribute($target, "FAPI_POS", $fapi_pos);
+ $self->setAttribute($target, "POSITION", $pmic);
+ $self->setHuid($target, $sys_pos, $node);
+
+ my $pmic_num = $fapi_pos;
+ # The norm for FAPI_NAME has a two digit number at the end
+ if ($fapi_pos < 10)
+ {
+ $pmic_num = "0$fapi_pos";
+ }
+ # chipunit:slot:node:system:position
+ $self->setAttribute($target, "FAPI_NAME", "pmic:k0:n0:s0:p$pmic_num");
+
+ # Find the OMI bus connection to determine target values
+ my $proc_num = -1;
+ my $mc_num = -1;
+ my $mi_num = -1;
+ my $mcc_num = -1;
+ my $omi_num = -1;
+ my $conn = $self->findConnectionsByDirection($self->getTargetParent($target), "OMI", "", 1);
+ if ($conn ne "")
+ {
+ foreach my $conn (@{$conn->{CONN}})
+ {
+ my $source = $conn->{SOURCE};
+ my @targets = split(/\//, $source);
+ # Split the source into proc#, mc#, mi#, mcc#, omi#
+ # Source example:
+ # /sys-#/node-#/Pallid-#/proc_socket-#/Hopper-#/p9_axone/mc#/mi#/mcc#/omi#
+ if ($source =~ /omic/i)
+ {
+ next;
+ }
+
+ foreach my $target (@targets)
+ {
+ $target =~ s/\D//g;
+ }
+ # Splitting on "/" makes the first array index empty string
+ # so every value here is shifted over by 1
+ # There are only ever two targets per parent in this case,
+ # so to get the relative positions for each target, we take
+ # mod two of the source value
+ $proc_num = $targets[4] % 2;
+ $mc_num = $targets[7] % 2;
+ $mi_num = $targets[8] % 2;
+ $mcc_num = $targets[9] % 2;
+ $omi_num = $targets[10] % 2;
+ }
+ }
+
+ my $ocmb_num = 0;
+ $pmic_num %= 2;
+ my $pmic_aff = $node_aff . "/proc-$proc_num/mc-$mc_num/mi-$mi_num/mcc-$mcc_num/omi-$omi_num/ocmb_chip-$ocmb_num/pmic-$pmic_num";
+ $self->setAttribute($target, "AFFINITY_PATH", $pmic_aff);
+
+ my $fapi_name = "FAPI_I2C_CONTROL_INFO";
+ $self->setAttributeField($target, $fapi_name, "i2cMasterPath",
+ "physical:sys-0/node-0/proc-$proc_num");
+ }
elsif ($type eq "PROC")
{
my $socket = $target;
@@ -879,14 +1283,14 @@ sub buildAffinity
$self->setAttribute($target, "POSITION", $proc);
$self->setAttribute($target, "FABRIC_GROUP_ID",
- $self->getAttribute($socket,"FABRIC_GROUP_ID"));
+ $self->getAttribute($socket,"FABRIC_GROUP_ID"));
$self->setAttribute($target, "FABRIC_CHIP_ID",
- $self->getAttribute($socket,"FABRIC_CHIP_ID"));
+ $self->getAttribute($socket,"FABRIC_CHIP_ID"));
$self->setAttribute($target, "VPD_REC_NUM", $proc);
- $self->setAttribute($target, "FAPI_POS",
- $self->getAttribute($socket,"FABRIC_GROUP_ID") *
- NUM_PROCS_PER_GROUP +
- $self->getAttribute($socket,"FABRIC_CHIP_ID"));
+ $proc_fapi = $self->getAttribute($socket, "FABRIC_GROUP_ID") *
+ NUM_PROCS_PER_GROUP +
+ $self->getAttribute($socket, "FABRIC_CHIP_ID");
+ $self->setAttribute($target, "FAPI_POS", $proc_fapi);
# Both for FSP and BMC based systems, it's good enough
# to look for processor with active LPC bus connected
@@ -1026,6 +1430,11 @@ sub iterateOverChiplets
my $tgt_ptr = $self->getTarget($target);
my $tgt_type = $self->getType($target);
+ # Previous OBUS parent
+ my $prev_obus = -1;
+ # Subtract factor for OBUS_BRICK
+ my $brick_sub = -1;
+
my $target_children = $self->getTargetChildren($target);
if ($target_children eq "")
@@ -1120,13 +1529,27 @@ sub iterateOverChiplets
#System XML has some sensor target as hidden children
#of targets. We don't care for sensors in this function
#So, we can avoid them with this conditional
-
if ($unit_type ne "PCI" && $unit_type ne "NA" &&
$unit_type ne "FSI" && $unit_type ne "PSI" &&
$unit_type ne "SYSREFCLKENDPT" && $unit_type ne "MFREFCLKENDPT")
{
+ if ($unit_type eq "OBUS_BRICK")
+ {
+ # Check to see if this is on a new obus
+ # Current obus is the CHIP_UNIT of the parent obus
+ my $curr_obus = $self->getAttribute($target,
+ "CHIP_UNIT");
+ if ($prev_obus ne $curr_obus)
+ {
+ my $brick_pos = $self->getAttribute($child,
+ "CHIP_UNIT");
+ $brick_sub = $brick_pos;
+ $prev_obus = $curr_obus;
+ }
+ }
#set common attrs for child
- $self->setCommonAttrForChiplet($child, $sys, $node, $proc);
+ $self->setCommonAttrForChiplet($child, $sys, $node, $proc,
+ $prev_obus, $brick_sub);
$self->iterateOverChiplets($child, $sys, $node, $proc);
}
}
@@ -1156,6 +1579,8 @@ sub setCommonAttrForChiplet
my $sys = shift;
my $node = shift;
my $proc = shift;
+ my $prev_obus = shift;
+ my $brick_sub = shift;
my $tgt_ptr = $self->getTarget($target);
my $tgt_type = $self->getType($target);
@@ -1194,7 +1619,15 @@ sub setCommonAttrForChiplet
}
elsif ($tgt_type eq "OBUS_BRICK")
{
- $unit_pos = $pos%3;
+ # Relative position of OBUS_BRICK is just the difference between the
+ # current position and the position of the first obus_brick of the
+ # parent obus
+ # Ex: obus3 -> obus_brick9
+ # -> obus_brick10
+ # -> obus_brick11
+ # Position of first obus_brick of parent obus = 9
+ # Relative position of obus_brick11 = 11 - 9 = 2
+ $unit_pos = $pos - $brick_sub;
}
elsif ($tgt_type eq "SMPGROUP")
{
@@ -1203,6 +1636,11 @@ sub setCommonAttrForChiplet
$self->setAttribute($target, "INSTANCE_PATH", $target);
$unit_pos = $pos%2;
}
+ elsif ($tgt_type eq "OMIC")
+ {
+ # There are 3 OMICs per MC parent
+ $unit_pos = $pos % 3;
+ }
my $parent_affinity = $self->getAttribute(
$self->getTargetParent($target),"AFFINITY_PATH");
@@ -1394,6 +1832,7 @@ sub getPervasiveForUnit
my $offset = 0;
for my $obrick (0..$maxInstance{"OBUS_BRICK"}-1)
{
+ #todo-RTC:209409-Handle Axone layout
$offset += (($obrick%3 == 0) && ($obrick != 0)) ? 1 : 0;
$unitToPervasive{"OBUS_BRICK$obrick"}
= PERVASIVE_PARENT_OBUS_OFFSET + $offset;
@@ -1412,6 +1851,7 @@ sub getPervasiveForUnit
return $pervasive
}
+
sub processMcaDimms
{
my $self = shift;
@@ -1546,6 +1986,12 @@ sub processMc
foreach my $dmi (@{ $self->getTargetChildren($mi) })
{
+ my $child_type = $self->getType($dmi);
+ if ($child_type ne "DMI")
+ {
+ next;
+ }
+
my $dmi_num = $self->getAttribute($dmi, "CHIP_UNIT");
my $membufnum = $proc * $self->{MAX_DMI} + $dmi_num;
@@ -1572,7 +2018,7 @@ sub processMc
my $parent_physical = $self->getAttribute($membuf, "PHYS_PATH");
$self->setAttribute($membuf,"FAPI_NAME",
- $self->getFapiName($membuf_type, $node, $membufnum));
+ $self->getFapiName($membuf_type, $node, $membufnum, $memCardOffset));
my $fapi_pos = (($node * $maxInstance{"PROC"}) + $proc ) * $self->{MAX_DMI} + $dmi_num;
@@ -1955,6 +2401,15 @@ sub getConnectionBus
return $target_ptr->{CONNECTION}->{BUS}->[$i];
}
+sub getConnectionBusParent
+{
+ my $self = shift;
+ my $target = shift;
+ my $i = shift;
+ my $target_ptr = $self->getTarget($target);
+ return $target_ptr->{CONNECTION}->{BUS_PARENT}->[$i];
+}
+
sub findFirstEndpoint
{
my $self = shift;
@@ -2012,6 +2467,192 @@ sub findDestConnections
}
+sub setEepromAttributesForAxone
+{
+ my $self = shift;
+ my $targetObj = shift;
+ # Expects ocmb target
+ my $target = shift;
+
+ my %connections;
+ my $num=0;
+
+ my $eeprom_name = "EEPROM_VPD_PRIMARY_INFO";
+ my $fapi_name = "FAPI_I2C_CONTROL_INFO";
+ # SPD contains data for EEPROM_VPD_PRIMARY_INFO and FAPI_I2C_CONTROL_INFO
+ # SPD is the child of ocmb's parent, so get ocmb's parent
+ # then look for the SPD child
+ # With the resulting info, we populate pmic0, pmic1, ocmb, and dimm
+ my $target_parent = $self->getTargetParent($target);
+
+ # Need to store pmic targets because they get parsed before we
+ # do calculations for engine, port, and muxBusSelector
+ # pmics need these values, so we store them until we need them later
+ my $address = 0;
+ my @pmic_array;
+ foreach my $child (@{ $self->getTargetChildren($target_parent) })
+ {
+ my $type = $self->getTargetType($child);
+ if ($type eq "chip-spd-device")
+ {
+ my $offset = $self->getAttribute($child, "BYTE_ADDRESS_OFFSET");
+ my $memory_size = $self->getAttribute($child, "MEMORY_SIZE_IN_KB");
+ my $cycle_time = $self->getAttribute($child, "WRITE_CYCLE_TIME");
+ my $page_size = $self->getAttribute($child, "WRITE_PAGE_SIZE");
+
+ # Populate EEPROM for ocmb
+ $targetObj->setAttributeField($target, $eeprom_name, "byteAddrOffset",
+ $offset);
+ $targetObj->setAttributeField($target, $eeprom_name, "maxMemorySizeKB",
+ $memory_size);
+ $targetObj->setAttributeField($target, $eeprom_name, "writeCycleTime",
+ $cycle_time);
+ $targetObj->setAttributeField($target, $eeprom_name, "writePageSize",
+ $page_size);
+
+ # Populate EEPROM for dimm
+ $targetObj->setAttributeField($target_parent, $eeprom_name, "byteAddrOffset",
+ $offset);
+ $targetObj->setAttributeField($target_parent, $eeprom_name, "maxMemorySizeKB",
+ $memory_size);
+ $targetObj->setAttributeField($target_parent, $eeprom_name, "writeCycleTime",
+ $cycle_time);
+ $targetObj->setAttributeField($target_parent, $eeprom_name, "writePageSize",
+ $page_size);
+
+ # spd only child is i2c-slave, which contains devAddr info
+ foreach my $i2c_slave (@{ $self->getTargetChildren($child) })
+ {
+ $address = $self->getAttribute($i2c_slave, "I2C_ADDRESS");
+ # Populate EEPROM for dimm
+ $targetObj->setAttributeField($target_parent, $eeprom_name, "devAddr",
+ $address);
+
+ # Populate EEPROM for ocmb
+ $targetObj->setAttributeField($target, $eeprom_name, "devAddr",
+ $address);
+ }
+ }
+ elsif ($type eq "chip-vreg-generic")
+ {
+ push(@pmic_array, $child);
+ foreach my $i2c_slave (@{ $self->getTargetChildren($child) })
+ {
+ $type = $self->getTargetType($i2c_slave);
+ # pmic has child i2c_slave which contains the device address
+ if ($type eq "unit-i2c-slave")
+ {
+ $address = $self->getAttribute($i2c_slave, "I2C_ADDRESS");
+
+ # Populate FAPI for pmic
+ $targetObj->setAttributeField($child, $fapi_name, "devAddr",
+ $address);
+ last;
+ }
+ }
+ }
+ elsif ($type eq "chip-ocmb")
+ {
+ foreach my $i2c_slave (@{ $self->getTargetChildren($child) })
+ {
+ # ocmb has multiple i2c-slaves, so we query with instance_name
+ my $instance_name = $self->getInstanceName($i2c_slave);
+ if ($instance_name eq "i2c-ocmb")
+ {
+ $address = $self->getAttribute($i2c_slave, "I2C_ADDRESS");
+
+ # Populate FAPI for ocmb
+ $targetObj->setAttributeField($target, $fapi_name, "devAddr",
+ $address);
+ last;
+ }
+ }
+ }
+ }
+
+ # Get data from i2c-master-omi, which connects to the i2c_mux PCA9847
+ my $conn = $self->findConnectionsByDirection($target, "I2C", "", 1);
+ if ($conn ne "")
+ {
+ # There exists multiple i2c bus connections with chip-ocmb
+ # They are all the same connections so we just take the first one
+ # The mux channel has the i2cMuxBusSelector
+ my $conn_source = @{$conn->{CONN}}[0]->{SOURCE};
+ my $mux = $self->getAttribute($conn_source, "MUX_CHANNEL");
+
+ # Parent PCA9848 determines the mux path
+ my $parent = $self->getTargetParent($conn_source);
+ my $parent_pos = $self->getAttribute($parent, "POSITION");
+ my $i2c_mux_path = "physical:sys-0/node-0/i2c_mux-$parent_pos";
+
+ # pmics and ocmb all grab FRU_ID from parent dimm
+ my $fru = $self->getAttribute($target_parent, "FRU_ID");
+
+ my $master_i2c = $self->findConnectionsByDirection($self->getTargetParent($conn_source), "I2C", "", 1);
+ if ($master_i2c ne "")
+ {
+ # There exists multiple i2c bus connections with the PCA9847 i2c_mux
+ # They are all the same connections so we just take the first one
+ $master_i2c = @{$master_i2c->{CONN}}[0];
+ # i2c-master-omi source which has data we need
+ my $source = $master_i2c->{SOURCE};
+ my $dest = $master_i2c->{DEST};
+ my $engine = $self->getAttribute($source, "I2C_ENGINE");
+ my $port = $self->getAttribute($source, "I2C_PORT");
+
+ # Populate FAPI for ocmb
+ $self->setAttributeField($target, $fapi_name, "engine",
+ $engine);
+ $self->setAttributeField($target, $fapi_name, "port",
+ $port);
+ $self->setAttributeField($target, $fapi_name, "i2cMuxBusSelector",
+ $mux);
+ $self->setAttributeField($target, $fapi_name, "i2cMuxPath",
+ $i2c_mux_path);
+ $self->setAttribute($target, "FRU_ID",
+ $fru);
+
+ # Populate EEPROM for ocmb
+ $self->setAttributeField($target, $eeprom_name, "i2cMuxPath",
+ $i2c_mux_path);
+ $self->setAttributeField($target, $eeprom_name, "engine",
+ $engine);
+ $self->setAttributeField($target, $eeprom_name, "port",
+ $port);
+ $self->setAttributeField($target, $eeprom_name, "i2cMuxBusSelector",
+ $mux);
+
+
+ # Populate FAPI for pmics
+ foreach my $pmic (@pmic_array)
+ {
+ $self->setAttributeField($pmic, $fapi_name, "engine",
+ $engine);
+ $self->setAttributeField($pmic, $fapi_name, "port",
+ $port);
+ $self->setAttributeField($pmic, $fapi_name, "i2cMuxBusSelector",
+ $mux);
+ $self->setAttributeField($pmic, $fapi_name, "i2cMuxPath",
+ $i2c_mux_path);
+ $self->setAttribute($pmic, "FRU_ID",
+ $fru);
+ }
+
+ # Populate EEPROM for dimm
+ $self->setAttributeField($target_parent, $eeprom_name, "engine",
+ $engine);
+ $self->setAttributeField($target_parent, $eeprom_name, "port",
+ $port);
+ $self->setAttributeField($target_parent, $eeprom_name, "i2cMuxBusSelector",
+ $mux);
+ $self->setAttributeField($target_parent, $eeprom_name, "i2cMuxPath",
+ $i2c_mux_path);
+ $self->setAttribute($target_parent, "FRU_ID",
+ $fru);
+ }
+ }
+}
+
# Find connections from/to $target (and it's children)
# $to_this_target indicates the direction to find.
sub findConnectionsByDirection
@@ -2049,6 +2690,7 @@ sub findConnectionsByDirection
{
$numOfConnections = $self->getNumConnections($child);
}
+
for (my $i = 0; $i < $numOfConnections; $i++)
{
my $other_end_target = undef;
@@ -2061,6 +2703,7 @@ sub findConnectionsByDirection
$other_end_target = $self->getConnectionDestination($child,
$i);
}
+
my $other_end_parent = $self->getTargetParent($other_end_target);
my $type = $self->getMrwType($other_end_parent);
my $dest_type = $self->getType($other_end_parent);
@@ -2079,12 +2722,10 @@ sub findConnectionsByDirection
#like unit->pingroup->muxgroup->chip where the chip has
#the interesting type.
while ($type ne $other_end_type) {
-
$other_end_parent = $self->getTargetParent($other_end_parent);
if ($other_end_parent eq "") {
last;
}
-
$type = $self->getMrwType($other_end_parent);
if ($type eq "NA") {
$type = $self->getType($other_end_parent);
@@ -2518,7 +3159,6 @@ sub setHuid
$index = $self->{huid_idx}->{$type};
}
else { $self->{huid_idx}->{$type} = 0; }
-
# Format: SSSS NNNN TTTTTTTT iiiiiiiiiiiiiiii
my $huid = sprintf("%01x%01x%02x%04x", $sys, $node, $type_id, $index);
$huid = "0x" . uc($huid);
@@ -2554,6 +3194,19 @@ sub setMruid
$self->{mru_idx}->{$node}->{$type}++;
}
+sub getMasterProc
+{
+ my $self = shift;
+ return $self->{master_proc};
+}
+
+sub setMasterProc
+{
+ my $self = shift;
+ my $target = shift;
+ $self->{master_proc}=$target;
+}
+
sub getSystemName
{
my $self = shift;
@@ -2786,11 +3439,16 @@ C<TARGET_STRING>. The bus data structure is also a target with attributes.
Returns the target string of the C<INDEX> target found connected to
C<TARGET_STRING>.
-=item getConnectionBus(C<TARGET_STRING>)
+=item getConnectionBus(C<TARGET_STRING>,C<INDEX>)
Returns the data structure of the C<INDEX> bus target found connected to
C<TARGET_STRING>.
+=item getConnectionBusParent(C<TARGET_STRING>,C<INDEX>)
+
+Returns C<PARENT_TARGET_STRING> of the parent target for the bus target found
+connected to C<TARGET_STRING>
+
=item findEndpoint(C<TARGET_STRING>,C<BUS_TYPE>,C<ENDPOINT_MRW_TYPE>)
Searches through all connections to C<TARGET_STRING>
diff --git a/src/usr/targeting/common/associationmanager.C b/src/usr/targeting/common/associationmanager.C
index 984eb17ec..b811f1861 100644
--- a/src/usr/targeting/common/associationmanager.C
+++ b/src/usr/targeting/common/associationmanager.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -199,7 +199,7 @@ errlHndl_t AssociationManager::reconnectSyAndNodeTargets()
{
TARG_ERR("Failed to find master system target");
- /*
+ /*@
* @errortype
* @refcode LIC_REFCODE
* @subsys EPUB_FIRMWARE_SP
@@ -304,7 +304,7 @@ errlHndl_t AssociationManager::_clearAssocsOfTypeFromSysOrNodeTarget(
pAssocsItrPreTrans,
i_pSysOrNodeTarget->getAttr<TARGETING::ATTR_HUID>(),
i_pSysOrNodeTarget);
- /*
+ /*@
* @errortype
* @refcode LIC_REFCODE
* @subsys EPUB_FIRMWARE_SP
@@ -447,7 +447,7 @@ errlHndl_t AssociationManager::_addAssocToSysOrNodeTarget(
pAssocsItrPreTrans,
i_pSourceSysOrNodeTarget->getAttr<TARGETING::ATTR_HUID>(),
i_pSourceSysOrNodeTarget);
- /*
+ /*@
* @errortype
* @refcode LIC_REFCODE
* @subsys EPUB_FIRMWARE_SP
@@ -482,7 +482,7 @@ errlHndl_t AssociationManager::_addAssocToSysOrNodeTarget(
"maxLinks = %d, i_assocType = 0x%08X, HUID = 0x%08X",
association, maxLinks, i_assocType,
i_pSourceSysOrNodeTarget->getAttr<TARGETING::ATTR_HUID>());
- /*
+ /*@
* @errortype
* @refcode LIC_REFCODE
* @subsys EPUB_FIRMWARE_SP
diff --git a/src/usr/targeting/common/attributeTank.C b/src/usr/targeting/common/attributeTank.C
index 07ccff982..c6cad3c49 100644
--- a/src/usr/targeting/common/attributeTank.C
+++ b/src/usr/targeting/common/attributeTank.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -99,10 +99,12 @@ void AttributeTank::clearAllAttributes(
while (l_itr != iv_attributes.end())
{
+ // Get a copy of the Attribute's node for quick access
+ uint8_t l_node = (*l_itr)->getHeader().iv_node;
if (i_nodeFilter == NODE_FILTER_NOT_ALL_NODES)
{
// Only clear attributes that are not for all nodes
- if ((*l_itr)->iv_hdr.iv_node == ATTR_NODE_NA)
+ if (l_node == ATTR_NODE_NA)
{
l_itr++;
continue;
@@ -111,8 +113,8 @@ void AttributeTank::clearAllAttributes(
else if (i_nodeFilter == NODE_FILTER_SPECIFIC_NODE_AND_ALL)
{
// Only clear attributes associated with i_node or all
- if ( ((*l_itr)->iv_hdr.iv_node != ATTR_NODE_NA) &&
- ((*l_itr)->iv_hdr.iv_node != i_node) )
+ if ( (l_node != ATTR_NODE_NA) &&
+ (l_node != i_node) )
{
l_itr++;
continue;
@@ -121,7 +123,7 @@ void AttributeTank::clearAllAttributes(
else if (i_nodeFilter == NODE_FILTER_SPECIFIC_NODE)
{
// Only clear attributes associated with i_node
- if ((*l_itr)->iv_hdr.iv_node != i_node)
+ if (l_node != i_node)
{
l_itr++;
continue;
@@ -153,13 +155,18 @@ void AttributeTank::clearNonConstAttribute(const uint32_t i_attrId,
for (AttributesItr_t l_itr = iv_attributes.begin();
l_itr != iv_attributes.end(); ++l_itr)
{
- if ( ((*l_itr)->iv_hdr.iv_attrId == i_attrId) &&
- ((*l_itr)->iv_hdr.iv_targetType == i_targetType) &&
- ((*l_itr)->iv_hdr.iv_pos == i_pos) &&
- ((*l_itr)->iv_hdr.iv_unitPos == i_unitPos) &&
- ((*l_itr)->iv_hdr.iv_node == i_node) )
+ // Get a (constant) reference to the Attribute Header
+ // for easy access to data members
+ const AttributeHeader &l_attributeHeader = (*l_itr)->getHeader();
+
+ // Find attribute that satisfies search criteria
+ if ( (l_attributeHeader.iv_attrId == i_attrId) &&
+ (l_attributeHeader.iv_targetType == i_targetType) &&
+ (l_attributeHeader.iv_pos == i_pos) &&
+ (l_attributeHeader.iv_unitPos == i_unitPos) &&
+ (l_attributeHeader.iv_node == i_node) )
{
- if (!((*l_itr)->iv_hdr.iv_flags & ATTR_FLAG_CONST))
+ if (!(l_attributeHeader.iv_flags & ATTR_FLAG_CONST))
{
delete (*l_itr);
(*l_itr) = NULL;
@@ -196,20 +203,25 @@ void AttributeTank::setAttribute(const uint32_t i_attrId,
for (AttributesItr_t l_itr = iv_attributes.begin();
l_itr != iv_attributes.end(); ++l_itr)
{
- if ( ((*l_itr)->iv_hdr.iv_attrId == i_attrId) &&
- ((*l_itr)->iv_hdr.iv_targetType == i_targetType) &&
- ((*l_itr)->iv_hdr.iv_pos == i_pos) &&
- ((*l_itr)->iv_hdr.iv_unitPos == i_unitPos) &&
- ((*l_itr)->iv_hdr.iv_node == i_node) &&
- ((*l_itr)->iv_hdr.iv_valSize == i_valSize) )
+ // Get a reference to the Attribute Header
+ // for easy access to data members
+ const AttributeHeader &l_attributeHeader = (*l_itr)->getHeader();
+
+ // Find attribute that satisfies search criteria
+ if ( (l_attributeHeader.iv_attrId == i_attrId) &&
+ (l_attributeHeader.iv_targetType == i_targetType) &&
+ (l_attributeHeader.iv_pos == i_pos) &&
+ (l_attributeHeader.iv_unitPos == i_unitPos) &&
+ (l_attributeHeader.iv_node == i_node) &&
+ (l_attributeHeader.iv_valSize == i_valSize) )
{
// Found existing attribute, update it unless the existing attribute
// is const and the new attribute is non-const
- if (!( ((*l_itr)->iv_hdr.iv_flags & ATTR_FLAG_CONST) &&
+ if (!( (l_attributeHeader.iv_flags & ATTR_FLAG_CONST) &&
(!(i_flags & ATTR_FLAG_CONST)) ) )
{
- (*l_itr)->iv_hdr.iv_flags = i_flags;
- memcpy((*l_itr)->iv_pVal, i_pVal, i_valSize);
+ (*l_itr)->setFlags(i_flags);
+ (*l_itr)->setValue(i_pVal, i_valSize);
}
l_found = true;
break;
@@ -221,15 +233,13 @@ void AttributeTank::setAttribute(const uint32_t i_attrId,
// Add a new attribute to the tank
Attribute * l_pAttr = new Attribute();
- l_pAttr->iv_hdr.iv_attrId = i_attrId;
- l_pAttr->iv_hdr.iv_targetType = i_targetType;
- l_pAttr->iv_hdr.iv_pos = i_pos;
- l_pAttr->iv_hdr.iv_unitPos = i_unitPos;
- l_pAttr->iv_hdr.iv_node = i_node;
- l_pAttr->iv_hdr.iv_flags = i_flags;
- l_pAttr->iv_hdr.iv_valSize = i_valSize;
- l_pAttr->iv_pVal = new uint8_t[i_valSize];
- memcpy(l_pAttr->iv_pVal, i_pVal, i_valSize);
+ l_pAttr->setId(i_attrId);
+ l_pAttr->setTargetType(i_targetType);
+ l_pAttr->setPosition(i_pos);
+ l_pAttr->setUnitPosition(i_unitPos);
+ l_pAttr->setNode(i_node);
+ l_pAttr->setFlags(i_flags);
+ l_pAttr->setValue(i_pVal, i_valSize);
iv_attributesExist = true;
iv_attributes.push_back(l_pAttr);
@@ -253,18 +263,22 @@ bool AttributeTank::getAttribute(const uint32_t i_attrId,
for (AttributesCItr_t l_itr = iv_attributes.begin(); l_itr
!= iv_attributes.end(); ++l_itr)
{
- // Allow match if attribute applies to all positions
- if ( ((*l_itr)->iv_hdr.iv_attrId == i_attrId) &&
- ((*l_itr)->iv_hdr.iv_targetType == i_targetType) &&
- (((*l_itr)->iv_hdr.iv_pos == ATTR_POS_NA) ||
- ((*l_itr)->iv_hdr.iv_pos == i_pos)) &&
- (((*l_itr)->iv_hdr.iv_unitPos == ATTR_UNIT_POS_NA) ||
- ((*l_itr)->iv_hdr.iv_unitPos == i_unitPos)) &&
- (((*l_itr)->iv_hdr.iv_node == ATTR_NODE_NA) ||
- ((*l_itr)->iv_hdr.iv_node == i_node)) )
+ // Get a (constant) reference to the Attribute Header
+ // for easy access to data members
+ const AttributeHeader &l_attributeHeader = (*l_itr)->getHeader();
+
+ // Find attribute that satisfies search criteria
+ if ( (l_attributeHeader.iv_attrId == i_attrId) &&
+ (l_attributeHeader.iv_targetType == i_targetType) &&
+ ((l_attributeHeader.iv_pos == ATTR_POS_NA) ||
+ (l_attributeHeader.iv_pos == i_pos)) &&
+ ((l_attributeHeader.iv_unitPos == ATTR_UNIT_POS_NA) ||
+ (l_attributeHeader.iv_unitPos == i_unitPos)) &&
+ ((l_attributeHeader.iv_node == ATTR_NODE_NA) ||
+ (l_attributeHeader.iv_node == i_node)) )
{
l_found = true;
- memcpy(o_pVal, (*l_itr)->iv_pVal, (*l_itr)->iv_hdr.iv_valSize);
+ (*l_itr)->cloneValue(o_pVal, l_attributeHeader.iv_valSize);
break;
}
}
@@ -293,10 +307,18 @@ void AttributeTank::serializeAttributes(
// Fill up the buffer with as many attributes as possible
while (l_itr != iv_attributes.end())
{
+ // Get a (constant) reference to the Attribute Header
+ // for easy access to data members
+ const AttributeHeader &l_attributeHeader =
+ (*l_itr)->getHeader();
+
+ // Get a copy of the node for quick access
+ uint8_t l_node = l_attributeHeader.iv_node;
+
if (i_nodeFilter == NODE_FILTER_NOT_ALL_NODES)
{
// Only want attributes that are not for all nodes
- if ((*l_itr)->iv_hdr.iv_node == ATTR_NODE_NA)
+ if (l_node == ATTR_NODE_NA)
{
l_itr++;
continue;
@@ -305,8 +327,8 @@ void AttributeTank::serializeAttributes(
else if (i_nodeFilter == NODE_FILTER_SPECIFIC_NODE_AND_ALL)
{
// Only want attributes associated with i_node or all
- if ( ((*l_itr)->iv_hdr.iv_node != ATTR_NODE_NA) &&
- ((*l_itr)->iv_hdr.iv_node != i_node) )
+ if ( (l_node != ATTR_NODE_NA) &&
+ (l_node != i_node) )
{
l_itr++;
continue;
@@ -315,15 +337,14 @@ void AttributeTank::serializeAttributes(
else if (i_nodeFilter == NODE_FILTER_SPECIFIC_NODE)
{
// Only want attributes associated with i_node
- if ((*l_itr)->iv_hdr.iv_node != i_node)
+ if (l_node != i_node)
{
l_itr++;
continue;
}
}
- if ((l_index + sizeof(AttributeHeader) +
- (*l_itr)->iv_hdr.iv_valSize) > i_chunkSize)
+ if ((l_index + (*l_itr)->getSize()) > i_chunkSize)
{
// Attribute will not fit into the buffer
if (l_index == 0)
@@ -334,7 +355,7 @@ void AttributeTank::serializeAttributes(
TRACFCOMP(g_trac_targeting,
"serializeAttributes: Error, attr too big to serialize "
"(0x%x)",
- (*l_itr)->iv_hdr.iv_valSize);
+ l_attributeHeader.iv_valSize);
l_itr++;
}
else
@@ -346,17 +367,8 @@ void AttributeTank::serializeAttributes(
}
else
{
- // Copy the attribute header to the buffer
- AttributeHeader * l_pHeader =
- reinterpret_cast<AttributeHeader *>(l_pBuffer + l_index);
- *l_pHeader = (*l_itr)->iv_hdr;
- l_index += sizeof(AttributeHeader);
-
- // Copy the attribute value to the buffer
- memcpy((l_pBuffer + l_index), (*l_itr)->iv_pVal,
- (*l_itr)->iv_hdr.iv_valSize);
- l_index += (*l_itr)->iv_hdr.iv_valSize;
-
+ l_index += (*l_itr)->serialize(l_pBuffer + l_index,
+ (*l_itr)->getSize());
l_itr++;
}
}
@@ -404,7 +416,7 @@ bool AttributeTank::attributeExists(const uint32_t i_attrId) const
for (AttributesCItr_t l_itr = iv_attributes.begin(); l_itr
!= iv_attributes.end(); ++l_itr)
{
- if ((*l_itr)->iv_hdr.iv_attrId == i_attrId)
+ if ((*l_itr)->getHeader().iv_attrId == i_attrId)
{
l_found = true;
break;
@@ -424,60 +436,54 @@ void AttributeTank::deserializeAttributes(
uint32_t l_index = 0;
+ // Get a handle to the serialized Attributes
+ uint8_t* l_serializedData =
+ reinterpret_cast<uint8_t*>(i_attributes.iv_pAttributes);
+
+ // Iterate thru the Attributes
while (l_index < i_attributes.iv_size)
{
- AttributeHeader * l_pAttrHdr =
- reinterpret_cast<AttributeHeader *>
- (i_attributes.iv_pAttributes + l_index);
+ // Create a new Attribute
+ Attribute * l_pAttribute = new Attribute();
- if (sizeof(AttributeHeader) > (i_attributes.iv_size - l_index))
+ // Deserialize the data, if possible
+ uint32_t l_deserializedDataSize = l_pAttribute->deserialize(
+ l_serializedData + l_index,
+ i_attributes.iv_size - l_index);
+
+ if (!l_deserializedDataSize)
{
+ // Unable to deserialize data, delete Attribute
+ delete l_pAttribute;
+ l_pAttribute = NULL;
+
// Remaining chunk smaller than attribute header, quit
TRACFCOMP(g_trac_targeting,
- "deserializeAttributes: Error, header too big for chunk "
- "(0x%x)",
+ "deserializeAttributes: Error, attribute too big for "
+ "chunk (0x%x)",
(i_attributes.iv_size - l_index));
break;
}
- l_index += sizeof(AttributeHeader);
-
- if (l_pAttrHdr->iv_valSize > (i_attributes.iv_size - l_index))
- {
- // Remaining chunk smaller than attribute value, quit
- TRACFCOMP(g_trac_targeting,
- "deserializeAttributes: Error, attr too big for chunk "
- "(0x%x:0x%x)",
- l_pAttrHdr->iv_valSize, (i_attributes.iv_size - l_index));
- break;
- }
-
- // Create a new Attribute and add it to the tank
- Attribute * l_pAttr = new Attribute();
- l_pAttr->iv_hdr = *l_pAttrHdr;
- l_pAttr->iv_pVal = new uint8_t[l_pAttrHdr->iv_valSize];
- memcpy(l_pAttr->iv_pVal, (i_attributes.iv_pAttributes + l_index),
- l_pAttrHdr->iv_valSize);
-
- l_index += l_pAttrHdr->iv_valSize;
+ // Was able to deserialize data, add Attribute to the tank
iv_attributesExist = true;
- iv_attributes.push_back(l_pAttr);
+ iv_attributes.push_back(l_pAttribute);
+
+ // Increment the index after deserializing an attribute
+ l_index += l_deserializedDataSize;
- if // attributes should be echo'd
- ( i_echoAttributes == true )
+ if ( i_echoAttributes == true ) // attributes should be echo'd
{
// extract individual fields from attribute
- uint32_t attrId = l_pAttr->iv_hdr.iv_attrId;
- uint32_t targetType = l_pAttr->iv_hdr.iv_targetType;
- uint16_t pos = l_pAttr->iv_hdr.iv_pos;
- uint8_t unitPos = l_pAttr->iv_hdr.iv_unitPos;
-
- const uint8_t * pNodeFlags = (&(l_pAttr->iv_hdr.iv_unitPos)) + 1;
+ uint32_t attrId(l_pAttribute->getHeader().iv_attrId);
+ uint32_t targetType(l_pAttribute->getHeader().iv_targetType);
+ uint16_t pos(l_pAttribute->getHeader().iv_pos);
+ uint8_t unitPos(l_pAttribute->getHeader().iv_unitPos);
- uint8_t node = (*pNodeFlags) >> 4; // isolate hi nibble
- uint8_t flags = (*pNodeFlags) & 0x0F; // isolate lo nibble
+ uint8_t node(l_pAttribute->getHeader().iv_node);
+ uint8_t flags(l_pAttribute->getHeader().iv_flags);
- uint32_t valueLen = l_pAttr->iv_hdr.iv_valSize;
+ uint32_t valueLen(l_pAttribute->getHeader().iv_valSize);
TRACFCOMP(g_trac_targeting,
"deserializeAttributes: Attribute Hdr: "
@@ -488,7 +494,7 @@ void AttributeTank::deserializeAttributes(
TRACFBIN(g_trac_targeting,
"deserializeAttributes: Parm Value: ",
- l_pAttr->iv_pVal, valueLen);
+ l_pAttribute->getValue(), valueLen);
} // end echo attributes
}
@@ -505,20 +511,6 @@ void AttributeTank::deserializeAttributes(
}
//******************************************************************************
-AttributeTank::Attribute::Attribute() :
- iv_pVal(NULL)
-{
-
-}
-
-//******************************************************************************
-AttributeTank::Attribute::~Attribute()
-{
- delete[] iv_pVal;
- iv_pVal = NULL;
-}
-
-//******************************************************************************
errlHndl_t AttributeTank::writePermAttributes()
{
errlHndl_t l_err = NULL;
@@ -526,8 +518,10 @@ errlHndl_t AttributeTank::writePermAttributes()
for(AttributesCItr_t l_attrIter = iv_attributes.begin();
l_attrIter != iv_attributes.end(); ++l_attrIter)
{
- Attribute* l_attr = *l_attrIter;
- AttributeHeader l_attrHdr = l_attr->iv_hdr;
+ // Get a (constant) reference to the Attribute Header
+ // for easy access to data members
+ const AttributeHeader &l_attrHdr = (*l_attrIter)->getHeader();
+
PredicatePostfixExpr l_permAttrOverrides;
// Predicate to match target type
@@ -553,7 +547,7 @@ errlHndl_t AttributeTank::writePermAttributes()
bool l_success = (*l_permTargetList)->_trySetAttr(
static_cast<ATTRIBUTE_ID>(l_attrHdr.iv_attrId),
l_attrHdr.iv_valSize,
- l_attr->iv_pVal );
+ (*l_attrIter)->getValue() );
if (l_success)
{
@@ -561,16 +555,17 @@ errlHndl_t AttributeTank::writePermAttributes()
"permanent override of Attr ID:0x%X Value:0x%llX applied "
"to target 0x%X",
l_attrHdr.iv_attrId,
- *reinterpret_cast<uint64_t *>(l_attr->iv_pVal),
+ *reinterpret_cast<const uint64_t *>
+ ((*l_attrIter)->getValue()),
(*l_permTargetList)->getAttr<ATTR_HUID>() );
}
else
{
- uint8_t * io_pAttrData = NULL;
+ uint8_t * l_pAttrData(NULL);
bool l_found = (*l_permTargetList)->_tryGetAttr(
static_cast<ATTRIBUTE_ID>(l_attrHdr.iv_attrId),
l_attrHdr.iv_valSize,
- io_pAttrData);
+ l_pAttrData);
if (l_found)
{
@@ -579,9 +574,10 @@ errlHndl_t AttributeTank::writePermAttributes()
"ID:0x%X Value:0x%llX on target 0x%X - current value "
"0x%llX",
l_attrHdr.iv_attrId,
- *reinterpret_cast<uint64_t *>(l_attr->iv_pVal),
+ *reinterpret_cast<const uint64_t *>
+ ((*l_attrIter)->getValue()),
(*l_permTargetList)->getAttr<ATTR_HUID>(),
- *reinterpret_cast<uint64_t *>(io_pAttrData) );
+ *reinterpret_cast<uint64_t *>(l_pAttrData) );
/*@
* @errortype
* @moduleid TARG_WRITE_PERM_ATTR
@@ -616,7 +612,7 @@ errlHndl_t AttributeTank::writePermAttributes()
* @devdesc Given target does not have given attribute
* to apply override
*/
- UTIL::createTracingError(
+ UTIL::createTracingError(
TARG_WRITE_PERM_ATTR,
TARG_RC_WRITE_PERM_ATTR_TARGET_FAIL,
(*l_permTargetList)->getAttr<ATTR_HUID>(),
@@ -641,4 +637,23 @@ size_t AttributeTank::size() const
return iv_attributes.size();
}
+//******************************************************************************
+void AttributeTank::getAllAttributes( std::list<Attribute *>& o_attributes ) const
+{
+ o_attributes = iv_attributes;
+}
+
+//******************************************************************************
+const char* AttributeTank::layerToString( TankLayer i_layer )
+{
+ switch(i_layer)
+ {
+ case(AttributeTank::TANK_LAYER_FAPI): return "FAPI";
+ case(AttributeTank::TANK_LAYER_TARG): return "TARG";
+ case(AttributeTank::TANK_LAYER_PERM): return "PERM";
+ default: return "UNKNOWN";
+ }
+}
+
}
+
diff --git a/src/usr/targeting/common/common.mk b/src/usr/targeting/common/common.mk
index 5c357f111..951aa8663 100644
--- a/src/usr/targeting/common/common.mk
+++ b/src/usr/targeting/common/common.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2011,2018
+# Contributors Listed Below - COPYRIGHT 2011,2020
# [+] International Business Machines Corp.
#
#
@@ -64,4 +64,3 @@ COMMON_TARGETING_OBJS += ${TARGET_OBJS}
COMMON_TARGETING_OBJS += ${PREDICATES_OBJS}
COMMON_TARGETING_OBJS += ${ITERATORS_OBJS}
COMMON_TARGETING_OBJS += ${OTHER_OBJS}
-
diff --git a/src/usr/targeting/common/genHDATstructures.pl b/src/usr/targeting/common/genHDATstructures.pl
index 5150e3a06..2bbcbfd9a 100755
--- a/src/usr/targeting/common/genHDATstructures.pl
+++ b/src/usr/targeting/common/genHDATstructures.pl
@@ -6,7 +6,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2015,2018
+# Contributors Listed Below - COPYRIGHT 2015,2019
# [+] International Business Machines Corp.
#
#
diff --git a/src/usr/targeting/common/genHwsvMrwXml.pl b/src/usr/targeting/common/genHwsvMrwXml.pl
index 1632b1cfc..c6b185426 100755
--- a/src/usr/targeting/common/genHwsvMrwXml.pl
+++ b/src/usr/targeting/common/genHwsvMrwXml.pl
@@ -6077,6 +6077,14 @@ sub generate_is_dimm
my $uidstr = sprintf( "0x%02X03%04X", $node, $dimm_rel_node );
+ # Generate the slot position for mvdimm restrictions
+ # The formula is:
+ # [processor position with no gaps, i.e. 0,1,2,3]*16 +
+ # [mca position on this processor * 2] + [dimm location behind this mca]
+ my $nvdimmslot = ($proc * MAX_MCA_PER_PROC * ARCH_LIMIT_DIMM_PER_MCA)
+ + ($mca * 2) + ($dimm_rel_mca);
+
+
# add dimm to mcbist array
push(@{$mcbist_dimms{$node . $proc."_".$mcb_rel_proc}}, "n${node}:p${pos}");
@@ -6117,6 +6125,10 @@ sub generate_is_dimm
<default>$dimm_drop</default>
</attribute>
<attribute>
+ <id>MSS_MRW_NVDIMM_SLOT_POSITION</id>
+ <default>$nvdimmslot</default>
+ </attribute>
+ <attribute>
<id>POS_ON_MEM_PORT</id>
<default>$dimm_rel_mca</default>
</attribute>";
diff --git a/src/usr/targeting/common/hbrt_target.C b/src/usr/targeting/common/hbrt_target.C
new file mode 100644
index 000000000..b91979922
--- /dev/null
+++ b/src/usr/targeting/common/hbrt_target.C
@@ -0,0 +1,101 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/targeting/common/hbrt_target.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <targeting/common/hbrt_target.H>
+#include <targeting/common/targetservice.H>
+#include <targeting/common/targreasoncodes.H>
+#include <runtime/customize_attrs_for_payload.H>
+#include <targeting/common/trace.H>
+#ifdef __HOSTBOOT_MODULE
+#include <errl/errludtarget.H>
+#endif
+
+extern trace_desc_t* g_trac_hbrt;
+using namespace TARGETING;
+
+namespace TARGETING
+{
+
+errlHndl_t getRtTarget(
+ const TARGETING::Target* i_pTarget,
+ rtChipId_t& o_rtTargetId)
+{
+ errlHndl_t pError = NULL;
+
+ do
+ {
+ if(i_pTarget == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL)
+ {
+ TARGETING::Target* masterProcChip = NULL;
+ TARGETING::targetService().
+ masterProcChipTargetHandle(masterProcChip);
+ i_pTarget = masterProcChip;
+ }
+
+ auto hbrtHypId = RUNTIME::HBRT_HYP_ID_UNKNOWN;
+ if( (!i_pTarget->tryGetAttr<TARGETING::ATTR_HBRT_HYP_ID>(hbrtHypId))
+ || (hbrtHypId == RUNTIME::HBRT_HYP_ID_UNKNOWN))
+ {
+ auto huid = get_huid(i_pTarget);
+ auto targetingTargetType =
+ i_pTarget->getAttr<TARGETING::ATTR_TYPE>();
+ TRACFCOMP(g_trac_targeting, ERR_MRK
+ "Targeting target type of 0x%08X not supported. "
+ "HUID: 0x%08X",
+ targetingTargetType,
+ huid);
+ /*@
+ * @errortype
+ * @moduleid TARG_RT_GET_RT_TARGET
+ * @reasoncode TARG_RT_TARGET_TYPE_NOT_SUPPORTED
+ * @userdata1 Target's HUID
+ * @userdata2 target's targeting type
+ * @devdesc Targeting target's type not supported by runtime
+ * code
+ */
+ pError = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ TARGETING::TARG_RT_GET_RT_TARGET,
+ TARGETING::TARG_RT_TARGET_TYPE_NOT_SUPPORTED,
+ huid,
+ targetingTargetType
+#ifdef __HOSTBOOT_MODULE
+ ,true);
+
+ ERRORLOG::ErrlUserDetailsTarget(i_pTarget,"Targeting Target").
+ addToLog(pError);
+#else
+ ); // if not in hostboot code then skip last param of error log
+ // and do not create a user details section
+#endif
+ }
+
+ o_rtTargetId = hbrtHypId;
+
+ } while(0);
+
+ return pError;
+}
+
+} \ No newline at end of file
diff --git a/src/usr/targeting/common/processMrw.pl b/src/usr/targeting/common/processMrw.pl
index 341574246..2b88520ba 100755
--- a/src/usr/targeting/common/processMrw.pl
+++ b/src/usr/targeting/common/processMrw.pl
@@ -44,9 +44,27 @@ my $debug = 0;
my $report = 0;
my $sdr_file = "";
my $build = "hb";
-my $system_config = "";
+my $system_config = "";
my $output_filename = "";
+# Map the OMI instance to its corresponding OMIC parent
+my %omi_map = (4 => "omic-0",
+ 5 => "omic-0",
+ 6 => "omic-0",
+ 7 => "omic-1",
+ 2 => "omic-1",
+ 3 => "omic-1",
+ 0 => "omic-2",
+ 1 => "omic-2",
+ 12 => "omic-0",
+ 13 => "omic-0",
+ 14 => "omic-0",
+ 15 => "omic-1",
+ 10 => "omic-1",
+ 11 => "omic-1",
+ 8 => "omic-2",
+ 9 => "omic-2");
+
# TODO RTC:170860 - Remove this after dimm connector defines VDDR_ID
my $num_voltage_rails_per_proc = 1;
@@ -378,7 +396,10 @@ foreach my $target (@targets)
{
processUcd($targetObj, $target);
}
-
+ }
+ elsif ($type eq "OCMB_CHIP")
+ {
+ processOcmbChip($targetObj, $target);
}
processIpmiSensors($targetObj,$target);
@@ -1135,7 +1156,6 @@ sub processProcessor
## update path for mvpd's and sbe's
my $path = $targetObj->getAttribute($target, "PHYS_PATH");
my $model = $targetObj->getAttribute($target, "MODEL");
-
$targetObj->setAttributeField($target,
"EEPROM_VPD_PRIMARY_INFO","i2cMasterPath",$path);
$targetObj->setAttributeField($target,
@@ -1434,9 +1454,9 @@ sub setupBars
foreach my $bar (keys %bars)
{
my $i_base = Math::BigInt->new($bars{$bar});
- my $value=sprintf("0x%016s",substr((
- $i_base+$groupOffset*$group+
- $procOffset*$proc)->as_hex(),2));
+ my $value=sprintf("0x%016s",substr((
+ $i_base+$groupOffset*$group+
+ $procOffset*$proc)->as_hex(),2));
$targetObj->setAttribute($target,$bar,$value);
}
}
@@ -1642,6 +1662,9 @@ sub processMcbist
##
sub processMc
{
+ # NOTE: OMI_INBAND_BAR_BASE_ADDR_OFFSET will be set for the MC
+ # targets via a specific child OMI Target. View the
+ # processOmi function for further details.
my $targetObj = shift;
my $target = shift;
@@ -1656,6 +1679,10 @@ sub processMc
{
processMi($targetObj, $child);
}
+ elsif ($child_type eq "OMIC")
+ {
+ processOmic($targetObj, $child);
+ }
}
{
@@ -1669,8 +1696,146 @@ sub processMc
}
}
+#--------------------------------------------------
+## MCC
+##
+##
+sub processMcc
+{
+ my $targetObj = shift;
+ my $target = shift;
+
+ foreach my $child (@{ $targetObj->getTargetChildren($target) })
+ {
+ my $child_type = $targetObj->getType($child);
+
+ $targetObj->log($target,
+ "Processing MCC child: $child Type: $child_type");
+
+ if ($child_type eq "OMI")
+ {
+ processOmi($targetObj, $child);
+ }
+ }
+
+ {
+ use integer;
+ # There are a total of four MCC units on an MC unit. So, to
+ # determine which MC an MCC belongs to, the CHIP_UNIT of the MCC can
+ # be divided by the number of units per MC to arrive at the correct
+ # offset to add to the pervasive MCC parent offset.
+ my $numberOfMccPerMc = 4;
+ my $chip_unit = $targetObj->getAttribute($target, "CHIP_UNIT");
+
+ my $value = sprintf("0x%x",
+ Targets::PERVASIVE_PARENT_MI_OFFSET
+ + ($chip_unit / $numberOfMccPerMc));
+
+ $targetObj->setAttribute( $target, "CHIPLET_ID", $value);
+ }
+}
#--------------------------------------------------
+## OMI
+##
+##
+sub processOmi
+{
+ my $mrwObj = shift;
+ my $omitarg = shift;
+
+ use integer;
+ # There are a total of eight OMI units on an MC unit. So, to
+ # determine which MC an OMI belongs to, the CHIP_UNIT of the OMI can
+ # be divided by the number of units per MC to arrive at the correct
+ # offset to add to the pervasive OMI parent offset.
+ my $numberOfOmiPerMc = 8;
+ my $chip_unit = $mrwObj->getAttribute($omitarg, "CHIP_UNIT");
+ my $fapi_pos = $mrwObj->getAttribute($omitarg, "FAPI_POS");
+ my $value = sprintf("0x%x",
+ Targets::PERVASIVE_PARENT_MI_OFFSET
+ + ($chip_unit / $numberOfOmiPerMc));
+
+ $mrwObj->setAttribute($omitarg, "CHIPLET_ID", $value);
+
+ # Start with our affinity path "sys-a/node-b/proc-c/mc-d/mi-e/mcc-f/omi-g"
+ # then snip off everything before the mi
+ my $phys_path = $mrwObj->getAttribute($omitarg, "PHYS_PATH");
+ my $up_to_mi = index($phys_path,"mi-");
+ my $omic_parent = substr($phys_path,0,$up_to_mi);
+ $omic_parent = $omic_parent.$omi_map{$chip_unit};
+ $mrwObj->setAttribute($omitarg, "OMIC_PARENT", $omic_parent);
+
+ my $omi = Math::BigInt->new($mrwObj->getAttribute($omitarg,"FAPI_POS"));
+ # Base omi bar offset
+ # We use this base address in simics_AXONE.system.xml and want our
+ # addresses to match the ones in that xml
+ my $base = 0x30400000000;
+ my $gigabyte = 0x40000000;
+ my $value = 0;
+
+ # This algorithm is explained in src/usr/mmio/mmio.C
+ if ($omi % 2 eq 0)
+ {
+ $value = $base + $omi * 4 * $gigabyte;
+ }
+ else
+ {
+ $value = $base + (($omi - 1) * 4 + 2) * $gigabyte;
+ }
+
+ $value = sprintf("0x%016s", substr(($value)->as_hex(),2));
+ $mrwObj->setAttribute($omitarg, "OMI_INBAND_BAR_BASE_ADDR_OFFSET",
+ $value);
+
+ # Set the parent MC BAR value to value of first OMI unit
+ if ($omi % 8 eq 0)
+ {
+ my $parent_mcc = $mrwObj->getTargetParent($omitarg);
+ my $parent_mi = $mrwObj->getTargetParent($parent_mcc);
+ my $parent_mc = $mrwObj->getTargetParent($parent_mi);
+ $mrwObj->setAttribute($parent_mc, "OMI_INBAND_BAR_BASE_ADDR_OFFSET",
+ $value);
+ }
+}
+
+#--------------------------------------------------
+## OMIC
+##
+##
+sub processOmic
+{
+ my $targetObj = shift;
+ my $target = shift;
+
+ use integer;
+ # There are a total of three OMIC units on an MC unit. So, to
+ # determine which MC an OMIC belongs to, the CHIP_UNIT of the OMIC can
+ # be divided by the number of units per MC to arrive at the correct
+ # offset to add to the pervasive OMIC parent offset.
+ my $numberOfOmicPerMc = 3;
+ my $chip_unit = $targetObj->getAttribute($target, "CHIP_UNIT");
+
+ my $value = sprintf("0x%x",
+ Targets::PERVASIVE_PARENT_MI_OFFSET
+ + ($chip_unit / $numberOfOmicPerMc));
+
+ $targetObj->setAttribute( $target, "CHIPLET_ID", $value);
+}
+
+#--------------------------------------------------
+## OCMB_CHIP
+##
+##
+sub processOcmbChip
+{
+ my $targetObj = shift;
+ my $target = shift;
+
+ $targetObj->setEepromAttributesForAxone($targetObj, $target);
+}
+
+#-------------------------------------------------g
## MI
##
##
@@ -1690,6 +1855,10 @@ sub processMi
{
processDmi($targetObj, $child);
}
+ elsif ($child_type eq "MCC")
+ {
+ processMcc($targetObj, $child);
+ }
}
{
@@ -1745,7 +1914,7 @@ sub processDmi
Targets::PERVASIVE_PARENT_DMI_OFFSET
+ ($chip_unit / $numberOfDmiPerMc));
- $targetObj->setAttribute( $target, "CHIPLET_ID", $value);
+ $targetObj->setAttribute($target, "CHIPLET_ID", $value);
}
}
@@ -1837,12 +2006,27 @@ sub processObus
if ($match eq 0)
{
$targetObj->setAttribute($obrick, "OBUS_SLOT_INDEX", -1);
-
}
}
}
}
+
+ my $chip_unit = $targetObj->getAttribute($target, "CHIP_UNIT");
+ my $value = sprintf("0x%x", Targets::PERVASIVE_PARENT_OBUS_OFFSET + $chip_unit);
+ $targetObj->setAttribute($target, "CHIPLET_ID", $value);
+
+ # Set CHIPLET_ID for OBUS_BRICKs
+ foreach my $child (@{ $targetObj->getTargetChildren($target) })
+ {
+ my $type = $targetObj->getType($child);
+ if ($type eq "OBUS_BRICK")
+ {
+ # OBUS_BRICK takes on CHIPLET_ID of OBUS parent
+ $targetObj->setAttribute($child, "CHIPLET_ID", $value);
+ }
+ }
}
+
#--------------------------------------------------
## XBUS
##
@@ -2769,6 +2953,23 @@ sub processI2C
{
$type = "0xFF";
}
+ # TPM types can vary by MODEL number
+ elsif ($type_str eq "NUVOTON_TPM")
+ {
+ # Model values can be found in tpmddif.H and are kept in
+ # sync with TPM_MODEL attribute in attribute_types_hb.xml
+ my $tpm_model = $targetObj->getAttribute($i2c->{DEST_PARENT},"TPM_MODEL");
+ if ($tpm_model eq 1)
+ {
+ $type = $targetObj->getEnumValue("HDAT_I2C_DEVICE_TYPE",$type_str);
+ }
+ if ($tpm_model eq 2)
+ {
+ # @TODO RTC 212201 use proper enum when <system>.xml supports it
+ #$type = $targetObj->getEnumValue("HDAT_I2C_DEVICE_TYPE","TCG_I2C_TPM");
+ $type = 0x15;
+ }
+ }
else
{
$type = $targetObj->getEnumValue("HDAT_I2C_DEVICE_TYPE",$type_str);
@@ -2901,7 +3102,17 @@ sub processI2C
# <vendor>,<device type>,<purpose>,<scope>
if ($type_str eq "NUVOTON_TPM")
{
- $label = "nuvoton,npct601,tpm,host";
+ # Model values can be found in tpmddif.H and are kept in
+ # sync with TPM_MODEL attribute in attribute_types_hb.xml
+ my $tpm_model = $targetObj->getAttribute($i2c->{DEST_PARENT},"TPM_MODEL");
+ if ($tpm_model eq 1)
+ {
+ $label = "nuvoton,npct601,tpm,host";
+ }
+ if ($tpm_model eq 2)
+ {
+ $label = "tcg,tpm_i2c_ptp,tpm,host";
+ }
}
if ($label eq "")
@@ -2938,7 +3149,6 @@ sub processI2C
\@i2cSpeed, \@i2cType, \@i2cPurpose, \@i2cLabel);
}
-
sub setEepromAttributes
{
my $targetObj = shift;
@@ -2953,9 +3163,7 @@ sub setEepromAttributes
# $conn_target->{BUS_NUM}, "I2C_ADDRESS");
my $addr = $targetObj->getAttribute($conn_target->{DEST},"I2C_ADDRESS");
-
- my $path = $targetObj->getAttribute($conn_target->{SOURCE_PARENT},
- "PHYS_PATH");
+ my $path = $targetObj->getAttribute($conn_target->{SOURCE_PARENT}, "PHYS_PATH");
my $mem = $targetObj->getAttribute($conn_target->{DEST_PARENT},
"MEMORY_SIZE_IN_KB");
my $count = 1; # default for VPD SEEPROMs
diff --git a/src/usr/targeting/common/target.C b/src/usr/targeting/common/target.C
index 15fedd006..244d04993 100644
--- a/src/usr/targeting/common/target.C
+++ b/src/usr/targeting/common/target.C
@@ -617,7 +617,9 @@ void Target::getAttrTankTargetPosData(uint16_t & o_pos,
}
else if ((l_element.type == TYPE_PROC) ||
(l_element.type == TYPE_MEMBUF) ||
- (l_element.type == TYPE_DIMM))
+ (l_element.type == TYPE_DIMM) ||
+ (l_element.type == TYPE_OCMB_CHIP) ||
+ (l_element.type == TYPE_PMIC))
{
o_pos = l_element.instance;
}
@@ -635,7 +637,11 @@ void Target::getAttrTankTargetPosData(uint16_t & o_pos,
(l_element.type == TYPE_PPE) ||
(l_element.type == TYPE_PERV) ||
(l_element.type == TYPE_PEC) ||
- (l_element.type == TYPE_PHB))
+ (l_element.type == TYPE_PHB) ||
+ (l_element.type == TYPE_OMI) ||
+ (l_element.type == TYPE_MCC) ||
+ (l_element.type == TYPE_OMIC) ||
+ (l_element.type == TYPE_MEM_PORT))
{
o_unitPos = l_element.instance;
}
@@ -745,6 +751,12 @@ void Target::targAssert(TargAssertReason i_reason,
"TARGETING::Target::setAttr<0x%7x>: trySetAttr returned false",
i_ffdc);
break;
+ case SET_ATTR_FROM_STD_ARR:
+ TARG_ASSERT(false,
+ "TARGETING::Target::setAttrFromStdArr<0x%7x>: setAttrFromStdArr "
+ "returned false",
+ i_ffdc);
+ break;
case GET_ATTR:
TARG_ASSERT(false,
"TARGETING::Target::getAttr<0x%7x>: tryGetAttr returned false",
@@ -755,6 +767,12 @@ void Target::targAssert(TargAssertReason i_reason,
"TARGETING::Target::getAttrAsString<0x%7x>: tryGetAttr returned false",
i_ffdc);
break;
+ case GET_ATTR_AS_STD_ARRAY:
+ TARG_ASSERT(false,
+ "TARGETING::Target::getAttrAsStdArray<0x%7x>: getAttrAsStdArray returned"
+ " false",
+ i_ffdc);
+ break;
case GET_HB_MUTEX_ATTR:
TARG_ASSERT(false,
"TARGETING::Target::_getHbMutexAttr<0x%7x>: _getAttrPtr returned NULL",
diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
index b1ae2e230..e15880f87 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2012,2019 -->
+<!-- Contributors Listed Below - COPYRIGHT 2012,2020 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -187,6 +187,62 @@
</simpleType>
</attribute>
+ <enumerationType>
+ <default>DEFAULT_ALL</default>
+ <description>Enumeration for the various BPM update behaviors</description>
+ <enumerator>
+ <name>DEFAULT_ALL</name>
+ <value>0x0000</value>
+ </enumerator>
+ <enumerator>
+ <name>SKIP_ALL</name>
+ <value>0x1010</value>
+ </enumerator>
+ <enumerator>
+ <name>FORCE_ALL</name>
+ <value>0x1111</value>
+ </enumerator>
+ <enumerator>
+ <name>SKIP_FW</name>
+ <value>0x1000</value>
+ </enumerator>
+ <enumerator>
+ <name>FORCE_FW</name>
+ <value>0x1100</value>
+ </enumerator>
+ <enumerator>
+ <name>SKIP_CONFIG</name>
+ <value>0x0010</value>
+ </enumerator>
+ <enumerator>
+ <name>FORCE_CONFIG</name>
+ <value>0x0011</value>
+ </enumerator>
+ <enumerator>
+ <name>FORCE_CONFIG_SKIP_FW</name>
+ <value>0x1011</value>
+ </enumerator>
+ <enumerator>
+ <name>SKIP_CONFIG_FORCE_FW</name>
+ <value>0x1110</value>
+ </enumerator>
+ <id>BPM_UPDATE_BEHAVIOR</id>
+ </enumerationType>
+
+ <attribute>
+ <id>BPM_UPDATE_OVERRIDE</id>
+ <description>
+ If non-zero then use value to determine which portion of BPM updates to
+ skip/force/default behavior.
+ </description>
+ <simpleType>
+ <uint16_t/>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <no_export/>
+ </attribute>
+
<attribute>
<id>BRAZOS_RX_FIFO_OVERRIDE</id>
<description>
@@ -884,6 +940,54 @@
</attribute>
<attribute>
+ <description>Specifies a target's eeprom content type.</description>
+ <hasStringConversion/>
+ <id>EEPROM_CONTENT_TYPE</id>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <simpleType>
+ <enumeration>
+ <id>EEPROM_CONTENT_TYPE</id>
+ </enumeration>
+ </simpleType>
+ </attribute>
+
+ <enumerationType>
+ <default>RAW</default>
+ <description>Enumeration indicating a target's eeprom
+ content type.
+ RAW - eeprom has no specified layout
+ ISDIMM - uses standard JEDEC layout for DDR memory
+ IBM_FRUVPD - uses ipz converged vpd layout with records/keywords for
+ generic FRUs
+ IBM_MVPD - use ipz converged vpd layout with records/keywords for
+ processor modules
+ DDIMM - uses Differential DIMM layout
+ </description>
+ <enumerator>
+ <name>RAW</name>
+ <value>0</value>
+ </enumerator>
+ <enumerator>
+ <name>ISDIMM</name>
+ <value>1</value>
+ </enumerator>
+ <enumerator>
+ <name>IBM_FRUVPD</name>
+ <value>2</value>
+ </enumerator>
+ <enumerator>
+ <name>IBM_MVPD</name>
+ <value>3</value>
+ </enumerator>
+ <enumerator>
+ <name>DDIMM</name>
+ <value>4</value>
+ </enumerator>
+ <id>EEPROM_CONTENT_TYPE</id>
+ </enumerationType>
+
+ <attribute>
<id>EEPROM_NV_INFO</id>
<description>Information needed to address the NV controller on the NVDIMM</description>
<complexType>
@@ -1179,8 +1283,9 @@
<attribute>
<complexType>
- <description>Structure to define the addressing for an I2C
- slave device.</description>
+ <description>Structure to define the addressing for an attached I2C
+ eeprom device that contains secondary VPD info.
+ </description>
<field>
<default>physical:sys-0</default>
<description>Entity path to the chip that contains the I2C
@@ -1189,49 +1294,49 @@
<type>EntityPath</type>
</field>
<field>
- <default>0x80</default>
+ <default>0xFF</default>
<description>Port from the I2C Master device. This is a 6-bit
value.</description>
<name>port</name>
<type>uint8_t</type>
</field>
<field>
- <default>0x80</default>
+ <default>0xFF</default>
<description>Device address on the I2C bus. This is a 7-bit value,
but then shifted 1 bit left.</description>
<name>devAddr</name>
<type>uint8_t</type>
</field>
<field>
- <default>0x80</default>
+ <default>0xFF</default>
<description>I2C master engine. This is a 2-bit
value.</description>
<name>engine</name>
<type>uint8_t</type>
</field>
<field>
- <default>0x02</default>
+ <default>0xFF</default>
<description>The number of bytes a device requires to set its
internal address/offset.</description>
<name>byteAddrOffset</name>
<type>uint8_t</type>
</field>
<field>
- <default>0x0</default>
+ <default>0xFFFFFFFFFFFFFFFF</default>
<description>The number of kilobytes a device can hold. 'Zero'
value possible for some devices.</description>
<name>maxMemorySizeKB</name>
<type>uint64_t</type>
</field>
<field>
- <default>0x01</default>
+ <default>0xFF</default>
<description>The number of chips making up an eeprom device.
</description>
<name>chipCount</name>
<type>uint8_t</type>
</field>
<field>
- <default>0x0</default>
+ <default>0xFFFFFFFFFFFFFFFF</default>
<description>The maximum number of bytes that can be written to
a device at one time. 'Zero' value means no maximum
value is expected or checked.</description>
@@ -1239,7 +1344,7 @@
<type>uint64_t</type>
</field>
<field>
- <default>0xA</default>
+ <default>0xFFFFFFFFFFFFFFFF</default>
<description>The amount of time in milliseconds a device requires
on the completion of a write command to update its
internal memory.</description>
@@ -1264,6 +1369,12 @@
<name>i2cMuxPath</name>
<type>EntityPath</type>
</field>
+ <field>
+ <default>0xFFFFFFFF</default>
+ <description>Indicates the target's eeprom content type</description>
+ <name>eepromContentType</name>
+ <type>uint32_t</type>
+ </field>
</complexType>
<description>Information needed to address the EERPROM slaves</description>
<id>EEPROM_VPD_BACKUP_INFO</id>
@@ -1273,8 +1384,9 @@
<attribute>
<complexType>
- <description>Structure to define the addressing for an I2C
- slave device.</description>
+ <description>Structure to define the addressing for an attached I2C
+ eeprom device that contains primary VPD info.
+ </description>
<field>
<default>physical:sys-0</default>
<description>Entity path to the chip that contains the I2C
@@ -1283,28 +1395,28 @@
<type>EntityPath</type>
</field>
<field>
- <default>0x80</default>
+ <default>0xFF</default>
<description>Port from the I2C Master device. This is a 6-bit
value.</description>
<name>port</name>
<type>uint8_t</type>
</field>
<field>
- <default>0x80</default>
+ <default>0xFF</default>
<description>Device address on the I2C bus. This is a 7-bit value,
but then shifted 1 bit left.</description>
<name>devAddr</name>
<type>uint8_t</type>
</field>
<field>
- <default>0x80</default>
+ <default>0xFF</default>
<description>I2C master engine. This is a 2-bit
value.</description>
<name>engine</name>
<type>uint8_t</type>
</field>
<field>
- <default>0x02</default>
+ <default>0xFF</default>
<description>
The number of bytes a device requires to set its
internal address/offset. DDR4 DIMMs require a special EEPROM
@@ -1318,21 +1430,21 @@
<type>uint8_t</type>
</field>
<field>
- <default>0x0</default>
+ <default>0xFFFFFFFFFFFFFFFF</default>
<description>The number of kilobytes a device can hold. 'Zero'
value possible for some devices.</description>
<name>maxMemorySizeKB</name>
<type>uint64_t</type>
</field>
<field>
- <default>0x01</default>
+ <default>0xFF</default>
<description>The number of chips making up an eeprom device.
</description>
<name>chipCount</name>
<type>uint8_t</type>
</field>
<field>
- <default>0x0</default>
+ <default>0xFFFFFFFFFFFFFFFF</default>
<description>The maximum number of bytes that can be written to
a device at one time. 'Zero' value means no maximum
value is expected or checked.</description>
@@ -1340,7 +1452,7 @@
<type>uint64_t</type>
</field>
<field>
- <default>0xA</default>
+ <default>0xFFFFFFFFFFFFFFFF</default>
<description>The amount of time in milliseconds a device requires
on the completion of a write command to update its
internal memory.</description>
@@ -1365,6 +1477,12 @@
<name>i2cMuxPath</name>
<type>EntityPath</type>
</field>
+ <field>
+ <default>0xFFFFFFFF</default>
+ <description>Indicates the target's eeprom content type</description>
+ <name>eepromContentType</name>
+ <type>uint32_t</type>
+ </field>
</complexType>
<description>Information needed to address the EEPROM slaves</description>
<id>EEPROM_VPD_PRIMARY_INFO</id>
@@ -1672,6 +1790,36 @@
</attribute>
<attribute>
+ <description>
+ Lab-only trigger to force a factory reset of the NVDIMMs.
+ NOTE: This will erase any saved image and encryption keys.
+ </description>
+ <id>FORCE_NVDIMM_RESET</id>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <simpleType>
+ <uint8_t>
+ <default>0</default>
+ </uint8_t>
+ </simpleType>
+ </attribute>
+
+ <attribute>
+ <id>FORCE_SRAM_MMIO_OVER_I2C</id>
+ <description>
+ Force inband SRAM access to be over I2C instead of MMIO
+ This is a way to get data when the MMIO path is not working
+ (0x00 = use normal path, 0x01 = force i2c path)
+ </description>
+ <simpleType>
+ <uint8_t/>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
<id>FREQ_CORE_CEILING_MHZ</id>
<description>
The maximum core frequency in MHz.
@@ -2208,6 +2356,46 @@
<value>0xB</value>
</enumerator>
<enumerator>
+ <name>THERMAL_SENSOR</name>
+ <value>0x0C</value>
+ </enumerator>
+ <enumerator>
+ <name>SEEPROM_Atmel24c04</name>
+ <value>0x0D</value>
+ </enumerator>
+ <enumerator>
+ <name>SEEPROM_Atmel24c412</name>
+ <value>0x0E</value>
+ </enumerator>
+ <enumerator>
+ <name>SEEPROM_Atmel24c32</name>
+ <value>0x0F</value>
+ </enumerator>
+ <enumerator>
+ <name>SEEPROM_Atmel24c64</name>
+ <value>0x10</value>
+ </enumerator>
+ <enumerator>
+ <name>SEEPROM_Atmel24c16</name>
+ <value>0x11</value>
+ </enumerator>
+ <enumerator>
+ <name>NVDIA_GPU</name>
+ <value>0x12</value>
+ </enumerator>
+ <enumerator>
+ <name>NXP_LPC_Microcontroller_LPC11U35</name>
+ <value>0x13</value>
+ </enumerator>
+ <enumerator>
+ <name>9550</name>
+ <value>0x14</value>
+ </enumerator>
+ <enumerator>
+ <name>TCG_I2C_TPM</name>
+ <value>0x15</value>
+ </enumerator>
+ <enumerator>
<name>UNKNOWN</name>
<value>0xFF</value>
</enumerator>
@@ -2782,6 +2970,81 @@
<writeable/>
</attribute>
+ <attribute>
+ <id>KEY_CLEAR_REQUEST</id>
+ <description>
+ Indicates types of Key Clear Requests are being made
+ </description>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <simpleType>
+ <enumeration>
+ <id>KEY_CLEAR_REQUEST</id>
+ <default>NONE</default>
+ </enumeration>
+ </simpleType>
+ <writeable/>
+ </attribute>
+
+ <enumerationType>
+ <id>KEY_CLEAR_REQUEST</id>
+ <description>
+ Enum indicating the different possible Key Clear Request values
+ </description>
+ <enumerator>
+ <description>
+ (Default) Key clear not requested
+ </description>
+ <name>NONE</name>
+ <value>0x0000</value>
+ </enumerator>
+ <enumerator>
+ <description>
+ Clear/reset all sensitive data controlled by platform firmware
+ from the system
+ </description>
+ <name>ALL</name>
+ <value>0x8000</value>
+ </enumerator>
+ <enumerator>
+ <description>
+ This indicates OPAL to clear the OS platform key
+ </description>
+ <name>OS_PK</name>
+ <value>0x4000</value>
+ </enumerator>
+ <enumerator>
+ <description>
+ This indicates to OPAL/PEF to clear the System Security Officer
+ certificate
+ </description>
+ <name>PEF_SSO</name>
+ <value>0x2000</value>
+ </enumerator>
+ <enumerator>
+ <description>
+ This indicates to PowerVM to clear the system key to the default state
+ </description>
+ <name>POWERVM_SYSKEY</name>
+ <value>0x1000</value>
+ </enumerator>
+ <enumerator>
+ <description>
+ Clear all sensitive data for MFG processing
+ Only valid on development drivers
+ </description>
+ <name>MFG</name>
+ <value>0x0100</value>
+ </enumerator>
+ <enumerator>
+ <description>
+ Reserved bits
+ </description>
+ <name>RESERVED</name>
+ <value>0x00FF</value>
+ </enumerator>
+ </enumerationType>
+
<enumerationType>
<id>KEY_TRANSITION_STATE</id>
<description>
@@ -3842,7 +4105,7 @@
<value>48</value>
</enumerator>
<enumerator>
- <name>EXPLORER</name>
+ <name>OCMB</name>
</enumerator>
<enumerator>
<name>JEDEC</name>
@@ -5033,12 +5296,33 @@
<field>
<bits>1</bits>
<default>0</default>
- <description>NVDIMM controller error detected</description>
- <name>error_detected</name>
+ <description>Is OCC active</description>
+ <name>occ_active</name>
<type>uint8_t</type>
</field>
<field>
- <bits>6</bits>
+ <bits>1</bits>
+ <default>0</default>
+ <description>NVDIMM controller fatal error detected</description>
+ <name>fatal_error_detected</name>
+ <type>uint8_t</type>
+ </field>
+ <field>
+ <bits>1</bits>
+ <default>0</default>
+ <description>NVDIMM controller risky error detected</description>
+ <name>risky_error_detected</name>
+ <type>uint8_t</type>
+ </field>
+ <field>
+ <bits>1</bits>
+ <default>0</default>
+ <description>NVDIMM encryption error detected</description>
+ <name>encryption_error_detected</name>
+ <type>uint8_t</type>
+ </field>
+ <field>
+ <bits>3</bits>
<default>0</default>
<description>Reserved for future use</description>
<name>reserved</name>
@@ -5049,6 +5333,88 @@
</attribute>
<attribute>
+ <id>NVDIMM_AUTO_ARM</id>
+ <description>
+ 0 - Do not automatically arm all NVDIMMS in the system at runtime
+ 1 - Automatically arm all NVDIMMS in the system at runtime
+ </description>
+ <simpleType>
+ <uint8_t>
+ <default>0</default>
+ </uint8_t>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
+ <id>NVDIMM_ENCRYPTION_ENABLE</id>
+ <description>
+ 0 - Encryption is not enabled on all NVDIMMS in the system
+ 1 - Encryption is enabled on all NVDIMMS in the system
+ </description>
+ <simpleType>
+ <uint8_t>
+ <default>0</default>
+ </uint8_t>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
+ <id>NVDIMM_ENCRYPTION_KEYS_ANCHOR</id>
+ <description>
+ NVDIMM Encryption keys
+ Bytes 0..31 Random String (RS)
+ Bytes 32..63 Erase Key (EK)
+ Bytes 64..95 Access Key (AK)
+ Set by HWSV, stored in anchor card
+ Should match NVDIMM_ENCRYPTION_KEYS_FW
+ </description>
+ <simpleType>
+ <array>96</array>
+ <uint8_t>
+ <default>
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ </default>
+ </uint8_t>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
+ <id>NVDIMM_ENCRYPTION_KEYS_FW</id>
+ <description>
+ NVDIMM Encryption keys
+ Bytes 0..31 Random String (RS)
+ Bytes 32..63 Erase Key (EK)
+ Bytes 64..95 Access Key (AK)
+ Set by Hostboot, stored in FSP flash
+ Should match NVDIMM_ENCRYPTION_KEYS_ANCHOR
+ </description>
+ <simpleType>
+ <array>96</array>
+ <uint8_t>
+ <default>
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ </default>
+ </uint8_t>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
<id>NV_OPS_TIMEOUT_MSEC</id>
<description>
NVDIMM timeout value for 6 main operations
@@ -5083,10 +5449,16 @@
NVDIMM status flag. This is used to record the status and
later report to OPAL/PHYP. Possible values:
- 0x08 - contents not preserved (genesis)
- 0x04 - contents preserved
- 0x02 - failed to preserve contents
- 0x01 - unable to preserve future contents
+ 0x01: Unable to preserve future contents
+ 0x02: Failed to preserve contents
+ 0x04: Contents preserved
+ 0x08: Contents not preserved
+ 0x10: Contents are encrypted
+ 0x20: Secure erase verify complete
+ 0x40: Error detected, but save/restore might work
+ 0x80: Reserved
+ 0xFF: Memory is invalid
+ NOTE: set for virtual SCM devices, does not persist across reboot
</description>
<simpleType>
<uint8_t>
@@ -5149,6 +5521,48 @@
<no_export/>
</attribute>
+ <enumerationType>
+ <default>DEFAULT_ALL</default>
+ <description>Enumeration for the various OCMB Firmware update behaviors</description>
+ <enumerator>
+ <!-- Compare actual and desired versions, update if they do not match -->
+ <name>CHECK_VERSIONS</name>
+ <value>0</value>
+ </enumerator>
+ <enumerator>
+ <!-- Force an update regardless of the current version in the hardware -->
+ <name>FORCE_UPDATE</name>
+ <value>1</value>
+ </enumerator>
+ <enumerator>
+ <!-- Do not update the firwmare, do not even check the versions -->
+ <name>PREVENT_UPDATE</name>
+ <value>2</value>
+ </enumerator>
+ <enumerator>
+ <!-- Compare actual and desired versions, but do not do any updates -->
+ <name>CHECK_BUT_NO_UPDATE</name>
+ <value>3</value>
+ </enumerator>
+ <id>OCMB_FW_UPDATE_BEHAVIOR</id>
+ </enumerationType>
+
+ <attribute>
+ <description>
+ Force specific behavior for the OCMB Firmware update function.
+ </description>
+ <id>OCMB_FW_UPDATE_OVERRIDE</id>
+ <!-- @fixme-RTC:244420-Should be volatile-zero -->
+ <persistency>volatile</persistency>
+ <readable/>
+ <simpleType>
+ <uint8_t>
+ <!-- Cannot use enumeration directly due to override issue -->
+ <default>2</default>
+ </uint8_t>
+ </simpleType>
+ </attribute>
+
<attribute>
<description>
Physical entity path an OMI's associated OMIC parent target
@@ -8131,7 +8545,7 @@
</description>
<simpleType>
<uint16_t>
- <default>1</default>
+ <default>0</default>
</uint16_t>
</simpleType>
<persistency>volatile</persistency>
diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
index d5dbb659c..7d9af5904 100755
--- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2012,2019 -->
+<!-- Contributors Listed Below - COPYRIGHT 2012,2020 -->
<!-- [+] Google Inc. -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
@@ -175,6 +175,21 @@
</attribute>
<attribute>
+ <id>DYNAMIC_I2C_DEVICE_ADDRESS</id>
+ <description>
+ This attribute is used when a given target could have different
+ i2c device addresses depending on which manufacture's device we
+ are using.
+ </description>
+ <simpleType>
+ <uint8_t/>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
<id>EARLY_TESTCASES_ISTEP</id>
<description>
Indicates which istep we should execute the CXX testcases after, if
@@ -230,6 +245,62 @@
<readable/>
</attribute>
+ <enumerationType>
+ <description>
+ Enumeration specifying a target's CEC degraded mode domain
+ </description>
+ <default>NO</default>
+ <enumerator>
+ <name>NO</name>
+ <value>0</value>
+ </enumerator>
+ <enumerator>
+ <name>BAR_MISMATCH</name>
+ <value>1</value>
+ </enumerator>
+ <id>FORCE_SBE_UPDATE</id>
+ </enumerationType>
+
+ <attribute>
+ <id>FORCE_SBE_UPDATE</id>
+ <description>
+ Set to non-zero to force a SBE update at various places in the IPL.
+ </description>
+ <simpleType>
+ <enumeration>
+ <id>FORCE_SBE_UPDATE</id>
+ <default>NO</default>
+ </enumeration>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ <hbOnly/>
+ </attribute>
+
+ <attribute>
+ <!-- Need to add this explicitly to handle the Axone case -->
+ <id>FREQ_MCA_MHZ</id>
+ <description>
+ The frequency of the memory controller channel. In synchronous mode,
+ this is equivalent to ATTR_FREQ_PB_MHZ. This may be independently set
+ per pair of memory channels if operating in asynchronous mode,
+ but this configuration is not anticipated. This clock drives the MCU queues,
+ and all the associated logic that drives the inputs to the DMI and reads
+ its outputs
+ </description>
+ <simpleType>
+ <uint32_t/>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <writeable/>
+ <hwpfToHbAttrMap>
+ <id>ATTR_FREQ_MCA_MHZ</id>
+ <macro>DIRECT</macro>
+ </hwpfToHbAttrMap>
+ </attribute>
+
<attribute>
<id>FSI_MASTER_MUTEX</id>
<description>Mutex for FSI Master Operations</description>
@@ -254,6 +325,78 @@
<hbOnly/>
</attribute>
+ <attribute>
+ <id>GPIO_INFO_PHYS_PRES</id>
+ <description>Information needed to address GPIO device that corresponds
+ to the Physical Presence Detect circuit</description>
+ <complexType>
+ <description>Structure to define the addessing for an I2C
+ slave device.</description>
+ <field>
+ <name>i2cMasterPath</name>
+ <description>Entity path to the chip that contains the I2C
+ master</description>
+ <type>EntityPath</type>
+ <default>physical:sys-0/node-0/proc-0</default>
+ </field>
+ <field>
+ <name>port</name>
+ <description>Port from the I2C Master device. This is a 6-bit
+ value.</description>
+ <type>uint8_t</type>
+ <default>0</default>
+ </field>
+ <field>
+ <name>devAddr</name>
+ <description>Device address on the I2C bus. This is a 7-bit value,
+ but then shifted 1 bit left.</description>
+ <type>uint8_t</type>
+ <default>0xC0</default>
+ </field>
+ <field>
+ <name>engine</name>
+ <description>I2C master engine. This is a 2-bit
+ value.</description>
+ <type>uint8_t</type>
+ <default>2</default>
+ </field>
+ <field>
+ <name>windowOpenPin</name>
+ <description>Logical GPIO pin number used to open or close the physcial
+ presence window</description>
+ <type>uint8_t</type>
+ <default>0</default>
+ </field>
+ <field>
+ <name>physicalPresencePin</name>
+ <description>Logical GPIO pin number used to determine if physical
+ presence was asserted</description>
+ <type>uint8_t</type>
+ <default>1</default>
+ </field>
+ <!-- i2c Mux Bus Selector Definition -->
+ <field>
+ <default>0xFF</default>
+ <description>Determines which of the N selectable buses the mux
+ will connect to. OxFF indicates no mux present
+ or N/A.</description>
+ <name>i2cMuxBusSelector</name>
+ <type>uint8_t</type>
+ </field>
+ <!-- i2c Mux Path Definition -->
+ <field>
+ <!-- NOTE: physical:sys-0 implies that there is no mux in
+ the bus path for this part. -->
+ <default>physical:sys-0</default>
+ <description>Entity path to the I2C mux for this device.</description>
+ <name>i2cMuxPath</name>
+ <type>EntityPath</type>
+ </field>
+ </complexType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ </attribute>
+
<!-- TODO RTC 122856 When support for HB only volatile attributes with non-zero
default is implemented, update default value to match the description,
Until that happens, code must set the appropriate default if needed. -->
@@ -323,6 +466,18 @@
</enumerator>
</enumerationType>
+ <attribute>
+ <id>HB_MUTEX_SERIALIZE_TEST_LOCK</id>
+ <description>Hostboot mutex for serializing certain tests</description>
+ <simpleType>
+ <hbmutex/>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ <hbOnly/>
+ </attribute>
+
<!-- For POD Testing -->
<attribute>
<id>HB_MUTEX_TEST_LOCK</id>
@@ -932,6 +1087,40 @@
</attribute>
<attribute>
+ <id>NVDIMM_READING_PAGE4</id>
+ <description>
+ 0 - Not reading page4 registers
+ 1 - Reading of page4 registers in progress
+ </description>
+ <simpleType>
+ <uint8_t>
+ <default>0</default>
+ </uint8_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ <hbOnly/>
+ </attribute>
+
+ <attribute>
+ <id>NVDIMM_READING_VENDOR_LOG</id>
+ <description>
+ 0 - Not reading vendor log
+ 1 - Reading of vendor log in progress
+ </description>
+ <simpleType>
+ <uint8_t>
+ <default>0</default>
+ </uint8_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ <hbOnly/>
+ </attribute>
+
+ <attribute>
<id>OCC_COMMON_AREA_PHYS_ADDR</id>
<description>
Physical address where OCC Common Area is placed in mainstore.
@@ -946,6 +1135,20 @@
</attribute>
<attribute>
+ <id>OCMB_COUNTER_HB</id>
+ <description>
+ Tracks the sequence id for OCMB command transactions.
+ The platform is expected to guarantee a unique value on each read.
+ </description>
+ <simpleType>
+ <uint32_t/>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
<description>
While in Secureboot, this value is set to 1 the first time attribute
override is attempted and error logged.
@@ -972,7 +1175,7 @@
<description>The part number for a particular FRU target</description>
<simpleType>
<uint8_t/>
- <array>20</array>
+ <array>48</array>
</simpleType>
<persistency>volatile-zeroed</persistency>
<readable/>
@@ -1047,6 +1250,72 @@
</attribute>
<attribute>
+ <description>Designates if the Physical Presence Window was Asserted:
+ 0 - Physiscal Presence was NOT Asserted
+ 1 - Physical Presence was Asserted
+ </description>
+ <id>PHYS_PRES_ASSERTED</id>
+ <simpleType>
+ <uint8_t>
+ <default>0x0</default>
+ </uint8_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
+ <description>Designates if the assertion of Physical Presence should
+ be faked:
+ 0 - Do NOT Fake Physical Presence
+ 1 - Fake Physical Presence
+ </description>
+ <id>PHYS_PRES_FAKE_ASSERT</id>
+ <simpleType>
+ <uint8_t>
+ <default>0x0</default>
+ </uint8_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
+ <description>Designates if there is a request to open the Physical Presence
+ Window:
+ 0 - No Request to Open Window (ie, do NOT open window)
+ 1 - Request to Open Window
+ </description>
+ <id>PHYS_PRES_REQUEST_OPEN_WINDOW</id>
+ <simpleType>
+ <uint8_t>
+ <default>0x0</default>
+ </uint8_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
+ <id>SBE_ARCH_DUMP_ADDR</id>
+ <description>
+ Physical address where SBE Architectued Dump Area is located (per
+ Hostboot Instance). Set in istep 21 it is only used during
+ MPIPLs to retrieve the the architected processor state (SPR/GPR)
+ </description>
+ <simpleType>
+ <uint64_t/>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ <hbOnly/>
+ </attribute>
+
+ <attribute>
<id>SBE_COMM_ADDR</id>
<description>
Virtual address where SBE Communications are placed in mainstore.
diff --git a/src/usr/targeting/common/xmltohb/hb_customized_attrs.xml b/src/usr/targeting/common/xmltohb/hb_customized_attrs.xml
index 25daef3dc..6033800d3 100644
--- a/src/usr/targeting/common/xmltohb/hb_customized_attrs.xml
+++ b/src/usr/targeting/common/xmltohb/hb_customized_attrs.xml
@@ -418,6 +418,7 @@
<no_export/>
</attribute>
+ <!-- Firmware boots rely on the hypervisor/os to enable the NPUs -->
<attribute>
<id>ATTR_PROC_NPU_PHY0_BAR_ENABLE</id>
<default>0</default>
@@ -455,6 +456,74 @@
</attribute>
<attribute>
+ <id>ATTR_PROC_NPU_MMIO_BAR_ENABLE</id>
+ <default>0</default>
+ <no_export/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_PROC_NPU0_MMIO_BAR_ENABLE</id>
+ <default>0</default>
+ <no_export/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_PROC_NPU1_MMIO_BAR_ENABLE</id>
+ <default>0</default>
+ <no_export/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_PROC_NPU2_MMIO_BAR_ENABLE</id>
+ <default>0</default>
+ <no_export/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_PROC_NPU_MMIO_BAR_BASE_ADDR_OFFSET</id>
+ <default>0x0000030200000000</default>
+ <no_export/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_PROC_NPU0_MMIO_BAR_BASE_ADDR_OFFSET</id>
+ <default>0x0</default>
+ <no_export/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_PROC_NPU1_MMIO_BAR_BASE_ADDR_OFFSET</id>
+ <default>0x0</default>
+ <no_export/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_PROC_NPU2_MMIO_BAR_BASE_ADDR_OFFSET</id>
+ <default>0x0</default>
+ <no_export/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_PROC_NPU0_PRI_CONFIG</id>
+ <default>0x0,0x0,0x0,0x0</default>
+ <no_export/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_PROC_NPU1_PRI_CONFIG</id>
+ <default>0x0,0x0,0x0,0x0</default>
+ <no_export/>
+ </attribute>
+
+ <attribute>
+ <id>ATTR_PROC_NPU2_PRI_CONFIG</id>
+ <default>0x0,0x0,0x0,0x0</default>
+ <no_export/>
+ </attribute>
+
+ <!-- end NPU config -->
+
+ <attribute>
<id>ATTR_PROC_NX_RNG_BAR_ENABLE</id>
<default>0</default>
<no_export/>
@@ -763,6 +832,34 @@
<writeable/>
<persistency>volatile-zeroed</persistency>
</attribute>
+
+ <!-- pSeries always runs in FULL_DIMM mode -->
+ <attribute>
+ <id>ATTR_MSS_OCMB_HALF_DIMM_MODE</id>
+ <no_export/>
+ <default>FULL_DIMM</default>
+ </attribute>
+
+ <!-- OCMB Endianess attributes -->
+ <attribute>
+ <id>ATTR_MSS_OCMB_EXP_STRUCT_ENDIAN</id>
+ <default>0x1</default>
+ <no_export/>
+ </attribute>
+ <attribute>
+ <id>ATTR_MSS_OCMB_EXP_STRUCT_MMIO_ENDIAN_CTRL</id>
+ <default>0x1</default>
+ <no_export/>
+ </attribute>
+ <attribute>
+ <id>ATTR_MSS_OCMB_EXP_STRUCT_MMIO_WORD_SWAP</id>
+ <default>NO_SWAP</default>
+ <no_export/>
+ </attribute>
+ <attribute>
+ <id>ATTR_MSS_OCMB_EXP_OMI_CFG_ENDIAN_CTRL</id>
+ <no_export/>
+ </attribute>
<!-- =====================================================================
End of customizations definitions
================================================================= -->
diff --git a/src/usr/targeting/common/xmltohb/simics_AXONE.system.xml b/src/usr/targeting/common/xmltohb/simics_AXONE.system.xml
index 157582ce6..df431c210 100644
--- a/src/usr/targeting/common/xmltohb/simics_AXONE.system.xml
+++ b/src/usr/targeting/common/xmltohb/simics_AXONE.system.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2018,2019 -->
+<!-- Contributors Listed Below - COPYRIGHT 2018,2020 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -38,12 +38,12 @@
* Each Axone has has 2 MC units
* Each MC unit has 2 MI units (a total of 4 per chip)
* Each MI unit has 2 MCC units (a total of 8 per chip)
- * Each MCC unit has 4 OMI Units (A total of 16 per chip)
+ * Each MCC unit has 2 OMI Units (A total of 16 per chip)
* OMI Units are special as they have two parents (MI + OMIC (more description below))
* Each OMI unit connects to 1 OCMB chip
* Each OCMB unit contains 1 MEM_PORT unit
* Each MEM_PORT unit connects to 2 DIMMS (Only 1 dimm per mem_port in this XML)
- * Each OCMB chip and its DIMMS are powered by 2 PMIC units
+ * Each OCMB chip and its DIMMS are powered by up to 4 PMIC units
* Each MC unit has 3 OMIC units (a total of 12 per chip)
* Each OMIC unit contains 2 or 3 OMI Units (OMIC0/1/3/4 contain 3 and OMIC2/5 contain 2 for a total of 16 per chip)
* OMI Units are special as they have two parents (OMIC + MCC (described above))
@@ -53,13 +53,19 @@
* PEC 2 has 3 PHBs
* Each Axone has 1 XBUS chiplet (1 XBUS Chiplet translates to multiple xbus units)
* Each Axone has 4 OBUS (OB0 to OB3)
- * Each OBUS has 3 OBUS_BRICK
+ * Each OBUS has up to 2 OBUS_BRICKs
+ * OBUS0 has 2 OBUS_BRICKs
+ * OBUS1 has 1 OBUS_BRICK
+ * OBUS2 has 1 OBUS_BRICK
+ * OBUS3 has 2 OBUS_BRICKs
+ * Each Axone has 3 NPU units, each associated with 2 OBUS_BRICKs
+ * NPU0 is associated with OBUS0, used for NVLINK ( 4 x4 links).
+ * NPU1 is associated with OBUS1/2, used for OpenCAPI ( 1 x8 link).
+ * NPU2 is associated with OBUS3, used for NVLINK ( 4 x4 links).
* Each Axone has 21 PPE units (including the SBE):
* 1 SBE, 1 Powerbus/Fabric PPE, 4 GPEs, 12 CMEs, and 3 IO PPEs.
* Each chiplet existing in an Axone has 1 equivalent PERV unit
- * Each Axone has 2 CAPP units ##TBD## has 2 sys0node0proc0capp0 units
- * with same target ID...input MRW has capp0 and capp1...something
- * wrong in the processMrw.pl (same observed for Witherspoon)
+ * Each Axone has 1 CAPP unit
* Each Axone has 1 OCC unit
- p9Proc0(axone chip)
@@ -195,7 +201,7 @@
</attribute>
<attribute>
<id>ASYNC_NEST_FREQ_MHZ</id>
- <default>0xFFFF</default>
+ <default>2000</default>
</attribute>
<attribute>
<id>HB_SETTINGS</id>
@@ -538,7 +544,7 @@
<default>400,400,0,0,0,0,0,0,0,0,0,0,0,
400,400,400,400,0,0,0,0,0,0,0,0,0,
400,400,0,0,0,0,0,0,0,0,0,0,0,
- 400,400,400,0,0,0,0,0,0,0,0,0,0</default>
+ 400,400,400,400,400,400,400,400,400,0,0,0,0</default>
</attribute>
<attribute>
<id>MRU_ID</id>
@@ -631,8 +637,243 @@
<id>VPD_REC_NUM</id>
<default>0</default>
</attribute>
+ <attribute>
+ <id>FREQ_OMI_MHZ</id>
+ <default>25600</default>
+ </attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1</id>
+ <type>chip-processor-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1</default>
+ </attribute>
+ <attribute>
+ <id>ALTFSI_MASTER_CHIP</id>
+ <default>physical:sys-0</default>
+ </attribute>
+ <attribute>
+ <id>ALTFSI_MASTER_PORT</id>
+ <default>0x1</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>CHIP</default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_SBE_BACKUP_INFO</id>
+ <default>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x04</value></field>
+ <field><id>devAddr</id><value>0xA8</value></field>
+ <field><id>engine</id><value>1</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x100</value></field>
+ <field><id>port</id><value>3</value></field>
+ <field><id>writeCycleTime</id><value>0x0A</value></field>
+ <field><id>writePageSize</id><value>0x80</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_SBE_PRIMARY_INFO</id>
+ <default>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x04</value></field>
+ <field><id>devAddr</id><value>0xA8</value></field>
+ <field><id>engine</id><value>1</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x100</value></field>
+ <field><id>port</id><value>1</value></field>
+ <field><id>writeCycleTime</id><value>0x0A</value></field>
+ <field><id>writePageSize</id><value>0x80</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_BACKUP_INFO</id>
+ <default>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <!-- Note: that there is actually two 64KB chips associated with the MVPD SEEPROM
+ but Hostboot should never access the second chip -->
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>engine</id><value>1</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x40</value></field>
+ <field><id>port</id><value>2</value></field>
+ <field><id>writeCycleTime</id><value>0x0A</value></field>
+ <field><id>writePageSize</id><value>0x80</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <!-- Note: that there is actually two 64KB chips associated with the MVPD SEEPROM
+ but Hostboot should never access the second chip -->
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>engine</id><value>1</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x40</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>writeCycleTime</id><value>0x0A</value></field>
+ <field><id>writePageSize</id><value>0x80</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>FABRIC_CHIP_ID</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>FABRIC_GROUP_ID</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu:k0:n0:s0:p01</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>FSI_MASTER_CHIP</id>
+ <default>physical:sys-0/node-0/proc-0</default>
+ </attribute>
+ <attribute>
+ <id>FSI_MASTER_PORT</id>
+ <default>0x1</default>
+ </attribute>
+ <attribute>
+ <id>FSI_MASTER_TYPE</id>
+ <default>MFSI</default>
+ </attribute>
+ <attribute>
+ <id>FSI_OPTION_FLAGS</id>
+ <default>
+ <field><id>flipPort</id><value>0</value></field>
+ <field><id>reserved</id><value>0</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>FSI_SLAVE_CASCADE</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FSP_BASE_ADDR</id>
+ <default>0x0006070100000000</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00050001</default>
+ </attribute>
+ <attribute>
+ <id>I2C_BUS_SPEED_ARRAY</id>
+ <default>400,400,0,0,0,0,0,0,0,0,0,0,0,
+ 400,400,400,400,0,0,0,0,0,0,0,0,0,
+ 400,400,0,0,0,0,0,0,0,0,0,0,0,
+ 400,400,400,400,400,400,400,400,400,0,0,0,0</default>
+ </attribute>
+ <attribute>
+ <id>MRU_ID</id>
+ <default>0x00010000</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1</default>
+ </attribute>
+ <attribute>
+ <id>POSITION</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>PROC_EFF_FABRIC_CHIP_ID</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>PROC_EFF_FABRIC_GROUP_ID</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>PROC_MASTER_TYPE</id>
+ <default>NOT_MASTER</default>
+ </attribute>
+ <attribute>
+ <id>PROC_R_DISTLOSS_VCS_UOHM</id>
+ <default>0x640</default>
+ </attribute>
+ <attribute>
+ <id>PROC_R_DISTLOSS_VDD_UOHM</id>
+ <default>0xAA</default>
+ </attribute>
+ <attribute>
+ <id>PROC_R_DISTLOSS_VDN_UOHM</id>
+ <default>0xAA</default>
+ </attribute>
+ <attribute>
+ <id>PROC_R_LOADLINE_VCS_UOHM</id>
+ <default>0x1F4</default>
+ </attribute>
+ <attribute>
+ <id>PROC_R_LOADLINE_VDD_UOHM</id>
+ <default>0x1F4</default>
+ </attribute>
+ <attribute>
+ <id>PROC_R_LOADLINE_VDN_UOHM</id>
+ <default>0x1F4</default>
+ </attribute>
+ <attribute>
+ <id>PROC_VRM_VOFFSET_VCS_UV</id>
+ <default>0x30D4</default>
+ </attribute>
+ <attribute>
+ <id>PROC_VRM_VOFFSET_VDD_UV</id>
+ <default>0x30D4</default>
+ </attribute>
+ <attribute>
+ <id>PROC_VRM_VOFFSET_VDN_UV</id>
+ <default>0x30D4</default>
+ </attribute>
+ <attribute>
+ <id>SCOM_SWITCHES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>useFsiScom</id><value>0</value></field>
+ <field><id>useInbandScom</id><value>0</value></field>
+ <field><id>useSbeScom</id><value>1</value></field>
+ <field><id>useXscom</id><value>0</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PROC</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>FREQ_OMI_MHZ</id>
+ <default>25600</default>
+ </attribute>
+</targetInstance>
+
+
<!-- ===================================================================== -->
<!-- EQ Units -->
<!-- ===================================================================== -->
@@ -1008,6 +1249,228 @@
</attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1eq0</id>
+ <type>unit-eq-power9</type>
+ <attribute><id>HUID</id><default>0x00230006</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.eq:k0:n0:s0:p01:c0</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-16</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x10</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq1</id>
+ <type>unit-eq-power9</type>
+ <attribute><id>HUID</id><default>0x00230007</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.eq:k0:n0:s0:p01:c1</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-17</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x11</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq2</id>
+ <type>unit-eq-power9</type>
+ <attribute><id>HUID</id><default>0x00230008</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.eq:k0:n0:s0:p01:c2</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-2</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-2</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>8</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>8</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-18</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x12</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq3</id>
+ <type>unit-eq-power9</type>
+ <attribute><id>HUID</id><default>0x00230009</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.eq:k0:n0:s0:p01:c3</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-3</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-3</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>9</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>9</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-19</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x13</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq4</id>
+ <type>unit-eq-power9</type>
+ <attribute><id>HUID</id><default>0x0023000A</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.eq:k0:n0:s0:p01:c4</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-4</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-4</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-20</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x14</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq5</id>
+ <type>unit-eq-power9</type>
+ <attribute><id>HUID</id><default>0x0023000B</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.eq:k0:n0:s0:p01:c5</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-5</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-5</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-21</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x15</default>
+ </attribute>
+</targetInstance>
+
<!-- ===================================================================== -->
<!-- EX Units -->
<!-- ===================================================================== -->
@@ -1755,6 +2218,402 @@
</attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1eq0ex0</id>
+ <type>unit-ex-power9</type>
+ <attribute><id>HUID</id><default>0x0006000C</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.ex:k0:n0:s0:p01:c0</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-0/ex-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-0/ex-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>12</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>12</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x10</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq0ex1</id>
+ <type>unit-ex-power9</type>
+ <attribute><id>HUID</id><default>0x0006000D</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.ex:k0:n0:s0:p01:c1</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-0/ex-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-0/ex-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>13</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>13</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x10</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq1ex0</id>
+ <type>unit-ex-power9</type>
+ <attribute><id>HUID</id><default>0x0006000E</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.ex:k0:n0:s0:p01:c2</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-1/ex-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-1/ex-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>14</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>14</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x11</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq1ex1</id>
+ <type>unit-ex-power9</type>
+ <attribute><id>HUID</id><default>0x0006000F</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.ex:k0:n0:s0:p01:c3</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-1/ex-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-1/ex-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>15</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>15</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x11</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq2ex0</id>
+ <type>unit-ex-power9</type>
+ <attribute><id>HUID</id><default>0x00060010</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.ex:k0:n0:s0:p01:c4</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-2/ex-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-2/ex-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x12</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq2ex1</id>
+ <type>unit-ex-power9</type>
+ <attribute><id>HUID</id><default>0x00060011</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.ex:k0:n0:s0:p01:c5</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-2/ex-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-2/ex-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>17</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>17</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x12</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq3ex0</id>
+ <type>unit-ex-power9</type>
+ <attribute><id>HUID</id><default>0x00060012</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.ex:k0:n0:s0:p01:c6</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-3/ex-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-3/ex-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x13</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq3ex1</id>
+ <type>unit-ex-power9</type>
+ <attribute><id>HUID</id><default>0x00060013</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.ex:k0:n0:s0:p01:c7</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-3/ex-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-3/ex-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x13</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq4ex0</id>
+ <type>unit-ex-power9</type>
+ <attribute><id>HUID</id><default>0x00060014</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.ex:k0:n0:s0:p01:c8</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-4/ex-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-4/ex-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>8</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x14</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq4ex1</id>
+ <type>unit-ex-power9</type>
+ <attribute><id>HUID</id><default>0x00060015</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.ex:k0:n0:s0:p01:c9</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-4/ex-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-4/ex-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>9</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x14</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq5ex0</id>
+ <type>unit-ex-power9</type>
+ <attribute><id>HUID</id><default>0x00060016</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.ex:k0:n0:s0:p01:c10</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-5/ex-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-5/ex-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x15</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq5ex1</id>
+ <type>unit-ex-power9</type>
+ <attribute><id>HUID</id><default>0x00060017</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.ex:k0:n0:s0:p01:c11</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-5/ex-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-5/ex-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x15</default>
+ </attribute>
+</targetInstance>
+
<!-- ===================================================================== -->
<!-- Core Units -->
<!-- ===================================================================== -->
@@ -3126,9 +3985,898 @@
</attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1eq0ex0core0</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x00070018</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c0</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-0/ex-0/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-0/ex-0/core-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>24</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>24</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-32</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x20</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq0ex0core1</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x00070019</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c1</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-0/ex-0/core-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-0/ex-0/core-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>25</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>25</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-33</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x21</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq0ex1core0</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x0007001A</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c2</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-0/ex-1/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-0/ex-1/core-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>26</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>26</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-34</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x22</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq0ex1core1</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x0007001B</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c3</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-0/ex-1/core-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-0/ex-1/core-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>27</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>27</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-35</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x23</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq1ex0core0</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x0007001C</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c4</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-1/ex-0/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-1/ex-0/core-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>28</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>28</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-36</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x24</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq1ex0core1</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x0007001D</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c5</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-1/ex-0/core-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-1/ex-0/core-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>29</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>29</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-37</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x25</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq1ex1core0</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x0007001E</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c6</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-1/ex-1/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-1/ex-1/core-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>30</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>30</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-38</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x26</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq1ex1core1</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x0007001F</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c7</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-1/ex-1/core-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-1/ex-1/core-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>31</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>31</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-39</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x27</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq2ex0core0</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x00070020</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c8</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-2/ex-0/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-2/ex-0/core-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>32</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>32</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-40</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>8</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x28</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq2ex0core1</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x00070021</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c9</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-2/ex-0/core-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-2/ex-0/core-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>33</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>33</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-41</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>9</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x29</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq2ex1core0</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x00070022</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c10</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-2/ex-1/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-2/ex-1/core-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>34</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>34</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-42</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x2A</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq2ex1core1</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x00070023</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c11</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-2/ex-1/core-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-2/ex-1/core-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>35</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>35</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-43</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x2B</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq3ex0core0</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x00070024</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c12</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-3/ex-0/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-3/ex-0/core-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>36</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>36</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-44</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>12</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x2C</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq3ex0core1</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x00070025</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c13</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-3/ex-0/core-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-3/ex-0/core-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>37</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>37</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-45</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>13</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x2D</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq3ex1core0</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x00070026</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c14</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-3/ex-1/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-3/ex-1/core-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>38</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>38</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-46</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>14</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x2E</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq3ex1core1</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x00070027</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c15</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-3/ex-1/core-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-3/ex-1/core-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>39</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>39</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-47</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>15</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x2F</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq4ex0core0</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x00070028</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c16</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-4/ex-0/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-4/ex-0/core-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>40</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>40</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-48</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x30</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq4ex0core1</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x00070029</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c17</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-4/ex-0/core-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-4/ex-0/core-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>41</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>41</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-49</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>17</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x31</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq4ex1core0</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x0007002A</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c18</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-4/ex-1/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-4/ex-1/core-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>42</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>42</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-50</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x32</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq4ex1core1</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x0007002B</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c19</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-4/ex-1/core-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-4/ex-1/core-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>43</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>43</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-51</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x33</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq5ex0core0</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x0007002C</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c20</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-5/ex-0/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-5/ex-0/core-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>44</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>44</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-52</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x34</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq5ex0core1</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x0007002D</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c21</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-5/ex-0/core-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-5/ex-0/core-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>45</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>45</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-53</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x35</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq5ex1core0</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x0007002E</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c22</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-5/ex-1/core-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-5/ex-1/core-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>46</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>46</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-54</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x36</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1eq5ex1core1</id>
+ <type>unit-core-power9</type>
+ <attribute><id>HUID</id><default>0x0007002F</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.core:k0:n0:s0:p01:c23</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/eq-5/ex-1/core-1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/eq-5/ex-1/core-1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>47</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>47</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-55</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x37</default>
+ </attribute>
+</targetInstance>
+
<!-- ===================================================================== -->
<!-- OBUS Units -->
<!-- ===================================================================== -->
+
<targetInstance>
<id>sys0node0proc0obus0</id>
<type>unit-obus-axone</type>
@@ -3393,6 +5141,270 @@
</attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1obus0</id>
+ <type>unit-obus-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/obus-0</default>
+ </attribute>
+ <attribute>
+ <id>PEER_PATH</id>
+ <default>physical:na</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x09</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.obus:k0:n0:s0:p01:c0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00280004</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-9</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/obus-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OBUS</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1obus1</id>
+ <type>unit-obus-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/obus-1</default>
+ </attribute>
+ <attribute>
+ <id>PEER_PATH</id>
+ <default>physical:na</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x0A</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.obus:k0:n0:s0:p01:c1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00280005</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-10</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/obus-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OBUS</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1obus2</id>
+ <type>unit-obus-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/obus-2</default>
+ </attribute>
+ <attribute>
+ <id>PEER_PATH</id>
+ <default>physical:na</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x0B</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.obus:k0:n0:s0:p01:c2</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00280006</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-11</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/obus-2</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OBUS</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1obus3</id>
+ <type>unit-obus-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/obus-3</default>
+ </attribute>
+ <attribute>
+ <id>PEER_PATH</id>
+ <default>physical:na</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x0C</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.obus:k0:n0:s0:p01:c3</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00280007</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-12</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/obus-3</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OBUS</default>
+ </attribute>
+</targetInstance>
+
<!-- ===================================================================== -->
<!-- OBUS_BRICK Units -->
<!-- ===================================================================== -->
@@ -3487,11 +5499,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0proc0obus0obus_brick2</id>
+ <id>sys0node0proc0obus1obus_brick0</id>
<type>unit-obus-brick-axone</type>
<attribute>
<id>AFFINITY_PATH</id>
- <default>affinity:sys-0/node-0/proc-0/obus-0/obus_brick-2</default>
+ <default>affinity:sys-0/node-0/proc-0/obus-1/obus_brick-0</default>
</attribute>
<attribute>
<id>CHIP_UNIT</id>
@@ -3499,7 +5511,7 @@
</attribute>
<attribute>
<id>CHIPLET_ID</id>
- <default>0x09</default>
+ <default>0x0A</default>
</attribute>
<attribute>
<id>FAPI_NAME</id>
@@ -3519,24 +5531,24 @@
</attribute>
<attribute>
<id>PARENT_PERVASIVE</id>
- <default>physical:sys-0/node-0/proc-0/perv-9</default>
+ <default>physical:sys-0/node-0/proc-0/perv-10</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/obus-0/obus_brick-2</default>
+ <default>physical:sys-0/node-0/proc-0/obus-1/obus_brick-0</default>
</attribute>
<attribute>
<id>REL_POS</id>
- <default>2</default>
+ <default>0</default>
</attribute>
</targetInstance>
<targetInstance>
- <id>sys0node0proc0obus1obus_brick0</id>
+ <id>sys0node0proc0obus2obus_brick0</id>
<type>unit-obus-brick-axone</type>
<attribute>
<id>AFFINITY_PATH</id>
- <default>affinity:sys-0/node-0/proc-0/obus-1/obus_brick-0</default>
+ <default>affinity:sys-0/node-0/proc-0/obus-2/obus_brick-0</default>
</attribute>
<attribute>
<id>CHIP_UNIT</id>
@@ -3544,15 +5556,15 @@
</attribute>
<attribute>
<id>CHIPLET_ID</id>
- <default>0x0A</default>
+ <default>0x0B</default>
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pu.obus_brick:k0:n0:s0:p00:c3</default>
+ <default>pu.obus_brick:k0:n0:s0:p00:c4</default>
</attribute>
<attribute>
<id>HUID</id>
- <default>0x00420003</default>
+ <default>0x00420004</default>
</attribute>
<attribute>
<id>OBUS_SLOT_INDEX</id>
@@ -3564,11 +5576,11 @@
</attribute>
<attribute>
<id>PARENT_PERVASIVE</id>
- <default>physical:sys-0/node-0/proc-0/perv-10</default>
+ <default>physical:sys-0/node-0/proc-0/perv-11</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/obus-1/obus_brick-0</default>
+ <default>physical:sys-0/node-0/proc-0/obus-2/obus_brick-0</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -3577,11 +5589,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0proc0obus1obus_brick1</id>
+ <id>sys0node0proc0obus3obus_brick0</id>
<type>unit-obus-brick-axone</type>
<attribute>
<id>AFFINITY_PATH</id>
- <default>affinity:sys-0/node-0/proc-0/obus-1/obus_brick-1</default>
+ <default>affinity:sys-0/node-0/proc-0/obus-3/obus_brick-0</default>
</attribute>
<attribute>
<id>CHIP_UNIT</id>
@@ -3589,15 +5601,15 @@
</attribute>
<attribute>
<id>CHIPLET_ID</id>
- <default>0x0A</default>
+ <default>0x0C</default>
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pu.obus_brick:k0:n0:s0:p00:c4</default>
+ <default>pu.obus_brick:k0:n0:s0:p00:c6</default>
</attribute>
<attribute>
<id>HUID</id>
- <default>0x00420004</default>
+ <default>0x00420006</default>
</attribute>
<attribute>
<id>OBUS_SLOT_INDEX</id>
@@ -3609,24 +5621,24 @@
</attribute>
<attribute>
<id>PARENT_PERVASIVE</id>
- <default>physical:sys-0/node-0/proc-0/perv-10</default>
+ <default>physical:sys-0/node-0/proc-0/perv-12</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/obus-1/obus_brick-1</default>
+ <default>physical:sys-0/node-0/proc-0/obus-3/obus_brick-0</default>
</attribute>
<attribute>
<id>REL_POS</id>
- <default>1</default>
+ <default>0</default>
</attribute>
</targetInstance>
<targetInstance>
- <id>sys0node0proc0obus1obus_brick2</id>
+ <id>sys0node0proc0obus3obus_brick1</id>
<type>unit-obus-brick-axone</type>
<attribute>
<id>AFFINITY_PATH</id>
- <default>affinity:sys-0/node-0/proc-0/obus-1/obus_brick-2</default>
+ <default>affinity:sys-0/node-0/proc-0/obus-3/obus_brick-1</default>
</attribute>
<attribute>
<id>CHIP_UNIT</id>
@@ -3634,7 +5646,7 @@
</attribute>
<attribute>
<id>CHIPLET_ID</id>
- <default>0x0A</default>
+ <default>0x0C</default>
</attribute>
<attribute>
<id>FAPI_NAME</id>
@@ -3642,7 +5654,7 @@
</attribute>
<attribute>
<id>HUID</id>
- <default>0x00420005</default>
+ <default>0x00420007</default>
</attribute>
<attribute>
<id>OBUS_SLOT_INDEX</id>
@@ -3654,40 +5666,40 @@
</attribute>
<attribute>
<id>PARENT_PERVASIVE</id>
- <default>physical:sys-0/node-0/proc-0/perv-10</default>
+ <default>physical:sys-0/node-0/proc-0/perv-12</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/obus-1/obus_brick-2</default>
+ <default>physical:sys-0/node-0/proc-0/obus-3/obus_brick-1</default>
</attribute>
<attribute>
<id>REL_POS</id>
- <default>3</default>
+ <default>1</default>
</attribute>
</targetInstance>
<targetInstance>
- <id>sys0node0proc0obus2obus_brick0</id>
+ <id>sys0node0proc1obus0obus_brick0</id>
<type>unit-obus-brick-axone</type>
<attribute>
<id>AFFINITY_PATH</id>
- <default>affinity:sys-0/node-0/proc-0/obus-2/obus_brick-0</default>
+ <default>affinity:sys-0/node-0/proc-1/obus-0/obus_brick-0</default>
</attribute>
<attribute>
<id>CHIP_UNIT</id>
- <default>6</default>
+ <default>0</default>
</attribute>
<attribute>
<id>CHIPLET_ID</id>
- <default>0x0B</default>
+ <default>0x09</default>
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pu.obus_brick:k0:n0:s0:p00:c6</default>
+ <default>pu.obus_brick:k0:n0:s0:p01:c0</default>
</attribute>
<attribute>
<id>HUID</id>
- <default>0x00420006</default>
+ <default>0x00420008</default>
</attribute>
<attribute>
<id>OBUS_SLOT_INDEX</id>
@@ -3695,15 +5707,15 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>6</default>
+ <default>8</default>
</attribute>
<attribute>
<id>PARENT_PERVASIVE</id>
- <default>physical:sys-0/node-0/proc-0/perv-11</default>
+ <default>physical:sys-0/node-0/proc-1/perv-9</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/obus-2/obus_brick-0</default>
+ <default>physical:sys-0/node-0/proc-1/obus-0/obus_brick-0</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -3712,27 +5724,27 @@
</targetInstance>
<targetInstance>
- <id>sys0node0proc0obus2obus_brick1</id>
+ <id>sys0node0proc1obus0obus_brick1</id>
<type>unit-obus-brick-axone</type>
<attribute>
<id>AFFINITY_PATH</id>
- <default>affinity:sys-0/node-0/proc-0/obus-2/obus_brick-1</default>
+ <default>affinity:sys-0/node-0/proc-1/obus-0/obus_brick-1</default>
</attribute>
<attribute>
<id>CHIP_UNIT</id>
- <default>7</default>
+ <default>1</default>
</attribute>
<attribute>
<id>CHIPLET_ID</id>
- <default>0x0B</default>
+ <default>0x09</default>
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pu.obus_brick:k0:n0:s0:p00:c7</default>
+ <default>pu.obus_brick:k0:n0:s0:p01:c1</default>
</attribute>
<attribute>
<id>HUID</id>
- <default>0x00420007</default>
+ <default>0x00420009</default>
</attribute>
<attribute>
<id>OBUS_SLOT_INDEX</id>
@@ -3740,15 +5752,15 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>7</default>
+ <default>9</default>
</attribute>
<attribute>
<id>PARENT_PERVASIVE</id>
- <default>physical:sys-0/node-0/proc-0/perv-11</default>
+ <default>physical:sys-0/node-0/proc-1/perv-9</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/obus-2/obus_brick-1</default>
+ <default>physical:sys-0/node-0/proc-1/obus-0/obus_brick-1</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -3757,27 +5769,27 @@
</targetInstance>
<targetInstance>
- <id>sys0node0proc0obus2obus_brick2</id>
+ <id>sys0node0proc1obus1obus_brick0</id>
<type>unit-obus-brick-axone</type>
<attribute>
<id>AFFINITY_PATH</id>
- <default>affinity:sys-0/node-0/proc-0/obus-2/obus_brick-2</default>
+ <default>affinity:sys-0/node-0/proc-1/obus-1/obus_brick-0</default>
</attribute>
<attribute>
<id>CHIP_UNIT</id>
- <default>8</default>
+ <default>2</default>
</attribute>
<attribute>
<id>CHIPLET_ID</id>
- <default>0x0B</default>
+ <default>0x0A</default>
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pu.obus_brick:k0:n0:s0:p00:c8</default>
+ <default>pu.obus_brick:k0:n0:s0:p01:c2</default>
</attribute>
<attribute>
<id>HUID</id>
- <default>0x00420008</default>
+ <default>0x0042000A</default>
</attribute>
<attribute>
<id>OBUS_SLOT_INDEX</id>
@@ -3785,44 +5797,44 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>8</default>
+ <default>10</default>
</attribute>
<attribute>
<id>PARENT_PERVASIVE</id>
- <default>physical:sys-0/node-0/proc-0/perv-11</default>
+ <default>physical:sys-0/node-0/proc-1/perv-10</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/obus-2/obus_brick-2</default>
+ <default>physical:sys-0/node-0/proc-1/obus-1/obus_brick-0</default>
</attribute>
<attribute>
<id>REL_POS</id>
- <default>2</default>
+ <default>0</default>
</attribute>
</targetInstance>
<targetInstance>
- <id>sys0node0proc0obus3obus_brick0</id>
+ <id>sys0node0proc1obus2obus_brick0</id>
<type>unit-obus-brick-axone</type>
<attribute>
<id>AFFINITY_PATH</id>
- <default>affinity:sys-0/node-0/proc-0/obus-3/obus_brick-0</default>
+ <default>affinity:sys-0/node-0/proc-1/obus-2/obus_brick-0</default>
</attribute>
<attribute>
<id>CHIP_UNIT</id>
- <default>9</default>
+ <default>3</default>
</attribute>
<attribute>
<id>CHIPLET_ID</id>
- <default>0x0C</default>
+ <default>0x0B</default>
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pu.obus_brick:k0:n0:s0:p00:c9</default>
+ <default>pu.obus_brick:k0:n0:s0:p01:c4</default>
</attribute>
<attribute>
<id>HUID</id>
- <default>0x00420009</default>
+ <default>0x0042000B</default>
</attribute>
<attribute>
<id>OBUS_SLOT_INDEX</id>
@@ -3830,15 +5842,15 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>9</default>
+ <default>11</default>
</attribute>
<attribute>
<id>PARENT_PERVASIVE</id>
- <default>physical:sys-0/node-0/proc-0/perv-12</default>
+ <default>physical:sys-0/node-0/proc-1/perv-11</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/obus-3/obus_brick-0</default>
+ <default>physical:sys-0/node-0/proc-1/obus-2/obus_brick-0</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -3847,15 +5859,15 @@
</targetInstance>
<targetInstance>
- <id>sys0node0proc0obus3obus_brick1</id>
+ <id>sys0node0proc1obus3obus_brick0</id>
<type>unit-obus-brick-axone</type>
<attribute>
<id>AFFINITY_PATH</id>
- <default>affinity:sys-0/node-0/proc-0/obus-3/obus_brick-1</default>
+ <default>affinity:sys-0/node-0/proc-1/obus-3/obus_brick-0</default>
</attribute>
<attribute>
<id>CHIP_UNIT</id>
- <default>10</default>
+ <default>4</default>
</attribute>
<attribute>
<id>CHIPLET_ID</id>
@@ -3863,11 +5875,11 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pu.obus_brick:k0:n0:s0:p00:c10</default>
+ <default>pu.obus_brick:k0:n0:s0:p01:c6</default>
</attribute>
<attribute>
<id>HUID</id>
- <default>0x0042000A</default>
+ <default>0x0042000C</default>
</attribute>
<attribute>
<id>OBUS_SLOT_INDEX</id>
@@ -3875,32 +5887,32 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>10</default>
+ <default>12</default>
</attribute>
<attribute>
<id>PARENT_PERVASIVE</id>
- <default>physical:sys-0/node-0/proc-0/perv-12</default>
+ <default>physical:sys-0/node-0/proc-1/perv-12</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/obus-3/obus_brick-1</default>
+ <default>physical:sys-0/node-0/proc-1/obus-3/obus_brick-0</default>
</attribute>
<attribute>
<id>REL_POS</id>
- <default>1</default>
+ <default>0</default>
</attribute>
</targetInstance>
<targetInstance>
- <id>sys0node0proc0obus3obus_brick2</id>
+ <id>sys0node0proc1obus3obus_brick1</id>
<type>unit-obus-brick-axone</type>
<attribute>
<id>AFFINITY_PATH</id>
- <default>affinity:sys-0/node-0/proc-0/obus-3/obus_brick-2</default>
+ <default>affinity:sys-0/node-0/proc-1/obus-3/obus_brick-1</default>
</attribute>
<attribute>
<id>CHIP_UNIT</id>
- <default>11</default>
+ <default>5</default>
</attribute>
<attribute>
<id>CHIPLET_ID</id>
@@ -3908,11 +5920,11 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pu.obus_brick:k0:n0:s0:p00:c11</default>
+ <default>pu.obus_brick:k0:n0:s0:p01:c5</default>
</attribute>
<attribute>
<id>HUID</id>
- <default>0x0042000B</default>
+ <default>0x0042000D</default>
</attribute>
<attribute>
<id>OBUS_SLOT_INDEX</id>
@@ -3920,22 +5932,325 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>11</default>
+ <default>13</default>
</attribute>
<attribute>
<id>PARENT_PERVASIVE</id>
- <default>physical:sys-0/node-0/proc-0/perv-12</default>
+ <default>physical:sys-0/node-0/proc-1/perv-12</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/obus-3/obus_brick-1</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+
+<!-- ===================================================================== -->
+<!-- NPU Units for node 0 -->
+<!-- ===================================================================== -->
+<targetInstance>
+ <!-- Note : NPU0 covers OBUS0 -->
+ <id>sys0node0proc0npu0</id>
+ <type>unit-npu-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/npu-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x05</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00430000</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-0/perv-5</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/npu-0</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <!-- Note : NPU1 covers OBUS1 and OBUS2, but OBUS1 isn't wired out -->
+ <!-- on the Swift configuration -->
+ <id>sys0node0proc0npu1</id>
+ <type>unit-npu-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/npu-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x05</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00430001</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-0/perv-5</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/npu-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>NPU</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <!-- Note : NPU2 covers OBUS3 -->
+ <id>sys0node0proc0npu2</id>
+ <type>unit-npu-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/npu-2</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x03</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00430002</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-0/perv-3</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/obus-3/obus_brick-2</default>
+ <default>physical:sys-0/node-0/proc-0/npu-2</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
</attribute>
<attribute>
<id>REL_POS</id>
<default>2</default>
</attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>NPU</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <!-- Note : NPU0 covers OBUS0 -->
+ <id>sys0node0proc1npu0</id>
+ <type>unit-npu-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/npu-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x05</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00430003</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-5</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/npu-0</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
</targetInstance>
+<targetInstance>
+ <!-- Note : NPU1 covers OBUS1 and OBUS2, but OBUS2 isn't wired out -->
+ <!-- on the Swift configuration -->
+ <id>sys0node0proc1npu1</id>
+ <type>unit-npu-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/npu-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x05</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00430004</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-5</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/npu-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>NPU</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <!-- Note : NPU2 covers OBUS3 -->
+ <id>sys0node0proc1npu2</id>
+ <type>unit-npu-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/npu-2</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x03</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00430005</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-3</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/npu-2</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>NPU</default>
+ </attribute>
+</targetInstance>
+
+
<!-- ===================================================================== -->
<!-- TPM Units for node 0 -->
<!-- ===================================================================== -->
@@ -4041,7 +6356,7 @@
</attribute>
<attribute>
<id>FAPI_POS</id>
- <default>1</default>
+ <default>0</default>
</attribute>
<attribute>
<id>HUID</id>
@@ -4070,23 +6385,23 @@
</targetInstance>
<targetInstance>
- <id>sys0node0proc0capp1</id>
+ <id>sys0node0proc1capp0</id>
<type>unit-capp-axone</type>
<attribute>
<id>AFFINITY_PATH</id>
- <default>affinity:sys-0/node-0/proc-0/capp-1</default>
+ <default>affinity:sys-0/node-0/proc-1/capp-0</default>
</attribute>
<attribute>
<id>CHIP_UNIT</id>
- <default>1</default>
+ <default>0</default>
</attribute>
<attribute>
<id>CHIPLET_ID</id>
- <default>4</default>
+ <default>2</default>
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pu.capp:k0:n0:s0:p00:c1</default>
+ <default>pu.capp:k0:n0:s0:p01:c0</default>
</attribute>
<attribute>
<id>FAPI_POS</id>
@@ -4098,7 +6413,7 @@
</attribute>
<attribute>
<id>MRU_ID</id>
- <default>0x02090001</default>
+ <default>0x02090000</default>
</attribute>
<attribute>
<id>ORDINAL_ID</id>
@@ -4106,18 +6421,19 @@
</attribute>
<attribute>
<id>PARENT_PERVASIVE</id>
- <default>physical:sys-0/node-0/proc-0/perv-2</default>
+ <default>physical:sys-0/node-0/proc-1/perv-2</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/capp-1</default>
+ <default>physical:sys-0/node-0/proc-1/capp-0</default>
</attribute>
<attribute>
<id>REL_POS</id>
- <default>1</default>
+ <default>0</default>
</attribute>
</targetInstance>
+
<!-- ===================================================================== -->
<!-- OCC Units -->
<!-- ===================================================================== -->
@@ -4179,6 +6495,65 @@
</attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1occ0</id>
+ <type>unit-occ-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/occ-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>NA</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00130001</default>
+ </attribute>
+ <attribute>
+ <id>MRU_ID</id>
+ <default>0x02010000</default>
+ </attribute>
+ <attribute>
+ <id>OCC_MASTER_CAPABLE</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/occ-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OCC</default>
+ </attribute>
+</targetInstance>
+
+
<!-- ===================================================================== -->
<!-- NX Units -->
<!-- ===================================================================== -->
@@ -4195,7 +6570,7 @@
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
- <default>physical:sys-0/node-0/proc-0/nx-0</default>
+ <default>affinity:sys-0/node-0/proc-0/nx-0</default>
</attribute>
<attribute>
<id>ORDINAL_ID</id>
@@ -4207,6 +6582,32 @@
</attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1nx0</id>
+ <type>unit-nx-power9</type>
+ <attribute><id>HUID</id><default>0x001E0001</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>NA</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/nx-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/nx-0</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+
<!-- ===================================================================== -->
<!-- PEC Units -->
<!-- ===================================================================== -->
@@ -4468,6 +6869,264 @@
</attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1pec0</id>
+ <type>unit-pec-power9</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/pec-0</default>
+ </attribute>
+ <attribute>
+ <id>CDM_DOMAIN</id>
+ <default>IO</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0xD</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.pec:k0:n0:s0:p01:c0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002D0003</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-13</default>
+ </attribute>
+ <attribute>
+ <id>PEC_PCIE_IOP_SWAP_NON_BIFURCATED</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>PEC_PCIE_LANE_MASK_NON_BIFURCATED</id>
+ <default>0xFFFF,0x0000,0x0000,0x0000</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/pec-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>PROC_PCIE_IOP_CONFIG</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>PROC_PCIE_IOP_SWAP</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>PROC_PCIE_LANE_MASK</id>
+ <default>,0x0000,0x0000,0x0000</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PEC</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1pec1</id>
+ <type>unit-pec-power9</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/pec-1</default>
+ </attribute>
+ <attribute>
+ <id>CDM_DOMAIN</id>
+ <default>IO</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0xE</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.pec:k0:n0:s0:p01:c1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002D0004</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-14</default>
+ </attribute>
+ <attribute>
+ <id>PEC_PCIE_IOP_SWAP_NON_BIFURCATED</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>PEC_PCIE_LANE_MASK_NON_BIFURCATED</id>
+ <default>0xFF00,0x0000,0x00FF,0x0000</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/pec-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>PROC_PCIE_IOP_CONFIG</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>PROC_PCIE_IOP_SWAP</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>PROC_PCIE_LANE_MASK</id>
+ <default>,0x0000,0x0000,0x0000</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PEC</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1pec2</id>
+ <type>unit-pec-power9</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/pec-2</default>
+ </attribute>
+ <attribute>
+ <id>CDM_DOMAIN</id>
+ <default>IO</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0xF</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.pec:k0:n0:s0:p00:c2</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002D0005</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-15</default>
+ </attribute>
+ <attribute>
+ <id>PEC_PCIE_IOP_SWAP_NON_BIFURCATED</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>PEC_PCIE_LANE_MASK_NON_BIFURCATED</id>
+ <default>0xFFFF,0x0000,0x0000,0x0000</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/pec-2</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>PROC_PCIE_IOP_CONFIG</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>PROC_PCIE_IOP_SWAP</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>PROC_PCIE_LANE_MASK</id>
+ <default>,0x0000,0x0000,0x0000</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PEC</default>
+ </attribute>
+</targetInstance>
+
<!-- ===================================================================== -->
<!-- PHB Units -->
<!-- ===================================================================== -->
@@ -4891,6 +7550,426 @@
</attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1pec0phb0</id>
+ <type>unit-phb-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/pec-0/phb-0</default>
+ </attribute>
+ <attribute>
+ <id>CDM_DOMAIN</id>
+ <default>IO</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0xD</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.phb:k0:n0:s0:p01:c0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002E0006</default>
+ </attribute>
+ <attribute>
+ <id>HWAS_STATE_CHANGED_SUBSCRIPTION_MASK</id>
+ <default>0x00000031</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-13</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/pec-0/phb-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PHB</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1pec1phb0</id>
+ <type>unit-phb-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/pec-1/phb-0</default>
+ </attribute>
+ <attribute>
+ <id>CDM_DOMAIN</id>
+ <default>IO</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0xE</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.phb:k0:n0:s0:p01:c1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002E0007</default>
+ </attribute>
+ <attribute>
+ <id>HWAS_STATE_CHANGED_SUBSCRIPTION_MASK</id>
+ <default>0x00000031</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-14</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/pec-1/phb-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PHB</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1pec1phb1</id>
+ <type>unit-phb-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/pec-1/phb-1</default>
+ </attribute>
+ <attribute>
+ <id>CDM_DOMAIN</id>
+ <default>IO</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0xE</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.phb:k0:n0:s0:p01:c2</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>8</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002E0008</default>
+ </attribute>
+ <attribute>
+ <id>HWAS_STATE_CHANGED_SUBSCRIPTION_MASK</id>
+ <default>0x00000031</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>8</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-14</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/pec-1/phb-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PHB</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1pec2phb0</id>
+ <type>unit-phb-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/pec-2/phb-0</default>
+ </attribute>
+ <attribute>
+ <id>CDM_DOMAIN</id>
+ <default>IO</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0xF</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.phb:k0:n0:s0:p01:c3</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>9</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002E0009</default>
+ </attribute>
+ <attribute>
+ <id>HWAS_STATE_CHANGED_SUBSCRIPTION_MASK</id>
+ <default>0x00000031</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>9</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-15</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/pec-2/phb-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PHB</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1pec2phb1</id>
+ <type>unit-phb-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/pec-2/phb-1</default>
+ </attribute>
+ <attribute>
+ <id>CDM_DOMAIN</id>
+ <default>IO</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0xF</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.phb:k0:n0:s0:p01:c4</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002E000A</default>
+ </attribute>
+ <attribute>
+ <id>HWAS_STATE_CHANGED_SUBSCRIPTION_MASK</id>
+ <default>0x00000031</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-15</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/pec-2/phb-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PHB</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1pec2phb2</id>
+ <type>unit-phb-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/pec-2/phb-2</default>
+ </attribute>
+ <attribute>
+ <id>CDM_DOMAIN</id>
+ <default>IO</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0xF</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.phb:k0:n0:s0:p01:c5</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002E000B</default>
+ </attribute>
+ <attribute>
+ <id>HWAS_STATE_CHANGED_SUBSCRIPTION_MASK</id>
+ <default>0x00000031</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-15</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/pec-2/phb-2</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PHB</default>
+ </attribute>
+</targetInstance>
+
<!-- ===================================================================== -->
<!-- PPE Units -->
<!-- ===================================================================== -->
@@ -6136,6 +9215,1248 @@
</attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1ppe0</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>64</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B0033</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>64</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe10</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-10</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c10</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>74</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B003D</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>74</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-10</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe11</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-11</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c11</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>75</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B003E</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>75</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-11</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe12</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-12</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>12</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c12</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>76</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B003F</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>76</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-12</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>12</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe13</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-13</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>13</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c13</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>77</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B0040</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>77</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-13</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>13</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe20</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-20</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c20</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>84</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B0047</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>84</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-20</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe21</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-21</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c21</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>85</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B0048</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>85</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-21</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe22</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-22</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c22</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>86</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B0049</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>86</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-22</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe23</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-23</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c23</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>87</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B004A</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>87</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-23</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe24</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-24</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>24</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c24</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>88</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B004B</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>88</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-24</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>24</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe25</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-25</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>25</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c25</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>89</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B004C</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>89</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-25</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>25</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe30</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-30</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>30</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c30</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>94</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B0051</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>94</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-30</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>30</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe31</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-31</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>31</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c31</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>95</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B0052</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>31</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-31</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>31</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe32</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-32</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>32</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c32</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>96</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B0053</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>96</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-32</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>32</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe33</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-33</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>33</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c33</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>97</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B0054</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>97</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-33</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>33</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe34</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-34</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>34</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c34</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>98</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B0055</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>98</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-34</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>34</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe35</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-35</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>35</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c35</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>99</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B0065</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>99</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-35</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>35</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe40</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-40</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>40</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c40</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>104</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B005B</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>104</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-40</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>40</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe41</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-41</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>41</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c41</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>105</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B005C</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>105</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-41</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>41</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe42</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-42</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>42</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c42</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>106</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B005D</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>106</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-42</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>42</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe43</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-43</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>43</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c43</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>107</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B005E</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>107</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-43</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>43</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe45</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-45</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>45</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c45</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>109</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B0060</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>109</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-45</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>45</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1ppe50</id>
+ <type>unit-ppe-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/ppe-50</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>50</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.ppe:k0:n0:s0:p01:c50</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>114</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002B0065</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>114</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/ppe-50</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>50</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PPE</default>
+ </attribute>
+</targetInstance>
+
<!-- ===================================================================== -->
<!-- SBE Units -->
<!-- ===================================================================== -->
@@ -6178,6 +10499,8 @@
<id>PHYS_PATH</id>
<default>physical:sys-0/node-0/proc-0/sbe-0</default>
</attribute>
+ <!--The eeprom associated w/ this target will have a valid entry in the EECACHE
+ that we preload in standalone simics. No cache updates should be needed -->
<attribute>
<id>PRIMARY_CAPABILITIES</id>
<default>
@@ -6253,11 +10576,11 @@
</attribute>
<attribute>
<id>PEER_TARGET</id>
- <default>NULL</default>
+ <default>physical:sys-0/node-0/proc-1/xbus-2</default>
</attribute>
<attribute>
<id>PEER_PATH</id>
- <default>physical:na</default>
+ <default>physical:sys-0/node-0/proc-1/xbus-2</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
@@ -6364,24 +10687,27 @@
</attribute>
</targetInstance>
+<!-- ===================================================================== -->
+<!-- MEMORY SUBSYSTEM -->
+<!-- ===================================================================== -->
+
+<!-- ===================================================================== -->
+<!-- MC Units -->
+<!-- ===================================================================== -->
<targetInstance>
- <id>sys0node0proc0xbus2</id>
- <type>unit-xbus-axone</type>
+ <id>sys0node0proc0mc0</id>
+ <type>unit-mc-axone</type>
<attribute>
<id>AFFINITY_PATH</id>
- <default>affinity:sys-0/node-0/proc-0/xbus-2</default>
- </attribute>
- <attribute>
- <id>CDM_DOMAIN</id>
- <default>FABRIC</default>
+ <default>affinity:sys-0/node-0/proc-0/mc-0</default>
</attribute>
<attribute>
<id>CHIP_UNIT</id>
- <default>2</default>
+ <default>0</default>
</attribute>
<attribute>
<id>CHIPLET_ID</id>
- <default>0x06</default>
+ <default>0x07</default>
</attribute>
<attribute>
<id>CLASS</id>
@@ -6389,43 +10715,94 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pu.xbus:k0:n0:s0:p00:c2</default>
+ <default>pu.mc:k0:n0:s0:p00:c0</default>
</attribute>
<attribute>
<id>FAPI_POS</id>
- <default>2</default>
+ <default>0</default>
</attribute>
<attribute>
<id>HUID</id>
- <default>0x000E0002</default>
+ <default>0x00440000</default>
</attribute>
<attribute>
- <id>HWAS_STATE_CHANGED_SUBSCRIPTION_MASK</id>
- <default>0x00000031</default>
+ <id>ORDINAL_ID</id>
+ <default>0</default>
</attribute>
<attribute>
- <id>MRU_ID</id>
- <default>0x03020002</default>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-0/perv-7</default>
</attribute>
<attribute>
- <id>ORDINAL_ID</id>
- <default>2</default>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/mc-0</default>
</attribute>
<attribute>
- <id>PARENT_PERVASIVE</id>
- <default>physical:sys-0/node-0/proc-0/perv-6</default>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
</attribute>
<attribute>
- <id>PEER_TARGET</id>
- <default>NULL</default>
+ <id>REL_POS</id>
+ <default>0</default>
</attribute>
<attribute>
- <id>PEER_PATH</id>
- <default>physical:na</default>
+ <id>TYPE</id>
+ <default>MC</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 16GB -->
+ <default>0x30400000000</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0mc1</id>
+ <type>unit-mc-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/mc-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.mc:k0:n0:s0:p00:c1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00440001</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-0/perv-8</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/xbus-2</default>
+ <default>physical:sys-0/node-0/proc-0/mc-1</default>
</attribute>
<attribute>
<id>PRIMARY_CAPABILITIES</id>
@@ -6438,27 +10815,25 @@
</attribute>
<attribute>
<id>REL_POS</id>
- <default>2</default>
+ <default>1</default>
</attribute>
<attribute>
<id>TYPE</id>
- <default>XBUS</default>
+ <default>MC</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 48GB -->
+ <default>0x30C00000000</default>
</attribute>
</targetInstance>
-<!-- ===================================================================== -->
-<!-- MEMORY SUBSYSTEM -->
-<!-- ===================================================================== -->
-
-<!-- ===================================================================== -->
-<!-- MC Units -->
-<!-- ===================================================================== -->
<targetInstance>
- <id>sys0node0proc0mc0</id>
+ <id>sys0node0proc1mc0</id>
<type>unit-mc-axone</type>
<attribute>
<id>AFFINITY_PATH</id>
- <default>affinity:sys-0/node-0/proc-0/mc-0</default>
+ <default>affinity:sys-0/node-0/proc-1/mc-0</default>
</attribute>
<attribute>
<id>CHIP_UNIT</id>
@@ -6474,27 +10849,27 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pu.mc:k0:n0:s0:p00:c0</default>
+ <default>pu.mc:k0:n0:s0:p01:c0</default>
</attribute>
<attribute>
<id>FAPI_POS</id>
- <default>0</default>
+ <default>2</default>
</attribute>
<attribute>
<id>HUID</id>
- <default>0x00440000</default>
+ <default>0x00440002</default>
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>0</default>
+ <default>2</default>
</attribute>
<attribute>
<id>PARENT_PERVASIVE</id>
- <default>physical:sys-0/node-0/proc-0/perv-7</default>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/mc-0</default>
+ <default>physical:sys-0/node-0/proc-1/mc-0</default>
</attribute>
<attribute>
<id>PRIMARY_CAPABILITIES</id>
@@ -6521,11 +10896,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0proc0mc1</id>
+ <id>sys0node0proc1mc1</id>
<type>unit-mc-axone</type>
<attribute>
<id>AFFINITY_PATH</id>
- <default>affinity:sys-0/node-0/proc-0/mc-1</default>
+ <default>affinity:sys-0/node-0/proc-1/mc-1</default>
</attribute>
<attribute>
<id>CHIP_UNIT</id>
@@ -6541,27 +10916,27 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pu.mc:k0:n0:s0:p00:c1</default>
+ <default>pu.mc:k0:n0:s0:p01:c1</default>
</attribute>
<attribute>
<id>FAPI_POS</id>
- <default>1</default>
+ <default>3</default>
</attribute>
<attribute>
<id>HUID</id>
- <default>0x00440001</default>
+ <default>0x00440003</default>
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>1</default>
+ <default>3</default>
</attribute>
<attribute>
<id>PARENT_PERVASIVE</id>
- <default>physical:sys-0/node-0/proc-0/perv-8</default>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/mc-1</default>
+ <default>physical:sys-0/node-0/proc-1/mc-1</default>
</attribute>
<attribute>
<id>PRIMARY_CAPABILITIES</id>
@@ -6838,6 +11213,255 @@
</attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1mc0mi0</id>
+ <type>unit-mi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.mi:k0:n0:s0:p01:c0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00260004</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/mi-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>MI</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc0mi1</id>
+ <type>unit-mi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.mi:k0:n0:s0:p01:c1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00260005</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/mi-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>MI</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1mi0</id>
+ <type>unit-mi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.mi:k0:n0:s0:p01:c2</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00260006</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/mi-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>MI</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1mi1</id>
+ <type>unit-mi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.mi:k0:n0:s0:p01:c3</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00260007</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/mi-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>MI</default>
+ </attribute>
+</targetInstance>
+
+
<!-- ===================================================================== -->
<!-- MCC Units -->
<!-- ===================================================================== -->
@@ -7337,6 +11961,502 @@
</attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1mc0mi0mcc0</id>
+ <type>unit-mcc-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.mcc:k0:n0:s0:p01:c0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00490010</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>MCC</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc0mi0mcc1</id>
+ <type>unit-mcc-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.mcc:k0:n0:s0:p01:c1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>17</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00490011</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>17</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>MCC</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc0mi1mcc0</id>
+ <type>unit-mcc-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.mcc:k0:n0:s0:p01:c2</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00490012</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>MCC</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc0mi1mcc1</id>
+ <type>unit-mcc-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.mcc:k0:n0:s0:p01:c3</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00490013</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>MCC</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1mi0mcc0</id>
+ <type>unit-mcc-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0/mcc-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.mcc:k0:n0:s0:p01:c4</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00490014</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/mi-0/mcc-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>MCC</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1mi0mcc1</id>
+ <type>unit-mcc-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0/mcc-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.mcc:k0:n0:s0:p01:c5</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00490015</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/mi-0/mcc-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>MCC</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1mi1mcc0</id>
+ <type>unit-mcc-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-1/mcc-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.mcc:k0:n0:s0:p01:c6</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00490016</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/mi-1/mcc-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>MCC</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1mi1mcc1</id>
+ <type>unit-mcc-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-1/mcc-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.mcc:k0:n0:s0:p01:c7</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00490017</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/mi-1/mcc-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>MCC</default>
+ </attribute>
+</targetInstance>
+
<!-- ===================================================================== -->
<!-- OMI Units -->
<!-- ===================================================================== -->
@@ -7416,6 +12536,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>0</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>0</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -7491,6 +12615,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>1</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>1</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -7566,6 +12694,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>2</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>1</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -7641,6 +12773,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>3</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>2</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -7716,6 +12852,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>4</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>0</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -7791,6 +12931,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>5</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>1</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -7866,6 +13010,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>6</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>2</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -7941,6 +13089,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>7</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>0</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -8016,6 +13168,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>8</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>0</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -8091,6 +13247,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>9</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>1</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -8166,6 +13326,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>10</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>1</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -8213,7 +13377,7 @@
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/proc-0/mc-1/mi-0/mcc-1/omi-11</default>
+ <default>physical:sys-0/node-0/proc-0/mc-1/mi-0/mcc-1/omi-1</default>
</attribute>
<attribute>
<id>PRIMARY_CAPABILITIES</id>
@@ -8241,6 +13405,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>11</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>2</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -8316,6 +13484,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>12</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>0</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -8391,6 +13563,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>13</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>1</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -8466,6 +13642,10 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>14</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>2</default>
+ </attribute>
</targetInstance>
<targetInstance>
@@ -8541,14 +13721,1286 @@
<id>OMI_REFCLOCK_SWIZZLE</id>
<default>15</default>
</attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc0mi0mcc0omi0</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00480010</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/omic-2</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <!-- TODO RTC 201493 - Need to remove these sets (all 16 of them) of
+ OMI_INBAND_BAR_BASE_ADDR_OFFSET once p9a_omi_setup_bars
+ is working -->
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 16GB -->
+ <default>0x30400000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc0mi0mcc0omi1</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>17</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00480011</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>17</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/omic-2</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 18GB -->
+ <default>0x30480000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc0mi0mcc1omi0</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c2</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00480012</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/omic-1</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 24GB -->
+ <default>0x30600000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc0mi0mcc1omi1</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c3</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00480013</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/omic-1</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 26GB -->
+ <default>0x30680000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>2</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc0mi1mcc0omi0</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c4</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00480014</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/omic-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 32GB -->
+ <default>0x30800000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc0mi1mcc0omi1</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c5</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00480015</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/omic-0</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 34GB -->
+ <default>0x30880000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc0mi1mcc1omi0</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c6</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00480016</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/omic-0</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 40GB -->
+ <default>0x30A00000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>2</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc0mi1mcc1omi1</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c7</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00480017</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/omic-1</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 42GB -->
+ <default>0x30A80000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1mi0mcc0omi0</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0/mcc-0/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>8</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c8</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>24</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00480018</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>24</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/omic-2</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/mi-0/mcc-0/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 48GB -->
+ <default>0x30C00000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>8</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>0</default>
+ </attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1mc1mi0mcc0omi1</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0/mcc-0/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>9</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c9</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>25</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00480019</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>25</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/omic-2</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/mi-0/mcc-0/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 50GB -->
+ <default>0x30C80000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>9</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1mi0mcc1omi0</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0/mcc-1/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c10</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>26</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0048001A</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>26</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/omic-1</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/mi-0/mcc-1/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 56GB -->
+ <default>0x30E00000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1mi0mcc1omi1</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0/mcc-1/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c11</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>27</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0048001B</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>27</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/omic-1</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/mi-0/mcc-1/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 58GB -->
+ <default>0x30E80000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>2</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1mi1mcc0omi0</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-1/mcc-0/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>12</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c12</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>28</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0048001C</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>28</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/omic-0</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/mi-1/mcc-0/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 64GB -->
+ <default>0x31000000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>12</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1mi1mcc0omi1</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-1/mcc-0/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>13</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c13</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>29</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0048001D</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>13</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/omic-0</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/mi-1/mcc-0/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 66GB -->
+ <default>0x31080000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>13</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1mi1mcc1omi0</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-1/mcc-1/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>14</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c14</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>30</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0048001E</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>30</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/omic-0</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/mi-1/mcc-1/omi-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 72GB -->
+ <default>0x31200000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>14</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>2</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1mi1mcc1omi1</id>
+ <type>unit-omi-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-1/mcc-1/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>15</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omi:k0:n0:s0:p01:c15</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>31</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0048001F</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>31</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>OMIC_PARENT</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/omic-1</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/mi-1/mcc-1/omi-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMI</default>
+ </attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ <!-- 3TB + 74GB -->
+ <default>0x31280000000</default>
+ </attribute>
+ <attribute>
+ <id>OMI_REFCLOCK_SWIZZLE</id>
+ <default>15</default>
+ </attribute>
+ <attribute>
+ <id>OMI_DL_GROUP_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+
<!-- ===================================================================== -->
<!-- OCMB_CHIP Units -->
<!-- ===================================================================== -->
<targetInstance>
<id>sys0node0ocmb0</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-0/mi-0/mcc-0/omi-0/ocmb_chip-0</default>
@@ -8586,9 +15038,10 @@
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>0</value></field>
- <field><id>devAddr</id><value>0xD0</value></field>
- <field><id>i2cMuxBusSelector</id><value>0x08</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x00</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -8600,13 +15053,13 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x08</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x00</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -8614,7 +15067,7 @@
<targetInstance>
<id>sys0node0ocmb1</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-0/mi-0/mcc-0/omi-1/ocmb_chip-0</default>
@@ -8652,9 +15105,10 @@
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>0</value></field>
- <field><id>devAddr</id><value>0xD0</value></field>
- <field><id>i2cMuxBusSelector</id><value>0x09</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x01</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -8666,13 +15120,13 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x09</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x01</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -8680,7 +15134,7 @@
<targetInstance>
<id>sys0node0ocmb2</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-0/mi-0/mcc-1/omi-0/ocmb_chip-0</default>
@@ -8718,9 +15172,10 @@
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>0</value></field>
- <field><id>devAddr</id><value>0xD0</value></field>
- <field><id>i2cMuxBusSelector</id><value>0x0A</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x02</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -8732,13 +15187,13 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x0A</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x02</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -8746,7 +15201,7 @@
<targetInstance>
<id>sys0node0ocmb3</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-0/mi-0/mcc-1/omi-1/ocmb_chip-0</default>
@@ -8784,9 +15239,10 @@
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>0</value></field>
- <field><id>devAddr</id><value>0xD0</value></field>
- <field><id>i2cMuxBusSelector</id><value>0x0B</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x03</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -8798,13 +15254,13 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x0B</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x03</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -8812,7 +15268,7 @@
<targetInstance>
<id>sys0node0ocmb4</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-0/mi-1/mcc-0/omi-0/ocmb_chip-0</default>
@@ -8850,9 +15306,10 @@
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>0</value></field>
- <field><id>devAddr</id><value>0xD0</value></field>
- <field><id>i2cMuxBusSelector</id><value>0x0C</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x04</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -8864,13 +15321,13 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x0C</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x04</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -8878,7 +15335,7 @@
<targetInstance>
<id>sys0node0ocmb5</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-0/mi-1/mcc-0/omi-1/ocmb_chip-0</default>
@@ -8916,9 +15373,10 @@
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>0</value></field>
- <field><id>devAddr</id><value>0xD0</value></field>
- <field><id>i2cMuxBusSelector</id><value>0x0D</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x05</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -8930,13 +15388,13 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x0D</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x05</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -8944,7 +15402,7 @@
<targetInstance>
<id>sys0node0ocmb6</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-0/mi-1/mcc-1/omi-0/ocmb_chip-0</default>
@@ -8982,9 +15440,10 @@
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>0</value></field>
- <field><id>devAddr</id><value>0xD0</value></field>
- <field><id>i2cMuxBusSelector</id><value>0x0E</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x06</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -8996,13 +15455,13 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x0E</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x06</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -9010,7 +15469,7 @@
<targetInstance>
<id>sys0node0ocmb7</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-0/mi-1/mcc-1/omi-1/ocmb_chip-0</default>
@@ -9048,9 +15507,10 @@
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>0</value></field>
- <field><id>devAddr</id><value>0xD0</value></field>
- <field><id>i2cMuxBusSelector</id><value>0x0F</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x07</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -9062,13 +15522,13 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x0F</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x07</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -9076,7 +15536,7 @@
<targetInstance>
<id>sys0node0ocmb8</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-1/mi-0/mcc-0/omi-0/ocmb_chip-0</default>
@@ -9114,8 +15574,9 @@
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>1</value></field>
- <field><id>devAddr</id><value>0xD0</value></field>
+ <!-- Engine 3 Port 0 is directly attached to DDIMM8 in the simics axone model -->
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
<field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
</default>
@@ -9127,8 +15588,8 @@
<field><id>chipCount</id><value>0x01</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>engine</id><value>3</value></field>
- <!-- Engine 3 Port 1 is directly attached to DDIMM0 in the simics axone model -->
- <field><id>port</id><value>1</value></field>
+ <!-- Engine 3 Port 0 is directly attached to DDIMM8 in the simics axone model -->
+ <field><id>port</id><value>0</value></field>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>20</value></field>
@@ -9141,7 +15602,7 @@
<targetInstance>
<id>sys0node0ocmb9</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-1/mi-0/mcc-0/omi-1/ocmb_chip-0</default>
@@ -9174,13 +15635,18 @@
<id>FAPI_POS</id>
<default>9</default>
</attribute>
+ <!-- Note that EEPROM_VPD_PRIMARY_INFO/FAPI_I2C_CONTROL_INFO attrs for OCMB 9-15 and DIMM 9-15
+ are invalid. The engine value is set to be engine 1 (C) which has 12
+ valid ports according to the simics axone model. Only the first 4 ports
+ are actually used so we will use 5-12 as dummy ports for the unused dimm targets.
+ We cannot use the ports on engine 3 (E) becuase simics only has 2 ports marked as valid-->
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
- <field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>1</value></field>
- <field><id>devAddr</id><value>0xD2</value></field>
+ <field><id>engine</id><value>1</value></field>
+ <field><id>port</id><value>5</value></field>
+ <field><id>devAddr</id><value>0xD0</value></field>
<field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
</default>
@@ -9188,25 +15654,22 @@
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>engine</id><value>1</value></field>
+ <field><id>port</id><value>5</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <field><id>devAddr</id><value>0xA2</value></field>
- <field><id>engine</id><value>3</value></field>
- <!-- Engine 3 Port 1 is directly attached to DDIMM0 in the simics axone model -->
- <field><id>port</id><value>1</value></field>
- <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
- <field><id>maxMemorySizeKB</id><value>0x4</value></field>
- <field><id>writeCycleTime</id><value>20</value></field>
- <field><id>writePageSize</id><value>32</value></field>
- <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
- <field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
</default>
</attribute>
</targetInstance>
<targetInstance>
<id>sys0node0ocmb10</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-1/mi-0/mcc-1/omi-0/ocmb_chip-0</default>
@@ -9239,13 +15702,18 @@
<id>FAPI_POS</id>
<default>10</default>
</attribute>
+ <!-- Note that EEPROM_VPD_PRIMARY_INFO/FAPI_I2C_CONTROL_INFO attrs for OCMB 9-15 and DIMM 9-15
+ are invalid. The engine value is set to be engine 1 (C) which has 12
+ valid ports according to the simics axone model. Only the first 4 ports
+ are actually used so we will use 5-12 as dummy ports for the unused dimm targets.
+ We cannot use the ports on engine 3 (E) becuase simics only has 2 ports marked as valid-->
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
- <field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>1</value></field>
- <field><id>devAddr</id><value>0xD4</value></field>
+ <field><id>engine</id><value>1</value></field>
+ <field><id>port</id><value>6</value></field>
+ <field><id>devAddr</id><value>0xD0</value></field>
<field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
</default>
@@ -9253,25 +15721,22 @@
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>engine</id><value>1</value></field>
+ <field><id>port</id><value>6</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <field><id>devAddr</id><value>0xA4</value></field>
- <field><id>engine</id><value>3</value></field>
- <!-- Engine 3 Port 1 is directly attached to DDIMM0 in the simics axone model -->
- <field><id>port</id><value>1</value></field>
- <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
- <field><id>maxMemorySizeKB</id><value>0x4</value></field>
- <field><id>writeCycleTime</id><value>20</value></field>
- <field><id>writePageSize</id><value>32</value></field>
- <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
- <field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
</default>
</attribute>
</targetInstance>
<targetInstance>
<id>sys0node0ocmb11</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-1/mi-0/mcc-1/omi-1/ocmb_chip-0</default>
@@ -9304,13 +15769,16 @@
<id>FAPI_POS</id>
<default>11</default>
</attribute>
+ <!-- Note that EEPROM_VPD_PRIMARY_INFO/FAPI_I2C_CONTROL_INFO attrs for OCMB 9-15 and DIMM 9-15
+ are invalid. The port and devAddr values are invalid, info is just here to fully test
+ the EEPROM caching code (DIMM X should match OCMB X) -->
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>1</value></field>
- <field><id>devAddr</id><value>0xD6</value></field>
+ <field><id>port</id><value>4</value></field>
+ <field><id>devAddr</id><value>0xD4</value></field>
<field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
</default>
@@ -9318,25 +15786,24 @@
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
- <field><id>byteAddrOffset</id><value>0x02</value></field>
- <field><id>chipCount</id><value>0x01</value></field>
- <field><id>devAddr</id><value>0xA6</value></field>
+ <field><id>devAddr</id><value>0xA4</value></field>
<field><id>engine</id><value>3</value></field>
- <!-- Engine 3 Port 1 is directly attached to DDIMM0 in the simics axone model -->
- <field><id>port</id><value>1</value></field>
- <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>port</id><value>4</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
- <field><id>writeCycleTime</id><value>20</value></field>
- <field><id>writePageSize</id><value>32</value></field>
- <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
</default>
</attribute>
</targetInstance>
<targetInstance>
<id>sys0node0ocmb12</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-1/mi-1/mcc-0/omi-0/ocmb_chip-0</default>
@@ -9369,13 +15836,16 @@
<id>FAPI_POS</id>
<default>12</default>
</attribute>
+ <!-- Note that EEPROM_VPD_PRIMARY_INFO/FAPI_I2C_CONTROL_INFO attrs for OCMB 9-15 and DIMM 9-15
+ are invalid. The port and devAddr values are invalid, info is just here to fully test
+ the EEPROM caching code (DIMM X should match OCMB X) -->
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>2</value></field>
- <field><id>devAddr</id><value>0xD2</value></field>
+ <field><id>port</id><value>5</value></field>
+ <field><id>devAddr</id><value>0xD5</value></field>
<field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
</default>
@@ -9383,25 +15853,24 @@
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
- <field><id>byteAddrOffset</id><value>0x02</value></field>
- <field><id>chipCount</id><value>0x01</value></field>
- <field><id>devAddr</id><value>0xA2</value></field>
+ <field><id>devAddr</id><value>0xA5</value></field>
<field><id>engine</id><value>3</value></field>
- <!-- Engine 3 Port 1 is directly attached to DDIMM0 in the simics axone model -->
- <field><id>port</id><value>2</value></field>
- <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>port</id><value>5</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
- <field><id>writeCycleTime</id><value>20</value></field>
- <field><id>writePageSize</id><value>32</value></field>
- <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
</default>
</attribute>
</targetInstance>
<targetInstance>
<id>sys0node0ocmb13</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-1/mi-1/mcc-0/omi-1/ocmb_chip-0</default>
@@ -9434,13 +15903,16 @@
<id>FAPI_POS</id>
<default>13</default>
</attribute>
+ <!-- Note that EEPROM_VPD_PRIMARY_INFO/FAPI_I2C_CONTROL_INFO attrs for OCMB 9-15 and DIMM 9-15
+ are invalid. The port and devAddr values are invalid, info is just here to fully test
+ the EEPROM caching code (DIMM X should match OCMB X) -->
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>2</value></field>
- <field><id>devAddr</id><value>0xD4</value></field>
+ <field><id>port</id><value>6</value></field>
+ <field><id>devAddr</id><value>0xD6</value></field>
<field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
</default>
@@ -9448,25 +15920,24 @@
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
- <field><id>byteAddrOffset</id><value>0x02</value></field>
- <field><id>chipCount</id><value>0x01</value></field>
- <field><id>devAddr</id><value>0xA4</value></field>
+ <field><id>devAddr</id><value>0xA6</value></field>
<field><id>engine</id><value>3</value></field>
- <!-- Engine 3 Port 1 is directly attached to DDIMM0 in the simics axone model -->
- <field><id>port</id><value>2</value></field>
- <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>port</id><value>6</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
- <field><id>writeCycleTime</id><value>20</value></field>
- <field><id>writePageSize</id><value>32</value></field>
- <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
</default>
</attribute>
</targetInstance>
<targetInstance>
<id>sys0node0ocmb14</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-1/mi-1/mcc-1/omi-0/ocmb_chip-0</default>
@@ -9499,13 +15970,16 @@
<id>FAPI_POS</id>
<default>14</default>
</attribute>
+ <!-- Note that EEPROM_VPD_PRIMARY_INFO/FAPI_I2C_CONTROL_INFO attrs for OCMB 9-15 and DIMM 9-15
+ are invalid. The port and devAddr values are invalid, info is just here to fully test
+ the EEPROM caching code (DIMM X should match OCMB X) -->
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>2</value></field>
- <field><id>devAddr</id><value>0xD6</value></field>
+ <field><id>port</id><value>7</value></field>
+ <field><id>devAddr</id><value>0xD7</value></field>
<field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
</default>
@@ -9513,25 +15987,24 @@
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
- <field><id>byteAddrOffset</id><value>0x02</value></field>
- <field><id>chipCount</id><value>0x01</value></field>
- <field><id>devAddr</id><value>0xA6</value></field>
+ <field><id>devAddr</id><value>0xA7</value></field>
<field><id>engine</id><value>3</value></field>
- <!-- Engine 3 Port 1 is directly attached to DDIMM0 in the simics axone model -->
- <field><id>port</id><value>2</value></field>
- <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>port</id><value>7</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
- <field><id>writeCycleTime</id><value>20</value></field>
- <field><id>writePageSize</id><value>32</value></field>
- <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
</default>
</attribute>
</targetInstance>
<targetInstance>
<id>sys0node0ocmb15</id>
- <type>chip-ocmb-explorer</type>
+ <type>chip-ocmb</type>
<attribute>
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-0/mc-1/mi-1/mcc-1/omi-1/ocmb_chip-0</default>
@@ -9564,6 +16037,9 @@
<id>FAPI_POS</id>
<default>15</default>
</attribute>
+ <!-- Note that EEPROM_VPD_PRIMARY_INFO/FAPI_I2C_CONTROL_INFO attrs for OCMB 9-15 and DIMM 9-15
+ are invalid. The port and devAddr values are invalid, info is just here to fully test
+ the EEPROM caching code (DIMM X should match OCMB X) -->
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
<default>
@@ -9578,13 +16054,614 @@
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
- <field><id>byteAddrOffset</id><value>0x02</value></field>
- <field><id>chipCount</id><value>0x01</value></field>
<field><id>devAddr</id><value>0xA8</value></field>
<field><id>engine</id><value>3</value></field>
- <!-- Engine 3 Port 1 is directly attached to DDIMM0 in the simics axone model -->
- <field><id>port</id><value>2</value></field>
+ <field><id>port</id><value>8</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb16</id>
+ <type>chip-ocmb</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0/omi-0/ocmb_chip-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>ocmb:k0:n0:s0:p16</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0004B0010</default>
+ </attribute>
+ <attribute>
+ <id>MRU_ID</id>
+ <default>0x00060000</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-16</default>
+ </attribute>
+ <attribute>
+ <id>POSITION</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x00</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x00</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb17</id>
+ <type>chip-ocmb</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0/omi-1/ocmb_chip-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>ocmb:k0:n0:s0:p17</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0004B0011</default>
+ </attribute>
+ <attribute>
+ <id>MRU_ID</id>
+ <default>0x00060000</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-17</default>
+ </attribute>
+ <attribute>
+ <id>POSITION</id>
+ <default>17</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>17</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x01</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x01</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb18</id>
+ <type>chip-ocmb</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1/omi-0/ocmb_chip-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>ocmb:k0:n0:s0:p18</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0004B0012</default>
+ </attribute>
+ <attribute>
+ <id>MRU_ID</id>
+ <default>0x00060000</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-18</default>
+ </attribute>
+ <attribute>
+ <id>POSITION</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x02</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x02</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb19</id>
+ <type>chip-ocmb</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1/omi-1/ocmb_chip-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>ocmb:k0:n0:s0:p19</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0004B0013</default>
+ </attribute>
+ <attribute>
+ <id>MRU_ID</id>
+ <default>0x00060000</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-19</default>
+ </attribute>
+ <attribute>
+ <id>POSITION</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x03</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x03</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb20</id>
+ <type>chip-ocmb</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0/omi-0/ocmb_chip-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>ocmb:k0:n0:s0:p20</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0004B0014</default>
+ </attribute>
+ <attribute>
+ <id>MRU_ID</id>
+ <default>0x00060000</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-20</default>
+ </attribute>
+ <attribute>
+ <id>POSITION</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x04</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x04</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb21</id>
+ <type>chip-ocmb</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0/omi-1/ocmb_chip-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>ocmb:k0:n0:s0:p21</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0004B0015</default>
+ </attribute>
+ <attribute>
+ <id>MRU_ID</id>
+ <default>0x00060000</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-21</default>
+ </attribute>
+ <attribute>
+ <id>POSITION</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x05</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x05</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb22</id>
+ <type>chip-ocmb</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1/omi-0/ocmb_chip-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>ocmb:k0:n0:s0:p22</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0004B0016</default>
+ </attribute>
+ <attribute>
+ <id>MRU_ID</id>
+ <default>0x00060000</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-22</default>
+ </attribute>
+ <attribute>
+ <id>POSITION</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x06</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x06</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb23</id>
+ <type>chip-ocmb</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1/omi-1/ocmb_chip-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>ocmb:k0:n0:s0:p23</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0004B0017</default>
+ </attribute>
+ <attribute>
+ <id>MRU_ID</id>
+ <default>0x00060000</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-23</default>
+ </attribute>
+ <attribute>
+ <id>POSITION</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x07</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <!-- Valid Mux Bus Selections are 0x00-0x07 -->
+ <field><id>i2cMuxBusSelector</id><value>0x07</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb24</id>
+ <type>chip-ocmb</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0/mcc-0/omi-0/ocmb_chip-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>ocmb:k0:n0:s0:p24</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0004B0018</default>
+ </attribute>
+ <attribute>
+ <id>MRU_ID</id>
+ <default>0x00060000</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-24</default>
+ </attribute>
+ <attribute>
+ <id>POSITION</id>
+ <default>24</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>24</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>24</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <!-- Engine 3 Port 0 is directly attached to DDIMM8 in the simics axone model -->
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0x40</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <!-- Engine 3 Port 0 is directly attached to DDIMM8 in the simics axone model -->
+ <field><id>port</id><value>0</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>20</value></field>
<field><id>writePageSize</id><value>32</value></field>
@@ -9613,6 +16690,10 @@
<default>pmic:k0:n0:s0:p00</default>
</attribute>
<attribute>
+ <id>FAPI_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
@@ -9653,6 +16734,10 @@
<default>pmic:k0:n0:s0:p01</default>
</attribute>
<attribute>
+ <id>FAPI_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
<default>
<field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
@@ -9678,11 +16763,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic2</id>
+ <id>sys0node0pmic4</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x00360002</default>
+ <default>0x00360004</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -9690,7 +16775,11 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p02</default>
+ <default>pmic:k0:n0:s0:p04</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>4</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -9705,11 +16794,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>2</default>
+ <default>4</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-2</default>
+ <default>physical:sys-0/node-0/pmic-4</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -9718,11 +16807,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic3</id>
+ <id>sys0node0pmic5</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x00360003</default>
+ <default>0x00360005</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -9730,7 +16819,11 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p03</default>
+ <default>pmic:k0:n0:s0:p05</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>5</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -9745,11 +16838,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>3</default>
+ <default>5</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-3</default>
+ <default>physical:sys-0/node-0/pmic-5</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -9758,11 +16851,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic4</id>
+ <id>sys0node0pmic8</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x00360004</default>
+ <default>0x00360008</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -9770,7 +16863,11 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p04</default>
+ <default>pmic:k0:n0:s0:p08</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>8</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -9785,11 +16882,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>4</default>
+ <default>8</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-4</default>
+ <default>physical:sys-0/node-0/pmic-8</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -9798,11 +16895,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic5</id>
+ <id>sys0node0pmic9</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x00360005</default>
+ <default>0x00360009</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -9810,7 +16907,11 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p05</default>
+ <default>pmic:k0:n0:s0:p09</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>9</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -9825,11 +16926,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>5</default>
+ <default>9</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-5</default>
+ <default>physical:sys-0/node-0/pmic-9</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -9838,11 +16939,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic6</id>
+ <id>sys0node0pmic12</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x00360006</default>
+ <default>0x0036000C</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -9850,7 +16951,11 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p06</default>
+ <default>pmic:k0:n0:s0:p12</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>12</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -9865,11 +16970,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>6</default>
+ <default>12</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-6</default>
+ <default>physical:sys-0/node-0/pmic-12</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -9878,11 +16983,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic7</id>
+ <id>sys0node0pmic13</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x00360007</default>
+ <default>0x0036000D</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -9890,7 +16995,11 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p07</default>
+ <default>pmic:k0:n0:s0:p13</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>13</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -9905,11 +17014,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>7</default>
+ <default>13</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-7</default>
+ <default>physical:sys-0/node-0/pmic-13</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -9918,11 +17027,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic8</id>
+ <id>sys0node0pmic16</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x00360008</default>
+ <default>0x00360010</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -9930,7 +17039,7 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p08</default>
+ <default>pmic:k0:n0:s0:p16</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -9945,11 +17054,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>8</default>
+ <default>16</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-8</default>
+ <default>physical:sys-0/node-0/pmic-16</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -9958,11 +17067,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic9</id>
+ <id>sys0node0pmic17</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x00360009</default>
+ <default>0x00360011</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -9970,7 +17079,11 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p09</default>
+ <default>pmic:k0:n0:s0:p17</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>17</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -9985,11 +17098,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>9</default>
+ <default>17</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-9</default>
+ <default>physical:sys-0/node-0/pmic-17</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -9998,11 +17111,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic10</id>
+ <id>sys0node0pmic20</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x0036000A</default>
+ <default>0x00360014</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -10010,7 +17123,7 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p10</default>
+ <default>pmic:k0:n0:s0:p20</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -10025,11 +17138,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>10</default>
+ <default>20</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-0</default>
+ <default>physical:sys-0/node-0/pmic-20</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -10038,11 +17151,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic11</id>
+ <id>sys0node0pmic21</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x0036000B</default>
+ <default>0x00360015</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -10050,7 +17163,7 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p11</default>
+ <default>pmic:k0:n0:s0:p21</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -10065,11 +17178,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>11</default>
+ <default>21</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-1</default>
+ <default>physical:sys-0/node-0/pmic-21</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -10078,11 +17191,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic12</id>
+ <id>sys0node0pmic24</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x0036000C</default>
+ <default>0x00360018</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -10090,7 +17203,11 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p12</default>
+ <default>pmic:k0:n0:s0:p24</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>24</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -10105,11 +17222,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>12</default>
+ <default>24</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-0</default>
+ <default>physical:sys-0/node-0/pmic-24</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -10118,11 +17235,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic13</id>
+ <id>sys0node0pmic25</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x0036000D</default>
+ <default>0x00360019</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -10130,7 +17247,7 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p13</default>
+ <default>pmic:k0:n0:s0:p25</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -10145,11 +17262,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>13</default>
+ <default>25</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-1</default>
+ <default>physical:sys-0/node-0/pmic-25</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -10158,11 +17275,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic14</id>
+ <id>sys0node0pmic28</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x0036000E</default>
+ <default>0x0036001C</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -10170,7 +17287,11 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p14</default>
+ <default>pmic:k0:n0:s0:p28</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>28</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -10185,11 +17306,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>14</default>
+ <default>28</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-0</default>
+ <default>physical:sys-0/node-0/pmic-28</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -10198,11 +17319,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic15</id>
+ <id>sys0node0pmic29</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x0036000F</default>
+ <default>0x0036001D</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -10210,7 +17331,7 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p15</default>
+ <default>pmic:k0:n0:s0:p29</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -10225,11 +17346,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>15</default>
+ <default>29</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-1</default>
+ <default>physical:sys-0/node-0/pmic-29</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -10238,11 +17359,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic16</id>
+ <id>sys0node0pmic32</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x00360010</default>
+ <default>0x00360020</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -10250,7 +17371,11 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p16</default>
+ <default>pmic:k0:n0:s0:p32</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>32</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -10265,11 +17390,11 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>16</default>
+ <default>32</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-0</default>
+ <default>physical:sys-0/node-0/pmic-32</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -10278,11 +17403,11 @@
</targetInstance>
<targetInstance>
- <id>sys0node0pmic17</id>
+ <id>sys0node0pmic33</id>
<type>pmic</type>
<attribute>
<id>HUID</id>
- <default>0x00360011</default>
+ <default>0x00360021</default>
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
@@ -10290,7 +17415,11 @@
</attribute>
<attribute>
<id>FAPI_NAME</id>
- <default>pmic:k0:n0:s0:p17</default>
+ <default>pmic:k0:n0:s0:p33</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>33</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
@@ -10305,11 +17434,783 @@
</attribute>
<attribute>
<id>ORDINAL_ID</id>
- <default>17</default>
+ <default>33</default>
</attribute>
<attribute>
<id>PHYS_PATH</id>
- <default>physical:sys-0/node-0/pmic-1</default>
+ <default>physical:sys-0/node-0/pmic-33</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic34</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00360022</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0/omi-0/ocmb_chip-0/pmic-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p34</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>34</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0x90</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x08</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>34</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-34</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic35</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00360023</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0/omi-0/ocmb_chip-0/pmic-1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p35</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>35</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0xC0</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x08</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>35</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-35</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic38</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00360026</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0/omi-1/ocmb_chip-0/pmic-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p38</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>38</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0x90</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x09</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>38</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-38</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic39</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00360027</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0/omi-1/ocmb_chip-0/pmic-1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p39</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>39</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0xC0</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x09</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>39</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-39</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic42</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0036002A</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1/omi-0/ocmb_chip-0/pmic-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p42</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>42</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0x90</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x0A</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>42</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-42</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic43</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0036002B</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1/omi-0/ocmb_chip-0/pmic-1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p43</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>43</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0xC0</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x0A</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>43</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-43</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic46</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0036002E</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1/omi-1/ocmb_chip-0/pmic-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p46</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>46</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0x90</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x0B</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>46</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-46</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic47</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0036002F</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1/omi-1/ocmb_chip-0/pmic-1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p47</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>47</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0xC0</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x0B</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>47</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-47</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic48</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00360032</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0/omi-0/ocmb_chip-0/pmic-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p48</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0x90</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x0C</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>48</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-48</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic51</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00360033</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0/omi-0/ocmb_chip-0/pmic-1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p51</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>51</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0xC0</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x0C</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>51</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-51</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic54</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00360036</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0/omi-1/ocmb_chip-0/pmic-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p54</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0x90</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x0D</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>54</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-54</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic55</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00360037</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0/omi-1/ocmb_chip-0/pmic-1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p55</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0xC0</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x0D</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>55</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-55</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic58</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0036003A</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1/omi-0/ocmb_chip-0/pmic-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p58</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>58</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0x90</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x0E</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>58</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-58</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic59</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0036003B</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1/omi-0/ocmb_chip-0/pmic-1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p59</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0xC0</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x0E</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>59</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-59</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic62</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0036003E</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1/omi-1/ocmb_chip-0/pmic-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p62</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>62</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0x90</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x0F</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>62</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-62</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic63</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x0036003F</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1/omi-1/ocmb_chip-0/pmic-1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p63</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>0</value></field>
+ <field><id>devAddr</id><value>0xC0</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x0F</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>63</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-63</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic66</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00360042</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0/mcc-0/omi-0/ocmb_chip-0/pmic-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p66</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>66</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0x90</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>66</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-66</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0pmic67</id>
+ <type>pmic</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x00360043</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0/mcc-0/omi-0/ocmb_chip-0/pmic-1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pmic:k0:n0:s0:p67</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>67</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0xC0</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>67</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/pmic-67</default>
</attribute>
<attribute>
<id>REL_POS</id>
@@ -10720,12 +18621,412 @@
</attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0ocmb16memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C0010</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-16/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0/omi-0/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c00</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb17memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C0011</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-17/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0/omi-1/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c01</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb18memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C0012</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-18/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1/omi-0/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c02</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb19memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C0013</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-19/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1/omi-1/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c03</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb20memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C0014</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-20/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0/omi-0/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c04</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb21memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C0015</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-21/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0/omi-1/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c05</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb22memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C0016</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-22/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1/omi-0/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c06</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb23memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C0017</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-23/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1/omi-1/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c07</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb24memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C0018</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-24/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0/mcc-0/omi-0/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c08</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb25memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C0019</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-25/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0/mcc-0/omi-1/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c09</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb26memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C001A</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-26/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0/mcc-1/omi-0/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c10</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb27memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C001B</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-27/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0/mcc-1/omi-1/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c11</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb28memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C001C</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-28/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-1/mcc-0/omi-0/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c12</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb29memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C001D</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-29/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-1/mcc-0/omi-1/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c13</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb30memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C001E</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-30/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-1/mcc-1/omi-0/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c14</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0ocmb31memport0</id>
+ <type>unit-mem_port</type>
+ <attribute><id>HUID</id><default>0x004C001F</default></attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/ocmb_chip-31/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-1/mcc-1/omi-1/ocmb_chip-0/mem_port-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>ocmb.mp:k0:n0:s0:p01:c15</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+</targetInstance>
+
<!-- ===================================================================== -->
<!-- DIMM Units -->
<!-- ===================================================================== -->
<targetInstance>
<id>sys0node0dimm0</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x00030000</default></attribute>
<attribute><id>POSITION</id><default>0</default></attribute>
<attribute>
@@ -10758,25 +19059,25 @@
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>engine</id><value>3</value></field>
<field><id>byteAddrOffset</id><value>0x02</value></field>
- <field><id>chipCount</id><value>0x01</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
- <field><id>engine</id><value>3</value></field>
- <!-- Engine 3 Port 1 is directly attached to DDIMM0 in the simics axone model -->
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
<field><id>port</id><value>1</value></field>
- <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
- <field><id>writeCycleTime</id><value>20</value></field>
- <field><id>writePageSize</id><value>32</value></field>
- <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
- <field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x00</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
</targetInstance>
<targetInstance>
<id>sys0node0dimm1</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x00030001</default></attribute>
<attribute><id>POSITION</id><default>1</default></attribute>
<attribute>
@@ -10814,13 +19115,12 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x08</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x01</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -10828,7 +19128,7 @@
<targetInstance>
<id>sys0node0dimm2</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x00030002</default></attribute>
<attribute><id>POSITION</id><default>2</default></attribute>
<attribute>
@@ -10866,13 +19166,12 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x09</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x02</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -10880,7 +19179,7 @@
<targetInstance>
<id>sys0node0dimm3</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x00030003</default></attribute>
<attribute><id>POSITION</id><default>3</default></attribute>
<attribute>
@@ -10918,13 +19217,12 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x0A</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x03</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -10932,7 +19230,7 @@
<targetInstance>
<id>sys0node0dimm4</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x00030004</default></attribute>
<attribute><id>POSITION</id><default>4</default></attribute>
<attribute>
@@ -10970,13 +19268,12 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x0B</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x04</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -10984,7 +19281,7 @@
<targetInstance>
<id>sys0node0dimm5</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x00030005</default></attribute>
<attribute><id>POSITION</id><default>5</default></attribute>
<attribute>
@@ -11022,13 +19319,12 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x0C</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x05</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -11036,7 +19332,7 @@
<targetInstance>
<id>sys0node0dimm6</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x00030006</default></attribute>
<attribute><id>POSITION</id><default>6</default></attribute>
<attribute>
@@ -11074,13 +19370,12 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x0D</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x06</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -11088,7 +19383,7 @@
<targetInstance>
<id>sys0node0dimm7</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x00030007</default></attribute>
<attribute><id>POSITION</id><default>7</default></attribute>
<attribute>
@@ -11126,13 +19421,12 @@
<field><id>byteAddrOffset</id><value>0x02</value></field>
<field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
- <field><id>port</id><value>0</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
<field><id>writeCycleTime</id><value>05</value></field>
<field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x0E</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x07</value></field>
<field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
</default>
</attribute>
@@ -11140,7 +19434,7 @@
<targetInstance>
<id>sys0node0dimm8</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x00030008</default></attribute>
<attribute><id>POSITION</id><default>8</default></attribute>
<attribute>
@@ -11173,26 +19467,25 @@
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
- <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
- <field><id>engine</id><value>3</value></field>
<field><id>byteAddrOffset</id><value>0x02</value></field>
- <field><id>devAddr</id><value>0xA0</value></field>
<field><id>chipCount</id><value>0x01</value></field>
- <!-- Engine 3 Port 0 connects to a 3 to 8 MUX attached to DDIMM1-8 in the simics axone model -->
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <!-- Engine 3 Port 0 is directly attached to DDIMM8 in the simics axone model -->
<field><id>port</id><value>0</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
- <field><id>writeCycleTime</id><value>05</value></field>
- <field><id>writePageSize</id><value>0x20</value></field>
- <!-- Valid Mux Bus Selections are 0x08-0x0F -->
- <field><id>i2cMuxBusSelector</id><value>0x0F</value></field>
- <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-0</value></field>
+ <field><id>writeCycleTime</id><value>20</value></field>
+ <field><id>writePageSize</id><value>32</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
</default>
</attribute>
</targetInstance>
<targetInstance>
<id>sys0node0dimm9</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x00030009</default></attribute>
<attribute><id>POSITION</id><default>9</default></attribute>
<attribute>
@@ -11223,22 +19516,29 @@
<default>9</default>
</attribute>
<!-- Note that EEPROM_VPD_PRIMARY_INFO attrs for OCMB 9-15 and DIMM 9-15
- are invalid. The port value is invalid, info is just here to fully test
- the EEPROM caching code (DIMM X should match OCMB X) -->
+ are invalid. The engine value is set to be engine 1 (C) which has 12
+ valid ports according to the simics axone model. Only the first 4 ports
+ are actually used so we will use 5-12 as dummy ports for the unused dimm targets.
+ We cannot use the ports on engine 3 (E) becuase simics only has 2 ports marked as valid-->
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
<field><id>devAddr</id><value>0xA0</value></field>
- <field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>2</value></field>
+ <field><id>engine</id><value>1</value></field>
+ <field><id>port</id><value>5</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
</default>
</attribute>
</targetInstance>
<targetInstance>
<id>sys0node0dimm10</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x0003000A</default></attribute>
<attribute><id>POSITION</id><default>10</default></attribute>
<attribute>
@@ -11269,22 +19569,29 @@
<default>10</default>
</attribute>
<!-- Note that EEPROM_VPD_PRIMARY_INFO attrs for OCMB 9-15 and DIMM 9-15
- are invalid. The port value is invalid, info is just here to fully test
- the EEPROM caching code (DIMM X should match OCMB X) -->
+ are invalid. The engine value is set to be engine 1 (C) which has 12
+ valid ports according to the simics axone model. Only the first 4 ports
+ are actually used so we will use 5-12 as dummy ports for the unused dimm targets.
+ We cannot use the ports on engine 3 (E) becuase simics only has 2 ports marked as valid-->
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
<field><id>devAddr</id><value>0xA0</value></field>
- <field><id>engine</id><value>3</value></field>
- <field><id>port</id><value>3</value></field>
+ <field><id>engine</id><value>1</value></field>
+ <field><id>port</id><value>6</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
</default>
</attribute>
</targetInstance>
<targetInstance>
<id>sys0node0dimm11</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x0003000B</default></attribute>
<attribute><id>POSITION</id><default>11</default></attribute>
<attribute>
@@ -11315,22 +19622,27 @@
<default>11</default>
</attribute>
<!-- Note that EEPROM_VPD_PRIMARY_INFO attrs for OCMB 9-15 and DIMM 9-15
- are invalid. The port value is invalid, info is just here to fully test
+ are invalid. The port and devAddr values are invalid, info is just here to fully test
the EEPROM caching code (DIMM X should match OCMB X) -->
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
- <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>devAddr</id><value>0xA4</value></field>
<field><id>engine</id><value>3</value></field>
<field><id>port</id><value>4</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
</default>
</attribute>
</targetInstance>
<targetInstance>
<id>sys0node0dimm12</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x0003000C</default></attribute>
<attribute><id>POSITION</id><default>12</default></attribute>
<attribute>
@@ -11361,22 +19673,27 @@
<default>12</default>
</attribute>
<!-- Note that EEPROM_VPD_PRIMARY_INFO attrs for OCMB 9-15 and DIMM 9-15
- are invalid. The port value is invalid, info is just here to fully test
+ are invalid. The port and devAddr values are invalid, info is just here to fully test
the EEPROM caching code (DIMM X should match OCMB X) -->
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
- <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>devAddr</id><value>0xA5</value></field>
<field><id>engine</id><value>3</value></field>
<field><id>port</id><value>5</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
</default>
</attribute>
</targetInstance>
<targetInstance>
<id>sys0node0dimm13</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x0003000D</default></attribute>
<attribute><id>POSITION</id><default>13</default></attribute>
<attribute>
@@ -11407,22 +19724,27 @@
<default>13</default>
</attribute>
<!-- Note that EEPROM_VPD_PRIMARY_INFO attrs for OCMB 9-15 and DIMM 9-15
- are invalid. The port value is invalid, info is just here to fully test
+ are invalid. The port and devAddr values are invalid, info is just here to fully test
the EEPROM caching code (DIMM X should match OCMB X) -->
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
- <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>devAddr</id><value>0xA6</value></field>
<field><id>engine</id><value>3</value></field>
<field><id>port</id><value>6</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
</default>
</attribute>
</targetInstance>
<targetInstance>
<id>sys0node0dimm14</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x0003000E</default></attribute>
<attribute><id>POSITION</id><default>14</default></attribute>
<attribute>
@@ -11453,22 +19775,27 @@
<default>14</default>
</attribute>
<!-- Note that EEPROM_VPD_PRIMARY_INFO attrs for OCMB 9-15 and DIMM 9-15
- are invalid. The port value is invalid, info is just here to fully test
+ are invalid. The port and devAddr values are invalid, info is just here to fully test
the EEPROM caching code (DIMM X should match OCMB X) -->
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
- <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>devAddr</id><value>0xA7</value></field>
<field><id>engine</id><value>3</value></field>
<field><id>port</id><value>7</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
</default>
</attribute>
</targetInstance>
<targetInstance>
<id>sys0node0dimm15</id>
- <type>lcard-dimm-jedec</type>
+ <type>lcard-dimm-ddimm</type>
<attribute><id>HUID</id><default>0x0003000F</default></attribute>
<attribute><id>POSITION</id><default>15</default></attribute>
<attribute>
@@ -11499,15 +19826,479 @@
<default>15</default>
</attribute>
<!-- Note that EEPROM_VPD_PRIMARY_INFO attrs for OCMB 9-15 and DIMM 9-15
- are invalid. The port value is invalid, info is just here to fully test
+ are invalid. The port and devAddr values are invalid, info is just here to fully test
the EEPROM caching code (DIMM X should match OCMB X) -->
<attribute>
<id>EEPROM_VPD_PRIMARY_INFO</id>
<default>
- <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>devAddr</id><value>0xA8</value></field>
<field><id>engine</id><value>3</value></field>
<field><id>port</id><value>8</value></field>
<field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0dimm16</id>
+ <type>lcard-dimm-ddimm</type>
+ <attribute><id>HUID</id><default>0x00030010</default></attribute>
+ <attribute><id>POSITION</id><default>16</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>dimm:k0:n0:s0:p16</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/dimm-16</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0/omi-0/ocmb_chip-0/mem_port-0/dimm-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x00</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0dimm17</id>
+ <type>lcard-dimm-ddimm</type>
+ <attribute><id>HUID</id><default>0x00030011</default></attribute>
+ <attribute><id>POSITION</id><default>17</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>dimm:k0:n0:s0:p17</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/dimm-17</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-0/omi-1/ocmb_chip-0/mem_port-0/dimm-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>17</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>17</default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x01</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0dimm18</id>
+ <type>lcard-dimm-ddimm</type>
+ <attribute><id>HUID</id><default>0x00030012</default></attribute>
+ <attribute><id>POSITION</id><default>18</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>dimm:k0:n0:s0:p18</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/dimm-18</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1/omi-0/ocmb_chip-0/mem_port-0/dimm-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x02</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0dimm19</id>
+ <type>lcard-dimm-ddimm</type>
+ <attribute><id>HUID</id><default>0x00030013</default></attribute>
+ <attribute><id>POSITION</id><default>19</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>dimm:k0:n0:s0:p19</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/dimm-19</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-0/mcc-1/omi-1/ocmb_chip-0/mem_port-0/dimm-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x03</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0dimm20</id>
+ <type>lcard-dimm-ddimm</type>
+ <attribute><id>HUID</id><default>0x00030014</default></attribute>
+ <attribute><id>POSITION</id><default>20</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>dimm:k0:n0:s0:p20</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/dimm-20</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0/omi-0/ocmb_chip-0/mem_port-0/dimm-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x04</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0dimm21</id>
+ <type>lcard-dimm-ddimm</type>
+ <attribute><id>HUID</id><default>0x00030015</default></attribute>
+ <attribute><id>POSITION</id><default>21</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>dimm:k0:n0:s0:p21</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/dimm-21</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-0/omi-1/ocmb_chip-0/mem_port-0/dimm-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x05</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0dimm22</id>
+ <type>lcard-dimm-ddimm</type>
+ <attribute><id>HUID</id><default>0x00030016</default></attribute>
+ <attribute><id>POSITION</id><default>22</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>dimm:k0:n0:s0:p22</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/dimm-22</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1/omi-0/ocmb_chip-0/mem_port-0/dimm-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>22</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x06</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0dimm23</id>
+ <type>lcard-dimm-ddimm</type>
+ <attribute><id>HUID</id><default>0x00030017</default></attribute>
+ <attribute><id>POSITION</id><default>23</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>dimm:k0:n0:s0:p23</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/dimm-23</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/mi-1/mcc-1/omi-1/ocmb_chip-0/mem_port-0/dimm-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>23</default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <!-- Engine 3 Port 1 connects to a 3 to 8 MUX attached to DDIMM0-7 in the simics axone model -->
+ <field><id>port</id><value>1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>05</value></field>
+ <field><id>writePageSize</id><value>0x20</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0x07</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0/node-0/i2c_mux-2</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0dimm24</id>
+ <type>lcard-dimm-ddimm</type>
+ <attribute><id>HUID</id><default>0x00030018</default></attribute>
+ <attribute><id>POSITION</id><default>24</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>dimm:k0:n0:s0:p24</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/dimm-24</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>24</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/mi-0/mcc-0/omi-0/ocmb_chip-0/mem_port-0/dimm-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>24</default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ <default>24</default>
+ </attribute>
+ <attribute>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ <default>
+ <field><id>byteAddrOffset</id><value>0x02</value></field>
+ <field><id>chipCount</id><value>0x01</value></field>
+ <field><id>devAddr</id><value>0xA0</value></field>
+ <field><id>engine</id><value>3</value></field>
+ <!-- Engine 3 Port 0 is directly attached to DDIMM8 in the simics axone model -->
+ <field><id>port</id><value>0</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
+ <field><id>maxMemorySizeKB</id><value>0x4</value></field>
+ <field><id>writeCycleTime</id><value>20</value></field>
+ <field><id>writePageSize</id><value>32</value></field>
+ <field><id>i2cMuxBusSelector</id><value>0xFF</value></field>
+ <field><id>i2cMuxPath</id><value>physical:sys-0</value></field>
</default>
</attribute>
</targetInstance>
@@ -11887,6 +20678,378 @@
</attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1mc0omic0</id>
+ <type>unit-omic-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/omic-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omic:k0:n0:s0:p01:c0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x004A0006</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/omic-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMIC</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc0omic1</id>
+ <type>unit-omic-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/omic-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omic:k0:n0:s0:p01:c1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x004A0007</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/omic-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMIC</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc0omic2</id>
+ <type>unit-omic-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-0/omic-2</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x07</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omic:k0:n0:s0:p01:c2</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>8</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x004A0008</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>8</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-0/omic-2</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMIC</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1omic0</id>
+ <type>unit-omic-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/omic-0</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omic:k0:n0:s0:p01:c3</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>9</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x004A0009</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>9</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/omic-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMIC</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1omic1</id>
+ <type>unit-omic-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/omic-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omic:k0:n0:s0:p01:c4</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x004A000A</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/omic-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMIC</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1mc1omic2</id>
+ <type>unit-omic-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/mc-1/omic-2</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x08</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.omic:k0:n0:s0:p01:c5</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x004A000B</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/mc-1/omic-2</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>OMIC</default>
+ </attribute>
+</targetInstance>
+
<!-- ===================================================================== -->
<!-- END MEMORY SUBSYSTEM -->
<!-- ===================================================================== -->
@@ -12417,6 +21580,122 @@
</targetInstance>
<targetInstance>
+ <id>sys0node0proc0perv10</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/perv-10</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p00:c10</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C000A</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/perv-10</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0perv11</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/perv-11</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p00:c11</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C000B</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/perv-11</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
<id>sys0node0proc0perv12</id>
<type>unit-perv-axone</type>
<attribute>
@@ -14396,6 +23675,2450 @@
</attribute>
</targetInstance>
+<targetInstance>
+ <id>sys0node0proc1perv1</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-1</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c1</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>57</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0039</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>57</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-1</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>1</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv2</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-2</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c2</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>58</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C003A</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>58</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-2</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv3</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-3</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c3</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>59</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C003B</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>59</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-3</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv4</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-4</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c4</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>60</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C003C</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>60</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-4</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>4</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv5</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-5</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c5</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>61</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C003D</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>61</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-5</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv6</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-6</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c6</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>62</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C003E</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>62</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-6</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>6</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv7</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c7</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>63</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C003F</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>63</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-7</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>7</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv8</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>8</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>8</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c8</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>64</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0040</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>64</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-8</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>8</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv9</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-9</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>9</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>9</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c9</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>65</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0041</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>65</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-9</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>9</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv10</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-10</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c10</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>66</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0042</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>66</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-10</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv11</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-11</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c11</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>67</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0043</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>67</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-11</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv12</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-12</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>12</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>12</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c12</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>68</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0044</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>68</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-12</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>12</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv13</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-13</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>13</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>13</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c13</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>69</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0045</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>69</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-13</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>13</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv14</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-14</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>14</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>14</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c14</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>70</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0046</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>70</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-14</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>14</default>
+ </attribute>
+ <attribute>
+ <id>RESOURCE_IS_CRITICAL</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv15</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-15</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>15</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>15</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c15</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>71</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0047</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>71</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-15</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>15</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv16</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-16</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c16</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>72</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0048</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>72</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-16</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>16</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv17</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-17</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>17</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>17</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c17</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>73</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0049</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>73</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-17</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>17</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv18</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-18</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c18</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>74</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C004A</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>74</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-18</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>18</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv19</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-19</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c19</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>75</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C004B</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>75</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-19</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>19</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv20</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-20</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c20</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>76</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C004C</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>76</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-20</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>20</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv21</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-21</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c21</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>77</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C004D</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>77</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-21</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>21</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv32</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-32</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>32</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>32</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c32</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>88</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0058</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>88</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-32</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>32</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv33</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-33</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>33</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>33</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c33</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>89</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0059</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>69</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-33</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>33</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv34</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-34</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>34</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>34</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c34</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>90</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C005A</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>90</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-34</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>34</default>
+ </attribute>
+ <attribute>
+ <id>RESOURCE_IS_CRITICAL</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv35</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-35</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>35</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>35</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c35</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>91</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C005B</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>91</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-35</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>35</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv36</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-36</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>36</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>36</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c36</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>92</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C005C</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>92</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-36</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>36</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv37</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-37</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>37</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>37</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c37</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>93</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C005D</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>93</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-37</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>37</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv38</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-38</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>38</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>38</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c38</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>94</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C005E</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>94</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-38</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>38</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv39</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-39</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>39</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>39</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c39</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>95</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C005F</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>85</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-39</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>39</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv40</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-40</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>40</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>40</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c40</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>96</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0060</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>96</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-40</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>40</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv41</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-41</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>41</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>41</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c41</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>97</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0061</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>97</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-41</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>41</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv42</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-42</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>42</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>42</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c42</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>98</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0062</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>98</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-42</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>42</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv43</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-43</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>43</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>43</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c43</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>99</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0063</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>99</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-43</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>43</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv44</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-44</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>44</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>44</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c44</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>100</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0064</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>100</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-44</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>44</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv45</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-45</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>45</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>45</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c45</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>101</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0065</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>101</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-45</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>45</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv46</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-46</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>46</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>46</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c46</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>102</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0066</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>102</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-46</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>46</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv47</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-47</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>47</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>47</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c47</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>103</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0067</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>103</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-47</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>47</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv48</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-48</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>48</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>48</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c48</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>104</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0068</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>104</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-48</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>48</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv49</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-49</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>49</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>49</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c49</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>105</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C0069</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>105</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-49</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>49</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv50</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-50</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>50</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>50</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c50</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>106</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C006A</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>106</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-50</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>50</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv51</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-51</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>51</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>51</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c51</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>107</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C006B</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>107</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-51</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>51</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1perv52</id>
+ <type>unit-perv-axone</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/perv-52</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>52</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>52</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p01:c52</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>108</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C006B</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>108</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/perv-52</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>52</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
<!-- ===================================================================== -->
<!-- I2C_MUX -->
<!-- ===================================================================== -->
@@ -14428,13 +26151,48 @@
<default>0</default>
</attribute>
<attribute>
- <id>FAPI_NAME</id>
- <default>NA</default>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <default>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>port</id><value>1</value></field>
+ <field><id>devAddr</id><value>0xE0</value></field>
+ <field><id>engine</id><value>3</value></field>
+ </default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0i2cmux2</id>
+ <type>i2c_mux_pca9847</type>
+ <attribute>
+ <id>HUID</id>
+ <default>0x004D0002</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/i2c_mux-2</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/i2c_mux-0</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>0</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>0</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>2</default>
</attribute>
<attribute>
<id>FAPI_I2C_CONTROL_INFO</id>
<default>
- <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-0</value></field>
+ <field><id>i2cMasterPath</id><value>physical:sys-0/node-0/proc-1</value></field>
<field><id>port</id><value>1</value></field>
<field><id>devAddr</id><value>0xE0</value></field>
<field><id>engine</id><value>3</value></field>
@@ -14442,4 +26200,97 @@
</attribute>
</targetInstance>
+<!-- ===================================================================== -->
+<!-- XBUS -->
+<!-- ===================================================================== -->
+<targetInstance>
+ <id>sys0node0proc0xbus2</id>
+ <type>unit-xbus-axone</type>
+ <attribute><id>HUID</id><default>0x000E0002</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.xbus:k0:n0:s0:p00:c2</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/xbus-2</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/xbus-2</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>2</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x06</default>
+ </attribute>
+ <attribute>
+ <id>PEER_TARGET</id>
+ <default>physical:sys-0/node-0/proc-1/xbus-0</default>
+ </attribute>
+ <attribute>
+ <id>PEER_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/xbus-0</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-0/perv-6</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc1xbus0</id>
+ <type>unit-xbus-axone</type>
+ <attribute><id>HUID</id><default>0x000E0003</default></attribute>
+ <attribute>
+ <id>FAPI_NAME</id><default>pu.xbus:k0:n0:s0:p01:c0</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-1/xbus-0</default>
+ </attribute>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-1/xbus-0</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>3</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>0x06</default>
+ </attribute>
+ <attribute>
+ <id>PEER_TARGET</id>
+ <default>physical:sys-0/node-0/proc-0/xbus-2</default>
+ </attribute>
+ <attribute>
+ <id>PEER_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/xbus-2</default>
+ </attribute>
+ <attribute>
+ <id>PARENT_PERVASIVE</id>
+ <default>physical:sys-0/node-0/proc-1/perv-6</default>
+ </attribute>
+</targetInstance>
+
</attributes>
diff --git a/src/usr/targeting/common/xmltohb/simics_CUMULUS.system.xml b/src/usr/targeting/common/xmltohb/simics_CUMULUS.system.xml
index e82b9e38a..17aee231d 100644
--- a/src/usr/targeting/common/xmltohb/simics_CUMULUS.system.xml
+++ b/src/usr/targeting/common/xmltohb/simics_CUMULUS.system.xml
@@ -7958,7 +7958,7 @@
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
- <default>physical:sys-0/node-0/proc-0/nx-0</default>
+ <default>affinity:sys-0/node-0/proc-0/nx-0</default>
</attribute>
<attribute>
<id>ORDINAL_ID</id>
@@ -8955,6 +8955,138 @@
<default>PERV</default>
</attribute>
</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0perv10</id>
+ <type>unit-perv-cumulus</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/perv-10</default>
+ </attribute>
+
+
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p00:c10</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C000A</default>
+ </attribute>
+
+
+
+
+
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/perv-10</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>RESOURCE_IS_CRITICAL</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0perv11</id>
+ <type>unit-perv-cumulus</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/perv-11</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p00:c11</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C000B</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/perv-11</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>RESOURCE_IS_CRITICAL</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
<targetInstance>
<id>sys0node0proc0perv12</id>
<type>unit-perv-cumulus</type>
diff --git a/src/usr/targeting/common/xmltohb/simics_CUMULUS_CDIMM.system.xml b/src/usr/targeting/common/xmltohb/simics_CUMULUS_CDIMM.system.xml
index fe3bea78c..6e0177ea2 100644
--- a/src/usr/targeting/common/xmltohb/simics_CUMULUS_CDIMM.system.xml
+++ b/src/usr/targeting/common/xmltohb/simics_CUMULUS_CDIMM.system.xml
@@ -7950,7 +7950,7 @@
</attribute>
<attribute>
<id>AFFINITY_PATH</id>
- <default>physical:sys-0/node-0/proc-0/nx-0</default>
+ <default>affinity:sys-0/node-0/proc-0/nx-0</default>
</attribute>
<attribute>
<id>ORDINAL_ID</id>
@@ -8947,6 +8947,134 @@
<default>PERV</default>
</attribute>
</targetInstance>
+
+
+<targetInstance>
+ <id>sys0node0proc0perv10</id>
+ <type>unit-perv-cumulus</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/perv-10</default>
+ </attribute>
+
+
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p00:c10</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C000A</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/perv-10</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>10</default>
+ </attribute>
+ <attribute>
+ <id>RESOURCE_IS_CRITICAL</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
+<targetInstance>
+ <id>sys0node0proc0perv11</id>
+ <type>unit-perv-cumulus</type>
+ <attribute>
+ <id>AFFINITY_PATH</id>
+ <default>affinity:sys-0/node-0/proc-0/perv-11</default>
+ </attribute>
+ <attribute>
+ <id>CHIP_UNIT</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>CHIPLET_ID</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>CLASS</id>
+ <default>UNIT</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_NAME</id>
+ <default>pu.perv:k0:n0:s0:p00:c11</default>
+ </attribute>
+ <attribute>
+ <id>FAPI_POS</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>HUID</id>
+ <default>0x002C000B</default>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>PHYS_PATH</id>
+ <default>physical:sys-0/node-0/proc-0/perv-11</default>
+ </attribute>
+ <attribute>
+ <id>PRIMARY_CAPABILITIES</id>
+ <default>
+ <field><id>reserved</id><value>0</value></field>
+ <field><id>supportsFsiScom</id><value>1</value></field>
+ <field><id>supportsInbandScom</id><value>0</value></field>
+ <field><id>supportsXscom</id><value>1</value></field>
+ </default>
+ </attribute>
+ <attribute>
+ <id>REL_POS</id>
+ <default>11</default>
+ </attribute>
+ <attribute>
+ <id>RESOURCE_IS_CRITICAL</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
+ <id>TYPE</id>
+ <default>PERV</default>
+ </attribute>
+</targetInstance>
+
<targetInstance>
<id>sys0node0proc0perv12</id>
<type>unit-perv-cumulus</type>
diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml
index 1b5b615a9..f87b8fa6e 100644
--- a/src/usr/targeting/common/xmltohb/target_types.xml
+++ b/src/usr/targeting/common/xmltohb/target_types.xml
@@ -159,6 +159,13 @@
<parent>chip-tpm-cectpm</parent>
</targetType>
+ <!-- This special I2C_MUX target adapts the MRW to Hostboot's specific I2C_MUX
+ target. All attributes should be declared against the parent target -->
+ <targetType>
+ <id>chip-PCA9847</id>
+ <parent>i2c_mux_pca9847</parent>
+ </targetType>
+
<!-- This special UCD target adapts the MRW to Hostboot's specific UCD
target. All attributes should be declared against the parent
target. -->
@@ -404,7 +411,7 @@
</attribute>
</targetType>
- <!-- Generic OCMB -->
+ <!-- Generic OCMB, used for Explorer, Gemini, etc -->
<targetType>
<id>chip-ocmb</id>
<parent>chip</parent>
@@ -413,6 +420,60 @@
<id>DECONFIG_GARDABLE</id>
</attribute>
<attribute>
+ <default>
+ <field>
+ <value>0xFF</value>
+ <id>byteAddrOffset</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>chipCount</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>devAddr</id>
+ </field>
+ <field>
+ <!--Since enum values cannot be used as default values in
+ a complexType, this is a workaround to set the value to the
+ corresponding enum value.-->
+ <!--value>DDIMM</value-->
+ <value>0x4</value>
+ <id>eepromContentType</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>engine</id>
+ </field>
+ <field>
+ <value>physical:sys-0</value>
+ <id>i2cMasterPath</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>i2cMuxBusSelector</id>
+ </field>
+ <field>
+ <value>physical:sys-0</value>
+ <id>i2cMuxPath</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>maxMemorySizeKB</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>port</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>writeCycleTime</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>writePageSize</id>
+ </field>
+ </default>
<id>EEPROM_VPD_PRIMARY_INFO</id>
</attribute>
<attribute>
@@ -426,6 +487,10 @@
<id>HWAS_STATE_CHANGED_SUBSCRIPTION_MASK</id>
</attribute>
<attribute>
+ <default>OCMB</default>
+ <id>MODEL</id>
+ </attribute>
+ <attribute>
<default>
<field>
<id>childRollupAllowed</id>
@@ -443,23 +508,6 @@
<id>PARENT_DECONFIG_RULES</id>
</attribute>
<attribute>
- <default>OCMB_CHIP</default>
- <id>TYPE</id>
- </attribute>
- <attribute>
- <id>VPD_REC_NUM</id>
- </attribute>
- </targetType>
-
- <!-- Explorer OCMB -->
- <targetType>
- <id>chip-ocmb-explorer</id>
- <parent>chip-ocmb</parent>
- <attribute>
- <default>EXPLORER</default>
- <id>MODEL</id>
- </attribute>
- <attribute>
<default>
<field>
<id>reserved</id>
@@ -509,6 +557,13 @@
</default>
<id>SCOM_SWITCHES</id>
</attribute>
+ <attribute>
+ <default>OCMB_CHIP</default>
+ <id>TYPE</id>
+ </attribute>
+ <attribute>
+ <id>VPD_REC_NUM</id>
+ </attribute>
</targetType>
<targetType>
@@ -601,9 +656,6 @@
<id>LOCATION_CODE</id>
</attribute>
<attribute>
- <id>NVDIMM_ARMED</id>
- </attribute>
- <attribute>
<default>
<field>
<id>childRollupAllowed</id>
@@ -753,9 +805,117 @@
<id>EEPROM_SBE_PRIMARY_INFO</id>
</attribute>
<attribute>
+ <default>
+ <field>
+ <value>0xFF</value>
+ <id>byteAddrOffset</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>chipCount</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>devAddr</id>
+ </field>
+ <field>
+ <!--Since enum values cannot be used as default values in
+ a complexType, this is a workaround to set the value to the
+ corresponding enum value.-->
+ <!--value>IBM_MVPD</value-->
+ <value>0x3</value>
+ <id>eepromContentType</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>engine</id>
+ </field>
+ <field>
+ <value>physical:sys-0</value>
+ <id>i2cMasterPath</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>i2cMuxBusSelector</id>
+ </field>
+ <field>
+ <value>physical:sys-0</value>
+ <id>i2cMuxPath</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>maxMemorySizeKB</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>port</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>writeCycleTime</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>writePageSize</id>
+ </field>
+ </default>
<id>EEPROM_VPD_BACKUP_INFO</id>
</attribute>
<attribute>
+ <default>
+ <field>
+ <value>0xFF</value>
+ <id>byteAddrOffset</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>chipCount</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>devAddr</id>
+ </field>
+ <field>
+ <!--Since enum values cannot be used as default values in
+ a complexType, this is a workaround to set the value to the
+ corresponding enum value.-->
+ <!--value>IBM_MVPD</value-->
+ <value>0x3</value>
+ <id>eepromContentType</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>engine</id>
+ </field>
+ <field>
+ <value>physical:sys-0</value>
+ <id>i2cMasterPath</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>i2cMuxBusSelector</id>
+ </field>
+ <field>
+ <value>physical:sys-0</value>
+ <id>i2cMuxPath</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>maxMemorySizeKB</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>port</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>writeCycleTime</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>writePageSize</id>
+ </field>
+ </default>
<id>EEPROM_VPD_PRIMARY_INFO</id>
</attribute>
<attribute>
@@ -990,6 +1150,60 @@
<id>DECONFIG_GARDABLE</id>
</attribute>
<attribute>
+ <default>
+ <field>
+ <value>0xFF</value>
+ <id>byteAddrOffset</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>chipCount</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>devAddr</id>
+ </field>
+ <field>
+ <!--Since enum values cannot be used as default values in
+ a complexType, this is a workaround to set the value to the
+ corresponding enum value.-->
+ <!--value>IBM_FRUVPD</value-->
+ <value>0x2</value>
+ <id>eepromContentType</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>engine</id>
+ </field>
+ <field>
+ <value>physical:sys-0</value>
+ <id>i2cMasterPath</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>i2cMuxBusSelector</id>
+ </field>
+ <field>
+ <value>physical:sys-0</value>
+ <id>i2cMuxPath</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>maxMemorySizeKB</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>port</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>writeCycleTime</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>writePageSize</id>
+ </field>
+ </default>
<id>EEPROM_VPD_PRIMARY_INFO</id>
</attribute>
<attribute>
@@ -1153,6 +1367,7 @@
</attribute>
</targetType>
+ <!-- Represents a I2C Mux device that is compatible with the PCA9847 spec -->
<targetType>
<id>i2c_mux_pca9847</id>
<parent>chip</parent>
@@ -1205,6 +1420,60 @@
<id>EEPROM_NV_INFO</id>
</attribute>
<attribute>
+ <default>
+ <field>
+ <value>0xFF</value>
+ <id>byteAddrOffset</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>chipCount</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>devAddr</id>
+ </field>
+ <field>
+ <!--Since enum values cannot be used as default values in
+ a complexType, this is a workaround to set the value to the
+ corresponding enum value.-->
+ <!--value>ISDIMM</value-->
+ <value>0x1</value>
+ <id>eepromContentType</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>engine</id>
+ </field>
+ <field>
+ <value>physical:sys-0</value>
+ <id>i2cMasterPath</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>i2cMuxBusSelector</id>
+ </field>
+ <field>
+ <value>physical:sys-0</value>
+ <id>i2cMuxPath</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>maxMemorySizeKB</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>port</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>writeCycleTime</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>writePageSize</id>
+ </field>
+ </default>
<id>EEPROM_VPD_PRIMARY_INFO</id>
</attribute>
<attribute>
@@ -1226,6 +1495,9 @@
<id>MEM_PORT</id>
</attribute>
<attribute>
+ <id>NVDIMM_ARMED</id>
+ </attribute>
+ <attribute>
<id>NV_OPS_TIMEOUT_MSEC</id>
</attribute>
<attribute>
@@ -1279,6 +1551,68 @@
</targetType>
<targetType>
+ <id>lcard-dimm-ddimm</id>
+ <parent>lcard-dimm</parent>
+ <attribute>
+ <default>
+ <field>
+ <value>0xFF</value>
+ <id>byteAddrOffset</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>chipCount</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>devAddr</id>
+ </field>
+ <field>
+ <!--Since enum values cannot be used as default values in
+ a complexType, this is a workaround to set the value to the
+ corresponding enum value.-->
+ <!--value>DDIMM</value-->
+ <value>0x4</value>
+ <id>eepromContentType</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>engine</id>
+ </field>
+ <field>
+ <value>physical:sys-0</value>
+ <id>i2cMasterPath</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>i2cMuxBusSelector</id>
+ </field>
+ <field>
+ <value>physical:sys-0</value>
+ <id>i2cMuxPath</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>maxMemorySizeKB</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>port</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>writeCycleTime</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>writePageSize</id>
+ </field>
+ </default>
+ <id>EEPROM_VPD_PRIMARY_INFO</id>
+ </attribute>
+ </targetType>
+
+ <targetType>
<id>lcard-dimm-ddr4</id>
<parent>lcard-dimm</parent>
</targetType>
@@ -1465,6 +1799,9 @@
<id>BOOT_FREQ_MHZ</id>
</attribute>
<attribute>
+ <id>BPM_UPDATE_OVERRIDE</id>
+ </attribute>
+ <attribute>
<id>BRAZOS_RX_FIFO_OVERRIDE</id>
</attribute>
<attribute>
@@ -1520,6 +1857,12 @@
<id>FIELD_TH_P8EX_L3_LINE_DELETES</id>
</attribute>
<attribute>
+ <id>FORCE_NVDIMM_RESET</id>
+ </attribute>
+ <attribute>
+ <id>FORCE_SRAM_MMIO_OVER_I2C</id>
+ </attribute>
+ <attribute>
<id>FREQ_CORE_CEILING_MHZ</id>
</attribute>
<attribute>
@@ -1578,6 +1921,9 @@
<id>ISTEP_PAUSE_ENABLE</id>
</attribute>
<attribute>
+ <id>KEY_CLEAR_REQUEST</id>
+ </attribute>
+ <attribute>
<default>0x0006030000000000</default>
<id>LPC_BUS_ADDR</id>
</attribute>
@@ -1613,6 +1959,9 @@
<id>MAX_SBE_SEEPROM_SIZE</id>
</attribute>
<attribute>
+ <id>MC_PLL_BUCKET</id>
+ </attribute>
+ <attribute>
<id>MFG_TRACE_ENABLE</id>
</attribute>
<attribute>
@@ -1767,6 +2116,21 @@
<id>NUMERIC_POD_TYPE_TEST</id>
</attribute>
<attribute>
+ <id>NVDIMM_AUTO_ARM</id>
+ </attribute>
+ <attribute>
+ <id>NVDIMM_ENCRYPTION_ENABLE</id>
+ </attribute>
+ <attribute>
+ <id>NVDIMM_ENCRYPTION_KEYS_ANCHOR</id>
+ </attribute>
+ <attribute>
+ <id>NVDIMM_ENCRYPTION_KEYS_FW</id>
+ </attribute>
+ <attribute>
+ <id>OCMB_FW_UPDATE_OVERRIDE</id>
+ </attribute>
+ <attribute>
<id>O_EREPAIR_THRESHOLD_FIELD</id>
</attribute>
<attribute>
@@ -2356,6 +2720,9 @@
<id>MODEL</id>
<default>AXONE</default>
</attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ </attribute>
</targetType>
<targetType>
@@ -2640,6 +3007,60 @@
<id>DECONFIG_GARDABLE</id>
</attribute>
<attribute>
+ <default>
+ <field>
+ <value>0xFF</value>
+ <id>byteAddrOffset</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>chipCount</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>devAddr</id>
+ </field>
+ <field>
+ <!--Since enum values cannot be used as default values in
+ a complexType, this is a workaround to set the value to the
+ corresponding enum value.-->
+ <!--value>IBM_FRUVPD</value-->
+ <value>0x2</value>
+ <id>eepromContentType</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>engine</id>
+ </field>
+ <field>
+ <value>physical:sys-0</value>
+ <id>i2cMasterPath</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>i2cMuxBusSelector</id>
+ </field>
+ <field>
+ <value>physical:sys-0</value>
+ <id>i2cMuxPath</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>maxMemorySizeKB</id>
+ </field>
+ <field>
+ <value>0xFF</value>
+ <id>port</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>writeCycleTime</id>
+ </field>
+ <field>
+ <value>0xFFFFFFFFFFFFFFFF</value>
+ <id>writePageSize</id>
+ </field>
+ </default>
<id>EEPROM_VPD_PRIMARY_INFO</id>
</attribute>
<!--fsp requirement-->
@@ -2784,6 +3205,7 @@
</attribute>
</targetType>
+ <!-- Three NPUs per proc -->
<targetType>
<id>unit-npu-axone</id>
<parent>unit-npu-power9</parent>
@@ -2791,8 +3213,26 @@
<id>MODEL</id>
<default>AXONE</default>
</attribute>
+ <attribute>
+ <default>
+ <field>
+ <id>childRollupAllowed</id>
+ <value>1</value>
+ </field>
+ <field>
+ <id>deconfigureParent</id>
+ <value>1</value>
+ </field>
+ <field>
+ <id>valid</id>
+ <value>1</value>
+ </field>
+ </default>
+ <id>PARENT_DECONFIG_RULES</id>
+ </attribute>
</targetType>
+ <!-- One NPU per proc -->
<targetType>
<id>unit-npu-cumulus</id>
<parent>unit-npu-power9</parent>
@@ -2802,6 +3242,7 @@
</attribute>
</targetType>
+ <!-- One NPU per proc -->
<targetType>
<id>unit-npu-nimbus</id>
<parent>unit-npu-power9</parent>
@@ -2811,7 +3252,6 @@
</attribute>
</targetType>
- <!-- One NPU per proc -->
<targetType>
<id>unit-npu-power9</id>
<parent>unit</parent>
@@ -3165,6 +3605,12 @@
<default>AXONE</default>
<id>MODEL</id>
</attribute>
+ <attribute>
+ <id>OMI_INBAND_BAR_BASE_ADDR_OFFSET</id>
+ </attribute>
+ <attribute>
+ <id>ORDINAL_ID</id>
+ </attribute>
</targetType>
<!-- OMI (Special has two parents)
diff --git a/src/usr/targeting/common/xmltohb/target_types_hb.xml b/src/usr/targeting/common/xmltohb/target_types_hb.xml
index ff955cf28..e2be5b6f8 100644
--- a/src/usr/targeting/common/xmltohb/target_types_hb.xml
+++ b/src/usr/targeting/common/xmltohb/target_types_hb.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2012,2019 -->
+<!-- Contributors Listed Below - COPYRIGHT 2012,2020 -->
<!-- [+] Google Inc. -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
@@ -87,10 +87,19 @@
<targetTypeExtension>
<id>chip-ocmb</id>
<attribute>
+ <id>HBRT_HYP_ID</id>
+ </attribute>
+ <attribute>
+ <id>IBSCOM_MUTEX</id>
+ </attribute>
+ <attribute>
<default>0</default>
<id>MMIO_VM_ADDR</id>
</attribute>
<attribute>
+ <id>OCMB_COUNTER_HB</id>
+ </attribute>
+ <attribute>
<id>VPD_SWITCHES</id>
</attribute>
</targetTypeExtension>
@@ -107,6 +116,9 @@
<id>FSI_SCOM_MUTEX</id>
</attribute>
<attribute>
+ <id>GPIO_INFO_PHYS_PRES</id>
+ </attribute>
+ <attribute>
<id>HBRT_HYP_ID</id>
</attribute>
<attribute>
@@ -240,6 +252,12 @@
<id>DIMM_SPD_BYTE_SIZE</id>
</attribute>
<attribute>
+ <id>NVDIMM_READING_PAGE4</id>
+ </attribute>
+ <attribute>
+ <id>NVDIMM_READING_VENDOR_LOG</id>
+ </attribute>
+ <attribute>
<id>PART_NUMBER</id>
</attribute>
<attribute>
@@ -251,6 +269,14 @@
</targetTypeExtension>
<targetTypeExtension>
+ <id>pmic</id>
+ <attribute>
+ <id>DYNAMIC_I2C_DEVICE_ADDRESS</id>
+ <default>0</default>
+ </attribute>
+ </targetTypeExtension>
+
+ <targetTypeExtension>
<id>sys-sys-power9</id>
<attribute>
<id>ALLOW_ATTR_OVERRIDES_IN_SECURE_MODE</id>
@@ -274,9 +300,19 @@
<id>FORCE_PRE_PAYLOAD_DRTM</id>
</attribute>
<attribute>
+ <id>FORCE_SBE_UPDATE</id>
+ </attribute>
+ <!-- Need to add this explicitly to handle the Axone case -->
+ <attribute>
+ <id>FREQ_MCA_MHZ</id>
+ </attribute>
+ <attribute>
<id>HB_EXISTING_IMAGE</id>
</attribute>
<attribute>
+ <id>HB_MUTEX_SERIALIZE_TEST_LOCK</id>
+ </attribute>
+ <attribute>
<id>HB_MUTEX_TEST_LOCK</id>
</attribute>
<attribute>
@@ -311,7 +347,7 @@
</attribute>
<attribute>
<id>OVERRIDES_ATTEMPTED_FLAG</id>
- </attribute>
+ </attribute>
<attribute>
<id>PDA_CAPTURED_THREAD_REG_ARRAY_ADDR</id>
</attribute>
@@ -324,6 +360,18 @@
<attribute>
<id>PDA_THREAD_REG_STATE_ENTRY_FORMAT</id>
</attribute>
+ <attribute>
+ <id>PHYS_PRES_ASSERTED</id>
+ </attribute>
+ <attribute>
+ <id>PHYS_PRES_FAKE_ASSERT</id>
+ </attribute>
+ <attribute>
+ <id>PHYS_PRES_REQUEST_OPEN_WINDOW</id>
+ </attribute>
+ <attribute>
+ <id>SBE_ARCH_DUMP_ADDR</id>
+ </attribute>
</targetTypeExtension>
<targetTypeExtension>
diff --git a/src/usr/targeting/common/xmltohb/xmltohb.pl b/src/usr/targeting/common/xmltohb/xmltohb.pl
index b3370906e..339c26960 100755
--- a/src/usr/targeting/common/xmltohb/xmltohb.pl
+++ b/src/usr/targeting/common/xmltohb/xmltohb.pl
@@ -8,6 +8,7 @@
#
# Contributors Listed Below - COPYRIGHT 2012,2019
# [+] International Business Machines Corp.
+# [+] YADRO
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,10 +27,7 @@
#
# Purpose:
-# Author: Nick Bofferding
-# Last Updated: 09/09/2011
-#
-# Version: 1.0
+# Process the attribute xml files, generate code, create binaries, etc
#
# Change Log **********************************************************
#
@@ -363,17 +361,17 @@ if( !($cfgSrcOutputDir =~ "none") )
writeFapi2PlatAttrMacrosHeaderFileFooter ($fapi2PlatAttrMacrosHeaderFile);
close $fapi2PlatAttrMacrosHeaderFile;
- open(ATTR_ATTRERRL_C_FILE,">$cfgSrcOutputDir"."errludattribute.C")
+ open(ATTR_ATTRERRL_C_FILE,">$cfgSrcOutputDir"."errludattribute_gen.C")
or croak ("Attribute errlog C file: \"$cfgSrcOutputDir"
- . "errludattribute.C\" could not be opened.");
+ . "errludattribute_gen.C\" could not be opened.");
my $attrErrlCFile = *ATTR_ATTRERRL_C_FILE;
writeAttrErrlCFile($attributes,$attrErrlCFile);
close $attrErrlCFile;
mkdir("$cfgSrcOutputDir/errl");
- open(ATTR_ATTRERRL_H_FILE,">$cfgSrcOutputDir"."errl/errludattribute.H")
+ open(ATTR_ATTRERRL_H_FILE,">$cfgSrcOutputDir"."errl/errludattributeP_gen.H")
or croak ("Attribute errlog H file: \"$cfgSrcOutputDir"
- . "errl/errludattribute.H\" could not be opened.");
+ . "errl/errludattributeP_gen.H\" could not be opened.");
my $attrErrlHFile = *ATTR_ATTRERRL_H_FILE;
writeAttrErrlHFile($attributes,$attrErrlHFile);
close $attrErrlHFile;
@@ -1018,32 +1016,30 @@ sub validateAttributes {
my($attributes) = @_;
my %elements = ( );
- $elements{"id"} = { required => 1, isscalar => 1};
- $elements{"description"} = { required => 1, isscalar => 1};
- $elements{"persistency"} = { required => 1, isscalar => 1};
- $elements{"fspOnly"} = { required => 0, isscalar => 0};
- $elements{"hbOnly"} = { required => 0, isscalar => 0};
- $elements{"readable"} = { required => 0, isscalar => 0};
- $elements{"simpleType"} = { required => 0, isscalar => 0};
- $elements{"complexType"} = { required => 0, isscalar => 0};
- $elements{"nativeType"} = { required => 0, isscalar => 0};
- $elements{"writeable"} = { required => 0, isscalar => 0};
- $elements{"hasStringConversion"}
- = { required => 0, isscalar => 0};
- $elements{"hwpfToHbAttrMap"}
- = { required => 0, isscalar => 0};
- $elements{"display-name"} = { required => 0, isscalar => 1};
- $elements{"virtual"} = { required => 0, isscalar => 0};
- $elements{"tempAttribute"} = { required => 0, isscalar => 0};
- $elements{"serverwizReadonly"} = { required => 0, isscalar => 0};
- $elements{"serverwizShow"} = { required => 0, isscalar => 1};
- $elements{"global"} = { required => 0, isscalar => 0};
- $elements{"range"} = { required => 0, isscalar => 0};
- $elements{"ignoreEkb"} = { required => 0, isscalar => 0};
- $elements{"mrwRequired"} = { required => 0, isscalar => 0};
+ $elements{"id"} = { required => 1, isscalar => 1};
+ $elements{"description"} = { required => 1, isscalar => 1};
+ $elements{"persistency"} = { required => 1, isscalar => 1};
+ $elements{"fspOnly"} = { required => 0, isscalar => 0};
+ $elements{"hbOnly"} = { required => 0, isscalar => 0};
+ $elements{"readable"} = { required => 0, isscalar => 0};
+ $elements{"simpleType"} = { required => 0, isscalar => 0};
+ $elements{"complexType"} = { required => 0, isscalar => 0};
+ $elements{"nativeType"} = { required => 0, isscalar => 0};
+ $elements{"writeable"} = { required => 0, isscalar => 0};
+ $elements{"hasStringConversion"} = { required => 0, isscalar => 0};
+ $elements{"hwpfToHbAttrMap"} = { required => 0, isscalar => 0};
+ $elements{"display-name"} = { required => 0, isscalar => 1};
+ $elements{"virtual"} = { required => 0, isscalar => 0};
+ $elements{"tempAttribute"} = { required => 0, isscalar => 0};
+ $elements{"serverwizReadonly"} = { required => 0, isscalar => 0};
+ $elements{"serverwizShow"} = { required => 0, isscalar => 1};
+ $elements{"global"} = { required => 0, isscalar => 0};
+ $elements{"range"} = { required => 0, isscalar => 0};
+ $elements{"ignoreEkb"} = { required => 0, isscalar => 0};
+ $elements{"mrwRequired"} = { required => 0, isscalar => 0};
# do NOT export attribute & its associated enum to serverwiz
- $elements{"no_export"} = { required => 0, isscalar => 0};
+ $elements{"no_export"} = { required => 0, isscalar => 0};
foreach my $attribute (@{$attributes->{attribute}})
{
@@ -2438,6 +2434,9 @@ print $outFile <<VERBATIM;
// STD
#include <stdint.h>
#include <stdlib.h>
+#ifdef __HOSTBOOT_MODULE
+#include <array>
+#endif
VERBATIM
foreach my $attribute (@{$attributes->{attribute}})
@@ -2541,12 +2540,11 @@ sub writeTraitFileTraits {
$traits .= " fspAccessible,";
}
- chop($traits);
-
# Build value type
my $type = "";
my $dimensions = "";
+ my $stdArrAddOn = ""; # Only used if attr holds array type
if(exists $attribute->{simpleType})
{
my $simpleType = $attribute->{simpleType};
@@ -2569,11 +2567,26 @@ sub writeTraitFileTraits {
if( (exists $simpleType->{array})
&& ($simpleTypeProperties->{$typeName}{supportsArray}) )
{
- my @bounds = split(/,/,$simpleType->{array});
- foreach my $bound (@bounds)
+
+ my @revBounds = reverse split(/,/,$simpleType->{array});
+
+ for my $idx (0 .. $#revBounds)
{
- $dimensions .= "[$bound]";
+ $dimensions = "[@revBounds[$idx]]$dimensions";
+
+ # Creating std::array, even if multi-dimensional
+ if ($idx == 0)
+ {
+ $stdArrAddOn = "std::array<$type, "
+ ."@revBounds[$idx]>";
+ }
+ else
+ {
+ $stdArrAddOn = "std::array<$stdArrAddOn, "
+ ."@revBounds[$idx]>";
+ }
}
+
}
if(exists $simpleType->{string})
@@ -2611,6 +2624,8 @@ sub writeTraitFileTraits {
. "$attribute->{id}.");
}
+ chop($traits);
+
# if it already exists skip it
if( !exists($attrValHash{$attribute->{id}}))
{
@@ -2625,6 +2640,13 @@ sub writeTraitFileTraits {
print $outFile " public:\n";
print $outFile " enum {",$traits," };\n";
print $outFile " typedef ", $type, " Type$dimensions;\n";
+ if ($stdArrAddOn ne "")
+ {
+ # Append typedef for std::array if attr holds array value
+ print $outFile "#ifdef __HOSTBOOT_MODULE\n";
+ print $outFile " typedef $stdArrAddOn TypeStdArr;\n";
+ print $outFile "#endif\n";
+ }
print $outFile "};\n\n";
$typedefs .= "// Type aliases and/or sizes for ATTR_"
@@ -2637,6 +2659,14 @@ sub writeTraitFileTraits {
$typedefs .= "typedef " . $type .
" ATTR_" . "$attribute->{id}" . "_type" . $dimensions . ";\n";
+ if ($stdArrAddOn ne "")
+ {
+ $typedefs .= "#ifdef __HOSTBOOT_MODULE\n";
+ $typedefs .= "typedef $stdArrAddOn "
+ ."ATTR_$attribute->{id}_typeStdArr;\n";
+ $typedefs .= "#endif\n";
+ }
+
# If a string, append max # of characters for the string
if( (exists $attribute->{simpleType})
&& (exists $attribute->{simpleType}->{string}))
@@ -2718,14 +2748,6 @@ VERBATIM
sub writeAttrErrlCFile {
my($attributes,$outFile) = @_;
- #First setup the includes and function definition
- print $outFile "#include <stdint.h>\n";
- print $outFile "#include <stdio.h>\n";
- print $outFile "#include <string.h>\n";
- print $outFile "#include <errl/errludattribute.H>\n";
- print $outFile "#include <errl/errlreasoncodes.H>\n";
- print $outFile "#include <targeting/common/targetservice.H>\n";
- print $outFile "#include <targeting/common/trace.H>\n";
print $outFile "\n";
print $outFile "namespace ERRORLOG\n";
print $outFile "{\n";
@@ -2742,52 +2764,38 @@ sub writeAttrErrlCFile {
print $outFile "\n";
print $outFile " switch (i_attr) {\n";
- print $outFile " case (ATTR_SERIAL_NUMBER): { //simpleType:uint, :int...\n";
- print $outFile " //TRACDCOMP( g_trac_errl, \"ErrlUserDetailsAttribute: SERIAL_NUMBER entry\");\n";
- print $outFile " AttributeTraits<ATTR_SERIAL_NUMBER>::Type tmp;\n";
- print $outFile " if( iv_pTarget->tryGetAttr<ATTR_SERIAL_NUMBER>(tmp) ) {\n";
- print $outFile " tmpBuffer = new char[sizeof(tmp)];\n";
- print $outFile " memcpy(tmpBuffer, &tmp, sizeof(tmp));\n";
- print $outFile " attrSize = sizeof(tmp);\n";
- print $outFile " }\n";
- print $outFile " break;\n";
- print $outFile " }\n";
- print $outFile " case (ATTR_PART_NUMBER): { //simpleType:uint, :int...\n";
- print $outFile " //TRACDCOMP( g_trac_errl, \"ErrlUserDetailsAttribute: PART_NUMBER entry\");\n";
- print $outFile " AttributeTraits<ATTR_PART_NUMBER>::Type tmp;\n";
- print $outFile " if( iv_pTarget->tryGetAttr<ATTR_PART_NUMBER>(tmp) ) {\n";
- print $outFile " tmpBuffer = new char[sizeof(tmp)];\n";
- print $outFile " memcpy(tmpBuffer, &tmp, sizeof(tmp));\n";
- print $outFile " attrSize = sizeof(tmp);\n";
- print $outFile " }\n";
- print $outFile " break;\n";
- print $outFile " }\n";
- print $outFile " case (ATTR_PEC_PCIE_HX_KEYWORD_DATA): { //simpleType:uint, :int...\n";
- print $outFile " //TRACDCOMP( g_trac_errl, \"ErrlUserDetailsAttribute: PEC_PCIE_HX_KEYWORD_DATA entry\");\n";
- print $outFile " AttributeTraits<ATTR_PEC_PCIE_HX_KEYWORD_DATA>::Type tmp;\n";
- print $outFile " if( iv_pTarget->tryGetAttr<ATTR_PEC_PCIE_HX_KEYWORD_DATA>(tmp) ) {\n";
- print $outFile " tmpBuffer = new char[sizeof(tmp)];\n";
- print $outFile " memcpy(tmpBuffer, &tmp, sizeof(tmp));\n";
- print $outFile " attrSize = sizeof(tmp);\n";
- print $outFile " }\n";
- print $outFile " break;\n";
- print $outFile " }\n";
- print $outFile "#if 0 //\@fixme-RTC:152874\n";
+ # List of attributes we want to explicitly support
+ my @allowed_attributes = (
+ "SERIAL_NUMBER",
+ "PART_NUMBER",
+ "PEC_PCIE_HX_KEYWORD_DATA",
+ "ECID",
+ "HUID",
+ );
- # loop through every attribute to make the swith/case
+ # loop through every attribute to make the switch/case
foreach my $attribute (@{$attributes->{attribute}})
{
+ my $skippedattr = 0;
+ if( grep { $_ eq $attribute->{id} } @allowed_attributes )
+ {
+ print "Allowing $attribute->{id}\n";
+ }
+ else
+ {
+ print $outFile "#if 0 //\@fixme-RTC:152874\n";
+ $skippedattr = 1;
+ }
+
# things we'll skip:
if(!(exists $attribute->{readable}) || # write-only attributes
- !(exists $attribute->{writeable}) || # read-only attributes
(exists $attribute->{simpleType} && (
(exists $attribute->{simpleType}->{hbmutex}) ||
(exists $attribute->{simpleType}->{hbrecrusivemutex}) ||
(exists $attribute->{simpleType}->{fspmutex}))) # mutex attributes
) {
print $outFile " case (ATTR_",$attribute->{id},"): { break; }\n";
- next;
}
# any complicated types just get dumped as raw hex binary
elsif(exists $attribute->{complexType}) {
@@ -2872,6 +2880,11 @@ sub writeAttrErrlCFile {
print $outFile " break;\n";
print $outFile " }\n";
}
+
+ if( $skippedattr )
+ {
+ print $outFile "#endif //\@fixme-RTC:152874\n";
+ }
}
print $outFile " default: { //Shouldn't be anything here!!\n";
@@ -2879,7 +2892,6 @@ sub writeAttrErrlCFile {
print $outFile " break;\n";
print $outFile " }\n";
- print $outFile "#endif //\@fixme-RTC:152874\n";
print $outFile " } //switch\n";
print $outFile "\n";
@@ -2898,45 +2910,6 @@ sub writeAttrErrlCFile {
print $outFile "}\n";
print $outFile "\n";
- # build constructor that dumps 1 attribute
- print $outFile "\n";
- print $outFile "//------------------------------------------------------------------------------\n";
- print $outFile "ErrlUserDetailsAttribute::ErrlUserDetailsAttribute(\n";
- print $outFile " const Target * i_pTarget, uint32_t i_attr)\n";
- print $outFile " : iv_pTarget(i_pTarget), iv_dataSize(0)\n";
- print $outFile "{\n";
- print $outFile " // Set up ErrlUserDetails instance variables\n";
- print $outFile " iv_CompId = ERRL_COMP_ID;\n";
- print $outFile " iv_Version = 1;\n";
- print $outFile " iv_SubSection = ERRL_UDT_ATTRIBUTE;\n";
- print $outFile " // override the default of false\n";
- print $outFile " iv_merge = true;\n";
- print $outFile "\n";
- print $outFile " // first, write out the HUID\n";
- print $outFile " addData(ATTR_HUID);\n";
- print $outFile " if (i_attr != ATTR_HUID) {\n";
- print $outFile " addData(i_attr);\n";
- print $outFile " }\n";
- print $outFile "}\n";
- print $outFile "\n";
-
- # build constructor that dumps all attributes
- print $outFile "//------------------------------------------------------------------------------\n";
- print $outFile "ErrlUserDetailsAttribute::ErrlUserDetailsAttribute(\n";
- print $outFile " const Target * i_pTarget)\n";
- print $outFile " : iv_pTarget(i_pTarget), iv_dataSize(0)\n";
- print $outFile "{\n";
- print $outFile " // Set up ErrlUserDetails instance variables\n";
- print $outFile " iv_CompId = ERRL_COMP_ID;\n";
- print $outFile " iv_Version = 1;\n";
- print $outFile " iv_SubSection = ERRL_UDT_ATTRIBUTE;\n";
- print $outFile " // override the default of false\n";
- print $outFile " iv_merge = true;\n";
- print $outFile "\n";
- print $outFile " dumpAll();\n";
- print $outFile "}\n";
- print $outFile "\n";
-
# build internal function that dumps all attributes
print $outFile "//------------------------------------------------------------------------------\n";
print $outFile "void ErrlUserDetailsAttribute::dumpAll()\n";
@@ -2967,10 +2940,7 @@ sub writeAttrErrlCFile {
print $outFile "\n";
- print $outFile "//------------------------------------------------------------------------------\n";
- print $outFile "ErrlUserDetailsAttribute::~ErrlUserDetailsAttribute()\n";
- print $outFile "{ }\n";
- print $outFile "} // namespace\n";
+ print $outFile "} // namespace\n\n";
} # sub writeAttrErrlCFile
@@ -2980,44 +2950,7 @@ sub writeAttrErrlCFile {
sub writeAttrErrlHFile {
my($attributes,$outFile) = @_;
- #First setup the includes and function definition
- print $outFile "\n";
- print $outFile "#ifndef ERRL_UDATTRIBUTE_H\n";
- print $outFile "#define ERRL_UDATTRIBUTE_H\n";
- print $outFile "\n";
- print $outFile "#if !defined(PARSER) && !defined(LOGPARSER)\n";
- print $outFile "\n";
- print $outFile "#include <errl/errluserdetails.H>\n";
- print $outFile "\n";
- print $outFile "namespace TARGETING // Forward reference\n";
- print $outFile "{ class Target; }\n";
- print $outFile "\n";
- print $outFile "namespace ERRORLOG\n";
- print $outFile "{\n";
- print $outFile "class ErrlUserDetailsAttribute : public ErrlUserDetails {\n";
- print $outFile "public:\n";
- print $outFile "\n";
- print $outFile " ErrlUserDetailsAttribute(const TARGETING::Target * i_pTarget, uint32_t i_attr);\n";
- print $outFile " ErrlUserDetailsAttribute(const TARGETING::Target * i_pTarget);\n";
- print $outFile " void addData(uint32_t i_attr);\n";
- print $outFile " virtual ~ErrlUserDetailsAttribute();\n";
- print $outFile "\n";
- print $outFile "private:\n";
- print $outFile "\n";
- print $outFile " // Disabled\n";
- print $outFile " ErrlUserDetailsAttribute(const ErrlUserDetailsAttribute &);\n";
- print $outFile " ErrlUserDetailsAttribute & operator=(const ErrlUserDetailsAttribute &);\n";
- print $outFile "\n";
- print $outFile " // internal function\n";
- print $outFile " void dumpAll();\n";
- print $outFile "\n";
- print $outFile " const TARGETING::Target * iv_pTarget;\n";
- print $outFile " uint32_t iv_dataSize;\n";
- print $outFile "};\n";
- print $outFile "}\n";
- print $outFile "#else // if LOGPARSER defined\n";
- print $outFile "\n";
- print $outFile "#include \"errluserdetails.H\"\n";
+ # Included by errludattributeP.H
print $outFile "\n";
print $outFile "namespace ERRORLOG\n";
print $outFile "{\n";
@@ -3048,8 +2981,9 @@ sub writeAttrErrlHFile {
print $outFile " for (; (l_ptr + sizeof(uint32_t)) <= ((uint8_t*)i_pBuffer + i_buflen); )\n";
print $outFile " {\n";
print $outFile " // first 4 bytes is the attr enum\n";
- print $outFile " uint32_t attrEnum = ntohl(*(uint32_t *)l_ptr);\n";
+ print $outFile " uint32_t attrEnum = ntohl(UINT32_FROM_PTR(l_ptr));\n";
print $outFile " l_ptr += sizeof(attrEnum);\n";
+ print $outFile " char* tmplabel = NULL;\n";
print $outFile "\n";
print $outFile " switch (attrEnum) {\n";
@@ -3179,21 +3113,21 @@ sub writeAttrErrlHFile {
elsif (exists $attribute->{simpleType}->{uint16_t}) {
print $outFile " l_traceEntry.resize(10+offset + $total_count * 7);\n";
print $outFile " for (uint32_t i = 0;i<$total_count;i++) {\n";
- print $outFile " sprintf(&(l_traceEntry[offset+i*7]), \"0x%.4X \", ntohs(*(((uint16_t *)l_ptr)+i)));\n";
+ print $outFile " sprintf(&(l_traceEntry[offset+i*7]), \"0x%.4X \", ntohs(UINT16_FROM_PTR(reinterpret_cast<const uint16_t*>(l_ptr) + i)));\n";
print $outFile " }\n";
print $outFile " l_ptr += $total_count * sizeof(uint16_t);\n";
}
elsif (exists $attribute->{simpleType}->{uint32_t}) {
print $outFile " l_traceEntry.resize(10+offset + $total_count * 11);\n";
print $outFile " for (uint32_t i = 0;i<$total_count;i++) {\n";
- print $outFile " sprintf(&(l_traceEntry[offset+i*11]), \"0x%.8X \", ntohl(*(((uint32_t *)l_ptr)+i)));\n";
+ print $outFile " sprintf(&(l_traceEntry[offset+i*11]), \"0x%.8X \", ntohl(UINT32_FROM_PTR(reinterpret_cast<const uint32_t*>(l_ptr)+i)));\n";
print $outFile " }\n";
print $outFile " l_ptr += $total_count * sizeof(uint32_t);\n";
}
elsif (exists $attribute->{simpleType}->{uint64_t}) {
print $outFile " l_traceEntry.resize(10+offset + $total_count * 19);\n";
print $outFile " for (uint32_t i = 0;i<$total_count;i++) {\n";
- print $outFile " sprintf(&(l_traceEntry[offset+i*19]), \"0x%.16llX \", ntohll(*(((uint64_t *)l_ptr)+i)));\n";
+ print $outFile " sprintf(&(l_traceEntry[offset+i*19]), \"0x%.16llX \", ntohll(UINT64_FROM_PTR(reinterpret_cast<const uint64_t*>(l_ptr)+i)));\n";
print $outFile " }\n";
print $outFile " l_ptr += $total_count * sizeof(uint64_t);\n";
}
@@ -3207,21 +3141,21 @@ sub writeAttrErrlHFile {
elsif (exists $attribute->{simpleType}->{int16_t}) {
print $outFile " l_traceEntry.resize(10+offset + $total_count * 7);\n";
print $outFile " for (uint32_t i = 0;i<$total_count;i++) {\n";
- print $outFile " sprintf(&(l_traceEntry[offset+i*7]), \"0x%.4X \", ntohs(*(((int16_t *)l_ptr)+i)));\n";
+ print $outFile " sprintf(&(l_traceEntry[offset+i*7]), \"0x%.4X \", ntohs(INT16_FROM_PTR(reinterpret_cast<const int16_t*>(l_ptr)+i)));\n";
print $outFile " }\n";
print $outFile " l_ptr += $total_count * sizeof(int16_t);\n";
}
elsif (exists $attribute->{simpleType}->{int32_t}) {
print $outFile " l_traceEntry.resize(10+offset + $total_count * 11);\n";
print $outFile " for (uint32_t i = 0;i<$total_count;i++) {\n";
- print $outFile " sprintf(&(l_traceEntry[offset+i*11]), \"0x%.8X \", ntohl(*(((int32_t *)l_ptr)+i)));\n";
+ print $outFile " sprintf(&(l_traceEntry[offset+i*11]), \"0x%.8X \", ntohl(INT32_FROM_PTR(reinterpret_cast<const int32_t*>(l_ptr)+i)));\n";
print $outFile " }\n";
print $outFile " l_ptr += $total_count * sizeof(int32_t);\n";
}
elsif (exists $attribute->{simpleType}->{int64_t}) {
print $outFile " l_traceEntry.resize(10+offset + $total_count * 19);\n";
print $outFile " for (uint32_t i = 0;i<$total_count;i++) {\n";
- print $outFile " sprintf(&(l_traceEntry[offset+i*19]), \"0x%.16llX \", ntohll(*(((int64_t *)l_ptr)+i)));\n";
+ print $outFile " sprintf(&(l_traceEntry[offset+i*19]), \"0x%.16llX \", ntohll(INT64_FROM_PTR(reinterpret_cast<const int64_t*>(l_ptr)+i)));\n";
print $outFile " }\n";
print $outFile " l_ptr += $total_count * sizeof(int64_t);\n";
}
@@ -3296,7 +3230,9 @@ sub writeAttrErrlHFile {
print $outFile " }\n";
}
print $outFile " default: {\n";
- print $outFile " pLabel = \"unknown Attribute\";\n";
+ print $outFile " tmplabel = new char[30];\n";
+ print $outFile " sprintf( tmplabel, \"Unknown [0x%x]\", attrEnum );\n";
+ print $outFile " pLabel = tmplabel;\n";
print $outFile " break;\n";
print $outFile " }\n";
print $outFile " } // switch\n";
@@ -3305,6 +3241,7 @@ sub writeAttrErrlHFile {
print $outFile " if (pLabel != NULL) {\n";
print $outFile " i_parser.PrintString(pLabel, &(l_traceEntry[0]));\n";
print $outFile " }\n";
+ print $outFile " if( tmplabel != NULL ) { delete[] tmplabel; }\n";
print $outFile " } // for\n";
print $outFile " } // parse\n\n";
print $outFile "private:\n";
@@ -3313,9 +3250,7 @@ sub writeAttrErrlHFile {
print $outFile "ErrlUserDetailsParserAttribute(const ErrlUserDetailsParserAttribute &);\n";
print $outFile "ErrlUserDetailsParserAttribute & operator=(const ErrlUserDetailsParserAttribute &);\n";
print $outFile "};\n";
- print $outFile "} // namespace\n";
- print $outFile "#endif\n";
- print $outFile "#endif\n";
+ print $outFile "} // namespace\n\n";
} # sub writeAttrErrlHFile
######
@@ -4016,11 +3951,11 @@ sub writeTargetErrlHFile {
print $outFile " // first 4 are always the same\n";
print $outFile " if ((l_ptr32 + 4) <= (uint32_t *)((uint8_t*)i_pBuffer + i_buflen)) {\n";
- print $outFile " i_parser.PrintNumber( l_label, \"HUID = 0x%08X\", ntohl(*l_ptr32) );\n";
+ print $outFile " i_parser.PrintNumber( l_label, \"HUID = 0x%08X\", ntohl(UINT32_FROM_PTR(l_ptr32)) );\n";
print $outFile " l_ptr32++;\n";
# find CLASS
- print $outFile " switch (ntohl(*l_ptr32)) { // CLASS\n";
+ print $outFile " switch (ntohl(UINT32_FROM_PTR(l_ptr32))) { // CLASS\n";
foreach my $enumerationType (@{$attributes->{enumerationType}})
{
if( $enumerationType->{id} eq "CLASS" ) {
@@ -4039,7 +3974,7 @@ sub writeTargetErrlHFile {
print $outFile " l_ptr32++;\n";
# find TYPE
- print $outFile " switch (ntohl(*l_ptr32)) { // TYPE\n";
+ print $outFile " switch (ntohl(UINT32_FROM_PTR(l_ptr32))) { // TYPE\n";
foreach my $enumerationType (@{$attributes->{enumerationType}})
{
if( $enumerationType->{id} eq "TYPE" ) {
@@ -4058,7 +3993,7 @@ sub writeTargetErrlHFile {
print $outFile " l_ptr32++;\n";
# find MODEL
- print $outFile " switch (ntohl(*l_ptr32)) { // MODEL\n";
+ print $outFile " switch (ntohl(UINT32_FROM_PTR(l_ptr32))) { // MODEL\n";
foreach my $enumerationType (@{$attributes->{enumerationType}})
{
if( $enumerationType->{id} eq "MODEL" ) {
@@ -4096,7 +4031,7 @@ sub writeTargetErrlHFile {
}
}
- print $outFile " uint32_t l_pathType = ntohl(*l_ptr32);\n";
+ print $outFile " uint32_t l_pathType = ntohl(UINT32_FROM_PTR(l_ptr32));\n";
print $outFile " if ((l_pathType == $attrPhysPath) || // ATTR_PHYS_PATH\n";
print $outFile " (l_pathType == $attrAffinityPath)) // ATTR_AFFINITY_PATH\n";
print $outFile " {\n";
diff --git a/src/usr/targeting/hostboot_common.mk b/src/usr/targeting/hostboot_common.mk
index 7be1449d7..4d10df929 100644
--- a/src/usr/targeting/hostboot_common.mk
+++ b/src/usr/targeting/hostboot_common.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2016
+# Contributors Listed Below - COPYRIGHT 2013,2020
# [+] International Business Machines Corp.
#
#
@@ -30,6 +30,9 @@ COMMON_TARGETING_MAKEFILE = ${COMMON_TARGETING_REL_PATH}/common.mk
include ${COMMON_TARGETING_MAKEFILE}
+# TODO: 248022 move this to common.mk when CMVC files are updated for fips
+TARGET_OBJS += hbrt_target.o
+
VPATH += ${TARGETING_REL_PATH}/adapters
VPATH += ${COMMON_TARGETING_REL_PATH}
VPATH += ${addprefix ${COMMON_TARGETING_REL_PATH}/, ${COMMON_TARGETING_SUBDIRS}}
diff --git a/src/usr/targeting/makefile b/src/usr/targeting/makefile
index 531c3fb7f..af1978f64 100644
--- a/src/usr/targeting/makefile
+++ b/src/usr/targeting/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2011,2018
+# Contributors Listed Below - COPYRIGHT 2011,2020
# [+] International Business Machines Corp.
#
#
@@ -54,7 +54,6 @@ HOSTBOOT_SPECIFIC_OBJS += ${ATTR_RP_OBJS}
HOSTBOOT_SPECIFIC_OBJS += ${DEBUG_OBJS}
HOSTBOOT_SPECIFIC_OBJS += ${HOSTBOOT_RT_IPL_COMMON_OBJS}
HOSTBOOT_SPECIFIC_OBJS += namedtarget.o
-HOSTBOOT_SPECIFIC_OBJS += errludattribute.o
HOSTBOOT_SPECIFIC_OBJS += attrcheck_errl.o
OBJS += persistrwattrcheck.o
diff --git a/src/usr/targeting/runtime/attrPlatOverride_rt.C b/src/usr/targeting/runtime/attrPlatOverride_rt.C
index b379313d9..3c805381c 100644
--- a/src/usr/targeting/runtime/attrPlatOverride_rt.C
+++ b/src/usr/targeting/runtime/attrPlatOverride_rt.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -24,14 +24,13 @@
/* IBM_PROLOG_END_TAG */
#include <runtime/interface.h>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <targeting/common/commontargeting.H>
#include <targeting/attrPlatOverride.H>
#include <fapi2/plat_attr_override_sync.H>
#include <targeting/common/trace.H>
#include <errl/errlmanager.H>
#include <initservice/initserviceif.H>
-#include <config.h>
#include <secureboot/service.H>
#include <targeting/common/targreasoncodes.H>
#include <devicefw/userif.H>
diff --git a/src/usr/targeting/runtime/makefile b/src/usr/targeting/runtime/makefile
index ffb2e8a14..eb1dd366e 100644
--- a/src/usr/targeting/runtime/makefile
+++ b/src/usr/targeting/runtime/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2018
+# Contributors Listed Below - COPYRIGHT 2013,2020
# [+] International Business Machines Corp.
#
#
@@ -38,7 +38,6 @@ HOSTBOOT_RUNTIME_SPECIFIC_OBJS += start_rt.o
HOSTBOOT_RUNTIME_SPECIFIC_OBJS += targplatutil.o
HOSTBOOT_RUNTIME_SPECIFIC_OBJS += rt_targeting.o
HOSTBOOT_RUNTIME_SPECIFIC_OBJS += attrPlatOverride_rt.o
-HOSTBOOT_RUNTIME_SPECIFIC_OBJS += errludattribute.o
HOSTBOOT_RUNTIME_SPECIFIC_OBJS += attributestrings.o
HOSTBOOT_RUNTIME_SPECIFIC_OBJS += attrsync.o
HOSTBOOT_RUNTIME_SPECIFIC_OBJS += rt_startup.o
diff --git a/src/usr/targeting/runtime/rt_startup.C b/src/usr/targeting/runtime/rt_startup.C
index 578750006..ed190f196 100644
--- a/src/usr/targeting/runtime/rt_startup.C
+++ b/src/usr/targeting/runtime/rt_startup.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -22,7 +22,7 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <runtime/interface.h>
#include <targeting/common/target.H>
#include <targeting/common/targetservice.H>
diff --git a/src/usr/targeting/runtime/rt_targeting.C b/src/usr/targeting/runtime/rt_targeting.C
index 581386985..28c1fdf7d 100644
--- a/src/usr/targeting/runtime/rt_targeting.C
+++ b/src/usr/targeting/runtime/rt_targeting.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,7 +39,7 @@
#include <targeting/attrrp.H>
#include <arch/pirformat.H>
#include <runtime/customize_attrs_for_payload.H>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <runtime/interface.h>
#include <map>
#include <util/memoize.H>
@@ -54,61 +54,6 @@ using namespace TARGETING;
namespace RT_TARG
{
-errlHndl_t getRtTarget(
- const TARGETING::Target* i_pTarget,
- rtChipId_t& o_rtTargetId)
-{
- errlHndl_t pError = NULL;
-
- do
- {
- if(i_pTarget == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL)
- {
- TARGETING::Target* masterProcChip = NULL;
- TARGETING::targetService().
- masterProcChipTargetHandle(masterProcChip);
- i_pTarget = masterProcChip;
- }
-
- auto hbrtHypId = RUNTIME::HBRT_HYP_ID_UNKNOWN;
- if( (!i_pTarget->tryGetAttr<TARGETING::ATTR_HBRT_HYP_ID>(hbrtHypId))
- || (hbrtHypId == RUNTIME::HBRT_HYP_ID_UNKNOWN))
- {
- auto huid = get_huid(i_pTarget);
- auto targetingTargetType =
- i_pTarget->getAttr<TARGETING::ATTR_TYPE>();
- TRACFCOMP(g_trac_targeting, ERR_MRK
- "Targeting target type of 0x%08X not supported. "
- "HUID: 0x%08X",
- targetingTargetType,
- huid);
- /*@
- * @errortype
- * @moduleid TARG_RT_GET_RT_TARGET
- * @reasoncode TARG_RT_TARGET_TYPE_NOT_SUPPORTED
- * @userdata1 Target's HUID
- * @userdata2 target's targeting type
- * @devdesc Targeting target's type not supported by runtime
- * code
- */
- pError = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_INFORMATIONAL,
- TARGETING::TARG_RT_GET_RT_TARGET,
- TARGETING::TARG_RT_TARGET_TYPE_NOT_SUPPORTED,
- huid,
- targetingTargetType,
- true);
-
- ERRORLOG::ErrlUserDetailsTarget(i_pTarget,"Targeting Target").
- addToLog(pError);
- }
-
- o_rtTargetId = hbrtHypId;
-
- } while(0);
-
- return pError;
-}
/**
* @brief API documentation same as for getHbTarget; this just implements the
diff --git a/src/usr/targeting/runtime/test/testtargeting.H b/src/usr/targeting/runtime/test/testtargeting.H
index fce91f46d..c6c7c0d60 100644
--- a/src/usr/targeting/runtime/test/testtargeting.H
+++ b/src/usr/targeting/runtime/test/testtargeting.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -25,7 +25,7 @@
#include <cxxtest/TestSuite.H>
#include <targeting/common/commontargeting.H>
#include <runtime/interface.h>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <targeting/common/trace.H>
@@ -62,7 +62,7 @@ class TargetingTestSuite : public CxxTest::TestSuite
{
using namespace TARGETING;
errlHndl_t err = NULL;
- RT_TARG::rtChipId_t rt_chipid;
+ TARGETING::rtChipId_t rt_chipid;
TARGETING::TargetHandleList allTargets;
TARGETING::TargetHandleList targetList;
@@ -91,7 +91,7 @@ class TargetingTestSuite : public CxxTest::TestSuite
for(TargetHandleList::iterator pTarg = allTargets.begin();
pTarg != allTargets.end(); ++pTarg)
{
- err = RT_TARG::getRtTarget(*pTarg, rt_chipid);
+ err = TARGETING::getRtTarget(*pTarg, rt_chipid);
if( err )
{
TS_FAIL("getRtTarget returned error log");
@@ -629,7 +629,8 @@ class TargetingTestSuite : public CxxTest::TestSuite
// Compare the complete set of memory
if( memcmp( l_lidStruct, l_rsvdMemPtr, l_attr_size ) )
{
- TS_FAIL( "testSaveRestoreAttrs> Data does not match" );
+ TS_FAIL( "testSaveRestoreAttrs> Data does not match. Attr size = 0x%lx",
+ l_attr_size );
}
uint64_t l_memcmpOffset = 0;
@@ -757,7 +758,6 @@ class TargetingTestSuite : public CxxTest::TestSuite
if(l_memcmpFailed != 0)
{
TS_FAIL("testSaveRestoreAttrs FAILED memcmp %d "
- ERR_MRK"testSaveRestoreAttrs FAILED memcmp %d "
"(0x%.8x) times out of %d (0x%.8x)",
l_memcmpFailed,
l_memcmpFailed,
diff --git a/src/usr/targeting/targetservicestart.C b/src/usr/targeting/targetservicestart.C
index 943b7befc..dea0b9867 100755
--- a/src/usr/targeting/targetservicestart.C
+++ b/src/usr/targeting/targetservicestart.C
@@ -61,7 +61,6 @@
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <devicefw/userif.H>
-#include <config.h>
#include <initservice/initserviceif.H>
#include <util/misc.H>
#include <util/utilrsvdmem.H>
@@ -74,6 +73,7 @@
#include <sbeio/sbeioif.H>
#include <sys/mm.h>
#include "../runtime/hdatstructs.H"
+#include <console/consoleif.H>
#ifdef CONFIG_BMC_IPMI
#include <ipmi/ipmiif.H>
@@ -591,11 +591,18 @@ static void initializeAttributes(TargetService& i_targetService,
(HB_INITIATED_PM_RESET_INACTIVE);
// clear the NVDIMM arming status so it gets redone when OCC is active
- ATTR_NVDIMM_ARMED_type l_nvdimms_armed_state =
- l_chip->getAttr<ATTR_NVDIMM_ARMED>();
- // Only force rearming (error setting should persist)
- l_nvdimms_armed_state.armed = 0;
- l_chip->setAttr<ATTR_NVDIMM_ARMED>(l_nvdimms_armed_state);
+ TargetHandleList l_nvdimmTargetList = getProcNVDIMMs(l_chip);
+ for (auto const l_nvdimm : l_nvdimmTargetList)
+ {
+ ATTR_NVDIMM_ARMED_type l_armed_state = {};
+ l_armed_state = l_nvdimm->getAttr<ATTR_NVDIMM_ARMED>();
+
+ // Only force rearming (error setting should persist)
+ l_armed_state.armed = 0;
+ l_armed_state.occ_active = 0;
+
+ l_nvdimm->setAttr<ATTR_NVDIMM_ARMED>(l_armed_state);
+ }
if (l_chip == l_pMasterProcChip)
{
@@ -839,6 +846,10 @@ static void adjustMemoryMap( TargetService& i_targetService )
ATTR_LPC_BUS_ADDR_type l_lpcBase =
l_pTopLevel->getAttr<ATTR_LPC_BUS_ADDR>();
+ // Whether to update the SYS's ATTR_XSCOM_BASE_ADDRESS with a new
+ // BAR before returning from this function
+ bool l_updateSysXscomBar = false;
+
// Loop through all the procs to recompute all the BARs
// also find the victim to swap with
Target* l_swapVictim = nullptr;
@@ -866,11 +877,13 @@ static void adjustMemoryMap( TargetService& i_targetService )
if(l_curXscomBAR & IS_SMF_ADDR_BIT)
{
l_xscomBAR |= IS_SMF_ADDR_BIT;
+ l_updateSysXscomBar = true;
}
TARG_INF( " XSCOM=%.16llX", l_xscomBAR );
l_procChip->setAttr<ATTR_XSCOM_BASE_ADDRESS>(l_xscomBAR);
+
// See if this chip's space now belongs to the master
if( l_xscomBAR == l_curXscomBAR )
{
@@ -961,11 +974,65 @@ static void adjustMemoryMap( TargetService& i_targetService )
// Set the rest of the BARs...
}
- // We must have found a match somewhere
- TARG_ASSERT( l_swapVictim != nullptr, "No swap match found" );
+ // We should have found a match, but if a processor was swapped
+ // between different systems we could end up with a non-match
+ if( l_swapVictim == nullptr )
+ {
+ TARG_INF( "No swap victim was found, forcing master proc to use calculated proc0 values" );
+
+ // figure out what fabric id we actually booted with
+ uint8_t l_bootGroup = 0;
+ uint8_t l_bootChip = 0;
+ getFabricIdFromAddr( l_curXscomBAR, l_bootGroup, l_bootChip );
+ CONSOLE::displayf( NULL, "Module swap detected - handling memory remap from g%d:c%d\n", l_bootGroup, l_bootChip );
+
+ // now adjust the attributes that our early code is going to consume
+ // to match the fabric id we're currently using
+ ATTR_XSCOM_BASE_ADDRESS_type l_xscomBAR =
+ computeMemoryMapOffset( l_xscomBase, l_bootGroup, l_bootChip );
+ l_pMasterProcChip->setAttr<ATTR_XSCOM_BASE_ADDRESS>(l_xscomBAR);
+
+ ATTR_LPC_BUS_ADDR_type l_lpcBAR =
+ computeMemoryMapOffset( l_lpcBase, l_bootGroup, l_bootChip );
+ l_pMasterProcChip->setAttr<ATTR_LPC_BUS_ADDR>(l_lpcBAR);
+
+ ATTR_PSI_BRIDGE_BASE_ADDR_type l_psiBridgeBAR =
+ computeMemoryMapOffset(MMIO_GROUP0_CHIP0_PSI_BRIDGE_BASE_ADDR,
+ l_bootGroup,
+ l_bootChip);
+ l_pMasterProcChip->setAttr<ATTR_PSI_BRIDGE_BASE_ADDR>(l_psiBridgeBAR);
+
+ ATTR_XIVE_CONTROLLER_BAR_ADDR_type l_xiveCtrlBAR =
+ computeMemoryMapOffset(MMIO_GROUP0_CHIP0_XIVE_CONTROLLER_BASE_ADDR,
+ l_bootGroup,
+ l_bootChip);
+ l_pMasterProcChip->setAttr<ATTR_XIVE_CONTROLLER_BAR_ADDR>(l_xiveCtrlBAR);
+
+ ATTR_XIVE_THREAD_MGMT1_BAR_ADDR_type l_xiveThreadMgmtBAR =
+ computeMemoryMapOffset(MMIO_GROUP0_CHIP0_XIVE_THREAD_MGMT1_BASE_ADDR,
+ l_bootGroup,
+ l_bootChip);
+ TARG_INF( " XIVE_THREAD_MGMT1_BAR =%.16llX", l_xiveThreadMgmtBAR );
+ l_pMasterProcChip->setAttr<ATTR_XIVE_THREAD_MGMT1_BAR_ADDR>(l_xiveThreadMgmtBAR);
+
+ ATTR_PSI_HB_ESB_ADDR_type l_psiHbEsbBAR =
+ computeMemoryMapOffset(MMIO_GROUP0_CHIP0_PSI_HB_ESB_BASE_ADDR,
+ l_bootGroup,
+ l_bootChip);
+ l_pMasterProcChip->setAttr<ATTR_PSI_HB_ESB_ADDR>(l_psiHbEsbBAR);
+
+ ATTR_INTP_BASE_ADDR_type l_intpBAR =
+ computeMemoryMapOffset(MMIO_GROUP0_CHIP0_INTP_BASE_ADDR,
+ l_bootGroup,
+ l_bootChip);
+ l_pMasterProcChip->setAttr<ATTR_INTP_BASE_ADDR>(l_intpBAR);
+ // Set the attribute to force a SBE update later
+ l_pTopLevel->setAttr<TARGETING::ATTR_FORCE_SBE_UPDATE>
+ (TARGETING::FORCE_SBE_UPDATE_BAR_MISMATCH);
+ }
// Now swap the BARs between the master and the victim if needed
- if( l_swapVictim != l_pMasterProcChip )
+ else if( l_swapVictim != l_pMasterProcChip )
{
// Walk through all of the attributes we cached above
SWAP_ATTRIBUTE( ATTR_PROC_EFF_FABRIC_GROUP_ID, l_pMasterProcChip,
@@ -992,23 +1059,33 @@ static void adjustMemoryMap( TargetService& i_targetService )
// Cross-check that what we ended up setting in the attributes
// matches the non-TARGETING values that the XSCOM and LPC
- // drivers computed
- if( l_pMasterProcChip->getAttr<ATTR_LPC_BUS_ADDR>()
- != LPC::get_lpc_bar() )
+ // drivers computed (only if we found a swap victim)
+ if( l_swapVictim &&
+ (l_pMasterProcChip->getAttr<ATTR_LPC_BUS_ADDR>()
+ != LPC::get_lpc_bar()) )
{
TARG_ERR( "LPC attribute=%.16llX, live=%.16llX",
l_pMasterProcChip->getAttr<ATTR_LPC_BUS_ADDR>(),
LPC::get_lpc_bar() );
TARG_ASSERT( false, "LPC BARs are inconsistent" );
}
- if( l_pMasterProcChip->getAttr<ATTR_XSCOM_BASE_ADDRESS>()
- != XSCOM::get_master_bar() )
+ if( l_swapVictim &&
+ (l_pMasterProcChip->getAttr<ATTR_XSCOM_BASE_ADDRESS>()
+ != XSCOM::get_master_bar()) )
{
TARG_ERR( "XSCOM attribute=%.16llX, live=%.16llX",
l_pMasterProcChip->getAttr<ATTR_XSCOM_BASE_ADDRESS>(),
XSCOM::get_master_bar() );
TARG_ASSERT( false, "XSCOM BARs are inconsistent" );
}
+
+ if(l_updateSysXscomBar)
+ {
+ l_pTopLevel->setAttr<ATTR_XSCOM_BASE_ADDRESS>(
+ l_xscomBase |= IS_SMF_ADDR_BIT);
+ TARG_INF("Updating the SYS XSCOM BAR to 0x%.16llX",
+ l_xscomBase |= IS_SMF_ADDR_BIT);
+ }
}
diff --git a/src/usr/targeting/targplatutil.C b/src/usr/targeting/targplatutil.C
index c8054cf60..24084d8b1 100644
--- a/src/usr/targeting/targplatutil.C
+++ b/src/usr/targeting/targplatutil.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,7 +42,6 @@
#include <targeting/common/predicates/predicates.H>
#include <targeting/common/utilFilter.H>
#include <errl/errlmanager.H>
-#include <config.h>
#include <algorithm>
namespace TARGETING
{
diff --git a/src/usr/targeting/test/makefile b/src/usr/targeting/test/makefile
index b8d466539..fa6fd0584 100644
--- a/src/usr/targeting/test/makefile
+++ b/src/usr/targeting/test/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2011,2015
+# Contributors Listed Below - COPYRIGHT 2011,2019
# [+] International Business Machines Corp.
#
#
@@ -67,6 +67,8 @@ COMMON_TESTCASE_REL_PATHS = \
TESTS += testtargeting.H
TESTS += testattrsync.H
TESTS += testattrtank.H
+TESTS += testAttribute.H
+TESTS += testTargetUtil.H
TESTS += ${COMMON_TESTCASE_REL_PATHS}
OBJS += attributestrings.o
diff --git a/src/usr/targeting/test/testAttribute.H b/src/usr/targeting/test/testAttribute.H
new file mode 100644
index 000000000..8014f1397
--- /dev/null
+++ b/src/usr/targeting/test/testAttribute.H
@@ -0,0 +1,1271 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/targeting/test/testAttribute.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __TEST_ATTRIBUTE_H
+#define __TEST_ATTRIBUTE_H
+
+/**
+ * @file targeting/test/testAttribute.H
+ *
+ * @brief Unit test for TARGETING::AttributeTank::Attribute
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// CXX TEST
+#include <cxxtest/TestSuite.H>
+
+#include <targeting/common/attributeTank.H>
+
+using namespace TARGETING;
+
+class AttributeTest: public CxxTest::TestSuite
+{
+public:
+ /**
+ * @test Tests the setters and getter methods
+ */
+ void testSimpleSettersAndGetters(void);
+
+ /**
+ * @test Test setting the Attribute Value
+ */
+ void testSettingAndGettingValue(void);
+
+ /**
+ * @test Test Serialize and Deserialize methods
+ */
+ void testSerializeAndDeserializeMethod(void);
+
+ /**
+ * @test Test the Operator Equal method
+ */
+ void testOperatorEqual(void);
+
+ /**
+ * @test Test the Copy Constructor Method
+ */
+ void testCopyConstructor(void);
+
+ private:
+
+ /**
+ * @test Compare the Attribute Header for the two given attributes
+ *
+ * @param[in] l_attribute1 Attribute to compare with
+ * @param[in] l_attribute2 Attribute to compare with
+ *
+ * @return true if Attribute Header's match, false otherwise
+ */
+ bool compareAttributeHeader(
+ const AttributeTank::Attribute* const l_attribute1,
+ const AttributeTank::Attribute* const l_attribute2);
+
+ /**
+ * @test Compare the Attribute Values for the two given attributes
+ *
+ * @param[in] l_attribute1 Attribute to compare with
+ * @param[in] l_attribute2 Attribute to compare with
+ *
+ * @return true if Attribute Values` match, false otherwise
+ */
+ bool compareAttributeValues(
+ const AttributeTank::Attribute* const l_attribute1,
+ const AttributeTank::Attribute* const l_attribute2);
+}; // end class AttributeTest
+
+
+// testSimpleSettersAndGetters
+void AttributeTest::testSimpleSettersAndGetters(void)
+{
+ TRACFCOMP( g_trac_test, ENTER_MRK "testSimpleSettersAndGetters" );
+
+ // Test stats
+ uint8_t l_numTests(0);
+ uint8_t l_numFails(0);
+
+ // Create an Attribute to test against
+ TARGETING::AttributeTank::Attribute l_attribute;
+
+ // Get a reference to the Attribute Header to test that
+ // what is returned is truly a reference and not a copy
+ const TARGETING::AttributeTank::AttributeHeader &l_attributeHeader =
+ l_attribute.getHeader();
+
+ // Test setting/getting the Attribute ID
+ ++l_numTests;
+ l_attribute.setId(0x1001);
+ if (0x1001 != l_attribute.getHeader().iv_attrId)
+ {
+ TS_FAIL("testSimpleSettersAndGetters: Test 1 - "
+ "set/get Attribute ID failed; "
+ "expected 0x1001 but got back 0x%X",
+ l_attribute.getHeader().iv_attrId);
+ ++l_numFails;
+ }
+
+ ++l_numTests;
+ if (0x1001 != l_attributeHeader.iv_attrId)
+ {
+ TS_FAIL("testSimpleSettersAndGetters: Test 2 - get Attribute ID "
+ "via Attribute Header reference failed; "
+ "expected 0x1001 but got back 0x%X",
+ l_attributeHeader.iv_attrId);
+ ++l_numFails;
+ }
+
+ // Test setting/getting the Attribute Target Type
+ ++l_numTests;
+ l_attribute.setTargetType(0x2002);
+ if (0x2002 != l_attribute.getHeader().iv_targetType)
+ {
+ TS_FAIL("testSimpleSettersAndGetters: Test 3 - "
+ "set/get Attribute Target Type failed; "
+ "expected 0x2002 but got back 0x%X",
+ l_attribute.getHeader().iv_targetType);
+ ++l_numFails;
+ }
+
+ ++l_numTests;
+ if (0x2002 != l_attributeHeader.iv_targetType)
+ {
+ TS_FAIL("testSimpleSettersAndGetters: Test 4 - get Attribute "
+ "Target Type via Attribute Header reference failed; "
+ "expected 0x2002 but got back 0x%X",
+ l_attributeHeader.iv_targetType);
+ ++l_numFails;
+ }
+
+ // Test setting/getting the Attribute Position
+ ++l_numTests;
+ l_attribute.setPosition(0x3003);
+ if (0x3003 != l_attribute.getHeader().iv_pos)
+ {
+ TS_FAIL("testSimpleSettersAndGetters: Test 5 - "
+ "set/get Attribute Position failed; "
+ "expected 0x3003 but got back 0x%X",
+ l_attribute.getHeader().iv_pos);
+ ++l_numFails;
+ }
+
+ ++l_numTests;
+ if (0x3003 != l_attributeHeader.iv_pos)
+ {
+ TS_FAIL("testSimpleSettersAndGetters: Test 6 - get Attribute Position "
+ "via Attribute Header reference failed; "
+ "expected 0x3003 but got back 0x%X",
+ l_attributeHeader.iv_pos);
+ ++l_numFails;
+ }
+
+ // Test setting/getting the Attribute Unit Position
+ ++l_numTests;
+ l_attribute.setUnitPosition(0x4);
+ if (0x4 != l_attribute.getHeader().iv_unitPos)
+ {
+ TS_FAIL("testSimpleSettersAndGetters: Test 7 - "
+ "set/get Attribute Unit Position failed; "
+ "expected 0x4 but got back 0x%X",
+ l_attribute.getHeader().iv_unitPos);
+ ++l_numFails;
+ }
+
+ ++l_numTests;
+ if (0x4 != l_attributeHeader.iv_unitPos)
+ {
+ TS_FAIL("testSimpleSettersAndGetters: Test 8 - "
+ "get Attribute Unit Position via Attribute Header reference "
+ "failed; expected 0x4 but got back 0x%X",
+ l_attributeHeader.iv_unitPos);
+ ++l_numFails;
+ }
+
+ // Test setting/getting the Attribute Node
+ ++l_numTests;
+ l_attribute.setNode(0x5);
+ if (0x5 != l_attribute.getHeader().iv_node)
+ {
+ TS_FAIL("testSimpleSettersAndGetters: Test 9 - "
+ "set/get Attribute Node failed; "
+ "expected 0x5 but got back 0x%X",
+ l_attribute.getHeader().iv_node);
+ ++l_numFails;
+ }
+
+ ++l_numTests;
+ if (0x5 != l_attributeHeader.iv_node)
+ {
+ TS_FAIL("testSimpleSettersAndGetters: Test 10 - get Attribute Node "
+ "via Attribute Header reference failed; "
+ "expected 0x5 but got back 0x%X",
+ l_attributeHeader.iv_node);
+ ++l_numFails;
+ }
+
+ // Test setting/getting the Attribute Flags
+ ++l_numTests;
+ l_attribute.setFlags(0x6);
+ if (0x6 != l_attribute.getHeader().iv_flags)
+ {
+ TS_FAIL("testSimpleSettersAndGetters: Test 11 - "
+ "set/get Attribute Flags failed; "
+ "expected 0x6 but got back 0x%X",
+ l_attribute.getHeader().iv_flags);
+ ++l_numFails;
+ }
+
+ ++l_numTests;
+ if (0x6 != l_attributeHeader.iv_flags)
+ {
+ TS_FAIL("testSimpleSettersAndGetters: Test 12 - get Attribute Flags "
+ "via Attribute Header reference failed; "
+ "expected 0x6 but got back 0x%X",
+ l_attributeHeader.iv_flags);
+ ++l_numFails;
+ }
+
+ TRACFCOMP( g_trac_test, EXIT_MRK "testSimpleSettersAndGetters "
+ "num tests = %d / num fails = %d", l_numTests, l_numFails);
+} // end testSimpleSettersAndGetters
+
+
+// testSettingAndGettingValue
+void AttributeTest::testSettingAndGettingValue(void)
+{
+ TRACFCOMP( g_trac_test, ENTER_MRK "testSettingAndGettingValue" );
+
+ // Test stats
+ uint8_t l_numTests(0);
+ uint8_t l_numFails(0);
+
+ // Create an Attribute to test with
+ TARGETING::AttributeTank::Attribute l_attribute;
+
+ /// Test getting Size of the Attribute when no Value exists/has been set
+ ++l_numTests;
+ if (l_attribute.getSize() !=
+ sizeof(TARGETING::AttributeTank::AttributeHeader))
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 1 - "
+ "get Attribute Size failed, when no value set; "
+ "expected size %d but got back size %d",
+ sizeof(TARGETING::AttributeTank::AttributeHeader),
+ l_attribute.getSize());
+ ++l_numFails;
+ }
+
+ /// Test cloning the value when no Value exists/has been set
+ // First create a buffer
+ uint32_t l_bufferSize = 3;
+ uint8_t l_buffer[l_bufferSize] = { 0 };
+ uint8_t l_compareBuffer[l_bufferSize] = { 0 };
+
+ uint32_t l_returnedSize = l_attribute.cloneValue(l_buffer, l_bufferSize);
+ // Make sure 0 is returned
+ ++l_numTests;
+ if (0 != l_returnedSize)
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 2 - "
+ "Attribute clone value failed, with buffer size 0; "
+ "expected size 0 but got back size %d",
+ l_returnedSize);
+ ++l_numFails;
+ }
+
+ // Make sure cloned data is correct
+ ++l_numTests;
+ if (0 != memcmp(l_buffer, l_compareBuffer, l_bufferSize))
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 3 - "
+ "Attribute clone value failed, with buffer size 0; "
+ "incorrect data returned");
+ ++l_numFails;
+ }
+
+ /// Test clearing the Value
+ l_returnedSize = l_attribute.setValue(nullptr, 0);
+ // Make sure 0 is returned
+ ++l_numTests;
+ if (0 != l_returnedSize)
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 4 - "
+ "returned Attribute Size failed, sent a value of size 0; "
+ "expected size 0 but got back size %d",
+ l_returnedSize);
+ ++l_numFails;
+ }
+
+ // Make sure size is only the Attribute Header size
+ ++l_numTests;
+ if (l_attribute.getSize() !=
+ sizeof(TARGETING::AttributeTank::AttributeHeader))
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 5 - "
+ "get Attribute Size failed, sent a value of size 0; "
+ "expected size %d but got back size %d",
+ sizeof(TARGETING::AttributeTank::AttributeHeader),
+ l_attribute.getSize());
+ ++l_numFails;
+ }
+
+ // Make sure value is NULL
+ ++l_numTests;
+ if (nullptr != l_attribute.getValue())
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 6 - "
+ "get Attribute Value failed, sent a value of size 0; "
+ "expected nullptr but got back %p",
+ l_attribute.getValue());
+ ++l_numFails;
+ }
+
+ /// Send in buffer with smaller size than actual size of buffer
+ // Add data o the buffer
+ l_buffer[0] = 0xAA;
+ l_buffer[1] = 0xBB;
+ l_buffer[2] = 0xCC;
+
+ // Set the Attribute Value to the buffer's first element
+ l_returnedSize = l_attribute.setValue(l_buffer, 1);
+ // Make sure only 1 is returned
+ ++l_numTests;
+ if (1 != l_returnedSize)
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 7 - "
+ "returned Attribute Size failed, sent a value of size 1; "
+ "expected size 1 but got back size %d",
+ l_returnedSize);
+ ++l_numFails;
+ }
+
+ // Make sure Attribute Value size is size of Attribute Header plus one
+ ++l_numTests;
+ if (l_attribute.getSize() !=
+ (sizeof(TARGETING::AttributeTank::AttributeHeader) + 1))
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 8 - "
+ "get Attribute Size failed, sent a Value of size 1 "
+ "expected size %d but got back size %d",
+ sizeof(TARGETING::AttributeTank::AttributeHeader) + 1,
+ l_attribute.getSize());
+ ++l_numFails;
+ }
+
+ // Get a handle to the Value to do some testing on it
+ const uint8_t* const l_value =
+ reinterpret_cast<const uint8_t* const>(l_attribute.getValue());
+
+ // Make sure Value is not NULL
+ ++l_numTests;
+ if (nullptr == l_value)
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 9 - "
+ "get Attribute Value failed; "
+ "expected a non-null pointer but got back a null pointer");
+ ++l_numFails;
+ }
+
+ // Make sure the first value is what we expect
+ ++l_numTests;
+ if (l_value[0] != 0xAA)
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 10 - "
+ "Accessing first value in Attribute Value failed; "
+ "expected 0xAA but got back 0x%X",
+ l_value[0]);
+ ++l_numFails;
+ }
+
+ // Test cloning with Attribute
+ uint8_t l_clonedBuffer[l_bufferSize] = { 0 };
+ memset(l_compareBuffer, 0, l_bufferSize);
+ l_compareBuffer[0] = 0xAA;
+ l_returnedSize = l_attribute.cloneValue(l_clonedBuffer, l_bufferSize);
+ // Make sure 1 is returned
+ ++l_numTests;
+ if (1 != l_returnedSize)
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 11 - "
+ "Attribute clone value failed, with buffer size 1; "
+ "expected size 1 but got back size %d",
+ l_returnedSize);
+ ++l_numFails;
+ }
+
+ // Make sure the cloned data is correct
+ ++l_numTests;
+ if (0 != memcmp(l_clonedBuffer, l_compareBuffer, l_bufferSize))
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 12 - "
+ "Attribute clone value failed, with buffer size 1; "
+ "incorrect data returned");
+ ++l_numFails;
+ }
+
+ /// Send in buffer with actual size of said buffer
+ // First set the buffer's values
+ l_buffer[0] = 0xDD;
+ l_buffer[1] = 0xEE;
+ l_buffer[2] = 0xFF;
+ l_returnedSize = l_attribute.setValue(l_buffer, l_bufferSize);
+
+ // Make sure buffer size is returned correctly
+ ++l_numTests;
+ if (l_bufferSize != l_returnedSize)
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 13 - "
+ "returned Attribute Size failed, sent a buffer of size %d; "
+ "expected size %d but got back size %d",
+ l_bufferSize,
+ l_bufferSize,
+ l_returnedSize);
+ ++l_numFails;
+ }
+
+ // Make sure Attribute Value size is size of Attribute Header
+ // plus buffer size
+ ++l_numTests;
+ if (l_attribute.getSize() !=
+ (sizeof(TARGETING::AttributeTank::AttributeHeader) + l_bufferSize))
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 14 - "
+ "get Attribute Size failed, sent a buffer of size %d; "
+ "expected size %d but got back size %d",
+ l_bufferSize,
+ sizeof(TARGETING::AttributeTank::AttributeHeader) + l_bufferSize,
+ l_attribute.getSize());
+ ++l_numFails;
+ }
+
+ // Get a handle to the Value to do some testing on it
+ const uint8_t* const l_value2 =
+ reinterpret_cast<const uint8_t* const>(l_attribute.getValue());
+
+ // Make sure Value is not NULL
+ ++l_numTests;
+ if (nullptr == l_value2)
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 15 - "
+ "get Attribute Value failed, sent a buffer of size %d "
+ "expected a non-null pointer but got back a null pointer",
+ l_bufferSize);
+ ++l_numFails;
+ }
+
+ // Make sure the first value is what we expect
+ ++l_numTests;
+ if (l_value2[0] != 0xDD)
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 16 - "
+ "Accessing first value in Attribute Value failed, "
+ "for a Value of size %d; "
+ "expected 0xDD but got back 0x%X",
+ l_bufferSize,
+ l_value2[0]);
+ ++l_numFails;
+ }
+
+ // Make sure the second value is what we expect
+ ++l_numTests;
+ if (l_value2[1] != 0xEE)
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 17 - "
+ "Accessing second value in Attribute Value failed, "
+ "for a Value of size %d; "
+ "expected 0xEE but got back 0x%X",
+ l_bufferSize,
+ l_value2[1]);
+ ++l_numFails;
+ }
+
+ // Make sure the third value is what we expect
+ ++l_numTests;
+ if (l_value2[2] != 0xFF)
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 18 - "
+ "Accessing third value in Attribute Value failed, "
+ "for a Value of size %d; "
+ "expected 0xFF but got back 0x%X",
+ l_bufferSize,
+ l_value2[2]);
+ ++l_numFails;
+ }
+
+ /// Make sure previously cloned data is an actually cloned and not
+ /// a copy
+ ++l_numTests;
+ if (0 != memcmp(l_clonedBuffer, l_compareBuffer, l_bufferSize))
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 19 - "
+ "Attribute clone value failed, with buffer size 1; "
+ "data not cloned but is a reference a pointer");
+ ++l_numFails;
+ }
+
+ l_returnedSize = l_attribute.cloneValue(l_clonedBuffer, l_bufferSize);
+ // Make sure 3 is returned
+ ++l_numTests;
+ if (3 != l_returnedSize)
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 20 - "
+ "returned Attribute clone value failed, with buffer size 3; "
+ "expected size 3 but got back size %d",
+ l_returnedSize);
+ ++l_numFails;
+ }
+
+ /// Make sure previously cloned data is correct
+ ++l_numTests;
+ if (0 != memcmp(l_clonedBuffer, l_buffer, l_bufferSize))
+ {
+ TS_FAIL("testSettingAndGettingValue: Test 21 - "
+ "Attribute clone value failed, with buffer size 3 ; "
+ "incorrect data returned");
+ ++l_numFails;
+ }
+
+ TRACFCOMP( g_trac_test, EXIT_MRK "testSettingAndGettingValue "
+ "num tests = %d / num fails = %d", l_numTests, l_numFails);
+} // end AttributeTest::testSettingAndGettingValue
+
+
+// testSerializeAndDeserializeMethod
+void AttributeTest::testSerializeAndDeserializeMethod(void)
+{
+ TRACFCOMP( g_trac_test, ENTER_MRK "testSerializeAndDeserializeMethod" );
+
+ // Test stats
+ uint8_t l_numTests(0);
+ uint8_t l_numFails(0);
+
+ // Create an Attribute to test with
+ AttributeTank::Attribute l_attribute;
+ // Get a copy of the Attribute Size for later purposes
+ uint32_t l_attributeSize(l_attribute.getSize());
+
+ /// Test serializing when attribute has no data at all
+ {
+ // Create a buffer to hold serialized data
+ uint8_t* l_serializedData = new uint8_t[l_attributeSize];
+ // Get the serialized data
+ uint32_t l_returnedSize = l_attribute.serialize(l_serializedData,
+ l_attributeSize);
+
+ // Make sure serialized data is the size expected
+ ++l_numTests;
+ if (l_returnedSize != l_attributeSize)
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 1 - "
+ "Attribute Serialize failed, with a 0 size Data Value; "
+ "expected size %d but got back size %d",
+ l_attributeSize,
+ l_returnedSize);
+ ++l_numFails;
+ }
+
+ // Make sure the serialized Attribute Header
+ // matches original Attribute Header
+ // Get a handle to Attribute Header
+ AttributeTank::Attribute* l_attribute2 =
+ reinterpret_cast<AttributeTank::Attribute*>(l_serializedData);
+ const AttributeTank::AttributeHeader & l_attributeHeader2 =
+ l_attribute2->getHeader();
+
+ // Compare the two different Attribute Header for a match
+ ++l_numTests;
+ if (!compareAttributeHeader(l_attribute2, &l_attribute))
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 2 - "
+ "Attribute Serialize failed, with a 0 size Data Value; "
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Make sure that the size of the Attribute Values is zero
+ ++l_numTests;
+ if (0 != l_attributeHeader2.iv_valSize)
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 3 - "
+ "Attribute Serialize failed, with a 0 size Data Value; "
+ "Expected 0 size Data Value but %d was returned",
+ l_attributeHeader2.iv_valSize);
+ ++l_numFails;
+ }
+
+ // Test deserialize
+ {
+ AttributeTank::Attribute l_attribute3;
+ uint32_t l_returnedSize2 =
+ l_attribute3.deserialize(l_serializedData, l_returnedSize);
+
+ // Make sure data size copied is correct
+ ++l_numTests;
+ if (l_returnedSize2 != l_returnedSize)
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 4 - "
+ "Attribute Deserialize failed, with a 0 size Data Value; "
+ "expected size %d but got back size %d",
+ l_returnedSize,
+ l_returnedSize2);
+ ++l_numFails;
+ }
+
+ // Make sure the Attribute Header matches original data
+ ++l_numTests;
+ if (!compareAttributeHeader(&l_attribute3, &l_attribute))
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 5 - "
+ "Attribute deserialize failed, with a 0 size Data Value; "
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Test when buffer is too small
+ ++l_numTests;
+ AttributeTank::Attribute l_attribute4;
+ l_returnedSize2 = l_attribute4.deserialize(l_serializedData,
+ l_returnedSize - 1);
+ if (0 != l_returnedSize2)
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 6 - "
+ "Attribute Deserialize failed, with too small of buffer;"
+ "expected size 0 but got back size %d",
+ l_returnedSize2);
+ ++l_numFails;
+ }
+ }
+ // Cleanup memory used for this test
+ delete []l_serializedData;
+ l_serializedData = nullptr;
+ }
+
+ /// Test serializing when Attribute has Attribute Header data
+ /// and no Attribute Values
+ // Set some values for the Attribute Header
+ l_attribute.setId(0x1001);
+ l_attribute.setTargetType(0x2002);
+ l_attribute.setPosition(0x3003);
+ l_attribute.setUnitPosition(0x4);
+ l_attribute.setNode(0x5);
+ l_attribute.setFlags(0x6);
+ {
+ // Create a buffer to hold serialized data
+ uint8_t* l_serializedData = new uint8_t[l_attributeSize];
+ // Get the serialized data
+ uint32_t l_returnedSize = l_attribute.serialize(l_serializedData,
+ l_attributeSize);
+
+ // Make sure serialized data is the size expected
+ ++l_numTests;
+ if (l_returnedSize != l_attributeSize)
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 7 - "
+ "Attribute Serialize failed, with valid Attribute "
+ "Header data and no Data Value;"
+ "expected size %d but got back size %d",
+ l_attributeSize,
+ l_returnedSize);
+ ++l_numFails;
+ }
+
+ // Make sure the serialized Attribute Header
+ // matches original Attribute Header
+ // Get a handle to Attribute Header
+ AttributeTank::Attribute* l_attribute2 =
+ reinterpret_cast<AttributeTank::Attribute*>(l_serializedData);
+ const AttributeTank::AttributeHeader & l_attributeHeader2 =
+ l_attribute2->getHeader();
+ // Compare the two different Attribute Header for a match
+ ++l_numTests;
+ if (!compareAttributeHeader(l_attribute2, &l_attribute))
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 8 - "
+ "Attribute Serialize failed, with valid Attribute "
+ "Header data and no Data Value;"
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Make sure that the size of the Attribute Values is zero
+ ++l_numTests;
+ if (0 != l_attributeHeader2.iv_valSize)
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 9 - "
+ "Attribute Serialize failed, with valid Attribute "
+ "Header data and no Data Value;"
+ "Expected 0 size Data Value but %d was returned",
+ l_attributeHeader2.iv_valSize);
+ ++l_numFails;
+ }
+
+ // Test deserialize
+ {
+ AttributeTank::Attribute l_attribute3;
+ uint32_t l_returnedSize2 =
+ l_attribute3.deserialize(l_serializedData, l_returnedSize);
+
+ // Make sure data size copied is correct
+ ++l_numTests;
+ if (l_returnedSize2 != l_returnedSize)
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 10 - "
+ "Attribute Deserialize failed, with valid Attribute "
+ "Header data and no Data Value;"
+ "expected size %d but got back size %d",
+ l_returnedSize,
+ l_returnedSize2);
+ ++l_numFails;
+ }
+
+ // Make sure the Attribute Header matches original data
+ ++l_numTests;
+ if (!compareAttributeHeader(&l_attribute3, &l_attribute))
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 11 - "
+ "Attribute Deserialize failed, with valid Attribute "
+ "Header data and no Data Value;"
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+ }
+
+ // Cleanup memory used for this test
+ delete []l_serializedData;
+ l_serializedData = nullptr;
+ }
+
+ /// Test serializing when Attribute has Attribute Header data
+ /// and a single Attribute Value
+ // Give the Attribute a single Attribute Value
+ uint8_t l_dataBuffer[1] = { 0 };
+ l_dataBuffer[0] = 0x44;
+ l_attribute.setValue(l_dataBuffer, 1);
+ l_attributeSize = l_attribute.getSize();
+ {
+ // Create a buffer to hold serialized data
+ uint8_t* l_serializedData = new uint8_t[l_attributeSize];
+ // Get the serialized data
+ uint32_t l_returnedSize = l_attribute.serialize(l_serializedData,
+ l_attributeSize);
+
+ // Make sure serialized data is the size expected
+ ++l_numTests;
+ if (l_returnedSize != l_attributeSize)
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 12 - "
+ "Attribute Serialize failed, with a size 1 Data Value; "
+ "expected size %d but got back size %d",
+ l_attributeSize,
+ l_returnedSize);
+ ++l_numFails;
+ }
+
+ // Make sure the serialized Attribute Header
+ // matches original Attribute Header
+ // Get a handle to Attribute Header
+ AttributeTank::Attribute* l_attribute2 =
+ reinterpret_cast<AttributeTank::Attribute*>(l_serializedData);
+ const AttributeTank::AttributeHeader & l_attributeHeader2 =
+ l_attribute2->getHeader();
+ // Compare the two different Attribute Header for a match
+ ++l_numTests;
+ if (!compareAttributeHeader(l_attribute2, &l_attribute))
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 13 - "
+ "Attribute Serialize failed, with a size 1 Data Value; "
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Make sure that the size of the Attribute Values is 1
+ ++l_numTests;
+ if (1 != l_attributeHeader2.iv_valSize)
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 14 - "
+ "Attribute Serialize failed, with a size 1 Data Value; "
+ "Expected 1 size Data Value but %d was returned",
+ l_attributeHeader2.iv_valSize);
+ ++l_numFails;
+ }
+
+ // Point to the Attribute Values
+ l_serializedData += sizeof(AttributeTank::AttributeHeader);
+
+ // Compare the two different Attribute Value
+ ++l_numTests;
+ if (0 != memcmp(l_serializedData, &l_dataBuffer, 1))
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 15 - "
+ "Attribute Serialize failed, with a size 1 Data Value; "
+ "incorrect Attribute Data Value returned");
+ ++l_numFails;
+ }
+
+ // Reset the Serialized Data for next test
+ l_serializedData -= sizeof(AttributeTank::AttributeHeader);
+
+ // Test deserialize
+ {
+ AttributeTank::Attribute l_attribute3;
+ uint32_t l_returnedSize2 =
+ l_attribute3.deserialize(l_serializedData, l_returnedSize);
+ // Make sure data size copied is correct
+ ++l_numTests;
+ if (l_returnedSize2 != l_returnedSize)
+ {
+
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 16 - "
+ "Attribute Deserialize failed, with a size 1 Data Value; "
+ "expected size %d but got back size %d",
+ l_returnedSize,
+ l_returnedSize2);
+ ++l_numFails;
+ }
+
+ // Make sure the Attribute Header matches original data
+ ++l_numTests;
+ if (!compareAttributeHeader(&l_attribute3, &l_attribute))
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 17 - "
+ "Attribute deserialize failed, with a size 1 Data Value; "
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Test when buffer is too small
+ AttributeTank::Attribute l_attribute4;
+ l_returnedSize2 = l_attribute4.deserialize(l_serializedData,
+ l_returnedSize - 1);
+
+ // Make sure returned size is 0
+ ++l_numTests;
+ if (0 != l_returnedSize2)
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 18 - "
+ "Attribute Deserialize failed, with too small of buffer "
+ "for 1 data value; expected size 0 but got back size %d",
+ l_returnedSize2);
+ ++l_numFails;
+ }
+ }
+
+ // Cleanup memory used for this test
+ delete []l_serializedData;
+ l_serializedData = nullptr;
+ }
+
+ /// Test serializing when Attribute has Attribute Header data
+ /// and a several Attribute Values
+ // Give the Attribute several Attribute Values
+ uint32_t l_bufferSize(3);
+ uint8_t l_dataBuffer2[l_bufferSize] = { 0 };
+ l_dataBuffer2[0] = 0x55;
+ l_dataBuffer2[1] = 0x66;
+ l_dataBuffer2[2] = 0x77;
+ l_attribute.setValue(l_dataBuffer2, l_bufferSize);
+ l_attributeSize = l_attribute.getSize();
+ {
+ // Create a buffer to hold serialized data
+ uint8_t* l_serializedData = new uint8_t[l_attributeSize];
+ // Get the serialized data
+ uint32_t l_returnedSize = l_attribute.serialize(l_serializedData,
+ l_attributeSize);
+
+ // Make sure serialized data is the size expected
+ ++l_numTests;
+ if (l_returnedSize != l_attributeSize)
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 19 - "
+ "Attribute Serialize failed, with a size 3 Data Value; "
+ "expected size %d but got back size %d",
+ l_attributeSize,
+ l_returnedSize);
+ ++l_numFails;
+ }
+
+ // Make sure the serialized Attribute Header
+ // matches original Attribute Header
+ // Get a handle to Attribute Header
+ AttributeTank::Attribute* l_attribute2 =
+ reinterpret_cast<AttributeTank::Attribute*>(l_serializedData);
+
+ // Compare the two different Attribute Header for a match
+ ++l_numTests;
+ if (!compareAttributeHeader(l_attribute2, &l_attribute))
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 20 - "
+ "Attribute Serialize failed, with a size 3 Data Value; "
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Make sure that the size of the Attribute Values is 3
+ ++l_numTests;
+ if (l_bufferSize != l_attribute2->getHeader().iv_valSize)
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 21 - "
+ "Attribute Serialize failed, with a size 3 Data Value; "
+ "Expected %d size Data Value but %d was returned",
+ l_bufferSize,
+ l_attribute2->getHeader().iv_valSize);
+
+ ++l_numFails;
+ }
+
+ // Point to the Attribute Values
+ l_serializedData += sizeof(AttributeTank::AttributeHeader);
+
+
+ // Compare the two different Attribute Value
+ ++l_numTests;
+ if (0 != memcmp(l_serializedData, &l_dataBuffer2, l_bufferSize))
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 22 - "
+ "Attribute Serialize failed, with a size 3 Data Value; "
+ "incorrect Attribute Data Values returned");
+ ++l_numFails;
+ }
+
+ // Reset the Serialized Data for next test
+ l_serializedData -= sizeof(AttributeTank::AttributeHeader);
+
+ // Test deserialize
+ {
+ AttributeTank::Attribute l_attribute3;
+ uint32_t l_returnedSize2 =
+ l_attribute3.deserialize(l_serializedData, l_returnedSize);
+
+ // Make sure data size copied is correct
+ ++l_numTests;
+ if (l_returnedSize2 != l_returnedSize)
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 23 - "
+ "Attribute Deserialize failed, with a size 3 Data Value; "
+ "expected size %d but got back size %d",
+ l_returnedSize,
+ l_returnedSize2);
+ ++l_numFails;
+ }
+
+ // Make sure the Attribute Header matches original data
+ ++l_numTests;
+ if (!compareAttributeHeader(&l_attribute3, &l_attribute))
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 24 - "
+ "Attribute Deserialize failed, with a size 3 Data Value; "
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Test when buffer is too small
+ AttributeTank::Attribute l_attribute4;
+ l_returnedSize2 = l_attribute4.deserialize(l_serializedData,
+ l_returnedSize - 1);
+
+ // Make sure returned size is 0
+ ++l_numTests;
+ if (0 != l_returnedSize2)
+ {
+ TS_FAIL("testSerializeAndDeserializeMethod: Test 25 - "
+ "Attribute Deserialize failed, with too small of buffer "
+ "for 3 data values; expected size 0 but got back size %d",
+ l_returnedSize2);
+ ++l_numFails;
+ }
+ }
+
+ // Cleanup memory used for this test
+ delete []l_serializedData;
+ l_serializedData = nullptr;
+ }
+
+ TRACFCOMP( g_trac_test, EXIT_MRK "testSerializeAndDeserializeMethod "
+ "num tests = %d / num fails = %d", l_numTests, l_numFails);
+} // end AttributeTest::testSerializeAndDeserializeMethod
+
+// testOperatorEqual
+void AttributeTest::testOperatorEqual(void)
+{
+ TRACFCOMP( g_trac_test, ENTER_MRK "testOperatorEqual" );
+
+ // Test stats
+ uint8_t l_numTests(0);
+ uint8_t l_numFails(0);
+
+ // Create an Attribute to test against
+ AttributeTank::Attribute l_attribute1;
+
+ // Test with an empty attribute
+ AttributeTank::Attribute l_attribute2;
+ // Invoke Operator Equal
+ l_attribute2 = l_attribute1;
+
+ // Make sure the Attribute Header match
+ ++l_numTests;
+ if (!compareAttributeHeader(&l_attribute1, &l_attribute2))
+ {
+ TS_FAIL("testOperatorEqual: Test 1 - "
+ "Attribute Operator = failed, with default values; "
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Modify the data
+ l_attribute1.setId(0x1001);
+ l_attribute1.setTargetType(0x2002);
+ l_attribute1.setPosition(0x3003);
+ l_attribute1.setUnitPosition(0x4);
+ l_attribute1.setNode(0x5);
+ l_attribute1.setFlags(0x6);
+
+ // Test with modified data
+ AttributeTank::Attribute l_attribute3;
+ // Invoke Operator Equal
+ l_attribute3 = l_attribute1;
+
+ // Make sure the Attribute Header match
+ ++l_numTests;
+ if (!compareAttributeHeader(&l_attribute1, &l_attribute3))
+ {
+ TS_FAIL("testOperatorEqual: Test 2 - "
+ "Attribute Operator = failed, with modifed values; "
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Add attribute values
+ uint32_t l_bufferSize(3);
+ uint8_t l_buffer[l_bufferSize];
+ l_buffer[0] = 0x66;
+ l_buffer[0] = 0x77;
+ l_buffer[0] = 0x88;
+ l_attribute1.setValue(l_buffer, l_bufferSize);
+
+ // Test with modified data
+ AttributeTank::Attribute l_attribute4;
+ // Invoke Operator Equal
+ l_attribute4 = l_attribute1;
+
+ // Make sure the Attribute Header match
+ ++l_numTests;
+ if (!compareAttributeHeader(&l_attribute1, &l_attribute4))
+ {
+ TS_FAIL("testOperatorEqual: Test 3 - "
+ "Attribute Operator = failed, with data values; "
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Make sure the Attribute Values match
+ ++l_numTests;
+ if (!compareAttributeValues(&l_attribute1, &l_attribute4))
+ {
+ TS_FAIL("testOperatorEqual: Test 4 - "
+ "Attribute Operator = failed, with data values; "
+ "incorrect Attribute Values data returned");
+ ++l_numFails;
+ }
+
+ // Update the Attribute Values and test again
+ l_buffer[0] = 0x22;
+ l_buffer[0] = 0x33;
+ l_buffer[0] = 0x55;
+ l_attribute1.setValue(l_buffer, l_bufferSize);
+
+ // Make sure the Attribute Header match original data
+ ++l_numTests;
+ if (!compareAttributeHeader(&l_attribute1, &l_attribute4))
+ {
+ TS_FAIL("testOperatorEqual: Test 5 - "
+ "Attribute Operator = failed, with data values updated; "
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Make sure the Attribute Values DO NOT match
+ ++l_numTests;
+ if (compareAttributeValues(&l_attribute1, &l_attribute4))
+ {
+ TS_FAIL("testOperatorEqual: Test 6 - "
+ "Attribute Operator = failed, with data values updated; "
+ "incorrect Attribute Values data returned");
+ ++l_numFails;
+ }
+
+ TRACFCOMP( g_trac_test, EXIT_MRK "testOperatorEqual "
+ "num tests = %d / num fails = %d", l_numTests, l_numFails);
+} // end testOperatorEqual
+
+// testCopyConstructor
+void AttributeTest::testCopyConstructor(void)
+{
+ TRACFCOMP( g_trac_test, ENTER_MRK "testCopyConstructor" );
+
+ // Test stats
+ uint8_t l_numTests(0);
+ uint8_t l_numFails(0);
+
+ // Create an Attribute to test against
+ AttributeTank::Attribute l_attribute1;
+
+ l_attribute1.setId(0x1001);
+ l_attribute1.setFlags(0x5);
+
+ // Test with an empty attribute, invoke copy constructor
+ AttributeTank::Attribute l_attribute2 = l_attribute1;
+
+ // Make sure the Attribute Header match
+ ++l_numTests;
+ if (!compareAttributeHeader(&l_attribute1, &l_attribute2))
+ {
+ TS_FAIL("testCopyConstructor: Test 1 - "
+ "Attribute Copy Ctor failed, with default values; "
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Modify the data
+ l_attribute1.setId(0x1001);
+ l_attribute1.setTargetType(0x2002);
+ l_attribute1.setPosition(0x3003);
+ l_attribute1.setUnitPosition(0x4);
+ l_attribute1.setNode(0x5);
+ l_attribute1.setFlags(0x6);
+
+ // Test with modified data, invoke copy constructor
+ AttributeTank::Attribute l_attribute3 = l_attribute1;
+
+ // Make sure the Attribute Header match
+ ++l_numTests;
+ if (!compareAttributeHeader(&l_attribute1, &l_attribute3))
+ {
+ TS_FAIL("testCopyConstructor: Test 2 - "
+ "Attribute Copy Ctor failed, with modifed values; "
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Add attribute values
+ uint32_t l_bufferSize(3);
+ uint8_t l_buffer[l_bufferSize];
+ l_buffer[0] = 0x66;
+ l_buffer[0] = 0x77;
+ l_buffer[0] = 0x88;
+ l_attribute1.setValue(l_buffer, l_bufferSize);
+
+ // Test with modified data, invoke copy constructor
+ AttributeTank::Attribute l_attribute4 = l_attribute1;
+
+ // Make sure the Attribute Header match
+ ++l_numTests;
+ if (!compareAttributeHeader(&l_attribute1, &l_attribute4))
+ {
+ TS_FAIL("testCopyConstructor: Test 3 - "
+ "Attribute Copy Ctor failed, with data values; "
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Make sure the Attribute Values match
+ ++l_numTests;
+ if (!compareAttributeValues(&l_attribute1, &l_attribute4))
+ {
+ TS_FAIL("testCopyConstructor: Test 4 - "
+ "Attribute Copy Ctor failed, with data values; "
+ "incorrect Attribute Values data returned");
+ ++l_numFails;
+ }
+
+ // Update the Attribute Values and test again
+ l_buffer[0] = 0x22;
+ l_buffer[0] = 0x33;
+ l_buffer[0] = 0x55;
+ l_attribute1.setValue(l_buffer, l_bufferSize);
+
+ // Make sure the Attribute Header match original data
+ ++l_numTests;
+ if (!compareAttributeHeader(&l_attribute1, &l_attribute4))
+ {
+ TS_FAIL("testCopyConstructor: Test 5 - "
+ "Attribute Copy Ctor failed, with data values updated; "
+ "incorrect Attribute Header data returned");
+ ++l_numFails;
+ }
+
+ // Make sure the Attribute Values DO NOT match
+ ++l_numTests;
+ if (compareAttributeValues(&l_attribute1, &l_attribute4))
+ {
+ TS_FAIL("testCopyConstructor: Test 6 - "
+ "Attribute Copy Ctor failed, with data values updated; "
+ "incorrect Attribute Values data returned");
+ ++l_numFails;
+ }
+
+ TRACFCOMP( g_trac_test, EXIT_MRK "testCopyConstructor "
+ "num tests = %d / num fails = %d", l_numTests, l_numFails);
+} // end testCopyConstructor
+
+// compareAttributeHeader
+bool AttributeTest::compareAttributeHeader(
+ const AttributeTank::Attribute* const l_attribute1,
+ const AttributeTank::Attribute* const l_attribute2)
+{
+ bool retVal(true);
+
+ // Make sure the Attribute Header matches original data
+ if (0 != memcmp(&(l_attribute1->getHeader()),
+ &(l_attribute2->getHeader()),
+ sizeof(AttributeTank::AttributeHeader)))
+ {
+ retVal = false;
+ }
+
+ return retVal;
+
+} // end compareAttributeHeader
+
+// compareAttributeValues
+bool AttributeTest::compareAttributeValues(
+ const AttributeTank::Attribute* const l_attribute1,
+ const AttributeTank::Attribute* const l_attribute2)
+{
+ bool retVal(true);
+
+ // Compare the Attribute Values for a match
+ if (0 != memcmp(l_attribute1->getValue(),
+ l_attribute2->getValue(),
+ l_attribute2->getHeader().iv_valSize))
+ {
+ retVal = false;
+ }
+
+ return retVal;
+
+} // end compareAttributeValues
+
+#endif // end __TEST_ATTRIBUTE_H
diff --git a/src/usr/targeting/test/testTargetUtil.H b/src/usr/targeting/test/testTargetUtil.H
new file mode 100644
index 000000000..1cfc8412f
--- /dev/null
+++ b/src/usr/targeting/test/testTargetUtil.H
@@ -0,0 +1,458 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/targeting/test/testTargetUtil.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __TEST_TARGETING_UTIL_H
+#define __TEST_TARGETING_UTIL_H
+
+/**
+ * @file targeting/test/testTargetUtil.H
+ *
+ * @brief Unit test for the templates makeAttribute
+ * and makeAttributeStdArr
+ */
+
+//******************************************************************************
+// Includes
+//******************************************************************************
+
+// CXX TEST
+#include <cxxtest/TestSuite.H>
+
+#include <targeting/common/targetUtil.H>
+
+using namespace TARGETING;
+
+//******************************************************************************
+// class MakeAttributeTest
+//******************************************************************************
+class MakeAttributeTest: public CxxTest::TestSuite
+{
+public:
+
+ /**
+ * @test Test the Make Attribute template
+ */
+ void testMakeAttribute(void);
+
+ /**
+ * @test Test the Make Attribute for Standard Array template
+ */
+ void testMakeAttributeStdArr(void);
+
+}; // end class MakeAttributeTest
+
+// testMakeAttribute
+void MakeAttributeTest::testMakeAttribute(void)
+{
+ TRACFCOMP( g_trac_test, ENTER_MRK "testMakeAttribute" );
+
+ // Test stats
+ uint8_t l_numTests(0);
+ uint8_t l_numFails(0);
+
+ if (!TARGETING::targetService().isInitialized())
+ {
+ TS_FAIL("testMakeAttribute: Target Service is not initialized, "
+ "cannot perform test, exiting");
+
+ TRACFCOMP( g_trac_test, EXIT_MRK "testMakeAttribute "
+ "num tests = 1 / num fails = 1");
+ return;
+ }
+
+ // Get the top level target
+ TARGETING::Target * l_sys(nullptr);
+ TARGETING::targetService().getTopLevelTarget( l_sys );
+
+ if(!l_sys)
+ {
+ TS_FAIL("testMakeAttribute: Get Top Level Target failed, "
+ "unable to get top level target, cannot perform "
+ "test, exiting");
+
+ TRACFCOMP( g_trac_test, EXIT_MRK "testMakeAttribute "
+ "num tests = 1 / num fails = 1");
+ return;
+ }
+
+ // Save initial value to restore later
+ uint8_t l_simpleTypeRestoreValue =
+ l_sys->getAttr<TARGETING::ATTR_IS_SIMULATION>();
+
+ // Test 1, test a simple attribute with known data
+ ++l_numTests;
+ do
+ {
+ // Set the attribute 'Is Simulation' to a known value to
+ // facilitate testing
+ uint8_t l_isSimulationSet = 1;
+ l_sys->setAttr<TARGETING::ATTR_IS_SIMULATION>(l_isSimulationSet);
+ uint8_t l_isSimulationReturn =
+ l_sys->getAttr<TARGETING::ATTR_IS_SIMULATION>();
+
+ // Verify setting the attribute worked
+ if (l_isSimulationSet != l_isSimulationReturn)
+ {
+ TS_FAIL("testMakeAttribute: Test 1 - Setting attribute failed "
+ "to initialize attribute to %d but retained "
+ "value at %d, cannot perform test, exiting",
+ l_isSimulationSet,
+ l_isSimulationReturn);
+ ++l_numFails;
+ break;
+ }
+
+ // Retrieve that set attribute back via the 'make attribute' call
+ TARGETING::AttributeTank::Attribute l_attribute;
+ bool l_return =
+ TARGETING::makeAttribute<TARGETING::ATTR_IS_SIMULATION>
+ (l_sys, l_attribute);
+
+ // Verify the called worked
+ if (true != l_return)
+ {
+ TS_INFO("testMakeAttribute: Test 1 - Make attribute call failed");
+ ++l_numFails;
+ break;
+ }
+
+ // Get a pointer to the attribute created in make attribute call,
+ // to get to the data.
+ const uint8_t* l_attributeValue =
+ static_cast<const uint8_t*>(l_attribute.getValue());
+
+ // If the pointer to the data is NULL, then the make attribute did fail
+ if (l_attributeValue == nullptr)
+ {
+ TS_INFO("testMakeAttribute: Test 1 - Getting attribute value "
+ "failed, NULL pointer returned when getting value.");
+ ++l_numFails;
+ break;
+ }
+
+ // Verify the returned attribute matches it's set value
+ if (*l_attributeValue != l_isSimulationSet)
+ {
+ TS_INFO("testMakeAttribute: Test 1 - Retrieved attribute value "
+ "failed, retrieved attribute value(%d) does not "
+ "match set attribute value(%d)",
+ l_isSimulationSet,
+ *l_attributeValue);
+ ++l_numFails;
+ break;
+ }
+ }
+ while (0);
+
+ // Test 2, test the same simple attribute but with different data
+ ++l_numTests;
+ do
+ {
+ // Set the attribute 'Is Simulation' to a known value to
+ // facilitate testing
+ uint8_t l_isSimulationSet = 5;
+ l_sys->setAttr<TARGETING::ATTR_IS_SIMULATION>(l_isSimulationSet);
+ uint8_t l_isSimulationReturn =
+ l_sys->getAttr<TARGETING::ATTR_IS_SIMULATION>();
+
+ // Verify setting the attribute worked
+ if (l_isSimulationSet != l_isSimulationReturn)
+ {
+ TS_FAIL("testMakeAttribute: Test 2 - Setting attribute failed "
+ "to initialize attribute to %d but retained "
+ "value at %d, cannot perform test, exiting",
+ l_isSimulationSet,
+ l_isSimulationReturn);
+ ++l_numFails;
+ break;
+ }
+
+ // Retrieve that set attribute back via the 'make attribute' call
+ TARGETING::AttributeTank::Attribute l_attribute;
+ bool l_return =
+ TARGETING::makeAttribute<TARGETING::ATTR_IS_SIMULATION>
+ (l_sys, l_attribute);
+
+ // Verify the called worked
+ if (true != l_return)
+ {
+ TS_INFO("testMakeAttribute: Test 2 - Make attribute call failed");
+ ++l_numFails;
+ break;
+ }
+
+ // Get a pointer to the attribute created in make attribute call,
+ // to get to the data.
+ const uint8_t* l_attributeValue =
+ static_cast<const uint8_t*>(l_attribute.getValue());
+
+ // If the pointer to the data is NULL, then the make attribute did fail
+ if (l_attributeValue == nullptr)
+ {
+ TS_INFO("testMakeAttribute: Test 1 - Getting attribute value "
+ "failed, NULL pointer returned when getting value.");
+ ++l_numFails;
+ break;
+ }
+
+ // Verify the returned attribute matches it's set value
+ if (*l_attributeValue != l_isSimulationSet)
+ {
+ TS_INFO("testMakeAttribute: Test 2 - Retrieved attribute value "
+ "failed, retrieved attribute value(%d) does not "
+ "match set attribute value(%d)",
+ l_isSimulationSet,
+ *l_attributeValue);
+ ++l_numFails;
+ break;
+ }
+ }
+ while (0);
+
+ // Restore value
+ l_sys->setAttr<TARGETING::ATTR_IS_SIMULATION>(l_simpleTypeRestoreValue);
+
+ TRACFCOMP( g_trac_test, EXIT_MRK "testMakeAttribute "
+ "num tests = %d / num fails = %d", l_numTests, l_numFails);
+} // end testMakeAttribute
+
+// testMakeAttributeStdArr
+void MakeAttributeTest::testMakeAttributeStdArr(void)
+{
+ TRACFCOMP( g_trac_test, ENTER_MRK "testMakeAttributeStdArr" );
+
+ // Test stats
+ uint8_t l_numTests(0);
+ uint8_t l_numFails(0);
+
+
+ if (!TARGETING::targetService().isInitialized())
+ {
+ TS_FAIL("testMakeAttributeStdArr: Target Service is not initialized, "
+ "cannot perform test, exiting");
+
+ TRACFCOMP( g_trac_test, EXIT_MRK "testMakeAttributeStdArr: "
+ "num tests = 1 / num fails = 1");
+ return;
+ }
+
+ // Get the top level target
+ TARGETING::Target * l_sys(nullptr);
+ TARGETING::targetService().getTopLevelTarget( l_sys );
+
+ if(!l_sys)
+ {
+ TS_FAIL("testMakeAttributeStdArr: Get Top Level Target failed, "
+ "unable to get top level target, cannot perform "
+ "test, exiting");
+
+ TRACFCOMP( g_trac_test, EXIT_MRK "testMakeAttributeStdArr: "
+ "num tests = 1 / num fails = 1");
+ return;
+ }
+
+ // Save initial value to restore later
+ TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS_typeStdArr
+ l_complexTypeRestoreValue;
+
+ // Test 1, test a complex attribute with known data
+ ++l_numTests;
+ do
+ {
+ // Set the attribute 'IPC Node Buffer Global Address' to a
+ // known value to facilitate testing
+ TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS_typeStdArr
+ l_complexTypeSet = {9, 6, 3, 1, 5, 1, 7, 3};
+
+ if ( !l_sys->trySetAttr<TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS>(
+ l_complexTypeSet) )
+ {
+ TS_FAIL("testMakeAttributeStdArr: Test 1 - can't set "
+ "TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS ");
+ ++l_numFails;
+ break;
+ }
+
+ // Do a sanity check and make sure we can set/get attribute via
+ // trySetAttr/tryGetAttr
+ TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS_typeStdArr
+ l_complexTypeGet;
+
+ if ( !l_sys->tryGetAttr<TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS>(
+ l_complexTypeGet) )
+ {
+ TS_FAIL("testMakeAttributeStdArr: Test 1 - can't get "
+ "TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS ");
+ ++l_numFails;
+ break;
+ }
+
+ // Verify setting the attribute worked
+ if (0 != memcmp(&l_complexTypeGet, &l_complexTypeSet,
+ sizeof(l_complexTypeSet)) )
+ {
+ TS_FAIL("testMakeAttributeStdArr: Test 1 - Setting "
+ "attribute failed, cannot perform test, exiting");
+ ++l_numFails;
+ break;
+ }
+
+ // Retrieved that set attribute back via the 'make attribute' call
+ TARGETING::AttributeTank::Attribute l_attribute;
+ bool l_return =
+ TARGETING::makeAttributeStdArr
+ <TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS>
+ (l_sys, l_attribute);
+
+ // Verify the called worked
+ if (l_return == false)
+ {
+ TS_FAIL("testMakeAttributeStdArr: Test 1 - Make "
+ "attribute call failed");
+ ++l_numFails;
+ break;
+ }
+
+ // Get a pointer to the attribute created in make attribute call,
+ // to get to the data.
+ const uint8_t* l_attributeValue =
+ static_cast<const uint8_t*>(l_attribute.getValue());
+
+ // If the pointer to the data is NULL, then the make attribute did fail
+ if (l_attributeValue == nullptr)
+ {
+ TS_INFO("testMakeAttributeStdArr: Test 1 - Getting attribute value "
+ "failed, NULL pointer returned when getting value.");
+ ++l_numFails;
+ }
+
+ // Verify the returned attribute matches it's set value
+ if (0 != memcmp(l_attributeValue, &l_complexTypeSet,
+ sizeof(l_complexTypeSet)) )
+ {
+ TS_INFO("testMakeAttributeStdArr: Test 1 - Retrieved attribute "
+ "value failed, expected value and retrieved value do "
+ "not match");
+ ++l_numFails;
+ break;
+ }
+ }
+ while (0);
+
+
+ // Test 2, test the same complex attribute but with different data
+ ++l_numTests;
+ do
+ {
+ // Set the attribute 'IPC Node Buffer Global Address' to a
+ // known value to facilitate testing
+ TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS_typeStdArr
+ l_complexTypeSet = {1, 2, 6, 8, 3, 2, 9, 3};
+
+ if ( !l_sys->trySetAttr<TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS>(
+ l_complexTypeSet) )
+ {
+ TS_FAIL("testMakeAttributeStdArr: Test 2 - can't set "
+ "TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS ");
+ ++l_numFails;
+ break;
+ }
+
+ // Do a sanity check and make sure we can set/get attribute via
+ // trySetAttr/tryGetAttr
+ TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS_typeStdArr
+ l_complexTypeGet;
+
+ if ( !l_sys->tryGetAttr<TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS>(
+ l_complexTypeGet) )
+ {
+ TS_FAIL("testMakeAttributeStdArr: Test 2 - can't get "
+ "TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS ");
+ ++l_numFails;
+ break;
+ }
+
+ // Verify setting the attribute worked
+ if (0 != memcmp(&l_complexTypeGet, &l_complexTypeSet,
+ sizeof(l_complexTypeSet)) )
+ {
+ TS_FAIL("testMakeAttributeStdArr: Test 2 - Setting "
+ "attribute failed, cannot perform test, exiting");
+ ++l_numFails;
+ break;
+ }
+
+ // Retrieved that set attribute back via the 'make attribute' call
+ TARGETING::AttributeTank::Attribute l_attribute;
+ bool l_return =
+ TARGETING::makeAttributeStdArr
+ <TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS>
+ (l_sys, l_attribute);
+
+ // Verify the called worked
+ if (l_return == false)
+ {
+ TS_FAIL("testMakeAttributeStdArr: Test 2 - Make "
+ "attribute call failed");
+ ++l_numFails;
+ break;
+ }
+
+ // Get a pointer to the attribute created in make attribute call,
+ // to get to the data.
+ const uint8_t* l_attributeValue =
+ static_cast<const uint8_t*>(l_attribute.getValue());
+
+ // If the pointer to the data is NULL, then the make attribute did fail
+ if (l_attributeValue == nullptr)
+ {
+ TS_INFO("testMakeAttributeStdArr: Test 2 - Getting attribute value "
+ "failed, NULL pointer returned when getting value.");
+ ++l_numFails;
+ }
+
+ // Verify the returned attribute matches it's set value
+ if (0 != memcmp(l_attributeValue, &l_complexTypeSet,
+ sizeof(l_complexTypeSet)) )
+ {
+ TS_INFO("testMakeAttributeStdArr: Test 2 - Retrieved attribute "
+ "value failed, expected value and retrieved value do "
+ "not match");
+ ++l_numFails;
+ break;
+ }
+ }
+ while (0);
+
+ // Restore value
+ l_sys->trySetAttr<TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS>(
+ l_complexTypeRestoreValue);
+
+ TRACFCOMP( g_trac_test, EXIT_MRK "testMakeAttributeStdArr "
+ "num tests = %d / num fails = %d", l_numTests, l_numFails);
+
+} // end testMakeAttributeStdArr
+
+#endif // end __TEST_ATTRIBUTE_H
diff --git a/src/usr/targeting/test/testtargeting.H b/src/usr/targeting/test/testtargeting.H
index 66bb940ca..5f49781df 100644
--- a/src/usr/targeting/test/testtargeting.H
+++ b/src/usr/targeting/test/testtargeting.H
@@ -147,6 +147,76 @@ void* funcTestRecursiveMutexEntry(void* i_pData)
return nullptr;
}
+/**
+ * @brief Function to test get and set of std::array values for attributes that
+ * support it. Any N-th dimensional array can be tested.
+ *
+ * @param[in] i_target Pointer to target object
+ * @param[in] i_setVal TA_typeStdArr type value to set
+ */
+template <const TARGETING::ATTRIBUTE_ID TA, typename TA_typeStdArr,
+ typename TA_type>
+void testStdArrayND(TARGETING::Target *i_target, TA_typeStdArr i_setVal)
+{
+
+ // Storing original value
+ TA_type l_origVal;
+
+ if(!i_target->tryGetAttr<TA>(l_origVal))
+ {
+ TS_FAIL("Failed to get original value of attribute.");
+ return;
+ }
+
+ // Setting value using std::array as input
+ i_target->setAttrFromStdArr<TA>(i_setVal);
+
+ // Get c-style array
+ TA_type l_cArrOutVal;
+ if(!i_target->tryGetAttr<TA>(l_cArrOutVal))
+ {
+ TS_FAIL("Could not get c-style array value of attribute.");
+ return;
+ }
+
+ // Copying l_cArrOutVal to a std::array var so that it can be
+ // compared with l_outVal below
+ TA_typeStdArr l_cArrOutValStdArr;
+ memcpy(&l_cArrOutValStdArr, &l_cArrOutVal, sizeof(l_cArrOutVal));
+
+ // std::array output
+ auto l_outVal = i_target->getAttrAsStdArr<TA>();
+
+ // Comparing set value with std::array value, and std::array value with
+ // c-array value
+ if (l_outVal == i_setVal)
+ {
+ TS_INFO("Success, get value equals set value.");
+ if (l_cArrOutValStdArr == l_outVal)
+ {
+ TS_INFO("Success, get c-style array value equals get std::array"
+ " value.");
+ }
+ else
+ {
+ TS_FAIL("Failure, get c-style array value does not equal get"
+ " std::array value.");
+ }
+ }
+ else
+ {
+ TS_FAIL("Failure, get value does not equal set value.");
+ }
+
+ // Restoring original value
+ if(!i_target->trySetAttr<TA>(l_origVal))
+ {
+ TS_FAIL("Failed to restore original attribute value.");
+ }
+
+}
+
+
class TargetingTestSuite : public CxxTest::TestSuite
{
public:
@@ -489,6 +559,59 @@ class TargetingTestSuite : public CxxTest::TestSuite
TS_TRACE(EXIT_MRK "testSignedAttribute");
}
+ /**
+ * @brief Testing attribute's ability to get/set using std::array
+ */
+ void testStdArray()
+ {
+
+ // Testing 1D array
+
+ TS_INFO(ENTER_MRK "testStdArray: Testing 1D array");
+
+ constexpr auto TA = TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS;
+ // TA: targeting attribute
+ typedef TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS_typeStdArr
+ TA_typeStdArr;
+ typedef TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS_type TA_type;
+
+ TARGETING::Target* l_pTarget = nullptr;
+ TARGETING::targetService().getTopLevelTarget(l_pTarget);
+ assert(l_pTarget != nullptr, "testStdArray, unable to establish top"
+ " level target service");
+
+ TA_typeStdArr l_setVal = {9, 6, 3, 1, 5, 1, 7, 3};
+
+ testStdArrayND<TA, TA_typeStdArr, TA_type>(l_pTarget, l_setVal);
+
+ // Testing 2D array
+ TS_INFO(ENTER_MRK "testStdArray: Testing 2D array");
+
+ constexpr auto TA2 = TARGETING::ATTR_EEPROM_PAGE_ARRAY;
+ typedef TARGETING::ATTR_EEPROM_PAGE_ARRAY_typeStdArr TA2_typeStdArr;
+ typedef TARGETING::ATTR_EEPROM_PAGE_ARRAY_type TA2_type;
+
+ TARGETING::TargetHandleList l_procList;
+ TARGETING::getAllChips(l_procList, TARGETING::TYPE_PROC);
+
+ if (l_procList.size() == 0 )
+ {
+ TS_FAIL("Failed to get proc targets.");
+ }
+ else
+ {
+ // Setting value using std::array as input
+ TA2_typeStdArr l_setVal2 {{ {9, 6, 3, 1}, {8, 4, 2, 44},
+ {18, 14, 22, 2}, {77, 8, 6, 54} }};
+
+ testStdArrayND<TA2, TA2_typeStdArr, TA2_type>(l_procList.front(),
+ l_setVal2);
+ }
+
+ TS_INFO(EXIT_MRK "testStdArray");
+
+ }
+
void testPciPhbTarget()
{
TS_TRACE(ENTER_MRK "testPciPhbTarget" );
@@ -598,6 +721,9 @@ class TargetingTestSuite : public CxxTest::TestSuite
{
// Mask off upper 8 bits in case of multiple nodes
uint32_t l_huid = get_huid(*l_targetList) & 0x00FFFFFF;
+
+ // Only keep lower bits for instance num
+ uint8_t l_instanceNum = l_huid & 0xFF;
// Extract the type, drop instance info
l_huid = l_huid >> 16;
if (TARGETING::TYPE_I2C_MUX != l_huid)
@@ -621,14 +747,30 @@ class TargetingTestSuite : public CxxTest::TestSuite
char * l_pathAsString =
l_i2cMuxInfo.i2cMasterPath.toString();
- if (0 != strcmp(l_pathAsString,
- "Physical:/Sys0/Node0/Proc0"))
+
+ // There is 1 mux per MC, so 2 muxes per proc
+ if (l_instanceNum >= 0 && l_instanceNum < 2)
{
- TS_FAIL("testI2cMux::i2cMuxPath path "
- "returned(%s), "
- "expected(Physical:/Sys0/Node0/Proc0)",
- l_pathAsString);
- } // end if (TARGETING
+ if (0 != strcmp(l_pathAsString,
+ "Physical:/Sys0/Node0/Proc0"))
+ {
+ TS_FAIL("testI2cMux::i2cMuxPath path "
+ "returned(%s), "
+ "expected(Physical:/Sys0/Node0/Proc0)",
+ l_pathAsString);
+ }
+ }
+ else
+ {
+ if (0 != strcmp(l_pathAsString,
+ "Physical:/Sys0/Node0/Proc1"))
+ {
+ TS_FAIL("testI2cMux::i2cMuxPath path "
+ "returned(%s), "
+ "expected(Physical:/Sys0/Node0/Proc1)",
+ l_pathAsString);
+ }
+ }
free (l_pathAsString);
l_pathAsString = nullptr;
diff --git a/src/usr/targeting/xmltohb/fapi_utils.pl b/src/usr/targeting/xmltohb/fapi_utils.pl
index 9253fa9eb..f1e7bd124 100644
--- a/src/usr/targeting/xmltohb/fapi_utils.pl
+++ b/src/usr/targeting/xmltohb/fapi_utils.pl
@@ -6,7 +6,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2017
+# Contributors Listed Below - COPYRIGHT 2017,2019
# [+] International Business Machines Corp.
#
#
@@ -282,7 +282,8 @@ sub createTargetExtensionFromFapi(\%,\%)
TARGET_TYPE_OMIC => "unit-omic-power9",
TARGET_TYPE_MCC => "unit-mcc-power9",
TARGET_TYPE_OCMB_CHIP => "chip-ocmb",
- TARGET_TYPE_MEM_PORT => "unit-mem_port"
+ TARGET_TYPE_MEM_PORT => "unit-mem_port",
+ TARGET_TYPE_PMIC => "pmic",
};
# Loop through all of the targets that this attribute
@@ -293,7 +294,7 @@ sub createTargetExtensionFromFapi(\%,\%)
my $foundmatch = 0;
$type =~ s/\s//g;
my $targtype = $fapi2targ->{$type};
- #print "type = $type -> $targtype\n";
+ # print "type = $type -> $targtype\n";
my $attrid = $fapiattr->{id};
$attrid =~ s/ATTR_//;
diff --git a/src/usr/targeting/xmltohb/makefile b/src/usr/targeting/xmltohb/makefile
index 8f36b995e..213d9a3a5 100755
--- a/src/usr/targeting/xmltohb/makefile
+++ b/src/usr/targeting/xmltohb/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2011,2018
+# Contributors Listed Below - COPYRIGHT 2011,2019
# [+] International Business Machines Corp.
#
#
@@ -59,11 +59,13 @@ FAPIATTRSRVC_SOURCE = \
# Attribute XML files.
-FAPI2_ATTR_XML += $(wildcard $(ROOTPATH)/src/import/chips/p9/procedures/xml/attribute_info/*)
-FAPI2_ATTR_XML += $(wildcard $(ROOTPATH)/src/import/hwpf/fapi2/xml/attribute_info/*)
-FAPI2_ATTR_XML += $(wildcard $(ROOTPATH)/src/import/chips/centaur/procedures/xml/attribute_info/*)
-FAPI2_ATTR_XML += $(wildcard $(ROOTPATH)/src/import/generic/procedures/xml/attribute_info/*)
-FAPI2_ATTR_XML += $(wildcard $(ROOTPATH)/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/*)
+FAPI2_ATTR_XML += $(wildcard $(ROOTPATH)/src/import/chips/p9/procedures/xml/attribute_info/*.xml)
+FAPI2_ATTR_XML += $(wildcard $(ROOTPATH)/src/import/hwpf/fapi2/xml/attribute_info/*.xml)
+FAPI2_ATTR_XML += $(wildcard $(ROOTPATH)/src/import/chips/centaur/procedures/xml/attribute_info/*.xml)
+FAPI2_ATTR_XML += $(wildcard $(ROOTPATH)/src/import/generic/procedures/xml/attribute_info/*.xml)
+FAPI2_ATTR_XML += $(wildcard $(ROOTPATH)/src/import/chips/ocmb/explorer/procedures/xml/attribute_info/*.xml)
+FAPI2_ATTR_XML += $(wildcard $(ROOTPATH)/src/import/chips/ocmb/common/procedures/xml/attribute_info/*.xml)
+
# Filter out Temp defaults XML file from Attribute XML files.
# NOTE: The hb_temp_defaults.xml file is not a normal attribute file with the
@@ -230,7 +232,8 @@ CLEAN_TARGETS += $(addprefix $(GENDIR)/, ${XMLTOHB_SYSTEM_BINARIES:.bin=.xml})
CLEAN_TARGETS += ${GENDIR}/${HB_PLAT_ATTR_SRVC_H}
CLEAN_TARGETS += ${GENDIR}/${XMLTOHB_GENERIC_XML}
CLEAN_TARGETS += ${GENDIR}/${XMLTOHB_FAPI_XML}
-CLEAN_TARGETS += ${GENDIR}/errl/errludattribute.H
+CLEAN_TARGETS += ${GENDIR}/errl/errludattributeP_gen.H
+CLEAN_TARGETS += ${GENDIR}/errludattribute_gen.C
CLEAN_TARGETS += ${GENDIR}/errl/errludtarget.H
CLEAN_TARGETS += ${GENDIR}/targAttrInfo.csv
CLEAN_TARGETS += ${GENDIR}/targAttrOverrideData.H
@@ -381,8 +384,7 @@ ${GENDIR}/${XMLTOHB_FULL_ATTRIBUTE_TYPES}: \
$(addprefix --ekbXmlFile=,${GENDIR}/${XMLTOHB_EKB_ATTRIBUTE_TYPES}) \
$(addprefix --hbXmlFile=,${GENDIR}/${XMLTOHB_SRC_ATTRIBUTE_TYPES}) \
$(addprefix --fapi2Header=,${ROOTPATH}/src/include/usr/fapi2/attribute_service.H) \
- $(addprefix --outFile=,${GENDIR}/${XMLTOHB_FULL_ATTRIBUTE_TYPES}) \
- --verbose
+ $(addprefix --outFile=,${GENDIR}/${XMLTOHB_FULL_ATTRIBUTE_TYPES})
# Add EKB attribute xml to config xml to produce the final output.
# Skip adding any attributes that already exists in the src xml
@@ -393,8 +395,7 @@ ${GENDIR}/${XMLTOHB_SP_ATTRIBUTE_TYPES}: \
$(addprefix --ekbXmlFile=,${GENDIR}/${XMLTOHB_EKB_ATTRIBUTE_TYPES}) \
$(addprefix --hbXmlFile=,${GENDIR}/${XMLTOHB_CONFIG_ATTRIBUTE_TYPES}) \
$(addprefix --fapi2Header=,${ROOTPATH}/src/include/usr/fapi2/attribute_service.H) \
- $(addprefix --outFile=,${GENDIR}/${XMLTOHB_SP_ATTRIBUTE_TYPES}) \
- --verbose
+ $(addprefix --outFile=,${GENDIR}/${XMLTOHB_SP_ATTRIBUTE_TYPES})
# generic XML is created from the generic sources only
${GENDIR}/${XMLTOHB_GENERIC_XML}: \
@@ -409,7 +410,7 @@ $(XMLTOHB_RAN_INDICATION): ${XMLTOHB_COMPILER_SCRIPT} \
$(addprefix --fapi-attributes-xml-file=,${GENDIR}/${XMLTOHB_FAPI_XML}) \
--src-output-dir=$(GENDIR) --img-output-dir=none \
--img-output-file=none
- cp ${GENDIR_ERRL}/errludattribute.H ${GENDIR_PLUGINS}
+ cp ${GENDIR_ERRL}/errludattributeP_gen.H ${GENDIR_PLUGINS}
cp ${GENDIR_ERRL}/errludtarget.H ${GENDIR_PLUGINS}
touch $(XMLTOHB_RAN_INDICATION)
diff --git a/src/usr/testcore/kernel/misctest.H b/src/usr/testcore/kernel/misctest.H
index c61741fac..e6322d741 100644
--- a/src/usr/testcore/kernel/misctest.H
+++ b/src/usr/testcore/kernel/misctest.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -64,8 +64,8 @@ class MiscTest : public CxxTest::TestSuite
phys = mm_virt_to_phys( heap );
if( phys != (reinterpret_cast<uint64_t>(heap)|hrmor) )
{
- TS_FAIL("Unexpected Physical Address for Heap.");
TS_TRACE( "heap> virt=%p, phys=%lX", (void*)heap, phys );
+ TS_FAIL("Unexpected Physical Address for Heap.");
}
free(heap);
@@ -78,18 +78,23 @@ class MiscTest : public CxxTest::TestSuite
}
// Verify a MMIO (XSCOM)
- TARGETING::EntityPath epath(TARGETING::EntityPath::PATH_PHYSICAL);
- epath.addLast(TARGETING::TYPE_SYS,0);
- epath.addLast(TARGETING::TYPE_NODE,0);
- epath.addLast(TARGETING::TYPE_PROC,1);
- TARGETING::Target* l_targ =
- TARGETING::targetService().toTarget(epath);
- if(l_targ != NULL)
+ TARGETING::Target * l_masterProc = nullptr;
+ TARGETING::Target * l_masterNode = nullptr;
+ bool l_onlyFunctional = true; // Make sure masterproc is functional
+ errlHndl_t l_err(nullptr);
+ l_err = TARGETING::targetService().queryMasterProcChipTargetHandle(
+ l_masterProc,
+ l_masterNode,
+ l_onlyFunctional);
+
+ //Validate we found a master proc and
+ // didn't encounter any error finding it
+ if(l_masterProc != nullptr && !l_err)
{
uint64_t xscom =
- l_targ->getAttr<TARGETING::ATTR_XSCOM_VIRTUAL_ADDR>();
+ l_masterProc->getAttr<TARGETING::ATTR_XSCOM_VIRTUAL_ADDR>();
phys = mm_virt_to_phys( (void*)xscom );
- if( (phys != (1020*TERABYTE+32*GIGABYTE))
+ if( (phys != (1020*TERABYTE+32*GIGABYTE))
&& (xscom != 0) ) //never got set
{
TS_FAIL("Unexpected Physical Address for MMIO.");
diff --git a/src/usr/testcore/kernel/vmmpagetest.H b/src/usr/testcore/kernel/vmmpagetest.H
index 80d2b9c9a..c1c21068b 100644
--- a/src/usr/testcore/kernel/vmmpagetest.H
+++ b/src/usr/testcore/kernel/vmmpagetest.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -50,13 +52,13 @@ class vmmpagetest: public CxxTest::TestSuite
rc = mm_alloc_block(iv_mq,reinterpret_cast<void*>(iv_va),iv_size);
if (rc != 0)
{
- TS_FAIL("Unable to allocate block.\n");
+ TS_FAIL("Unable to allocate block - rc=%d.\n",rc);
}
rc = mm_set_permission(reinterpret_cast<void*>(iv_va),iv_size,
initPerm);
if (rc != 0)
{
- TS_FAIL("Failed to set block permissions to READ_ONLY.\n");
+ TS_FAIL("Failed to set block permissions to READ_ONLY - rc=%d.\n",rc);
}
task_create(testDaemon, NULL);
}
@@ -76,7 +78,7 @@ class vmmpagetest: public CxxTest::TestSuite
reinterpret_cast<void*>(iv_va),iv_size);
if (rc != 0)
{
- TS_FAIL("Failed to release read pages\n");
+ TS_FAIL("Failed to release read pages - rc=%d.\n",rc);
}
}
@@ -86,7 +88,7 @@ class vmmpagetest: public CxxTest::TestSuite
if (rc != 0)
{
TS_FAIL(
- "Failed to set WRITE_TRACKED permissions on first page.\n");
+ "Failed to set WRITE_TRACKED permissions on first page - rc=%d.\n",rc);
}
(*(volatile uint64_t *)iv_va) = 0x12345678; sync();
@@ -99,13 +101,13 @@ class vmmpagetest: public CxxTest::TestSuite
if (rc != 0)
{
TS_FAIL(
- "Failed to set WRITE_TRACKED permissions on second page.\n");
+ "Failed to set WRITE_TRACKED permissions on second page - rc=%d.\n",rc);
}
rc = mm_remove_pages(FLUSH,
reinterpret_cast<void*>(iv_va),iv_size);
if (rc != 0)
{
- TS_FAIL("Failed to flush write tracked pages\n");
+ TS_FAIL("Failed to flush write tracked pages - rc=%d.\n",rc);
}
}
@@ -115,7 +117,7 @@ class vmmpagetest: public CxxTest::TestSuite
if (rc != 0)
{
TS_FAIL(
- "Failed to set WRITE_TRACKED permissions on first page.\n");
+ "Failed to set WRITE_TRACKED permissions on first page - rc=%d.\n",rc);
}
(*(volatile uint64_t *)(iv_va+2*PAGESIZE)) = 0x33333333; sync();
@@ -126,14 +128,14 @@ class vmmpagetest: public CxxTest::TestSuite
if (rc != 0)
{
TS_FAIL(
- "Failed to set WRITE_TRACKED permissions on first page.\n");
+ "Failed to set WRITE_TRACKED permissions on first page - rc=%d.\n",rc);
}
rc = mm_remove_pages(RELEASE,
reinterpret_cast<void*>(iv_va),iv_size);
if (rc != 0)
{
- TS_FAIL("Failed to release write track pages\n");
+ TS_FAIL("Failed to release write track pages - rc=%d.\n",rc);
}
}
@@ -143,7 +145,7 @@ class vmmpagetest: public CxxTest::TestSuite
rc = mm_set_permission(reinterpret_cast<void*>(iv_va+4*PAGESIZE), 3*PAGESIZE, READ_ONLY);
if (rc != 0)
{
- TS_FAIL(" 1 Failed to Update permissions.\n");
+ TS_FAIL(" 1 Failed to Update permissions - rc=%d.\n",rc);
}
// try to write to a read_only page
@@ -153,13 +155,13 @@ class vmmpagetest: public CxxTest::TestSuite
if ((child != task_wait_tid(child, &status, NULL)) ||
(status != TASK_STATUS_CRASHED))
{
- TS_FAIL("ERROR! Write to READ_ONLY address not caught.");
+ TS_FAIL("ERROR! Write to READ_ONLY address not caught - status=%d.",status);
}
rc = mm_set_permission(reinterpret_cast<void*>(iv_va+4*PAGESIZE), 3*PAGESIZE, EXECUTABLE);
if (rc != 0)
{
- TS_FAIL("2 Failed to Update permissions.\n");
+ TS_FAIL("2 Failed to Update permissions - rc=%d.\n",rc);
}
// try to write to an executable page
@@ -168,13 +170,13 @@ class vmmpagetest: public CxxTest::TestSuite
if ((child != task_wait_tid(child, &status, NULL)) ||
(status != TASK_STATUS_CRASHED))
{
- TS_FAIL("ERROR! Write to EXECUTABLE address not caught.");
+ TS_FAIL("ERROR! Write to EXECUTABLE address not caught - status=%d",status);
}
rc = mm_set_permission(reinterpret_cast<void*>(iv_va+4*PAGESIZE), 3*PAGESIZE, NO_ACCESS);
if (rc != 0)
{
- TS_FAIL("3 Failed to Update permissions.\n");
+ TS_FAIL("3 Failed to Update permissions - rc=%d.\n",rc);
}
// try to write to a no access page
@@ -183,7 +185,7 @@ class vmmpagetest: public CxxTest::TestSuite
if ((child != task_wait_tid(child, &status, NULL)) ||
(status != TASK_STATUS_CRASHED))
{
- TS_FAIL("ERROR! write to a NO_ACCESS addr not caught.\n");
+ TS_FAIL("ERROR! write to a NO_ACCESS addr not caught - status=%d",status);
}
// test that you cannot set WRITABLE and EXECUTABLE permissions
@@ -191,13 +193,13 @@ class vmmpagetest: public CxxTest::TestSuite
if (rc == 0)
{
printk("Error .. invalid combination that did not get detected\n");
- TS_FAIL(" ERROR..Failed to detect a bad parm condition.\n");
+ TS_FAIL(" ERROR..Failed to detect a bad parm condition - rc=%d.\n",rc);
}
rc = mm_set_permission(reinterpret_cast<void*>(iv_va+4*PAGESIZE), 3*PAGESIZE, WRITABLE);
if (rc != 0)
{
- TS_FAIL(" 4 Failed to detect a bad parm condition.\n");
+ TS_FAIL(" 4 Failed to detect a bad parm condition - rc=%d.\n",rc);
}
diff --git a/src/usr/testcore/lib/stltest.H b/src/usr/testcore/lib/stltest.H
index 31cc3cbe9..34cb64d4a 100644
--- a/src/usr/testcore/lib/stltest.H
+++ b/src/usr/testcore/lib/stltest.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -782,5 +782,35 @@ class STLTest : public CxxTest::TestSuite
}
}
+ /// Test std::begin() and std::end() on base-type array
+ void testBaseTypeBeginEnd()
+ {
+ const int MAX_ENTRIES = 1025;
+ int baseA[MAX_ENTRIES] = {0}; // base-type array
+
+ // Initialize base array to known values
+ for (int i = 0; i < MAX_ENTRIES; i++)
+ {
+ baseA[i] = i;
+ }
+
+ // use std::begin() and std::end() to copy base-type array to vector
+ std::vector<int> baseV ( std::begin(baseA), std::end(baseA));
+
+ if (baseV.size() != MAX_ENTRIES)
+ {
+ TS_FAIL("testBaseTypeBeginEnd: expected %d elements, found %d in vector",
+ MAX_ENTRIES, baseV.size());
+ }
+
+ for (int i = 0; i < MAX_ENTRIES; i++)
+ {
+ if (baseA[i] != baseV[i])
+ {
+ TS_FAIL("testBaseTypeBeginEnd: No match at index %d (base %d vs vector %d)",
+ i, baseA[i], baseV[i]);
+ }
+ }
+ }
};
#endif
diff --git a/src/usr/testcore/rtloader/loader.H b/src/usr/testcore/rtloader/loader.H
index c7f1193ef..d9d1448a2 100644
--- a/src/usr/testcore/rtloader/loader.H
+++ b/src/usr/testcore/rtloader/loader.H
@@ -25,6 +25,7 @@
#ifndef __TESTCORE_RTLOADER_LOADER_H
#define __TESTCORE_RTLOADER_LOADER_H
+
#include <util/align.H>
#include <sys/mm.h>
#include <targeting/common/targetservice.H>
@@ -44,7 +45,6 @@
#include <pnor/ecc.H>
#include <ipmi/ipmiif.H>
#include <targeting/common/attributeTank.H>
-#include <config.h>
#include <util/utilrsvdmem.H>
#include <sys/misc.h>
#include <errno.h>
@@ -57,7 +57,10 @@ TRAC_INIT(&g_trac_hbrt, "HBRT_TEST", 12*KILOBYTE);
class RuntimeLoaderTest : public CxxTest::TestSuite
{
- public:
+public:
+ // =====================================================================
+ // testLoader
+ // =====================================================================
void testLoader()
{
static const uint64_t HEADER_OFFSET = 0x2000;
@@ -188,9 +191,12 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
}
#endif
- }
+ } // end testLoader
private:
+ // =====================================================================
+ // tearDown
+ // =====================================================================
void tearDown()
{
if (cv_hb_data_addr != 0)
@@ -218,8 +224,11 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
TRACFCOMP( g_trac_hbrt,
"tearDown(): skipping unmap hb_data virt addr");
}
- }
+ } // end tearDown
+ // =====================================================================
+ // callViaCtr
+ // =====================================================================
uint64_t callViaCtr(uint64_t entry, void* param0, void* param1)
{
register uint64_t result = 0;
@@ -232,23 +241,35 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
"r10","r11"); // TODO: Need to double check the ABI here.
return result;
- }
+ } // end callViaCtr
+ // =====================================================================
+ // rt_puts
+ // =====================================================================
static void rt_puts(const char* str)
{
TRACFCOMP(g_trac_hbrt, "HBRT TRACE: %s", str);
}
+ // =====================================================================
+ // rt_setPageExecute
+ // =====================================================================
static int rt_setPageExecute(void* addr)
{
return mm_set_permission(addr, PAGESIZE, EXECUTABLE);
}
+ // =====================================================================
+ // rt_assert
+ // =====================================================================
static void rt_assert()
{
assert(false);
}
+ // =====================================================================
+ // rt_scom_read
+ // =====================================================================
static int rt_scom_read(uint64_t chipid,
uint64_t addr,
void* data)
@@ -284,8 +305,11 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
}
return rc;
- }
+ } // end rt_scom_read
+ // =====================================================================
+ // rt_scom_write
+ // =====================================================================
static int rt_scom_write(uint64_t chipid,
uint64_t addr,
void* data)
@@ -313,12 +337,11 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
}
return rc;
- }
-
- typedef std::pair<uint64_t,uint64_t> SCOM_KEY;
- typedef std::map<SCOM_KEY,uint64_t> SCOM_MAP;
- static SCOM_MAP cv_scomMap;
+ } // end rt_scom_write
+ // =====================================================================
+ // rt_logErr
+ // =====================================================================
static int rt_logErr(uint32_t plid,
uint32_t data_len,
void * data)
@@ -340,10 +363,11 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
errlCommit(err,CXXTEST_COMP_ID);
return rc;
- }
-
- static std::map<void*, UtilLidMgr*> cv_loadedLids;
+ } // end rt_logErr
+ // =====================================================================
+ // rt_lid_load
+ // =====================================================================
static int rt_lid_load(uint32_t lid, void** buffer, size_t* size)
{
errlHndl_t l_errl = NULL;
@@ -375,9 +399,11 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
cv_loadedLids[*buffer] = lidmgr;
return 0;
}
+ } // end rt_lid_load
- }
-
+ // =====================================================================
+ // rt_lid_unload
+ // =====================================================================
static int rt_lid_unload(void* buffer)
{
UtilLidMgr* lidmgr = cv_loadedLids[buffer];
@@ -389,7 +415,9 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
return 0;
}
- //--------------------------------------------------------------------
+ // =====================================================================
+ // rt_get_reserved_mem
+ // =====================================================================
static uint64_t rt_get_reserved_mem(const char* i_region,
uint32_t i_instance)
{
@@ -401,6 +429,9 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
return 0;
}
+ // =====================================================================
+ // rt_get_hb_data
+ // =====================================================================
static uint64_t rt_get_hb_data(uint32_t i_instance)
{
TRACFCOMP( g_trac_hbrt,
@@ -416,7 +447,6 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
return cv_hb_data_addr;
}
-
uint64_t l_physical_addr = cpu_spr_value(CPU_SPR_HRMOR) +
VMM_HB_DATA_TOC_START_OFFSET;
@@ -469,9 +499,11 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
i_instance, cv_hb_data_addr);
return cv_hb_data_addr;
- }
-
+ } // end rt_get_hb_data
+ // =====================================================================
+ // find_sectionId
+ // =====================================================================
static PNOR::SectionId find_sectionId (const char* i_partitionName)
{
PNOR::SectionId l_id = PNOR::INVALID_SECTION;
@@ -485,8 +517,11 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
}
}
return l_id;
- }
+ } // end find_sectionId
+ // =====================================================================
+ // rt_pnor_read
+ // =====================================================================
static int rt_pnor_read (uint32_t i_proc, const char* i_partitionName,
uint64_t i_offset, void* o_data, size_t i_sizeBytes)
{
@@ -559,9 +594,11 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
}
TRACFCOMP(g_trac_hbrt, EXIT_MRK"rt_pnor_read");
return rc;
- }
-
+ } // end rt_pnor_read
+ // =====================================================================
+ // rt_pnor_write
+ // =====================================================================
static int rt_pnor_write(uint32_t i_proc, const char* i_partitionName,
uint64_t i_offset, void* i_data, size_t i_sizeBytes)
{
@@ -624,9 +661,11 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
}
TRACFCOMP(g_trac_hbrt, EXIT_MRK"rt_pnor_write");
return rc;
- }
+ } // end rt_pnor_write
- //--------------------------------------------------------------------
+ // =====================================================================
+ // rt_get_comm
+ // =====================================================================
static uint64_t rt_get_comm(uint32_t i_instance)
{
if (cv_comm_addr != 0)
@@ -677,9 +716,11 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
"calculated cv_comm_addr:%lld",
cv_comm_addr);
return cv_comm_addr;
- }
+ } // end rt_get_comm
- //--------------------------------------------------------------------
+ // =====================================================================
+ // rt_ipmi_msg
+ // =====================================================================
static int rt_ipmi_msg(uint8_t netfn, uint8_t cmd,
void *tx_buf, size_t tx_size,
void *rx_buf, size_t *rx_size)
@@ -704,9 +745,11 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
}
TRACFCOMP(g_trac_hbrt, EXIT_MRK"rt_ipmi_msg");
return l_plid;
- }
+ } // end rt_ipmi_msg
- //--------------------------------------------------------------------
+ // =====================================================================
+ // rt_hcode_update
+ // =====================================================================
static int rt_hcode_update( uint64_t i_chipId,
uint32_t i_section,
uint32_t i_operation,
@@ -721,291 +764,677 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
return 0;
}
- //--------------------------------------------------------------------
- static int rt_firmware_request(uint64_t i_reqLen, void *i_req,
- uint64_t* o_respLen, void *o_resp )
+ // =====================================================================
+ // rt_firmware_request
+ // =====================================================================
+ static int rt_firmware_request(uint64_t i_reqLen, void *i_req,
+ uint64_t* o_respLen, void *o_resp )
{
+ TRACFCOMP(g_trac_hbrt, ENTER_MRK"rt_firmware_request: "
+ "request length:%d, request ptr:%p, "
+ "response length:%d, response ptr:%p",
+ i_reqLen, i_req, *o_respLen, o_resp );
+
+ if ( (i_req == nullptr) ||
+ (o_respLen == nullptr) ||
+ (o_resp == nullptr) )
+ {
+ TS_FAIL("rt_firmware_request: FAILED: Received bad input - "
+ "either request message, response length "
+ "or response message is NULL")
+
+ return -EINVAL;
+ }
+
+ if ( (*o_respLen != i_reqLen) &&
+ (*o_respLen < (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(hostInterfaces::hbrt_fw_msg))) )
+ {
+ TS_FAIL("rt_firmware_request: FAILED: Response length(%d) "
+ "needs to be at a minimum(%d), or equal to "
+ "request length(%d)",
+ *o_respLen,
+ (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(hostInterfaces::hbrt_fw_msg)),
+ i_reqLen);
+
+ return -EINVAL;
+ }
+
size_t retVal = 0;
+
do
{
- if (i_req == nullptr ||
- o_respLen == nullptr ||
- o_resp == nullptr)
- {
- retVal = -EINVAL;
- break;
- }
+ // Cast the input to the type of data that it is
+ hostInterfaces::hbrt_fw_msg* l_req_fw_msg =
+ reinterpret_cast<hostInterfaces::hbrt_fw_msg*>(i_req);
+ hostInterfaces::hbrt_fw_msg* l_resp_fw_msg =
+ reinterpret_cast<hostInterfaces::hbrt_fw_msg*>(o_resp);
- hostInterfaces::hbrt_fw_msg* l_req_fw_msg =
- (hostInterfaces::hbrt_fw_msg*) i_req;
- hostInterfaces::hbrt_fw_msg* l_resp_fw_msg =
- (hostInterfaces::hbrt_fw_msg*) o_resp;
-
- if (hostInterfaces::HBRT_FW_MSG_TYPE_REQ_HCODE_UPDATE
+ if (hostInterfaces::HBRT_FW_MSG_TYPE_REQ_HCODE_UPDATE
== l_req_fw_msg->io_type)
- {
- if (i_reqLen < (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
- sizeof(l_req_fw_msg->req_hcode_update)))
- {
- retVal = -EINVAL;
- break;
- }
-
- if (*o_respLen < (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
- sizeof(l_resp_fw_msg->resp_generic)))
- {
- retVal = -EINVAL;
- break;
- }
-
- TRACFCOMP(g_trac_hbrt,
- "rt_firmware_request for HCODE SCOM update: "
- "type:%d, chipId:0x%X, section:%d, "
- "operation:%d, scomAddr:0x%X scomData:0x%X",
- l_req_fw_msg->io_type,
- l_req_fw_msg->req_hcode_update.i_chipId,
- l_req_fw_msg->req_hcode_update.i_section,
- l_req_fw_msg->req_hcode_update.i_operation,
- l_req_fw_msg->req_hcode_update.i_scomAddr,
- l_req_fw_msg->req_hcode_update.i_scomData);
-
- l_resp_fw_msg->io_type =
- hostInterfaces::HBRT_FW_MSG_TYPE_RESP_GENERIC;
-
- // dummy return value for testing
- l_resp_fw_msg->resp_generic.o_status = 264;
-
- retVal = 1; // just return 1 for testing
- }
- else if (hostInterfaces::HBRT_FW_MSG_TYPE_ERROR_LOG
+ {
+ retVal = testFirmwareRequestHcodeUpdate(i_reqLen,
+ l_req_fw_msg,
+ *o_respLen,
+ l_resp_fw_msg );
+ }
+ else if (hostInterfaces::HBRT_FW_MSG_TYPE_ERROR_LOG
== l_req_fw_msg->io_type)
- {
- if (i_reqLen < (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
- sizeof(l_req_fw_msg->error_log)))
- {
- retVal = -EINVAL;
- break;
- }
-
- if (i_reqLen < (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
- sizeof(l_req_fw_msg->error_log) +
- l_req_fw_msg->error_log.i_errlSize - 1))
- {
- retVal = -EINVAL;
- break;
- }
-
- if (*o_respLen < (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
- sizeof(l_resp_fw_msg->resp_generic)))
- {
- retVal = -EINVAL;
- break;
- }
-
- TRACFCOMP(g_trac_hbrt,
- "rt_firmware_request for error log: "
- "type:%d, plid:0x%08x, size:%d, data:0x%02x",
- l_req_fw_msg->io_type,
- l_req_fw_msg->error_log.i_plid,
- l_req_fw_msg->error_log.i_errlSize,
- l_req_fw_msg->error_log.i_data);
-
- l_resp_fw_msg->io_type =
- hostInterfaces::HBRT_FW_MSG_TYPE_RESP_GENERIC;
-
- // dummy return value for testing
- l_resp_fw_msg->resp_generic.o_status = 20;
-
- retVal = 0; // just return 0 for testing
- }
- else if (hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ
+ {
+ retVal = testFirmwareRequestErrLogToFsp(i_reqLen,
+ l_req_fw_msg,
+ *o_respLen,
+ l_resp_fw_msg );
+ }
+ else if (hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ
== l_req_fw_msg->io_type)
- {
- if (i_reqLen < (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
- sizeof(l_req_fw_msg->generic_msg)))
- {
- retVal = -EINVAL;
- break;
- }
-
- if (*o_respLen < (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
- sizeof(l_resp_fw_msg->generic_msg)))
- {
- retVal = -EINVAL;
- break;
- }
-
- if (i_reqLen != *o_respLen)
- {
- retVal = -EINVAL;
- break;
- }
-
- uint32_t* l_data =
- (uint32_t*) &(l_req_fw_msg->generic_msg.data);
- TRACFCOMP(g_trac_hbrt,
- "rt_firmware_request request: "
- "type:%d, magic:0x%.8X, dataSize:%d, "
- "structVer:0x%.8X, seqnum:%d, msgq:0x%.8X, "
- "msgType:0x%.8X, __req:%d, __onlyError:%d, "
- "data:0x%.8X, plid:0x%.8X, huid:0x%.8X",
- l_req_fw_msg->io_type,
- l_req_fw_msg->generic_msg.magic,
- l_req_fw_msg->generic_msg.dataSize,
- l_req_fw_msg->generic_msg.structVer,
- l_req_fw_msg->generic_msg.seqnum,
- l_req_fw_msg->generic_msg.msgq,
- l_req_fw_msg->generic_msg.msgType,
- l_req_fw_msg->generic_msg.__req,
- l_req_fw_msg->generic_msg.__onlyError,
- l_req_fw_msg->generic_msg.data,
- l_data[0],
- l_data[1]);
-
- // Simple map of SCOM addresses to values, this ignores
- // the target (or huid).
- static std::map<uint64_t, uint64_t> l_scomCache;
-
- // Used to give unique, spoofed SCOM values
- static uint64_t l_fakeVal = 0x11;
-
- // Simulate response message from FSP
- l_resp_fw_msg->io_type =
+ {
+ if (i_reqLen < (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(l_req_fw_msg->generic_msg)))
+ {
+ TS_FAIL("rt_firmware_request: FAILED: Generic FSP "
+ "Message' response length(%d) needs to be "
+ "at a minimum(%d)",
+ *o_respLen,
+ (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(l_req_fw_msg->generic_msg)) );
+
+ retVal = -EINVAL;
+ break;
+ }
+
+ TRACDCOMP(g_trac_hbrt,
+ "rt_firmware_request: Generic FSP Message' "
+ "Request data set 1/2: "
+ "type:%d, magic:0x%.8X, dataSize:%d, "
+ "structVer:0x%.8X, seqnum:%d, msgq:0x%.8X",
+ l_req_fw_msg->io_type,
+ l_req_fw_msg->generic_msg.magic,
+ l_req_fw_msg->generic_msg.dataSize,
+ l_req_fw_msg->generic_msg.structVer,
+ l_req_fw_msg->generic_msg.seqnum,
+ l_req_fw_msg->generic_msg.msgq);
+
+ TRACDCOMP(g_trac_hbrt,
+ "rt_firmware_request: Generic FSP Message' "
+ "Request data set 2/2: "
+ "msgType:0x%.8X, __req:%d, "
+ "__onlyError:%d, data:0x%.8X",
+ l_req_fw_msg->generic_msg.msgType,
+ l_req_fw_msg->generic_msg.__req,
+ l_req_fw_msg->generic_msg.__onlyError,
+ l_req_fw_msg->generic_msg.data);
+
+ // Simulate response message from FSP
+ l_resp_fw_msg->io_type =
hostInterfaces::HBRT_FW_MSG_HBRT_FSP_RESP;
- l_resp_fw_msg->generic_msg.magic =
+ l_resp_fw_msg->generic_msg.magic =
GenericFspMboxMessage_t::MAGIC_NUMBER;
- l_resp_fw_msg->generic_msg.structVer =
+ l_resp_fw_msg->generic_msg.structVer =
l_req_fw_msg->generic_msg.structVer;
- l_resp_fw_msg->generic_msg.seqnum =
+ l_resp_fw_msg->generic_msg.seqnum =
l_req_fw_msg->generic_msg.seqnum + 1;
- l_resp_fw_msg->generic_msg.msgq =
+ l_resp_fw_msg->generic_msg.msgq =
l_req_fw_msg->generic_msg.msgq;
- l_resp_fw_msg->generic_msg.msgType =
+ l_resp_fw_msg->generic_msg.msgType =
l_req_fw_msg->generic_msg.msgType;
- l_resp_fw_msg->generic_msg.__req =
+ l_resp_fw_msg->generic_msg.__req =
GenericFspMboxMessage_t::RESPONSE;
- l_resp_fw_msg->generic_msg.__onlyError =
+ l_resp_fw_msg->generic_msg.__onlyError =
GenericFspMboxMessage_t::NOT_ERROR_ONLY;
- switch (l_req_fw_msg->generic_msg.msgType)
- {
- case GenericFspMboxMessage_t::MSG_SINGLE_SCOM_OP:
- {
- SingleScomOpHbrtFspData_t* l_req_fspData =
- reinterpret_cast<SingleScomOpHbrtFspData_t*>
- (&(l_req_fw_msg->generic_msg.data));
- SingleScomOpHbrtFspData_t* l_resp_fspData =
- reinterpret_cast<SingleScomOpHbrtFspData_t*>
- (&(l_resp_fw_msg->generic_msg.data));
-
- l_resp_fw_msg->generic_msg.dataSize =
- GENERIC_FSP_MBOX_MESSAGE_BASE_SIZE +
- sizeof(SingleScomOpHbrtFspData_t);
-
- auto l_scomAddr = l_req_fspData->scom_addr;
- auto targ = l_scomCache.find(l_scomAddr);
- if (targ == l_scomCache.end()) // need to create
- { // a cache entry
- l_scomCache[l_scomAddr] = l_fakeVal++;
- }
-
- l_resp_fspData->scom_op = l_req_fspData->scom_op;
- l_resp_fspData->huid = l_req_fspData->huid;
- l_resp_fspData->scom_addr = l_req_fspData->scom_addr;
- if (l_resp_fspData->scom_op == DeviceFW::WRITE)
- {
- l_scomCache[l_scomAddr] =
- l_req_fspData->scom_data;
- }
- l_resp_fspData->scom_data = l_scomCache[l_scomAddr];
- retVal = 0;
- break;
- }
- case GenericFspMboxMessage_t::MSG_MULTI_SCOM_OP:
- {
- MultiScomReadHbrtFspData_t* l_req_fspData =
- reinterpret_cast<MultiScomReadHbrtFspData_t*>
- (&(l_req_fw_msg->generic_msg.data));
- MultiScomReadHbrtFspData_t* l_resp_fspData =
- reinterpret_cast<MultiScomReadHbrtFspData_t*>
- (&(l_resp_fw_msg->generic_msg.data));
-
- l_resp_fw_msg->generic_msg.dataSize =
- GENERIC_FSP_MBOX_MESSAGE_BASE_SIZE +
- sizeof(MultiScomReadHbrtFspData_t) +
- ((l_req_fspData->scom_num - 1) * sizeof(uint64_t));
-
- auto l_scomAddrs =
- static_cast<uint64_t *>
- (&l_req_fspData->scom_data);
- auto l_scomData =
- static_cast<uint64_t *>
- (&l_resp_fspData->scom_data);
-
- l_resp_fspData->huid = l_req_fspData->huid;
- l_resp_fspData->scom_num = l_req_fspData->scom_num;
- for (int i = 0;i < l_resp_fspData->scom_num;++i)
- {
- auto targ = l_scomCache.find(l_scomAddrs[i]);
- if (targ == l_scomCache.end()) // need to create
- { // a cache entry
- l_scomCache[l_scomAddrs[i]] = l_fakeVal++;
- }
- l_scomData[i] = l_scomCache[l_scomAddrs[i]];
- }
- retVal = 0;
- break;
- }
- default:
- // random testing data
- struct
- {
- uint32_t plid;
- uint32_t huid;
- } l_resp_data;
-
- l_resp_fw_msg->generic_msg.dataSize =
- sizeof(l_resp_fw_msg->generic_msg);
-
- l_resp_data.plid = 0x60;
- l_resp_data.huid = 0x70;
- memcpy(&(l_resp_fw_msg->generic_msg.data),
- &(l_resp_data),
- sizeof(l_resp_fw_msg->generic_msg.data));
- retVal = 5;
- break;
- }
-
- TRACFCOMP(g_trac_hbrt,
- "rt_firmware_request response: "
- "type:%d, magic:0x%.8X, dataSize:%d, structVer:0x%.8X, "
- "seqnum:%d, msgq:0x%.8X, msgType:0x%.8X, __req:%d, "
- "__onlyError:%d, data:0x%.8X, plid:0x%.8X, huid:0x%.8X, "
- "retVal=%d",
- l_resp_fw_msg->io_type,
- l_resp_fw_msg->generic_msg.magic,
- l_resp_fw_msg->generic_msg.dataSize,
- l_resp_fw_msg->generic_msg.structVer,
- l_resp_fw_msg->generic_msg.seqnum,
- l_resp_fw_msg->generic_msg.msgq,
- l_resp_fw_msg->generic_msg.msgType,
- l_resp_fw_msg->generic_msg.__req,
- l_resp_fw_msg->generic_msg.__onlyError,
- l_resp_fw_msg->generic_msg.data,
- l_resp_fw_msg->generic_msg.data >> 32,
- 0x0000FFFF & l_resp_fw_msg->generic_msg.data,
- retVal);
- }
- else
- {
- TRACFCOMP(g_trac_hbrt,
- "rt_firmware_request: unrecognized request, type=%d",
- l_req_fw_msg->io_type);
+
+ // Check the individual message types
+ switch (l_req_fw_msg->generic_msg.msgType)
+ {
+ case GenericFspMboxMessage_t::MSG_SINGLE_SCOM_OP:
+ {
+ testFirmwareRequestSingleScomOperation(i_reqLen,
+ l_req_fw_msg,
+ *o_respLen,
+ l_resp_fw_msg);
+ break;
+ }
+ case GenericFspMboxMessage_t::MSG_MULTI_SCOM_OP:
+ {
+ testFirmwareRequestMultipleScomOperation(i_reqLen,
+ l_req_fw_msg,
+ *o_respLen,
+ l_resp_fw_msg);
+ break;
+ }
+ case GenericFspMboxMessage_t::MSG_ATTR_WRITE_OP:
+ {
+ testFirmwareRequestSendAttributes(i_reqLen,
+ l_req_fw_msg,
+ *o_respLen,
+ l_resp_fw_msg);
+ break;
+ }
+ case GenericFspMboxMessage_t::MSG_SBE_ERROR:
+ {
+ retVal = testFirmwareRequestSbeRetry(i_reqLen,
+ l_req_fw_msg,
+ *o_respLen,
+ l_resp_fw_msg);
+ break;
+ }
+
+ default:
+ {
+ TS_FAIL("rt_firmware_request: FAILED: Generic FSP "
+ "unrecognized test request, type(0x%X). "
+ "Need to add a test case for this "
+ "generic FSP firmware request type",
+ l_req_fw_msg->generic_msg.msgType);
+ break;
+ }
+ } // end switch (l_req_fw_msg->generic_msg.msgType)
+
+ TRACDCOMP(g_trac_hbrt,
+ "rt_firmware_request: Generic FSP Message' "
+ "Response data set 1/2: "
+ "type:%d, magic:0x%.8X, dataSize:%d, "
+ "structVer:0x%.8X, seqnum:%d, msgq:0x%.8X",
+ l_resp_fw_msg->io_type,
+ l_resp_fw_msg->generic_msg.magic,
+ l_resp_fw_msg->generic_msg.dataSize,
+ l_resp_fw_msg->generic_msg.structVer,
+ l_resp_fw_msg->generic_msg.seqnum,
+ l_resp_fw_msg->generic_msg.msgq);
+
+ TRACDCOMP(g_trac_hbrt,
+ "rt_firmware_request: Generic FSP Message' "
+ "Response data set 2/2: "
+ "msgType:0x%.8X, __req:%d, __onlyError:%d, "
+ "data:0x%.8X",
+ l_resp_fw_msg->generic_msg.msgType,
+ l_resp_fw_msg->generic_msg.__req,
+ l_resp_fw_msg->generic_msg.__onlyError,
+ l_resp_fw_msg->generic_msg.data);
+
+ } // end else if (hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ
+ else
+ {
+ TS_FAIL("rt_firmware_request: FAILED: "
+ "unrecognized test request, type(0x%X). Need to "
+ "add a test case for this firmware request type",
+ l_req_fw_msg->io_type);
}
} while (0) ;
+ TRACFCOMP(g_trac_hbrt, EXIT_MRK"rt_firmware_request: returning %d",
+ retVal );
+
return retVal;
- }
+ } // end static int rt_firmware_request ...
+
+ /// Firmware Request Test Helper Functions
+ // =====================================================================
+ // testFirmwareRequestSbeRetry
+ // =====================================================================
+ static size_t testFirmwareRequestSbeRetry(
+ uint64_t i_reqLen,
+ hostInterfaces::hbrt_fw_msg* i_req_fw_msg,
+ uint64_t i_respLen,
+ hostInterfaces::hbrt_fw_msg* i_resp_fw_msg )
+ {
+ TRACFCOMP(g_trac_hbrt, ENTER_MRK
+ "rt_firmware_request::testFirmwareRequestSbeRetry");
+
+ struct
+ {
+ uint32_t plid;
+ uint32_t huid;
+ } l_resp_data;
+
+ i_resp_fw_msg->generic_msg.dataSize =
+ sizeof(i_resp_fw_msg->generic_msg);
+
+ l_resp_data.plid = 0x60;
+ l_resp_data.huid = 0x70;
+ memcpy(&(i_resp_fw_msg->generic_msg.data),
+ &(l_resp_data),
+ sizeof(i_resp_fw_msg->generic_msg.data));
+
+ TRACFCOMP(g_trac_hbrt, EXIT_MRK
+ "rt_firmware_request::testFirmwareRequestSbeRetry");
+
+ return 5;
+ } // end testFirmwareRequestSbeRetry
+
+ // =====================================================================
+ // testFirmwareRequestSingleScomOperation
+ // =====================================================================
+ static void testFirmwareRequestSingleScomOperation(
+ uint64_t i_reqLen,
+ hostInterfaces::hbrt_fw_msg* i_req_fw_msg,
+ uint64_t i_respLen,
+ hostInterfaces::hbrt_fw_msg* i_resp_fw_msg )
+ {
+ TRACFCOMP(g_trac_hbrt, ENTER_MRK
+ "rt_firmware_request::testFirmwareRequestSingleScomOperation");
+
+ // Simple map of SCOM addresses to values, this ignores
+ // the target (or huid).
+ static std::map<uint64_t, uint64_t> l_scomCache;
+
+ // Used to give unique, spoofed SCOM values
+ static uint64_t l_fakeVal = 0x11;
+
+ SingleScomOpHbrtFspData_t* l_req_fspData =
+ reinterpret_cast<SingleScomOpHbrtFspData_t*>
+ (&(i_req_fw_msg->generic_msg.data));
+
+ SingleScomOpHbrtFspData_t* l_resp_fspData =
+ reinterpret_cast<SingleScomOpHbrtFspData_t*>
+ (&(i_resp_fw_msg->generic_msg.data));
+
+ i_resp_fw_msg->generic_msg.dataSize =
+ GENERIC_FSP_MBOX_MESSAGE_BASE_SIZE +
+ sizeof(SingleScomOpHbrtFspData_t);
+
+ auto l_scomAddr = l_req_fspData->scom_addr;
+ auto targ = l_scomCache.find(l_scomAddr);
+ if (targ == l_scomCache.end()) // need to create
+ { // a cache entry
+ l_scomCache[l_scomAddr] = l_fakeVal++;
+ }
+
+ l_resp_fspData->scom_op = l_req_fspData->scom_op;
+ l_resp_fspData->huid = l_req_fspData->huid;
+ l_resp_fspData->scom_addr = l_req_fspData->scom_addr;
+
+ if (l_resp_fspData->scom_op == DeviceFW::WRITE)
+ {
+ l_scomCache[l_scomAddr] =
+ l_req_fspData->scom_data;
+ }
+ l_resp_fspData->scom_data = l_scomCache[l_scomAddr];
+
+ TRACFCOMP(g_trac_hbrt, EXIT_MRK
+ "rt_firmware_request::testFirmwareRequestSingleScomOperation");
+ } // end testFirmwareRequestSingleScomOperation
+
+ // =====================================================================
+ // testFirmwareRequestMultipleScomOperation
+ // =====================================================================
+ static void testFirmwareRequestMultipleScomOperation(
+ uint64_t i_reqLen,
+ hostInterfaces::hbrt_fw_msg* i_req_fw_msg,
+ uint64_t i_respLen,
+ hostInterfaces::hbrt_fw_msg* i_resp_fw_msg )
+ {
+ TRACFCOMP(g_trac_hbrt, ENTER_MRK
+ "rt_firmware_request::testFirmwareRequestMultipleScomOperation");
+
+ // Simple map of SCOM addresses to values, this ignores
+ // the target (or huid).
+ static std::map<uint64_t, uint64_t> l_scomCache;
+
+ // Used to give unique, spoofed SCOM values
+ static uint64_t l_fakeVal = 0x11;
+
+ MultiScomReadHbrtFspData_t* l_req_fspData =
+ reinterpret_cast<MultiScomReadHbrtFspData_t*>
+ (&(i_req_fw_msg->generic_msg.data));
+ MultiScomReadHbrtFspData_t* l_resp_fspData =
+ reinterpret_cast<MultiScomReadHbrtFspData_t*>
+ (&(i_resp_fw_msg->generic_msg.data));
+
+ i_resp_fw_msg->generic_msg.dataSize =
+ GENERIC_FSP_MBOX_MESSAGE_BASE_SIZE +
+ sizeof(MultiScomReadHbrtFspData_t) +
+ ((l_req_fspData->scom_num - 1) * sizeof(uint64_t));
+
+ auto l_scomAddrs =
+ static_cast<uint64_t *>
+ (&l_req_fspData->scom_data);
+ auto l_scomData =
+ static_cast<uint64_t *>
+ (&l_resp_fspData->scom_data);
+
+ l_resp_fspData->huid = l_req_fspData->huid;
+ l_resp_fspData->scom_num = l_req_fspData->scom_num;
+ for (int i = 0;i < l_resp_fspData->scom_num;++i)
+ {
+ auto targ = l_scomCache.find(l_scomAddrs[i]);
+ if (targ == l_scomCache.end()) // need to create
+ { // a cache entry
+ l_scomCache[l_scomAddrs[i]] = l_fakeVal++;
+ }
+ l_scomData[i] = l_scomCache[l_scomAddrs[i]];
+ }
+
+ TRACFCOMP(g_trac_hbrt, EXIT_MRK
+ "rt_firmware_request::testFirmwareRequestMultipleScomOperation");
+ } // end testFirmwareRequestMultipleScomOperation
+
+ // =====================================================================
+ // testFirmwareRequestSendAttributes
+ // =====================================================================
+ static void testFirmwareRequestSendAttributes(
+ uint64_t i_reqLen,
+ hostInterfaces::hbrt_fw_msg* i_req_fw_msg,
+ uint64_t i_respLen,
+ hostInterfaces::hbrt_fw_msg* i_resp_fw_msg )
+ {
+ TRACFCOMP(g_trac_hbrt, ENTER_MRK
+ "rt_firmware_request::testFirmwareRequestSendAttributes");
+
+ uint32_t l_dataSize = i_reqLen -
+ ( hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(i_req_fw_msg->generic_msg.data) +
+ sizeof(AttributeSetter_t) );
+
+ if (l_dataSize < 0)
+ {
+ TS_FAIL("rt_firmware_request::"
+ "testFirmwareRequestSendAttributes: FAILED: "
+ "Size of the AttributeSetter_t data is "
+ "negative(%d)", l_dataSize);
+ return;
+ }
+
+ // Get a handle to the AttributeSetter_t
+ AttributeSetter_t* l_attributeSetter =
+ reinterpret_cast<AttributeSetter_t*>
+ (&(i_req_fw_msg->generic_msg.data));
+ // Get a handle to the Attributes Data
+ uint8_t* l_attributeData = reinterpret_cast<uint8_t*>
+ (l_attributeSetter->iv_attrData);
+
+ // Create some Attributes to populate with serialized data and
+ // compare to expected values
+ TARGETING::AttributeTank::Attribute l_sentAttribute,
+ l_expectedAttribute;
+ uint32_t l_deserializedDataSize(0);
+
+ // Create a buffer to be used to test against
+ uint32_t l_bufferSize(3);
+ uint8_t l_buffer[l_bufferSize];
+
+ // Populate buffer with known values
+ l_buffer[0] = 0xAA;
+ l_buffer[1] = 0xBB;
+ l_buffer[2] = 0xCC;
+
+ // Iterate thru the attributes and compare to expected values
+ for (uint16_t i = 0; i < l_attributeSetter->iv_numAttributes; ++i)
+ {
+ // Deserialize the data, if possible
+ l_deserializedDataSize = l_sentAttribute.deserialize
+ (l_attributeData, l_dataSize);
+
+ if (!l_deserializedDataSize)
+ {
+ TS_FAIL("rt_firmware_request::"
+ "testFirmwareRequestSendAttributes: FAILED: "
+ "deserialization of attribute failed")
+ return;
+ }
+
+ if (0 == i)
+ {
+ // Verify first deserialized Attribute
+ if (!compareAttributeHeader(&l_sentAttribute,
+ &l_expectedAttribute))
+ {
+ TS_FAIL("rt_firmware_request::"
+ "testFirmwareRequestSendAttributes: "
+ "Test 1 FAILED: sent Attribute does not match "
+ "expected Values");
+ }
+
+ // Prep for next test
+ l_expectedAttribute.setId(0x1001);
+ l_expectedAttribute.setTargetType(0x2002);
+ l_expectedAttribute.setPosition(0x3003);
+ l_expectedAttribute.setUnitPosition(0x4);
+ l_expectedAttribute.setNode(0x5);
+ l_expectedAttribute.setFlags(0x6);
+ } // end if (0 == i)
+ else if (1 == i)
+ {
+ // Verify second deserialized Attribute
+ if (!compareAttributeHeader(&l_sentAttribute,
+ &l_expectedAttribute))
+ {
+ TS_FAIL("rt_firmware_request::"
+ "testFirmwareRequestSendAttributes: "
+ "Test 2 FAILED: sent Attribute does not match "
+ "expected Values");
+ }
+
+ // Prep for next test
+ l_expectedAttribute.setValue(l_buffer, 1);
+ } // end else if (1 == i)
+ else if (2 == i)
+ {
+ // Verify third deserialized Attribute
+ if (!compareAttributeHeader(&l_sentAttribute,
+ &l_expectedAttribute))
+ {
+ TS_FAIL("rt_firmware_request::"
+ "testFirmwareRequestSendAttributes: "
+ "Test 3 FAILED: sent Attribute does not match "
+ "expected Values");
+ }
+
+ if (!compareAttributeValues(&l_sentAttribute,
+ &l_expectedAttribute))
+ {
+ TS_FAIL("rt_firmware_request::"
+ "testFirmwareRequestSendAttributes: "
+ "Test 3 FAILED: sent Attribute Values does not "
+ "match expected Values");
+ }
+
+ // Prep for next test
+ l_buffer[0] = 0xDD;
+ l_expectedAttribute.setValue(l_buffer, l_bufferSize);
+ } // end else if (2 == i)
+ else if (3 == i)
+ {
+ // Verify fourth deserialized Attribute
+ if (!compareAttributeHeader(&l_sentAttribute,
+ &l_expectedAttribute))
+ {
+ TS_FAIL("rt_firmware_request::"
+ "testFirmwareRequestSendAttributes: "
+ "Test 4 FAILED: sent Attribute does not match "
+ "expected Values");
+ }
+
+ if (!compareAttributeValues(&l_sentAttribute,
+ &l_expectedAttribute))
+ {
+ TS_FAIL("rt_firmware_request::"
+ "testFirmwareRequestSendAttributes: "
+ "Test 4 FAILED: sent Attribute Values does not "
+ "match expected Values");
+ }
+ } // end else if (3 == i)
+
+ // Decrement/increment our counters/pointers
+ l_dataSize -= l_deserializedDataSize;
+ l_attributeData += l_deserializedDataSize;
+
+ } // end for (uint16_t i = 0; ...
+
+ TRACFCOMP(g_trac_hbrt, EXIT_MRK
+ "rt_firmware_request::testFirmwareRequestSendAttributes");
+ } // end testFirmwareRequestSendAttributes
+
+ // =====================================================================
+ // testFirmwareRequestErrLogToFsp
+ // =====================================================================
+ static size_t testFirmwareRequestErrLogToFsp(
+ uint64_t i_reqLen,
+ hostInterfaces::hbrt_fw_msg* i_req_fw_msg,
+ uint64_t i_respLen,
+ hostInterfaces::hbrt_fw_msg* i_resp_fw_msg )
+
+ {
+
+ TRACFCOMP(g_trac_hbrt, ENTER_MRK
+ "rt_firmware_request::testFirmwareRequestErrLogToFsp");
+
+ if (i_reqLen < (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(i_req_fw_msg->error_log)))
+ {
+ TS_FAIL("rt_firmware_request::testFirmwareRequestErrLogToFsp: "
+ "FAILED: Request length(%d) needs to be at a "
+ "minimum(%d)",
+ i_reqLen,
+ (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(i_req_fw_msg->error_log)) );
+ return -EINVAL;
+ }
+
+ if (i_reqLen < (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(i_req_fw_msg->error_log) +
+ i_req_fw_msg->error_log.i_errlSize - 1))
+ {
+ TS_FAIL("rt_firmware_request::testFirmwareRequestErrLogToFsp: "
+ "FAILED: Request length(%d) needs to be at a "
+ "minimum(%d)",
+ i_reqLen,
+ (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(i_req_fw_msg->error_log) +
+ i_req_fw_msg->error_log.i_errlSize - 1) );
+ return -EINVAL;
+ }
+
+ if ( (0x300 != i_req_fw_msg->error_log.i_plid) ||
+ ( 1 != i_req_fw_msg->error_log.i_errlSize) ||
+ ( 0xAA != i_req_fw_msg->error_log.i_data) )
+ {
+ TS_FAIL("rt_firmware_request::testFirmwareRequestErrLogToFsp: "
+ "FAILED: Loader received incorrect data: type:%d, "
+ "plid:0x%08x, size:%d, data:0x%02x",
+ i_req_fw_msg->io_type,
+ i_req_fw_msg->error_log.i_plid,
+ i_req_fw_msg->error_log.i_errlSize,
+ i_req_fw_msg->error_log.i_data);
+ }
+
+ i_resp_fw_msg->io_type =
+ hostInterfaces::HBRT_FW_MSG_TYPE_RESP_GENERIC;
+
+ // dummy return value for testing
+ i_resp_fw_msg->resp_generic.o_status = 20;
+
+ TRACFCOMP(g_trac_hbrt, EXIT_MRK
+ "rt_firmware_request::testFirmwareRequestErrLogToFsp");
+
+ // just return 0 for testing
+ return 0;
+ } // end testFirmwareRequestErrLogToFsp
+
+ // =====================================================================
+ // testFirmwareRequestHcodeUpdate
+ // =====================================================================
+ static size_t testFirmwareRequestHcodeUpdate(
+ uint64_t i_reqLen,
+ hostInterfaces::hbrt_fw_msg* i_req_fw_msg,
+ uint64_t i_respLen,
+ hostInterfaces::hbrt_fw_msg* i_resp_fw_msg )
+ {
+ TRACFCOMP(g_trac_hbrt, ENTER_MRK
+ "rt_firmware_request::testFirmwareRequestHcodeUpdate");
+
+ if (i_reqLen < (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(i_req_fw_msg->req_hcode_update)))
+ {
+ TRACFCOMP(g_trac_hbrt, ENTER_MRK"rt_firmware_request::"
+ "testFirmwareRequestHcodeUpdate: FAILED: Request "
+ "length(%d) needs to be at a minimum(%d)",
+ i_reqLen,
+ (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(i_req_fw_msg->req_hcode_update)) );
+ return -EINVAL;
+ }
+
+ if ( (0x100 != i_req_fw_msg->req_hcode_update.i_chipId) ||
+ ( 20 != i_req_fw_msg->req_hcode_update.i_section) ||
+ ( 30 != i_req_fw_msg->req_hcode_update.i_operation) ||
+ (0x400 != i_req_fw_msg->req_hcode_update.i_scomAddr) ||
+ (0x500 != i_req_fw_msg->req_hcode_update.i_scomData) )
+ {
+ TS_FAIL("rt_firmware_request::testFirmwareRequestHcodeUpdate: "
+ "FAILED: Loader received incorrect data: chipId:0x%X, "
+ "section:%d, operation:%d, scomAddr:0x%X, scomData:0x%X",
+ i_req_fw_msg->req_hcode_update.i_chipId,
+ i_req_fw_msg->req_hcode_update.i_section,
+ i_req_fw_msg->req_hcode_update.i_operation,
+ i_req_fw_msg->req_hcode_update.i_scomAddr,
+ i_req_fw_msg->req_hcode_update.i_scomData);
+ }
+
+ i_resp_fw_msg->io_type =
+ hostInterfaces::HBRT_FW_MSG_TYPE_RESP_GENERIC;
+
+ // dummy return value for testing
+ i_resp_fw_msg->resp_generic.o_status = 264;
+
+
+ TRACFCOMP(g_trac_hbrt, EXIT_MRK
+ "rt_firmware_request::testFirmwareRequestHcodeUpdate");
+
+ // just return 1 for testing
+ return 1;
+ } // end firmwareRequestHcodeUpdateTest
+
+ // =====================================================================
+ // compareAttributeHeader
+ // =====================================================================
+ static bool compareAttributeHeader(
+ const TARGETING::AttributeTank::Attribute* const l_attribute1,
+ const TARGETING::AttributeTank::Attribute* const l_attribute2)
+ {
+ bool retVal(true);
+
+ // Make sure the Attribute Header matches original data
+ if (0 != memcmp(&(l_attribute1->getHeader()),
+ &(l_attribute2->getHeader()),
+ sizeof(TARGETING::AttributeTank::AttributeHeader)))
+ {
+ retVal = false;
+ }
+
+ return retVal;
+ } // end compareAttributeHeader
+
+ // =====================================================================
+ // compareAttributeValues
+ // =====================================================================
+ static bool compareAttributeValues(
+ const TARGETING::AttributeTank::Attribute* const l_attribute1,
+ const TARGETING::AttributeTank::Attribute* const l_attribute2)
+ {
+ bool retVal(true);
+
+ // Compare the Attribute Values for a match
+ if (0 != memcmp(l_attribute1->getValue(),
+ l_attribute2->getValue(),
+ l_attribute2->getHeader().iv_valSize))
+ {
+ retVal = false;
+ }
+
+ return retVal;
+ } // end compareAttributeValues
+ /// end Firmware Request Test Helper Functions
+
+ // =====================================================================
+ // Some needed definitions
+ // =====================================================================
+ typedef std::pair<uint64_t,uint64_t> SCOM_KEY;
+ typedef std::map<SCOM_KEY,uint64_t> SCOM_MAP;
+ static SCOM_MAP cv_scomMap;
+ static std::map<void*, UtilLidMgr*> cv_loadedLids;
static uint64_t cv_hb_data_addr;
static uint64_t cv_comm_addr;
static uint64_t cv_comm_phys_addr;
@@ -1015,6 +1444,7 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
RuntimeLoaderTest::SCOM_MAP RuntimeLoaderTest::cv_scomMap;
std::map<void*, UtilLidMgr*> RuntimeLoaderTest::cv_loadedLids;
+// Initialize static member variables
uint64_t RuntimeLoaderTest::cv_hb_data_addr = 0;
uint64_t RuntimeLoaderTest::cv_comm_addr = 0;
uint64_t RuntimeLoaderTest::cv_comm_phys_addr = 0;
diff --git a/src/usr/trace/bufferpage.C b/src/usr/trace/bufferpage.C
index c6cfb57e0..27feb9bd7 100644
--- a/src/usr/trace/bufferpage.C
+++ b/src/usr/trace/bufferpage.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -41,7 +41,7 @@ namespace TRACE
uint64_t l_usedSize = this->usedSize;
// Verify there is enough space.
- while ((usedSize + i_size) < (PAGESIZE - sizeof(BufferPage)))
+ while ((l_usedSize + i_size) < (PAGESIZE - sizeof(BufferPage)))
{
// Atomically attempt to claim i_size worth.
uint64_t newSize = l_usedSize + i_size;
diff --git a/src/usr/trace/daemon/daemon.C b/src/usr/trace/daemon/daemon.C
index a70ad2997..dffe118b8 100644
--- a/src/usr/trace/daemon/daemon.C
+++ b/src/usr/trace/daemon/daemon.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -47,7 +47,6 @@
#include <devicefw/userif.H>
#include <mbox/mboxif.H>
-#include <config.h>
#include <console/consoleif.H>
#include <util/utilmbox_scratch.H>
#include <debugpointers.H>
diff --git a/src/usr/trace/runtime/rt_rsvdtracebuffer.C b/src/usr/trace/runtime/rt_rsvdtracebuffer.C
index b9d21b774..175850ff8 100644
--- a/src/usr/trace/runtime/rt_rsvdtracebuffer.C
+++ b/src/usr/trace/runtime/rt_rsvdtracebuffer.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2018 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -28,6 +28,18 @@
namespace TRACE
{
+
+/// Some constants to help keep track of the structure of the buffer
+/// Have these build on each other
+// A pointer of where the reserved memory points to itself. Helps to determine
+// if the buffer has been relocated
+const uint32_t RESERVED_MEMORY_POINTER_OFFSET = 0;
+// The location of the buffer for Entries.
+const uint32_t BUFFER_BEGINNINIG_BOUNDARY_OFFSET =
+ sizeof(uintptr_t) + RESERVED_MEMORY_POINTER_OFFSET;
+// Minimum size of the buffer, based on the buffers needs to be functional
+const uint32_t MINIMUM_SIZE_OF_BUFFER_IN_BYTES =
+ BUFFER_BEGINNINIG_BOUNDARY_OFFSET;
/**
* ctor
*/
@@ -48,17 +60,27 @@ void RsvdTraceBuffer::init(uint32_t i_bufferSize,
uintptr_t i_addressToBuffer,
uintptr_t* i_addressToHead)
{
- // If buffer is not already initilaized and incoming data is legit
+ // If buffer is not already initialized and incoming data is legit
if ( (false == isBufferValid()) &&
- (i_bufferSize > 0 ) &&
+ (i_bufferSize > MINIMUM_SIZE_OF_BUFFER_IN_BYTES ) &&
(i_addressToBuffer > 0) &&
(nullptr != i_addressToHead) )
{
- setBeginningBoundary(convertToCharPointer(i_addressToBuffer));
- setEndingBoundary(convertToCharPointer(i_addressToBuffer +
- i_bufferSize - 1));
+ // Set the list head pointer. This needs to be set first.
setListHeadPtr(i_addressToHead);
+ // Set the reserved memory pointer
+ iv_ptrToRsvdMem = reinterpret_cast<uintptr_t*>
+ (i_addressToBuffer + RESERVED_MEMORY_POINTER_OFFSET);
+
+ setBeginningBoundary(convertToCharPointer
+ (i_addressToBuffer + BUFFER_BEGINNINIG_BOUNDARY_OFFSET));
+ setEndingBoundary(convertToCharPointer
+ (i_addressToBuffer + i_bufferSize - 1));
+
+ // Check if buffer has moved and if so, realign the pointers
+ checkBuffer();
+
// Now that there is an actual/real buffer to point to, the buffer is
// valid, although it may/may not have any entries associated with it.
setBufferValidity(true);
@@ -66,6 +88,60 @@ void RsvdTraceBuffer::init(uint32_t i_bufferSize,
}
/**
+ * checkBuffer
+ */
+void RsvdTraceBuffer::checkBuffer()
+{
+ intptr_t l_offset(0);
+
+ // If the reserved memory data is not zero, meaning that buffer is being
+ // revisited again, and the memory does not match the current pointer of
+ // the reserved memory data, then the buffer has been relocated and the
+ // pointer info in the buffer needs to be realigned/corrected.
+ // The buffer gets revisited to pull data when a crash happens. Please
+ // see the details section for the class in the .H file.
+ if ((0 != iv_ptrToRsvdMem[0]) &&
+ (reinterpret_cast<uintptr_t>(iv_ptrToRsvdMem) != iv_ptrToRsvdMem[0]))
+ {
+ // Get the difference in memory location
+ l_offset = reinterpret_cast<uintptr_t>
+ (iv_ptrToRsvdMem) - iv_ptrToRsvdMem[0];
+
+ realignListPointers(l_offset);
+ }
+
+ // Persist the current buffer location
+ iv_ptrToRsvdMem[0] = reinterpret_cast<uintptr_t>(iv_ptrToRsvdMem);
+}
+
+/**
+ * realignListPointers
+ */
+void RsvdTraceBuffer::realignListPointers(intptr_t l_offset)
+{
+ // Verify that there is actual data to realign
+ Entry* l_head = getListHead();
+ if (l_head)
+ {
+ // Update the pointer to the list
+ *iv_ptrToHead = *iv_ptrToHead + l_offset;
+
+ // Get the the head of list to traverse over and correct pointers
+ Entry* l_entry = l_head = getListHead();
+ do
+ {
+ // Update the pointers of Entry item
+ l_entry->next = reinterpret_cast<Entry *>(
+ reinterpret_cast<uintptr_t>(l_entry->next) + l_offset);
+ l_entry->prev = reinterpret_cast<Entry *>(
+ reinterpret_cast<uintptr_t>(l_entry->prev) + l_offset);
+
+ l_entry = l_entry->next;
+ } while (l_entry != l_head);
+ }
+}
+
+/**
* insertEntry
*/
Entry* RsvdTraceBuffer::insertEntry(uint32_t i_dataSize)
@@ -83,9 +159,11 @@ Entry* RsvdTraceBuffer::insertEntry(uint32_t i_dataSize)
// (Alignment is needed so that Entry's members can be atomically
// updated).
uint32_t l_entrySize = getAlignedSizeOfEntry(i_dataSize);
- if (makeSpaceForEntry(l_entrySize, l_availableAddress) && l_availableAddress)
+ if (makeSpaceForEntry(l_entrySize, l_availableAddress) &&
+ l_availableAddress)
{
- // Set entry if space was created and an avilable address is returned
+ // Set entry if space was created and an available address
+ // is returned
l_entry = reinterpret_cast<Entry*>(l_availableAddress);
setListTail(l_entry);
@@ -104,7 +182,8 @@ uint32_t RsvdTraceBuffer::makeSpaceForEntry(uint32_t i_spaceNeeded,
o_availableAddress = nullptr;
uint32_t l_spaceAvailable = 0;
- // Only look for space if requested space is less or equal to buffer size
+ // Only look for space if requested space is less than
+ // or equal to buffer size
if (i_spaceNeeded <= getBufferSize())
{
l_spaceAvailable = getAvailableSpace(i_spaceNeeded, o_availableAddress);
@@ -112,7 +191,7 @@ uint32_t RsvdTraceBuffer::makeSpaceForEntry(uint32_t i_spaceNeeded,
// Keep requesting for space until we get the space that is asked for
while (l_spaceAvailable < i_spaceNeeded)
{
- // If we can't remove any entries, then we exhausted all efforts
+ // If we can't remove any entries, then we exhausted all efforts.
// Should not happen, because the space requested should be less
// than or equal to buffer size
if (!removeOldestEntry())
@@ -167,7 +246,7 @@ uint32_t RsvdTraceBuffer::getAvailableSpace(uint32_t i_spaceNeeded,
// space needed, then return that value else return the space
// available at the beginning of the buffer. If the space at the
// end does not have enough of the needed space, then space will
- // ultimately be made at the beginning of the
+ // ultimately be made at the beginning of the buffer.
//
// Right now, you are probably thinking, what if I only need 5 free
// spaces and if the end has 10 available and the beginning has 7
@@ -215,7 +294,7 @@ bool RsvdTraceBuffer::removeOldestEntry()
if (!isListEmpty())
{
// Get a handle to the head
- Entry* l_head = getListHead();
+ Entry* l_head(getListHead());
// Is there only one entry?
if (l_head->next == l_head)
@@ -252,12 +331,17 @@ uint32_t RsvdTraceBuffer::getTrace(void* o_data, uint32_t i_dataSize) const
// Before continuing, make sure the buffer is valid
if (isBufferValid())
{
+ // If caller passed in a nullptr for the data or zero for the data size,
+ // then that signals the user only wants to ascertain the size
+ // requirement to hold all the data associated with the entries.
if ((nullptr == o_data) || (0 == i_dataSize))
{
+ // Caller wants to ascertain size requirements for data
l_sizeOfBufferExtracted = getAggregateSizeOfEntries();
}
else
{
+ // Caller wants to collect data - enough data to fill data size
l_sizeOfBufferExtracted = getTraceEntries(o_data, i_dataSize);
}
}
@@ -273,7 +357,7 @@ uint32_t RsvdTraceBuffer::getAggregateSizeOfEntries() const
uint32_t l_aggregatedSize(0);
// Get a handle to the head
- Entry* l_head = getListHead();
+ Entry* l_head(getListHead());
// Make sure the list is not null
if (l_head)
@@ -283,8 +367,8 @@ uint32_t RsvdTraceBuffer::getAggregateSizeOfEntries() const
{
// Need to add to the size, the size of an uint32_t. The uint32_t
// will hold the size of the data that is to be returned along
- // with the returned data. This is why it is added.
- l_aggregatedSize += l_entry->size + sizeof(uint32_t);
+ // with the returned data.
+ l_aggregatedSize += ALIGN_8(l_entry->size) + sizeof(uint32_t);
l_entry = l_entry->next;
} while (l_entry != l_head);
}
@@ -304,12 +388,12 @@ uint32_t RsvdTraceBuffer::getTraceEntries(void* o_data, uint32_t i_dataSize) con
if ((nullptr != o_data) &&
(i_dataSize >= sizeof(trace_buf_head_t)) )
{
+ // Clear the outgoing data before populating it
+ memset(o_data, 0, i_dataSize);
+
// Get a useful "trace buffer head" handle to the data buffer passed in
trace_buf_head_t* l_header =reinterpret_cast<trace_buf_head_t*>(o_data);
- // Now that we have an easy handle to the data, let's clear it for now
- memset(l_header, '\0', sizeof(trace_buf_head_t));
-
// Now populate the trace buffer header with some useful info
l_header->ver = TRACE_BUF_VERSION;
l_header->hdr_len = l_header->size = sizeof(trace_buf_head_t);
@@ -318,35 +402,42 @@ uint32_t RsvdTraceBuffer::getTraceEntries(void* o_data, uint32_t i_dataSize) con
l_header->endian_flg = 'B'; // Big Endian.
// Get a handle to the head
- Entry* l_head = getListHead();
+ Entry* l_head(getListHead());
// Extract the trace info from this class' internal buffer
// If the list is not empty and have data then extract the trace info
if (l_head)
{
- // Keep a tally of the size of the data that can be copied over
- uint32_t l_totalSize(l_head->size);
+ // Keep a tally of the size of the data that can be copied over.
+ // Also account for the trace_buf_head_t that is at the beginning
+ // of buffer o_data.
+ uint32_t l_totalSize(sizeof(trace_buf_head_t));
// Keep a tally of the number of entries that can be extracted
uint32_t l_entriesToExtract(0);
// The entry size as data type uint32_t; for code up keep
uint32_t l_entrySize(0);
// Get a handle on the last entry on the list
- Entry* l_entry = l_head->prev;
+ Entry* l_entry(l_head->prev);
- // Calculate the number of entries that can be stuffed into data buffer
- // starting with newest entry (tail) to oldest entry (head)
+ // Calculate the number of entries that can be stuffed into the data
+ // buffer - starting with newest entry (tail) to oldest entry (head)
do
{
- // Calculate the size: add the size of the data, that will be
- // copied over, plus the size of the type of the entry size,
- // that will hold the size of the data being copied over.
- if ((l_totalSize + l_entry->size + sizeof(l_entrySize)) <= i_dataSize)
+ // Calculate the size: add the size of the data (that will be
+ // copied over) plus the size of the type of the entry size
+ // (that will hold the size of the data being copied over).
+ if ((l_totalSize + ALIGN_8(l_entry->size) + sizeof(l_entrySize))
+ <= i_dataSize)
{
- l_totalSize += l_entry->size + sizeof(l_entrySize);
+ l_totalSize += ALIGN_8(l_entry->size) + sizeof(l_entrySize);
++l_entriesToExtract;
}
else // Can't retrieve this entry; it breaks the size limitation
{
+ // Although we are done here, we still need to point to
+ // the previous item. The continuation of this algorithm
+ // depends on it (expects to be one behind the needed data)
+ l_entry = l_entry->prev;
break;
}
@@ -368,17 +459,18 @@ uint32_t RsvdTraceBuffer::getTraceEntries(void* o_data, uint32_t i_dataSize) con
// Copy entry data.
memcpy(&l_data[l_header->size], l_entry->data, l_entry->size);
- l_header->size += l_entry->size;
+ l_header->size += ALIGN_8(l_entry->size);
// Copy entry size.
l_entrySize = l_entry->size + sizeof(l_entrySize);
memcpy(&l_data[l_header->size], &l_entrySize, sizeof(l_entrySize));
l_header->size += sizeof(l_entrySize);
+ // increment/decrements our counters
++l_header->te_count;
--l_entriesToExtract;
} // end while (l_entriesToExtract)
- } // end if (!isListEmpty())
+ } // end if (l_head)
// Update the size of the entries retrieved and the
// next free memory location in header trace buffer
diff --git a/src/usr/trace/runtime/rt_rsvdtracebuffer.H b/src/usr/trace/runtime/rt_rsvdtracebuffer.H
index 24c9204cf..e804a41ed 100644
--- a/src/usr/trace/runtime/rt_rsvdtracebuffer.H
+++ b/src/usr/trace/runtime/rt_rsvdtracebuffer.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -43,9 +43,25 @@ namespace TRACE
*
* @brief Class to manage the Reserved Trace Buffer
*
- * This is a utility class to manage the buffer - looking for space
- * for an entry, adding entries and removing entries.
- *
+ * @details This is a utility class to manage the buffer - looking
+ * for space for an entry, adding entries and removing entries.
+ * When a system crashes, this buffer will persist the last
+ * few traces. When HB is IPLed again, the persisted data
+ * will be retrieved for inspection.
+ * With PHYP, the buffer will be retrieved at the same memory
+ * location as before the crash. With OPAL, the buffer may be
+ * relocated to a different location and all the pointers within
+ * the buffer will be invalid. If the buffer does get relocated,
+ * this class will correct the pointers.
+ * To correct the pointers, a section at the beginning of the
+ * persisted buffer is reserved to save the address of the buffer.
+ * Such that when the buffer is retrieved after a crash, if that
+ * data does not match the current buffer address, then we can
+ * conclude it has been relocated and the pointers in the buffer
+ * need to be updated/corrected.
+ * If the data at the beginning of the buffer is 0, then this is
+ * first time this buffer is being used and therefore no need to
+ * correct pointers.
*/
class RsvdTraceBuffer
{
@@ -61,7 +77,7 @@ namespace TRACE
*
* @param[in] i_addressToBuffer - Where the buffer begins
*
- * @param[in] i_addressToHead - A pointer to a ponter to the first
+ * @param[in] i_addressToHead - A pointer to a pointer to the first
* Entry, cannot be a nullptr
*/
void init(uint32_t i_bufferSize,
@@ -89,12 +105,12 @@ namespace TRACE
* If o_data is valid and the i_size is greater than
* the size of trace_buf_head_t, then as many trace
* entries will be returned in the o_data buffer that
- * i_size will allow.
+ * i_size will allow, minus size of trace_buf_head_t.
*
- * @param[in] o_data - if not null, the buffer area to copy
+ * @param[out] o_data - if not null, the buffer area to copy
* trace data into
*
- * @param[out] i_dataSize - if not 0, the size of the buffer area,
+ * @param[in] i_dataSize - if not 0, the size of the buffer area,
* which dictates how many trace entries'
* payload (or data the entry contains)
* that can be copied
@@ -123,7 +139,23 @@ namespace TRACE
*/
uint32_t getNumberOfEntries() const;
+ // Private methods
private:
+
+ /** @brief Checks the buffer to see if it has been relocated and if
+ * so, realign the pointers within the buffer.
+ */
+ void checkBuffer();
+
+
+ /** @brief When and if buffer has been relocated this method will
+ * realign the pointers within the buffer.
+ *
+ * @param[in] i_offset - the offset the buffer has moved
+ * within memory
+ */
+ void realignListPointers(intptr_t i_offset);
+
/** @brief This function will find a contiguous piece of memory that
* is large enough in size to accommodate the space needed.
* If not enough free contiguous memory exists to accommodate
@@ -147,7 +179,8 @@ namespace TRACE
* requested is not larger in size to the buffer size,
* then an available space will eventually be returned.
*
- * @param[in] i_spaceNeeded - @see insertEntry::i_dataSize above
+ * @param[in] i_spaceNeeded - The size of the contiguous piece
+ * of memory caller desires
*
* @param[out] o_availableAddress - A pointer to the contiguous
* piece of memory found that satisfies the caller's
@@ -160,8 +193,8 @@ namespace TRACE
char* &o_availableAddress);
/** @brief Returns a contiguous piece of memory that will satisfy
- * the space that is needed if large enough space can be
- * had, else returns the size of the largest contiguous
+ * the space that is needed if a large enough space can be
+ * found, else return the size of the largest contiguous
* piece of memory.
*
* @algorithm There are three cases to consider:
@@ -176,7 +209,7 @@ namespace TRACE
* ---------------------------------------------------------
* | < - 10 bytes -> | Head | .....| Tail | <- 20 bytes -> |
* ---------------------------------------------------------
- * scenario 1: Contigous space desired: 15 bytes
+ * scenario 1: Contiguous space desired: 15 bytes
* Return the 20 bytes after the Tail
* scenario 2: Contiguous space desired: 10 bytes
* Return the 20 bytes after the Tail
@@ -223,18 +256,21 @@ namespace TRACE
* ---------------------------------------------------------
* | .... | Tail | < - 30 bytes -> | Head | ....
* ---------------------------------------------------------
- * Case 1: Contigous space desired: 25 bytes
+ * Case 1: Contiguous space desired: 25 bytes
* Return the 30 bytes between Tail and Head.
- * Case 2: Contigous space desired: 40 bytes
+ * Case 2: Contiguous space desired: 40 bytes
* Return the 30 bytes between Tail and Head.
*
- * @param[in] i_spaceNeeded - @see insertEntry::i_dataSize above
+ * @param[in] i_spaceNeeded - The size of the contiguous piece
+ * of memory caller desires
*
- * @param[out] o_availableAddress - @see makeSpaceForEntry above
+ * @param[out] o_availableAddress - A pointer to the biggest
+ * piece of contiguous memory found. May or may
+ * not satisfy i_spaceNeeded.
*
* @return The minimum size of the space found that meets the
* requested space needed; or the largest size that comes
- * close to meeting the space needed
+ * close to meeting the space needed.
*
*/
uint32_t getAvailableSpace(uint32_t i_spaceNeeded,
@@ -256,7 +292,7 @@ namespace TRACE
uint32_t getAggregateSizeOfEntries() const;
/** @brief This will return as many data entries that can be
- * accommodated by size
+ * accommodated by i_dataSize
*
* @param[out] o_data - the buffer area to copy trace data into
*
@@ -380,7 +416,6 @@ namespace TRACE
*
* @param[in] i_tail - a pointer to an Entry data type;
* OK to be a nullptr
- *
*/
void setListTail(Entry* i_newEntry)
{
@@ -448,9 +483,13 @@ namespace TRACE
void clearPtrToHead()
{ iv_ptrToHead = nullptr; }
+ // Private data members
+ private:
+ uintptr_t* iv_ptrToRsvdMem; //< Pointer to Reserved Memory. Used to
+ // realign pointers if RsvdMem relocates
+ uintptr_t* iv_ptrToHead; //< Pointer to oldest Entry (time wise)
char *iv_bufferBeginningBoundary; //< Pointer to beginning of buffer
char *iv_bufferEndingBoundary; //< Pointer to end of buffer
- uintptr_t* iv_ptrToHead; //< Pointer to oldest Entry (time wise)
bool iv_isBufferValid; //< Indicates an initialized buffer
// For testing purposes only
diff --git a/src/usr/trace/runtime/rt_rsvdtracebufservice.C b/src/usr/trace/runtime/rt_rsvdtracebufservice.C
index 3d0c1bb95..21316e6f6 100644
--- a/src/usr/trace/runtime/rt_rsvdtracebufservice.C
+++ b/src/usr/trace/runtime/rt_rsvdtracebufservice.C
@@ -80,10 +80,10 @@ void RsvdTraceBufService::init()
// If the data is not NULL, then retrieve crashed data
// I want NULL in this case, not nullptr; *l_addressToHead is an int.
// If I use nullptr; compiler complains
- //if (*l_addressToHead != NULL)
- //{
- // retrieveDataFromLastCrash();
- //}
+ if (*l_addressToHead != NULL)
+ {
+ retrieveDataFromLastCrash();
+ }
// After gathering trace info from previous crash, clear buffer data
iv_rsvdTraceBuffer.clearBuffer();
diff --git a/src/usr/trace/runtime/test/testrsvdtracebuf.H b/src/usr/trace/runtime/test/testrsvdtracebuf.H
index 148df5d07..0b6374ba7 100644
--- a/src/usr/trace/runtime/test/testrsvdtracebuf.H
+++ b/src/usr/trace/runtime/test/testrsvdtracebuf.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -25,10 +25,8 @@
#include <cxxtest/TestSuite.H>
#include <trace/runtime/rt_rsvdtracebuffer.H> // TRACE::RsvdTraceBuffer
-#include <trace/runtime/rt_rsvdtracebufservice.H> // TRACE::RsvdTraceBufService
-#include <trace/entry.H> // TRACE::Entry
-#include <trace/compdesc.H> // TRACE::ComponentDesc
-#include <util/runtime/util_rt.H> // hb_get_rt_rsvd_mem
+#include <trace/entry.H> // TRACE::Entry
+#include <trace/compdesc.H> // TRACE::ComponentDesc
#include <stdint.h> // uint32_t
#include <stdlib.h> // malloc
@@ -83,7 +81,7 @@ void testRsvdTraceBuffConstructor()
}
TRACFCOMP(g_trac_test, EXIT_MRK"RsvdTraceBuffTestSuite:%s", __func__);
-} // void testRsvdTraceBuffConstructor()
+} // end void testRsvdTraceBuffConstructor
// Some more simple tests - the initializer
void testRsvdTraceBuffInit()
@@ -108,7 +106,7 @@ void testRsvdTraceBuffInit()
l_addressToHead);
char* l_bufferBegin = reinterpret_cast<char*>(l_bufferAddr +
- sizeof(uintptr_t));
+ (2 * sizeof(uintptr_t)));
char* l_bufferEnd = reinterpret_cast<char*>(l_bufferAddr +
l_bufferSize - 1);
@@ -155,7 +153,7 @@ void testRsvdTraceBuffInit()
}
TRACFCOMP(g_trac_test, EXIT_MRK"RsvdTraceBuffTestSuite:%s", __func__);
-} // end void testRsvdTraceBuffInit()
+} // end void testRsvdTraceBuffInit
// Test where buffer is too small to accommodate any Entry size
void testRsvdTraceBuffBufferToSmall()
@@ -225,7 +223,7 @@ void testRsvdTraceBuffBufferToSmall()
free(l_buffer);
TRACFCOMP(g_trac_test, EXIT_MRK"RsvdTraceBuffTestSuite:%s", __func__);
-} // end void testRsvdTraceBuffBufferToSmall()
+} // end void testRsvdTraceBuffBufferToSmall
// Test where buffer is just the right size to fit a single Entry
void testRsvdTraceBuffOnlyAccommodateOneItem()
@@ -283,7 +281,8 @@ void testRsvdTraceBuffOnlyAccommodateOneItem()
TS_FAIL("%s:%s: Pointer to list is not correct", __FILE__, __func__);
}
- if (true != runSelfDiagnostics(l_rsvd))
+ uint32_t l_itemCount(0);
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -329,7 +328,8 @@ void testRsvdTraceBuffOnlyAccommodateOneItem()
TS_FAIL("%s:%s: Pointer to list is not correct", __FILE__, __func__);
}
- if (true != runSelfDiagnostics(l_rsvd))
+ l_itemCount = 0;
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -354,7 +354,8 @@ void testRsvdTraceBuffOnlyAccommodateOneItem()
TS_FAIL("%s:%s: Pointer to list is not correct", __FILE__, __func__);
}
- if (true != runSelfDiagnostics(l_rsvd))
+ l_itemCount = 0;
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -363,7 +364,7 @@ void testRsvdTraceBuffOnlyAccommodateOneItem()
free(l_buffer);
TRACFCOMP(g_trac_test, EXIT_MRK"RsvdTraceBuffTestSuite:%s", __func__);
-} // end void testRsvdTraceBuffOnlyAccommodateOneItem()
+} // end void testRsvdTraceBuffOnlyAccommodateOneItem
// Test where buffer is just the right size to fit a single Entry plus size
void testRsvdTraceBuffOnlyAccommodateOneItemPlusSize()
@@ -378,7 +379,7 @@ void testRsvdTraceBuffOnlyAccommodateOneItemPlusSize()
l_rsvd);
// Adjust buffer to the area we are interested in
- char* l_buffer = l_fullBuffer + sizeof(uintptr_t);
+ char* l_buffer = l_fullBuffer + (2 * sizeof(uintptr_t));
if (l_rsvd.getBufferSize() != l_bufferSize)
{
@@ -434,8 +435,8 @@ void testRsvdTraceBuffOnlyAccommodateOneItemPlusSize()
__FILE__, __func__);
}
-
- if (true != runSelfDiagnostics(l_rsvd))
+ uint32_t l_itemCount(0);
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -533,7 +534,8 @@ void testRsvdTraceBuffOnlyAccommodateOneItemPlusSize()
__FILE__, __func__);
}
- if (true != runSelfDiagnostics(l_rsvd))
+ l_itemCount = 0;
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -603,7 +605,8 @@ void testRsvdTraceBuffOnlyAccommodateOneItemPlusSize()
__FILE__, __func__);
}
- if (true != runSelfDiagnostics(l_rsvd))
+ l_itemCount = 0;
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -682,7 +685,7 @@ void testRsvdTraceBuffOnlyAccommodateOneItemPlusSize()
free(l_fullBuffer);
TRACFCOMP(g_trac_test, EXIT_MRK"RsvdTraceBuffTestSuite:%s", __func__);
-} // end void testRsvdTraceBuffOnlyAccommodateOneItemPlusSize()
+} // end void testRsvdTraceBuffOnlyAccommodateOneItemPlusSize
// Test where buffer is just the right size to fit two Entries
void testRsvdTraceBuffOnlyAccommodateTwoItems()
@@ -697,7 +700,7 @@ void testRsvdTraceBuffOnlyAccommodateTwoItems()
l_rsvd);
// Adjust buffer to the area we are interested in
- char* l_buffer = l_fullBuffer + sizeof(uintptr_t);
+ char* l_buffer = l_fullBuffer + (2 * sizeof(uintptr_t));
if (l_rsvd.getBufferSize() != l_bufferSize)
{
@@ -741,7 +744,8 @@ void testRsvdTraceBuffOnlyAccommodateTwoItems()
__FILE__, __func__);
}
- if (true != runSelfDiagnostics(l_rsvd))
+ uint32_t l_itemCount(0);
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -790,7 +794,8 @@ void testRsvdTraceBuffOnlyAccommodateTwoItems()
__FILE__, __func__);
}
- if (true != runSelfDiagnostics(l_rsvd))
+ l_itemCount = 0;
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -833,7 +838,8 @@ void testRsvdTraceBuffOnlyAccommodateTwoItems()
__FILE__, __func__);
}
- if (true != runSelfDiagnostics(l_rsvd))
+ l_itemCount = 0;
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -887,7 +893,8 @@ void testRsvdTraceBuffOnlyAccommodateTwoItems()
__FILE__, __func__);
}
- if (true != runSelfDiagnostics(l_rsvd))
+ l_itemCount = 0;
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -912,7 +919,7 @@ void testRsvdTraceBuffTestTheEnds()
l_rsvd);
// Adjust buffer to the area we are interested in
- char* l_buffer = l_fullBuffer + sizeof(uintptr_t);
+ char* l_buffer = l_fullBuffer + (2 * sizeof(uintptr_t));
if (l_rsvd.getBufferSize() != l_bufferSize)
{
@@ -991,7 +998,8 @@ void testRsvdTraceBuffTestTheEnds()
__FILE__, __func__);
}
- if (true != runSelfDiagnostics(l_rsvd))
+ uint32_t l_itemCount(0);
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -1028,7 +1036,8 @@ void testRsvdTraceBuffTestTheEnds()
__FILE__, __func__);
}
- if (true != runSelfDiagnostics(l_rsvd))
+ l_itemCount = 0;
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -1064,7 +1073,8 @@ void testRsvdTraceBuffTestTheEnds()
__FILE__, __func__);
}
- if (true != runSelfDiagnostics(l_rsvd))
+ l_itemCount = 0;
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -1089,16 +1099,18 @@ void testRsvdTraceBuffTestReentrant ()
iv_buffer = initializeRsvdBuffer(iv_bufferSize,
l_rsvd);
+
iv_bufferBeginningBoundary = l_rsvd.iv_bufferBeginningBoundary;
iv_bufferEndingBoundary = l_rsvd.iv_bufferEndingBoundary;
// Adjust buffer to the area we are interested in
- char* l_buffer = iv_buffer + sizeof(uintptr_t);
+ char* l_buffer = iv_buffer + (2 * sizeof(uintptr_t));
- if (l_rsvd.getBufferSize() != iv_bufferSize)
+ if (l_rsvd.getBufferSize() != (iv_bufferSize - sizeof(uintptr_t)))
{
- TS_FAIL("%s:%s: buffer size is not correct",
- __FILE__, __func__);
+ TS_FAIL("%s:%s: buffer size is not correct %d %d",
+ __FILE__, __func__, l_rsvd.getBufferSize(),
+ (iv_bufferSize - sizeof(uintptr_t)));
}
if (true != l_rsvd.isBufferValid())
@@ -1149,7 +1161,8 @@ void testRsvdTraceBuffTestReentrant ()
__FILE__, __func__);
}
- if (true != runSelfDiagnostics(l_rsvd))
+ uint32_t l_itemCount(0);
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -1168,7 +1181,7 @@ void testRsvdTraceBuffTestReentrant2()
TRACE::RsvdTraceBuffer l_rsvd;
initializeRsvdBufferForReentrant(l_rsvd);
- if (l_rsvd.getBufferSize() != iv_bufferSize)
+ if (l_rsvd.getBufferSize() != (iv_bufferSize - sizeof(uintptr_t)))
{
TS_FAIL("%s:%s: buffer size is not correct",
__FILE__, __func__);
@@ -1196,7 +1209,8 @@ void testRsvdTraceBuffTestReentrant2()
TS_FAIL("%s:%s: buffer is not valid", __FILE__, __func__);
}
- if (true != runSelfDiagnostics(l_rsvd))
+ uint32_t l_itemCount(0);
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
{
TS_FAIL("%s:%s: self diagnostics discovered an error",
__FILE__, __func__);
@@ -1259,7 +1273,7 @@ void testRsvdTraceBuffTestReentrant3()
TRACE::RsvdTraceBuffer l_rsvd;
initializeRsvdBufferForReentrant(l_rsvd);
- if (l_rsvd.getBufferSize() != iv_bufferSize)
+ if (l_rsvd.getBufferSize() != (iv_bufferSize - sizeof(uintptr_t)))
{
TS_FAIL("%s:%s: buffer size is not correct",
__FILE__, __func__);
@@ -1353,7 +1367,7 @@ void testRsvdTraceBuffTestReentrant4()
TRACE::RsvdTraceBuffer l_rsvd;
initializeRsvdBufferForReentrant(l_rsvd);
- if (l_rsvd.getBufferSize() != iv_bufferSize)
+ if (l_rsvd.getBufferSize() != (iv_bufferSize - sizeof(uintptr_t)))
{
TS_FAIL("%s:%s: buffer size is not correct",
__FILE__, __func__);
@@ -1423,7 +1437,7 @@ void testRsvdTraceBuffTestReentrant5()
TRACE::RsvdTraceBuffer l_rsvd;
initializeRsvdBufferForReentrant(l_rsvd);
- if (l_rsvd.getBufferSize() != iv_bufferSize)
+ if (l_rsvd.getBufferSize() != (iv_bufferSize - sizeof(uintptr_t)))
{
TS_FAIL("%s:%s: buffer size is not correct",
__FILE__, __func__);
@@ -1474,11 +1488,175 @@ void testRsvdTraceBuffTestReentrant5()
TRACFCOMP(g_trac_test, EXIT_MRK"RsvdTraceBuffTestSuite:%s", __func__);
} // end void testRsvdTraceBuffTestReentrant5
+// Test when the buffer has been relocated
+// To simulate that the buffer has been relocated in memory and the pointers
+// within the buffer corrected, I create a buffer and divided it into
+// 3 sections. I populate the middle section with data and verify that it
+// is valid. Then I copy the middle buffer data over to the top section,
+// basically a memory location before the middle buffer. Zero out the middle
+// section to keep myself honest, then hand that buffer over to the
+// RsvdTraceBuffer class, which should detect that the buffer has been relocated
+// and correct the pointers. Once the RsvdTraceBuffer class has worked it's
+// magic, the buffer is tested for correctness. I repeat this process by
+// moving the buffer data to the bottom buffer, basically a memory location
+// after the top and repeat this test.
+void testRsvdTraceBuffTestBufferRelocation()
+{
+ TRACFCOMP(g_trac_test, ENTER_MRK"RsvdTraceBuffTestSuite:%s", __func__);
+
+ // Size of each buffer segment (top buffer, middle buffer, bottom buffer)
+ const uint32_t SEGMENT_BUFFER_SIZE = 1024;
+ const uint32_t NUM_SEGMENTS = 3;
+ // Aggregate the size of the 3 buffer segments.
+ uint32_t l_bufferSize = NUM_SEGMENTS * SEGMENT_BUFFER_SIZE;
+ // Create the buffer of all combined segments and 'zero' out
+ char l_buffer[l_bufferSize];
+ memset(l_buffer, 0, l_bufferSize);
+
+ // Segment the buffer into 3 sections, top, middle, bottom
+ char * l_niflheim = l_buffer;
+ char * l_midgard = &(l_buffer[1 * SEGMENT_BUFFER_SIZE]);
+ char * l_muspelheim = &(l_buffer[2 * SEGMENT_BUFFER_SIZE]);
+
+ uint32_t l_itemCount(0);
+ uint32_t l_expectedItemCount(3);
+ TRACE::RsvdTraceBuffer l_rsvd;
+
+ // Populate middle buffer with data and verify it is correct
+ // This is just setting up the data before simulating a relocation
+ {
+ // Get the address of buffer
+ uintptr_t l_bufferAddr = reinterpret_cast<uintptr_t>(l_midgard);
+
+ // Get a pointer to where the list head needs to reside in the buffer
+ uintptr_t *l_addressToListHead = reinterpret_cast<uintptr_t *>(l_bufferAddr);
+
+
+ l_rsvd.init(SEGMENT_BUFFER_SIZE - sizeof(uintptr_t), // subtract list head pointer
+ l_bufferAddr + sizeof(uintptr_t), // 'hop' over list head pointer
+ l_addressToListHead);
+
+ // populate the middle buffer (l_midgard) with data
+ l_rsvd.insertEntry(sizeof(TRACE::Entry) + 20);
+ l_rsvd.insertEntry(sizeof(TRACE::Entry) + 5);
+ l_rsvd.insertEntry(sizeof(TRACE::Entry) + 30);
+
+ // Validate the buffer
+ l_itemCount = 0;
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
+ {
+ TS_FAIL("%s:%s: Entry datas in midgard are corrupt",
+ __FILE__, __func__);
+ }
+
+ if (l_itemCount != l_expectedItemCount)
+ {
+ TS_FAIL("%s:%s: The number of items found in midgard is incorrect, "
+ " expected %d, but got back %d",
+ __FILE__, __func__, l_expectedItemCount, l_itemCount);
+ }
+ }
+
+ // Copy data over to the top buffer and clear out the middle buffer
+ // Simulate a relocation of the buffer to a memory address that precedes
+ // the original buffer's memory location
+ memcpy(l_niflheim, l_midgard, SEGMENT_BUFFER_SIZE);
+ memset(l_midgard, 0, SEGMENT_BUFFER_SIZE);
+
+ // Test the top buffer
+ {
+ // Get the address of buffer
+ uintptr_t l_bufferAddr = reinterpret_cast<uintptr_t>(l_niflheim);
+
+ // Get a pointer to where the list head needs to reside in the buffer
+ uintptr_t *l_addressToListHead = reinterpret_cast<uintptr_t *>(l_bufferAddr);
+
+ // First invalidate buffer
+ // We need to invalidate the buffer before using it again. Saying
+ // it is invalid is probably a misnomer here, it really should be
+ // 'buffer is not initialized'. In a real situation, HB would have
+ // crashed and restarted. The validity of the buffer would be false
+ // since that info is not persisted. The buffer gets initialized with
+ // buffer data, which may or may not be empty. During the
+ // initialization the buffer gets evaluated to see if there is crash
+ // data to retrieve and a buffer that may or may not need the pointers
+ // corrected.
+ l_rsvd.iv_isBufferValid = false;
+ l_rsvd.init(SEGMENT_BUFFER_SIZE - sizeof(uintptr_t), // subtract list head pointer
+ l_bufferAddr + sizeof(uintptr_t), // 'hop' over list head pointer
+ l_addressToListHead);
+
+ // Validate the buffer
+ l_itemCount = 0;
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
+ {
+ TS_FAIL("%s:%s: Entry datas in niflheim are corrupt",
+ __FILE__, __func__);
+ }
+
+ if (l_itemCount != l_expectedItemCount)
+ {
+ TS_FAIL("%s:%s: The number of items found in niflheim is incorrect, "
+ " expected %d, but got back %d",
+ __FILE__, __func__, l_expectedItemCount, l_itemCount);
+
+ }
+ }
+
+ // Copy data over to the bottom buffer and clear out the top buffer
+ // Simulate a relocation of the buffer to a memory address that succeeds
+ // the original buffer's memory location
+ memcpy(l_muspelheim, l_niflheim, SEGMENT_BUFFER_SIZE);
+ memset(l_niflheim, 0, SEGMENT_BUFFER_SIZE);
+
+ // Test the bottom buffer
+ {
+ // Get the address of buffer
+ uintptr_t l_bufferAddr = reinterpret_cast<uintptr_t>(l_muspelheim);
+
+ // Get a pointer to where the list head needs to reside in the buffer
+ uintptr_t *l_addressToListHead = reinterpret_cast<uintptr_t *>(l_bufferAddr);
+
+ // First invalidate buffer
+ // We need to invalidate the buffer before using it again. Saying
+ // it is invalid is probably a misnomer here, it really should be
+ // 'buffer is not initialized'. In a real situation, HB would have
+ // crashed and restarted. The validity of the buffer would be false
+ // since that info is not persisted. The buffer gets initialized with
+ // buffer data, which may or may not be empty. During the
+ // initialization the buffer gets evaluated to see if there is crash
+ // data to retrieve and a buffer that may or may not need the pointers
+ // corrected.
+ l_rsvd.iv_isBufferValid = false;
+ l_rsvd.init(SEGMENT_BUFFER_SIZE - sizeof(uintptr_t), // subtract list head pointer
+ l_bufferAddr + sizeof(uintptr_t), // 'hop' over list head pointer
+ l_addressToListHead);
+
+ // Validate the buffer
+ l_itemCount = 0;
+ if (true != runSelfDiagnostics(l_rsvd, l_itemCount))
+ {
+ TS_FAIL("%s:%s: Entry datas in muspelheim are corrupt",
+ __FILE__, __func__);
+ }
+
+ if (l_itemCount != l_expectedItemCount)
+ {
+ TS_FAIL("%s:%s: The number of items found in muspelheim is incorrect, "
+ " expected %d, but got back %d",
+ __FILE__, __func__, l_expectedItemCount, l_itemCount);
+ }
+ }
+ TRACFCOMP(g_trac_test, EXIT_MRK"RsvdTraceBuffTestSuite:%s", __func__);
+} // end void testRsvdTraceBuffTestBufferRelocation
+
private:
// Helpful methods to help in testing
char* initializeRsvdBuffer(uint32_t i_bufferSize,
TRACE::RsvdTraceBuffer& i_rsvd)
{
+ i_bufferSize += sizeof(uintptr_t);
+ iv_bufferSize = i_bufferSize;
// Create a buffer
uint32_t l_realBufferSize = i_bufferSize + sizeof(uintptr_t);
char *l_buffer = reinterpret_cast<char*>(malloc(l_realBufferSize));
@@ -1513,7 +1691,7 @@ void initializeRsvdBufferForReentrant(TRACE::RsvdTraceBuffer& i_rsvd)
}
-bool runSelfDiagnostics(TRACE::RsvdTraceBuffer& l_rsvd)
+bool runSelfDiagnostics(TRACE::RsvdTraceBuffer& l_rsvd, uint32_t & o_itemCount)
{
bool l_everythingChecksOut = true;
uintptr_t l_bufferBeginningBoundary = l_rsvd.getAddressOfPtr
@@ -1521,15 +1699,15 @@ bool runSelfDiagnostics(TRACE::RsvdTraceBuffer& l_rsvd)
uintptr_t l_bufferEndingBoundary = l_rsvd.getAddressOfPtr
(l_rsvd.iv_bufferEndingBoundary);
+ o_itemCount = 0;
+
if (!l_rsvd.isListEmpty())
{
- uint32_t l_itemCount(0);
-
TRACE::Entry* l_entry = l_rsvd.getListHead();
TRACE::Entry* l_head = l_entry;
do
{
- ++l_itemCount;
+ ++o_itemCount;
uintptr_t l_entryAddr = l_rsvd.getAddressOfPtr(l_entry);
uintptr_t l_entryAddrEnd =
l_rsvd.getEndingAddressOfEntry(l_entry);
@@ -1539,7 +1717,7 @@ bool runSelfDiagnostics(TRACE::RsvdTraceBuffer& l_rsvd)
TS_FAIL("Item [%d] at address (0x%X) precedes the "
"allocated memory location at address "
"(0x%X) by %d byte(s)",
- l_itemCount, l_entryAddr, l_bufferBeginningBoundary,
+ o_itemCount, l_entryAddr, l_bufferBeginningBoundary,
(l_bufferBeginningBoundary - l_entryAddr));
l_everythingChecksOut = false;
}
@@ -1548,7 +1726,7 @@ bool runSelfDiagnostics(TRACE::RsvdTraceBuffer& l_rsvd)
TS_FAIL("Item [%d] at address (0x%X) is beyond the "
"ending allocated memory location at address "
"(0x%X) by %d byte(s)",
- l_itemCount, l_entryAddr, l_bufferEndingBoundary,
+ o_itemCount, l_entryAddr, l_bufferEndingBoundary,
(l_entryAddr - l_bufferEndingBoundary));
l_everythingChecksOut = false;
}
@@ -1557,7 +1735,7 @@ bool runSelfDiagnostics(TRACE::RsvdTraceBuffer& l_rsvd)
TS_FAIL("Item [%d] at address (0x%X) overruns the "
"ending allocated memory location at address "
"(0x%X) by %d byte(s)",
- l_itemCount, l_entryAddr, l_bufferEndingBoundary,
+ o_itemCount, l_entryAddr, l_bufferEndingBoundary,
(l_entryAddrEnd - l_bufferEndingBoundary));
l_everythingChecksOut = false;
}
@@ -1570,7 +1748,7 @@ bool runSelfDiagnostics(TRACE::RsvdTraceBuffer& l_rsvd)
{
TS_FAIL("Item [%d] at address (0x%X) overruns the "
"next item at address (0x%X) by %d byte(s)",
- l_itemCount, l_entryAddr, l_entryNextAddr,
+ o_itemCount, l_entryAddr, l_entryNextAddr,
(l_entryAddrEnd - l_entryNextAddr + 1));
l_everythingChecksOut = false;
}
diff --git a/src/usr/trace/service.C b/src/usr/trace/service.C
index ad8a0250c..21b2269b5 100644
--- a/src/usr/trace/service.C
+++ b/src/usr/trace/service.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -37,7 +37,6 @@
#include <util/singleton.H>
#include <assert.h>
#include <time.h>
-#include <config.h>
#include <console/consoleif.H>
#include <stdio.h>
#include <ctype.h>
diff --git a/src/usr/util/runtime/rt_cmds.C b/src/usr/util/runtime/rt_cmds.C
index c015215b5..aa23ae7c0 100644
--- a/src/usr/util/runtime/rt_cmds.C
+++ b/src/usr/util/runtime/rt_cmds.C
@@ -48,6 +48,7 @@
// switchToFspScomAccess
#ifdef CONFIG_NVDIMM
#include <isteps/nvdimm/nvdimm.H> // notify NVDIMM protection change
+#include <util/runtime/rt_fwnotify.H>
#endif
extern char hbi_ImageId;
@@ -1162,42 +1163,101 @@ void cmd_nvdimm_protection_msg( char* &o_output, uint32_t i_huid,
{
errlHndl_t l_err = nullptr;
o_output = new char[500];
- uint8_t l_notifyType = NVDIMM::NOT_PROTECTED;
TARGETING::Target* l_targ{};
l_targ = getTargetFromHUID(i_huid);
- if (l_targ != NULL)
- {
- if (protection == 1)
- {
- l_notifyType = NVDIMM::PROTECTED;
- l_err = notifyNvdimmProtectionChange(l_targ, NVDIMM::PROTECTED);
- }
- else if (protection == 2)
- {
- l_notifyType = NVDIMM::UNPROTECTED_BECAUSE_ERROR;
- l_err = notifyNvdimmProtectionChange(l_targ, NVDIMM::UNPROTECTED_BECAUSE_ERROR);
- }
- else
- {
- l_err = notifyNvdimmProtectionChange(l_targ, NVDIMM::NOT_PROTECTED);
- }
- if (l_err)
- {
- sprintf( o_output, "Error on call to notifyNvdimmProtectionChange"
- "(0x%.8X, %d), rc=0x%.8X, plid=0x%.8X",
- i_huid, l_notifyType, ERRL_GETRC_SAFE(l_err), l_err->plid() );
- errlCommit(l_err, UTIL_COMP_ID);
- return;
- }
+
+ // protection should match enum from nvdimm_protection_t
+ // No match will just return, no error generated
+ l_err = notifyNvdimmProtectionChange( l_targ,
+ (NVDIMM::nvdimm_protection_t)protection);
+ if (l_err)
+ {
+ sprintf( o_output, "Error on call to notifyNvdimmProtectionChange"
+ "(0x%.8X, %d), rc=0x%.8X, plid=0x%.8X",
+ i_huid, protection, ERRL_GETRC_SAFE(l_err), l_err->plid() );
+ errlCommit(l_err, UTIL_COMP_ID);
+ }
+}
+
+/**
+ * @brief Check the ES (energy source) health status of all NVDIMMs in the
+ * system. If check fails, see HBRT traces for further details.
+ * @param[out] o_output Output display buffer, memory allocated here.
+ * Will inform caller if ES health check passes or fails.
+ */
+void cmd_nvDimmEsCheckHealthStatus( char* &o_output)
+{
+ o_output = new char[500];
+ if (NVDIMM::nvDimmEsCheckHealthStatusOnSystem())
+ {
+ sprintf( o_output, "cmd_nvDimmEsCheckHealthStatus: "
+ "ES (energy source) health status check passed.");
+
}
else
{
- sprintf( o_output, "cmd_nvdimm_protection_msg: HUID 0x%.8X not found",
- i_huid );
- return;
+ sprintf( o_output, "cmd_nvDimmEsCheckHealthStatus: "
+ "ES (energy source) health status check failed. "
+ "Inspect HBRT traces for further details.");
+
+ }
+
+ return;
+} // end cmd_nvDimmEsCheckHealthStatus
+
+/**
+ * @brief Check the NVM (non-volatile memory) health status of all NVDIMMs in
+ * the system. If check fails, see HBRT traces for further details.
+ * @param[out] o_output Output display buffer, memory allocated here.
+ * Will inform caller if NVM health check passes or fails.
+ */
+
+void cmd_nvdDmmNvmCheckHealthStatus( char* &o_output)
+{
+ o_output = new char[500];
+ if (NVDIMM::nvDimmNvmCheckHealthStatusOnSystem())
+ {
+ sprintf( o_output, "cmd_nvdDmmNvmCheckHealthStatus: "
+ "NVM (non-volatile memory) health status check passed.");
+
+ }
+ else
+ {
+ sprintf( o_output, "cmd_nvdDmmNvmCheckHealthStatus: "
+ "NVM (non-volatile memory) health status check failed. "
+ "Inspect HBRT traces for further details.");
+
+ }
+
+ return;
+} // end cmd_nvdDmmNvmCheckHealthStatus
+
+
+/**
+ * @brief Execute nvdimm operation, see interface.h for operation format
+ * @param[out] o_output Output display buffer, memory allocated here.
+ * Will inform caller if nvdimm op passes or fails.
+ * @param[in] i_op nvdimm operation to perform, see interface.h
+ */
+void cmd_nvdimm_op( char* &o_output, uint16_t i_op )
+{
+ o_output = new char[500];
+
+ hostInterfaces::nvdimm_operation_t l_operation;
+ l_operation.procId = HBRT_NVDIMM_OPERATION_APPLY_TO_ALL_NVDIMMS;
+ l_operation.rsvd1 = 0x0;
+ l_operation.rsvd2 = 0x0;
+ l_operation.opType = (hostInterfaces::NVDIMM_Op_t)i_op;
+
+ int rc = doNvDimmOperation(l_operation);
+ if (rc == -1)
+ {
+ sprintf( o_output, "Error on call doNvDimmOperation() op 0x%X",i_op);
}
}
+
+
#endif
/**
@@ -1534,6 +1594,44 @@ int hbrtCommand( int argc,
sprintf(*l_output, "ERROR: nvdimm_protection <huid> <0 or 1>");
}
}
+ else if( !strcmp( argv[0], "nvdimm_es_check_status" ) )
+ {
+ if (argc == 1)
+ {
+ cmd_nvDimmEsCheckHealthStatus( *l_output );
+ }
+ else
+ {
+ *l_output = new char[100];
+ sprintf(*l_output, "Usage: nvdimm_es_check_status");
+ }
+ }
+ else if( !strcmp( argv[0], "nvdimm_nvm_check_status" ) )
+ {
+ if (argc == 1)
+ {
+ cmd_nvdDmmNvmCheckHealthStatus( *l_output );
+ }
+ else
+ {
+ *l_output = new char[100];
+ sprintf(*l_output, "Usage: nvdimm_nvm_check_status");
+ }
+ }
+ else if( !strcmp( argv[0], "nvdimm_op" ) )
+ {
+ if (argc == 2)
+ {
+ uint16_t op = strtou64(argv[1], NULL, 16);
+ cmd_nvdimm_op( *l_output, op );
+ }
+ else
+ {
+ *l_output = new char[100];
+ sprintf(*l_output, "ERROR: nvdimm_op <op>");
+ }
+ }
+
#endif
else
{
@@ -1574,6 +1672,16 @@ int hbrtCommand( int argc,
#ifdef CONFIG_NVDIMM
sprintf( l_tmpstr, "nvdimm_protection <huid> <0 or 1>\n");
strcat( *l_output, l_tmpstr );
+ sprintf( l_tmpstr, "nvdimm_es_check_status\n");
+ strcat( *l_output, l_tmpstr );
+ sprintf( l_tmpstr, "nvdimm_nvm_check_status\n");
+ strcat( *l_output, l_tmpstr );
+ sprintf( l_tmpstr, "nvdimm_op <op>\n"
+ " 0x1=disarm 0x2=disable_encryption 0x4=remove_keys\n"
+ " 0x8=enable_encryption 0x10=arm 0x20=es_healthcheck\n"
+ " 0x40=nvm_healthcheck\n");
+ strcat( *l_output, l_tmpstr );
+
#endif
}
diff --git a/src/usr/util/runtime/rt_fwnotify.C b/src/usr/util/runtime/rt_fwnotify.C
index dae81e7d6..556a1c31f 100644
--- a/src/usr/util/runtime/rt_fwnotify.C
+++ b/src/usr/util/runtime/rt_fwnotify.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2019 */
+/* Contributors Listed Below - COPYRIGHT 2017,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -31,10 +31,14 @@
#include <errl/errlmanager.H> // errlCommit
#include <errl/hberrltypes.H> // TWO_UINT32_TO_UINT64
#include <targeting/common/target.H> // TargetHandle_t, getTargetFromHuid
+#include <targeting/runtime/rt_targeting.H> // RT_TARG::getHbTarget
#include <attributeenums.H> // ATTRIBUTE_ID
#ifdef CONFIG_NVDIMM
-#include <isteps/nvdimm/nvdimm.H> // notify NVDIMM protection change
+#include <isteps/nvdimm/nvdimm.H> // NVDIMM related activities
+#include <targeting/common/targetUtil.H> // makeAttribute
+#include <runtime/hbrt_utilities.H>
+using namespace NVDIMM;
#endif
using namespace TARGETING;
@@ -43,6 +47,7 @@ using namespace ERRORLOG;
using namespace MBOX;
using namespace SBEIO;
+
// Trace definition
extern trace_desc_t* g_trac_runtime;
extern trace_desc_t* g_trac_hbrt;
@@ -51,7 +56,7 @@ extern trace_desc_t* g_trac_hbrt;
* @brief The lower and upper bounds for the sequence ID.
**/
const uint16_t SEQ_ID_MIN = 0x0000;
-const uint16_t SEQ_ID_MAX = 0x7FFF;
+const uint16_t SEQ_ID_MAX = 0x7FFF;
/**
* @brief Set the sequence ID to the minimum value
@@ -85,7 +90,7 @@ uint16_t SeqId_t::getNextSeqId()
**/
uint16_t SeqId_t::getCurrentSeqId()
{
- return SeqId_t::SEQ_ID;
+ return SeqId_t::SEQ_ID;
}
/**
@@ -96,12 +101,12 @@ uint16_t SeqId_t::getCurrentSeqId()
**/
void sbeAttemptRecovery(uint64_t i_data)
{
- // Create a useful struct to get to the data
- // The data is expected to be a HUID (in the first 4 bytes)
- // followed by a PLID (in the last 4 bytes).
- SbeRetryReqData_t *l_sbeRetryData = reinterpret_cast<SbeRetryReqData_t*>(&i_data);
+ // Create a useful struct to get to the data
+ // The data is expected to be a HUID (in the first 4 bytes)
+ // followed by a PLID (in the last 4 bytes).
+ SbeRetryReqData_t *l_sbeRetryData = reinterpret_cast<SbeRetryReqData_t*>(&i_data);
- TRACFCOMP(g_trac_runtime, ENTER_MRK"sbeAttemptRecovery: plid:0x%X, "
+ TRACFCOMP(g_trac_runtime, ENTER_MRK"sbeAttemptRecovery: plid:0x%X, "
"HUID:0x%X", l_sbeRetryData->plid, l_sbeRetryData->huid);
errlHndl_t l_err = nullptr;
@@ -115,7 +120,7 @@ void sbeAttemptRecovery(uint64_t i_data)
// If HUID invalid, log error and quit
if (nullptr == l_target)
{
- TRACFCOMP(g_trac_runtime, ERR_MRK"sbeAttemptRecovery: "
+ TRACFCOMP(g_trac_runtime, ERR_MRK"sbeAttemptRecovery: "
"No target associated with HUID:0x%.8X",
l_sbeRetryData->huid);
@@ -149,7 +154,7 @@ void sbeAttemptRecovery(uint64_t i_data)
if (nullptr == g_hostInterfaces ||
nullptr == g_hostInterfaces->firmware_request)
{
- TRACFCOMP(g_trac_runtime, ERR_MRK"sbeAttemptRecovery: "
+ TRACFCOMP(g_trac_runtime, ERR_MRK"sbeAttemptRecovery: "
"Hypervisor firmware_request interface not linked");
/*@
@@ -260,12 +265,12 @@ void occActiveNotification( void * i_data )
if (*l_active)
{
l_err = NVDIMM::notifyNvdimmProtectionChange(l_proc,
- NVDIMM::PROTECTED);
+ NVDIMM::OCC_ACTIVE);
}
else
{
l_err = NVDIMM::notifyNvdimmProtectionChange(l_proc,
- NVDIMM::NOT_PROTECTED);
+ NVDIMM::OCC_INACTIVE);
}
// commit error if it exists
@@ -294,12 +299,12 @@ void attrSyncRequest( void * i_data)
HbrtAttrSyncData_t * l_hbrtAttrData =
reinterpret_cast<HbrtAttrSyncData_t*>(i_data);
TRACFCOMP(g_trac_runtime, ENTER_MRK"attrSyncRequest: Target HUID 0x%0X "
- "for AttrID: 0x%0X with AttrSize: %lld", l_hbrtAttrData->huid,
- l_hbrtAttrData->attrID, l_hbrtAttrData->sizeOfAttrData);
+ "for AttrID: 0x%0X with AttrSize: %lld", l_hbrtAttrData->huid,
+ l_hbrtAttrData->attrID, l_hbrtAttrData->sizeOfAttrData);
TRACFBIN(g_trac_runtime, "Attribute data: ",
- &(l_hbrtAttrData->attrDataStart),
- l_hbrtAttrData->sizeOfAttrData);
+ &(l_hbrtAttrData->attrDataStart),
+ l_hbrtAttrData->sizeOfAttrData);
// extract the target from the given HUID
TargetHandle_t l_target = Target::getTargetFromHuid(l_hbrtAttrData->huid);
@@ -325,36 +330,496 @@ void attrSyncRequest( void * i_data)
memcpy(&l_attrData, &(l_hbrtAttrData->attrDataStart), l_attrSize);
/*@
- * @errortype
- * @severity ERRL_SEV_PREDICTIVE
- * @moduleid MOD_RT_ATTR_SYNC_REQUEST
- * @reasoncode RC_ATTR_UPDATE_FAILED
- * @userdata1[0:31] Target HUID
- * @userdata1[32:63] Attribute ID
- * @userdata2[0:31] Data Size
- * @userdata2[32:63] Up to 4 bytes of attribute data
- * @devdesc Attribute failed to update on HBRT side
- */
- errlHndl_t l_err = new ErrlEntry(ERRL_SEV_PREDICTIVE,
- MOD_RT_ATTR_SYNC_REQUEST,
- RC_ATTR_UPDATE_FAILED,
- TWO_UINT32_TO_UINT64(
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_RT_ATTR_SYNC_REQUEST
+ * @reasoncode RC_ATTR_UPDATE_FAILED
+ * @userdata1[0:31] Target HUID
+ * @userdata1[32:63] Attribute ID
+ * @userdata2[0:31] Data Size
+ * @userdata2[32:63] Up to 4 bytes of attribute data
+ * @devdesc Attribute failed to update on HBRT side
+ */
+ errlHndl_t l_err = new ErrlEntry(ERRL_SEV_PREDICTIVE,
+ MOD_RT_ATTR_SYNC_REQUEST,
+ RC_ATTR_UPDATE_FAILED,
+ TWO_UINT32_TO_UINT64(
l_hbrtAttrData->huid,
l_hbrtAttrData->attrID),
- TWO_UINT32_TO_UINT64(
+ TWO_UINT32_TO_UINT64(
l_hbrtAttrData->sizeOfAttrData,
l_attrData),
- true);
+ true);
- l_err->collectTrace(RUNTIME_COMP_NAME, 256);
+ l_err->collectTrace(RUNTIME_COMP_NAME, 256);
- //Commit the error
- errlCommit(l_err, RUNTIME_COMP_ID);
+ //Commit the error
+ errlCommit(l_err, RUNTIME_COMP_ID);
}
TRACFCOMP(g_trac_runtime, EXIT_MRK"attrSyncRequest");
}
+#ifdef CONFIG_NVDIMM
+/**
+ * @brief Utility function to set ATTR_NVDIMM_ENCRYPTION_ENABLE
+ * and send the value to the FSP
+ */
+void set_ATTR_NVDIMM_ENCRYPTION_ENABLE(
+ ATTR_NVDIMM_ENCRYPTION_ENABLE_type i_val )
+{
+ errlHndl_t l_err = nullptr;
+
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "set_ATTR_NVDIMM_ENCRYPTION_ENABLE: no TopLevelTarget");
+ l_sys->setAttr<ATTR_NVDIMM_ENCRYPTION_ENABLE>(i_val);
+
+ // Send it down to the FSP
+ AttributeTank::Attribute l_attr = {};
+ if( !makeAttribute<ATTR_NVDIMM_ENCRYPTION_ENABLE>
+ (l_sys, l_attr) )
+ {
+ TRACFCOMP(g_trac_runtime, ERR_MRK"set_ATTR_NVDIMM_ENCRYPTION_ENABLE() Could not create Attribute");
+ /*@
+ *@errortype
+ *@reasoncode RC_CANNOT_MAKE_ATTRIBUTE
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid SET_ATTR_NVDIMM_ENCRYPTION_ENABLE
+ *@devdesc Couldn't create an Attribute to send the data
+ * to the FSP
+ *@custdesc NVDIMM encryption error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ SET_ATTR_NVDIMM_ENCRYPTION_ENABLE,
+ RC_CANNOT_MAKE_ATTRIBUTE,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ else
+ {
+ std::vector<TARGETING::AttributeTank::Attribute> l_attrList;
+ l_attrList.push_back(l_attr);
+ l_err = sendAttributes( l_attrList );
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_runtime, ERR_MRK"set_ATTR_NVDIMM_ENCRYPTION_ENABLE() Error sending ATTR_NVDIMM_ENCRYPTION_ENABLE down to FSP");
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ }
+}
+#endif //CONFIG_NVDIMM
+
+/**
+ * @brief Perform an NVDIMM operation
+ * @param[in] i_nvDimmOp - A struct that contains the operation(s) to perform
+ * and a flag indicating whether to perform operation
+ * on all processors or a given single processor.
+ *
+ * @Note The arming/disarming operations below are in the order of which they
+ * should be performed. If a new sequence is added to the
+ * arming/disarming sequence, make sure it is inserted in the
+ * correct order.
+ * The current order is: disarm -> disable encryption -> remove keys ->
+ * enable encryption -> arm
+ **/
+int doNvDimmOperation(const hostInterfaces::nvdimm_operation_t& i_nvDimmOp)
+{
+ int rc = 0;
+#ifndef CONFIG_NVDIMM
+ TRACFCOMP(g_trac_runtime, ENTER_MRK"doNvDimmOperation: not an "
+ "NVDIMM configuration, this call becomes a noop.");
+
+#else
+ TRACFCOMP(g_trac_runtime, ENTER_MRK"doNvDimmOperation: Operation(s) "
+ "0x%0X, processor ID 0x%0X",
+ i_nvDimmOp.opType,
+ i_nvDimmOp.procId);
+
+ // Error log handle for capturing any errors
+ errlHndl_t l_err{nullptr};
+ // List of NVDIMM Targets to execute NVDIMM operation on
+ TargetHandleList l_nvDimmTargetList;
+
+ // Perform the operations requested
+ do
+ {
+ /// Populate the NVDIMM target list
+ // If requesting to perform operation on all NVDIMMs, then
+ // retrieve all NVDIMMs from system
+ if (HBRT_NVDIMM_OPERATION_APPLY_TO_ALL_NVDIMMS == i_nvDimmOp.procId)
+ {
+ nvdimm_getNvdimmList(l_nvDimmTargetList);
+ }
+ // Else retrieve only the NVDIMMs from given processor ID
+ else
+ {
+ /// Get the NVDIMMs associated with procId
+ // Convert the procId to a real boy, uh, I mean target
+ TARGETING::TargetHandle_t l_procTarget;
+ l_err = RT_TARG::getHbTarget(i_nvDimmOp.procId, l_procTarget);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: Error getting "
+ "HB Target from processor ID 0x%0X, "
+ "exiting ...",
+ i_nvDimmOp.procId);
+ rc = -1;
+ break;
+ }
+
+ // Get the list of NVDIMMs associated with processor target
+ l_nvDimmTargetList = TARGETING::getProcNVDIMMs(l_procTarget);
+ }
+
+ // No point in continuing if the list of NVDIMM Targets is empty
+ if (!l_nvDimmTargetList.size())
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: No NVDIMMs found, "
+ "exiting ...");
+ rc = -1;
+ break;
+ }
+
+ // Perform the arming/disarming operations. If anyone fails in the
+ // sequence, no point in calling the next, if there is a next operation.
+ do
+ {
+ // Disarm the NV logic
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_DISARM)
+ {
+ // Make call to disarm
+ if (!nvdimmDisarm(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to disarm failed. Will not perform any "
+ "more arming/disarming calls, if they exist");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to disarm succeeded");
+ }
+ }
+
+ // Disable encryption on the NVDIMM and clear saved values from FW
+ if (i_nvDimmOp.opType &
+ hostInterfaces::HBRT_FW_NVDIMM_DISABLE_ENCRYPTION)
+ {
+ // Make call to disable encryption
+ if (!nvdimm_crypto_erase(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to disable encryption failed. Will not "
+ "perform any more arming/disarming calls, if "
+ "they exist");
+
+ // Clear the encryption enable attribute
+ set_ATTR_NVDIMM_ENCRYPTION_ENABLE(0);
+
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to disable encryption succeeded.");
+ }
+
+ // Clear the encryption enable attribute
+ set_ATTR_NVDIMM_ENCRYPTION_ENABLE(0);
+ }
+
+ // Remove keys
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_REMOVE_KEYS)
+ {
+ // Make call to remove keys
+ if (!nvdimm_remove_keys())
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to remove keys failed. Will not perform "
+ "any more arming/disarming calls, if they exist");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to remove keys succeeded.");
+ }
+ }
+
+ // Enable encryption on the NVDIMM
+ if (i_nvDimmOp.opType &
+ hostInterfaces::HBRT_FW_NVDIMM_ENABLE_ENCRYPTION)
+ {
+ // Set the encryption enable attribute
+ set_ATTR_NVDIMM_ENCRYPTION_ENABLE(1);
+
+ // Make call to generate keys before enabling encryption
+ if(!nvdimm_gen_keys())
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to generate keys failed, unable to enable "
+ "encryption. Will not perform any more "
+ "arming/disarming calls, if they exist");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ // Make call to enable encryption
+ if (!nvdimm_encrypt_enable(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to enable encryption failed. "
+ "Will not perform any more arming/disarming "
+ "calls, if they exist");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to enable encryption succeeded.");
+ }
+ } // end if(!nvdimm_gen_keys()) ... else ...
+ }
+
+ // Arm the NV logic
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_ARM)
+ {
+ // Make call to arm
+ if (!nvdimmArm(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to arm failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to arm succeeded.");
+ }
+ } // end if (nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_ARM)
+ } while (0); // end Perform the arming/disarming operations.
+
+ // Perform the ES (energy source) health check operation
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_MNFG_ES_HEALTH_CHECK)
+ {
+ if (!nvDimmEsCheckHealthStatus(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do an ES (energy source) health check failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do an ES (energy source) health check succeeded.");
+ }
+ }
+
+ // Perform the NVM (non-volatile memory) health check operation
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_MNFG_NVM_HEALTH_CHECK)
+ {
+ if (!nvDimmNvmCheckHealthStatus(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do a NVM (non-volatile memory) health check failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do a NVM (non-volatile memory) health check succeeded.");
+ }
+ }
+
+ // Perform the factory default operation
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_FACTORY_DEFAULT)
+ {
+ if (!nvdimmFactoryDefault(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Factory Default operation failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Factory Default operation succeeded.");
+ }
+ }
+
+ // Perform the secure erase verify start operation
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_SECURE_EV_START)
+ {
+ if (!nvdimmSecureEraseVerifyStart(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Secure Erase Verify Start failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Secure Erase Verify Start succeeded.");
+ }
+ }
+
+ // Perform the secure erase verify status operation
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_SECURE_EV_STATUS)
+ {
+ if (!nvdimmSecureEraseVerifyStatus(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Secure Erase Verify Status failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Secure Erase Verify Status succeeded.");
+ }
+ }
+
+ } while(0); // end Perform the operations requested
+
+ if (l_err)
+ {
+ //Commit the error if it exists
+ errlCommit(l_err, RUNTIME_COMP_ID);
+ }
+
+#endif
+
+ TRACFCOMP(g_trac_runtime, EXIT_MRK"doNvDimmOperation")
+ return rc;
+}
+
+/**
+ * @brief Log the gard event from PHYP/OPAL
+ *
+ * @param[in] i_gardEvent - The details of the gard event
+ * @see hostInterfaces::gard_event_t for more info
+ *
+ **/
+void logGardEvent(const hostInterfaces::gard_event_t& i_gardEvent)
+{
+ // Trace input components
+ TRACFCOMP(g_trac_runtime,
+ ENTER_MRK"logGardEvent: Gard Event Data: "
+ "error type(0x%.8X), processor ID(0x%.8X), "
+ "PLID(0x%.8X), sub unit mask(0x.%4X), "
+ "recovery level(0x.%4X)",
+ i_gardEvent.i_error_type,
+ i_gardEvent.i_procId,
+ i_gardEvent.i_plid,
+ i_gardEvent.i_sub_unit_mask,
+ i_gardEvent.i_recovery_level);
+
+ errlHndl_t l_err{nullptr};
+
+ do
+ {
+ // Make sure the error type is valid, if not, log it
+ if ((i_gardEvent.i_error_type == hostInterfaces::HBRT_GARD_ERROR_UNKNOWN ) ||
+ (i_gardEvent.i_error_type >= hostInterfaces::HBRT_GARD_ERROR_LAST) )
+ {
+ TRACFCOMP(g_trac_runtime, "logGardEvent: ERROR: unknown/invalid "
+ "error type 0x%.8X",
+ i_gardEvent.i_error_type);
+
+ /* @
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_RT_FIRMWARE_NOTIFY
+ * @reasoncode RC_LOG_GARD_EVENT_UNKNOWN_ERROR_TYPE
+ * @userdata1[0:31] GARD error type
+ * @userdata1[32:63] Processor ID
+ * @userdata2[0:31] Sub unit mask
+ * @userdata2[32:63] Recovery level
+ * @devdesc Unknown/invalid error type
+ * @custdesc Internal firmware error
+ */
+ l_err = new ErrlEntry( ERRL_SEV_PREDICTIVE,
+ MOD_RT_FIRMWARE_NOTIFY,
+ RC_LOG_GARD_EVENT_UNKNOWN_ERROR_TYPE,
+ TWO_UINT32_TO_UINT64(
+ i_gardEvent.i_error_type,
+ i_gardEvent.i_procId),
+ TWO_UINT32_TO_UINT64(
+ i_gardEvent.i_sub_unit_mask,
+ i_gardEvent.i_recovery_level),
+ ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+
+ // Get the Target associated with processor ID
+ TARGETING::TargetHandle_t l_procTarget{nullptr};
+ l_err = RT_TARG::getHbTarget(i_gardEvent.i_procId, l_procTarget);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_runtime, "logGardEvent: Error getting "
+ "HB Target from processor ID 0x%0X, "
+ "exiting ...",
+ i_gardEvent.i_procId);
+ break;
+ }
+
+ // Log the GARD event
+ /* @
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_RT_FIRMWARE_NOTIFY
+ * @reasoncode RC_LOG_GARD_EVENT
+ * @userdata1[0:31] GARD error type
+ * @userdata1[32:63] Processor ID
+ * @userdata2[0:31] Sub unit mask
+ * @userdata2[32:63] Recovery level
+ * @devdesc Gard event from Opal/Phyp
+ * @custdesc Hardware error detected at runtime
+ */
+ l_err = new ErrlEntry( ERRL_SEV_PREDICTIVE,
+ MOD_RT_FIRMWARE_NOTIFY,
+ RC_LOG_GARD_EVENT,
+ TWO_UINT32_TO_UINT64(
+ i_gardEvent.i_error_type,
+ i_gardEvent.i_procId),
+ TWO_UINT32_TO_UINT64(
+ i_gardEvent.i_sub_unit_mask,
+ i_gardEvent.i_recovery_level));
+
+ // Set the PLID to the given gard event PLID if it exist
+ if (i_gardEvent.i_plid)
+ {
+ l_err->plid(i_gardEvent.i_plid);
+ }
+
+ // Do the actual gard
+ l_err->addHwCallout( l_procTarget, HWAS::SRCI_PRIORITY_MED,
+ HWAS::NO_DECONFIG, HWAS::GARD_PHYP);
+ } while(0);
+
+ // Commit any error log that occurred.
+ errlCommit(l_err, RUNTIME_COMP_ID);
+
+ TRACFCOMP(g_trac_runtime, EXIT_MRK"logGardEvent")
+}
/**
* @see src/include/runtime/interface.h for definition of call
@@ -362,12 +827,12 @@ void attrSyncRequest( void * i_data)
*/
void firmware_notify( uint64_t i_len, void *i_data )
{
- TRACFCOMP(g_trac_hbrt, ENTER_MRK"firmware_notify: "
+ TRACFCOMP(g_trac_hbrt, ENTER_MRK"firmware_notify: "
"i_len:%d", i_len );
- TRACFBIN(g_trac_runtime, "firmware_notify: i_data", i_data, i_len);
+ TRACFBIN(g_trac_runtime, "firmware_notify: i_data", i_data, i_len);
- errlHndl_t l_err = nullptr;
+ errlHndl_t l_err = nullptr;
// Flag to detect an invalid/unknown/not used message
bool l_badMessage = false;
@@ -381,12 +846,12 @@ void firmware_notify( uint64_t i_len, void *i_data )
// data necessary to determine type of message
if (i_len < hostInterfaces::HBRT_FW_MSG_BASE_SIZE)
{
- l_badMessage = true;
+ l_badMessage = true;
- TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
- "Received a non hostInterfaces::hbrt_fw_msg data stream" );
+ TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: Received "
+ "a non hostInterfaces::hbrt_fw_msg data stream" );
- break;
+ break;
}
// Cast the data to an hbrt_fw_msg to extract the input type
@@ -394,68 +859,116 @@ void firmware_notify( uint64_t i_len, void *i_data )
static_cast<hostInterfaces::hbrt_fw_msg*>(i_data);
switch (l_hbrt_fw_msg->io_type)
{
- case hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ:
- {
- // Distinguish based on msgType and msgq
- if ( (l_hbrt_fw_msg->generic_msg.msgType ==
+ case hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ:
+ {
+ // Distinguish based on msgType and msgq
+ if ( (l_hbrt_fw_msg->generic_msg.msgType ==
GenericFspMboxMessage_t::MSG_ATTR_SYNC_REQUEST) &&
(l_hbrt_fw_msg->generic_msg.msgq ==
MBOX::HB_ATTR_SYNC_MSGQ) )
- {
- attrSyncRequest((void*)&(l_hbrt_fw_msg->generic_msg.data));
- }
- else if ((l_hbrt_fw_msg->generic_msg.msgType ==
- GenericFspMboxMessage_t::MSG_OCC_ACTIVE) &&
- (l_hbrt_fw_msg->generic_msg.msgq ==
- MBOX::FSP_OCC_MSGQ_ID) )
- {
- occActiveNotification((void*)&(l_hbrt_fw_msg->generic_msg.data));
- }
- // Placing this at end as it does not have a msgq specified
- // Want to match msgType & msgq combos first
- else if (l_hbrt_fw_msg->generic_msg.msgType ==
- GenericFspMboxMessage_t::MSG_SBE_ERROR)
- {
- sbeAttemptRecovery(l_hbrt_fw_msg->generic_msg.data);
- }
- else
- {
- l_badMessage = true;
-
- TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
- "Unknown FSP message type:0x%.8X, "
- "message queue id:0x%.8X, seqNum:%d ",
- l_hbrt_fw_msg->generic_msg.msgType,
- l_hbrt_fw_msg->generic_msg.msgq,
- l_hbrt_fw_msg->generic_msg.seqnum);
-
- // Pack user data 1 with message input type and
- // firmware request message sequence number
- l_userData1 = TWO_UINT32_TO_UINT64(
- l_hbrt_fw_msg->io_type,
- l_hbrt_fw_msg->generic_msg.seqnum);
-
- // Pack user data 2 with message queue and message type
- l_userData2 = TWO_UINT32_TO_UINT64(
- l_hbrt_fw_msg->generic_msg.msgq,
- l_hbrt_fw_msg->generic_msg.msgType);
- }
- } // END case HBRT_FW_MSG_HBRT_FSP_REQ:
+ {
+ attrSyncRequest((void*)&(l_hbrt_fw_msg->generic_msg.data));
+ }
+ else if ((l_hbrt_fw_msg->generic_msg.msgType ==
+ GenericFspMboxMessage_t::MSG_OCC_ACTIVE) &&
+ (l_hbrt_fw_msg->generic_msg.msgq ==
+ MBOX::FSP_OCC_MSGQ_ID) )
+ {
+ occActiveNotification((void*)&(l_hbrt_fw_msg->generic_msg.data));
+ }
+ // Placing this at end as it does not have a msgq specified
+ // Want to match msgType & msgq combos first
+ else if (l_hbrt_fw_msg->generic_msg.msgType ==
+ GenericFspMboxMessage_t::MSG_SBE_ERROR)
+ {
+ sbeAttemptRecovery(l_hbrt_fw_msg->generic_msg.data);
+ }
+ else
+ {
+ l_badMessage = true;
+
+ TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
+ "Unknown FSP message type:0x%.8X, "
+ "message queue id:0x%.8X, seqNum:%d ",
+ l_hbrt_fw_msg->generic_msg.msgType,
+ l_hbrt_fw_msg->generic_msg.msgq,
+ l_hbrt_fw_msg->generic_msg.seqnum);
+
+ // Pack user data 1 with message input type and
+ // firmware request message sequence number
+ l_userData1 = TWO_UINT32_TO_UINT64(
+ l_hbrt_fw_msg->io_type,
+ l_hbrt_fw_msg->generic_msg.seqnum);
+
+ // Pack user data 2 with message queue and message type
+ l_userData2 = TWO_UINT32_TO_UINT64(
+ l_hbrt_fw_msg->generic_msg.msgq,
+ l_hbrt_fw_msg->generic_msg.msgType);
+ } // END if ( (l_hbrt_fw_msg->generic_msg.msgType ... else ...
+ } // END case hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ:
+ break;
- break;
+ case hostInterfaces::HBRT_FW_MSG_TYPE_NVDIMM_OPERATION:
+ {
+ uint64_t l_minMsgSize = hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(hostInterfaces::hbrt_fw_msg::nvdimm_operation);
+ if (i_len < l_minMsgSize)
+ {
+ l_badMessage = true;
+
+ TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
+ "Received message HBRT_FW_MSG_TYPE_NVDIMM_OPERATION, "
+ "but size of message data(%d) is not adequate for a "
+ "complete message of this type, with size requirement of "
+ "%d", i_len, l_minMsgSize );
+
+ // Pack user data 1 with the message input type, the only
+ // data that can be safely retrieved
+ l_userData1 = l_hbrt_fw_msg->io_type;
+
+ break;
+ }
+
+ doNvDimmOperation(l_hbrt_fw_msg->nvdimm_operation);
+ } // END case hostInterfaces::HBRT_FW_MSG_TYPE_NVDIMM_OPERATION:
+ break;
- default:
- {
- l_badMessage = true;
+ case hostInterfaces::HBRT_FW_MSG_TYPE_GARD_EVENT:
+ {
+ uint64_t l_minMsgSize = hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(hostInterfaces::hbrt_fw_msg::gard_event);
+ if (i_len < l_minMsgSize)
+ {
+ l_badMessage = true;
+
+ TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
+ "Received message HBRT_FW_MSG_TYPE_GARD_EVENT, "
+ "but size of message data(%d) is not adequate for a "
+ "complete message of this type, with size requirement of "
+ "%d", i_len, l_minMsgSize );
+
+ // Pack user data 1 with the message input type, the only
+ // data that can be safely retrieved
+ l_userData1 = l_hbrt_fw_msg->io_type;
+
+ break;
+ }
+
+ logGardEvent(l_hbrt_fw_msg->gard_event);
+ } // END case hostInterfaces::HBRT_FW_MSG_TYPE_GARD_EVENT:
+ break;
- TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
- "Unknown firmware request input type:0x%.8X ",
- l_hbrt_fw_msg->io_type);
+ default:
+ {
+ l_badMessage = true;
- l_userData1 = l_hbrt_fw_msg->io_type;
- } // END default
+ TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
+ "Unknown firmware request input type:0x%.8X ",
+ l_hbrt_fw_msg->io_type);
- break;
+ l_userData1 = l_hbrt_fw_msg->io_type;
+ } // END default
+ break;
}; // END switch (l_hbrt_fw_msg->io_type)
@@ -463,42 +976,42 @@ void firmware_notify( uint64_t i_len, void *i_data )
if (l_badMessage)
{
- /*@
- * @errortype
- * @severity ERRL_SEV_PREDICTIVE
- * @moduleid MOD_RT_FIRMWARE_NOTIFY
- * @reasoncode RC_FW_NOTIFY_RT_INVALID_MSG
- * @userdata1[0:31] Firmware Request type
- * @userdata1[32:63] Sequence number (FSP msg)
- * @userdata2[0:31] MBOX message type (FSP msg)
- * @userdata2[32:63] Message Type (FSP msg)
- * @devdesc Error with Firmware Notify request
- */
- l_err = new ErrlEntry(ERRL_SEV_PREDICTIVE,
- MOD_RT_FIRMWARE_NOTIFY,
- RC_FW_NOTIFY_RT_INVALID_MSG,
- l_userData1,
- l_userData2,
- true);
-
- if (i_len > 0)
- {
- l_err->addFFDC(RUNTIME_COMP_ID,
- i_data,
- i_len,
- 0, 0, false );
- }
-
- l_err->collectTrace( "FW_REQ", 256);
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_RT_FIRMWARE_NOTIFY
+ * @reasoncode RC_FW_NOTIFY_RT_INVALID_MSG
+ * @userdata1[0:31] Firmware Request type
+ * @userdata1[32:63] Sequence number (FSP msg)
+ * @userdata2[0:31] MBOX message type (FSP msg)
+ * @userdata2[32:63] Message Type (FSP msg)
+ * @devdesc Error with Firmware Notify request
+ */
+ l_err = new ErrlEntry(ERRL_SEV_PREDICTIVE,
+ MOD_RT_FIRMWARE_NOTIFY,
+ RC_FW_NOTIFY_RT_INVALID_MSG,
+ l_userData1,
+ l_userData2,
+ true);
+
+ if (i_len > 0)
+ {
+ l_err->addFFDC(RUNTIME_COMP_ID,
+ i_data,
+ i_len,
+ 0, 0, false );
+ }
+
+ l_err->collectTrace(RUNTIME_COMP_NAME, 256);
}
if (l_err)
{
- //Commit the error if it exists
- errlCommit(l_err, RUNTIME_COMP_ID);
+ //Commit the error if it exists
+ errlCommit(l_err, RUNTIME_COMP_ID);
}
- TRACFCOMP(g_trac_hbrt, EXIT_MRK"firmware_notify");
+ TRACFCOMP(g_trac_hbrt, EXIT_MRK"firmware_notify");
};
struct registerFwNotify
diff --git a/src/usr/util/runtime/rt_fwreq_helper.C b/src/usr/util/runtime/rt_fwreq_helper.C
index f94dab238..ce2a1baf6 100644
--- a/src/usr/util/runtime/rt_fwreq_helper.C
+++ b/src/usr/util/runtime/rt_fwreq_helper.C
@@ -27,6 +27,7 @@
#include <runtime/interface.h> // hostInterfaces
#include <runtime/runtime_reasoncodes.H> // MOD_RT_FIRMWARE_REQUEST, etc
#include <errl/errlmanager.H> // errlCommit
+#include <targeting/common/targetUtil.H> // makeAttribute
using namespace ERRORLOG;
using namespace RUNTIME;
@@ -629,3 +630,285 @@ errlHndl_t firmware_request_helper(uint64_t i_reqLen, void *i_req,
return l_err;
};
+
+/**
+ * @brief A handy utility to create the firmware request and response
+ * messages, for FSP, where the messages must be of equal size.
+ */
+bool createGenericFspMsg(uint32_t i_fspReqPayloadSize,
+ uint32_t &o_fspMsgSize,
+ uint64_t &o_requestMsgSize,
+ hostInterfaces::hbrt_fw_msg* &o_requestMsg,
+ uint64_t &o_responseMsgSize,
+ hostInterfaces::hbrt_fw_msg* &o_responseMsg)
+{
+ // Default the return value to true, assume things will go right
+ bool l_retVal(true);
+
+ // Do some quick initialization of the output data
+ o_fspMsgSize = o_requestMsgSize = o_responseMsgSize = 0;
+ o_requestMsg = o_responseMsg = nullptr;
+
+ // Calculate the total size of the Generic FSP Message.
+ o_fspMsgSize = GENERIC_FSP_MBOX_MESSAGE_BASE_SIZE +
+ i_fspReqPayloadSize;
+
+ // The total Generic FSP Message size must be at a minimum the
+ // size of the FSP generic message (sizeof(GenericFspMboxMessage_t))
+ if (o_fspMsgSize < sizeof(GenericFspMboxMessage_t))
+ {
+ o_fspMsgSize = sizeof(GenericFspMboxMessage_t);
+ }
+
+ // Calculate the total size of the hbrt_fw_msgs which
+ // means only adding hostInterfaces::HBRT_FW_MSG_BASE_SIZE to
+ // the previous calculated Generic FSP Message size.
+ o_requestMsgSize = o_responseMsgSize =
+ hostInterfaces::HBRT_FW_MSG_BASE_SIZE + o_fspMsgSize;
+
+ // Create the hbrt_fw_msgs
+ o_responseMsg = reinterpret_cast<hostInterfaces::hbrt_fw_msg *>
+ (new uint8_t[o_responseMsgSize]);
+ o_requestMsg = reinterpret_cast<hostInterfaces::hbrt_fw_msg *>
+ (new uint8_t[o_requestMsgSize]);
+
+ // If any one of these two message's memory can't be allocated, then
+ // delete both messages (in case one did allocate memory), set both
+ // messages to NULL pointers and set their respective sizes to zero.
+ if (!o_responseMsg || !o_requestMsg)
+ {
+ // OK to delete a NULL pointer if it happens
+ delete []o_responseMsg;
+ delete []o_requestMsg;
+
+ // Return output data zeroed out
+ o_responseMsg = o_requestMsg = nullptr;
+ o_fspMsgSize = o_requestMsgSize = o_responseMsgSize = 0;
+
+ // Return false, indicating that this function had an issue creating
+ // the request and/or response message
+ l_retVal = false;
+ }
+ else
+ {
+ // Initialize/zero out hbrt_fw_msgs
+ o_requestMsg->generic_msg.initialize();
+ memset(o_responseMsg, 0, o_responseMsgSize);
+
+ // We can at least set these parameters based on current usage
+ o_requestMsg->io_type = hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ;
+ o_requestMsg->generic_msg.dataSize = o_fspMsgSize;
+ o_requestMsg->generic_msg.__req = GenericFspMboxMessage_t::REQUEST;
+ }
+
+ return l_retVal;
+} // end createGenericFspMsg
+
+
+/**
+ * @brief Serializes a list of Attributes to be sent to FSP
+ */
+errlHndl_t sendAttributes(const std::vector<TARGETING::AttributeTank::Attribute>&
+ i_attributeList)
+{
+ TRACFCOMP(g_trac_runtime,
+ ENTER_MRK"sendAttributes - number of attributes to send %d",
+ i_attributeList.size());
+
+ // Handle to error log
+ errlHndl_t l_err{nullptr};
+
+ // Handles to the firmware messages
+ hostInterfaces::hbrt_fw_msg *l_fwRequestMsg{nullptr}; // request message
+ hostInterfaces::hbrt_fw_msg *l_fwResponseMsg{nullptr}; // response message
+
+ do
+ {
+ // If caller passes in an empty list, then nothing to do
+ if (!i_attributeList.size())
+ {
+ TRACFCOMP(g_trac_runtime, "sendAttributes: attribute list is "
+ "empty,nothing to do ...");
+ break;
+ }
+
+ // Make sure we have all of our function pointers setup right
+ if ((nullptr == g_hostInterfaces) ||
+ (nullptr == g_hostInterfaces->firmware_request))
+ {
+ TRACFCOMP(g_trac_runtime, ERR_MRK"sendAttributes: "
+ "Hypervisor firmware_request interface not linked");
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_RT_FIRMWARE_REQUEST
+ * @reasoncode RC_FW_REQUEST_RT_NULL_PTR
+ * @userdata1 Number of Attributes to serialize and send
+ * @devdesc Hypervisor firmware request interface not linked
+ * @custdesc Internal firmware error
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_RT_FIRMWARE_REQUEST,
+ RUNTIME::RC_FW_REQUEST_RT_NULL_PTR,
+ i_attributeList.size(),
+ 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ break;
+ }
+
+ /// Calculate the size requirements needed to serialize
+ /// the Attribute info
+ // Aggregate the size of the incoming Attributes
+ uint32_t l_aggregatedAttributeSize(0);
+ for (auto l_attribute: i_attributeList)
+ {
+ l_aggregatedAttributeSize += l_attribute.getSize();
+ }
+
+ // Combine the size of the AttributeSetter_t itself to the size of
+ // incoming Attributes to get the full size requirement needed
+ uint32_t l_dataSize(sizeof(AttributeSetter_t) +
+ l_aggregatedAttributeSize);
+
+ // Create and initialize to zero a few needed variables
+ uint32_t l_fullFspDataSize(0);
+ uint64_t l_fwRequestMsgSize(0), l_fwResponseMsgSize(0);
+
+ // Create the dynamic firmware messages
+ if (!createGenericFspMsg(l_dataSize,
+ l_fullFspDataSize,
+ l_fwRequestMsgSize,
+ l_fwRequestMsg,
+ l_fwResponseMsgSize,
+ l_fwResponseMsg) )
+ {
+ TRACFCOMP(g_trac_runtime, ERR_MRK"sendAttributes: "
+ "Unable to allocate firmware request messages");
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_SEND_ATTRIBUTES_TO_FSP
+ * @reasoncode RC_NULL_FIRMWARE_MSG_PTR
+ * @userdata1 Number of Attributes to serialize and send
+ * @devdesc Unable to allocate firmware request messages
+ * @custdesc Internal firmware error
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_SEND_ATTRIBUTES_TO_FSP,
+ RUNTIME::RC_NULL_FIRMWARE_MSG_PTR,
+ i_attributeList.size(),
+ 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ break;
+ }
+
+ // Populate the 'message queue' and 'message type' for this message
+ l_fwRequestMsg->generic_msg.msgq = MBOX::FSP_NVDIMM_KEYS_MSGQ_ID;
+ l_fwRequestMsg->generic_msg.msgType =
+ GenericFspMboxMessage_t::MSG_ATTR_WRITE_OP;
+
+ // Create a useful struct to populate the generic_msg::data field
+ AttributeSetter_t* l_attributeSetter =
+ reinterpret_cast<AttributeSetter_t*>
+ (&(l_fwRequestMsg->generic_msg.data));
+
+ // Initialize the AttributeSetter to default values
+ l_attributeSetter->initialize();
+
+ // The number of attributes being copied can be obtained from
+ // size of the attrbute input list
+ l_attributeSetter->iv_numAttributes = i_attributeList.size();
+
+ // Retrieve the individual attributes (header and value)
+ // Create a useful struct to poulate attribute data
+ uint8_t* l_attributeData = l_attributeSetter->iv_attrData;
+ uint32_t l_sizeOfDataCopied(0);
+
+ // Iterate thru the attribute list and serialize the attributes
+ for (const auto & l_attribute: i_attributeList)
+ {
+ if (l_aggregatedAttributeSize >= l_attribute.getSize())
+ {
+ l_sizeOfDataCopied = l_attribute.serialize(
+ l_attributeData, l_aggregatedAttributeSize);
+
+ if (!l_sizeOfDataCopied)
+ {
+ TRACFCOMP(g_trac_runtime, ERR_MRK"sendAttributes: "
+ "Serialization of an Attribute failed, "
+ "should never happen")
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_SEND_ATTRIBUTES_TO_FSP
+ * @reasoncode RC_SERIALIZE_ATTRIBUTE_FAILED
+ * @userdata1 Number of Attributes to serialize and send
+ * @devdesc Serialization of an Attribute Failed
+ * @custdesc Internal firmware error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_SEND_ATTRIBUTES_TO_FSP,
+ RUNTIME::RC_SERIALIZE_ATTRIBUTE_FAILED,
+ i_attributeList.size(),
+ 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ break;
+ } // end if (!l_sizeOfDataCopied)
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, ERR_MRK"sendAttributes: "
+ "Miscalculation of aggregated size of attributes, "
+ "should never happen")
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_SEND_ATTRIBUTES_TO_FSP
+ * @reasoncode RC_NO_SPACE_FOR_ATTRIBUTE_SERIALIZATION
+ * @userdata1 Number of Attributes to serialize and send
+ * @devdesc Serialization data of Attribute to large
+ * for given buffer
+ * @custdesc Internal firmware error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_SEND_ATTRIBUTES_TO_FSP,
+ RUNTIME::RC_NO_SPACE_FOR_ATTRIBUTE_SERIALIZATION,
+ i_attributeList.size(),
+ 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ break;
+ }
+
+ // Decrement/increment our counters/pointers
+ l_aggregatedAttributeSize -= l_sizeOfDataCopied;
+ l_attributeData += l_sizeOfDataCopied;
+ } // end for (const auto & l_attribute: i_attributeList)
+
+ // Make the firmware_request call
+ l_err = firmware_request_helper(l_fwRequestMsgSize,
+ l_fwRequestMsg,
+ &l_fwResponseMsgSize,
+ l_fwResponseMsg);
+ } while (0);
+
+ // Release the firmware messages and set to NULL
+ delete []l_fwRequestMsg;
+ delete []l_fwResponseMsg;
+ l_fwRequestMsg = l_fwResponseMsg = nullptr;
+
+ TRACFCOMP(g_trac_runtime, EXIT_MRK"sendAttributes - exit with %s",
+ (nullptr == l_err ? "no error" : "error"));
+
+
+ return l_err;
+}
diff --git a/src/usr/util/runtime/test/testlidmgr_rt.H b/src/usr/util/runtime/test/testlidmgr_rt.H
index 36eb8bc64..a6681b37b 100644
--- a/src/usr/util/runtime/test/testlidmgr_rt.H
+++ b/src/usr/util/runtime/test/testlidmgr_rt.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2016 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -26,7 +26,6 @@
#include <cxxtest/TestSuite.H>
#include <errl/errlmanager.H>
#include <utilbase.H>
-#include <config.h>
class LidMgrRtTest : public CxxTest::TestSuite
{
diff --git a/src/usr/util/runtime/test/testruncommand.H b/src/usr/util/runtime/test/testruncommand.H
index 9dbb6b5c0..f6563819e 100644
--- a/src/usr/util/runtime/test/testruncommand.H
+++ b/src/usr/util/runtime/test/testruncommand.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -24,7 +24,6 @@
/* IBM_PROLOG_END_TAG */
#include <cxxtest/TestSuite.H>
#include <errl/errlmanager.H>
-#include <config.h>
#include <runtime/interface.h>
#include <string.h>
#include <stdio.h>
diff --git a/src/usr/util/runtime/utillidmgr_rt.C b/src/usr/util/runtime/utillidmgr_rt.C
index ad5a7cd48..55bebdeb3 100644
--- a/src/usr/util/runtime/utillidmgr_rt.C
+++ b/src/usr/util/runtime/utillidmgr_rt.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -192,13 +192,24 @@ errlHndl_t UtilLidMgr::loadLid()
UTIL_FT(ERR_MRK"UtilLidMgr::loadLid - setheader failed");
break;
}
- iv_lidSize = l_conHdr.payloadTextSize();
UTIL_FT("UtilLidMgr::loadLid - resv mem section has secure header");
-
- // Increment by page size to not expose secure header
- iv_lidBuffer = static_cast<uint8_t*>(iv_lidBuffer) +
- PAGESIZE;
+ if (l_conHdr.sb_flags()->sw_hash)
+ {
+ // Size of lid has to be size of unprotected data. So we
+ // need to take out header and hash table sizes
+ iv_lidSize = l_conHdr.totalContainerSize() - PAGESIZE -
+ l_conHdr.payloadTextSize();
+ iv_lidBuffer = static_cast<uint8_t*>(iv_lidBuffer) +
+ PAGESIZE + l_conHdr.payloadTextSize();
+ }
+ else
+ {
+ iv_lidSize = l_conHdr.payloadTextSize();
+ // Increment by page size to not expose secure header
+ iv_lidBuffer = static_cast<uint8_t*>(iv_lidBuffer) +
+ PAGESIZE;
+ }
}
}
else if(iv_isLidInVFS)
diff --git a/src/usr/util/test/threadpool.H b/src/usr/util/test/threadpool.H
index 9784540a9..7e474b2c3 100644
--- a/src/usr/util/test/threadpool.H
+++ b/src/usr/util/test/threadpool.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -25,6 +27,15 @@
#include <cxxtest/TestSuite.H>
#include <util/threadpool.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <util/util_reasoncodes.H>
+#include <hbotcompid.H>
+#include <kernel/console.H>
+
+// Thread pool constructor flags
+#define DISABLE_CHILD_RC_CHECKING false
+#define CHECK_CHILD_RC true
namespace __ThreadPoolTest
{
@@ -86,6 +97,17 @@ namespace __ThreadPoolTest
uint64_t* iv_value;
};
+ /** A simple work item that causes the task to crash */
+ struct CrashedTask
+ {
+ CrashedTask() {};
+ void operator()()
+ {
+ uint8_t* l_ptr = nullptr;
+ *l_ptr = 1;
+ }
+ };
+
};
@@ -96,7 +118,8 @@ class ThreadPoolTest: public CxxTest::TestSuite
* ordered pools. */
void testSimpleWorkItem()
{
- Util::ThreadPool<__ThreadPoolTest::Simple> instance;
+ Util::ThreadPool<__ThreadPoolTest::Simple>
+ instance(DISABLE_CHILD_RC_CHECKING);
uint64_t value = 0;
instance.insert(new __ThreadPoolTest::Simple(&value));
@@ -108,7 +131,8 @@ class ThreadPoolTest: public CxxTest::TestSuite
TS_FAIL("Value was not changed by Simple worker thread.");
}
- Util::ThreadPool<__ThreadPoolTest::SimpleOrdered> instance2;
+ Util::ThreadPool<__ThreadPoolTest::SimpleOrdered>
+ instance2(DISABLE_CHILD_RC_CHECKING);
value = 0;
instance2.insert(new __ThreadPoolTest::SimpleOrdered(&value));
@@ -127,7 +151,8 @@ class ThreadPoolTest: public CxxTest::TestSuite
* threads as directed. */
void testThreadManager()
{
- Util::ThreadPool<__ThreadPoolTest::EnsureThreads> instance;
+ Util::ThreadPool<__ThreadPoolTest::EnsureThreads>
+ instance(DISABLE_CHILD_RC_CHECKING);
barrier_t barrier;
for (size_t count = 1; count < 5; count++)
@@ -151,7 +176,8 @@ class ThreadPoolTest: public CxxTest::TestSuite
/** Test that the order functions work on the thread pool. */
void testThreadOrder()
{
- Util::ThreadPool<__ThreadPoolTest::EnsureOrder> instance;
+ Util::ThreadPool<__ThreadPoolTest::EnsureOrder>
+ instance(DISABLE_CHILD_RC_CHECKING);
uint64_t value = 0;
// Ensure that adding work items in order works.
@@ -191,6 +217,104 @@ class ThreadPoolTest: public CxxTest::TestSuite
instance.start();
instance.shutdown();
}
+
+ /** Test a good child task that doesn't return an error. */
+ void testChildRCGoodTask()
+ {
+ TS_INFO(ENTER_MRK"testChildRCGoodTask");
+ Util::ThreadPool<__ThreadPoolTest::Simple>
+ l_threadPool(CHECK_CHILD_RC);
+ uint64_t l_value = 0;
+
+ do {
+ l_threadPool.insert(new __ThreadPoolTest::Simple(&l_value));
+ l_threadPool.start();
+ errlHndl_t l_errl = l_threadPool.shutdown();
+ if(l_errl)
+ {
+ TS_FAIL("testChildRCGoodTask: an unexpected error log (EID 0x%.8%x) returned from the thread pool", l_errl->eid());
+ errlCommit(l_errl, CXXTEST_COMP_ID);
+ break;
+ }
+
+ if(l_value == 0)
+ {
+ TS_FAIL("testChildRCGoodTask: the test value was not changed by the child task");
+ break;
+ }
+
+ }while(0);
+ TS_INFO(EXIT_MRK"testChildRCGoodTask");
+ }
+
+ /** Test that the crashed task's error log is returned to thread pool
+ correctly */
+ void testChildRCCrashedTask()
+ {
+ TS_INFO(ENTER_MRK"testChildRCCrashedTask");
+ Util::ThreadPool<__ThreadPoolTest::CrashedTask>
+ l_threadPool(CHECK_CHILD_RC);
+ errlHndl_t l_errl = nullptr;
+
+ do {
+ printk("testChildRCCrashedTask: Expect to see uncaught exception\n");
+ l_threadPool.insert(new __ThreadPoolTest::CrashedTask());
+ l_threadPool.start();
+ l_errl = l_threadPool.shutdown();
+ if(!l_errl)
+ {
+ TS_FAIL("testChildRCCrashedTask: the thread pool did not return an error log as was expected");
+ break;
+ }
+
+ if(l_errl->moduleId() != Util::UTIL_MOD_TP_SHUTDOWN)
+ {
+ TS_FAIL("testChildRCCrashedTask: unexpected moduleId returned from EID 0x%.8x; expected: 0x%x; actual: 0x%x",
+ l_errl->eid(),
+ Util::UTIL_MOD_TP_SHUTDOWN,
+ l_errl->moduleId());
+ break;
+ }
+
+ if(l_errl->reasonCode() != Util::UTIL_RC_CHILD_TASK_FAILED)
+ {
+ TS_FAIL("testChildRCCrashedTask: unexpected return code from EID 0x%.8x; expected: 0x%x; actual 0x%x",
+ l_errl->eid(),
+ Util::UTIL_RC_CHILD_TASK_FAILED,
+ l_errl->reasonCode());
+ break;
+ }
+ }while(0);
+
+ if(l_errl)
+ {
+ ERRORLOG::errlCommit(l_errl, CXXTEST_COMP_ID);
+ }
+ TS_INFO(EXIT_MRK"testChildRCCrashedTask");
+ }
+
+ /* Test that error is not returned by crashed task when explicitly
+ not requested by thread pool */
+ void testChildNoRCCrashedTask()
+ {
+ TS_INFO(ENTER_MRK"testChildNoRCCrashedTask");
+ Util::ThreadPool<__ThreadPoolTest::CrashedTask>
+ l_threadPool(DISABLE_CHILD_RC_CHECKING);
+ errlHndl_t l_errl = nullptr;
+
+ printk("testChildNoRCCrashedTask: Expect to see uncaught exception\n");
+ l_threadPool.insert(new __ThreadPoolTest::CrashedTask());
+ l_threadPool.start();
+ l_errl = l_threadPool.shutdown();
+
+ if(l_errl)
+ {
+ TS_FAIL("testChildNoRCCrashedTask: unexpected error returned from the thread pool (EID 0x%.8x)", l_errl->eid());
+ ERRORLOG::errlCommit(l_errl, CXXTEST_COMP_ID);
+ }
+
+ TS_INFO(EXIT_MRK"testChildNoRCCrashedTask");
+ }
};
#endif
diff --git a/src/usr/util/threadpool.C b/src/usr/util/threadpool.C
index d2b156839..b51cca642 100644
--- a/src/usr/util/threadpool.C
+++ b/src/usr/util/threadpool.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -23,6 +25,9 @@
#include <util/threadpool.H>
#include <sys/task.h>
#include <sys/misc.h>
+#include <util/util_reasoncodes.H>
+#include <errl/errlmanager.H>
+#include <hbotcompid.H>
void Util::__Util_ThreadPool_Impl::ThreadPoolImpl::__init()
{
@@ -96,10 +101,15 @@ void Util::__Util_ThreadPool_Impl::ThreadPoolImpl::__start(
mutex_unlock(&iv_mutex);
}
-void Util::__Util_ThreadPool_Impl::ThreadPoolImpl::__shutdown()
+errlHndl_t Util::__Util_ThreadPool_Impl::ThreadPoolImpl::__shutdown()
{
mutex_lock(&iv_mutex);
+ int l_childRc = 0;
+ void* l_childRetval = nullptr;
+ errlHndl_t l_origError = nullptr;
+ errlHndl_t l_errl = nullptr;
+
// Set shutdown status and signal all children to release from their
// condition variable.
iv_shutdown = true;
@@ -109,14 +119,52 @@ void Util::__Util_ThreadPool_Impl::ThreadPoolImpl::__shutdown()
while(!iv_children.empty())
{
tid_t child = iv_children.front();
+ tid_t l_returnedTid = 0;
iv_children.pop_front();
mutex_unlock(&iv_mutex);
- task_wait_tid(child, NULL, NULL); // Don't need status.
+ l_returnedTid = task_wait_tid(child, &l_childRc, &l_childRetval);
+ if(iv_checkChildRc &&
+ ((l_returnedTid != child) ||
+ (l_childRc != TASK_STATUS_EXITED_CLEAN)))
+ {
+ /**
+ * @errortype
+ * @moduleid UTIL_MOD_TP_SHUTDOWN
+ * @reasoncode UTIL_RC_CHILD_TASK_FAILED
+ * @userdata1 The return code of the child thread
+ * @userdata2[0:31] The returned task ID of the child thread
+ * @userdata2[32:63] The original task ID of the child thread
+ * @devdesc The child thread of a thread pool returned an
+ * error
+ * @custdesc A failure occurred during the IPL of the system
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ UTIL_MOD_TP_SHUTDOWN,
+ UTIL_RC_CHILD_TASK_FAILED,
+ l_childRc,
+ TWO_UINT32_TO_UINT64(l_returnedTid,
+ child),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT
+ );
+ l_errl->collectTrace(UTIL_COMP_NAME);
+
+ if(!l_origError)
+ {
+ l_origError = l_errl;
+ l_errl = nullptr;
+ }
+ else
+ {
+ l_errl->plid(l_origError->plid());
+ errlCommit(l_errl, UTIL_COMP_ID);
+ }
+ }
mutex_lock(&iv_mutex);
}
mutex_unlock(&iv_mutex);
+ return l_origError;
}
// Default thread count of one per HW thread.
diff --git a/src/usr/util/utillidmgr.C b/src/usr/util/utillidmgr.C
index da9b26052..05c671fe4 100644
--- a/src/usr/util/utillidmgr.C
+++ b/src/usr/util/utillidmgr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,7 +37,6 @@
#include <sys/mm.h>
#include <util/align.H>
-#include <config.h>
#ifdef CONFIG_SECUREBOOT
#include <pnor/pnorif.H>
#include <secureboot/service.H>
diff --git a/src/usr/util/utillidpnor.C b/src/usr/util/utillidpnor.C
index 7e910f6eb..89dc09711 100644
--- a/src/usr/util/utillidpnor.C
+++ b/src/usr/util/utillidpnor.C
@@ -25,7 +25,6 @@
#include <util/utillidmgr.H>
#include <util/utillidpnor.H>
-#include <config.h>
#include <pnor/pnorif.H>
#include <errl/errlmanager.H>
@@ -53,10 +52,6 @@ static const PnorLidsMap PnorToLidsMap =
{ PNOR::OCC, LidAndContainerLid(OCC_LIDID, OCC_CONTAINER_LIDID)},
{ PNOR::WOFDATA, LidAndContainerLid(WOF_LIDID, WOF_CONTAINER_LIDID)},
{ PNOR::HCODE, LidAndContainerLid(NIMBUS_HCODE_LIDID, HCODE_CONTAINER_LIDID)},
- /* @TODO RTC:177927 - Figure out how to handle different Lids for the
- same PNOR section based on chip.
- { PNOR::HCODE, LidAndContainerLid(CUMULUS_HCODE_LIDID, HCODE_CONTAINER_LIDID)},
- */
{ PNOR::RINGOVD, LidAndContainerLid(HWREFIMG_RINGOVD_LIDID,INVALID_LIDID)},
};
@@ -179,7 +174,13 @@ errlHndl_t UtilLidMgr::getLidPnorSectionInfo(const uint32_t i_lidId,
// downstream logic from going past the end of the image.
// NOTE: This assumes that any secure lid loaded from PNOR by
// UtilLidMgr does not contain an unprotected section
- iv_lidPnorInfo.size = iv_lidPnorInfo.secureProtectedPayloadSize;
+ // In this case of hash tables, we need to load the entire
+ // partition size because the user data is part of the
+ // unprotected payload
+ if (!iv_lidPnorInfo.hasHashTable)
+ {
+ iv_lidPnorInfo.size = iv_lidPnorInfo.secureProtectedPayloadSize;
+ }
}
#endif
#endif
diff --git a/src/usr/vfs/vfsrp.C b/src/usr/vfs/vfsrp.C
index fde05d820..aaf4aa57d 100644
--- a/src/usr/vfs/vfsrp.C
+++ b/src/usr/vfs/vfsrp.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -45,7 +45,6 @@
#include <secureboot/service.H>
#include <secureboot/containerheader.H>
#include <kernel/console.H>
-#include <config.h>
using namespace VFS;
@@ -754,7 +753,7 @@ void VfsRp::get_test_modules(std::vector<const char *> & o_list) const
VfsSystemModule * vfsItr =
(VfsSystemModule *) (iv_pnor_vaddr + VFS_EXTENDED_MODULE_TABLE_OFFSET);
- //TRACDCOMP(g_trac_vfs,"finding test modules...");
+ TRACFCOMP(g_trac_vfs,"finding test modules...");
while(vfsItr->module[0] != '\0')
{
@@ -762,7 +761,7 @@ void VfsRp::get_test_modules(std::vector<const char *> & o_list) const
{
if (NULL != vfsItr->start)
{
- //TRACDCOMP( g_trac_vfs, "%s",vfsItr->module);
+ TRACDCOMP( g_trac_vfs, "%s",vfsItr->module);
o_list.push_back(vfsItr->module);
}
}
diff --git a/src/usr/vfs/vfsrp.H b/src/usr/vfs/vfsrp.H
index ebf9c86fd..7530445c1 100644
--- a/src/usr/vfs/vfsrp.H
+++ b/src/usr/vfs/vfsrp.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
diff --git a/src/usr/vpd/HBconfig b/src/usr/vpd/HBconfig
index 0d321192c..86979d7fa 100644
--- a/src/usr/vpd/HBconfig
+++ b/src/usr/vpd/HBconfig
@@ -1,10 +1,12 @@
config MEMVPD_READ_FROM_PNOR
default y
+ default n if SUPPORT_EEPROM_CACHING
help
Read memory VPD data from PNOR cache
config MEMVPD_READ_FROM_HW
default n
+ default y if SUPPORT_EEPROM_CACHING
depends on !PALMETTO_PASS1
help
Read memory VPD data from HW resources
@@ -17,12 +19,14 @@ config MEMVPD_READ
config MEMVPD_WRITE_TO_PNOR
default y if MEMVPD_READ_FROM_PNOR
+ default n if SUPPORT_EEPROM_CACHING
depends on MEMVPD_READ_FROM_PNOR
help
Write memory VPD data to PNOR cache
config MEMVPD_WRITE_TO_HW
default y if MEMVPD_READ_FROM_HW
+ default y if SUPPORT_EEPROM_CACHING
depends on !PALMETTO_PASS1 && MEMVPD_READ_FROM_HW
help
Write memory VPD data to HW resources
@@ -40,6 +44,7 @@ config PVPD_READ_FROM_PNOR
config PVPD_READ_FROM_HW
default n
+ default y if SUPPORT_EEPROM_CACHING
help
Read Planar VPD data from HW resources
@@ -51,17 +56,20 @@ config PVPD_WRITE_TO_PNOR
config PVPD_WRITE_TO_HW
default y if PVPD_READ_FROM_HW
+ default y if SUPPORT_EEPROM_CACHING
depends on PVPD_READ_FROM_HW
help
Write Planar VPD data to HW resources
config MVPD_READ_FROM_PNOR
default y
+ default n if SUPPORT_EEPROM_CACHING
help
Read Module VPD data from PNOR cache
config MVPD_READ_FROM_HW
default n
+ default y if SUPPORT_EEPROM_CACHING
help
Read Module VPD data from HW resources
@@ -73,11 +81,13 @@ config MVPD_READ
config MVPD_WRITE_TO_PNOR
default y if MVPD_READ_FROM_PNOR
+ default n if SUPPORT_EEPROM_CACHING
help
Write Module VPD data to PNOR cache
config MVPD_WRITE_TO_HW
default y if MVPD_READ_FROM_HW
+ default y if SUPPORT_EEPROM_CACHING
depends on MVPD_READ_FROM_HW
help
Write Module VPD data to HW resources
@@ -90,11 +100,13 @@ config MVPD_WRITE
config DJVPD_READ_FROM_PNOR
default y
+ default n if SUPPORT_EEPROM_CACHING
help
Read Dimm JEDEC VPD/SPD data from PNOR cache
config DJVPD_READ_FROM_HW
default n
+ default y if SUPPORT_EEPROM_CACHING
help
Read Dimm JEDEC VPD/SPD data from HW resources
@@ -106,6 +118,7 @@ config DJVPD_READ
config DJVPD_WRITE_TO_PNOR
default y if DJVPD_READ_FROM_PNOR
+ default n if SUPPORT_EEPROM_CACHING
help
Write Dimm JEDEC VPD/SPD data to PNOR cache
diff --git a/src/usr/vpd/cvpd.C b/src/usr/vpd/cvpd.C
index 354e76ab9..5b56655f0 100644
--- a/src/usr/vpd/cvpd.C
+++ b/src/usr/vpd/cvpd.C
@@ -41,7 +41,6 @@
#include <vpd/cvpdenums.H>
#include <vpd/vpd_if.H>
#include <i2c/eepromif.H>
-#include <config.h>
#include "cvpd.H"
#include "pvpd.H"
#include "vpd.H"
diff --git a/src/usr/vpd/cvpd.H b/src/usr/vpd/cvpd.H
index 31f89b29f..05f09386b 100644
--- a/src/usr/vpd/cvpd.H
+++ b/src/usr/vpd/cvpd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,7 +40,6 @@
#include <vpd/cvpdenums.H>
#include "ipvpd.H"
-#include <config.h>
namespace CVPD
{
diff --git a/src/usr/vpd/dimmPres.C b/src/usr/vpd/dimmPres.C
index a62d31f5e..dad7c027e 100755
--- a/src/usr/vpd/dimmPres.C
+++ b/src/usr/vpd/dimmPres.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2016 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -41,7 +41,6 @@
#include <devicefw/driverif.H>
#include <vpd/vpdreasoncodes.H>
#include <vpd/spdenums.H>
-#include <config.h>
#include <initservice/initserviceif.H>
#include <fsi/fsiif.H>
diff --git a/src/usr/vpd/dvpd.C b/src/usr/vpd/dvpd.C
index d0238b997..9d3bc796d 100644
--- a/src/usr/vpd/dvpd.C
+++ b/src/usr/vpd/dvpd.C
@@ -39,7 +39,6 @@
#include <vpd/dvpdenums.H>
#include <vpd/vpd_if.H>
#include <i2c/eepromif.H>
-#include <config.h>
#include "dvpd.H"
#include "cvpd.H"
#include "vpd.H"
diff --git a/src/usr/vpd/dvpd.H b/src/usr/vpd/dvpd.H
index 92985aebe..7517fce2a 100644
--- a/src/usr/vpd/dvpd.H
+++ b/src/usr/vpd/dvpd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,7 +40,6 @@
#include <vpd/dvpdenums.H>
#include "ipvpd.H"
-#include <config.h>
namespace DVPD
{
diff --git a/src/usr/vpd/errlud_vpd.C b/src/usr/vpd/errlud_vpd.C
index f24a5a030..8030e134c 100644
--- a/src/usr/vpd/errlud_vpd.C
+++ b/src/usr/vpd/errlud_vpd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -61,8 +61,8 @@ UdVpdParms::UdVpdParms( TARGETING::Target * i_target,
reallocUsrBuf(sizeof(uint8_t)
+sizeof(uint32_t)
+sizeof(uint64_t)*3));
- uint32_t tmp64 = 0;
- uint16_t tmp32 = 0;
+ uint64_t tmp64 = 0;
+ uint32_t tmp32 = 0;
uint8_t tmp8 = 0;
tmp8 = read_notWrite;
@@ -124,8 +124,8 @@ UdConfigParms::UdConfigParms( TARGETING::Target * i_target,
char * l_pBuf = reinterpret_cast<char *>(
reallocUsrBuf(sizeof(uint32_t)
+sizeof(uint64_t)*7));
- uint32_t tmp64 = 0;
- uint16_t tmp32 = 0;
+ uint64_t tmp64 = 0;
+ uint32_t tmp32 = 0;
tmp32 = TARGETING::get_huid(i_target);
memcpy(l_pBuf, &tmp32, sizeof(tmp32));
diff --git a/src/usr/vpd/ipvpd.C b/src/usr/vpd/ipvpd.C
index 168bc5d36..b38bd77a3 100644
--- a/src/usr/vpd/ipvpd.C
+++ b/src/usr/vpd/ipvpd.C
@@ -39,7 +39,6 @@
#include <vfs/vfs.H>
#include <vpd/vpdreasoncodes.H>
#include <vpd/vpd_if.H>
-#include <config.h>
#include <vpd/ipvpdenums.H>
#include <util/utilrsvdmem.H>
#include <util/runtime/util_rt.H>
@@ -319,6 +318,117 @@ errlHndl_t IpVpdFacade::write ( TARGETING::Target * i_target,
}
// ------------------------------------------------------------------
+// IpVpdFacade::cmpEecacheToEeprom
+// ------------------------------------------------------------------
+errlHndl_t IpVpdFacade::cmpEecacheToEeprom(TARGETING::Target * i_target,
+ VPD::vpdRecord i_record,
+ VPD::vpdKeyword i_keyword,
+ bool & o_match)
+{
+ errlHndl_t l_err = nullptr;
+
+ TRACSSCOMP(g_trac_vpd, ENTER_MRK"cmpEecacheToEeprom() ");
+
+ o_match = false;
+
+ input_args_t l_cacheArgs;
+ l_cacheArgs.record = i_record;
+ l_cacheArgs.keyword = i_keyword;
+ l_cacheArgs.location = VPD::SEEPROM;
+ l_cacheArgs.eepromSource = EEPROM::CACHE;
+
+ input_args_t l_hardwareArgs;
+ l_hardwareArgs.record = i_record;
+ l_hardwareArgs.keyword = i_keyword;
+ l_hardwareArgs.location = VPD::SEEPROM;
+ l_hardwareArgs.eepromSource = EEPROM::HARDWARE;
+
+ do
+ {
+ // Get the CACHE size
+ size_t l_sizeCache = 0;
+
+ l_err = read(i_target,
+ nullptr,
+ l_sizeCache,
+ l_cacheArgs);
+
+ if( l_err || (l_sizeCache == 0) )
+ {
+ TRACFCOMP(g_trac_vpd,
+ "cmpEecacheToEeprom() an error occurred reading the keyword size in cache");
+ break;
+ }
+
+ // Get the CACHE data
+ uint8_t l_dataCache[l_sizeCache];
+ l_err = read( i_target,
+ l_dataCache,
+ l_sizeCache,
+ l_cacheArgs );
+
+ if( l_err )
+ {
+ TRACFCOMP(g_trac_vpd,
+ "cmpEecacheToEeprom() an error occurred reading the keyword in cache");
+ break;
+ }
+
+ // Get the HARDWARE size
+ size_t l_sizeHardware = 0;
+ l_err = read( i_target,
+ nullptr,
+ l_sizeHardware,
+ l_hardwareArgs );
+
+ if( l_err || (l_sizeHardware == 0) )
+ {
+ TRACFCOMP(g_trac_vpd,
+ "cmpEecacheToEeprom() an error occurred reading the keyword size in hardware");
+ break;
+ }
+
+ // Get the HARDWARE data
+ uint8_t l_dataHardware[l_sizeHardware];
+ l_err = read( i_target,
+ l_dataHardware,
+ l_sizeHardware,
+ l_hardwareArgs );
+
+ if( l_err )
+ {
+ TRACFCOMP(g_trac_vpd,
+ "cmpEecacheToEeprom() an error occurred reading the keyword in hardware");
+ break;
+ }
+
+ // Compare the CACHE/HARDWARE keyword size/data
+ if( l_sizeCache != l_sizeHardware )
+ {
+ // Leave o_match == false since there isn't a match.
+ break;
+ }
+
+ if( memcmp( l_dataCache,
+ l_dataHardware,
+ l_sizeCache ) != 0 )
+ {
+ TRACFCOMP( g_trac_vpd, "cmpEecacheToEeprom found mismatch for HUID %.8X 0x%X:0x%X", TARGETING::get_huid(i_target), i_record, i_keyword );
+ TRACFBIN( g_trac_vpd, "HARDWARE", l_dataHardware, l_sizeHardware );
+ TRACFBIN( g_trac_vpd, "CACHE", l_dataCache, l_sizeCache );
+ break;
+ }
+
+ o_match = true;
+
+ } while(0);
+
+ TRACSSCOMP( g_trac_vpd, EXIT_MRK"cmpEecacheToEeprom()" );
+
+ return l_err;
+}
+
+// ------------------------------------------------------------------
// IpVpdFacade::cmpPnorToSeeprom
// ------------------------------------------------------------------
errlHndl_t IpVpdFacade::cmpPnorToSeeprom ( TARGETING::Target * i_target,
@@ -885,8 +995,12 @@ errlHndl_t IpVpdFacade::findRecordOffset ( const char * i_record,
return err;
}
- TRACFCOMP( g_trac_vpd, INFO_MRK" Record %s for target 0x%.8X exists at %p in PNOR",
+ // Don't trace that record exists in PNOR if it does not
+ if (l_overridePtr != nullptr)
+ {
+ TRACFCOMP( g_trac_vpd, INFO_MRK" Record %s for target 0x%.8X exists at %p in PNOR",
i_record, get_huid(i_target), l_overridePtr );
+ }
}
// If we have an override, the record is already pointed at directly
@@ -1180,7 +1294,7 @@ errlHndl_t IpVpdFacade::findRecordOffsetSeeprom ( const char * i_record,
TARGETING::Target * i_target,
input_args_t i_args )
{
- errlHndl_t err = NULL;
+ errlHndl_t err = nullptr;
char l_buffer[256] = { 0 };
uint16_t offset = 0x0;
@@ -1248,6 +1362,12 @@ errlHndl_t IpVpdFacade::findRecordOffsetSeeprom ( const char * i_record,
err = retrieveKeyword( "PT", "VTOC", offset, index, i_target, l_buffer,
pt_len, i_args );
if ( err ) {
+ // There may be only one PT record
+ if (index != 0)
+ {
+ delete err;
+ err = nullptr;
+ }
break;
}
@@ -1271,7 +1391,7 @@ errlHndl_t IpVpdFacade::findRecordOffsetSeeprom ( const char * i_record,
}
}
- if ( !found && err == NULL ) {
+ if ( !found && err == nullptr ) {
TRACFCOMP( g_trac_vpd,
ERR_MRK"IpVpdFacade::findRecordOffsetSeeprom: "
"No matching Record (%s) found in VTOC!", i_record );
@@ -1618,6 +1738,36 @@ errlHndl_t IpVpdFacade::retrieveRecord( const char * i_recordName,
return err;
}
+
+// ------------------------------------------------------------------
+// IpVpdFacade::fetchData
+// ------------------------------------------------------------------
+errlHndl_t IpVpdFacade::fetchData ( uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * o_data,
+ TARGETING::Target * i_target,
+ VPD::vpdCmdTarget i_location,
+ const char* i_record )
+{
+ errlHndl_t err = nullptr;
+
+ // Create an input_args struct which will default EEPROM_SOURCE
+ // to EEPROM::AUTOSELECT.
+ input_args_t inputArgs;
+
+ // Set the VPD location to the given location (PNOR/SEEPROM).
+ inputArgs.location = i_location;
+
+ err = fetchData(i_byteAddr,
+ i_numBytes,
+ o_data,
+ i_target,
+ inputArgs,
+ i_record);
+
+ return err;
+}
+
// ------------------------------------------------------------------
// IpVpdFacade::fetchData
// ------------------------------------------------------------------
@@ -1625,7 +1775,7 @@ errlHndl_t IpVpdFacade::fetchData ( uint64_t i_byteAddr,
size_t i_numBytes,
void * o_data,
TARGETING::Target * i_target,
- VPD::vpdCmdTarget i_location,
+ input_args_t i_args,
const char* i_record )
{
errlHndl_t err = NULL;
@@ -1636,12 +1786,12 @@ errlHndl_t IpVpdFacade::fetchData ( uint64_t i_byteAddr,
configError = VPD::resolveVpdSource( i_target,
iv_configInfo.vpdReadPNOR,
iv_configInfo.vpdReadHW,
- i_location,
+ i_args.location,
vpdSource );
// Look for a record override in our image unless explicitly told not to
bool l_foundOverride = false;
- if( (i_location & VPD::OVERRIDE_MASK) != VPD::USEVPD )
+ if( (i_args.location & VPD::OVERRIDE_MASK) != VPD::USEVPD )
{
uint8_t* l_overridePtr = nullptr;
VPD::RecordTargetPair_t l_recTarg =
@@ -1694,7 +1844,11 @@ errlHndl_t IpVpdFacade::fetchData ( uint64_t i_byteAddr,
}
else if ( (vpdSource == VPD::SEEPROM) && !l_foundOverride )
{
- err = fetchDataFromEeprom( i_byteAddr, i_numBytes, o_data, i_target );
+ err = fetchDataFromEeprom(i_byteAddr,
+ i_numBytes,
+ o_data,
+ i_target,
+ i_args.eepromSource);
}
else
{
@@ -1723,7 +1877,7 @@ errlHndl_t IpVpdFacade::fetchData ( uint64_t i_byteAddr,
VPD::VPD_READ_SOURCE_UNRESOLVED,
TWO_UINT32_TO_UINT64(
TARGETING::get_huid(i_target),
- i_location ),
+ i_args.location ),
TWO_UINT32_TO_UINT64(
iv_configInfo.vpdReadPNOR,
iv_configInfo.vpdReadHW ),
@@ -1777,10 +1931,11 @@ errlHndl_t IpVpdFacade::fetchDataFromPnor ( uint64_t i_byteAddr,
// ------------------------------------------------------------------
// IpVpdFacade::fetchDataFromEeprom
// ------------------------------------------------------------------
-errlHndl_t IpVpdFacade::fetchDataFromEeprom ( uint64_t i_byteAddr,
- size_t i_numBytes,
- void * o_data,
- TARGETING::Target * i_target )
+errlHndl_t IpVpdFacade::fetchDataFromEeprom(uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * o_data,
+ TARGETING::Target * i_target,
+ EEPROM::EEPROM_SOURCE i_eepromSource)
{
errlHndl_t err = NULL;
TRACSSCOMP( g_trac_vpd,
@@ -1797,7 +1952,8 @@ errlHndl_t IpVpdFacade::fetchDataFromEeprom ( uint64_t i_byteAddr,
i_numBytes,
DEVICE_EEPROM_ADDRESS(
EEPROM::VPD_PRIMARY,
- i_byteAddr, EEPROM::AUTOSELECT ) );
+ i_byteAddr,
+ i_eepromSource ) );
if( err )
{
break;
@@ -1896,21 +2052,31 @@ errlHndl_t IpVpdFacade::findKeywordAddr ( const char * i_keywordName,
offset,
i_recordName );
+ // convert data for SRC display
+ uint32_t exp_rec;
+ memcpy( &exp_rec, i_recordName, RECORD_BYTE_SIZE );
+ uint32_t act_rec;
+ memcpy( &act_rec, record, RECORD_BYTE_SIZE );
+
/*@
* @errortype
* @reasoncode VPD::VPD_RECORD_MISMATCH
* @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
* @moduleid VPD::VPD_IPVPD_FIND_KEYWORD_ADDR
- * @userdata1 Current offset into VPD
- * @userdata2 Start of Record offset
+ * @userdata1[00:31] Current offset into VPD
+ * @userdata1[32:63] Start of Record offset
+ * @userdata2[00:31] Expected record name
+ * @userdata2[32:63] Found record name
* @devdesc Record name does not match value expected for
* offset read.
*/
err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
VPD::VPD_IPVPD_FIND_KEYWORD_ADDR,
VPD::VPD_RECORD_MISMATCH,
- offset,
- i_offset );
+ TWO_UINT32_TO_UINT64(offset,
+ i_offset ),
+ TWO_UINT32_TO_UINT64(exp_rec,
+ act_rec) );
// Could be the VPD of the target wasn't set up properly
// -- DECONFIG so that we can possibly keep booting
diff --git a/src/usr/vpd/ipvpd.H b/src/usr/vpd/ipvpd.H
index 597c6e256..c47a241a6 100644
--- a/src/usr/vpd/ipvpd.H
+++ b/src/usr/vpd/ipvpd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -31,9 +31,8 @@
#include <map>
#include <pnor/pnorif.H>
#include <devicefw/driverif.H>
-#include <config.h>
#include "vpd.H"
-
+#include <i2c/eeprom_const.H>
/** @file ipvpd.H
* @brief Provides base support for i/p-Series style IBM VPD
@@ -79,11 +78,35 @@ class IpVpdFacade
/**
* @brief Structure for all VPD dd input parameter arguments
*/
- typedef struct
+ typedef struct device_driver_input_args
{
- VPD::vpdRecord record;
- VPD::vpdKeyword keyword;
- VPD::vpdCmdTarget location;
+ VPD::vpdRecord record;
+ VPD::vpdKeyword keyword;
+ VPD::vpdCmdTarget location;
+ EEPROM::EEPROM_SOURCE eepromSource;
+
+ // Default constructor
+ device_driver_input_args() : record(0xFFFFFFFF),
+ keyword(0xFFFFFFFF),
+ location(VPD::AUTOSELECT),
+ eepromSource(EEPROM::AUTOSELECT)
+ {};
+
+ // This constructor allows for existing code using brace-enclosed
+ // initializer lists of the first three arguments to continue to
+ // function normally. Since the default behavior for EEPROM_SOURCE is
+ // AUTOSELECT, setting it automatically here is done to maintain that
+ // default assumption.
+ device_driver_input_args(VPD::vpdRecord i_record,
+ VPD::vpdKeyword i_keyword,
+ VPD::vpdCmdTarget i_location)
+ : record(i_record),
+ keyword(i_keyword),
+ location(i_location),
+ eepromSource(EEPROM::AUTOSELECT)
+ {};
+
+
} input_args_t;
/**
@@ -237,6 +260,28 @@ class IpVpdFacade
VPD::vpdRecord record,
VPD::vpdKeyword keyword );
+
+ /**
+ * @brief This function compares the specified record/keyword
+ * in CACHE/HARDWARE and returns the result. A mismatch
+ * will not return an error.
+ *
+ * @param[in] i_target Target device
+ *
+ * @param[in] i_record Record to compare
+ *
+ * @param[in] i_keyword Keyword to compare
+ *
+ * @param[out] o_match Result of compare
+ *
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+ errlHndl_t cmpEecacheToEeprom(TARGETING::Target * i_target,
+ VPD::vpdRecord i_record,
+ VPD::vpdKeyword i_keyword,
+ bool & o_match);
+
/**
* @brief This function compares the specified record/keyword
* in PNOR/SEEPROM and returns the result. A mismatch
@@ -594,6 +639,8 @@ class IpVpdFacade
uint64_t& o_byteAddr,
input_args_t i_args );
+
+
/**
* @brief This function calls the PNOR or EEPROM version of
* the fetchData function based on the configInfo
@@ -613,12 +660,38 @@ class IpVpdFacade
* @return errHndl_t - NULL if successful, otherwise a pointer to the
* error log.
*/
- errlHndl_t fetchData ( uint64_t i_byteAddr,
- size_t i_numBytes,
- void * o_data,
- TARGETING::Target * i_target,
- VPD::vpdCmdTarget i_location,
- const char* i_record );
+ errlHndl_t fetchData(uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * o_data,
+ TARGETING::Target * i_target,
+ VPD::vpdCmdTarget i_location,
+ const char* i_record);
+
+ /**
+ * @brief This function calls the PNOR or EEPROM version of
+ * the fetchData function based on the configInfo
+ *
+ * @param[in] i_byteAddr The offset to be read.
+ *
+ * @param[in] i_numBytes The number of bytes to read.
+ *
+ * @param[out] o_data The data buffer where the data will be placed.
+ *
+ * @param[in] i_target Target device.
+ *
+ * @param[in] i_args The input arguments
+ *
+ * @param[in] i_record String representation of the record.
+ *
+ * @return errHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+ errlHndl_t fetchData(uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * o_data,
+ TARGETING::Target * i_target,
+ input_args_t i_args,
+ const char* i_record);
/**
* @brief This function actually reads the data from PNOR
@@ -653,10 +726,11 @@ class IpVpdFacade
* @return errHndl_t - NULL if successful, otherwise a pointer to the
* error log.
*/
- errlHndl_t fetchDataFromEeprom ( uint64_t i_byteAddr,
- size_t i_numBytes,
- void * o_data,
- TARGETING::Target * i_target );
+ errlHndl_t fetchDataFromEeprom(uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * o_data,
+ TARGETING::Target * i_target,
+ EEPROM::EEPROM_SOURCE i_eepromSource = EEPROM::AUTOSELECT);
/**
* @brief This function compares 2 ipvpd record values. Used for binary
diff --git a/src/usr/vpd/makefile b/src/usr/vpd/makefile
index 728750fca..9ef60d788 100644
--- a/src/usr/vpd/makefile
+++ b/src/usr/vpd/makefile
@@ -31,7 +31,6 @@ include vpd.mk
#include unique objects
OBJS += vpd.o
OBJS += dimmPres.o
-OBJS += ocmb_spd.o
OBJS += rtvpd_load.o
SUBDIRS += test.d
diff --git a/src/usr/vpd/mvpd.C b/src/usr/vpd/mvpd.C
index 4de720594..242e3bab1 100644
--- a/src/usr/vpd/mvpd.C
+++ b/src/usr/vpd/mvpd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -38,7 +38,6 @@
#include <vpd/mvpdenums.H>
#include <vpd/vpd_if.H>
#include <i2c/eepromif.H>
-#include <config.h>
#include "mvpd.H"
#include "ipvpd.H"
diff --git a/src/usr/vpd/ocmb_spd.C b/src/usr/vpd/ocmb_spd.C
index c4f8137cc..2767efca7 100644
--- a/src/usr/vpd/ocmb_spd.C
+++ b/src/usr/vpd/ocmb_spd.C
@@ -28,16 +28,24 @@
#include <errl/errlentry.H>
#include <vpd/vpdreasoncodes.H>
+#include "ocmb_spd.H"
+#include "spd.H"
+#include "errlud_vpd.H"
+#include <vpd/vpd_if.H>
+
extern trace_desc_t * g_trac_spd;
+//#define TRACSSCOMP(args...) TRACFCOMP(args)
+#define TRACSSCOMP(args...)
+
+// Namespace alias for targeting
+namespace T = TARGETING;
+
namespace SPD
{
/**
* @brief Handle SPD READ deviceOp to OCMB_CHIP targets
- * This function performs read operations on OCMBs by in turn performing
- * an EEPROM deviceOp on this target, reading the first 2 KB of the OCMB's
- * Primary VPD eeprom and returning it via a buffer
*
* @param[in] i_opType Operation type, see driverif.H
* @param[in] i_target MMIO target
@@ -50,107 +58,327 @@ namespace SPD
* In this function, there is one argument,
* the l_keyword, so far we only support ENTIRE_SPD
* @return errlHndl_t
- *
- * NOTE: ONLY ENTIRE_SPD READ SUPPORTED CURRENTLY
*/
errlHndl_t ocmbSPDPerformOp(DeviceFW::OperationType i_opType,
- TARGETING::Target* i_target,
- void* io_buffer,
- size_t& io_buflen,
- int64_t i_accessType,
- va_list i_args);
+ T::TargetHandle_t i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ va_list i_args);
// Register the perform Op with the routing code for OCMBs.
-DEVICE_REGISTER_ROUTE( DeviceFW::READ,
- DeviceFW::SPD,
- TARGETING::TYPE_OCMB_CHIP,
- ocmbSPDPerformOp );
+DEVICE_REGISTER_ROUTE(DeviceFW::READ,
+ DeviceFW::SPD,
+ T::TYPE_OCMB_CHIP,
+ ocmbSPDPerformOp);
-/**
- * @brief Read keyword from SPD
- *
- * Currently used to detect I2C_MUTEX and OCMB_CHIP targets
- *
- * @param[in] i_target OCMB target to read data from
- * @param[in] i_keyword keyword from spdenums.H to read
- * @param[in/out] io_buffer databuffer SPD will be written to
- * @param[in] i_buflen length of the given data buffer
- *
- * @pre io_buffer and i_target must be non-null
- * @pre currenlty only supported value for i_keyword is ENTIRE_SPD
- *
- * @return errlHndl_t
- */
-errlHndl_t ocmbGetSPD(const TARGETING::Target* i_target,
- const uint64_t & i_keyword,
- void* const io_buffer,
- const size_t& i_buflen)
+errlHndl_t ocmbGetSPD(T::TargetHandle_t i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ const VPD::vpdKeyword i_keyword,
+ const uint8_t i_memType,
+ EEPROM::EEPROM_SOURCE i_location)
{
errlHndl_t l_errl = nullptr;
- TRACFCOMP( g_trac_spd,
- ENTER_MRK"ocmbGetSPD()" );
-
- // If any of these asserts fail it is a SW error
- assert(io_buffer != nullptr, "io_buffer is nullptr in ocmbGetSPD");
assert(i_target != nullptr, "i_target is nullptr in ocmbGetSPD");
- assert(i_buflen >= SPD::OCMB_SPD_EFD_COMBINED_SIZE, "Buffer must be at least 2 KB in ocmbGetSPD");
do {
- if(i_keyword != ENTIRE_SPD)
+ const KeywordData* entry = nullptr;
+ l_errl = getKeywordEntry(i_keyword,
+ i_memType,
+ i_target,
+ entry);
+ if (l_errl != nullptr)
+ {
+ break;
+ }
+
+ // Check to be sure entry is not nullptr.
+ if (entry == nullptr)
{
- TRACFCOMP( g_trac_spd,
- "ocmbGetSPD() only entire SPD currently supported, 0x%X is not supported",
- i_keyword);
+ TRACFCOMP(g_trac_spd,
+ ERR_MRK"KeywordData entry pointer is nullptr!");
+
/*@
* @errortype
- * @moduleid VPD::VPD_OCMB_GET_SPD
- * @reasoncode VPD::VPD_NOT_SUPPORTED
- * @userdata1 Keyword Enum
- * @userdata2 Target huid
- * @devdesc Attempted to lookup SPD keyword not supported
- * @custdesc Firmware error during system IPL
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_OCMB_GET_SPD
+ * @reasoncode VPD::VPD_NULL_ENTRY
+ * @userdata1[00:31] Buffer Size
+ * @userdata1[32:63] Memory Type
+ * @userdata2[00:31] SPD Keyword
+ * @userdata2[32:63] Target HUID
+ * @devdesc SPD is not valid for this part
+ * @custdesc A problem occurred during the IPL
+ * of the system.
*/
l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_OCMB_GET_SPD,
- VPD::VPD_NOT_SUPPORTED,
- i_keyword,
- i_target->getAttr<TARGETING::ATTR_HUID>(),
- ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ VPD::VPD_OCMB_GET_SPD,
+ VPD::VPD_NULL_ENTRY,
+ TWO_UINT32_TO_UINT64(io_buflen,
+ i_memType),
+ TWO_UINT32_TO_UINT64(i_keyword,
+ T::get_huid(i_target)),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ l_errl->collectTrace( "SPD", 256);
+
break;
+ }
+
+ // Only allow keywords supported by DDIMM
+ l_errl = checkModSpecificKeyword(*entry,
+ i_memType,
+ i_target,
+ VPD::SEEPROM);
+ if (l_errl != nullptr)
+ {
+ break;
+ }
+
+ if (entry->isSpecialCase)
+ {
+ l_errl = spdSpecialCases(*entry,
+ io_buffer,
+ i_target,
+ i_memType,
+ VPD::SEEPROM);
+ if (l_errl != nullptr)
+ {
+ break;
+ }
+ }
+
+ // Support passing in nullptr buffer to return VPD field size.
+ if (io_buffer == nullptr)
+ {
+ io_buflen = entry->length;
+ break;
}
- size_t l_spdReadBufferLen = SPD::OCMB_SPD_EFD_COMBINED_SIZE;
- l_errl = DeviceFW::deviceOp(DeviceFW::READ,
- const_cast<TARGETING::Target*>(i_target),
- io_buffer,
- l_spdReadBufferLen,
- DEVICE_EEPROM_ADDRESS(EEPROM::VPD_PRIMARY,
- 0,
- EEPROM::AUTOSELECT)
- );
+ l_errl = spdCheckSize(io_buflen,
+ entry->length,
+ i_keyword);
- }while(0);
+ if (l_errl != nullptr)
+ {
+ break;
+ }
+
+ l_errl = ocmbFetchData(i_target,
+ entry->offset,
+ entry->length,
+ io_buffer,
+ i_location);
+
+ if (l_errl != nullptr)
+ {
+ break;
+ }
+
+ // Return the size read.
+ io_buflen = entry->length;
+
+ } while(0);
return l_errl;
}
+// ------------------------------------------------------------------
+// ocmbFetchData
+// ------------------------------------------------------------------
+errlHndl_t ocmbFetchData(T::TargetHandle_t i_target,
+ uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void* o_data,
+ EEPROM::EEPROM_SOURCE i_location)
+{
+ errlHndl_t err = nullptr;
+
+ TRACSSCOMP(g_trac_spd,
+ ENTER_MRK"ocmbFetchData()"
+ " i_byteAddr = 0x%x i_numBytes = %d i_location = 0x%x",
+ i_byteAddr, i_numBytes, i_location);
+
+ do
+ {
+ // Get the data
+ err = DeviceFW::deviceOp(DeviceFW::READ,
+ i_target,
+ o_data,
+ i_numBytes,
+ DEVICE_EEPROM_ADDRESS(EEPROM::VPD_PRIMARY,
+ i_byteAddr,
+ i_location));
+ if( err )
+ {
+ TRACFCOMP(g_trac_spd,
+ ERR_MRK"ocmbFetchData(): failing out of deviceOp");
+ break;
+ }
+
+ } while(0);
+
+ TRACSSCOMP(g_trac_spd,
+ EXIT_MRK"ocmbFetchData(): returning %s errors",
+ ((err != nullptr) ? "with" : "with no") );
+
+ return err;
+}
+
+// ------------------------------------------------------------------
+// isValidOcmbDimmType
+// ------------------------------------------------------------------
+bool isValidOcmbDimmType(const uint8_t i_dimmType)
+{
+ return ((SPD_DDR4_TYPE == i_dimmType ));
+}
+
+// ------------------------------------------------------------------
+// getMemType
+// ------------------------------------------------------------------
+errlHndl_t getMemType(uint8_t& o_memType,
+ T::TargetHandle_t i_target,
+ EEPROM::EEPROM_SOURCE i_location)
+{
+ errlHndl_t err = nullptr;
+
+ err = ocmbFetchData(i_target,
+ MEM_TYPE_ADDR,
+ MEM_TYPE_SZ,
+ &o_memType,
+ i_location);
+
+ TRACSSCOMP(g_trac_spd,
+ EXIT_MRK"SPD::getMemType() - MemType: 0x%02x, Error: %s",
+ o_memType,
+ ((err != nullptr) ? "Yes" : "No"));
+
+ return err;
+}
+
// See above for details
errlHndl_t ocmbSPDPerformOp(DeviceFW::OperationType i_opType,
- TARGETING::Target* i_target,
+ T::TargetHandle_t i_target,
void* io_buffer,
size_t& io_buflen,
int64_t i_accessType,
va_list i_args)
{
- errlHndl_t l_errl = nullptr;
- const uint64_t l_keyword = va_arg(i_args, uint64_t);
- l_errl = ocmbGetSPD(i_target, l_keyword, io_buffer, io_buflen);
- return l_errl;
-}
+ errlHndl_t errl = nullptr;
+ const uint64_t keyword = va_arg(i_args, uint64_t);
+
+ TRACSSCOMP(g_trac_spd,
+ ENTER_MRK"ocmbSPDPerformOP(), io_buflen: %d, keyword: 0x%04x",
+ io_buflen, keyword );
+
+ do
+ {
+ // Read the Basic Memory Type
+ uint8_t memType(MEM_TYPE_INVALID);
+ errl = getMemType(memType, i_target, EEPROM::AUTOSELECT);
+
+ if( errl )
+ {
+ break;
+ }
+
+ TRACSSCOMP(g_trac_spd,
+ INFO_MRK"Mem Type: %04x",
+ memType);
+
+ // Check the Basic Memory Type
+ if (isValidOcmbDimmType(memType))
+ {
+ // If the user wanted the Basic memory type, return this now.
+ if(BASIC_MEMORY_TYPE == keyword)
+ {
+ io_buflen = MEM_TYPE_SZ;
+ if (io_buffer != nullptr)
+ {
+ memcpy(io_buffer, &memType, io_buflen);
+ }
+ break;
+ }
+
+ // Read the keyword value
+ errl = ocmbGetSPD(i_target,
+ io_buffer,
+ io_buflen,
+ keyword,
+ memType,
+ EEPROM::AUTOSELECT);
+
+ if( errl )
+ {
+ break;
+ }
+ }
+ else
+ {
+ TRACFCOMP(g_trac_spd,
+ ERR_MRK"Invalid Basic Memory Type (0x%04x), "
+ "target huid = 0x%x",
+ memType,
+ T::get_huid(i_target));
+
+ /*@
+ * @errlortype
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_OCMB_SPD_PERFORM_OP
+ * @reasoncode VPD::VPD_INVALID_BASIC_MEMORY_TYPE
+ * @userdata1[00:31] Basic Memory Type (Byte 2)
+ * @userdata1[32:63] Target HUID
+ * @userdata2 Keyword Requested
+ * @devdesc Invalid Basic Memory Type
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_OCMB_SPD_PERFORM_OP,
+ VPD::VPD_INVALID_BASIC_MEMORY_TYPE,
+ TWO_UINT32_TO_UINT64(memType,
+ T::get_huid(i_target)),
+ keyword);
+ // User could have installed a bad/unsupported dimm
+ errl->addHwCallout(i_target,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DECONFIG,
+ HWAS::GARD_NULL);
+
+ errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_LOW);
+
+ errl->addProcedureCallout(HWAS::EPUB_PRC_SP_CODE,
+ HWAS::SRCI_PRIORITY_LOW);
+
+ errl->collectTrace("SPD", 256);
+
+ break;
+ }
+ } while(0);
+
+ // If there is an error, add parameter info to log
+ if ( errl != nullptr )
+ {
+ VPD::UdVpdParms(i_target,
+ io_buflen,
+ 0,
+ keyword,
+ true) // read
+ .addToLog(errl);
+ }
+
+ TRACSSCOMP(g_trac_spd,
+ EXIT_MRK"ocmbSPDPerformOP(): returning %s errors",
+ (errl ? "with" : "with no") );
+
+ return errl;
}
+
+
+} // End of SPD namespace
diff --git a/src/usr/vpd/ocmb_spd.H b/src/usr/vpd/ocmb_spd.H
new file mode 100644
index 000000000..91123dfd4
--- /dev/null
+++ b/src/usr/vpd/ocmb_spd.H
@@ -0,0 +1,102 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/vpd/ocmb_spd.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __OCMB_SPD_H
+#define __OCMB_SPD_H
+
+#include <i2c/eeprom_const.H>
+
+namespace SPD
+{
+
+/*
+ * @brief Read keyword from SPD
+ *
+ * @param[in] i_target OCMB target to read data from
+ * @param[in/out] io_buffer databuffer SPD will be written to
+ * @param[in/out] io_buflen length of the given data buffer
+ * @param[in] i_keyword keyword from spdenums.H to read
+ * @param[in] i_memType The memory type of this target.
+ * @param[in] i_location The EEPROM source (CACHE/HARDWARE).
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, error log.
+ */
+errlHndl_t ocmbGetSPD(TARGETING::TargetHandle_t i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ const VPD::vpdKeyword i_keyword,
+ const uint8_t i_memType,
+ EEPROM::EEPROM_SOURCE i_location);
+
+/*
+ * @brief Determine if the given DIMM type is a known DIMM type or not
+ *
+ * @param[in] i_dimmType - The DIMM to verify if valid
+ *
+ * @return boolean - return true if given parameter is a known DIMM type,
+ * false otherwise
+ */
+bool isValidOcmbDimmType(const uint8_t i_dimmType);
+
+/*
+ * @brief This function will read the DIMM memory type for OCMBs.
+ *
+ * @param[out] o_memType - The memory type value to return.
+ *
+ * @param[in] i_target - The target to read data from.
+ *
+ * @param[in] i_eepromSource - The EEPROM source (CACHE/HARDWARE).
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer
+ * to the error log.
+ */
+errlHndl_t getMemType(uint8_t& o_memType,
+ TARGETING::TargetHandle_t i_target,
+ EEPROM::EEPROM_SOURCE i_eepromSource);
+
+/**
+ * @param This function is a wrapper for reading the correct keyword.
+ *
+ * @param[in] i_target The target DDIMM to access.
+ *
+ * @param[in] i_byteAddr The offset into the JEDEC SPD layout.
+ *
+ * @param[in] i_numbytes Number of bytes to read.
+ *
+ * @param[out] o_data The data buffer that will return the data read.
+ *
+ * @param[in] i_location The EEPROM source (CACHE/HARDWARE).
+ *
+ * @return errlHndl_t nullptr if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t ocmbFetchData(TARGETING::TargetHandle_t i_target,
+ uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void* o_data,
+ EEPROM::EEPROM_SOURCE i_location);
+
+}
+
+#endif
diff --git a/src/usr/vpd/pvpd.C b/src/usr/vpd/pvpd.C
index 371a87deb..ae6442554 100644
--- a/src/usr/vpd/pvpd.C
+++ b/src/usr/vpd/pvpd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,9 +39,9 @@
#include <vpd/pvpdenums.H>
#include <vpd/vpd_if.H>
#include <i2c/eepromif.H>
-#include <config.h>
#include "pvpd.H"
#include "cvpd.H"
+#include "dvpd.H"
#include "vpd.H"
#include <initservice/initserviceif.H>
@@ -245,7 +245,7 @@ errlHndl_t nodePresenceDetect(DeviceFW::OperationType i_opType,
}
pvpd_present = VPD::pvpdPresent( i_target );
-#if(defined( CONFIG_PVPD_READ_FROM_HW ) && !defined( __HOSTBOOT_RUNTIME) )
+#if(defined( CONFIG_PVPD_READ_FROM_HW ) && !defined( __HOSTBOOT_RUNTIME) && defined(CONFIG_PVPD_READ_FROM_PNOR))
if( pvpd_present )
{
// Check if the VPD data in the PNOR matches the SEEPROM
diff --git a/src/usr/vpd/pvpd.H b/src/usr/vpd/pvpd.H
index e3e947521..cd6115c26 100644
--- a/src/usr/vpd/pvpd.H
+++ b/src/usr/vpd/pvpd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,7 +40,6 @@
#include <vpd/pvpdenums.H>
#include "ipvpd.H"
-#include <config.h>
namespace PVPD
{
diff --git a/src/usr/vpd/rtvpd_load.C b/src/usr/vpd/rtvpd_load.C
index 26ad6f031..f12d23d01 100644
--- a/src/usr/vpd/rtvpd_load.C
+++ b/src/usr/vpd/rtvpd_load.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -108,6 +108,7 @@ errlHndl_t VPD::vpd_load_rt_image(uint64_t & i_vpd_addr)
do
{
+#ifndef CONFIG_SUPPORT_EEPROM_CACHING
void* vptr = reinterpret_cast<void*>(i_vpd_addr);
uint8_t* vpd_ptr = reinterpret_cast<uint8_t*>(vptr);
@@ -136,6 +137,21 @@ errlHndl_t VPD::vpd_load_rt_image(uint64_t & i_vpd_addr)
{
break;
}
+#else
+ // In Axone we store all contents of EEPROMs in EECACHE
+ // so copy the EECACHE pnor section to the space in reserved
+ // memory allocated for VPD.
+ void* vptr = reinterpret_cast<void*>(i_vpd_addr);
+ uint8_t* vpd_ptr = reinterpret_cast<uint8_t*>(vptr);
+
+ err = bld_vpd_image(PNOR::EECACHE,
+ vpd_ptr,
+ VMM_RT_VPD_SIZE);
+ if(err)
+ {
+ break;
+ }
+#endif
} while( 0 );
diff --git a/src/usr/vpd/runtime/rt_vpd.C b/src/usr/vpd/runtime/rt_vpd.C
index ba0335484..ee7fa9f7b 100644
--- a/src/usr/vpd/runtime/rt_vpd.C
+++ b/src/usr/vpd/runtime/rt_vpd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -34,7 +34,7 @@
#include <util/runtime/rt_fwreq_helper.H> // firmware_request_helper
#include <targeting/common/util.H>
#include <util/runtime/util_rt.H>
-#include <runtime/rt_targeting.H>
+#include <targeting/runtime/rt_targeting.H>
#include <runtime/interface.h>
#include <initservice/initserviceif.H>
diff --git a/src/usr/vpd/spd.C b/src/usr/vpd/spd.C
index a58398e4a..47dfe0f83 100644
--- a/src/usr/vpd/spd.C
+++ b/src/usr/vpd/spd.C
@@ -48,10 +48,12 @@
#include <vpd/spdenums.H>
#include <algorithm>
#include "spd.H"
+#include "ocmb_spd.H"
#include "spdDDR3.H"
#include "spdDDR4.H"
+#include "spdDDR4_DDIMM.H"
#include "errlud_vpd.H"
-#include <config.h>
+#include "ocmb_spd.H"
// ----------------------------------------------
// Trace definitions
@@ -115,12 +117,27 @@ const bool g_usePNOR = true;
*
* @param[in] i_dimmType - The DIMM to verify if valid
*
-* @return boolean - return true if given paramter is a known DIMM type,
+* @return boolean - return true if given parameter is a known DIMM type,
* false otherwise
*/
bool isValidDimmType ( uint8_t i_dimmType );
/**
+ * @brief Determines if the given DIMM type is a known DIMM type or not by
+ * calling the correct isValidDimmType function for OCMB_SPD or SPD.
+ *
+ * @param[in] i_dimmType - The DIMM to verify if valid
+ *
+ * @param[in] i_eepromType - The eeprom content type of the DIMM
+ *
+ * @return boolean - return true if given paramter is a known DIMM type,
+ * false otherwise
+ */
+bool isValidDimmType(uint8_t i_dimmType,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType);
+
+
+/**
* @brief Compare two values and return whether e2 is greater than
* the e1 value. This is used during lower_bound to cut
* search time down.
@@ -140,18 +157,42 @@ bool compareEntries ( const KeywordData e1,
/**
* @brief This function will read the DIMM memory type.
*
- * @param[out] o_memType - The memory type value to return.
+ * @param[out] o_memType - The memory type value to return.
*
- * @param[in] i_target - The target to read data from.
+ * @param[in] i_target - The target to read data from.
*
- * @param[in] i_location - The SPD source (PNOR/SEEPROM).
+ * @param[in] i_location - The SPD source (PNOR/SEEPROM).
+ *
+ * @param[in] i_eepromSource - The EEPROM source (CACHE/HARDWARE).
+ * Default to AUTOSELECT.
*
* @return errlHndl_t - NULL if successful, otherwise a pointer
* to the error log.
*/
-errlHndl_t getMemType ( uint8_t & o_memType,
- TARGETING::Target * i_target,
- VPD::vpdCmdTarget i_location );
+errlHndl_t getMemType(uint8_t & o_memType,
+ TARGETING::Target * i_target,
+ VPD::vpdCmdTarget i_location,
+ EEPROM::EEPROM_SOURCE i_eepromSource = EEPROM::AUTOSELECT);
+
+/**
+ * @brief This function will read the DIMM memory type by calling the correct
+ * function given the eeprom content type.
+ *
+ * @param[out] o_memType - The memory type value to return.
+ *
+ * @param[in] i_target - The target to read data from.
+ *
+ * @param[in] i_eepromType - The Eeprom content type of the target.
+ *
+ * @param[in] i_eepromSource - The EEPROM source (CACHE/HARDWARE).
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer
+ * to the error log.
+ */
+errlHndl_t getMemType(uint8_t & o_memType,
+ TARGETING::Target * i_target,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType,
+ EEPROM::EEPROM_SOURCE i_eepromSource);
/**
* @brief This function will read the DIMM module type.
@@ -173,26 +214,6 @@ errlHndl_t getModType ( modSpecTypes_t & o_modType,
VPD::vpdCmdTarget i_location );
/**
- * @brief This function will scan the table and return the entry
- * corresponding to the keyword being requested.
- *
- * @param[in] i_keyword - The keyword being requested.
- *
- * @param[in] i_memType - The memory type of the target.
- *
- * @param[in] i_target - Target (only used for callouts)
- *
- * @param[out] o_entry - The table entry corresponding to the keyword.
- *
- * @return errlHndl_t - NULL if successful, otherwise a pointer to
- * the error log.
- */
-errlHndl_t getKeywordEntry ( VPD::vpdKeyword i_keyword,
- uint64_t i_memType,
- TARGETING::Target * i_target,
- const KeywordData *& o_entry );
-
-/**
* @brief This function will set the size of SPD for the given target based on
* the DIMM type.
*
@@ -226,6 +247,29 @@ bool isValidDimmType ( const uint8_t i_dimmType )
( SPD_DDR4_TYPE == i_dimmType ) );
}
+
+bool isValidDimmType(uint8_t i_memType,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType)
+{
+ bool isValid = false;
+
+// TODO RTC:204341 Add support for reading/write EECACHE during runtime
+#ifndef __HOSTBOOT_RUNTIME
+ if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_ISDIMM)
+ {
+ isValid = isValidDimmType(i_memType);
+ }
+ else if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_DDIMM)
+ {
+ isValid = isValidOcmbDimmType(i_memType);
+ }
+
+#endif
+
+ return isValid;
+}
+
+
// ------------------------------------------------------------------
// spdGetKeywordValue
// ------------------------------------------------------------------
@@ -456,11 +500,12 @@ errlHndl_t spdWriteKeywordValue ( DeviceFW::OperationType i_opType,
// ------------------------------------------------------------------
// spdFetchData
// ------------------------------------------------------------------
-errlHndl_t spdFetchData ( uint64_t i_byteAddr,
- size_t i_numBytes,
- void * o_data,
- TARGETING::Target * i_target,
- VPD::vpdCmdTarget i_location )
+errlHndl_t spdFetchData ( uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * o_data,
+ TARGETING::Target * i_target,
+ VPD::vpdCmdTarget i_location,
+ EEPROM::EEPROM_SOURCE i_eepromSource)
{
errlHndl_t err{nullptr};
@@ -516,7 +561,7 @@ errlHndl_t spdFetchData ( uint64_t i_byteAddr,
DEVICE_EEPROM_ADDRESS(
EEPROM::VPD_PRIMARY,
i_byteAddr,
- EEPROM::AUTOSELECT) );
+ i_eepromSource));
if( err )
{
TRACFCOMP(g_trac_spd,
@@ -640,12 +685,13 @@ errlHndl_t spdWriteData ( uint64_t i_offset,
// ------------------------------------------------------------------
// spdGetValue
// ------------------------------------------------------------------
-errlHndl_t spdGetValue ( VPD::vpdKeyword i_keyword,
- void * io_buffer,
- size_t & io_buflen,
- TARGETING::Target * i_target,
- uint64_t i_DDRRev,
- VPD::vpdCmdTarget i_location )
+errlHndl_t spdGetValue(VPD::vpdKeyword i_keyword,
+ void * io_buffer,
+ size_t & io_buflen,
+ TARGETING::Target * i_target,
+ uint64_t i_DDRRev,
+ VPD::vpdCmdTarget i_location,
+ EEPROM::EEPROM_SOURCE i_eepromSource)
{
errlHndl_t err{nullptr};
uint8_t * tmpBuffer = static_cast<uint8_t *>(io_buffer);
@@ -1247,6 +1293,36 @@ errlHndl_t ddr3SpecialCases(const KeywordData & i_kwdData,
return err;
}
+
+errlHndl_t fetchDataFromEepromType(uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * o_data,
+ TARGETING::Target * i_target,
+ VPD::vpdCmdTarget i_location,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType)
+{
+ errlHndl_t errl = nullptr;
+
+ if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_ISDIMM)
+ {
+ errl = spdFetchData(i_byteAddr,
+ i_numBytes,
+ o_data,
+ i_target,
+ i_location);
+ }
+ else if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_DDIMM)
+ {
+ errl = ocmbFetchData(i_target,
+ i_byteAddr,
+ i_numBytes,
+ o_data,
+ EEPROM::AUTOSELECT);
+ }
+
+ return errl;
+}
+
// ------------------------------------------------------------------
// ddr4SpecialCases
// ------------------------------------------------------------------
@@ -1260,6 +1336,12 @@ errlHndl_t ddr4SpecialCases(const KeywordData & i_kwdData,
TRACSSCOMP( g_trac_spd, ENTER_MRK"ddr4SpecialCases()" );
+ auto eepromVpd =
+ i_target->getAttr<TARGETING::ATTR_EEPROM_VPD_PRIMARY_INFO>();
+
+ TARGETING::EEPROM_CONTENT_TYPE eepromType =
+ static_cast<TARGETING::EEPROM_CONTENT_TYPE>(eepromVpd.eepromContentType);
+
switch( i_kwdData.keyword )
{
// ==================================================
@@ -1276,12 +1358,14 @@ errlHndl_t ddr4SpecialCases(const KeywordData & i_kwdData,
case RMM_CRC:
case MODSPEC_MM_MFR_ID_CODE:
case LRMM_CRC:
+
// Get MSB
- err = spdFetchData( i_kwdData.offset,
- 1, /* Read 1 byte at a time */
- &tmpBuffer[0],
- i_target,
- i_location );
+ err = fetchDataFromEepromType(i_kwdData.offset,
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[0],
+ i_target,
+ i_location,
+ eepromType);
if( err ) break;
@@ -1293,22 +1377,24 @@ errlHndl_t ddr4SpecialCases(const KeywordData & i_kwdData,
}
// Get LSB
- err = spdFetchData( (i_kwdData.offset - 1),
- 1, /* Read 1 byte at a time */
- &tmpBuffer[1],
- i_target,
- i_location );
+ err = fetchDataFromEepromType((i_kwdData.offset - 1),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[1],
+ i_target,
+ i_location,
+ eepromType);
break;
// ==================================================
// 2 byte - MSB with mask then LSB is 2 more than MSB
case TRC_MIN:
// Get MSB
- err = spdFetchData( i_kwdData.offset,
- 1, /* Read 1 byte at a time */
- &tmpBuffer[0],
- i_target,
- i_location );
+ err = fetchDataFromEepromType(i_kwdData.offset,
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[0],
+ i_target,
+ i_location,
+ eepromType);
if( err ) break;
@@ -1320,49 +1406,54 @@ errlHndl_t ddr4SpecialCases(const KeywordData & i_kwdData,
}
// Get LSB
- err = spdFetchData( (i_kwdData.offset + 2),
- 1, /* Read 1 byte at a time */
- &tmpBuffer[1],
- i_target,
- i_location );
+ err = fetchDataFromEepromType((i_kwdData.offset + 2),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[1],
+ i_target,
+ i_location,
+ eepromType);
break;
// ==================================================
// 4 byte - LSB first, no mask
case CAS_LATENCIES_SUPPORTED_DDR4:
// Get 4th byte
- err = spdFetchData( i_kwdData.offset,
- 1, /* Read 1 byte at a time */
- &tmpBuffer[0],
- i_target,
- i_location );
+ err = fetchDataFromEepromType(i_kwdData.offset,
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[0],
+ i_target,
+ i_location,
+ eepromType);
if( err ) break;
// Get 3rd Byte
- err = spdFetchData( (i_kwdData.offset - 1),
- 1, /* Read 1 byte at a time */
- &tmpBuffer[1],
- i_target,
- i_location );
+ err = fetchDataFromEepromType((i_kwdData.offset - 1),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[1],
+ i_target,
+ i_location,
+ eepromType);
if( err ) break;
// Get 2nd Byte
- err = spdFetchData( (i_kwdData.offset - 2),
- 1, /* Read 1 byte at a time */
- &tmpBuffer[2],
- i_target,
- i_location );
+ err = fetchDataFromEepromType((i_kwdData.offset - 2),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[2],
+ i_target,
+ i_location,
+ eepromType);
if( err ) break;
// Get 1st Byte
- err = spdFetchData( (i_kwdData.offset - 3),
- 1, /* Read 1 byte at a time */
- &tmpBuffer[3],
- i_target,
- i_location );
+ err = fetchDataFromEepromType((i_kwdData.offset - 3),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[3],
+ i_target,
+ i_location,
+ eepromType);
break;
// ==================================================
@@ -1685,12 +1776,6 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData,
do
{
- // If not a Module Specific keyword, skip this logic
- if( NA == i_kwdData.modSpec )
- {
- break;
- }
-
// Check that a Module Specific keyword is being accessed from a DIMM
// of the correct Module Type.
modSpecTypes_t modType = NA;
@@ -1701,263 +1786,43 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData,
break;
}
- // Check Unbuffered Memory Module (UMM)
- if (UMM == modType)
- {
- if ((UMM != i_kwdData.modSpec) &&
- (ALL != i_kwdData.modSpec) )
- {
- TRACFCOMP( g_trac_spd, ERR_MRK"checkModSpecificKeyword: "
- "Keyword (0x%04x) is not valid with UMM modules!",
- i_kwdData.keyword );
- /*@
- * @errortype
- * @reasoncode VPD::VPD_MOD_SPECIFIC_MISMATCH_UMM
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD
- * @userdata1[0:31] Module Type (byte 3[3:0])
- * @userdata1[32:63] Memory Type (byte 2)
- * @userdata2[0:31] SPD Keyword
- * @userdata2[32:63] Module Specific flag
- * @devdesc Keyword requested was not UMM Module
- * specific.
- * @custdesc A problem occurred during the IPL
- * of the system.
- */
- err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
- VPD::VPD_MOD_SPECIFIC_MISMATCH_UMM,
- TWO_UINT32_TO_UINT64( modType, i_memType ),
- TWO_UINT32_TO_UINT64( i_kwdData.keyword,
- i_kwdData.modSpec ) );
-
- // HB code asked for an unsupprted keyword for this Module
- err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
-
- // Or user could have installed a bad/unsupported dimm
- err->addHwCallout( i_target,
- HWAS::SRCI_PRIORITY_LOW,
- HWAS::DECONFIG,
- HWAS::GARD_NULL );
-
- err->collectTrace( "SPD", 256);
-
- break;
- }
- }
- // Check Registered Memory Module (RMM)
- else if (RMM == modType)
- {
- if ((RMM != i_kwdData.modSpec) &&
- (ALL != i_kwdData.modSpec) )
- {
- TRACFCOMP( g_trac_spd, ERR_MRK"checkModSpecificKeyword: "
- "Keyword (0x%04x) is not valid with RMM modules!",
- i_kwdData.keyword );
- /*@
- * @errortype
- * @reasoncode VPD::VPD_MOD_SPECIFIC_MISMATCH_RMM
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD
- * @userdata1[0:31] Module Type (byte 3[3:0])
- * @userdata1[32:63] Memory Type (byte 2)
- * @userdata2[0:31] SPD Keyword
- * @userdata2[32:63] Module Specific flag
- * @devdesc Keyword requested was not RMM Module
- * specific.
- * @custdesc A problem occurred during the IPL
- * of the system.
- */
- err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
- VPD::VPD_MOD_SPECIFIC_MISMATCH_RMM,
- TWO_UINT32_TO_UINT64( modType, i_memType ),
- TWO_UINT32_TO_UINT64( i_kwdData.keyword,
- i_kwdData.modSpec ) );
-
- // HB code asked for an unsupprted keyword for this Module
- err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
-
- // Or user could have installed a bad/unsupported dimm
- err->addHwCallout( i_target,
- HWAS::SRCI_PRIORITY_LOW,
- HWAS::DECONFIG,
- HWAS::GARD_NULL );
-
- err->collectTrace( "SPD", 256);
-
- break;
- }
- }
- // Check Clocked Memory Module (CMM)
- else if (CMM == modType)
- {
- if ((CMM != i_kwdData.modSpec) &&
- (ALL != i_kwdData.modSpec) )
- {
- TRACFCOMP( g_trac_spd, ERR_MRK"checkModSpecificKeyword: "
- "Keyword (0x%04x) is not valid with CMM modules!",
- i_kwdData.keyword );
- /*@
- * @errortype
- * @reasoncode VPD::VPD_MOD_SPECIFIC_MISMATCH_CMM
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD
- * @userdata1[0:31] Module Type (byte 3[3:0])
- * @userdata1[32:63] Memory Type (byte 2)
- * @userdata2[0:31] SPD Keyword
- * @userdata2[32:63] Module Specific flag
- * @devdesc Keyword requested was not CMM Module
- * specific.
- * @custdesc A problem occurred during the IPL
- * of the system.
- */
- err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
- VPD::VPD_MOD_SPECIFIC_MISMATCH_CMM,
- TWO_UINT32_TO_UINT64( modType, i_memType ),
- TWO_UINT32_TO_UINT64( i_kwdData.keyword,
- i_kwdData.modSpec ) );
-
- // HB code asked for an unsupprted keyword for this Module
- err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
-
- // Or user could have installed a bad/unsupported dimm
- err->addHwCallout( i_target,
- HWAS::SRCI_PRIORITY_LOW,
- HWAS::DECONFIG,
- HWAS::GARD_NULL );
-
- err->collectTrace( "SPD", 256);
-
- break;
- }
- }
- // Check Load Reduction Memory Module (LRMM)
- else if (LRMM == modType)
- {
- if ((LRMM != i_kwdData.modSpec) &&
- (ALL != i_kwdData.modSpec) )
- {
- TRACFCOMP( g_trac_spd, ERR_MRK"checkModSpecificKeyword: "
- "Keyword (0x%04x) is not valid with LRMM modules!",
- i_kwdData.keyword );
- /*@
- * @errortype
- * @reasoncode VPD::VPD_MOD_SPECIFIC_MISMATCH_LRMM
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD
- * @userdata1[0:31] Module Type (byte 3[3:0])
- * @userdata1[32:63] Memory Type (byte 2)
- * @userdata2[0:31] SPD Keyword
- * @userdata2[32:63] Module Specific flag
- * @devdesc Keyword requested was not LRMM Module
- * specific.
- * @custdesc A problem occurred during the IPL
- * of the system.
- */
- err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
- VPD::VPD_MOD_SPECIFIC_MISMATCH_LRMM,
- TWO_UINT32_TO_UINT64( modType, i_memType ),
- TWO_UINT32_TO_UINT64( i_kwdData.keyword,
- i_kwdData.modSpec ) );
-
- // HB code asked for an unsupprted keyword for this Module
- err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
-
- // Or user could have installed a bad/unsupported dimm
- err->addHwCallout( i_target,
- HWAS::SRCI_PRIORITY_LOW,
- HWAS::DECONFIG,
- HWAS::GARD_NULL );
-
- err->collectTrace( "SPD", 256);
-
- break;
- }
- }
- else if(DDIMM == modType)
- {
- if ((DDIMM != i_kwdData.modSpec) &&
- (ALL != i_kwdData.modSpec) )
- {
- TRACFCOMP( g_trac_spd, ERR_MRK"checkModSpecificKeyword: "
- "Keyword (0x%04x) is not valid with DDIMM modules!",
- i_kwdData.keyword );
- /*@
- * @errortype
- * @reasoncode VPD::VPD_MOD_SPECIFIC_MISMATCH_DDIMM
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD
- * @userdata1[0:31] Module Type (byte 3[3:0])
- * @userdata1[32:63] Memory Type (byte 2)
- * @userdata2[0:31] SPD Keyword
- * @userdata2[32:63] Module Specific flag
- * @devdesc Keyword requested was not LRMM Module
- * specific.
- * @custdesc A problem occurred during the IPL
- * of the system.
- */
- err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
- VPD::VPD_MOD_SPECIFIC_MISMATCH_DDIMM,
- TWO_UINT32_TO_UINT64( modType, i_memType ),
- TWO_UINT32_TO_UINT64( i_kwdData.keyword,
- i_kwdData.modSpec ) );
-
- // HB code asked for an unsupprted keyword for this Module
- err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
-
- // Or user could have installed a bad/unsupported dimm
- err->addHwCallout( i_target,
- HWAS::SRCI_PRIORITY_LOW,
- HWAS::DECONFIG,
- HWAS::GARD_NULL );
-
- err->collectTrace( "SPD", 256);
-
- break;
- }
- }
- else
+ if (!(modType & i_kwdData.modSpec))
{
TRACFCOMP( g_trac_spd, ERR_MRK"checkModSpecificKeyword: "
"Module specific keyword could not be matched with an "
"appropriate scenario!" );
+
TRACFCOMP( g_trac_spd, ERR_MRK
" Mem Type: 0x%04x, Mod Type: 0x%04x, Keyword: 0x%04x",
i_memType,
modType,
i_kwdData.keyword );
+
+ uint32_t udUpper32 = TWO_UINT16_TO_UINT32(modType, i_memType);
+ uint32_t udLower32 = TWO_UINT16_TO_UINT32(i_kwdData.keyword,
+ i_kwdData.modSpec);
+ uint64_t userdata1 = TWO_UINT32_TO_UINT64(udUpper32, udLower32);
+
/*@
* @errortype
- * @reasoncode VPD::VPD_MOD_SPECIFIC_UNSUPPORTED
* @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
* @moduleid VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD
- * @userdata1 Module Type
- * @userdata2 Memory Type (byte 2)
+ * @reasoncode VPD::VPD_MOD_SPECIFIC_UNSUPPORTED
+ * @userdata1[00:15] Memory Module Type
+ * @userdata1[16:31] Memory Type (byte 2)
+ * @userdata1[32:47] SPD Keyword
+ * @userdata1[48:63] Module Specific Flag
+ * @userdata2 Target HUID
* @devdesc Unsupported Module Type.
* @custdesc A problem occurred during the IPL
* of the system.
*/
err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
- VPD::VPD_MOD_SPECIFIC_UNSUPPORTED,
- TWO_UINT32_TO_UINT64( modType, i_memType ),
- TWO_UINT32_TO_UINT64( i_kwdData.keyword,
- i_kwdData.modSpec ) );
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
+ VPD::VPD_MOD_SPECIFIC_UNSUPPORTED,
+ userdata1,
+ TARGETING::get_huid(i_target));
// HB code asked for an unsupprted keyword for this Module
err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
@@ -1987,9 +1852,10 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData,
// ------------------------------------------------------------------
// getMemType
// ------------------------------------------------------------------
-errlHndl_t getMemType ( uint8_t & o_memType,
- TARGETING::Target * i_target,
- VPD::vpdCmdTarget i_location )
+errlHndl_t getMemType(uint8_t & o_memType,
+ TARGETING::Target * i_target,
+ VPD::vpdCmdTarget i_location,
+ EEPROM::EEPROM_SOURCE i_eepromSource)
{
errlHndl_t err{nullptr};
@@ -1997,7 +1863,8 @@ errlHndl_t getMemType ( uint8_t & o_memType,
MEM_TYPE_SZ,
&o_memType,
i_target,
- i_location );
+ i_location,
+ i_eepromSource);
TRACUCOMP( g_trac_spd,
EXIT_MRK"SPD::getMemType() - MemType: 0x%02x, Error: %s",
@@ -2007,6 +1874,57 @@ errlHndl_t getMemType ( uint8_t & o_memType,
return err;
}
+
+errlHndl_t getMemType(uint8_t & o_memType,
+ TARGETING::Target * i_target,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType,
+ EEPROM::EEPROM_SOURCE i_eepromSource)
+{
+ errlHndl_t err = nullptr;
+
+// @TODO RTC 204341 Implement for runtime
+#ifndef __HOSTBOOT_RUNTIME
+
+ if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_ISDIMM)
+ {
+ err = getMemType(o_memType,
+ i_target,
+ VPD::AUTOSELECT,
+ i_eepromSource);
+ }
+ else if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_DDIMM)
+ {
+ err = getMemType(o_memType,
+ i_target,
+ i_eepromSource);
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_GET_MEMTYPE
+ * @reasoncode VPD::VPD_INVALID_EEPROM_CONTENT_TYPE
+ * @userdata1 Eeprom Content Type Given
+ * @userdata2 Target HUID
+ * @devdesc An unsupported eeprom content type was supplied.
+ * @custdesc A problem occurred during the IPL
+ * of the system.
+ */
+ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_GET_MEMTYPE,
+ VPD::VPD_INVALID_EEPROM_CONTENT_TYPE,
+ i_eepromType,
+ TARGETING::get_huid(i_target),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ }
+
+#endif
+
+ return err;
+
+}
+
// ------------------------------------------------------------------
// getModType
// ------------------------------------------------------------------
@@ -2018,12 +1936,19 @@ errlHndl_t getModType ( modSpecTypes_t & o_modType,
errlHndl_t err{nullptr};
o_modType = NA;
+ auto eepromVpd =
+ i_target->getAttr<TARGETING::ATTR_EEPROM_VPD_PRIMARY_INFO>();
+
+ TARGETING::EEPROM_CONTENT_TYPE eepromType =
+ static_cast<TARGETING::EEPROM_CONTENT_TYPE>(eepromVpd.eepromContentType);
+
uint8_t modTypeVal = 0;
- err = spdFetchData( MOD_TYPE_ADDR,
- MOD_TYPE_SZ,
- &modTypeVal,
- i_target,
- i_location );
+ err = fetchDataFromEepromType(MOD_TYPE_ADDR,
+ MOD_TYPE_SZ,
+ &modTypeVal,
+ i_target,
+ i_location,
+ eepromType);
if (err)
{
@@ -2145,8 +2070,18 @@ errlHndl_t getKeywordEntry ( VPD::vpdKeyword i_keyword,
}
else if ( SPD_DDR4_TYPE == i_memType )
{
- arraySize = (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
- kwdData = ddr4Data;
+ modSpecTypes_t modType = NA;
+ err = getModType(modType, i_target, i_memType, VPD::AUTOSELECT);
+ if (modType == DDIMM)
+ {
+ arraySize = (sizeof(ddr4DDIMMData)/sizeof(ddr4DDIMMData[0]));
+ kwdData = ddr4DDIMMData;
+ }
+ else
+ {
+ arraySize = (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+ kwdData = ddr4Data;
+ }
}
else
{
@@ -2354,6 +2289,214 @@ void setPartAndSerialNumberAttributes( TARGETING::Target * i_target )
TRACSSCOMP(g_trac_spd, EXIT_MRK"spd.C::setPartAndSerialNumberAttributes()");
}
+/*
+ * @brief Read keyword from SPD by determining which function to call based on
+ * eeprom content type.
+ *
+ * @param[in] i_target target to read data from
+ * @param[in] i_eepromType Eeprom content type of the target.
+ * @param[in] i_keyword keyword from spdenums.H to read
+ * @param[in] i_memType The memory type of this target.
+ * @param[in/out] io_buffer data buffer SPD will be written to
+ * @param[in/out] io_buflen length of the given data buffer
+ * @param[in] i_eepromSource The EEPROM source (CACHE/HARDWARE).
+ *
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, error log.
+ */
+errlHndl_t readFromEepromSource(TARGETING::Target* i_target,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType,
+ const VPD::vpdKeyword i_keyword,
+ const uint8_t i_memType,
+ void* io_buffer,
+ size_t& io_buflen,
+ EEPROM::EEPROM_SOURCE i_eepromSource)
+{
+ errlHndl_t err = nullptr;
+
+ TRACSSCOMP(g_trac_spd, ENTER_MRK
+ "readFromEepromSource: i_eepromSource %d , i_memType %d, i_eepromType %d",
+ i_eepromSource, i_memType, i_eepromType);
+
+// @TODO RTC 204341 Implement for runtime
+#ifndef __HOSTBOOT_RUNTIME
+ if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_ISDIMM)
+ {
+ err = spdGetValue(i_keyword,
+ io_buffer,
+ io_buflen,
+ i_target,
+ i_memType,
+ VPD::SEEPROM,
+ i_eepromSource);
+ }
+ else if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_DDIMM)
+ {
+ err = ocmbGetSPD(i_target,
+ io_buffer,
+ io_buflen,
+ i_keyword,
+ i_memType,
+ i_eepromSource);
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_READ_FROM_EEPROM_SOURCE
+ * @reasoncode VPD::VPD_INVALID_EEPROM_CONTENT_TYPE
+ * @userdata1 Eeprom Content Type Given
+ * @userdata2 Target HUID
+ * @devdesc An unsupported eeprom content type was supplied.
+ * @custdesc A problem occurred during the IPL
+ * of the system.
+ */
+ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_READ_FROM_EEPROM_SOURCE,
+ VPD::VPD_INVALID_EEPROM_CONTENT_TYPE,
+ i_eepromType,
+ TARGETING::get_huid(i_target),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ }
+#endif
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
+// cmpEecacheToEeprom
+// ------------------------------------------------------------------
+errlHndl_t cmpEecacheToEeprom(TARGETING::Target * i_target,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType,
+ VPD::vpdKeyword i_keyword,
+ bool &o_match)
+{
+ errlHndl_t err = nullptr;
+
+ TRACSSCOMP(g_trac_spd, ENTER_MRK"cmpEecacheToEeprom()");
+
+ o_match = false;
+ do
+ {
+ // Read the Basic Memory Type from the Eeprom Cache
+ uint8_t memTypeCache(MEM_TYPE_INVALID);
+ err = getMemType(memTypeCache,
+ i_target,
+ i_eepromType,
+ EEPROM::CACHE);
+ if (err)
+ {
+ break;
+ }
+
+ if (!isValidDimmType(memTypeCache, i_eepromType))
+ {
+ TRACFCOMP(g_trac_spd, ERR_MRK
+ "cmpEecacheToEeprom() Invalid DIMM type found in cache copy of eeprom,"
+ " we will not be able to understand contents");
+ break;
+ }
+
+ // Read the Basic Memory Type from HARDWARE
+ uint8_t memTypeHardware(MEM_TYPE_INVALID);
+ err = getMemType(memTypeHardware,
+ i_target,
+ i_eepromType,
+ EEPROM::HARDWARE);
+ if (err)
+ {
+ break;
+ }
+
+ if (!isValidDimmType(memTypeHardware, i_eepromType))
+ {
+ // Leave o_match == false and exit.
+ TRACFCOMP(g_trac_spd, ERR_MRK"cmpEecacheToEeprom() Invalid DIMM type found in hw copy of eeprom");
+ break;
+ }
+
+ if (memTypeCache != memTypeHardware)
+ {
+ // CACHE and HARDWARE don't match.
+ // Leave o_match == false and exit.
+ break;
+ }
+
+ // Get the keyword size
+ const KeywordData* entry = nullptr;
+ err = getKeywordEntry(i_keyword,
+ memTypeHardware,
+ i_target,
+ entry);
+ if (err)
+ {
+ break;
+ }
+ size_t dataSize = entry->length;
+
+
+ // Read the keyword from HARDWARE
+ size_t sizeHardware = dataSize;
+ uint8_t dataHardware[sizeHardware];
+ err = readFromEepromSource(i_target,
+ i_eepromType,
+ i_keyword,
+ memTypeHardware,
+ dataHardware,
+ sizeHardware,
+ EEPROM::HARDWARE);
+ if (err)
+ {
+ break;
+ }
+
+ // Read the keyword from CACHE
+ size_t sizeCache = dataSize;
+ uint8_t dataCache[sizeCache];
+ err = readFromEepromSource(i_target,
+ i_eepromType,
+ i_keyword,
+ memTypeHardware,
+ dataCache,
+ sizeCache,
+ EEPROM::CACHE);
+ if (err)
+ {
+ // CACHE may not be loaded, ignore the error
+ delete err;
+ err = NULL;
+ break;
+ }
+
+ // Compare the HARDWARE/CACHE keyword size/data
+ if (sizeHardware != sizeCache)
+ {
+ // CACHE and HARDWARE don't match.
+ // Leave o_match == false and exit.
+ break;
+ }
+ if (memcmp(dataHardware, dataCache, sizeHardware))
+ {
+ // CACHE and HARDWARE don't match.
+ // Leave o_match == false and exit.
+ break;
+ }
+
+ o_match = true;
+
+ } while(0);
+
+ TRACDBIN(g_trac_spd, "Hardware data : ", dataHardware, sizeHardware);
+ TRACDBIN(g_trac_spd, "Cache data : ", dataCache, sizeCache);
+
+ TRACSSCOMP( g_trac_spd, EXIT_MRK"cmpEecacheToEeprom(): returning %s errors. o_match = 0x%X ",
+ (err ? "with" : "with no"), o_match );
+
+ return err;
+ }
+
// ------------------------------------------------------------------
// cmpPnorToSeeprom
// ------------------------------------------------------------------
@@ -2368,17 +2511,37 @@ errlHndl_t cmpPnorToSeeprom ( TARGETING::Target * i_target,
o_match = false;
do
{
- // Read the Basic Memory Type
- uint8_t memType(MEM_TYPE_INVALID);
- err = getMemType( memType,
+ // Read the Basic Memory Type from the Seeprom
+ uint8_t memTypeSeeprom(MEM_TYPE_INVALID);
+ err = getMemType( memTypeSeeprom,
i_target,
- VPD::AUTOSELECT );
+ VPD::SEEPROM );
if( err )
{
break;
}
- if( false == isValidDimmType(memType) )
+ if( false == isValidDimmType(memTypeSeeprom) )
+ {
+ break;
+ }
+
+ // Read the Basic Memory Type from PNOR
+ uint8_t memTypePnor(MEM_TYPE_INVALID);
+ err = getMemType( memTypePnor,
+ i_target,
+ VPD::PNOR );
+ if( err )
+ {
+ break;
+ }
+
+ if( false == isValidDimmType(memTypePnor) )
+ {
+ break;
+ }
+
+ if (memTypeSeeprom != memTypePnor)
{
break;
}
@@ -2386,7 +2549,7 @@ errlHndl_t cmpPnorToSeeprom ( TARGETING::Target * i_target,
// Get the keyword size
const KeywordData* entry = NULL;
err = getKeywordEntry( i_keyword,
- memType,
+ memTypePnor,
i_target,
entry );
if( err )
@@ -2403,7 +2566,7 @@ errlHndl_t cmpPnorToSeeprom ( TARGETING::Target * i_target,
dataPnor,
sizePnor,
i_target,
- memType,
+ memTypePnor,
VPD::PNOR );
if( err )
{
@@ -2420,7 +2583,7 @@ errlHndl_t cmpPnorToSeeprom ( TARGETING::Target * i_target,
dataSeeprom,
sizeSeeprom,
i_target,
- memType,
+ memTypePnor,
VPD::SEEPROM );
if( err )
{
diff --git a/src/usr/vpd/spd.H b/src/usr/vpd/spd.H
index edf7d74c7..f0e1a157b 100755
--- a/src/usr/vpd/spd.H
+++ b/src/usr/vpd/spd.H
@@ -39,6 +39,8 @@
#include <errl/errlentry.H>
#include <vpd/spdenums.H>
#include "vpd.H"
+#include <attributeenums.H>
+#include <i2c/eeprom_const.H>
namespace SPD
{
@@ -94,13 +96,13 @@ enum
*/
typedef enum
{
- NA = 0x00,
- UMM = 0x01, // Unbuffered Memory Modules
- RMM = 0x02, // Registered Memory Modules
- CMM = 0x04, // Clocked Memory Modules
- LRMM = 0x08, // Load Reduction Memory Modules
- DDIMM = 0x0A,
- ALL = 0xFFFF,
+ NA = 0x00, // Invalid Type
+ UMM = 0x01, // Unbuffered Memory Modules
+ RMM = 0x02, // Registered Memory Modules
+ CMM = 0x04, // Clocked Memory Modules
+ LRMM = 0x08, // Load Reduction Memory Modules
+ DDIMM = 0x10, // Differential DIMM
+ ALL = 0xFFFF,
} modSpecTypes_t;
@@ -202,14 +204,19 @@ errlHndl_t spdWriteKeywordValue ( DeviceFW::OperationType i_opType,
*
* @param[in] i_location - The SPD source (PNOR/SEEPROM).
*
+ * @param[in] i_eepromSource Eeprom source (CACHE/HARDWARE).
+ * Default AUTOSELECT
+ *
* @return errlHndl_t - NULL if successful, otherwise a pointer to the
* error log.
*/
-errlHndl_t spdFetchData ( uint64_t i_byteAddr,
- size_t i_numBytes,
- void * o_data,
- TARGETING::Target * i_target,
- VPD::vpdCmdTarget i_location );
+errlHndl_t spdFetchData(uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * o_data,
+ TARGETING::Target * i_target,
+ VPD::vpdCmdTarget i_location,
+ EEPROM::EEPROM_SOURCE i_eepromSource = EEPROM::AUTOSELECT
+ );
/**
* @brief This function is a wrapper for writing the correct keyword.
@@ -254,15 +261,20 @@ errlHndl_t spdWriteData ( uint64_t i_offset,
*
* @param[in] i_location - The SPD source (PNOR/SEEPROM).
*
+ * @param[in] i_eepromSource The eeprom source (CACHE/HARDWARE).
+ * Default AUTOSELECT
+ *
* @return errlHndl_t - NULL if successful, otherwise a pointer to the
* error log.
*/
-errlHndl_t spdGetValue ( VPD::vpdKeyword i_keyword,
- void * io_buffer,
- size_t & io_buflen,
- TARGETING::Target * i_target,
- uint64_t i_DDRRev,
- VPD::vpdCmdTarget i_location );
+errlHndl_t spdGetValue(VPD::vpdKeyword i_keyword,
+ void * io_buffer,
+ size_t & io_buflen,
+ TARGETING::Target * i_target,
+ uint64_t i_DDRRev,
+ VPD::vpdCmdTarget i_location,
+ EEPROM::EEPROM_SOURCE i_eepromSource = EEPROM::AUTOSELECT
+ );
/**
@@ -392,6 +404,45 @@ errlHndl_t dimmPresenceDetect( DeviceFW::OperationType i_opType,
int64_t i_accessType,
va_list i_args );
+
+/**
+ * @brief This function will read the DIMM module type.
+ *
+ * @param[out] o_modType - The module type value to return.
+ *
+ * @param[in] i_target - The target to read data from.
+ *
+ * @param[in] i_memType - The memory type
+ *
+ * @param[in] i_location - The SPD source (PNOR/SEEPROM).
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer
+ * to the error log.
+ */
+errlHndl_t getModType ( modSpecTypes_t & o_modType,
+ TARGETING::Target * i_target,
+ uint64_t i_memType,
+ VPD::vpdCmdTarget i_location );
+
+/**
+ * @brief This function will scan the table and return the entry
+ * corresponding to the keyword being requested.
+ *
+ * @param[in] i_keyword - The keyword being requested.
+ *
+ * @param[in] i_memType - The memory type of the target.
+ *
+ * @param[in] i_target - Target (only used for callouts)
+ *
+ * @param[out] o_entry - The table entry corresponding to the keyword.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t getKeywordEntry(VPD::vpdKeyword i_keyword,
+ uint64_t i_memType,
+ TARGETING::Target* i_target,
+ const KeywordData* &o_entry );
/**
* @brief This function is used to check the parameters in the SPD data that
* indicate which module specific keywords are valid, and then check that
@@ -457,6 +508,26 @@ errlHndl_t cmpPnorToSeeprom( TARGETING::Target * i_target,
bool &o_match );
/**
+ * @brief This function compares value of the keyword in CACHE/HARDWARE
+ * and returns the result
+ *
+ * @param[in] i_target - Target device
+ *
+ * @param[in] i_eepromType - Eeprom content type of target device
+ *
+ * @param [in] i_keyword - Keyword to compare
+ *
+ * @param [in] o_match - Result of keyword compare
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to the
+ * error log. A mismatch will not return an error.
+ */
+errlHndl_t cmpEecacheToEeprom(TARGETING::Target * i_target,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType,
+ VPD::vpdKeyword i_keyword,
+ bool& o_match);
+
+/**
* @brief This function loads the SPD data from the SEEPROM into the PNOR cache
*
* @param[in] i_target - Target device
diff --git a/src/usr/vpd/spdDDR3.H b/src/usr/vpd/spdDDR3.H
index 06fc33aa5..26aa36660 100644
--- a/src/usr/vpd/spdDDR3.H
+++ b/src/usr/vpd/spdDDR3.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2015 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -68,74 +68,74 @@ const KeywordData ddr3Data[] =
// Number Case able Spec
// ------------------------------------------------------------------------------------------
// Normal fields supported on both DDR3 and DDR4
- { CRC_EXCLUDE, 0x00, 0x01, 0x80, 0x07, false, false, NA },
- { SPD_BYTES_TOTAL, 0x00, 0x01, 0x70, 0x04, false, false, NA },
- { SPD_BYTES_USED, 0x00, 0x01, 0x0F, 0x00, false, false, NA },
- { SPD_MAJOR_REVISION, 0x01, 0x01, 0xF0, 0x04, false, false, NA },
- { SPD_MINOR_REVISION, 0x01, 0x01, 0x0F, 0x00, false, false, NA },
- { BASIC_MEMORY_TYPE, 0x02, 0x01, 0x00, 0x00, false, false, NA },
- { CUSTOM, 0x03, 0x01, 0x80, 0x07, false, false, NA },
- { MODULE_TYPE, 0x03, 0x01, 0x0F, 0x00, false, false, NA },
- { DENSITY, 0x04, 0x01, 0x0F, 0x00, false, false, NA },
- { ROW_ADDRESS, 0x05, 0x01, 0x38, 0x03, false, false, NA },
- { COL_ADDRESS, 0x05, 0x01, 0x07, 0x00, false, false, NA },
- { MODULE_RANKS, 0x07, 0x01, 0x38, 0x03, false, false, NA },
- { MODULE_DRAM_WIDTH, 0x07, 0x01, 0x07, 0x00, false, false, NA },
- { MODULE_MEMORY_BUS_WIDTH, 0x08, 0x01, 0x1f, 0x00, false, false, NA },
- { MODULE_MEMORY_BUS_WIDTH_EXT, 0x08, 0x01, 0x18, 0x03, false, false, NA },
- { MODULE_MEMORY_BUS_WIDTH_PRI, 0x08, 0x01, 0x07, 0x00, false, false, NA },
- { TCK_MIN, 0x0c, 0x01, 0x00, 0x00, false, false, NA },
- { MIN_CAS_LATENCY, 0x10, 0x01, 0x00, 0x00, false, false, NA },
- { TRCD_MIN, 0x12, 0x01, 0x00, 0x00, false, false, NA },
- { TRP_MIN, 0x14, 0x01, 0x00, 0x00, false, false, NA },
- { TRC_MIN, 0x15, 0x02, 0xF0, 0x04, true, false, NA },
- { TRAS_MIN, 0x15, 0x02, 0x0F, 0x00, false, false, NA },
- { TFAW_MIN, 0x1c, 0x02, 0x0F, 0x00, false, false, NA },
- { SDRAM_OPTIONAL_FEATURES, 0x1e, 0x01, 0x00, 0x00, false, false, NA },
- { SDRAM_THERMAL_REFRESH_OPTIONS, 0x1f, 0x01, 0x00, 0x00, false, false, NA },
- { MODULE_THERMAL_SENSOR, 0x20, 0x01, 0x00, 0x00, false, false, NA },
- { THERMAL_SENSOR_PRESENT, 0x20, 0x01, 0x80, 0x07, false, false, NA },
- { THERMAL_SENSOR_ACCURACY, 0x20, 0x01, 0x7F, 0x00, false, false, NA },
- { SDRAM_DEVICE_TYPE, 0x21, 0x01, 0x80, 0x07, false, false, NA },
- { SDRAM_DIE_COUNT, 0x21, 0x01, 0x70, 0x04, false, false, NA },
- { SDRAM_DEVICE_TYPE_SIGNAL_LOADING, 0x21, 0x01, 0x03, 0x00, false, false, NA },
- { TCKMIN_FINE_OFFSET, 0x22, 0x01, 0x00, 0x00, false, false, NA },
- { TAAMIN_FINE_OFFSET, 0x23, 0x01, 0x00, 0x00, false, false, NA },
- { TRCDMIN_FINE_OFFSET, 0x24, 0x01, 0x00, 0x00, false, false, NA },
- { TRPMIN_FINE_OFFSET, 0x25, 0x01, 0x00, 0x00, false, false, NA },
- { TRCMIN_FINE_OFFSET, 0x26, 0x01, 0x00, 0x00, false, false, NA },
- { MODULE_TYPE_SPECIFIC_SECTION, 0x3c, 0x39, 0x00, 0x00, false, false, NA },
- { MODULE_MANUFACTURER_ID, 0x76, 0x02, 0x00, 0x00, true, false, NA },
- { MODULE_MANUFACTURING_LOCATION, 0x77, 0x01, 0x00, 0x00, false, false, NA },
- { MODULE_MANUFACTURING_DATE, 0x78, 0x02, 0x00, 0x00, false, false, NA },
- { MODULE_SERIAL_NUMBER, 0x7a, 0x04, 0x00, 0x00, false, false, NA },
- { MODULE_PART_NUMBER, 0x80, 0x12, 0x00, 0x00, false, false, NA },
- { DRAM_MANUFACTURER_ID, 0x95, 0x02, 0x00, 0x00, true, false, NA },
- { MANUFACTURER_SPECIFIC_DATA, 0x96, 0x1a, 0x00, 0x00, false, false, NA },
- { DIMM_BAD_DQ_DATA, 0xb0, 0x50, 0x00, 0x00, false, true, NA },
+ { CRC_EXCLUDE, 0x00, 0x01, 0x80, 0x07, false, false, ALL },
+ { SPD_BYTES_TOTAL, 0x00, 0x01, 0x70, 0x04, false, false, ALL },
+ { SPD_BYTES_USED, 0x00, 0x01, 0x0F, 0x00, false, false, ALL },
+ { SPD_MAJOR_REVISION, 0x01, 0x01, 0xF0, 0x04, false, false, ALL },
+ { SPD_MINOR_REVISION, 0x01, 0x01, 0x0F, 0x00, false, false, ALL },
+ { BASIC_MEMORY_TYPE, 0x02, 0x01, 0x00, 0x00, false, false, ALL },
+ { CUSTOM, 0x03, 0x01, 0x80, 0x07, false, false, ALL },
+ { MODULE_TYPE, 0x03, 0x01, 0x0F, 0x00, false, false, ALL },
+ { DENSITY, 0x04, 0x01, 0x0F, 0x00, false, false, ALL },
+ { ROW_ADDRESS, 0x05, 0x01, 0x38, 0x03, false, false, ALL },
+ { COL_ADDRESS, 0x05, 0x01, 0x07, 0x00, false, false, ALL },
+ { MODULE_RANKS, 0x07, 0x01, 0x38, 0x03, false, false, ALL },
+ { MODULE_DRAM_WIDTH, 0x07, 0x01, 0x07, 0x00, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH, 0x08, 0x01, 0x1f, 0x00, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH_EXT, 0x08, 0x01, 0x18, 0x03, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH_PRI, 0x08, 0x01, 0x07, 0x00, false, false, ALL },
+ { TCK_MIN, 0x0c, 0x01, 0x00, 0x00, false, false, ALL },
+ { MIN_CAS_LATENCY, 0x10, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCD_MIN, 0x12, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRP_MIN, 0x14, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRC_MIN, 0x15, 0x02, 0xF0, 0x04, true, false, ALL },
+ { TRAS_MIN, 0x15, 0x02, 0x0F, 0x00, false, false, ALL },
+ { TFAW_MIN, 0x1c, 0x02, 0x0F, 0x00, false, false, ALL },
+ { SDRAM_OPTIONAL_FEATURES, 0x1e, 0x01, 0x00, 0x00, false, false, ALL },
+ { SDRAM_THERMAL_REFRESH_OPTIONS, 0x1f, 0x01, 0x00, 0x00, false, false, ALL },
+ { MODULE_THERMAL_SENSOR, 0x20, 0x01, 0x00, 0x00, false, false, ALL },
+ { THERMAL_SENSOR_PRESENT, 0x20, 0x01, 0x80, 0x07, false, false, ALL },
+ { THERMAL_SENSOR_ACCURACY, 0x20, 0x01, 0x7F, 0x00, false, false, ALL },
+ { SDRAM_DEVICE_TYPE, 0x21, 0x01, 0x80, 0x07, false, false, ALL },
+ { SDRAM_DIE_COUNT, 0x21, 0x01, 0x70, 0x04, false, false, ALL },
+ { SDRAM_DEVICE_TYPE_SIGNAL_LOADING, 0x21, 0x01, 0x03, 0x00, false, false, ALL },
+ { TCKMIN_FINE_OFFSET, 0x22, 0x01, 0x00, 0x00, false, false, ALL },
+ { TAAMIN_FINE_OFFSET, 0x23, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCDMIN_FINE_OFFSET, 0x24, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRPMIN_FINE_OFFSET, 0x25, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCMIN_FINE_OFFSET, 0x26, 0x01, 0x00, 0x00, false, false, ALL },
+ { MODULE_TYPE_SPECIFIC_SECTION, 0x3c, 0x39, 0x00, 0x00, false, false, ALL },
+ { MODULE_MANUFACTURER_ID, 0x76, 0x02, 0x00, 0x00, true, false, ALL },
+ { MODULE_MANUFACTURING_LOCATION, 0x77, 0x01, 0x00, 0x00, false, false, ALL },
+ { MODULE_MANUFACTURING_DATE, 0x78, 0x02, 0x00, 0x00, false, false, ALL },
+ { MODULE_SERIAL_NUMBER, 0x7a, 0x04, 0x00, 0x00, false, false, ALL },
+ { MODULE_PART_NUMBER, 0x80, 0x12, 0x00, 0x00, false, false, ALL },
+ { DRAM_MANUFACTURER_ID, 0x95, 0x02, 0x00, 0x00, true, false, ALL },
+ { MANUFACTURER_SPECIFIC_DATA, 0x96, 0x1a, 0x00, 0x00, false, false, ALL },
+ { DIMM_BAD_DQ_DATA, 0xb0, 0x50, 0x00, 0x00, false, true, ALL },
// Normal fields supported on DDR3 only
- { BANK_ADDRESS_BITS, 0x04, 0x01, 0x70, 0x04, false, false, NA },
- { MODULE_NOMINAL_VOLTAGE, 0x06, 0x01, 0x07, 0x00, false, false, NA },
- { FTB_DIVIDEND, 0x09, 0x01, 0xF0, 0x04, false, false, NA },
- { FTB_DIVISOR, 0x09, 0x01, 0x0F, 0x00, false, false, NA },
- { MTB_DIVIDEND, 0x0a, 0x01, 0x00, 0x00, false, false, NA },
- { MTB_DIVISOR, 0x0b, 0x01, 0x00, 0x00, false, false, NA },
- { CAS_LATENCIES_SUPPORTED, 0x0f, 0x02, 0x7F, 0x00, true, false, NA },
- { TWR_MIN, 0x11, 0x01, 0x00, 0x00, false, false, NA },
- { TRRD_MIN, 0x13, 0x01, 0x00, 0x00, false, false, NA },
- { TRFC_MIN, 0x19, 0x02, 0x00, 0x00, true, false, NA },
- { TWTR_MIN, 0x1a, 0x01, 0x00, 0x00, false, false, NA },
- { TRTP_MIN, 0x1b, 0x01, 0x00, 0x00, false, false, NA },
- { DLL_OFF, 0x1e, 0x01, 0x80, 0x07, false, false, NA },
- { RZQ_7, 0x1e, 0x01, 0x02, 0x01, false, false, NA },
- { RZQ_6, 0x1e, 0x01, 0x01, 0x00, false, false, NA },
- { PASR, 0x1f, 0x01, 0x80, 0x07, false, false, NA },
- { ODTS, 0x1f, 0x01, 0x08, 0x03, false, false, NA },
- { ASR, 0x1f, 0x01, 0x04, 0x02, false, false, NA },
- { ETR_1X, 0x1f, 0x01, 0x02, 0x01, false, false, NA },
- { ETR, 0x1f, 0x01, 0x01, 0x00, false, false, NA },
- { MODULE_CRC, 0x7f, 0x02, 0x00, 0x00, true, false, NA },
- { MODULE_REVISION_CODE, 0x93, 0x02, 0x00, 0x00, true, false, NA },
+ { BANK_ADDRESS_BITS, 0x04, 0x01, 0x70, 0x04, false, false, ALL },
+ { MODULE_NOMINAL_VOLTAGE, 0x06, 0x01, 0x07, 0x00, false, false, ALL },
+ { FTB_DIVIDEND, 0x09, 0x01, 0xF0, 0x04, false, false, ALL },
+ { FTB_DIVISOR, 0x09, 0x01, 0x0F, 0x00, false, false, ALL },
+ { MTB_DIVIDEND, 0x0a, 0x01, 0x00, 0x00, false, false, ALL },
+ { MTB_DIVISOR, 0x0b, 0x01, 0x00, 0x00, false, false, ALL },
+ { CAS_LATENCIES_SUPPORTED, 0x0f, 0x02, 0x7F, 0x00, true, false, ALL },
+ { TWR_MIN, 0x11, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRRD_MIN, 0x13, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRFC_MIN, 0x19, 0x02, 0x00, 0x00, true, false, ALL },
+ { TWTR_MIN, 0x1a, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRTP_MIN, 0x1b, 0x01, 0x00, 0x00, false, false, ALL },
+ { DLL_OFF, 0x1e, 0x01, 0x80, 0x07, false, false, ALL },
+ { RZQ_7, 0x1e, 0x01, 0x02, 0x01, false, false, ALL },
+ { RZQ_6, 0x1e, 0x01, 0x01, 0x00, false, false, ALL },
+ { PASR, 0x1f, 0x01, 0x80, 0x07, false, false, ALL },
+ { ODTS, 0x1f, 0x01, 0x08, 0x03, false, false, ALL },
+ { ASR, 0x1f, 0x01, 0x04, 0x02, false, false, ALL },
+ { ETR_1X, 0x1f, 0x01, 0x02, 0x01, false, false, ALL },
+ { ETR, 0x1f, 0x01, 0x01, 0x00, false, false, ALL },
+ { MODULE_CRC, 0x7f, 0x02, 0x00, 0x00, true, false, ALL },
+ { MODULE_REVISION_CODE, 0x93, 0x02, 0x00, 0x00, true, false, ALL },
// Module Specific fields supported on both DDR3 and DDR4
{ MODSPEC_COM_NOM_HEIGHT_MAX, 0x3c, 0x01, 0x1f, 0x00, false, false, ALL },
{ MODSPEC_COM_MAX_THICK_BACK, 0x3d, 0x01, 0xf0, 0x04, false, false, ALL },
diff --git a/src/usr/vpd/spdDDR4.H b/src/usr/vpd/spdDDR4.H
index 0d732fa92..b29a1043f 100755
--- a/src/usr/vpd/spdDDR4.H
+++ b/src/usr/vpd/spdDDR4.H
@@ -69,76 +69,76 @@ const KeywordData ddr4Data[] =
// ------------------------------------------------------------------------------------------
//
// Normal fields supported on both DDR3 and DDR4
- { SPD_BYTES_TOTAL, 0x00, 0x01, 0x70, 0x04, false, false, NA },
- { SPD_BYTES_USED, 0x00, 0x01, 0x0F, 0x00, false, false, NA },
- { SPD_MAJOR_REVISION, 0x01, 0x01, 0xF0, 0x04, false, false, NA },
- { SPD_MINOR_REVISION, 0x01, 0x01, 0x0F, 0x00, false, false, NA },
- { BASIC_MEMORY_TYPE, 0x02, 0x01, 0x00, 0x00, false, false, NA },
- { CUSTOM, 0x03, 0x01, 0x80, 0x07, false, false, NA },
- { MODULE_TYPE, 0x03, 0x01, 0x0F, 0x00, false, false, NA },
- { DENSITY, 0x04, 0x01, 0x0F, 0x00, false, false, NA },
- { ROW_ADDRESS, 0x05, 0x01, 0x38, 0x03, false, false, NA },
- { COL_ADDRESS, 0x05, 0x01, 0x07, 0x00, false, false, NA },
- { MODULE_RANKS, 0x0c, 0x01, 0x38, 0x03, false, false, NA },
- { MODULE_DRAM_WIDTH, 0x0c, 0x01, 0x07, 0x00, false, false, NA },
- { MODULE_MEMORY_BUS_WIDTH, 0x0d, 0x01, 0x1f, 0x00, false, false, NA },
- { MODULE_MEMORY_BUS_WIDTH_EXT, 0x0d, 0x01, 0x18, 0x03, false, false, NA },
- { MODULE_MEMORY_BUS_WIDTH_PRI, 0x0d, 0x01, 0x07, 0x00, false, false, NA },
- { TCK_MIN, 0x12, 0x01, 0x00, 0x00, false, false, NA },
- { MIN_CAS_LATENCY, 0x18, 0x01, 0x00, 0x00, false, false, NA },
- { TRCD_MIN, 0x19, 0x01, 0x00, 0x00, false, false, NA },
- { TRP_MIN, 0x1a, 0x01, 0x00, 0x00, false, false, NA },
- { TRC_MIN, 0x1b, 0x02, 0xF0, 0x04, true, false, NA },
- { TRAS_MIN, 0x1b, 0x02, 0x0F, 0x00, false, false, NA },
- { TFAW_MIN, 0x24, 0x02, 0x0F, 0x00, false, false, NA },
- { SDRAM_OPTIONAL_FEATURES, 0x07, 0x01, 0x00, 0x00, false, false, NA },
- { SDRAM_THERMAL_REFRESH_OPTIONS, 0x08, 0x01, 0x00, 0x00, false, false, NA },
- { MODULE_THERMAL_SENSOR, 0x0e, 0x01, 0x00, 0x00, false, false, NA },
- { THERMAL_SENSOR_PRESENT, 0x0e, 0x01, 0x80, 0x07, false, false, NA },
- { SDRAM_DEVICE_TYPE , 0x06, 0x01, 0x80, 0x07, false, false, NA },
- { SDRAM_DIE_COUNT, 0x06, 0x01, 0x70, 0x04, false, false, NA },
- { SDRAM_DEVICE_TYPE_SIGNAL_LOADING, 0x06, 0x01, 0x03, 0x00, false, false, NA },
- { TCKMIN_FINE_OFFSET, 0x7d, 0x01, 0x00, 0x00, false, false, NA },
- { TAAMIN_FINE_OFFSET, 0x7b, 0x01, 0x00, 0x00, false, false, NA },
- { TRCDMIN_FINE_OFFSET, 0x7a, 0x01, 0x00, 0x00, false, false, NA },
- { TRPMIN_FINE_OFFSET, 0x79, 0x01, 0x00, 0x00, false, false, NA },
- { TRCMIN_FINE_OFFSET, 0x78, 0x01, 0x00, 0x00, false, false, NA },
- // Note - All data below 128 is common across all DDR4 DIMMs, even DDIMM
- { MODULE_TYPE_SPECIFIC_SECTION, 0x80, 0x80, 0x00, 0x00, false, false, NA },
- { MODULE_MANUFACTURER_ID, 0x141, 0x02, 0x00, 0x00, true, false, NA },
- { MODULE_MANUFACTURING_LOCATION, 0x142, 0x01, 0x00, 0x00, false, false, NA },
- { MODULE_MANUFACTURING_DATE, 0x143, 0x02, 0x00, 0x00, false, false, NA },
- { MODULE_SERIAL_NUMBER, 0x145, 0x04, 0x00, 0x00, false, false, NA },
- { MODULE_PART_NUMBER, 0x149, 0x14, 0x00, 0x00, false, false, NA },
- { DRAM_MANUFACTURER_ID, 0x15f, 0x02, 0x00, 0x00, true, false, NA },
- { MANUFACTURER_SPECIFIC_DATA, 0x161, 0x1d, 0x00, 0x00, false, false, NA },
- { DIMM_BAD_DQ_DATA, 0x180, 0x50, 0x00, 0x00, false, true, NA },
- { MODULE_REVISION_CODE, 0x15d, 0x01, 0x00, 0x00, false, false, NA },
+ { SPD_BYTES_TOTAL, 0x00, 0x01, 0x70, 0x04, false, false, ALL },
+ { SPD_BYTES_USED, 0x00, 0x01, 0x0F, 0x00, false, false, ALL },
+ { SPD_MAJOR_REVISION, 0x01, 0x01, 0xF0, 0x04, false, false, ALL },
+ { SPD_MINOR_REVISION, 0x01, 0x01, 0x0F, 0x00, false, false, ALL },
+ { BASIC_MEMORY_TYPE, 0x02, 0x01, 0x00, 0x00, false, false, ALL },
+ { CUSTOM, 0x03, 0x01, 0x80, 0x07, false, false, ALL },
+ { MODULE_TYPE, 0x03, 0x01, 0x0F, 0x00, false, false, ALL },
+ { DENSITY, 0x04, 0x01, 0x0F, 0x00, false, false, ALL },
+ { ROW_ADDRESS, 0x05, 0x01, 0x38, 0x03, false, false, ALL },
+ { COL_ADDRESS, 0x05, 0x01, 0x07, 0x00, false, false, ALL },
+ { MODULE_RANKS, 0x0c, 0x01, 0x38, 0x03, false, false, ALL },
+ { MODULE_DRAM_WIDTH, 0x0c, 0x01, 0x07, 0x00, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH, 0x0d, 0x01, 0x1f, 0x00, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH_EXT, 0x0d, 0x01, 0x18, 0x03, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH_PRI, 0x0d, 0x01, 0x07, 0x00, false, false, ALL },
+ { TCK_MIN, 0x12, 0x01, 0x00, 0x00, false, false, ALL },
+ { MIN_CAS_LATENCY, 0x18, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCD_MIN, 0x19, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRP_MIN, 0x1a, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRC_MIN, 0x1b, 0x02, 0xF0, 0x04, true, false, ALL },
+ { TRAS_MIN, 0x1b, 0x02, 0x0F, 0x00, false, false, ALL },
+ { TFAW_MIN, 0x24, 0x02, 0x0F, 0x00, false, false, ALL },
+ { SDRAM_OPTIONAL_FEATURES, 0x07, 0x01, 0x00, 0x00, false, false, ALL },
+ { SDRAM_THERMAL_REFRESH_OPTIONS, 0x08, 0x01, 0x00, 0x00, false, false, ALL },
+ { MODULE_THERMAL_SENSOR, 0x0e, 0x01, 0x00, 0x00, false, false, ALL },
+ { THERMAL_SENSOR_PRESENT, 0x0e, 0x01, 0x80, 0x07, false, false, ALL },
+ { SDRAM_DEVICE_TYPE , 0x06, 0x01, 0x80, 0x07, false, false, ALL },
+ { SDRAM_DIE_COUNT, 0x06, 0x01, 0x70, 0x04, false, false, ALL },
+ { SDRAM_DEVICE_TYPE_SIGNAL_LOADING, 0x06, 0x01, 0x03, 0x00, false, false, ALL },
+ { TCKMIN_FINE_OFFSET, 0x7d, 0x01, 0x00, 0x00, false, false, ALL },
+ { TAAMIN_FINE_OFFSET, 0x7b, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCDMIN_FINE_OFFSET, 0x7a, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRPMIN_FINE_OFFSET, 0x79, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCMIN_FINE_OFFSET, 0x78, 0x01, 0x00, 0x00, false, false, ALL },
+ // Note - All data below 128 is common across all DDR4 DIMMs, except DDIMM
+ { MODULE_TYPE_SPECIFIC_SECTION, 0x80, 0x80, 0x00, 0x00, false, false, ALL },
+ { MODULE_MANUFACTURER_ID, 0x141, 0x02, 0x00, 0x00, true, false, ALL },
+ { MODULE_MANUFACTURING_LOCATION, 0x142, 0x01, 0x00, 0x00, false, false, ALL },
+ { MODULE_MANUFACTURING_DATE, 0x143, 0x02, 0x00, 0x00, false, false, ALL },
+ { MODULE_SERIAL_NUMBER, 0x145, 0x04, 0x00, 0x00, false, false, ALL },
+ { MODULE_PART_NUMBER, 0x149, 0x14, 0x00, 0x00, false, false, ALL },
+ { DRAM_MANUFACTURER_ID, 0x15f, 0x02, 0x00, 0x00, true, false, ALL },
+ { MANUFACTURER_SPECIFIC_DATA, 0x161, 0x1d, 0x00, 0x00, false, false, ALL },
+ { DIMM_BAD_DQ_DATA, 0x180, 0x50, 0x00, 0x00, false, true, ALL },
+ { MODULE_REVISION_CODE, 0x15d, 0x01, 0x00, 0x00, false, false, ALL },
// Normal fields supported on DDR4 only
- { BANK_GROUP_BITS, 0x04, 0x01, 0xC0, 0x06, false, false, NA },
- { BANK_ADDRESS_BITS_DDR4, 0x04, 0x01, 0x30, 0x04, false, false, NA },
- { MODULE_NOMINAL_VOLTAGE_DDR4, 0x0b, 0x01, 0x3F, 0x00, false, false, NA },
- { TIMEBASES_MTB , 0x11, 0x01, 0x0C, 0x02, false, false, NA },
- { TIMEBASES_FTB, 0x11, 0x01, 0x03, 0x00, false, false, NA },
- { TCK_MAX, 0x13, 0x01, 0x00, 0x00, false, false, NA },
- { CAS_LATENCIES_SUPPORTED_DDR4, 0x17, 0x04, 0x00, 0x00, true, false, NA },
- { TRFC1_MIN, 0x1f, 0x02, 0x00, 0x00, true, false, NA },
- { TRFC2_MIN, 0x21, 0x02, 0x00, 0x00, true, false, NA },
- { TRFC4_MIN, 0x23, 0x02, 0x00, 0x00, true, false, NA },
- { TRRDS_MIN, 0x26, 0x01, 0x00, 0x00, false, false, NA },
- { TRRDL_MIN, 0x27, 0x01, 0x00, 0x00, false, false, NA },
- { TCCDL_MIN, 0x28, 0x01, 0x00, 0x00, false, false, NA },
- { CONNECTOR_SDRAM_MAP, 0x3C, 0x12, 0x00, 0x00, false, false, NA },
- { TCCDL_FINE_OFFSET, 0x75, 0x01, 0x00, 0x00, false, false, NA },
- { TRRDL_FINE_OFFSET, 0x76, 0x01, 0x00, 0x00, false, false, NA },
- { TRRDS_FINE_OFFSET, 0x77, 0x01, 0x00, 0x00, false, false, NA },
- { TCKMAX_FINE_OFFSET, 0x7c, 0x01, 0x00, 0x00, false, false, NA },
- { BASE_CONFIG_CRC, 0x7f, 0x02, 0x00, 0x00, true, false, NA },
- { DRAM_STEPPING, 0x160, 0x01, 0x00, 0x00, false, false, NA },
- { MANUFACTURING_SECTION_CRC, 0x17f, 0x02, 0x00, 0x00, true, false, NA },
- { NVM_INIT_TIME, 0xCB, 0x01, 0x00, 0x00, false, false, NA },
- { RAW_MODULE_PRODUCT_ID, 0xc0, 0x02, 0x00, 0x00, false, false, NA },
- { RAW_MODULE_MANUFACTURER_ID, 0x140, 0x02, 0x00, 0x00, false, false, NA },
+ { BANK_GROUP_BITS, 0x04, 0x01, 0xC0, 0x06, false, false, ALL },
+ { BANK_ADDRESS_BITS_DDR4, 0x04, 0x01, 0x30, 0x04, false, false, ALL },
+ { MODULE_NOMINAL_VOLTAGE_DDR4, 0x0b, 0x01, 0x3F, 0x00, false, false, ALL },
+ { TIMEBASES_MTB, 0x11, 0x01, 0x0C, 0x02, false, false, ALL },
+ { TIMEBASES_FTB, 0x11, 0x01, 0x03, 0x00, false, false, ALL },
+ { TCK_MAX, 0x13, 0x01, 0x00, 0x00, false, false, ALL },
+ { CAS_LATENCIES_SUPPORTED_DDR4, 0x17, 0x04, 0x00, 0x00, true, false, ALL },
+ { TRFC1_MIN, 0x1f, 0x02, 0x00, 0x00, true, false, ALL },
+ { TRFC2_MIN, 0x21, 0x02, 0x00, 0x00, true, false, ALL },
+ { TRFC4_MIN, 0x23, 0x02, 0x00, 0x00, true, false, ALL },
+ { TRRDS_MIN, 0x26, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRRDL_MIN, 0x27, 0x01, 0x00, 0x00, false, false, ALL },
+ { TCCDL_MIN, 0x28, 0x01, 0x00, 0x00, false, false, ALL },
+ { CONNECTOR_SDRAM_MAP, 0x3C, 0x12, 0x00, 0x00, false, false, ALL },
+ { TCCDL_FINE_OFFSET, 0x75, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRRDL_FINE_OFFSET, 0x76, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRRDS_FINE_OFFSET, 0x77, 0x01, 0x00, 0x00, false, false, ALL },
+ { TCKMAX_FINE_OFFSET, 0x7c, 0x01, 0x00, 0x00, false, false, ALL },
+ { BASE_CONFIG_CRC, 0x7f, 0x02, 0x00, 0x00, true, false, ALL },
+ { DRAM_STEPPING, 0x160, 0x01, 0x00, 0x00, false, false, ALL },
+ { MANUFACTURING_SECTION_CRC, 0x17f, 0x02, 0x00, 0x00, true, false, ALL },
+ { NVM_INIT_TIME, 0xCB, 0x01, 0x00, 0x00, false, false, ALL },
+ { RAW_MODULE_PRODUCT_ID, 0xc0, 0x02, 0x00, 0x00, false, false, ALL },
+ { RAW_MODULE_MANUFACTURER_ID, 0x140, 0x02, 0x00, 0x00, false, false, ALL },
// Module Specific fields supported on both DDR3 and DDR4
{ MODSPEC_COM_NOM_HEIGHT_MAX, 0x80, 0x01, 0x1f, 0x00, false, false, ALL },
{ MODSPEC_COM_MAX_THICK_BACK, 0x81, 0x01, 0xf0, 0x04, false, false, ALL },
diff --git a/src/usr/vpd/spdDDR4_DDIMM.H b/src/usr/vpd/spdDDR4_DDIMM.H
new file mode 100755
index 000000000..38899b88e
--- /dev/null
+++ b/src/usr/vpd/spdDDR4_DDIMM.H
@@ -0,0 +1,141 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/vpd/spdDDR4_DDIMM.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SPDDDR4_DDIMM_H
+#define __SPDDDR4_DDIMM_H
+
+/**
+ * @file spdDDR4_DDIMM.H
+ *
+ * @brief Provides the DDR4 field information for DDIMM
+ *
+ */
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include "spd.H"
+
+namespace SPD
+{
+
+/**
+ * @brief Pre-defined lookup table for DDR4 keywords and the
+ * information needed to read that data from the SPD data.
+ */
+const KeywordData ddr4DDIMMData[] =
+{
+ // ----------------------------------------------------------------------------------
+ // NOTE: This list must remain an ordered list! The Keyword must be in numerical
+ // order (values defined in spdenums.H) to allow efficient searching, a unit
+ // test enforces this.
+ // ----------------------------------------------------------------------------------
+ // Bit order for each byte is [7:0] as defined by the JEDEC spec (little endian)
+ //
+ // For multi-byte fields, the offset specifies the byte that is placed at offset 0 in
+ // the output buffer.
+ // - If SpecialCase=false then the next byte in SPD is placed at the next offset in
+ // the output buffer until complete. Any bitmask/shift only affects the byte at
+ // offset 0
+ // - If SpecialCase=true then spd.C handles the field in a custom way (e.g. working
+ // backwards through SPD bytes).
+ // Typically for a 2-byte field consisting of (LSB,MSB), the offset points to MSB and
+ // it is a SpecialCase where spd.C first copies the MSB to the output buffer then
+ // copies the previous byte (LSB) to the output buffer (big endian).
+ // ------------------------------------------------------------------------------------------
+ // Keyword offset size Bitmsk Shift Spec Writ- Mod
+ // Number Case able Spec
+ // ------------------------------------------------------------------------------------------
+ //
+ // Normal fields supported on both DDR3 and DDR4
+ { SPD_BYTES_TOTAL, 0x00, 0x01, 0x70, 0x04, false, false, ALL },
+ { SPD_BYTES_USED, 0x00, 0x01, 0x0F, 0x00, false, false, ALL },
+ { SPD_MAJOR_REVISION, 0x01, 0x01, 0xF0, 0x04, false, false, ALL },
+ { SPD_MINOR_REVISION, 0x01, 0x01, 0x0F, 0x00, false, false, ALL },
+ { BASIC_MEMORY_TYPE, 0x02, 0x01, 0x00, 0x00, false, false, ALL },
+ { CUSTOM, 0x03, 0x01, 0x80, 0x07, false, false, ALL },
+ { MODULE_TYPE, 0x03, 0x01, 0x0F, 0x00, false, false, ALL },
+ { DENSITY, 0x04, 0x01, 0x0F, 0x00, false, false, ALL },
+ { ROW_ADDRESS, 0x05, 0x01, 0x38, 0x03, false, false, ALL },
+ { COL_ADDRESS, 0x05, 0x01, 0x07, 0x00, false, false, ALL },
+ { MODULE_RANKS, 0x0c, 0x01, 0x38, 0x03, false, false, ALL },
+ { MODULE_DRAM_WIDTH, 0x0c, 0x01, 0x07, 0x00, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH, 0x0d, 0x01, 0x1f, 0x00, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH_EXT, 0x0d, 0x01, 0x18, 0x03, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH_PRI, 0x0d, 0x01, 0x07, 0x00, false, false, ALL },
+ { TCK_MIN, 0x12, 0x01, 0x00, 0x00, false, false, ALL },
+ { MIN_CAS_LATENCY, 0x18, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCD_MIN, 0x19, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRP_MIN, 0x1a, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRC_MIN, 0x1b, 0x02, 0xF0, 0x04, true, false, ALL },
+ { TRAS_MIN, 0x1b, 0x02, 0x0F, 0x00, false, false, ALL },
+ { TFAW_MIN, 0x24, 0x02, 0x0F, 0x00, false, false, ALL },
+ { SDRAM_OPTIONAL_FEATURES, 0x07, 0x01, 0x00, 0x00, false, false, ALL },
+ { SDRAM_THERMAL_REFRESH_OPTIONS, 0x08, 0x01, 0x00, 0x00, false, false, ALL },
+ { MODULE_THERMAL_SENSOR, 0x0e, 0x01, 0x00, 0x00, false, false, ALL },
+ { THERMAL_SENSOR_PRESENT, 0x0e, 0x01, 0x80, 0x07, false, false, ALL },
+ { SDRAM_DEVICE_TYPE , 0x06, 0x01, 0x80, 0x07, false, false, ALL },
+ { SDRAM_DIE_COUNT, 0x06, 0x01, 0x70, 0x04, false, false, ALL },
+ { SDRAM_DEVICE_TYPE_SIGNAL_LOADING, 0x06, 0x01, 0x03, 0x00, false, false, ALL },
+ { TCKMIN_FINE_OFFSET, 0x7d, 0x01, 0x00, 0x00, false, false, ALL },
+ { TAAMIN_FINE_OFFSET, 0x7b, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCDMIN_FINE_OFFSET, 0x7a, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRPMIN_FINE_OFFSET, 0x79, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCMIN_FINE_OFFSET, 0x78, 0x01, 0x00, 0x00, false, false, ALL },
+ // Note - All data below 128 is common across all DDR4 DIMMs, except DDIMM
+ { MODULE_MANUFACTURER_ID, 0x200, 0x02, 0x00, 0x00, true, false, ALL },
+ { MODULE_SERIAL_NUMBER, 0x205, 0x04, 0x00, 0x00, false, false, ALL },
+ { MODULE_PART_NUMBER, 0x209, 0x1E, 0x00, 0x00, false, false, ALL },
+ { DIMM_BAD_DQ_DATA, 0x280, 0x50, 0x00, 0x00, false, true, ALL },
+ { MODULE_REVISION_CODE, 0x277, 0x01, 0x00, 0x00, false, false, ALL },
+ // Normal fields supported on DDR4 only
+ { BANK_GROUP_BITS, 0x04, 0x01, 0xC0, 0x06, false, false, ALL },
+ { BANK_ADDRESS_BITS_DDR4, 0x04, 0x01, 0x30, 0x04, false, false, ALL },
+ { MODULE_NOMINAL_VOLTAGE_DDR4, 0x0b, 0x01, 0x3F, 0x00, false, false, ALL },
+ { TIMEBASES_MTB, 0x11, 0x01, 0x0C, 0x02, false, false, ALL },
+ { TIMEBASES_FTB, 0x11, 0x01, 0x03, 0x00, false, false, ALL },
+ { TCK_MAX, 0x13, 0x01, 0x00, 0x00, false, false, ALL },
+ { CAS_LATENCIES_SUPPORTED_DDR4, 0x17, 0x04, 0x00, 0x00, true, false, ALL },
+ { TRFC1_MIN, 0x1f, 0x02, 0x00, 0x00, true, false, ALL },
+ { TRFC2_MIN, 0x21, 0x02, 0x00, 0x00, true, false, ALL },
+ { TRFC4_MIN, 0x23, 0x02, 0x00, 0x00, true, false, ALL },
+ { TRRDS_MIN, 0x26, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRRDL_MIN, 0x27, 0x01, 0x00, 0x00, false, false, ALL },
+ { TCCDL_MIN, 0x28, 0x01, 0x00, 0x00, false, false, ALL },
+ { CONNECTOR_SDRAM_MAP, 0x3C, 0x12, 0x00, 0x00, false, false, ALL },
+ { TCCDL_FINE_OFFSET, 0x75, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRRDL_FINE_OFFSET, 0x76, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRRDS_FINE_OFFSET, 0x77, 0x01, 0x00, 0x00, false, false, ALL },
+ { TCKMAX_FINE_OFFSET, 0x7c, 0x01, 0x00, 0x00, false, false, ALL },
+ { BASE_CONFIG_CRC, 0x7f, 0x02, 0x00, 0x00, true, false, ALL },
+ // Module Specific fields supported on DDR4 only
+ { ENTIRE_SPD_WITHOUT_EFD, 0x00, 0x280, 0x00, 0x00, false, false, ALL },
+ { ENTIRE_SPD, 0x00, 0x800, 0x00, 0x00, false, false, ALL },
+ //---------------------------------------------------------------------------------------
+};
+
+
+}; // end SPD namespace
+
+#endif // __SPDDDR4_DDR4_H
diff --git a/src/usr/vpd/test/dvpdtest.H b/src/usr/vpd/test/dvpdtest.H
index b0d62a062..3f16139f3 100755
--- a/src/usr/vpd/test/dvpdtest.H
+++ b/src/usr/vpd/test/dvpdtest.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,7 +37,6 @@
#include <errl/errlentry.H>
#include <devicefw/driverif.H>
#include <targeting/common/predicates/predicatectm.H>
-#include <config.h>
#include <vpd/dvpdenums.H>
#include <vpd/vpdreasoncodes.H>
@@ -732,7 +731,7 @@ class DVPDTest: public CxxTest::TestSuite
DVPDTest() : CxxTest::TestSuite()
{
TRACFCOMP( g_trac_vpd, "Starting DVPDTest" );
-#ifdef CONFIG_SECUREBOOT
+#if (defined CONFIG_SECUREBOOT && ! defined CONFIG_AXONE)
#ifndef __HOSTBOOT_RUNTIME
errlHndl_t l_err = loadSecureSection(PNOR::MEMD);
if(l_err)
@@ -746,7 +745,7 @@ class DVPDTest: public CxxTest::TestSuite
~DVPDTest()
{
-#ifdef CONFIG_SECUREBOOT
+#if (defined CONFIG_SECUREBOOT && ! defined CONFIG_AXONE)
#ifndef __HOSTBOOT_RUNTIME
errlHndl_t l_err = unloadSecureSection(PNOR::MEMD);
TRACFCOMP( g_trac_vpd, "Ending DVPDTest" );
diff --git a/src/usr/vpd/test/spdtest.H b/src/usr/vpd/test/spdtest.H
index bd7f6ef5b..a2e4c7b70 100755
--- a/src/usr/vpd/test/spdtest.H
+++ b/src/usr/vpd/test/spdtest.H
@@ -43,6 +43,7 @@
#include <vpd/spdenums.H>
#include "../spdDDR3.H"
#include "../spdDDR4.H"
+#include "../spdDDR4_DDIMM.H"
#include "../spd.H"
extern trace_desc_t* g_trac_spd;
@@ -117,16 +118,31 @@ class SPDTest: public CxxTest::TestSuite
uint8_t memType = 0x0;
err = getMemType( theTarget,
memType );
+ if( err )
+ {
+ fails++;
+ TS_FAIL("testSpdRead- Failure reading Basic memory type!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;
+ }
+ // Get the module type.
+ modSpecTypes_t modType = NA;
+ err = getModType(modType,
+ theTarget,
+ memType,
+ VPD::AUTOSELECT);
if( err )
{
fails++;
- TS_FAIL( "testSpdRead- Failure reading Basic memory type!" );
+ TS_FAIL("testSpdRead- Failure reading memory module type!");
errlCommit( err,
VPD_COMP_ID );
- break;;
+ break;
}
+
for( uint64_t keyword = SPD::SPD_FIRST_NORM_KEYWORD;
keyword <= SPD::SPD_LAST_NORM_KEYWORD; keyword++ )
{
@@ -154,14 +170,29 @@ class SPDTest: public CxxTest::TestSuite
}
else if( SPD_DDR4_TYPE == memType )
{
+ size_t dataSize = (modType == DDIMM)
+ ? (sizeof(ddr4DDIMMData)/sizeof(ddr4DDIMMData[0]))
+ : (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+
for( entry = 0;
- entry < (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+ entry < dataSize;
entry++ )
{
- if( keyword == ddr4Data[entry].keyword )
+ if (modType == DDIMM)
{
- theSize = ddr4Data[entry].length;
- break;
+ if( keyword == ddr4DDIMMData[entry].keyword )
+ {
+ theSize = ddr4DDIMMData[entry].length;
+ break;
+ }
+ }
+ else
+ {
+ if( keyword == ddr4Data[entry].keyword )
+ {
+ theSize = ddr4Data[entry].length;
+ break;
+ }
}
}
}
@@ -304,6 +335,21 @@ class SPDTest: public CxxTest::TestSuite
break;
}
+ // Get the module type.
+ modSpecTypes_t modType = NA;
+ err = getModType(modType,
+ theTarget,
+ memType,
+ VPD::AUTOSELECT);
+ if( err )
+ {
+ fails++;
+ TS_FAIL("testSpdRead- Failure reading memory module type!");
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;
+ }
+
// Get the size
if( SPD_DDR3_TYPE == memType )
{
@@ -320,14 +366,29 @@ class SPDTest: public CxxTest::TestSuite
}
else if( SPD_DDR4_TYPE == memType )
{
+ size_t dataSize = (modType == DDIMM)
+ ? (sizeof(ddr4DDIMMData)/sizeof(ddr4DDIMMData[0]))
+ : (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+
for( uint32_t entry = 0;
- entry < (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+ entry < dataSize;
entry++ )
{
- if( SPD::DIMM_BAD_DQ_DATA == ddr4Data[entry].keyword )
+ if (modType == DDIMM)
{
- theSize = ddr4Data[entry].length;
- break;
+ if( SPD::DIMM_BAD_DQ_DATA == ddr4DDIMMData[entry].keyword )
+ {
+ theSize = ddr4DDIMMData[entry].length;
+ break;
+ }
+ }
+ else
+ {
+ if( SPD::DIMM_BAD_DQ_DATA == ddr4Data[entry].keyword )
+ {
+ theSize = ddr4Data[entry].length;
+ break;
+ }
}
}
}
@@ -343,6 +404,14 @@ class SPDTest: public CxxTest::TestSuite
break;
}
+ if( 0 == theSize )
+ {
+ // memType not supported or Keyword not supported on
+ // this memType
+ cmds++;
+ break;
+ }
+
// Allocate data buffer
origData = static_cast<uint8_t*>(malloc( theSize ));
@@ -892,6 +961,21 @@ class SPDTest: public CxxTest::TestSuite
break;
}
+ // Get the module type.
+ modSpecTypes_t modType = NA;
+ err = getModType(modType,
+ theTarget,
+ memType,
+ VPD::AUTOSELECT);
+ if( err )
+ {
+ fails++;
+ TS_FAIL("testSpdRead- Failure reading memory module type!");
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;
+ }
+
// The real Keyword read testing
for( uint64_t keyword = SPD::SPD_FIRST_MOD_SPEC;
keyword <= SPD::SPD_LAST_MOD_SPEC; keyword++ )
@@ -922,15 +1006,31 @@ class SPDTest: public CxxTest::TestSuite
}
else if( SPD_DDR4_TYPE == memType )
{
+ size_t dataSize = (modType == DDIMM)
+ ? (sizeof(ddr4DDIMMData)/sizeof(ddr4DDIMMData[0]))
+ : (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+
for( entry = 0;
- entry < (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+ entry < dataSize;
entry++ )
{
- if( keyword == ddr4Data[entry].keyword )
+ if (modType == DDIMM)
{
- kwdData = ddr4Data[entry];
- theSize = ddr4Data[entry].length;
- break;
+ if( keyword == ddr4DDIMMData[entry].keyword )
+ {
+ kwdData = ddr4DDIMMData[entry];
+ theSize = ddr4DDIMMData[entry].length;
+ break;
+ }
+ }
+ else
+ {
+ if( keyword == ddr4Data[entry].keyword )
+ {
+ kwdData = ddr4Data[entry];
+ theSize = ddr4Data[entry].length;
+ break;
+ }
}
}
}
diff --git a/src/usr/vpd/vpd.C b/src/usr/vpd/vpd.C
index a9bc590b5..490c8bbc8 100755
--- a/src/usr/vpd/vpd.C
+++ b/src/usr/vpd/vpd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -475,55 +475,55 @@ void setPartAndSerialNumberAttributes( TARGETING::Target * i_target )
void updateSerialNumberFromBMC( TARGETING::Target * i_nodetarget )
{
#ifdef CONFIG_UPDATE_SN_FROM_BMC
- errlHndl_t l_errl = NULL;
- size_t l_vpdSize = 0;
-
- //Get Product Serial Number from Backplane
- char* l_sn_prod = NULL;
- l_sn_prod = IPMIFRUINV::getProductSN(0);
- if (l_sn_prod != NULL)
- {
- TRACFCOMP(g_trac_vpd, "Got system serial number from BMC.");
- TRACFCOMP(g_trac_vpd, "SN from BMC is: %s", l_sn_prod);
-
- l_errl = deviceRead(i_nodetarget, NULL, l_vpdSize,
- DEVICE_PVPD_ADDRESS( PVPD::OSYS, PVPD::SS ));
-
- if(l_errl == NULL)
- {
- uint8_t l_vpddata[l_vpdSize];
-
- l_errl = deviceRead(i_nodetarget, l_vpddata, l_vpdSize,
- DEVICE_PVPD_ADDRESS( PVPD::OSYS, PVPD::SS ));
-
- if(l_errl == NULL)
- {
- TRACFCOMP(g_trac_vpd, "SN in PVPD::OSYS:SS: %s, size: %d", l_vpddata, l_vpdSize);
-
- if (strncmp(l_sn_prod, l_vpddata, l_vpdSize) != 0)
- {
- l_errl = deviceWrite(i_nodetarget, l_sn_prod, l_vpdSize,
- DEVICE_PVPD_ADDRESS( PVPD::OSYS, PVPD::SS ));
- CONSOLE::displayf(NULL, "updated SN from BMC into PVPD.");
- CONSOLE::flush();
- CONSOLE::displayf(NULL, "Need a reboot.");
- CONSOLE::flush();
- INITSERVICE::requestReboot();
- }
- }
- }
-
- if(l_errl)
- {
- ERRORLOG::errlCommit(l_errl,VPD_COMP_ID);
- }
-
- //getProductSN requires the caller to delete the char array
- delete[] l_sn_prod;
- l_sn_prod = NULL;
-
- TRACFCOMP(g_trac_vpd, "End updateSerialNumberFromBMC.");
- }
+ errlHndl_t l_errl = NULL;
+ size_t l_vpdSize = 0;
+
+ //Get Product Serial Number from Backplane
+ char* l_sn_prod = NULL;
+ l_sn_prod = IPMIFRUINV::getProductSN(0);
+ if (l_sn_prod != NULL)
+ {
+ TRACFCOMP(g_trac_vpd, "Got system serial number from BMC.");
+ TRACFCOMP(g_trac_vpd, "SN from BMC is: %s", l_sn_prod);
+
+ l_errl = deviceRead(i_nodetarget, NULL, l_vpdSize,
+ DEVICE_PVPD_ADDRESS( PVPD::OSYS, PVPD::SS ));
+
+ if(l_errl == NULL)
+ {
+ uint8_t l_vpddata[l_vpdSize];
+
+ l_errl = deviceRead(i_nodetarget, l_vpddata, l_vpdSize,
+ DEVICE_PVPD_ADDRESS( PVPD::OSYS, PVPD::SS ));
+
+ if(l_errl == NULL)
+ {
+ TRACFCOMP(g_trac_vpd, "SN in PVPD::OSYS:SS: %s, size: %d", l_vpddata, l_vpdSize);
+
+ if (strncmp(l_sn_prod, l_vpddata, l_vpdSize) != 0)
+ {
+ l_errl = deviceWrite(i_nodetarget, l_sn_prod, l_vpdSize,
+ DEVICE_PVPD_ADDRESS( PVPD::OSYS, PVPD::SS ));
+ CONSOLE::displayf(NULL, "updated SN from BMC into PVPD.");
+ CONSOLE::flush();
+ CONSOLE::displayf(NULL, "Need a reboot.");
+ CONSOLE::flush();
+ INITSERVICE::requestReboot();
+ }
+ }
+ }
+
+ if(l_errl)
+ {
+ ERRORLOG::errlCommit(l_errl,VPD_COMP_ID);
+ }
+
+ //getProductSN requires the caller to delete the char array
+ delete[] l_sn_prod;
+ l_sn_prod = NULL;
+
+ TRACFCOMP(g_trac_vpd, "End updateSerialNumberFromBMC.");
+ }
#endif
}
@@ -590,56 +590,19 @@ errlHndl_t getPnAndSnRecordAndKeywords( TARGETING::Target * i_target,
io_keywordSN = CVPD::SN;
#endif
}
- else if( i_type == TARGETING::TYPE_DIMM )
+ else if(( i_type == TARGETING::TYPE_DIMM )
+ || (i_type == TARGETING::TYPE_OCMB_CHIP))
{
// SPD does not have singleton instance
- // SPD does not use records
+ // SPD does not use record
io_keywordPN = SPD::MODULE_PART_NUMBER;
io_keywordSN = SPD::MODULE_SERIAL_NUMBER;
}
else if( i_type == TARGETING::TYPE_NODE )
{
-#if defined(CONFIG_PVPD_READ_FROM_HW) && defined(CONFIG_PVPD_READ_FROM_PNOR)
- IpVpdFacade* l_ipvpd = &(Singleton<PvpdFacade>::instance());
io_record = PVPD::OPFR;
io_keywordPN = PVPD::VP;
io_keywordSN = PVPD::VS;
-
- bool l_zeroPN;
- l_err = l_ipvpd->cmpSeepromToZero( i_target,
- io_record,
- io_keywordPN,
- l_zeroPN );
- if (l_err)
- {
- TRACFCOMP(g_trac_vpd,ERR_MRK"VPD::getPnAndSnRecordAndKeywords: Error checking if OPFR:VP == 0");
- break;
- }
-
- bool l_zeroSN;
- l_err = l_ipvpd->cmpSeepromToZero( i_target,
- io_record,
- io_keywordSN,
- l_zeroSN );
- if (l_err)
- {
- TRACFCOMP(g_trac_vpd,ERR_MRK"VPD::getPnAndSnRecordAndKeywords: Error checking if OPFR:VS == 0");
- break;
- }
-
- // If VP and VS are zero, use VINI instead
- if( l_zeroPN && l_zeroSN )
- {
- TRACFCOMP(g_trac_vpd, "setting cvpd to VINI PN SN");
- io_record = PVPD::VINI;
- io_keywordPN = PVPD::PN;
- io_keywordSN = PVPD::SN;
- }
-#else
- io_record = PVPD::VINI;
- io_keywordPN = PVPD::PN;
- io_keywordSN = PVPD::SN;
-#endif
}
else if( i_type == TARGETING::TYPE_MCS )
{
@@ -672,6 +635,249 @@ errlHndl_t getPnAndSnRecordAndKeywords( TARGETING::Target * i_target,
return l_err;
}
+/**
+ * @brief This function compares the specified record/keyword in
+ * CACHE/HARDWARE by calling the correct function based on the
+ * target's eeprom content type and returns the result. A mismatch
+ * will not return an error.
+ *
+ * @param[in] i_target Target device
+ *
+ * @param[in] i_eepromType Eeprom content type for the target.
+ *
+ * @param[in] i_keyword Keyword to compare
+ *
+ * @param[in] i_record Record to compare
+ *
+ * @param[out] o_match Result of compare
+ *
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t cmpEecacheToEeprom(TARGETING::Target * i_target,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType,
+ vpdKeyword i_keyword,
+ vpdRecord i_record,
+ bool& o_match)
+{
+ errlHndl_t l_err = nullptr;
+
+ if ( (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_IBM_MVPD)
+ || (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_IBM_FRUVPD))
+ {
+ auto l_type = i_target->getAttr<TARGETING::ATTR_TYPE>();
+ IpVpdFacade* l_ipvpd = &(Singleton<MvpdFacade>::instance());
+
+ // If we have a NODE, use pvpd api
+ if(l_type == TARGETING::TYPE_NODE)
+ {
+ l_ipvpd = &(Singleton<PvpdFacade>::instance());
+ }
+
+ l_err = l_ipvpd->cmpEecacheToEeprom(i_target,
+ i_record,
+ i_keyword,
+ o_match);
+ }
+ else if ( (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_ISDIMM)
+ || (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_DDIMM))
+ {
+ l_err = SPD::cmpEecacheToEeprom(i_target,
+ i_eepromType,
+ i_keyword,
+ o_match);
+ }
+ else
+ {
+ assert(false, "Error, invalid EEPROM type 0x%x for target HUID 0x%X passed to cmpEecacheToEeprom",
+ i_eepromType, get_huid(i_target));
+ }
+
+ return l_err;
+}
+
+
+// ------------------------------------------------------------------
+// ensureEepromCacheIsInSync
+// ------------------------------------------------------------------
+errlHndl_t ensureEepromCacheIsInSync(TARGETING::Target * i_target,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType,
+ bool & o_isInSync)
+{
+ errlHndl_t l_err = nullptr;
+
+ TRACDCOMP(g_trac_vpd, ENTER_MRK"ensureEepromCacheIsInSync() ");
+
+ vpdRecord l_record = 0;
+ vpdKeyword l_keywordPN = 0;
+ vpdKeyword l_keywordSN = 0;
+ TARGETING::TYPE l_type = i_target->getAttr<TARGETING::ATTR_TYPE>();
+
+ do
+ {
+ // Get the correct Part and serial numbers
+ l_err = getPnAndSnRecordAndKeywords(i_target,
+ i_target->
+ getAttr<TARGETING::ATTR_TYPE>(),
+ l_record,
+ l_keywordPN,
+ l_keywordSN);
+ if( l_err )
+ {
+ TRACFCOMP(g_trac_vpd,
+ "VPD::ensureEepromCacheIsInSync: "
+ "Error getting part and serial numbers");
+ break;
+ }
+
+ // Compare the Part Numbers in CACHE/HARDWARE
+ bool l_matchPN = false;
+ l_err = cmpEecacheToEeprom(i_target,
+ i_eepromType,
+ l_keywordPN,
+ l_record,
+ l_matchPN);
+
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_vpd,ERR_MRK
+ "VPD::ensureEepromCacheIsInSync: "
+ "Error checking for CACHE/HARDWARE PN match");
+ break;
+ }
+
+ // Compare the Serial Numbers in CACHE/HARDWARE
+ bool l_matchSN = false;
+ l_err = cmpEecacheToEeprom(i_target,
+ i_eepromType,
+ l_keywordSN,
+ l_record,
+ l_matchSN);
+
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_vpd, ERR_MRK
+ "VPD::ensureEepromCacheIsInSync: Error checking for "
+ "CACHE/HARDWARE SN match");
+ break;
+ }
+
+ // Check the serial number and part number of the system if the previous
+ // record/key pair matched. Note that this time the record/key pairs are
+ // OSYS/SS and OSYS/MM for serial number and part number, respectively
+ if (l_type == TARGETING::TYPE_NODE &&
+ (l_matchSN && l_matchPN))
+ {
+ // If we have a NODE, use pvpd api
+ IpVpdFacade* l_ipvpd = &(Singleton<PvpdFacade>::instance());
+ bool l_zeroPN = false;
+ bool l_zeroSN = false;
+ l_err = l_ipvpd->cmpSeepromToZero(i_target,
+ PVPD::OSYS,
+ PVPD::MM,
+ l_zeroPN);
+ if(l_err)
+ {
+ TRACDCOMP(g_trac_vpd,ERR_MRK"VPD::ensureEepromCacheIsInSync: "
+ "cmpSeepromToZero returned an error. Assuming this error is "
+ "related to OSYS/MM not being present in SEEPROM. Skipping "
+ "this error. HUID: 0x%.8X",
+ TARGETING::get_huid(i_target));
+ delete l_err;
+ l_err = nullptr;
+ l_zeroPN = true;
+
+ }
+
+ l_err = l_ipvpd->cmpSeepromToZero(i_target,
+ PVPD::OSYS,
+ PVPD::SS,
+ l_zeroSN);
+ if(l_err)
+ {
+ TRACDCOMP(g_trac_vpd,ERR_MRK"VPD::ensureEepromCacheIsInSync: "
+ "cmpSeepromToZero returned an error. Assuming this error is "
+ "related to OSYS/SS not being present in SEEPROM. Skipping "
+ "this error. HUID: 0x%.8X",
+ TARGETING::get_huid(i_target));
+ delete l_err;
+ l_err = nullptr;
+ l_zeroSN = true;
+ }
+
+ //Only compare the SN/PN between SEEPROM and EECACHE if they are
+ //nonzero.
+ if(!l_zeroPN)
+ {
+ l_err = cmpEecacheToEeprom(i_target,
+ i_eepromType,
+ PVPD::MM,
+ PVPD::OSYS,
+ l_matchPN);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_vpd,ERR_MRK"VPD::ensureEepromCacheIsInSync: Error"
+ " checking for EECACHE/SEEPROM PN match for NODE target 0x%.8X",
+ TARGETING::get_huid(i_target));
+ break;
+ }
+ }
+
+ if(!l_zeroSN)
+ {
+ l_err = cmpEecacheToEeprom(i_target,
+ i_eepromType,
+ PVPD::SS,
+ PVPD::OSYS,
+ l_matchSN);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_vpd,ERR_MRK"VPD::ensureEepromCacheIsInSync: Error"
+ " checking for EECACHE/SEEPROM SN match for NODE target 0x%.8X",
+ TARGETING::get_huid(i_target));
+ break;
+ }
+ }
+ }
+
+ o_isInSync = (l_matchPN && l_matchSN);
+
+ // If we did not match, we need to load HARDWARE VPD data into CACHE
+ if (o_isInSync)
+ {
+ TRACFCOMP(g_trac_vpd,
+ "VPD::ensureEepromCacheIsInSync: "
+ "CACHE_PN/SN == HARDWARE_PN/SN for target %.8X",
+ TARGETING::get_huid(i_target));
+ }
+ else
+ {
+ TRACFCOMP(g_trac_vpd,
+ "VPD::ensureEepromCacheIsInSync: CACHE_PN/SN != HARDWARE_PN/SN,CACHE must be loaded from HARDWARE for target %.8X",
+ TARGETING::get_huid(i_target));
+ const char* l_pathstring
+ = i_target->getAttr<TARGETING::ATTR_PHYS_PATH>().toString();
+ CONSOLE::displayf(NULL,"Detected new part : %.8X (%s)",
+ TARGETING::get_huid(i_target),
+ l_pathstring);
+ free((void*)(l_pathstring));
+ l_pathstring = nullptr;
+ CONSOLE::flush();
+#ifndef CONFIG_SUPPORT_EEPROM_CACHING
+ //Set the targets as changed since the p/n's don't match
+ HWAS::markTargetChanged(i_target);
+#else
+ //No need to mark target changed here, it will be handled by eecache code
+#endif
+ }
+
+ } while(0);
+
+ TRACDCOMP(g_trac_vpd, EXIT_MRK"ensureEepromCacheIsInSync()");
+
+ return l_err;
+}
+
// ------------------------------------------------------------------
// ensureCacheIsInSync
// ------------------------------------------------------------------
@@ -842,6 +1048,14 @@ errlHndl_t ensureCacheIsInSync ( TARGETING::Target * i_target )
else
{
TRACFCOMP(g_trac_vpd,"VPD::ensureCacheIsInSync: PNOR_PN/SN != SEEPROM_PN/SN, Loading PNOR from SEEPROM for target %.8X",TARGETING::get_huid(i_target));
+ const char* l_pathstring =
+ i_target->getAttr<TARGETING::ATTR_PHYS_PATH>().toString();
+ CONSOLE::displayf(NULL,"Detected new part : %.8X (%s)",
+ TARGETING::get_huid(i_target),
+ l_pathstring);
+ free((void*)(l_pathstring));
+ l_pathstring = nullptr;
+ CONSOLE::flush();
//Set the targets as changed since the p/n's don't match
HWAS::markTargetChanged(i_target);
@@ -1122,14 +1336,16 @@ void getListOfOverrideSections( OverrideRsvMemMap_t& o_overrides )
delete l_elog;
return;
}
+ else
+ {
+ // Add MEMD section
+ OverrideSpecifier_t l_memd = {
+ PNOR::MEMD,
+ l_memd_info.size
+ };
- // Add MEMD section
- OverrideSpecifier_t l_memd = {
- PNOR::MEMD,
- l_memd_info.size
- };
-
- o_overrides[0x4D454D44/*MEMD*/] = l_memd;
+ o_overrides[0x4D454D44/*MEMD*/] = l_memd;
+ }
}
}; //end VPD namespace
diff --git a/src/usr/vpd/vpd.mk b/src/usr/vpd/vpd.mk
index d5717e653..aa3333291 100644
--- a/src/usr/vpd/vpd.mk
+++ b/src/usr/vpd/vpd.mk
@@ -34,4 +34,5 @@ OBJS += cvpd.o
OBJS += pvpd.o
OBJS += dvpd.o
OBJS += spd.o
+OBJS += ocmb_spd.o
OBJS += errlud_vpd.o
diff --git a/src/usr/vpd/vpd_common.C b/src/usr/vpd/vpd_common.C
index 0196b8be8..92c4e9294 100644
--- a/src/usr/vpd/vpd_common.C
+++ b/src/usr/vpd/vpd_common.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -156,6 +156,8 @@ bool resolveVpdSource( TARGETING::Target * i_target,
}
}
+ TRACDCOMP(g_trac_vpd,"resolveVpdSource: o_vpdSource = %s" ,o_vpdSource == VPD::PNOR ? "PNOR" : "SEEPROM" );
+
return badConfig;
}
diff --git a/src/usr/xscom/test/xscomtest.H b/src/usr/xscom/test/xscomtest.H
index a3d7076ce..03718532c 100644
--- a/src/usr/xscom/test/xscomtest.H
+++ b/src/usr/xscom/test/xscomtest.H
@@ -71,9 +71,10 @@ const testXscomAddrData g_xscomMultiWriteTable[] =
{0x21010A89, 0x0200000000000000},
{0x22010A89, 0x0030000000000000},
{0x23010A89, 0x0004000000000000},
- // Local checkstop regs
- {0x10040018, 0x1000000000000000}, // ChipletID 0x10
- {0x20040018, 0x1000000000000000}, // ChipletID 0x20
+ // Group0 Xstop mask regs, TPEQPCC.EPS.FIR.GXSTOP0_MASK_REG
+ // Use register without actions attached to it
+ {0x10040014, 0x8000000000000000}, // ChipletID 0x10, set bit0
+ {0x20040014, 0x8000000000000000}, // ChipletID 0x20, set bit0
};
const uint32_t g_xscomMultiWriteTableSz =
sizeof(g_xscomMultiWriteTable)/sizeof(testXscomAddrData);
@@ -85,10 +86,10 @@ const testXscomAddrData g_xscomMultiReadTable[] =
// Scratch reg 3
// Multicast OR op
{0x41010a89, 0x1234000000000000},
- // Local checkstop regs
+ // Group0 Xstop Mask regs, TPEQPCC.EPS.FIR.GXSTOP0_MASK_REG
// ChipletID 0x10 0x20
// Multicast BITWISE op
- {0x50040018, 0x0000800080000000},
+ {0x50040014, 0x0000800080000000},
};
const uint32_t g_xscomMultiReadTableSz =
sizeof(g_xscomMultiReadTable)/sizeof(testXscomAddrData);
@@ -404,8 +405,8 @@ public:
uint32_t l_num;
do {
-#if defined(CONFIG_EARLY_TESTCASES) || defined(CONFIG_AXONE_BRING_UP)
- TS_TRACE("testXscom4: Skipping test, multicast groups not setup yet");
+#if defined(CONFIG_EARLY_TESTCASES)
+ TS_INFO("testXscom4: Skipping test, multicast groups not setup yet");
break;
#endif
diff --git a/src/usr/xscom/xscom.C b/src/usr/xscom/xscom.C
index 73d7e9e22..3b3a59d40 100644
--- a/src/usr/xscom/xscom.C
+++ b/src/usr/xscom/xscom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -810,11 +810,8 @@ uint64_t generate_mmio_addr( TARGETING::Target* i_proc,
// Build the XSCom address (relative to group 0, chip 0)
XSComP9Address l_mmioAddr(i_scomAddr);
- // Get the offset
- uint64_t l_offset = l_mmioAddr.offset();
-
// Compute value relative to target chip
- l_returnAddr = l_XSComBaseAddr + l_offset;
+ l_returnAddr = l_XSComBaseAddr + l_mmioAddr;
return l_returnAddr;
}
OpenPOWER on IntegriCloud